Итак...
После осознанного перепрочтения всех своих тредов в форуме, посвященных несчастной шине обмена CPU=>FPGA, внял тому что сказал
Shivers, в
этой теме.
Сделал цепочку из двойных триггеров:
Код
process(C)
begin
if rising_edge(C) then
CE1<=Port_CE;
WE1<=Port_WE;
A1<=Port_A;
D1<=Port_D;
CE2<=CE1;
WE2<=WE1;
A2<=A1;
D2<=D1;
if R_M(0)='0' then
WriteAddress1<=("101000000"*Y)+X;
else
WriteAddress1<=("010100000"*Y)+X;
end if;
WriteAddress2<=WriteAddress1;
end if;
end process;
process(C)
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 H2:std_logic_vector(7 downto 0);
variable Y0:std_logic_vector(7 downto 0);
variable Y1:std_logic_vector(7 downto 0);
begin
if rising_edge(C) then
if(WE1='0' and WE2='1') then
if CE2='0' then
if A2='0' then
case D2(15 downto 12) is
when "1001" =>
R_P:=D2(0);
when "1010" =>
R_W:=D2(8 downto 0);
W2:='0'&R_W(8 downto 1);
X0:="010100000"-W2;
X1:="010011111"+W2;
X:=X0;
when "1011" =>
R_H:=D2(7 downto 0);
H2:='0'&R_H(7 downto 1);
Y0:="01111000"-H2;
Y1:="01110111"+H2;
Y:=Y0;
when others =>null;
end case;
else
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 if;
end process;
VRAM0_CE<='0';
VRAM1_CE<='0';
VRAM0_OE<=H(0) when (R_P='0' and Blank='1') else '1';
VRAM1_OE<=H(0) when (R_P='1' and Blank='1') else '1';
VRAM0_WE<=WE2 when (A2='1' and R_P='1') else '1';
VRAM1_WE<=WE2 when (A2='1' and R_P='0') else '1';
VRAM0_D<=D2 when R_P='1' else (others => 'Z');
VRAM1_D<=D2 when R_P='0' else (others => 'Z');
VRAM0_A<=WriteAddress2 when R_P='1' else ReadAddress;
VRAM1_A<=WriteAddress2 when R_P='0' else ReadAddress;
end VideoFlipper_Architecture;
И что вы думаете?
Фрагмент работает исправно как часы - глюков с путаницей "регистр-память" не возникло ни разу!
C - это клок с PLL = 200 МГц
С Блекфина биру только CE,WE,A,D. CLKOUT=133.3 МГц (не биру)
Устройство работает устойчиво при Tsu>=2, Tw>=1
При Tsu<2 адрес не успевает вычисляться - изобразение начинает скролиться по горизонтали и потихоньку съезжать по вертикали, что логично. Для регистров хватает.
При любом режиме с Thold>0, адрес вычисляется также некорректно.
В целом Tsu=2, Tw=1 я доволен, но интересует возможность получить более быструю времянку , например Tsu=1, Tw=1 -
возможно ли как-нибудь изменить вышеприведенный код?
С какой оптимальной (компромисс надёжность(!главное)/потребление) частотой можно нарезать данные для такого метода?
Понимаю, что
des00, говорил что в 2.5 - 3 больше чем отдельный минимальный отсчёт нуля или единицы, но интересует данный случай.
P.S. а адрес с данными тоже надо нарезать - а то пиксель пишится в память размазанно влево-вправо
Сообщение отредактировал %-) - Dec 10 2009, 13:40