-1

Thanks to all your input, I implemented your suggestions, however the problem remains the same. The result in simulation works fine, but the hardware outputs something different. Just to briefly recap, 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")  res := (op1 << 1) | tx;
                           tx  := tx >> 31;

Here is the VHDL code:

    library ieee;
    use ieee.std_logic_1164.all;

     entity test is
     port
     (
       op1   : in  std_logic_vector(31 downto 0);      -- 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;

       sel_out: process (res_sel, inp1, tx)
       begin

         case res_sel is

          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               (this sets tx <= 0 )
   SH1_L 0xfedcba90     exp. output: 0xfdb97520  act. output = 0xfdb97521
   SH1_L 0x7654321f     exp. output: 0xeca8643f  act. output = 0xeca8643f
   SH1_L 0x71234567     exp. output: 0xe2468ace  act. output = 0xe2468ace

As you can see, the last bit is wrong for the first SH1_L operation. The first SH1_L operation produces a carry for the NEXT SH1_L operation since the MSB is set to one of the input, however, it seems that this carry is already considered in the current SH1_L operation, which is wrong (tx should be zero). I checked the synthesis report and there are no latches, so I am a bit clueless and almost desperate what is going wrong here. I use Xilinx ISE 12.1 for synthesis, could there be a problem because I do not have a reset signal in my architecture, that the wrong kind of latches are instantiated?

Many thanks for further helpful comments to solve this issue, Patrick

toolic
  • 57,801
  • 17
  • 75
  • 117

1 Answers1

0

Unlike RTL simulation, real-life timing of inputs and clocks is not ideal. For example, the clock tree might have a longer delay than input buffers or vice versa. Did you take this into account?

Jan Decaluwe
  • 2,405
  • 19
  • 18
  • I have to admit I am not sure how I can check that. I just checked that no latches and other warnings came up during sythesis. Further, the design does not violate the critical path. Can I redesign my module to avoid such race conditions? Many thanks – Patrick Feb 27 '11 at 23:46
  • I am not talking about the design, but about how the input signals / clocks are applied in practice on the hardware, i.e. input signals should not change close to the rising clock edge. – Jan Decaluwe Feb 28 '11 at 08:39