J
jmariano
Guest
Dear All,
I'm not an expert in VHDL, i'm just a curious trying to solve a
research problem with an FPGA.
I'm using a 32 bit accumulator in a IP, as part of a SoC project with
a microblaze, implemented in a Digilent Spartan-3 SKB ( the FPGA is a
Xilinx XC3S200). The code is included at the end of this message. The
input is a 32 bit signed integer coded in two's complement and the
output also a 32 bit signed integer. What I would like the accumulator
to do is to accumulate synchronously with the rising edge of clk when
enb=1 and maintain the result stable at the output when enb=0 ( enb is
a asynchronous signal generated elsewhere in the system)
But it does not work in this way, it behaves in a strange manner...
Some times I get the expected results but often I get strange values
(large when they should be small, often negative instead of positive,
etc.). If I look at the binary representation of the output, it looks
like if the output din't had time to sum and propagate to the output
again. In fact, the post place and route simulation shows that when
the enb signal goes to 0, the output stays in a undetermined condition
(you know, red line with XXXX).
I'm guessing I'm doing a very basic mistake that as something to do
with the timing of the enb signal, but after 3 days banging my had to
the wall, all I have is a a monumental headache.
Can some kind soul help me with this?
jmariano
================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity int_accum is
port (clk:in std_logic;
clr:in std_logic;
enb:in std_logic;
d: in std_logic_vector(31 downto 0);
ovfut std_logic; -- overflow
q: out std_logic_vector(31 downto 0));
end int_accum;
architecture archi of int_accum is
signal tmp : signed(32 downto 0);
begin
process(clk, clr)
begin
if (clr = '1') then
tmp <= (others => '0');
elsif (rising_edge (clk)) then
if (enb = '1') then
-- The result of the adder will be on 33 bits to keep the carry
tmp <= tmp + signed ('0'& d);
end if;
end if;
end process;
-- The carry is extracted from the most significant bit of the
result
ovf <= tmp(32);
-- The q output is the 32 least significant bits of sum
q <= std_logic_vector (tmp(31 downto 0));
end archi;
I'm not an expert in VHDL, i'm just a curious trying to solve a
research problem with an FPGA.
I'm using a 32 bit accumulator in a IP, as part of a SoC project with
a microblaze, implemented in a Digilent Spartan-3 SKB ( the FPGA is a
Xilinx XC3S200). The code is included at the end of this message. The
input is a 32 bit signed integer coded in two's complement and the
output also a 32 bit signed integer. What I would like the accumulator
to do is to accumulate synchronously with the rising edge of clk when
enb=1 and maintain the result stable at the output when enb=0 ( enb is
a asynchronous signal generated elsewhere in the system)
But it does not work in this way, it behaves in a strange manner...
Some times I get the expected results but often I get strange values
(large when they should be small, often negative instead of positive,
etc.). If I look at the binary representation of the output, it looks
like if the output din't had time to sum and propagate to the output
again. In fact, the post place and route simulation shows that when
the enb signal goes to 0, the output stays in a undetermined condition
(you know, red line with XXXX).
I'm guessing I'm doing a very basic mistake that as something to do
with the timing of the enb signal, but after 3 days banging my had to
the wall, all I have is a a monumental headache.
Can some kind soul help me with this?
jmariano
================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity int_accum is
port (clk:in std_logic;
clr:in std_logic;
enb:in std_logic;
d: in std_logic_vector(31 downto 0);
ovfut std_logic; -- overflow
q: out std_logic_vector(31 downto 0));
end int_accum;
architecture archi of int_accum is
signal tmp : signed(32 downto 0);
begin
process(clk, clr)
begin
if (clr = '1') then
tmp <= (others => '0');
elsif (rising_edge (clk)) then
if (enb = '1') then
-- The result of the adder will be on 33 bits to keep the carry
tmp <= tmp + signed ('0'& d);
end if;
end if;
end process;
-- The carry is extracted from the most significant bit of the
result
ovf <= tmp(32);
-- The q output is the 32 least significant bits of sum
q <= std_logic_vector (tmp(31 downto 0));
end archi;