开发者

Simulation vs hardware mismatch

开发者 https://www.devze.com 2023-02-10 22:17 出处:网络
I have a very simple problem but I do not get my head around what is going wrong. Essentially, the whole thing works fine when simulating it, however, having it

I have a very simple problem but I do not get my head around what is going wrong. Essentially, the whole thing works fine when simulating it, however, having it in hardware gives me the wrong result. Basically I have two ctrl signals that determine the behaviour of the entity:

 GET   (ctrl = "00000000") sets register tx to input of op1
 SH1_L (ctrl = "00000001") outputs (op1 << 1) or register tx
                           shifts register tx to the right by 31 bits  (tx >> 31)


  library ieee;
  use ieee.std_logic_1164.all;

  entity test is
  port
  (
    op1    : in  std_logic_vector(31 downto 0);      -- First input operand
    ctrl   : in std_logic_vector(7 downto 0);        -- Control signal
    clk    : in  std_logic;                          -- clock
    res    : out std_logic_vector(31 downto 0)       -- Result
  );
  end;

  architecture rtl of test is

    type res_sel_type is (GET, SH1_L); 

    constant Z : std_logic_vector(31 downto 0) := (others => '0');                        

    signal res_sel  : res_sel_type;
    signal load     : std_logic := '0';
    signal shl      : std_logic := '0';

    signal tx       : std_logic_vector(31 downto 0) := (others => '0');
    signal inp1     : std_logic_vector(31 downto 0) := (others => '0');

  begin

    dec_op: process (ctrl, op1)
    begin  

        res_sel  <= GET;
      load     <= '0';
      shl      <= '0';
      inp1     <= ( others => '0');

      case ctrl is

         -- store operand 
             when "00000000" =>
                inp1    <= op1;             
                load    <= '1';          
                res_sel <= GET;

             -- 1-bit left-shift with carry 
             when "00000001" =>
              inp1    <= op1;
          shl     <= '1'; 
                res_sel <= SH1_L;

             when others =>
                -- Leave default values

             end case;                  

    end process;

    -- Selection of output
    sel_out: process (res_sel, inp1) 
    begin

      case res_sel is

       when GET => NULL;  

       when SH1_L =>
        res  <= ( inp1(30 downto 0) & '0' ) or tx;
开发者_开发技巧
         when others =>
            res <= (others => '0');

      end case;

    end process;

    sync: process(clk)
    begin       
     if clk'event and clk = '1' then
          if load = '1' then  
             tx <= op1;
          elsif shl = '1' then
             tx <= Z(30 downto 0) & op1(31);
          end if;      
     end if;
    end process;  

  end rtl;

TESTPROGRAM

GET  0
SH1_L 0xfedcba90    exp. output: 0xfdb97520  act. output = 0xfdb97521
SH1_L 0x7654321f    exp. output: 0xeca8643f  act. output = 0xeca8643e
SH1_L 0x71234567    exp. output: 0xe2468ace  act. output = 0xe2468ace

As you can see, the last bit is wrong for some reason. I must have something wrong with the timing, so that the register tx is first written before it is acutally used in the computation of the output.

Anyone an idea how to solve this problem?

Many thanks!


Didn't you forget the tx signal in your process sensitivity list?

Simulation vs hardware mismatch


res is not defined under all conditions in a combinatorial process. Therefore, you will presumably have latches gated by logic in the synthesis result. Never a good idea.

Start by removing them by providing a default assignment.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号