|
Отдельное АЛУ, Простенькое АЛУ, отдельное от ядра для своих нужд |
|
|
|
May 19 2014, 11:39
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Всем привет!
Понадобилось чтобы для прибора управления (шевелит ножками, крутит моторами, опрашивает датчики) пользователь мог писать свои микропрограмки. Сначала в приборе был свой специализированный автомат который разбирал входной поток команд и превращал его в управляющие воздействия. Поток шел через FIFO, но сейчас захотели чтобы можно было делать циклы, и я так понимаю на этом не остановимся.
Потому вместо наращивания набора команд спец автомата думаю сразу забабахать полноценное АЛУ, выделить пользователю регистров и памяти, и путь пишет программы в машинных кодах. В целом этот велосипед уже изобрел, но хочется поглядеть-послушать на то как еще это делают. Интересует даже не столько сама реализация, а больше сколько надо команд, как сделано сравнение, как сделаны команды перехода, маскирование. Сколько надо регистров для того чтобы было комфортно и не много и так далее...
В общем я тут больше посоветоваться и послушать что умные люди скажут. Готовые ядра ставить не предлагать, это принципиально должен быть отдельный блок, который я защищу от пользовательского произвола как смогу. А любые мысли по поводу того как бы вы это сделали приветствуются!
|
|
|
|
|
 |
Ответов
|
May 20 2014, 12:47
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Ну что же, будет оно все вот так.
Все регистры управления периферией у меня 32 битные, и проц. будет таким. Программа будет лежать в 2 портовой памяти на Брамах и для процессора будет только для чтения
Оперативной памяти пользователю достанется 4, 32 битных регистра, совмещенных в единое пространство со всеми управляющими регистрами. Будет 3 специализированных регистра, в том же пространстве памяти 1. это счетчик команд, фактически адрес очередной выбираемой из памяти команды 2. это таймер, который сбрасывается в ноль по спец команде записи в управляющие регистры, а дальше считает каждый клок вперед 3. это аккумулятор куда попадают все результаты операций сложения, вычитания, логического И и ИЛИ, этот регистр будет 33 битным, чтобы просекать переполнение, к этому регистру будут 4 флага, аккумулятор == 0, больше 0, меньше 0, переполнение. Все входные сигналы на схему собраны в 32 битный регистр в том же пространстве, для этого регистра предусмотрены прерывания
Основные операции, которых будет большинство это задание констант и ожидание заданное время, потому память программы будет 8192 слова по 64 бита. И все команды будут иметь фиксированный вид 32 бита - код операции и адреса операндов, и 32 бита константа. Удобно выжать 16536 слов памяти в 48 бит не удалось, а память хочется иметь цикличную, чтобы после последнего адреса, она прыгала на 0, потому решил не жаться и сделать 8192 слова по 64 бита.
в целом команды будут иметь общий вид [code] [addr1][addr2][constant] code - это код addr1, addr2 - это адреса данных/операндов: 0 - константа из команды, N - регистр из общего адресного пространства
команды будут 0. NOP 1. задать значение в addr1 из addr2 2. задать значение в периферию из addr2, со сбросом таймера (тут на самом деле серия команд, которые меняют комбинации регистров управления, но все они делают одно, задают значения и сбрасывают таймер) 3. ожидать пока таймер не превысит значение из addr2 4. вычесть, прибавить, ИЛИ, И данных из addr1 c данными из addr2, результат в аккумулятор 5. выполнить переход по данным из addr2, если выставлен флаг регистра аккумулятора (какой флаг выбирается маской)
после каждой команды кроме команд перехода будет выбираться следующая команда, неизвестные или неправильные команды будут останавливать процесс выбора команд и выставлять флаг ошибки команды, который отображается в регистре входных сигналов.
Прерывания: будут 4 прерывания, все они работают с регистром входных сигналов, для них можно задать 1. полярность входа (какой уровень активный) 2. маску (какие сигналы генерируют прерывание) 3. активный уровень прерывания, 0 или 1 вызывает прерывание 4. адрес перехода, вектор прерывания фактически 5. разрешение прерывания
прерывание <= |((вход ^ полярность) & маска);
Если прерывание разрешено и его значение равно активному уровню, схема переходит по заданному вектору, и снимает разрешение всех прерываний. Адрес с которого совершен переход сохраняется в спец регистре.
Архитектура в целом не предполагает возврата к выполнению прошлой программы если случилось прерывание, но ручками это можно сделать если очень хочется, даже можно сделать вложенные прерывания, сохраняя адрес возврата в регистры общего назначения
С прерывания не все гладко на самом деле, возможно стоит добавить команду выход из прерывания в которой будет возвращаться разрешения прерываний. Потому что иначе можно разрешить прерывание перед возвращением, и если оно уже стоит улететь в новое прерывание, с адресом возврата старого прерывания, а не основной программы.
В текущей архитектуре это не нужно, но наверное стоит проработать....
|
|
|
|
|
May 20 2014, 15:08
|
Знающий
   
Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515

