【问题标题】:waveform does not work properly for some operations对于某些操作,波形无法正常工作
【发布时间】:2021-01-05 20:40:57
【问题描述】:

我是 vhdl、modelsim、波形等方面的新手。我开发了一个简单的操作流程和一个测试平台,可以在 modelsim 波形上一一测试我的操作。

当我在模拟器上运行时,我发现有一些问题;尽管在临时变量 (uQ2) 中正确计算了乘法运算结果,但不会将结果放入输出变量 (result_out1)。此外 mod 和 rem 操作不提供任何输出。

虽然 add、sub 和 div 操作按预期工作,但为什么 mul、mod 和 rem 操作会失败?

我在下面分享我的代码和波形结果。

我的代码和测试平台如下;

 rns.vhd
 library IEEE;
 use IEEE.STD_LOGIC_1164.ALL;
 use IEEE.NUMERIC_STD.ALL;

 entity rns is 
      port(
           en: in std_logic;
           op: in std_logic_vector(2 downto 0);
           reg_a_in: in std_logic_vector(7 downto 0);
           reg_b_in: in std_logic_vector(7 downto 0);
           reg_c_in: in std_logic_vector(7 downto 0);
           result_out1: out std_logic_vector(7 downto 0);
           result_out2: out std_logic_vector(7 downto 0)
      );
 end entity;


 architecture behave of rns is     
      signal uA, uB, uC, uQ, uR: unsigned(8 downto 0);
      signal uQ2: unsigned(17 downto 0);
      signal result: std_logic_vector(8 downto 0);
      
 begin
      
      process(reg_a_in, reg_b_in, op)
      begin
           uA <= unsigned('0' & reg_a_in);
           uB <= unsigned('0' & reg_b_in);
      
           if op = "000" then
                uQ <= uA + uB;
           elsif op = "001" then
                uQ <= uA - uB;
           elsif op = "010" then
                uQ2 <= uA * uB;
                uQ <= resize(uQ2, uQ'length); --uQ2(8 downto 0);
           elsif op = "011" then
                uQ <= uA / uB;
           elsif op = "100" then
                uQ <= uA mod uB;
           elsif op = "101" then
                uQ <= uA rem uB;
           end if;
                
      end process;
       
      result <= std_logic_vector(uQ) when en = '1' else (others=>'Z'); 
      result_out1 <= result(7 downto 0) when en = '1' else (others=>'Z');
      
 end behave;


rns_tb.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity rns_tb is 
end entity;

architecture behave of rns_tb is

    component rns is
        port(
            en: in std_logic;
            op: in std_logic_vector(2 downto 0);
            reg_a_in: in std_logic_vector(7 downto 0);
            reg_b_in: in std_logic_vector(7 downto 0);
            reg_c_in: in std_logic_vector(7 downto 0);
            result_out1: out std_logic_vector(7 downto 0);
            result_out2: out std_logic_vector(7 downto 0)
        );
    end component;

    signal en_sig: std_logic;
    signal op_sig: std_logic_vector(2 downto 0);
    signal reg_a_in_sig: std_logic_vector(7 downto 0);
    signal reg_b_in_sig: std_logic_vector(7 downto 0);
    signal reg_c_in_sig: std_logic_vector(7 downto 0);  
    signal result_out1_sig: std_logic_vector(7 downto 0);
    signal result_out2_sig: std_logic_vector(7 downto 0);

    constant wait_period: time :=10 ns;

begin
    rns1 : rns port map(en=>en_sig, op=>op_sig, reg_a_in=>reg_a_in_sig, reg_b_in=>reg_b_in_sig, 
    reg_c_in=>reg_c_in_sig, result_out1=>result_out1_sig, result_out2=>result_out2_sig);
    
    process
    begin
    
        op_sig <= (others => 'Z');
        wait for wait_period * 3;
        reg_a_in_sig <= "00000011";
        reg_b_in_sig <= "00000010";
        reg_c_in_sig <= "00000101";
        
        wait for wait_period;
        en_sig <= '1';
        op_sig <= "000";
        
        wait for wait_period * 5;
        op_sig <= "001";
        
        wait for wait_period * 5;
        op_sig <= "010";
        
        wait for wait_period * 5;
        op_sig <= "011";

        wait for wait_period * 5;
        op_sig <= "100";
        
        wait for wait_period * 5;
        op_sig <= "101";
        wait;
                
    end process;
end behave;

提前致谢。

【问题讨论】:

  • 请以文本形式添加您的代码,而不是屏幕截图,这些数据很难处理。
  • 我刚刚将我的代码添加为文本格式
  • 你能把整个代码贴出来吗,opreg_a_inreg_b_in是从哪里来的?
  • 我添加了完整代码@po.pe
  • 代码图像不允许复制问题,也不允许未来读者作为搜索结果显示。从图像上的波形部分,我们可以看到所有 ms_tb.vhd 信号。多个驱动程序分辨率可能会导致“X”。提供minimal reproducible example,此处包括测试台、预期和实际结果。

标签: vhdl modelsim waveform


【解决方案1】:

说实话,在您完全了解它们的工作原理之前,我建议您只使用时钟进程。但是让我们看看我们是否可以解决您的问题。

问题在于您的流程的敏感度列表。每当灵敏度列表中的信号发生变化时,仿真工具都会评估过程的结果。对于所有操作,这是信号 op,它会发生变化,并且流程会重新评估 uQ

重要提示:敏感度列表仅用于模拟目的,信号在过程评估完成后分配。

上面的意思是在你乘法的情况下,op 更改为010 并且过程评估

            uQ2 <= uA * uB;
            uQ <= resize(uQ2, uQ'length); --uQ2(8 downto 0);

但是因为信号是在求值后分配的,uQ2 会有乘法的结果,但uQ 是前一个uQ2 的resize。要解决此问题,您可以...

  1. 不使用uQ2,直接写uQ &lt;= resize(uA * uB, uQ'length)
  2. 使用uQ2 扩展敏感度列表,以便在uQ2 更新后重新评估uQ
  3. 正如评论中正确提到的,如果您需要在 process 中立即评估的“信号”,请使用 variables 而不是 signal 类型。

结果分配可以优化,老实说,在这种情况下我不会使用Z

  --result <= std_logic_vector(uQ) when en = '1' else (others=>'Z');
  result_out1 <= std_logic_vector(uQ(7 downto 0)) when en = '1' else (others=>'0');

一般而言,此实现存在一些缺陷,您可能应该添加一些额外的控制信号,甚至将其设为时钟进程。检查这是否解决了你的问题,我没有测试它,我的大脑仍然处于圣诞节模式。

【讨论】:

  • 非常感谢@po.pe,你启发了我。当我实施了您的第一个建议时,它就奏效了。但我想知道一些事情;如果进程中有多行,我们总是需要顺时针信号来刷新模拟器上的值以查看新值?据我了解,它按顺序而不是同步评估每个语句。它不会等到当前语句评估结束才进行下一个,对吗?好像它异步计算每个语句,对吧?
  • 这个答案的第二和第三段是不准确的。第四段有语法错误(但因为信号或评估后分配)。这个问题没有提供“mod 和 rem 操作”的预期结果,那些操作呢?您还可以将 uQ2 声明为进程中的变量,而不是避免信号更新问题的信号。否则修复工作。
  • @user1155120 您能否澄清您所指的不准确之处,我会相应地更新答案。当然,您可以在流程中添加变量,但我不想让从未使用过它们的人过于复杂……但为了完整起见,我已经添加了它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-28
  • 2013-01-06
  • 2019-01-11
相关资源
最近更新 更多