Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Порекомендуйте какое-нибудь softcore
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
Страницы: 1, 2, 3
Mahagam
Цитата(Leka @ Oct 17 2008, 18:20) *
Сравниваю "безрегистровую" и регистровую архитектуры мелких софт-процессоров... Пример - работа с памятью:
Код
  
//копирование массива
//while(src <= pmax) *dst++ = *src++;

//"безрегистровая" архитектура
//цикл: 3команды, 8тактов
//ofs = dst - src
loop: *src[ofs] = *src //4такта
src++ //2
loop(src <= pmax) //2

MSP430:
Код
loop1:    mov.w    @R12+, offset(R12) // 5 тактов, один из которых именно для
                              // mov можно исключить (зазря читается регистр
                              // назначения, так как mov выполняется так же как и
                              // add, sub, or, and, etc.)
                              // разве что размер ядра увеличится и частота упадёт
        cmp.w    R12, R13          // 1 такт
        jnz        loop1              // 2 такта, но в моей реализации - 1.

паритет. либо у MSP кода есть выигрыш в 1 такт (это если jnz за такт, как у меня)
что касается размера кода - четыре 16-ти разрядных слова. что опять же меньше чем три 32-х разрядных.

Цитата
//регистровое, "пустой магазин": 7команд, 7 тактов
r1 = b
r1 = *r1
r2 = c
r2 = *r2
r2 += r1
r1 = a
*r1 = r2

что-то мне подсказывает, что такая архитектура, если её грамотно реализовать, без проблем заведётся на 100+ MHz. даже в чахлом спартане/циклоне.

кажется мне, что нужно серьёзно посравнивать архитектуры на разных подзадачках. и по размеру кода, и по растактовке и по сложности реализации. и что-то мне подсказывает, что древняя PDP11 будет ох как хороша.
vetal
Цитата
что-то мне подсказывает, что такая архитектура, если её грамотно реализовать, без проблем заведётся на 100+ MHz. даже в чахлом спартане/циклоне.

Так и есть smile.gif
Mahagam
Цитата(vetal @ Oct 20 2008, 11:47) *
Так и есть smile.gif

только при этом:
а) мало полезных действий за такт. то есть особо выигрыша от высокой частоты не получаем
б) дюже разреженный код. из этого вытекает жирный недостаток - если доступ к памяти медленный - проигрываем всем остальным вчистую.
vetal
Цитата(Mahagam @ Oct 20 2008, 13:54) *
только при этом:
а) мало полезных действий за такт. то есть особо выигрыша от высокой частоты не получаем
б) дюже разреженный код. из этого вытекает жирный недостаток - если доступ к памяти медленный - проигрываем всем остальным вчистую.

а) Вы хотите за 1 такт что-то большее, чем R3=R1+R2? Это идеология всех современных ядер, начиная от микроблэйзов, ниосов, армов и заканчивая спарками.
б) Память в любой системе - слабое место. Дюже это сколько?
Leka
Что делаю:
- фон-неймановская архитектура, 32 разряда команда/данные
- внутренняя 2х-портовая память команд/данных
- трехоперандная система команд
- минимальный набор инструкций (алу: + - & | ^ div2, переходы: < <= == != > >=) - 2..4 такта в зависимости от типа адресации (a,*a,*a[b], proc, *proc).
Примеры:
a = b + c ... *a = *b ^ *c
a += *b[c] ... *a[b] ^= *c
label(a < B ) ... label(*a >= *B )
proc(a) ... *proc(*a) - переход на подпрограмму с передачей аргумента.
Написано и проверено на синтезаторе 3/4 кода, вроде укладывается в ожидаемые <500лут, >75МГц для Спартана. Сначала хотел 16-разрядное АЛУ, но для фон-неймановской архитектуры появляются лишние мультиплексоры(и задержки), поэтому отказался пока от такого варианта.
Mahagam
Цитата(vetal @ Oct 20 2008, 13:22) *
а) Вы хотите за 1 такт что-то большее, чем R3=R1+R2? Это идеология всех современных ядер, начиная от микроблэйзов, ниосов, армов и заканчивая спарками.
б) Память в любой системе - слабое место. Дюже это сколько?

опять упомяну PDP11. например хочется чего-то подобного на add @R1+, @R2+
тут не за такт, но в одну команду совершается много действий. вся соль в том, что шина данных освобождается от выборки кучи команд.

