Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Hardware vs simulation mismatch problem

Reply
Thread Tools

Hardware vs simulation mismatch problem

 
 
Patrick
Guest
Posts: n/a
 
      02-17-2011
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!
 
Reply With Quote
 
 
 
 
vcraft vcraft is offline
Junior Member
Join Date: Feb 2011
Posts: 7
 
      02-17-2011
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
 
Reply With Quote
 
 
 
 
Paul Uiterlinden
Guest
Posts: n/a
 
      02-17-2011
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.
 
Reply With Quote
 
Patrick
Guest
Posts: n/a
 
      02-27-2011

> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem with post-route simulation / timing simulation jasperng VHDL 0 11-27-2008 06:23 AM
CCNP lab - home/WAN simulation hardware setup Sian Cisco 2 04-08-2007 08:27 PM
Problem in mismatch of .NET Framework Versions Raj ASP .Net 6 02-15-2006 10:20 PM
Software simulation of hardware evolution apsolar@rediffmail.com VHDL 2 08-25-2005 04:22 PM
FS: IKOS NSIM 64 Simulation Acceleration Hardware Tristan Hunt VHDL 0 09-18-2003 11:02 AM



Advertisments