VHDL信号分配延迟与仿真混淆
VHDL新手,正在尝试实现小型缓存 我的VHDL信号分配延迟与仿真混淆,vhdl,Vhdl,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_se
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
....
实体缓存不可用
端口(时钟:标准_逻辑中;
rw_sel:在标准逻辑中--“1”从缓存中读取,
--“0”将写入缓存
ad_sel:在STD_逻辑中--“0”用于发送地址,“1”用于发送数据
数据输入:标准逻辑向量(7到0);
--发送由ad_sel控制的数据或地址
...
端缓存;
行为缓存的体系结构是
....
信号块地址:整数范围0至15;
--缓存块地址
信号块单元地址:整数范围0到1;
--缓存地址中的字节
开始
进程(时钟,初始化)
开始
案例初始化是
当“0”=>
对于0到15循环中的i
高速缓存(i)
地址数据\u cpu\u wrnull;
终例;
block_addr_n灵敏度列表不包含该过程中使用的所有信号,因为地址
是一个信号(在同一过程中分配,但这并不重要)但是信号不在过程的灵敏度列表中。因此当地址的值改变时,模拟器不会重新执行该过程。过程部分:
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));
进程(时钟,初始化)
开始
...
地址我认为您的实际问题可能是对如何编写时钟进程的误解。
现在编写进程的方式将生成纯粹的组合逻辑和锁存。
这里需要的是寄存器、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;
process(clock,init)——一个时钟进程在灵敏度列表中应该只有时钟和复位信号。这是正确的。
开始
如果init='0',则--“init”用作重置信号
对于0到15循环中的i
--这将重置缓存。它可以工作,但是
--这样做可以防止合成工具推断RAM块。
--为了允许RAM推断,每个时钟周期只能写入一个内存位置。
高速缓存(i)通过添加“地址”信号,我纠正了这个问题。但我仍然感到困惑。你说地址分配“无关紧要”,这是否意味着所有真正的信号分配都发生在进程结束时?此外,我不知道如何使缓存项目的这部分组合或顺序。我设计使用Nexys 3上的开关和按钮为了实现这个项目。它是组合的还是顺序的?时钟信号被用作发送数据的触发信号。地址
分配在进程执行后生效一个增量延迟,如果进程中的其他信号依赖于地址
,则必须重新执行进程,因此地址必须在敏感列表中,如您所经历的那样,触发重新执行。通过组合,我只考虑门,因此输出完全基于当前输入(如函数),并且通过时钟/顺序,考虑进程更新状态,如触发器或存储器。非常感谢。现在我有一个关于将要发生什么的想法。n进程运行时。我终于完成了我的项目。万分感谢。@ArthurTian:如果这回答了您的问题,请按说明单击复选标记接受答案。这也适用于您提出的问题。请参阅中的详细信息。
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;
if ad_sel='0' then
address<=data_in(6 downto 0);
else
data_cpu_wr<=data_in;
end if;