и, кстати, вы неправы относительно, например, АРМа, там в одну команду пихается тьма действий. wacko.gif другое дело, что браться за реализацию ядра арма я буду только под принуждением smile.gif
Leka
В вариант с внутренней памятью программ/данных можно будет добавить поддержку внешней SPI флешки - для неторопливого выполнения длинного внешнего кода.
des00
Цитата(Mahagam @ Oct 20 2008, 06:11) *
опять упомяну PDP11. например хочется чего-то подобного на add @R1+, @R2+
тут не за такт, но в одну команду совершается много действий. вся соль в том, что шина данных освобождается от выборки кучи команд.


Года 2-3 назад была подобная тема, помню высказывание SM, он говорил о том что при современном уровне развития электроники идет откат от RISC архитектур в пользу CISC. Т.к. они более гибкие у уже почти не проигрывают в производительности RISC.

PDP11 ИМХО очень красивая архитектура для фпга, вот выйду на пенсию займусь %)

Цитата
и, кстати, вы неправы относительно, например, АРМа, там в одну команду пихается тьма действий. wacko.gif другое дело, что браться за реализацию ядра арма я буду только под принуждением smile.gif


подход микроблейза по своей сути арм7 и есть %)
Leka
Цитата(Leka @ Oct 20 2008, 15:10) *
Что делаю:
- фон-неймановская архитектура, 32 разряда команда/данные
- внутренняя 2х-портовая память команд/данных
- трехоперандная система команд
- минимальный набор инструкций (алу: + - & | ^ div2, переходы: < <= == != > >=) - 2..4 такта в зависимости от типа адресации (a,*a,*a[b], proc, *proc).
Примеры:
a = b + c ... *a = *b ^ *c
a += *b[c] ... *a[b] ^= *c
label(a < B ) ... label(*a >= *B )
proc(a) ... *proc(*a) - переход на подпрограмму с передачей аргумента.
Написано и проверено на синтезаторе 3/4 кода, вроде укладывается в ожидаемые <500лут, >75МГц для Спартана. Сначала хотел 16-разрядное АЛУ, но для фон-неймановской архитектуры появляются лишние мультиплексоры(и задержки), поэтому отказался пока от такого варианта.

Дописал, ~400лут ~100МГц для Спартан3, ~300лут ~200МГц для Virtex5. Так что "безрегистровая" архитектура - в самый раз для FPGA, имхо.
vetal
Тут рано судить. Надо собирать реальную систему(хотя бы простейшую timer+uart+пару кило внутрикристальной памяти) и смотреть. Для полноты надо еще прерывания, shifter и возможность работать с байтами/шортами.
Если не сложно - соберите ваш код под cyclone и огласите результат.
Ну а дальше - сравнение эффективности на памяти CL2-CL3 без кэша.

Цитата
Так что "безрегистровая" архитектура - в самый раз для FPGA, имхо.

Я уже упоминал по моему - у вас не безрегистровая архитектура, а регистровая с вынесенным относительно ядра регистровым файлом smile.gif Вопрос стоит как раз в эффективности вынесения.
Leka
Цифры для ядра с памятью 2К*32. Установлен только ISE, так что для циклона пока нет возможности синтезировать, но ожидаю сопоставимые цифры. Периферии пока нет, идеология обмена поменялась - все переделывать придется.
Mahagam
Цитата(Leka @ Oct 23 2008, 22:27) *
Цифры для ядра с памятью 2К*32. Установлен только ISE, так что для циклона пока нет возможности синтезировать, но ожидаю сопоставимые цифры. Периферии пока нет, идеология обмена поменялась - все переделывать придется.

что там с новой идеологией?
Leka
Цитата(Mahagam @ Oct 27 2008, 14:38) *
что там с новой идеологией?

Обмен с периферией только в виде выполнения внешней команды c=ext(f,a,b ), где f - номер внешней команды/устройства, любой тип адресации a,b,c. Чтобы можно было, например: умножение f=1 --> c=ext(1,a,b ) --> c=a*b, запись в видеобуфер f=2 c=ext(2,a,b ) --> c=vga[a], vga[a]=b, и тд и тп.
des00
Цитата(Leka @ Oct 27 2008, 07:38) *
Обмен с периферией только в виде выполнения внешней команды c=ext(f,a,b ), где f - номер внешней команды/устройства, любой тип адресации a,b,c. Чтобы можно было, например: умножение f=1 --> c=ext(1,a,b ) --> c=a*b, запись в видеобуфер f=2 c=ext(2,a,b ) --> c=vga[a], vga[a]=b, и тд и тп.


решил пройтись по opencores

а вот это не безрегистровый ли процессор ? smile.gif)

http://opencores.org/projects.cgi/web/tiny8/overview

