Перейти к содержанию
    

Доброго времени суток!

 

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

Остановился на лэттисовском Mico8, как наиболее доступном, как мне показалось.

 

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

Так ещё до кучи оказалось, что и отладка JTAG для Мико8 отсутствует как класс.

 

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

 

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

Стало немного понятно, как выглядит код и чем будет заниматься процессор.

 

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

Правда, без библиотек Cygwin эта утилита не запускается, пришлось закинуть её в директорию Cygwin... а причём тут последний, зачем он мне нужен под Windows, не понимаю?

Это что получается, компилятор и все его утилиты работают под эмулятором?

 

В общем, кривенько как то все выходит, может, я что-то не так делаю?

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

 

Ещё пара не очень приятных впечатлений.

У процессора отсутствуют коды команд нецикличного сдвига битов.

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

Неужели не хватило места для имплементации простейшего сдвига?

 

Стек прерываний почему то у процессора отдельный от общего стека. Причём нигде не нашёл задание его размера.

К примеру, при выборе средней модели памяти (64к) стек прерываний задаётся равным 512 байтам, и точка.

Кто так решил, и почему я должен отводить под него львиную долю памяти?

Слава богу, что есть галочка MICO_NO_INTERRUPTS, где вместе с прерываниями удаляется и этот стек... :cranky:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я мико8 не пользовал (пользовал мико32), так как мико8 под очень сильную экономию ресурсов и соотв. возможности очень ограничены.

поэтому отвечу "вообще", и похвально, что взяли латисовский софт проц, а не ниос или блейз привязанные к ксайлинсу или альтере

 

 

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

 

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

 

3) аппаратные стеки у минималистических процессоров - весьма частое дело (про микрочип pic12 pic14 pic16 слышали?).

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Offtop

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

Вот давайте без "религии"...

САПР для Алтеры и Ксайлинса под что был разработан изначально??? ну никак не под "в проф. сообществе не в среде опенсорсников" а под "голимую" "убогая система для офисных работников" итд итп.

"Мухи и котлеты по отдельности"

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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:

 

Раньше, судя по найденному в сети, для Мико8 существовал симулятор инструкций для проверки\отладки проекта.

Сейчас об этом нигде нет даже упоминания...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Весьма странное решение, на мой взгляд, не находите? :05:

Да нет, я тоже так делал. Это дает возможность заносить в стек что угодно и не думать о том, что там делается при возвратах... Например передавать данные в подпрограмму через стек.

Так же как в Форте... Стек данных и стек возвратов...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да нет, я тоже так делал. Это дает возможность заносить в стек что угодно и не думать о том, что там делается при возвратах... Например передавать данные в подпрограмму через стек.

Так же как в Форте... Стек данных и стек возвратов...

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

 

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

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

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

 

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

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

Для справки - у меня на сайте - статьи "Микропроцессор своими руками"...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Для справки - у меня на сайте - статьи "Микропроцессор своими руками"...

Не совсем.

Ещё раз.

 

В Мико8 три стека.

1. Аппаратный call stack - размер выбирается между 8, 16 и 32 байтами.

Используется для хранения адреса возврата из подпрограмм.

 

2. Стек данных, про который вы говорите.

С ним всё нормально - вершина находится на последнем адресе памяти данных и растёт вниз.

Размер задавать смысла нет - может занимать всю свободную память.

 

3. Стек прерываний irq_stack - выделенный стек прерываний, располагается в отдельном сегменте bss и размер прописан, похоже, жестко и зависит только от выбранной модели памяти.

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

 

Вот последний - это то, о чём я говорю.

Во первых, сама идея выделять для прерываний отдельный стек, для таких маленьких процессоров? Не находите это сомнительным?

И такая грубая реализация... :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не совсем.

Ещё раз.

 

В Мико8 три стека.

1. Аппаратный call stack - размер выбирается между 8, 16 и 32 байтами.

Используется для хранения адреса возврата из подпрограмм.

 

2. Стек данных, про который вы говорите.

С ним всё нормально - вершина находится на последнем адресе памяти данных и растёт вниз.

Размер задавать смысла нет - может занимать всю свободную память.

 

