|
NIOSII - Странный глюк, тестирую модуль для SOPC и не понимаю :( |
|
|
|
Jul 13 2007, 14:36
|
Знающий
   
Группа: Свой
Сообщений: 518
Регистрация: 12-04-07
Из: Санкт-Петербург
Пользователь №: 26 997

|
Здравствуйте! Наконец-то, после долгого чтения мануалов я написал свой модуль для SOPC. Написал небольшую программку для NIOSII с целью протестировать модуль и столкнулся с очень странным для меня глюком. Сначала о модуле: Два порта, мастер и слейв. У слейва три регистра: CNTRL, STATUS и ADR. CNTRL: 0-ой бит – go. NIOSII выставляет этот бит, модуль начинает работать, на следующий такт бит автоматически сбрасываетя. STATUS: 2-ой бит – error, этот бит выставляется, если произошла ошибка. 1-ый бит – busy, выставлен пока модуль работает. 0-ой бит – done, выставлется когда работа модуля закончена. ADR – в этот регистр NIOSII записывает адрес. Работает модуль (по моей задумке, по крайней мере) так: выставляется бит go, логика модуля по этому биту считывает данные извне (свитчи на плате) и передает их мастер-порту. Мастерпорт, получив эти данные, записывает их по адресу из регистра ADR слейва, потом читает данные оттуда же. Если данные совпадают, то работа модуля заканчивается, если не совпадают, то выставляется бит error. Код программы для NIOSII: Код #include <stdlib.h> #include "alt_types.h" #include <stdio.h> #include <unistd.h> #include "system.h" #include "sys/alt_irq.h" #include "altera_avalon_pio_regs.h" #include "TestM_regs.h"
int ButFlag=0;
static void handle_button_interrupts(void* context, alt_u32 id) { *((alt_u8*)context)=1; IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUT_BASE, 0); }
static void init_button_pio() { IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUT_BASE, 0x1); IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUT_BASE, 0x0); alt_irq_register( BUT_IRQ, (void*) &ButFlag, handle_button_interrupts ); }
int main() { alt_u32 led=0xAAAA; init_button_pio();
while(1) { if (ButFlag){ IOWR_TESTM_ADR(TESTM_0_BASE,(int)&led); IOWR_TESTM_CTRL(TESTM_0_BASE,0x1); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! while (IORD_TESTM_STATUS(TESTM_0_BASE) & 0x1); IOWR_ALTERA_AVALON_PIO_DATA(LEDR_BASE,led); ButFlag=0; } } return 0; } Суть глюка: если прогу запустить как Run As, то LEDR (лампочки на плате) выводят 0xAAAA, а не то, что выставлено свичами. При этом бит ошибки не выставляется. Если запустить как Debug as NIOSII Hardware, то начинаются странности. Если на любой строчке до помеченной восклицательными знаками включительно сделать step (F5 или F6), то все прекрасно работает, выводится именно то, что на свичах. Если же с самого начала дебагинга сделать resume (F8) или же поставить брейкпоинт за помеченной строчкой, то прога ведет себя как при Run As. В чем суть глюка я понять не могу решительно. Адрес в ADR пишется, бит done выставляется, error – нет. Грешил на SDRAM, но проект делал на основе альтеровского примера ниоса для этой самой платы (Starter kit - cyclon 2). Попробовал снизить частоту со 100 до 50 – не помогло. На всякий случай прикладываю файлы головного модуля, модуля pll и reset. Подскажите, в чем может быть дело и где вообще искать решение? PS: Я еще только начинаю. Если кому-то вдруг будет не лень просмотреть мои верилоговские файлы и указать всякие ошибки перехода от C к Verilog? поправить стиль и т.п., то я буду очень благодарен!!! Прикладываю файлы: TESTM.v, TESTM_L.v, TESTM_M.v, TESTM_S.v - верилоговские файлы, описывающие сам модль. TestM_regs.h -файл с макросами для работы с модулем. sdram_pll.v и reset_delay.v - соответственно названию. NT.v - головной модуль проекта. Кстати, пытался добавить квартовский архив проекта, но "не имеете прав на добавление файла с разрешением" qar. Почему?
Прикрепленные файлы
TestM.v ( 1.54 килобайт )
Кол-во скачиваний: 58
TestM_L.v ( 759 байт )
Кол-во скачиваний: 48
TestM_M.v ( 3.06 килобайт )
Кол-во скачиваний: 71
TestM_S.v ( 2.27 килобайт )
Кол-во скачиваний: 59
NT.v ( 6.22 килобайт )
Кол-во скачиваний: 191
Reset_Delay.v ( 1.09 килобайт )
Кол-во скачиваний: 59
SDRAM_PLL.v ( 14.88 килобайт )
Кол-во скачиваний: 87
|
|
|
|
|
 |
