VHDL新手并试图实现一个小缓存。
我的cache.vhd
entity cache is
Port ( clock : in STD_LOGIC;
rw_sel : in STD_LOGIC; --'1' to read from cache ,
--'0' to write to cache
ad_sel: in STD_LOGIC; --'0' to send address, '1' to send data
data_in :in STD_LOGIC_VECTOR (7 downto 0);
--send data or address controled by ad_sel
...
end cache;
architecture Behavioral of cache is
....
signal block_addr_n : integer range 0 to 15;
-- cache block address
signal block_cell_addr_n: integer range 0 to 1;
-- byte-in-cache address
begin
process(clock, init)
begin
case init is
when '0' =>
for i in 0 to 15 loop
cache_memory(i)<="1111111111111111";
tag_memory(i)<="11";
end loop;
when others =>null;
end case;
case ad_sel is
when '0' =>
address<=data_in(6 downto 0);
when '1' => data_cpu_wr<=data_in;
when others =>null;
end case;
block_addr_n <= conv_integer(unsigned(address(4 downto 1)));
block_cell_addr_n<=conv_integer(address(0));
case rw_sel is
....
我的testbench文件的一部分:
....
--Inputs
signal clock : std_logic := '0';
signal rw_sel : std_logic := '1';
signal ad_sel : std_logic := '0';
signal init: std_logic:='1';
signal data_in : std_logic_vector(7 downto 0) := (others => '0');
....
stim_proc: process
begin
-- initialize
init<='0';
wait for 100 ns;
-- read address "0101111"(MSB cut), expecting miss
cache_mem_data<="1100110011001100";
ad_sel<='0';
rw_sel<='1';
data_in<="00101111";
clock <= not clock;
wait for 100 ns;
-- write to address "0101111" but written in "0000000" which is default
data_in<="10101010";
ad_sel<='1';
rw_sel<='0';
clock<=not clock;
wait for 100 ns;
data_in<="00101111";
ad_sel<='0';
rw_sel<='1';
clock<=not clock;
wait;
end process;
END;
我在ISim窗口中得到的是
为什么不在第二个100 ns内分配block_addr_n
和block_cell_addr_n
,因为此时直接分配信号address
?我认为这是导致我的程序出现意外结果的原因,因为写入缓存块0时我只是将地址0设置为默认值但传入地址&#34; 0101111&#34;在前100 ns之后。
有什么想法吗?
答案 0 :(得分:1)
灵敏度列表不包含过程中使用的所有信号,因为address
是一个信号(在同一过程中分配,但无关紧要)但信号不在灵敏度中进程列表。因此,当address
的值发生变化时,模拟器不会重新执行该过程。流程部分:
process(clock, init)
begin
...
address<=data_in(6 downto 0);
...
block_addr_n <= conv_integer(unsigned(address(4 downto 1)));
block_cell_addr_n<=conv_integer(address(0));
如果您使用的是VHDL-2008,那么您可以使用process (all)
自动生成敏感度列表,但我不认为Xilinx已经实现了VHDL-2008,因此您必须制作灵敏度列表通过在灵敏度列表中手动包含所有使用的信号来自己。
顺便说一句,考虑使这些过程纯粹是组合(门)或时钟(触发器或RAM),因此组合过程不应该在灵敏度列表中具有例如clock
。
答案 1 :(得分:1)
我认为你的实际问题可能是对如何编写时钟进程的误解。 现在编写流程的方式将产生纯粹的组合逻辑和锁存器。 你想要的是寄存器,RAM和组合逻辑。
时钟流程将按如下方式编写:
process(clock, init) --A clocked process shall have only the clock and reset signal in the sensitivity list. This is correct.
begin
if init = '0' then --"init" is used as a reset signal
for i in 0 to 15 loop
--This will reset the cache memory. It works, but
--doing it this way prevents the synthesis tool from infering a RAM block.
--To allow RAM inference you can write only one memory location per clock cycle.
cache_memory(i)<="1111111111111111";
tag_memory(i)<="11";
end loop;
elsif rising_edge( clock ) then
case ad_sel is
when '0' =>
address<=data_in(6 downto 0);
when '1' => data_cpu_wr<=data_in;
when others =>null;
end case;
block_addr_n <= conv_integer(unsigned(address(4 downto 1)));
block_cell_addr_n<=conv_integer(address(0));
case rw_sel is
...
end if;
请注意,这不会立即生效。您的测试平台也存在问题。例如,您的初始化信号无限期低。
您可能还想使用&#34;如果&#34;陈述而非&#34;案例&#34;对于简单的条件。例如:
if ad_sel='0' then
address<=data_in(6 downto 0);
else
data_cpu_wr<=data_in;
end if;