P
Patrick
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!
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!