The registers resides in RAM addressed via a base pointer in the WP register (like the TMS9900).
Leka
Описание(архитектура, система команд, ...) - интересно взглянуть, но логина нет пока(запрос послал). Свой опробовал на простом примере(вывод фонта в цикле на VGA), и отложил в сторону, сейчас главное - прикрутить ЯВУ. Требования к ЯВУ:
1) из распространенных, с исходниками,
2) легко настраиваемый компилятор - самокомпилирующийся, и с минимумом
машинно-зависимого кода(<1К строк),
3) генерация компактного(<2Кслов) кода.
des00
Цитата(Leka @ Nov 18 2008, 07:44) *
Описание(архитектура, система команд, ...) - интересно взглянуть, но логина нет пока(запрос послал).


Если еще не пришло
Leka
Посмотрел, самый информативный файл - opcodes.txt, имхо. Что заметил:
1) load/store архитектура - косвенная адресация только для команды MOV(не считая JMP),
2) отсутствие команды перехода на подпрограмму,
3) основные команды - 3х-байтные,
4) отсутствие IN/OUT команд.

По поводу ЯВУ - пересмотрел кучу проектов в инете - так и не выбрал
какой-либо за основу - хард оказывается намного мягче софта.
Leka
Пишу компилятор автокода "безрегистрового"(с регистровым файлом на памяти) софт-ядра:
- более низкий уровень - только в машинных кодах
- построчная запись операторов
- оптимизация только в пределах строки
- одна строка на автокоде может транслироваться в несколько машинных команд
- отсутствие типов - всегда подразумевается "integer"
- отсутствие адресных операторов и типов - только индексная адресация
Цель введенных ограничений - переносимость программ между разными версиями ядер.
Пример программы "N ферзей" (из ветки "Паскаль для АВР") на автокоде:
Код
procedure queens(N, count)
var
    arow[N], aleft[N], aright[N], aposs[N]
    poss, place, val, pos
begin    
    count = 0
    val = shl(1, N) - 1
    pos = 1
    arow[1] = 0
    aleft[1] = 0
    aright[1] = 0
    aposs[1] = shr(1, N / 2)
    poss = aposs[1]
    while pos <> 0
          if poss <> 0
              place = poss & - poss
              poss &= ~ place
              if  pos = 1 and poss = 0 and (N & 1) <> 0
                  count *= 2
              end    
              if pos <> N
                  aposs[pos] = poss              
                  arow[pos + 1] = arow[pos] | place
                  aleft[pos + 1] = (aleft[pos] | place) * 2
                  aright[pos + 1] = (aright[pos] | place) / 2
                  poss = ~ (arow[pos + 1] | aleft[pos + 1] | aright[pos + 1]) & val
                  pos += 1
              else
                  count += 1
              end
        else
            pos -= 1
            poss = aposs[pos]
        end
    end
    if (N & 1) = 0
        count *= 2
    end
end
Leka
Перерыв был большой в этом проекте...

Посмотрел для Cyclone3 - ~600 ЛУТ, ~80 МГц, 10 блоков M9K.
На LatticeXP2 лучше переносится - ~500 ЛУТ, ~115 МГц, 4 блока памяти (по 18К).

Компилятор в тетрады почти готов (queens компилируется в ~60 команд), дальше тривиально - перевод в машинные коды. Сейчас ~700 строк на Паскале, думаю уложиться в ~1000 строк - рефакторинг проще будет делать. В планах - набить 64 ядра с 0.5Кслов памяти каждое в Spartan3A-DSP, и запустить queens впараллель - сравню с ПК.
SM
Вы для Lattice PAR делали? Или оценка по какому-нить Precision? Если PAR не делали, то эту оценку надо выкинуть на свалку.
Leka
Цитата(SM @ May 25 2009, 21:19) *
Вы для Lattice PAR делали? Или оценка по какому-нить Precision? Если PAR не делали, то эту оценку надо выкинуть на свалку.

PAR после Synplify (не Synplify-Pro), все настройки по умолчанию.
SM
Цитата(Leka @ May 25 2009, 21:51) *
PAR после Synplify (не Synplify-Pro), все настройки по умолчанию.

Тогда сорри. Просто сам когда-то проходил, что без PAR (isplever) оценки синтезаторов слишком оптимистичны, у синплифи еще более менее, а у Precision просто неадекватны.
Leka
Написал компилятор и упростил ядро - при большом регистровом файле на памяти развитая система адресации оказалась неэффективной. Новое ядро заметно меньше, и немного быстрее.
В железе пока не пробовал, тестирую в функциональном эмуляторе - скорость эмуляции ~2 МГц тактовой, можно и большие/сложные программы гонять. N-ферзей компилируется в ~100 слов (код + данные без учета 80 слов, занимаемых массивами), исполняется без ошибок (в эмуляторе). smile.gif

