|
ПЛИС + SRAM, посоветуйте |
|
|
|
Nov 27 2009, 00:49
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
есть порт для ввода данных из хост-процессора в ПЛИС (запись в ПЛИС) к ПЛИС подключена SRAM нужно организовать запись в SRAM через ПЛИС. при этом адрес на память выставляет сама ПЛИС. сделано вот так: Код SRAM_D<=Port_D; --линии данных порта ПЛИС соединяем с линиями данных SRAM SRAM_A<=Address; --линии адреса SRAM соединены со счётчиком ПЛИС SRAM_CS<=Port_CS; --линия выбора SRAM соединена с линией порта ПЛИС SRAM_OE<='1'; --чтение не используется SRAM0_WE<=Port_WE; --линия разрешения записи SRAM соединена с линией порта ПЛИС
process(Port_WE) --увеличение адреса на 1 begin if falling_edge(Port_WE) then if Port_CS='0' then if Address=1000 then Address<=(others => '0'); else Address<=Address+1; end if; end if; end if; end process; По времянкам. Tsetup=20нс Thold=20нс Twrite=20нс Тем не менее, в силу каких-то обстоятельств(возможно когда на линии данных 0xFFFF) ИНОГДА происходит пропуск увеличения адреса - он как бы тот же. Прошу покритиковать и обсудить код. А также причины, вызвавшие сей эффект
Сообщение отредактировал %-) - Nov 27 2009, 01:24
|
|
|
|
|
Nov 27 2009, 02:22
|
iBuilder©
   
Группа: Свой
Сообщений: 519
Регистрация: 14-07-04
Из: Минск
Пользователь №: 322

|
Цитата(%-) @ Nov 27 2009, 04:49)  По времянкам. Времянка укладывается в рекомендации на хост процессор и SRAM? Сами по себе 20 нан ничего не гарантируют. Цитата(%-) @ Nov 27 2009, 04:49)  Тем не менее, в силу каких-то обстоятельств(возможно когда на линии данных 0xFFFF) ИНОГДА происходит пропуск увеличения адреса - он как бы тот же. Может земля между устройствами плохая? Попробуйте её улучшить, напаяв доп шину.
|
|
|
|
|
Nov 27 2009, 03:25
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
Цитата(Builder @ Nov 27 2009, 05:22)  Времянка укладывается в рекомендации на хост процессор и SRAM? Сами по себе 20 нан ничего не гарантируют. с лихвой! ещё как. запас в 2 раза (понизил скорость обмена) память 10нс, времянка для процессора вполне "низкочастотная" выскажу свою мысль. дело в том, что может такой подход (как я описал выше) не совсем корректен, так как адрес на SRAM выставляется фактически в момент опускания строба записи, а должен был выставлен намного раньше! в итоге имеют место "данные, записанные не в тот адрес" ИМХО нужно по опусканию CS подсчитывать адрес, но тут может возникнуть проблема с дешифрацией адресного бита типа "регистр/память", так как неизвестно будет ли установлен этот адресный бит "регистр-память" РАНЬШЕ чем произойдёт опускание CS. в общем гемор ещё тот
|
|
|
|
|
Nov 27 2009, 06:14
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
Цитата(BSV @ Nov 27 2009, 08:08)  Нужно в каждом цикле обращения выполнять операции с памятью по ТЕКУЩЕМУ адресу, а инкрементировать его ПОСЛЕ выполнения операции. Это обычная практика, тогда не будет проблем со времянками. P.S. В Вашей теме про ПЛИС и процессор я уже писал, что запись по спаду строба записи - это неправильно, но Вы упорно продолжаете это делать... ваш пример: Код process(AWEn) begin if (AWEn'event and AWEn = '1') then if (CS='0' and A='0' and D(15 downto 12) = "0101") then Y<=D(7 downto 0); end if; ... end if; end process; всё хорошо, но есть неуверенность, что в момент подымания AWE будет актуален A (возможно он изменится) кстати, когда CS=1, то каким будет сигнал на линии A (адрес со стороны процессора) - последний или Z-состояние? ниже времянка той памяти с которой идёт работа. в момент поднятия WE, данные ещё актуальны. тогда какое мы имеем право изменять адрес во время фронта WE ? (rising edge?) ведь он уже должен быть стабилен и актуален до поднятия CS. прошу разъяснить если заблуждаюсь. P.S. вот ещё что надумалось. можно увеличивать адрес по rising_edge(CS). Приемущество в том что память защищена от записи в этот момент (Thold>0, WE=1) исправил процесс. позже потестирую Код process(Port_CS,Port_A,Port_WE) begin --Register CS=0,WE=0 if Port_CS='0' then if Port_WE='0' then case Port_D(15 downto 12) is when "1000" => R_M:=Port_D(2 downto 0); when "1001" => if VBlank='0' then R_P:=Port_D(0); end if; when "1010" => R_W:=Port_D(8 downto 0); W2:='0'&R_W(8 downto 1); X0:="010100000"-W2; X1:="010011111"+W2; X:=X0; when "1011" => R_H:=Port_D(7 downto 0); H2:='0'&R_H(7 downto 1); Y0:="01111000"-H2; Y1:="01110111"+H2; Y:=Y0; when others => null; end case; end if; else --VideoRAM CS=1,A ---|___ if rising_edge(Port_A) then if X=X1 then X:=X0; if Y=Y1 then Y:=Y0; else Y:=Y+1; end if; else X:=X+1; end if; WriteAddress<=("101000000"*Y)+X; end if; end if; end process; в vhdl-коде решил Port_A превратить в CS для данных. тоесть: Port_CS=0 - разрешение пиать в регистры Port_A=0 - разрешение увеличивать адрес памяти Port_WE - разрешение записи (общий)
Сообщение отредактировал %-) - Nov 27 2009, 06:17
Эскизы прикрепленных изображений
|
|
|
|
|
Nov 27 2009, 08:15
|
iBuilder©
   
