PSP 0 5 ноября, 2007 Опубликовано 5 ноября, 2007 · Жалоба Тут, в ветке обсуждения 8-ми битных ядер, я упомянул о баге в LatticeMico8 и получил предложение рассказать о нем (баге) подробнее. Дальше речь только о Verilog реализации, как там в VHDL - не знаю. Сразу скажу, что если не использовать прерывания, то ядро работает прекрасно. Система команд полноценная, два такта на команду, в плотно забитом (90%) FPGA работает на 50 МГц. Теперь о грустном, в чем проявляется проблема. Если сигнал прерывания приходит во время выполнения "простой" команды, т.е. без передачи управления (не меняется PC), то все нормально: сохранение адрес возврата в стеке, переход по вектору и возврат. Но если мы попадаем на команду перехода, то происходит следующее. В первом такте сохраняется адреса возврата в стеке, а во втором внутренний автомат принимает решение - раз сейчас переход, то прерывание не выполняем. Похоже, по начальной мысли автора, должна была быть только задержка прерывания на время команды перехода, но из-за ошибки в реализации происходит наращивание стека без его освобождения. В свое время я попытался поправить это, но с наскоку не получилось, в одном месте поправил, в другом сломал. Там в коде не злоупотребляют комментариями, хорошо хоть обфускатор не использовали, а потом и времени не было. Вот исходный текст примера программы, которая была использована при описании бага для техподдержки Lattice: # interrupt vector ........b..........int_handler # start ........movi.....r0,5 ........seti main_loop: ........subi.....r0,1 ........bnz......main_loop ........clri stop: ........b..........stop # end int_handler: ........iret На входе прерываний постоянный запрос. Успевает пройти нормальное прерывание между командами "seti" (разрешение прерываний) и "subi" (декремент). Затем, пока крутится цикл, прерывания не проходят вообще, но наращивается стек, а в конце "clri" запрещает прерывания. К багрепорту прилагался проект в Modelsim, и даже скриншот происходящего. Ошибка была признана, но не исправлена до сих пор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Doka 4 5 ноября, 2007 Опубликовано 5 ноября, 2007 · Жалоба спасибо за быструю реакцию. :beer: PS: для сохранения в исходном коде табуляций и отступов используйте таг [соdе] (иконка меню - #). Это намного проще. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vetal 0 6 ноября, 2007 Опубликовано 6 ноября, 2007 · Жалоба У них там большая проблема с прерываниями :) Я еще в феврале 2006 года посылал баг репорт CASE_ID_NUM: C72764-022706 на этот счет и мне тоже сказали что они исправят :)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
PSP 0 6 ноября, 2007 Опубликовано 6 ноября, 2007 (изменено) · Жалоба Значит Вы меня опередили, я с ними переписывался в сентябре 2006-го. Любопытно, что они сделали вид, что первый раз об этом слышат, если, правда, Вы писали им о том же баге. Изменено 6 ноября, 2007 пользователем PSP Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vetal 0 6 ноября, 2007 Опубликовано 6 ноября, 2007 · Жалоба баг из той же оперы...точно не помню...если прерывание попадало на инструкцию перехода - проц крутился в ней Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vladz 0 8 ноября, 2007 Опубликовано 8 ноября, 2007 · Жалоба Пара проблем на которые я наткнулся в версии 2.4: 1. Из-за того что в ассемблере от латтиса нельзя использовать константы пришлось попробовать AS Assembler by Alfred Arnold. Оказалось что в описании инструкций коды "RORC Rd, Rb" и "ROL Rd, Rb" перепутаны, и в результате AS Assembler генерит правильный по документации, но нерабочий код. 2. Команды clrc и setc вообще не работают. За флаг переноса отвечает код: // Carry flag always @(posedge clk or negedge rst_n) begin if (!rst_n) carry_flag <= 1'b0; else case (1'b1) /* synthesis parallel_case */ clrc : carry_flag <= 1'b0; setc : carry_flag <= 1'b1; update_c : carry_flag <= cout_alu; iret : carry_flag <= pushed_carry; default : carry_flag <= carry_flag; endcase end В Моделсиме видно, что сигнал update_c активен одновременно с clrc или setc в зависимости от команды. Synplify решает, что update_c все же имеет больший приоритет и в железе флаг переноса не меняется. Похоже, что флаг Z обрабатывается аналогично. Интересно, что гугль ничего не знает о багах в мико8, или просто этот контроллер никто не использует? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
PSP 0 8 ноября, 2007 Опубликовано 8 ноября, 2007 · Жалоба AS Assembler by Alfred Arnold тоже пробовал, но прогнав тестовый пример из поставки Mico8, сразу наткнулся на ошибку и больше к нему не возвращался. А по поводу команд clrc и setc ничего плохого сказать не могу. Специально посмотрел свои исходники - используются эти команды для возврата результата функции и все работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vladz 0 8 ноября, 2007 Опубликовано 8 ноября, 2007 · Жалоба А по поводу команд clrc и setc ничего плохого сказать не могу. Специально посмотрел свои исходники - используются эти команды для возврата результата функции и все работает. Предполагаю, что результат может зависеть от синтезатора и используемого семейства. Я изпользовал Synplify и ECP2. А у Вас на чем все это работает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
PSP 0 9 ноября, 2007 Опубликовано 9 ноября, 2007 · Жалоба Synplify Pro и XP. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться