Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Lattice Mico8 Soft Processor
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
sonycman
Доброго времени суток!

Недавно начал осваивать ПЛИС, и потихоньку добрался до имплементации простенького софт процессора.
Остановился на лэттисовском Mico8, как наиболее доступном, как мне показалось.

Несколько удивил некоторый аскетизм среды разработки, в том смысле, что по умолчанию я не нашёл возможности посмотреть получившийся код, который будет исполнять процессор.
Так ещё до кучи оказалось, что и отладка JTAG для Мико8 отсутствует как класс.

В общем - чёрный ящичек такой, никому не покажу, что и как smile3046.gif

Порылся в доках (с компилятором GCC я практически не знаком) и нашёл таки, как включить файл карты памяти линкера (опция -Map) и ассемблерных файлов, которые генерирует компилятор (опция -save-temps).
Стало немного понятно, как выглядит код и чем будет заниматься процессор.

Ещё научился запускать утилиту objdump.exe, с помощью которой можно дизассемблировать исполняемый файл проекта целиком и увидеть машинные коды полностью вместе с библиотечными функциями.
Правда, без библиотек Cygwin эта утилита не запускается, пришлось закинуть её в директорию Cygwin... а причём тут последний, зачем он мне нужен под Windows, не понимаю?
Это что получается, компилятор и все его утилиты работают под эмулятором?

В общем, кривенько как то все выходит, может, я что-то не так делаю?
Обычно в средах разработки все эти фишки включаются парой галочек в настройках графического интерфейса, и нет надобности лезть глубже...

Ещё пара не очень приятных впечатлений.
У процессора отсутствуют коды команд нецикличного сдвига битов.
Соостветственно для выполнения операций сдвига >> и << (даже на единичку) генерируются вызовы функций, где операция выполняется в цикле с помощью команд цикличного сдвига.
Неужели не хватило места для имплементации простейшего сдвига?

Стек прерываний почему то у процессора отдельный от общего стека. Причём нигде не нашёл задание его размера.
К примеру, при выборе средней модели памяти (64к) стек прерываний задаётся равным 512 байтам, и точка.
Кто так решил, и почему я должен отводить под него львиную долю памяти?
Слава богу, что есть галочка MICO_NO_INTERRUPTS, где вместе с прерываниями удаляется и этот стек... cranky.gif
yes
я мико8 не пользовал (пользовал мико32), так как мико8 под очень сильную экономию ресурсов и соотв. возможности очень ограничены.
поэтому отвечу "вообще", и похвально, что взяли латисовский софт проц, а не ниос или блейз привязанные к ксайлинсу или альтере


1) если интересуетесь процессорами, то нужно освоить софт для хоста - это линуксные утилиты gcc, gdb, llvm, qemu и т.д. так как виндовс это убогая система для офисных работников, то ни в проф. сообществе не в среде опенсорсников оно не используется и соответственно код для винды не разрабатывается (некоторые уже готовые продукты портируются). чтобы как-то скрасить убогую виндовзную жизнь были придуманы костыли типа cygwin, msys и т.п. но в родной среде все это работает гораздо лучше

2) также советую посмотреть opencores.org (например проект openrisc). а если VHDL не вызывает нервного тика, то LEON3 от GAISLER-а

3) аппаратные стеки у минималистических процессоров - весьма частое дело (про микрочип pic12 pic14 pic16 слышали?).
это делается чтобы ресурсы ПЛИС сэкономить. а отсутствие некоторых инструкций может вызвано отсутствием свободного места в формате команды - я так понимаю, что для тех сдвигов понадобится второй операнд на 3 бита? видимо, на этом авторы сэкономили - опять же таких сдвигов я так сразу ни в одном коммерческом 8-ми битнике не припомню
Alex77
Offtop
Цитата(yes @ Nov 6 2015, 14:41) *
1) если интересуетесь процессорами, то нужно освоить софт для хоста - это линуксные утилиты gcc, gdb, llvm, qemu и т.д. так как виндовс это убогая система для офисных работников, то ни в проф. сообществе не в среде опенсорсников оно не используется и соответственно код для винды не разрабатывается (некоторые уже готовые продукты портируются). чтобы как-то скрасить убогую виндовзную жизнь были придуманы костыли типа cygwin, msys и т.п. но в родной среде все это работает гораздо лучше

