Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
556 views
in Technique[技术] by (71.8m points)

vhdl - waveform does not work properly for some operations

i am newbie in vhdl, modelsim, waveform etc. i've developed a simple operational process and a testbench to test my operations one by one on modelsim waveform.

when i run at simulator i see there are some problems; at multiply operation result is not put to output variable (result_out1) although it is calculated correctly at temp variable (uQ2). furthermore mod and rem operations do not give any output.

although add, sub and div operations work as expected why mul, mod and rem operaions fail?

i am sharing my code and waveform result below.

my code and testbench are below;

 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;

thanks in advance.

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

To be honest I'd suggest to use only clocked processes until you fully understand how they work. But let's see if we can fix your problem.

The problem is with the sensitivity list of your process. The simulation tool will evaluate the result of the process whenever a signal in the sensitivity list changes. For all operations this is signal op that changes and the process re-evaluates uQ.

Important note: Sensitivity lists only serve for simulation purpose and signals are assigned after the process evaluation is complete.

The above means that in case of your multiplication, the op changes to 010 and the process evaluates

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

but because signals are assigned after evaluation, uQ2 will have the result of the multiplication but uQ is the resize of the previous uQ2. To fix this you can either...

  1. Not use uQ2 and directly write uQ <= resize(uA * uB, uQ'length)
  2. Extend the sensitivity list with uQ2 so that uQ is re-evaluated once uQ2 got updated.
  3. As correctly mentioned in the comment, if you need "signals" in a process that are evaluated immediately use variables instead of signal types.

The result assignment can be optimized and to be honest, I would't use Z in this case.

  --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');

In general, this implementation has some pitfalls and you might should add some additional control signals or even make it a clocked process. Check if this solves your issue, I didn't test it and my brain is still in Christmas mode.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...