3. Стек прерываний irq_stack - выделенный стек прерываний, располагается в отдельном сегменте bss и размер прописан, похоже, жестко и зависит только от выбранной модели памяти.

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

 

Вот последний - это то, о чём я говорю.

Во первых, сама идея выделять для прерываний отдельный стек, для таких маленьких процессоров? Не находите это сомнительным?

И такая грубая реализация... :(

Реализация совсем не грубая, а аппаратно-зависимая...

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

Ничего сомнительного не вижу. Просто ПЛИС имеют свои особенности, только и всего...

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Реализация совсем не грубая, а аппаратно-зависимая...

Так причём тут аппаратно-зависимая?

Когда оба софтовых стека - общий и прерываний - находятся в одной и той же области памяти данных (scratchpad) и аппаратно реализованы абсолютно одинаково!

И латентность тут совсем не при чём...

 

Ничего сомнительного не вижу.

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

Весело, правда?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так причём тут аппаратно-зависимая?

Когда оба софтовых стека - общий и прерываний - находятся в одной и той же области памяти данных (scratchpad) и аппаратно реализованы абсолютно одинаково!

И латентность тут совсем не при чём...

Просто из любпытства посмотрите реализацию стеков на кристалле.

По поводу латентности. Какая будет латентность при чтении из памяти? 1 или 2 клока. Которые процессор должен ждать данные из стека...

А то что в "в одной и той же области памяти данных" так это не факт, это так дешифратор адресов может быть сделан, что память физически реализована по разному, а для софта - в одной области...

Поймите, это на ASIC, а FPGA и тут другие правила игры...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Просто из любпытства посмотрите реализацию стеков на кристалле.

По поводу латентности. Какая будет латентность при чтении из памяти? 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:

 

Вообще, то, о чём вы говорите, имеет, конечно, смысл на больших и навороченных процессорах типа Mico32, больших Кортексах и т.п.

Но примитивный восьмибитник - это из другой оперы, имхо.

Он вон даже опкода логического сдвига не имеет :)

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Память данных реализована на базе параметризированного модуля PMI pmi_ram_dq, это такая IP корка лэттис, насколько я понимаю:

 

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

 

Вообще, то, о чём вы говорите, имеет, конечно, смысл на больших и навороченных процессорах типа Mico32, больших Кортексах и т.п.

Но примитивный восьмибитник - это из другой оперы, имхо.

Он вон даже опкода логического сдвига не имеет :)

 

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

ОК! Тогда поищите на чем сделан стек возвратов... Если он на триггерах, то он в эту PMI pmi_ram_dq не попадает...

Ну так техподдержка же есть, можно им написать в европу...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не совсем.

3. Стек прерываний irq_stack - выделенный стек прерываний, располагается в отдельном сегменте bss и размер прописан, похоже, жестко и зависит только от выбранной модели памяти.

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

 

возможно, что это сделано для убыстрения входа в обработчик - надо с ISA разбираться

например, у кортексов-м сделали тоже отдельный стек (при том, что в классических арм-ах с fiq и lr все было гораздо лучше и проще, имхо) - я, например, вообще не понимаю нафига такая фигня нужна, но когда (на этом же форуме, например) кто-нибудь делает софт-проц со своей архитектурой и спрашивает совета - куча народу хочет иметь отдельный стек для irq

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ОК! Тогда поищите на чем сделан стек возвратов... Если он на триггерах, то он в эту PMI pmi_ram_dq не попадает...

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

Вернее всего на триггерах...

 

возможно, что это сделано для убыстрения входа в обработчик - надо с ISA разбираться

Вот вы тоже предполагаете, что для убыстрения.

Но я нигде не вижу механизма такого ускорения.

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

 

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

Скорость будет одна и та же.

 

кто-нибудь делает софт-проц со своей архитектурой и спрашивает совета - куча народу хочет иметь отдельный стек для irq

И единственное этому объяснение - ускорение входа в прерывание?

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

 

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

 

Просто в моём случае, когда вся ROM и RAM память у Mico8 будет внутренней, такая модель не имеет смысла и даже вредна.

И ничего с этим сделать нельзя :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...