Группа: Свой
Сообщений: 519
Регистрация: 14-07-04
Из: Минск
Пользователь №: 322

|
Цитата(%-) @ Nov 27 2009, 06:25)  дело в том, что может такой подход (как я описал выше) не совсем корректен, так как адрес на SRAM выставляется фактически в момент опускания строба записи, а должен был выставлен намного раньше! в итоге имеют место "данные, записанные не в тот адрес" Вообще, когда я спрашивал про времянку, я имел ввиду не просто, 10 нан память, 20 нан ограничения - всё пучком. Вигушки, нужно учесть все сетапы и холды памяти. Т.е. если у Вас идёт строб, то нужно посмотреть сколько времени сигнал идёт от этого строба обратно на адресса памяти. Хватает ли того времени что остаётся для нормальной работы памяти. И что-то мне одсказывает что не всё там у Вас стыкуется. Перепроверьте ещё раз. Ну больше запаса будет, если действительно инкрементпировать после записи, а не перед.
|
|
|
|
|
Nov 27 2009, 09:02
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
проблема почти выявлена. инкремент адреса иногда не срабатывает когда цвет близок к белому (большинство битов =1) заземлил кабель наконец-то - ничего не дало. действительно, после подъёма WE времянка укороченная. Удалось Tsetup=1, Twrite=1, Thold=0, тоесть 2 такта @150 МГц => 75МГц но как только встречается белый цвет - всё глюкает - кадр крутится слеванаправо и сверхувниз... уже мозг сломал, но причину ЯВНО не нашёл  на текущий момент: Код process(Port_WE,Port_CS) variable W2:std_logic_vector(8 downto 0); variable X0:std_logic_vector(8 downto 0); variable X1:std_logic_vector(8 downto 0); variable X:std_logic_vector(8 downto 0); variable H2:std_logic_vector(7 downto 0); variable Y0:std_logic_vector(7 downto 0); variable Y1:std_logic_vector(7 downto 0); variable Y:std_logic_vector(7 downto 0); begin if rising_edge(Port_WE) then if Port_CS='0' then --Register if Port_A='0' then case Port_D(15 downto 12) is when "1000" => R_M:=Port_D(2 downto 0); when "1001" => if ((R_M(2)='0' and VBlank='0') or (R_M(2)='1' and Blank='0')) then R_P:=Port_D(0); end if; when "1010" => R_W:=Port_D(8 downto 0); W2:='0'&R_W(8 downto 1); X0:="010100000"-W2; X1:="010011111"+W2; X:=X0; when "1011" => R_H:=Port_D(7 downto 0); H2:='0'&R_H(7 downto 1); Y0:="01111000"-H2; Y1:="01110111"+H2; Y:=Y0; when others => null; end case; --VideoRAM else WriteAddress<=("101000000"*Y)+X; if X=X1 then X:=X0; if Y=Y1 then Y:=Y0; else Y:=Y+1; end if; else X:=X+1; end if; end if; end if; end if; end process;
Сообщение отредактировал %-) - Nov 27 2009, 09:04
|
|
|
|
|
Nov 29 2009, 04:25
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
значит так. 1) буфер чисто на данные ставить нельзя - так как стробы приходят раньше чем данные на выводах буфера. тоесть задержка. не работает даже с тормозными времянками 2) отпаяв буфер, перепроверил ещё раз. всё пашет как надо. ошибка была в счётчике строк. 3) так и не понятно - в какой момент времени можно менять адрес снова прикрепляю картинку - ткните носом плиз - на рисунке - КОГДА МОЖНО МЕНЯТЬ АДРЕС??? 4) пока сделана отдельная команда изменить адрес
Сообщение отредактировал %-) - Nov 29 2009, 04:26
Прикрепленные изображения
|
|
|
|
|
Dec 1 2009, 02:28
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
Решил вникнуть в синхронный дизайн и сделать обработку следующим образом. сигналы с процессора на ПЛИС: CLKOUT - синхронизация для шины Port_A - адресный бит (0 - регистры, 1 - увеличение адреса) Port_D - данные Port_WE - строб записи (активен когда 0) сигналы с ПЛИС на SRAM: SRAM_A - биты адреса SRAM SRAM_D - данные SRAM_WE - строб записи Картинка с времянками ниже. Кажный setup по 2 clk (clk=133Мц) - чтоб ПЛИС гарантированно захватила уровни сигналов. Автомат наподобие, как Shtirlits давал в соседней теме: Код signal state:std_logic:='0'; --начальное состояние
--коммутируем шины: адреса, данных SRAM_D<=Port_D when (Port_A='1') else (others => 'Z'); --когда Port_A=1 SRAM_A<=WriteAddress;
process(CLKOUT) begin
if falling_edge(CLKOUT) then if (state='0' and Port_CS='0' and Port_WE='0' and Port_A='0') then --если Port_CS=0 и Port_WE=0 и Port_A=0 и состояние=0, то данные актуальны для записи врегистры. state<='1'; --следующее состояние для инкремента адреса case Port_D(15 downto 12) is --запись в регистры (формируют старшие 4 бита) when "0000" => reg_0<=Port_D(7 downto 0); --запись в регистр 0x0000 when "0001" => reg_1<=Port_D(7 downto 0); --запись в регистр 0x1000 .... end case; end if; if (state='1' and Port_CS='0' and Port_WE='1' and Port_A='1') then --если Port_CS=0 и Port_WE=1 и Port_A=1 и состояние=1(тоесть уже была запись в регистр или SRAM), то записть в SRAM запрещена - можно менять адрес state<='0'; --следующее состояние для записи в память или регистры
WriteAddress<=WriteAddress+1; --увеличиваем адрес на 1
end if;
SRAM_CS<=Port_CS; --коммутируем выбор SRAM SRAM_WE<=Port_WE; --коммутируем разреш. записи
end if;
end Process; CLKOUT - берется с платы процессора(к его лапке резистор 33 Ом) и 12-см проводом ко входу ПЛИС. Прошу покритиковать. Имеет ли право дизайн на жизнь, или нужно изменить?
Сообщение отредактировал %-) - Dec 1 2009, 02:31
Эскизы прикрепленных изображений
|
|
|
|
|
Dec 1 2009, 07:06
|
Частый гость
 
