|
Асинхронная запись данных в ПЛИС, глючит иногда |
|
|
|
Nov 2 2009, 23:40
|
Частый гость
 
Группа: Участник
Сообщений: 78
Регистрация: 12-10-09
Пользователь №: 52 902

|
требуется считывать данные из шины в ПЛИС (запись в регистры аппаратуры-ПЛИС) CS - выбор кристалла ПЛИС (активный 0) WE - разрешение записи (активный 0) D0..D7 - данные A0 - адрес (при обращении к регистрам должен быть 1, иначе увеличение адреса памяти (прикручена к ПЛИС)) написал такое: Код process(CS,WE,A0) begin if CS='0' then -- если CS=0 активен if rising_edge(WE) then --если пришёл фронт WE данные должны защёлкнуться if A0='1' then --если регистры Register(7 downto 0)<=D(7 downto 0); else -- если не регистры VRAM_Address<=VRAM_Address+1; -- увеличиваем адрес памяти end if; end if; end if; end process; Оно работает, но иногда глючит... Шина хоста (со стороны CPU) имитируется портами PIOA контроллера AT91SAM7S64. Связаны ли глюки с тем, что имитировать шину портами нежелательно из-за выбросов ? или не так делаю?
Сообщение отредактировал penauch - Nov 2 2009, 23:41
|
|
|
|
|
Nov 3 2009, 00:05
|
iBuilder©
   
Группа: Свой
Сообщений: 519
Регистрация: 14-07-04
Из: Минск
Пользователь №: 322

|
Цитата(penauch @ Nov 3 2009, 02:40)  требуется считывать данные из шины в ПЛИС (запись в регистры аппаратуры-ПЛИС)
Оно работает, но иногда глючит...
или не так делаю? А что дальше с данными делаете? И в чём глюки? Как осуществляете синхронизацию асинхронной и синхронной части проекта?
|
|
|
|
|
Nov 3 2009, 00:09
|
Знающий
   
Группа: Свой
Сообщений: 845
Регистрация: 18-10-04
Из: Pereslavl-Zalessky, Russian Federation
Пользователь №: 905

|
Цитата(penauch @ Nov 3 2009, 02:40)  CS - выбор кристалла ПЛИС (активный 0) WE - разрешение записи (активный 0) D0..D7 - данные A0 - адрес (при обращении к регистрам должен быть 1, иначе увеличение адреса памяти (прикручена к ПЛИС)) Сколько времени проходит между готовностью данных, адреса и CS до фронта WE ? Подозреваю, что к приходу фронта WE адрес и данные еще или уже не действительны. Отражено ли это время в файле с констрейнами для статического анализа таймингов ? Подозреваю, что проблема могла бы быть выявлена анализом таймингов при аккуратном вводе констрейнов. Если переставить условие под CS внутрь условия с фронтом, то для знакомых мне FPGA синтезируется регистр с clock enable, а так я не уверен, что получится. Подозреваю, что проблема усугубляется не оптимальным использованием ресурсов. Код process(reset, WE) begin if reset='1' then VRAM_Address <= (others=>'0'); -- например. elsif rising_edge(WE) then --если пришёл фронт WE данные должны защёлкнуться if CS='0' then -- если CS=0 активен, то клок разрешается if A0='1' then --если регистры Register(7 downto 0)<=D(7 downto 0); else -- если не регистры VRAM_Address<=VRAM_Address+1; -- увеличиваем адрес памяти end if; end if; end if; end process; Однако, я подозреваю, что это не вся схема и где-то есть еще какой-то клок, который с сигналом WE не синхронизирован, но использует Register и/или VRAM_Address. В этом случае глюки ожидаемы.
|
|
|
|
|
Nov 4 2009, 02:40
|
Частый гость
 
Группа: Участник
Сообщений: 78
Регистрация: 12-10-09
Пользователь №: 52 902

