[讨论]终于解决了
原来程序读取的时候,第一个周期上的地址址没有有效赋值,也就是必须延迟一个时钟后地址线上数据才有效,如下:
-- 5.5 16:36
-- 地址信号进入必须至少维持两个时钟周期 5.6
-- 5 个时钟周期完成数据的存取
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY ram4 IS
PORT (
address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
address_c : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
address_d : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
clock : IN STD_LOGIC ;
data_a : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
data_b : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
data_c : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
data_d : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
wren : IN STD_LOGIC := '1';
q_a : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
q_c : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
q_d : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
flag : OUT STD_LOGIC := '0'-- 标志存取操作完成
);
END ram4;
ARCHITECTURE SYN OF ram4 IS
component ram2
PORT (
address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
clock : IN STD_LOGIC ;
data_a : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
data_b : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
wren_a : IN STD_LOGIC := '1';
wren_b : IN STD_LOGIC := '1';
q_a : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
);
end component;
signal address_a_sig : STD_LOGIC_VECTOR (7 DOWNTO 0) := address_a;
signal address_b_sig : STD_LOGIC_VECTOR (7 DOWNTO 0) := address_b;
signal data_a_sig : STD_LOGIC_VECTOR (31 DOWNTO 0);
signal data_b_sig : STD_LOGIC_VECTOR (31 DOWNTO 0);
signal q_a_sig : STD_LOGIC_VECTOR (31 DOWNTO 0);
signal q_b_sig : STD_LOGIC_VECTOR (31 DOWNTO 0);
SIGNAL present_state: STD_LOGIC_VECTOR(2 DOWNTO 0):= "000";
--SIGNAL processing : STD_LOGIC := '0';
begin
ram2_inst : ram2 -- 需要两个时钟周期
PORT MAP (
address_a=> address_a_sig,
address_b=> address_b_sig,
clock => clock,
data_a => data_a_sig,
data_b => data_b_sig,
wren_a => wren, -- 共用一个wren信号
wren_b => wren, -- 使两个port同时读写
q_a => q_a_sig,
q_b => q_b_sig
);
state_fb :process(clock)
begin
if(clock'event and clock = '1') then
--if (processing='1') then
case present_state is
when "000" => -- 前两个时钟赋地址值
address_a_sig <= address_a;
address_b_sig <= address_b;
data_a_sig <= data_a;
data_b_sig <= data_b;
flag <= '0';
present_state <= present_state + "1";
when "001" =>
address_a_sig <= address_c;
address_b_sig <= address_d;
data_a_sig <= data_c;
data_b_sig <= data_d;
flag <= '0';
present_state <= present_state + "001";
when "010" =>
flag <= '0';
present_state <= present_state + "001"; -- ???
when "011" => -- 后两个时钟读取对应位置的数据
--q_c <= (others=> 'Z');--q_a_sig;--
--q_d <= (others=> 'Z');
address_a_sig <= address_a;
address_b_sig <= address_b;
q_a <= q_a_sig;
q_b <= q_b_sig;
flag <= '0';
present_state <= present_state + "001";
when "100" => -- 后两个时钟读取对应位置的数据
--q_a <= (others=> 'Z');--q_a_sig;--
--q_b <= (others=> 'Z');
address_a_sig <= address_c;
address_b_sig <= address_d;
q_c <= q_a_sig;
q_d <= q_b_sig;
flag <= '1'; -- 存取操作结束
present_state <= "000";
when others => present_state <= "000";
end case;
--end if;
end if;
end process state_fb;
END SYN;
如果有更好的解决方案,希望大家提出
发表时间:2007年5月13日9:09:08