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

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
            ....
实体缓存不可用
端口(时钟:标准_逻辑中;
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;