|
А я сделал специализированный процессор для несложных вычислений, используется для ПИД регуляторов с обвязкой и всего такого. Система команд похожа на PIC, одноадресная, команда 10 бит, данные 20(но могут быть любой длины, при желании). 64 адреса под порты, константы и переменные(регистры), которые можно расположить в любом соотношении. команды загрузки, сохранения, сложения, вычитания, минимума, максимума, умножения, деления, корня, сдвига на произвольную константу, переходы безусловный и условный по знаку аккумулятора. Фиксированная точка стоит перед первым значащим битом, то есть диапазон значений для умножения, деления, корня считается от -1.0 до 1.0-2^-19. Частота 200-250МГц на ECP2, весит около 700 ЛУТ(из них примерно 300 модули умножения, деления, корня), один такт на инструкцию, простой трёхступенчатый конвеер. По соотношению производительности к "весу" трудно найти что-либо подобное. Ассемблер написал на TCL, всего 248 строк, всё очень просто, и макросы на TCL удобно делать, чего очень не хватало в своё время на MASM:). Вместо пихания временных значений в регистры по номерам используется директива temp, которая связывает имя временной переменной с первым свободным регистром, а end_temp - освобождает. Такого, вроде, ни в одном ассемблере нет, а очень удобная штука. Чтобы закодить 150 инструкций, Си как бы и не особенно нужен. Вот ассемблер, сам процессор тоже могу выложить, если интересно, он не секретный.
cc.7z ( 2.57 килобайт )
Кол-во скачиваний: 55И примерчик кода: CODE constr cur_filter_cf.a1 {cur_filter_cf.a1} constr cur_filter_cf.a2 {cur_filter_cf.a2} constr cur_filter_cf.b0 {cur_filter_cf.b0} constr cur_filter_cf.b1 {cur_filter_cf.b1} constr cur_filter_cf.b2 {cur_filter_cf.b2} var cur_filter_st.w2 cur_filter_st.w1
proc lpf_step {st cf} { locals t t1 temp $t $t1 shl $cf.pre_scale ;#di * 2.0**pre_scale ld $st.w2 st $t1 mul $cf.a2 ;#w2*a2 ld $st.w1 st $t mul $cf.a1 ;#w1*a1 add $t shl $cf.rec_scale add $t1 ;#w1*a1+w2*a2+di ld $st.w2 st $t1 mul $cf.b2 ld $st.w1 st $t st $st.w2 mul $cf.b1 add $t ld $t1 st $t st $st.w1 mul $cf.b0 add $t end_temp $t $t1 }
|
|
|
|
|
May 22 2014, 10:12
|
Знающий
   
Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515

|
Цитата(Serhiy_UA @ May 21 2014, 10:00)  В части temp - действительно что-то новое. Это взамен дополнительного аккумулятора, стека (LIFO) или очереди (FIFO)? Как узнать в temp, что регистр свободный? Как загружаете программу в ПЛИС? Какие алгоритмы деления и извлечения корня? temp используется для организации локального стека, но этим не ограничивается. Ассемблер хранит битовую маску свободных регистров. Ассемблер создаёт код модуля на VHDL, который уже включает в себя экземпляр процессора, код и константы к нему. Деление и корень обыкновенные многоцикловые в столбик  . Модуль для корня я уже тут выкладывал в соответствующей теме. В делении(как и в корне, впрочем) используется non-restoring алгоритм, остаток может быть отрицательным, и в следующем такте делитель к нему прибавляется, а не вычитается. Если регистров для temp не хватает, выдаётся ошибка.
|
|
|
|
|
May 23 2014, 01:17
|
Знающий
   
Группа: Свой
Сообщений: 721
Регистрация: 23-10-08
Из: next to Odessa
Пользователь №: 41 112

|
к Timmy Спасибо за информацию. Не совсем понял, ассемблер генерирует код на HDL, который затем можно включать в прошивку ПЛИС? Тоже, что-то новое!
А temp как локальный стек - это удобно.
По делению и корню столбиком без восстановления остатка все понятно, хотя здесь можно использовать и матричный (аппаратный) метод для ускорения, я предпочитаю его. Просто мне показалось, что для этих операций Вы использовали умножители.
Уточните, если не сложно, как и из чего выполняете загрузку конфигурации ПЛИС и программы для процессора? Используется ли для этого отдельное ядро, и как оно запускается?
И еще, почему выбрали Lattice, при более популярных Altera и Xilinx, в чем преимущество?
|
|
|
|
|
May 28 2014, 04:23
|
Знающий
   
Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515

|
Цитата(Serhiy_UA @ May 23 2014, 09:27)  Не совсем понял, ассемблер генерирует код на HDL, который затем можно включать в прошивку ПЛИС? Тоже, что-то новое!
По делению и корню столбиком без восстановления остатка все понятно, хотя здесь можно использовать и матричный (аппаратный) метод для ускорения, я предпочитаю его. Просто мне показалось, что для этих операций Вы использовали умножители.
Уточните, если не сложно, как и из чего выполняете загрузку конфигурации ПЛИС и программы для процессора? Используется ли для этого отдельное ядро, и как оно запускается?
И еще, почему выбрали Lattice, при более популярных Altera и Xilinx, в чем преимущество? Да, ассемблер генерирует wrapper к процессору в виде исходника VHDL модуля, который содержит в себе код программы, константы, отладочную информацию для симуляции, всякие параметры, и инстанциацию процессора. Загрузка конфигурации производится из SPI flash, как обычно, а программа для процессора хранится в ROM на LUT-ах(она короткая, 200 инструкций в текущем проекте). Lattice выбрали, потому что в low-end чипах есть поддержка DDR2 SDRAM с широкой шиной данных, приличная защита прошивки, чтение синхронных данных со скоростью до 800Mb/s. С использованием аппаратного 36-битного умножителя у меня есть другой процессор попроще, который умеет только умножать и складывать, зато параллельно и за один такт с использованием конвейера, рабочая частота где-то тоже 250МГц, ограничена умножителем. Этот процессор для обсчёта нестандартных рекурсивных фильтров.
|
|
|
|
Сообщений в этой теме
Golikov A. Отдельное АЛУ May 19 2014, 11:39 Alex77 Цитата(Golikov A. @ May 19 2014, 19:49) В... May 19 2014, 14:13 Lmx2315 ..в приложении самоделка ни на что не претендующая... May 19 2014, 15:06  Pavia Для Lmx2315:
Цитата(Lmx2315 @ May 19 2014, 23... May 19 2014, 22:19   Serhiy_UA Тема интересная, но в конечном итоге все может увя... May 20 2014, 01:14 alman Цитата(Golikov A. @ May 19 2014, 19:49) В... May 19 2014, 16:42 RobFPGA Приветствую!
Цитата(alman @ May 19 2014,... May 19 2014, 17:22  alman Цитата(RobFPGA @ May 20 2014, 01:32) А см... May 19 2014, 18:54   iosifk Цитата(alman @ May 20 2014, 03:04) Если к... May 20 2014, 00:58    alman Цитата(iosifk @ May 20 2014, 09:08) Проце... May 20 2014, 04:29    RobFPGA Приветствую!
Цитата(iosifk @ May 20 2014... May 20 2014, 05:16 Golikov A. Спасибо ответившим. Спасибо за пример, обязательно... May 20 2014, 01:06 Golikov A. Большой ФСМ - однозначно определен, и придется его... May 20 2014, 01:53 RobFPGA Приветствую!
Цитата(Golikov A. @ May 20 ... May 20 2014, 03:49 Golikov A. В целом я определился с тем какого вида я хочу пос... May 20 2014, 07:23 Serhiy_UA Цитата(Golikov A. @ May 20 2014, 14:33) Е... May 20 2014, 08:00  Кнкн Цитата(Timmy @ May 20 2014, 22:18) сам пр... May 21 2014, 02:16 Golikov A. Забавный процессор, и всего 700 лутиков.
С temp пр... May 21 2014, 02:58 Serhiy_UA Цитата(Golikov A. @ May 21 2014, 11:08) В... May 21 2014, 03:43 iosifk Цитата(Golikov A. @ May 21 2014, 11:08) Т... May 21 2014, 10:38 Golikov A. ну так интерпретатор и есть процессор%). Череда у... May 21 2014, 03:51 RobFPGA Приветствую!
Цитата(Golikov A. @ May 21 ... May 21 2014, 04:35 Alex77 Цитата(Golikov A. @ May 21 2014, 12:01) н... May 21 2014, 05:40 Golikov A. 1 микросекунда на команду, при 100 МГц основном кл... May 21 2014, 05:30 RobFPGA Приветствую!
Цитата(Golikov A. @ May 21 ... May 21 2014, 05:36 Golikov A. я может не внимательно читал, но не увидел там ком... May 21 2014, 07:13 Alex77 Цитата(Golikov A. @ May 21 2014, 15:23) я... May 21 2014, 07:18 Golikov A. понятно, спасиб...
но я уже успел полюбить свой в... May 21 2014, 07:31 Golikov A. если нету ПИДа, он сам не появиться. А если есть п... May 21 2014, 13:18
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|