Hardware vs simulation mismatch problem

Discussion in 'VHDL' started by Patrick, Feb 17, 2011.

  1. Patrick

    Patrick Guest

    Hi all,

    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); -- 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!
     
    Patrick, Feb 17, 2011
    #1
    1. Advertising

  2. Patrick

    vcraft

    Joined:
    Feb 14, 2011
    Messages:
    7
    Hi

    1. There is a signal missing in sensitivity list of a process

    sel_out: process (res_sel, inp1)

    it should be

    sel_out: process (res_sel, inp1, tx)

    This MAY make the simulation run improperly, whilst the real hardware remains unaffected. Perhaps that's why you get different results.

    2. In same process res is a nasty asynchronous latch. Every time when you make a non-clocked process, use case statement and do not describe what happens to a signal for all possible cases, you get a mux followed by asynchronous latch.

    You should convert it to either synchronous latch (using clocked processes) or mux (by describing all possible cases, and NULL is not the solution).

    good luck
     
    vcraft, Feb 17, 2011
    #2
    1. Advertising

  3. Patrick wrote:

    > Hi all,
    >
    > 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); -- 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,


    No, I haven't looked at the function of the code yet.

    > 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?


    First of all: look at the synthesis report. I would expect at least a
    warning about tx: it is read in process sel_out and it is not in the
    sensitivity list.

    Secondly: why so many processes? It only complicates things.

    That's why I see at first glance.

    --
    Paul Uiterlinden
    www.aimvalley.nl
    e-mail addres: remove the not.
     
    Paul Uiterlinden, Feb 17, 2011
    #3
  4. Patrick

    Patrick Guest


    > First of all: look at the synthesis report. I would expect at least a
    > warning about tx: it is read in process sel_out and it is not in the
    > sensitivity list.


    Hi again,

    Thanks to your input, I implemented your suggestions, however the
    problem remains the same. I checked the synthesis report and there are
    no latches. 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;

    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
    sincethe 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). 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
     
    Patrick, Feb 27, 2011
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tristan Hunt
    Replies:
    0
    Views:
    1,526
    Tristan Hunt
    Sep 18, 2003
  2. Replies:
    2
    Views:
    533
  3. Raj
    Replies:
    6
    Views:
    1,791
    Scott M.
    Feb 15, 2006
  4. jasperng
    Replies:
    0
    Views:
    1,339
    jasperng
    Nov 27, 2008
  5. littlegamer
    Replies:
    2
    Views:
    1,504
    Antony Mathew
    Oct 14, 2014
Loading...

Share This Page