Ответов
|
Jul 13 2007, 17:02
|
carpe manana
  
Группа: Свой
Сообщений: 321
Регистрация: 2-06-05
Пользователь №: 5 659

|
Ну во-первых, вы не приложили модуль syst. Во-вторых, лучше бы вы все файлы в одном архиве выложили рядом, чтобы разом скачать, для желающих. Самое главное - вы систему моделировали в моделсиме до синтеза? Программа небольшая, много времени не займет. Общие замечания: много лишнего верилога в регистрах, о чем вам должен был сказать синтезатор. пример: если вы записываете в регистр, достаточно просто написать Код if (write) my_reg <= writedata; и совсем не надо дописывать Код else my_reg <= my_reg; Читать тяжело. Сейчас я попробую посмотреть, что внутри, если получится - напишу. А может вы просто в тесте ошибку сделали, и проверяете while (IORD_TESTM_STATUS(TESTM_0_BASE) & 0x1); вместо while (IORD_TESTM_STATUS(TESTM_0_BASE) & 0x2); Но тогда у вас все висеть должно намертво. И еще я бы led объявил как volatile, но это вы должны были в дебагере в ассемблере увидеть, что чтениz не происходит.
|
|
|
|
|
Jul 13 2007, 17:24
|
Знающий
   
Группа: Свой
Сообщений: 518
Регистрация: 12-04-07
Из: Санкт-Петербург
Пользователь №: 26 997

|
Цитата(id_gene @ Jul 13 2007, 20:20)  Ну во-первых, вы не приложили модуль syst. Во-вторых, лучше бы вы все файлы в одном архиве выложили рядом, чтобы разом скачать, для желающих. Про syst.v не сообразил - прикладываю тут. Про "рядом" - тоже не сообразил. Сейчас выложу. Цитата(id_gene @ Jul 13 2007, 20:20)  Самое главное - вы систему моделировали в моделсиме до синтеза? Программа небольшая, много времени не займет. Нет.  Поскольку моделсимом пока не владею.  он в очереди на освоение. Цитата(id_gene @ Jul 13 2007, 20:20)  Общие замечания: много лишнего верилога в регистрах, о чем вам должен был сказать синтезатор. Спасибо. Синтезатор не ругался (варингами, по крайне мере). А он по умолчанию будет считать, что в противном случае значение не меняется? Это гуд, буду знать. Просто у альтеры в примере именно так сделано, а другого образца я не имею - у нас на работе никто верилогом не владеет.  Цитата(id_gene @ Jul 13 2007, 21:02)  А может вы просто в тесте ошибку сделали, и проверяете while (IORD_TESTM_STATUS(TESTM_0_BASE) & 0x1); Упс. Просто я в течение дня ковырялся и уходя с работы взял файлы впопыхах. Разумеется, там Код while (!(IORD_TESTM_STATUS(TESTM_0_BASE) & 0x1)) Цитата(id_gene @ Jul 13 2007, 21:02)  И еще я бы led объявил как volatile, но это вы должны были в дебагере в ассемблере увидеть, что чтениz не происходит. Хочу уточнить, какое именно чтение не происходит? Можете вкратце объяснить, как компилятор среагирует на volatile? Может, действительно тут дело? Хотя, тогда совершение одного шага в дебагере не должно делать код работающим, но делает. Что ввергает меня в шок.  Вот файлы: nt.qar - http://ifolder.ru/2658520 - квартуcoвский архив проекта. software - http://ifolder.ru/2658543 - архив програмного проекта (вдруг там в настройках syslib дело?). nt.rar - http://ifolder.ru/2658813 - архив всей папки с проектом, включая и модуль и софт.
Прикрепленные файлы
syst.v ( 343.28 килобайт )
Кол-во скачиваний: 95
|
|
|
|
|
Jul 13 2007, 18:04
|
carpe manana
  
Группа: Свой
Сообщений: 321
Регистрация: 2-06-05
Пользователь №: 5 659

