首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VHDL信号分配延迟与仿真混淆

VHDL信号分配延迟与仿真混淆
EN

Stack Overflow用户
提问于 2015-04-18 04:50:49
回答 2查看 1.3K关注 0票数 0

新的VHDL,并试图实现一个小的缓存。

我的cache.vhd的一部分

代码语言:javascript
复制
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文件的一部分:

代码语言:javascript
复制
 ....
      --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窗口里得到的是

为什么block_addr_nblock_cell_addr_n不能在第二个100 ns内分配,因为信号address是直接分配的?我认为这就是导致我的程序产生意外结果的原因,因为缓存块0是写入的,而我只是将address 0设置为默认值,但在前100 ns之后传入地址"0101111“。

有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-18 05:23:47

灵敏度列表并不包含在进程中使用的所有信号,因为address是一个信号(分配在同一进程中,但这并不重要),但是信号不在进程的灵敏度列表中。因此,当address的值发生变化时,模拟器不会重新执行该进程。工艺部件:

代码语言:javascript
复制
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,所以您可能必须手动将所有使用过的信号都包含在灵敏度列表中,这样才能自己创建灵敏度列表。

顺便说一句,考虑让进程纯粹是组合(门)或时钟(触发器或RAMs),这样组合进程就不应该在灵敏度列表中有clock

票数 1
EN

Stack Overflow用户

发布于 2015-04-18 09:49:11

我认为您的实际问题可能是对如何编写进度的误解。现在编写流程的方式将产生纯粹的组合逻辑和锁存。你想要的是寄存器,RAM和组合逻辑。

一个时钟化的进程会写成这样:

代码语言:javascript
复制
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;

请注意,这不会立即起作用。您的测试平台中也存在一些问题。例如,您的init信号无限期低。

对于简单的条件,您也可能希望使用"if“语句而不是"case”。示例:

代码语言:javascript
复制
if ad_sel='0' then
   address<=data_in(6 downto 0);
else
   data_cpu_wr<=data_in;
end if;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29713041

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档