Вот давайте без "религии"...
САПР для Алтеры и Ксайлинса под что был разработан изначально??? ну никак не под "в проф. сообществе не в среде опенсорсников" а под "голимую" "убогая система для офисных работников" итд итп.
"Мухи и котлеты по отдельности"
sonycman
Цитата(yes @ Nov 6 2015, 15:41) *
1) если интересуетесь процессорами, то нужно освоить софт для хоста - это линуксные утилиты gcc, gdb, llvm, qemu и т.д. так как виндовс это убогая система для офисных работников, то ни в проф. сообществе не в среде опенсорсников оно не используется и соответственно код для винды не разрабатывается (некоторые уже готовые продукты портируются). чтобы как-то скрасить убогую виндовзную жизнь были придуманы костыли типа cygwin, msys и т.п. но в родной среде все это работает гораздо лучше

2) также советую посмотреть opencores.org (например проект openrisc). а если VHDL не вызывает нервного тика, то LEON3 от GAISLER-а

3) аппаратные стеки у минималистических процессоров - весьма частое дело (про микрочип pic12 pic14 pic16 слышали?).
это делается чтобы ресурсы ПЛИС сэкономить. а отсутствие некоторых инструкций может вызвано отсутствием свободного места в формате команды - я так понимаю, что для тех сдвигов понадобится второй операнд на 3 бита? видимо, на этом авторы сэкономили - опять же таких сдвигов я так сразу ни в одном коммерческом 8-ми битнике не припомню

1. Это да, придётся осваивать помаленьку, хотя не сказал бы, что различного софта под винду мало и есть какая-то необходимость ставить Линукс.
2. Ну пока что остановлюсь и поработаю на одном - Мико8. Но спасибо за совет.

3. По аппаратному стеку (call stack) вопросов нет - от у мико маленький и задаётся при конфигурации.

Там ещё существует два софтовых стека - общий (стандартный) для локальных переменных и для передачи параметров - устанавливается на последний адрес памяти данных.
И второй - irq stack - выделенный стек прерываний, располагается в отдельном сегменте bss и размер прописан, похоже, жестко и зависит только от выбранной модели памяти.
К примеру, для малой модели памяти (scratchpad memory = до 256 байт) он устанавливается в 32 байта, для средней и для большой моделей (до 64 килобайта или до 4 гигабайт) его размер выставляется 512 байт.

Весьма странное решение, на мой взгляд, не находите?
К примеру, не уложился я в 256 байт памяти данных - нужно 512. Опа - а компилятор взял, и отхватил ВСЕ 512 байт для этого самого irq_stack...
Весело, правда? 05.gif

Раньше, судя по найденному в сети, для Мико8 существовал симулятор инструкций для проверки\отладки проекта.
Сейчас об этом нигде нет даже упоминания...
iosifk
Цитата(sonycman @ Nov 8 2015, 11:51) *
Весьма странное решение, на мой взгляд, не находите? 05.gif

Да нет, я тоже так делал. Это дает возможность заносить в стек что угодно и не думать о том, что там делается при возвратах... Например передавать данные в подпрограмму через стек.
Так же как в Форте... Стек данных и стек возвратов...
sonycman
Цитата(iosifk @ Nov 8 2015, 13:11) *
Да нет, я тоже так делал. Это дает возможность заносить в стек что угодно и не думать о том, что там делается при возвратах... Например передавать данные в подпрограмму через стек.
Так же как в Форте... Стек данных и стек возвратов...

Вы, наверное, не поняли - для передачи данных служит простой stack, который растёт от вершины памяти данных.

Я же говорю про другой - выделенный стек прерываний irq_stack.

Это разные вещи.

И больше всего меня бесит, что влиять на размер irq_stack я никак не могу... sad.gif
iosifk
Цитата(sonycman @ Nov 8 2015, 12:19) *
Вы, наверное, не поняли - для передачи данных служит простой stack, который растёт от вершины памяти данных.

Я же говорю про другой - выделенный стек прерываний irq_stack.

Это разные вещи.

И больше всего меня бесит, что влиять на размер irq_stack я никак не могу... sad.gif

Так это же я и написал. Два стека. И можно данные передавать в подпрограммы или в прерывания через стек данных... А "влиять" не имеет смысла. Потому как такие процессоры мы делаем не для "вычислений", а как "стрелочники" для предварительной обработки данных и управления вводом-выводом...
Для справки - у меня на сайте - статьи "Микропроцессор своими руками"...
sonycman
Цитата(iosifk @ Nov 8 2015, 13:24) *
Так это же я и написал. Два стека. И можно данные передавать в подпрограммы или в прерывания через стек данных... А "влиять" не имеет смысла. Потому как такие процессоры мы делаем не для "вычислений", а как "стрелочники" для предварительной обработки данных и управления вводом-выводом...
Для справки - у меня на сайте - статьи "Микропроцессор своими руками"...

Не совсем.
Ещё раз.

В Мико8 три стека.
1. Аппаратный call stack - размер выбирается между 8, 16 и 32 байтами.
Используется для хранения адреса возврата из подпрограмм.

2. Стек данных, про который вы говорите.
С ним всё нормально - вершина находится на последнем адресе памяти данных и растёт вниз.
Размер задавать смысла нет - может занимать всю свободную память.

3. Стек прерываний irq_stack - выделенный стек прерываний, располагается в отдельном сегменте bss и размер прописан, похоже, жестко и зависит только от выбранной модели памяти.
К примеру, для малой модели памяти (scratchpad memory = до 256 байт) он устанавливается в 32 байта, для средней и для большой моделей (до 64 килобайта или до 4 гигабайт) его размер выставляется 512 байт.

Вот последний - это то, о чём я говорю.
Во первых, сама идея выделять для прерываний отдельный стек, для таких маленьких процессоров? Не находите это сомнительным?
И такая грубая реализация... sad.gif
iosifk
Цитата(sonycman @ Nov 8 2015, 12:30) *
Не совсем.
Ещё раз.

В Мико8 три стека.
1. Аппаратный call stack - размер выбирается между 8, 16 и 32 байтами.
Используется для хранения адреса возврата из подпрограмм.

2. Стек данных, про который вы говорите.
С ним всё нормально - вершина находится на последнем адресе памяти данных и растёт вниз.
Размер задавать смысла нет - может занимать всю свободную память.

3. Стек прерываний irq_stack - выделенный стек прерываний, располагается в отдельном сегменте bss и размер прописан, похоже, жестко и зависит только от выбранной модели памяти.
К примеру, для малой модели памяти (scratchpad memory = до 256 байт) он устанавливается в 32 байта, для средней и для большой моделей (до 64 килобайта или до 4 гигабайт) его размер выставляется 512 байт.

Вот последний - это то, о чём я говорю.
Во первых, сама идея выделять для прерываний отдельный стек, для таких маленьких процессоров? Не находите это сомнительным?
И такая грубая реализация... sad.gif

Реализация совсем не грубая, а аппаратно-зависимая...
Для того, чтобы с этим разобраться, посмотрите, какая память реализуется в этих ПЛИС. И смотрите на латентность. Если для вызова подпрограмм латентность не важна, то для возврата из прерываний - наверное важна, а потому там стек для возвратов скорее всего сделан на триггерах. А их и интерконнектов много не бывает. И я так и делал...
Ничего сомнительного не вижу. Просто ПЛИС имеют свои особенности, только и всего...

sonycman
Цитата(iosifk @ Nov 8 2015, 15:35) *
Реализация совсем не грубая, а аппаратно-зависимая...

Так причём тут аппаратно-зависимая?
Когда оба софтовых стека - общий и прерываний - находятся в одной и той же области памяти данных (scratchpad) и аппаратно реализованы абсолютно одинаково!
И латентность тут совсем не при чём...

Цитата(iosifk @ Nov 8 2015, 15:35) *
Ничего сомнительного не вижу.

