Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Асинхронная запись данных в ПЛИС
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
penauch
требуется считывать данные из шины в ПЛИС (запись в регистры аппаратуры-ПЛИС)

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.
Связаны ли глюки с тем, что имитировать шину портами нежелательно из-за выбросов ?

или не так делаю?
Builder
Цитата(penauch @ Nov 3 2009, 02:40) *
требуется считывать данные из шины в ПЛИС (запись в регистры аппаратуры-ПЛИС)

Оно работает, но иногда глючит...

или не так делаю?

А что дальше с данными делаете? И в чём глюки?
Как осуществляете синхронизацию асинхронной и синхронной части проекта?
rezident
Я не силен в HDL, но на мой взгляд у вас асинхронный дизайн описан, правильно? Что за ПЛИС используется? Асинхронный дизайн обычно рекомендуется применять лишь в самых крайних случаях. Вероятнее всего поэтому и глючит у вас обмен.
Shtirlits
Цитата(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. В этом случае глюки ожидаемы.
penauch
Глюк в том, что когда интенсивно используются команды задания региона для записи в память(регистры- координаты углов прямоугольной области) при последующем выводе данных в эту область- иногда заходит на регистр переключения страницы(мультиплексируются две SRAM- пока из одной ПЛИС читает, другая коммутируется на порт хост-CPU для записи данных, адрес автоматически увеличивается ПЛИСом по нарастанию WE, вычисляется адрес по спаду WE по формуле 320*у+х, где х и у - сигналы, началное присвоение которых зависит от регистров.

в итоге при медленном переключении страниц видим, что часть символов попала не на ту страницу- возникают 'рваные' или 'перекрученные' символы.

страницы переключаю когда луч завершил рисовать видимую часть (начало VBlank)
des00
нарежте асинхронную шину на ~100 МГц и сделайте нормальное ее декодирование.
penauch
что значит нарезать?

синхронизация в проекте 50 мгц.
плата- altera DE
des00
Цитата(penauch @ Nov 2 2009, 23:06) *
что значит нарезать?


значит нарезать сигналы управления (не данных и адреса!!!) асинхронной шиной на частоте ~100МГц на регистрах и сделать нормальную синхронную обработку.
penauch
Мне нужно писать в свободную банку SRAM со скоростью доступа 10нс.
penauch
Цитата(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 ?
SM
Цитата(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 были без глитчей. Никакое обконстреивание тут не спасет.
penauch
Цитата(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 не знаю smile.gif
Что значит always @ в двух ваших случаях?

Ну или на словах , если перевод в vhdl затруднителен..
SM
Цитата(penauch @ Nov 4 2009, 14:35) *
Что значит always @ в двух ваших случаях?

В первом случае это такой процесс, в списке чувствительности которого перечислены все сигналы, которые задействованы внутри процесса, т.е. dsel и D. Во втором случае - rising_edge(asel).
eliza
Цитата
Есть ли какие нибудь мысли как можно сделать корректную фиксацию данных на шине при одновременном опускании 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, хотя, если сигналы берутся с синхронного счетчика, в нем они оттактированы по выходу.

Память, она терплячая и может работать даже когда не обязана, но лучше делать в соответствии с диаграммами.
penauch
попробую перевести на 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;

Правильно? Интуиция подсказывает что ошибся sad.gif
SM
Цитата(penauch @ Nov 4 2009, 17:16) *
Правильно? Интуиция подсказывает что ошибся sad.gif

Смысл вроде правильный, кроме asel, который еще должен уметь быть нулем, когда выражение неверно. Т.е. asel не должен быть защелкой. Насчет синтаксиса я не на столько знаток VHDL, чтобы его в уме проверять.
penauch
Цитата(eliza @ Nov 4 2009, 17:11) *
Смотрим, к примеру, 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, хотя, если сигналы берутся с синхронного счетчика, в нем они оттактированы по выходу.

Память, она терплячая и может работать даже когда не обязана, но лучше делать в соответствии с диаграммами.


вы совершенно правы, но с памятью проблем нет, так как она мухается-демухается на порт напрямую после управляющего сигнала A=1.

проблема была с ошибочным распознаванием регистров - иногда данные для памяти затекали на case с регистрами. Или не тот регистр срабатывал или адрес увеличивался когда не надо и не увеличивался когда надо smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.