|
Цитата(Builder @ Nov 3 2009, 04:05)  И в чём глюки? Разобрался с проблемой! Нужно было считывать по спаду сигнала записи! Код process(Port_WE,Port_CS) begin if (falling_edge(Port_WE) and Port_CS='0') then --Register if Port_A='0' then --Data else end if; end if; end process; Отлично работает при условии, что Port_WE опустится чуть-позже, чем Port_CS. Если одновременно - не сработает. Можно было сделать Port_CSWE<=Port_CS or Port_WE и анализировать по falling_edge(Port_CSWE), но при этом данные недостоверны! Есть ли какие нибудь мысли как можно сделать корректную фиксацию данных на шине при одновременном опускании CS и WE ?
Сообщение отредактировал penauch - Nov 4 2009, 02:43
|
|
|
|
|
Nov 4 2009, 11:28
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(penauch @ Nov 4 2009, 05:40)  Есть ли какие нибудь мысли как можно сделать корректную фиксацию данных на шине при одновременном опускании CS и WE ? Есть мысли... Код // данные - сделать прозрачную защелку:
wire dsel = A0 & !CS & !WE; always @* if (dsel) Register <= D;
// адрес - сделать счетчик по началу цикла
wire asel = !A0 & !CS & !WE;
always @(posedge asel) VRAM_Address<=VRAM_Address+1'b1; Только надо быть очень внимательным в части изучения временных диаграмм входных сигналов, чтобы asel/dsel были без глитчей. Никакое обконстреивание тут не спасет.
|
|
|
|
|
Nov 4 2009, 11:35
|
Частый гость
 
Группа: Участник
Сообщений: 78
Регистрация: 12-10-09
Пользователь №: 52 902

|
Цитата(SM @ Nov 4 2009, 15:28)  Есть мысли... Код // данные - сделать прозрачную защелку:
wire dsel = A0 & !CS & !WE; always @* if (dsel) Register <= D;
// адрес - сделать счетчик по началу цикла
wire asel = !A0 & !CS & !WE;
always @(posedge asel) VRAM_Address<=VRAM_Address+1'b1; Только надо быть очень внимательным в части изучения временных диаграмм входных сигналов, чтобы asel/dsel были без глитчей. Никакое обконстреивание тут не спасет. Verilog не знаю  Что значит always @ в двух ваших случаях? Ну или на словах , если перевод в vhdl затруднителен..
Сообщение отредактировал penauch - Nov 4 2009, 11:36
|
|
|
|
|
Nov 4 2009, 14:11
|
Группа: Участник
Сообщений: 8
Регистрация: 25-01-06
Пользователь №: 13 605

|
Цитата Есть ли какие нибудь мысли как можно сделать корректную фиксацию данных на шине при одновременном опускании CS и WE ? Есть. Предлагаю обратиться к временным диаграммам Вашей SRAM. Цитата Нужно было считывать по спаду сигнала записи! А вот этого не надо. Edit: пардон, недосмотрела - это же данные считываете с регистра на шину для записи в память - тогда все ОК. Смотрим, к примеру, AC WAVEFORMS WRITE CYCLE NO. 1(1,2) (CS1 Controlled, OE = HIGH or LOW). 1. CS и WE одновременно можно, но Address Setup Time tsa >=0 и Address Hold from Write End tha>=0 должно быть обеспечено. У Вас адрес меняется по rizing edge CS & WE - там все в порядке? 2. Данные пишутся в память по rizing edge CS или WE, в зависимости от того, CS-controlled или WE-controlled цикл записи. И нужно обеспечить Data Setup to Write End tsd - в общем случае меньше длительности WE, CS. Не советовала бы без нужды "нарезать", т.е. тактировать эти сигналы, просто внимательно отнеситесь к диаграмме. Если не поможет - тогда ищите "склейки" (здесь называют "иголки") при объединении CS и WE, хотя, если сигналы берутся с синхронного счетчика, в нем они оттактированы по выходу. Память, она терплячая и может работать даже когда не обязана, но лучше делать в соответствии с диаграммами.
Сообщение отредактировал eliza - Nov 4 2009, 14:39
|
|
|
|
|
Nov 4 2009, 14:16
|
Частый гость
 
Группа: Участник
Сообщений: 78
Регистрация: 12-10-09
Пользователь №: 52 902

|
попробую перевести на vhdl: register<=d when (A0='1' and CS='0' and WE='0'); --защёлка получается сознательно asel<='1' when A0='0' and CS='0' and WE='0'; process(asel) begin if rising_edge(asel) then vramaddress<=vramaddress+1; en if; end process; Правильно? Интуиция подсказывает что ошибся
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|