Сомнительное здесь вот это, как пример: не уложился я в 256 байт памяти данных - нужно 512. Опа - а компилятор взял, и отхватил ВСЕ 512 байт для этого самого irq_stack...
Весело, правда?
iosifk
Цитата(sonycman @ Nov 8 2015, 16:43) *
Так причём тут аппаратно-зависимая?
Когда оба софтовых стека - общий и прерываний - находятся в одной и той же области памяти данных (scratchpad) и аппаратно реализованы абсолютно одинаково!
И латентность тут совсем не при чём...

Просто из любпытства посмотрите реализацию стеков на кристалле.
По поводу латентности. Какая будет латентность при чтении из памяти? 1 или 2 клока. Которые процессор должен ждать данные из стека...
А то что в "в одной и той же области памяти данных" так это не факт, это так дешифратор адресов может быть сделан, что память физически реализована по разному, а для софта - в одной области...
Поймите, это на ASIC, а FPGA и тут другие правила игры...
sonycman
Цитата(iosifk @ Nov 8 2015, 17:57) *
Просто из любпытства посмотрите реализацию стеков на кристалле.
По поводу латентности. Какая будет латентность при чтении из памяти? 1 или 2 клока. Которые процессор должен ждать данные из стека...
А то что в "в одной и той же области памяти данных" так это не факт, это так дешифратор адресов может быть сделан, что память физически реализована по разному, а для софта - в одной области...
Поймите, это на ASIC, а FPGA и тут другие правила игры...