|
Цитата(RHnd @ Jul 13 2007, 21:24)  Можете вкратце объяснить, как компилятор среагирует на volatile? Например вы читаете в цикле переменную, которая у вас меняется независимо от программы (аппаратным контроллером). int a = 0; while (a); Такую конструкцию компилятор оптимизирует и выкидыает, потому что не увидит в ней смысла, пока вы не объявите переменную как voltile. Тогда компилятор честно вставит чтение. Как раз ваш случай. Зачем процессору читать второй раз переменную led из памяти, если она уже хранится в стеке или в регистре. Успел покопаться только в вашем модуле, глобальных проблем в нем не вижу. Попробуйте в дебагере определить адрес переменной led и монитором памяти (он там внизу запрятан) посмотреть реальное содержание памяти в этом месте до и после программы. Общие замечания по верилогу: на мой взгляд, слишком много лишних регистров. В каких-то случаях это может быть оправдано, особенно, когда вам нужно все конвееризировать, и сильно не хватает скорости, или когда вы хотите избавиться от лишних переключений в нерабочем состоянии, но вся эта братия занимет ресурсы и межсоединения. Вот посмотрите, как я переписал ваш модуль. Вы к этому тоже со временем привыкнете, начнете понимать, что и где можно сократить. Я там все три модуля в один записал, чтобы файлы не плодить. Синхронизация внешних данных происходит всегда, а не только по стробу старта. Если это критично, то не надо там плодить еще одну машину состояний, просто поставьте два регистра после go_reg, и пользуйтесь ими. Чтение слейва синхронное, т.е. данные идут из регистра. можно урезать до асинхронного, выиграть такт, но удлиннить путь. Чтение контрольного регистра я выкинул, потому что полезной информации вы там не найдете. Машина состояний теперь имеет три состояния. Для увеличения скорости можно добавить еще одно состояние после чтения, чтобы принять прочитанные данные в регистр, и только потом сравнивать с сохраненным значением. Это разгрузит логику данных по чтению, и вы получите большую частоту. Все вышесказанное мое имхо и, возможно, слегка упрощено. Критика принимается. Ушел.
Прикрепленные файлы
my_sm.v ( 4.51 килобайт )
Кол-во скачиваний: 172
|
|
|
|
Сообщений в этой теме
RHnd NIOSII - Странный глюк Jul 13 2007, 14:36   RHnd Про volatile примерно понял. Вообще, по симптомавм... Jul 13 2007, 18:29    RHnd Цитата(RHnd @ Jul 13 2007, 22:29) Пошел с... Jul 13 2007, 20:10     id_gene Цитата(RHnd @ Jul 14 2007, 00:10) Помню, ... Jul 14 2007, 07:30      RHnd Цитата(id_gene @ Jul 14 2007, 11:30) Есть... Jul 14 2007, 17:21       RHnd Итак, дело оказалось в data cache. Сначала попробо... Jul 16 2007, 15:45 vetal что-то мне не совсем понятно.
1.Для задач общения ... Jul 16 2007, 16:17 RHnd Цитата(vetal @ Jul 16 2007, 20:17) 1.Для ... Jul 16 2007, 16:29  vetal Цитата(RHnd @ Jul 16 2007, 20:29) Т.е. мн... Jul 16 2007, 16:51   RHnd Спасибо, завтра попробую заменить макросы. Надеюсь... Jul 16 2007, 16:59 vetal Практически ничем, она подставляет в старший бит а... Jul 16 2007, 17:15 RHnd Цитата(vetal @ Jul 16 2007, 21:15) Практи... Jul 16 2007, 17:26 vetal Для чтения используйте макрос IORD_32DIRECT, для ч... Jul 16 2007, 17:31 RHnd Цитата(vetal @ Jul 16 2007, 21:31) Для чт... Jul 16 2007, 17:39 vetal Расположить там, где это вам нужно.
alt_u32 i;
i= ... Jul 16 2007, 18:03 RHnd Может таки проще будет uncached_malloc или remap_u... Jul 16 2007, 18:18 vetal По моему с макросами быстрее, т.к. нет лишней опер... Jul 16 2007, 18:23 RHnd Не, в документации-то я посмотрел. Я осмыслить пыт... Jul 16 2007, 18:44 vetal скорее всего так и есть. сейчас пока времени нет п... Jul 16 2007, 19:45 RHnd Итак, повозился сегодня с железкой - разобрался с ... Jul 17 2007, 15:41
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|