CODE
module queens
N, N2, count, poss, place, val, pos, pos1, i, j
arow:20, aleft:20, aright:20, aposs:20
begin
for N:=1 to 16
count := 0
j := 1
for i := 1 to N
j := j * 2
end
val := j - 1
pos := 1
arow[1] := 0
aleft[1] := 0
aright[1] := 0
j := val
N2 := N / 2
for i := 1 to N2
j := j / 2
end
aposs[1] := j
poss := aposs[1]
while pos <> 0
if poss <> 0
place := poss & - poss
poss := poss & ~ place
if pos == 1 and poss == 0 and N & 1 <> 0
count := count * 2
end
if pos <> N
pos1 := pos + 1
aposs[pos] := poss
arow[pos1] := arow[pos] | place
aleft[pos1] := (aleft[pos] | place) * 2
aright[pos1] := (aright[pos] | place) / 2
poss := ~ (arow[pos1] | aleft[pos1] | aright[pos1]) & val
pos := pos1
else
count := count + 1
end
else
pos := pos - 1
poss := aposs[pos]
end
end
if (N & 1) == 0
count := count * 2
end
out := count //вывод результата в порт
end
end



~Исходник на Си:
http://electronix.ru/forum/index.php?showt...st&p=516828
Leka
Посмотрел такты - при N=13 (ответ 73712) код выполняется за ~200 млн. тактов, те за ~2 сек на Спартане3(~100МГц). Аналогичный код на Delphi(консоль) ~2ГГц x86(AMD) считает
за ~0,04 сек, те в 50 раз быстрее(хотя тактовая больше в ~200 раз).
Leka
Цитата
хотя тактовая больше в ~200 раз

Sorry, в ~20 раз (2ГГц vs 100МГц).
Leka
Хотелось-бы посмотреть результаты компиляции(размер кода, листинг, если есть, и такты) для NIOS-2, MicroBlaze(EDK не установлен),и др софт-процессоров, для сравнения. Исходники N-ферзей можно отсюда:
http://electronix.ru/forum/index.php?showt...mp;#entry516828


На Си давно уже не пишу, не хотелось-бы только для сравнения ставить, разбираться... А Паскаля для софт-процессоров нет.
blackfin
Цитата(Leka @ Jun 11 2009, 02:13) *
Посмотрел такты - при N=13 (ответ 73712) код выполняется за ~200 млн. тактов, те за ~2 сек на Спартане3(~100МГц). Аналогичный код на Delphi(консоль) ~2ГГц x86(AMD) считает
за ~0,04 сек, те в 50 раз быстрее(хотя тактовая больше в ~200 раз).

На BF537-600 при N=13 код выполняется за ~213 млн. тактов, те за ~0,36 сек (CPU_CLOCK = 600МГц).

Исходники N-ферзей отсюда: http://electronix.ru/forum/index.php?showt...mp;#entry516828
Leka
Любопытно, для N-ферзей пока получается ~одинаковое количество тактов для двух архитектур:
1) BF: 1 такт на инструкцию, и 8 32-разрядных(или 16 16-разрядных) РОН + адресные, индексные, и др специальные регистры. Если не путаю.
2)моя текущая: 2..3 такта на инструкцию: 3 такта на load/store(a[i]:=b, b:=a[i]), 2 такта на все остальные, и 1К 32-разрядных РОН. В среднем для задач с массивами ~2.5 такта/инструкция, те ~40 MIPS для 100 МГц тактовой.
Leka
Мысли вслух... a[ i ] - фактически ((a)+(i)), поэтому a[ i ] эквивалентно i[ a ] (в безтиповом языке), a a[ i ][ j ][ k ] эквивалентно k[ j[ i[ a ] ] ]. Т.е. многомерный массив - частный случай одномерного. Кроме того, k[ j[ i[ a ] ] ] требует меньше инструкций и тактов, чем a[i*n+j*m+k].

Цитата(blackfin @ Jun 15 2009, 10:54) *
На BF537-600 при N=13 код выполняется за ~213 млн. тактов, те за ~0,36 сек (CPU_CLOCK = 600МГц).

Исходники N-ферзей отсюда: http://electronix.ru/forum/index.php?showt...mp;#entry516828

Наверно, надо подправить типы, чтобы не было операций приведения типов.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.