Память данных реализована на базе параметризированного модуля PMI pmi_ram_dq, это такая IP корка лэттис, насколько я понимаю:
Код
     pmi_ram_dq
       #(
         .pmi_addr_depth       (SP_SIZE),
         .pmi_addr_width       (SP_AW),
         .pmi_data_width       (8),
         .pmi_regmode          ("noreg"),
         .pmi_gsr              ("disable"),
         .pmi_resetmode        ("async"),
         .pmi_init_file        (CFG_SP_INIT_FILE),
         .pmi_init_file_format (CFG_SP_INIT_FILE_FORMAT),
         .pmi_family           (LATTICE_FAMILY),
         .module_type          ("pmi_ram_dq")
         ) u1_scratchpad
         (
          // Outputs
          .Q        (internal_sp_dout),
          // Inputs
          .Data        (sp_wren ? sp_wdata : ext_dout),
          .Address            (sp_wren ? sp_waddr[SP_AW-1:0] : ext_addr[SP_AW-1:0]),
          .Clock        (clk_i),
          .ClockEn            (1'b1),
          .WE        ((ext_mem_wr | sp_wren) & ~external_sp),
          .Reset        (1'b0));


В результате после маппера вижу обычную RAM на базе двух EBR блоков, суммарный объём 2048 байт:
Код
/platform1_u/LM8/scratchpad_init.memspeedasyncdisablenoreg8112048:
    EBRs: 2
    RAM SLICEs: 0
    Logic SLICEs: 0
    PFU Registers: 0
    -Contains EBR pmi_ram_dqMnhscratchpad_initsadn8112048f9ce2e6_0_1_0:  TYPE=
         DP8KC,  Width_A= 4,  Depth_A= 2048,  REGMODE_A= NOREG,  REGMODE_B=
         NOREG,  RESETMODE= ASYNC,  ASYNC_RESET_RELEASE= SYNC,  WRITEMODE_A=
         NORMAL,  WRITEMODE_B= NORMAL,  GSR= ENABLED,  MEM_INIT_FILE=
         scratchpad_init.mem,  MEM_LPC_FILE=
         pmi_ram_dqMnhscratchpad_initsadn8112048f9ce2e6__PMIS__2048__8__8H
    -Contains EBR pmi_ram_dqMnhscratchpad_initsadn8112048f9ce2e6_0_0_1:  TYPE=
         DP8KC,  Width_A= 4,  Depth_A= 2048,  REGMODE_A= NOREG,  REGMODE_B=
         NOREG,  RESETMODE= ASYNC,  ASYNC_RESET_RELEASE= SYNC,  WRITEMODE_A=
         NORMAL,  WRITEMODE_B= NORMAL,  GSR= ENABLED,  MEM_INIT_FILE=
         scratchpad_init.mem,  MEM_LPC_FILE=
         pmi_ram_dqMnhscratchpad_initsadn8112048f9ce2e6__PMIS__2048__8__8H

Не думаю, что эта память имеет несколько регионов с различной латентностью... 05.gif

Вообще, то, о чём вы говорите, имеет, конечно, смысл на больших и навороченных процессорах типа Mico32, больших Кортексах и т.п.
Но примитивный восьмибитник - это из другой оперы, имхо.
Он вон даже опкода логического сдвига не имеет sm.gif

Жаль, что у Лэттиса нет форума. Общаются только с корпоративными клиентами... sad.gif
iosifk
Цитата(sonycman @ Nov 8 2015, 18:10) *
Память данных реализована на базе параметризированного модуля PMI pmi_ram_dq, это такая IP корка лэттис, насколько я понимаю:

Не думаю, что эта память имеет несколько регионов с различной латентностью... 05.gif

Вообще, то, о чём вы говорите, имеет, конечно, смысл на больших и навороченных процессорах типа Mico32, больших Кортексах и т.п.
Но примитивный восьмибитник - это из другой оперы, имхо.
Он вон даже опкода логического сдвига не имеет sm.gif

Жаль, что у Лэттиса нет форума. Общаются только с корпоративными клиентами... sad.gif

ОК! Тогда поищите на чем сделан стек возвратов... Если он на триггерах, то он в эту PMI pmi_ram_dq не попадает...
Ну так техподдержка же есть, можно им написать в европу...
yes
Цитата(sonycman @ Nov 8 2015, 12:30) *
Не совсем.
3. Стек прерываний irq_stack - выделенный стек прерываний, располагается в отдельном сегменте bss и размер прописан, похоже, жестко и зависит только от выбранной модели памяти.
К примеру, для малой модели памяти (scratchpad memory = до 256 байт) он устанавливается в 32 байта, для средней и для большой моделей (до 64 килобайта или до 4 гигабайт) его размер выставляется 512 байт.


возможно, что это сделано для убыстрения входа в обработчик - надо с ISA разбираться
например, у кортексов-м сделали тоже отдельный стек (при том, что в классических арм-ах с fiq и lr все было гораздо лучше и проще, имхо) - я, например, вообще не понимаю нафига такая фигня нужна, но когда (на этом же форуме, например) кто-нибудь делает софт-проц со своей архитектурой и спрашивает совета - куча народу хочет иметь отдельный стек для irq
sonycman
Цитата(iosifk @ Nov 8 2015, 19:25) *
ОК! Тогда поищите на чем сделан стек возвратов... Если он на триггерах, то он в эту PMI pmi_ram_dq не попадает...

Этот отдельный, однозначно, т.к. он аппаратный и маленький.
Вернее всего на триггерах...

Цитата(yes @ Nov 9 2015, 15:16) *
возможно, что это сделано для убыстрения входа в обработчик - надо с ISA разбираться

Вот вы тоже предполагаете, что для убыстрения.
Но я нигде не вижу механизма такого ускорения.
Я вижу простую память данных, совершенно однородную по структуре, в которой по произвольным адресам будут данные и оба стека.

Процессору совершенно побоку, по какому адресу и по какому указателю сохранять контекст в эту область памяти при входе в прерывание.
Скорость будет одна и та же.

Цитата(yes @ Nov 9 2015, 15:16) *
кто-нибудь делает софт-проц со своей архитектурой и спрашивает совета - куча народу хочет иметь отдельный стек для irq

И единственное этому объяснение - ускорение входа в прерывание?
К примеру, если основная память внешняя и медленная, а стек расположить на внутренней и быстрой?

Или такая модель чем то удобнее с точки зрения распределения памяти?

Просто в моём случае, когда вся ROM и RAM память у Mico8 будет внутренней, такая модель не имеет смысла и даже вредна.
И ничего с этим сделать нельзя sad.gif
yes
ну кроме скорости может быть надежность - то есть эта память всегда есть и всегда есть место, то есть стек оверфлоу не происходит.
я не понимаю, зачем это может понадобится в 8-ми битнике (а с мико8 мне лень разбираться), но в 32-х битных, с юзерским стеком могут быть проблемы (например, выравнивание), или же в многозадачке, когда каждая задача имеет очень маленький стек, резервировать память в стеке каждой задаче для прерывания - расход памяти.
вобщем причин может быть много, конкретно для мико8 - не знаю
sonycman
Да, после красивого ARM кода компиляторов под кортексы местный GNUтый компилер выглядит весьма деревянным.

А именно - работа с регистром страниц памяти.
Если размер памяти scratchpad (то есть оперативки) не превышает 256 байт - то есть одной странички - то всё в порядке, переключать page регистр не надо.
Но если больше 256 байт - то появляется page регистр(ы), состояние которого компилятором не отслеживается, а просто тупо переписывается каждый раз при обращении к памяти:
Код
    movi    r13,_hi(16)
    export    r20,_lo(16)
    movi    r13,_hi(17)
    export    r22,_lo(17)
    movi    r13,_hi(17)
    export    r14,_lo(17)
    movi    r13,_hi(11)
    import    r0,_lo(11)

r13 - регистр страницы.
Совершенно лишние три команды, упорно запихивающие одно и то же значение...
Оптимизация Os.

Это здорово увеличивает размер кода, что вообще-то противоречит самой идее компактного процессора.

Неужели так трудно было допилить компилер? 01.gif

ЗЫ: что-то уже хочется плисину с нормальным хардовым армом, для которого можно писать оптимальный код в кейле или иаре, а не париться с недопроцессорами и такими-же недокомпиляторами для них.
Мелкие кортексы есть у Microsemi, но их или не достать, или дорогие, собаки... sad.gif
sonycman
С другой стороны сегодня посмотрел по тактам выполнение программы и был приятно удивлён весьма шустрым выполнением команд.
Основная масса выполняется за 2 такта, включая команды переходов и даже вызовов подпрограмм(!).
Очень удивился насчёт переходов - вот что значит простой процессор sm.gif

Команды по работе с ОЗУ выполняются 3 такта, тоже достаточно быстро.

И только обращение к периферии (export/import) идёт 5 тактов.

В общем - очень шустрый восьмибитник sm.gif
Ему бы ещё вылизанный компилятор...
Doka
коль скоро в этой теме собрались корифеи lm8, спрошу и я:

1. вот распаковал я rpm'ку diamond_3_8-lm_x64-115-3-x86_64-linux.rpm
нашел папку с тулчейнами под lm8 & lm32, а сам lm8 (verilog) нигде не лежит в дистрибутиве?
только из красивого GUI генерится? и что генерится - нетлист или захардкоженный RTL?

2. кто-то пробовал этот lm8 синтезить под отличные от поддерживаемых diamond семейства - например на кристалы серии iCE или того хуже под Xilinx?


Цитата(sonycman @ Mar 27 2016, 18:21) *
В общем - очень шустрый восьмибитник sm.gif
Ему бы ещё вылизанный компилятор...

FYI, компилятор (тулчейн) похоже не обновлялся с октября 2011 года(((
faa
Цитата(Doka @ Nov 29 2016, 17:56) *
FYI, компилятор (тулчейн) похоже не обновлялся с октября 2011 года(((


Крайний gcc-4.4.3 (с патчем для lm8) от января 2010 года.
Свежее не видел.

Для lm32 можно собрать посвежее. Работает.
Можно посмотреть на ohwr.org в "Белом кролике" - церновцы lm32 используют в свитче и оконечниках, причем на Xilinx-е.
gk2
В 3.6 было здесь:

/usr/local/latticemicosystem/3.6_x64/lm/micosystem/components/lm8/rtl/
Doka
Цитата(faa @ Nov 30 2016, 09:18) *
Для lm32 можно собрать посвежее. Работает.

не, интересует только Mico8, как замена хитрому FSM
lm32 - это как из пушки по воробьям.



Цитата(gk2 @ Nov 30 2016, 13:00) *
В 3.6 было здесь:

/usr/local/latticemicosystem/3.6_x64/lm/micosystem/components/lm8/rtl/


спасибо, нашёл.
в 3.8 тут:

latticemicosystem/3.8_x64/micosystem/components/lm8/rtl/verilog/
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.