【发布时间】:2019-11-30 23:57:22
【问题描述】:
我正在尝试创建一个简单的内存,用于在时钟为 1 且 wrenable 为 1 时存储向量(同样用于读取),但不幸的是我一直面临时间问题:
来源:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY test_memdata IS
PORT (
address, data : IN std_logic_vector(31 DOWNTO 0) := (OTHERS => '0');
wrenable, clock, rdenable : IN std_logic := '0';
readout : OUT std_logic_vector(31 DOWNTO 0)
);
END test_memdata;
ARCHITECTURE arch OF test_memdata IS
TYPE ram_type IS ARRAY(0 TO 31) OF std_logic_vector(31 DOWNTO 0);
SIGNAL ram_block : ram_type;
BEGIN
process(clock, wrenable, address)
variable write_addr : integer;
variable write_en, read_en : std_logic;
begin
write_en := wrenable;
read_en := rdenable;
write_addr := to_integer(unsigned(address));
if rising_edge(clock) then
if write_en = '1' then
ram_block(write_addr) <= data;
elsif read_en = '1' then
readout <= ram_block(write_addr);
end if;
end if;
end process;
END arch;
Modelsim 测试台
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY memdata_test IS
END memdata_test;
ARCHITECTURE arch OF memdata_test IS
SIGNAL address, data : std_logic_vector(31 DOWNTO 0) := (OTHERS => '0');
SIGNAL wrenable, clock, rdenable : std_logic := '0';
SIGNAL readout : std_logic_vector(31 DOWNTO 0);
COMPONENT test_memdata IS
PORT (
address, data : IN std_logic_vector(31 DOWNTO 0) := (OTHERS => '0');
wrenable, clock, rdenable : IN std_logic := '0';
readout : OUT std_logic_vector(31 DOWNTO 0)
);
END COMPONENT test_memdata;
BEGIN
uut : test_memdata PORT MAP(
address => address,
data => data,
wrenable => wrenable,
rdenable => rdenable,
clock => clock,
readout => readout
);
PROCESS
BEGIN
address <= (OTHERS => '0');
data <= (OTHERS => '1');
WAIT FOR 200 ns;
clock <= '1';
wrenable <= '1';
WAIT FOR 200 ns;
clock <= '0';
wrenable <= '0';
WAIT FOR 200 ns;
clock <= '1';
rdenable <= '1';
WAIT FOR 200 ns;
REPORT "end";
WAIT;
END PROCESS;
END arch;
在 ModelSim 中,此测试平台按预期工作: 但在 Quartus 中,由于某种原因,它不能按预期工作:
但如果我在时钟信号上升沿之前扩展 rden 和 wren,它可以工作:
我已经在这方面工作了很长时间,如果wrenable/rdenable 和clock 都是肯定的,我将非常感谢我如何能够进行读/写。在同一时间边缘。
谢谢。
ModelSim-Altera 10.1d,Quartus 版本 13.0sp1
【问题讨论】:
-
您的两个 Quartus 波形的差异似乎通过时钟上升沿发生时 wren 和 rden 是否为“1”来表示。使用连续生成的时钟来驱动时钟同步刺激可能很有用。使用与用于驱动模型的边缘相反的边缘可以消除同步输入和时钟边缘的顺序问题。
-
在您的模拟中,您有一个竞争条件。实际上,您将违反设置时间。阅读寄存器以及建立和保持时间。总而言之,这不是编写 HDL 代码的最佳方式:使用在整个时钟周期内都有效的信号,直到您有更多的经验。
-
感谢@user1155120 的建议,使用下降沿有效,但不幸的是我的设计需要上升沿
-
是的,您的设计需要上升沿,您错过了在同步中,wren 或 rden 高应该具有一个时钟的最小周期并且由于连续时钟的时钟沿而改变,不是异步的。当激励和被测设备都在相同的时钟沿上驱动时。使能在下一个边缘生效。使用在相对边沿变化的外部刺激明确地展示了哪个边沿,展示了相对于(此处)上升沿的建立时间和保持时间。
标签: vhdl simulation modelsim quartus