Группа: Участник
Сообщений: 90
Регистрация: 17-05-07
Пользователь №: 27 775

|
Цитата(%-) @ Nov 27 2009, 15:02)  инкремент адреса иногда не срабатывает когда цвет близок к белому (большинство битов =1) По моему типичный глюк "ground bounce" - плохая земля между FPGA и памятью. Практически один в один ситуация была. Лечилась пропайкой доп. земли между FPGA и другой микрухой (памятью в вашем случае). Смею предположить, что плата - двухслойка? Я прав?
Сообщение отредактировал alevnew - Dec 1 2009, 07:08
|
|
|
|
|
Dec 1 2009, 07:11
|
Частый гость
 
Группа: Участник
Сообщений: 118
Регистрация: 13-09-09
Пользователь №: 52 331

|
Цитата(alevnew @ Dec 1 2009, 11:06)  По моему типичный глюк "ground bounce" - плохая земля между FPGA и памятью. Практически один в один ситуация была. Лечилась пропайкой доп. земли между FPGA и другой микрухой (памятью в вашем случае).
Смею предположить, что плата - двухслойка? Я прав? Плата с процессором - 4 слойка Плата с ПЛИС - отладочная от Terasic. Тоже вроде 4 слоя(не менее) Соединены ленточным кабелем длиной 12см + 8 см на печатке до ПЛИС + 3 см до процессора на плате кабель в золотинке и он за GND-нен. Народ, выскажитесь по моему синхронному автомату. Будет жить?
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|