0
\$\begingroup\$

I am trying to implement an adder tree for 8 bit signed numbers using VHDL and recursion. The code works well if there is not overflow or underflow. The problem starts when I am trying to write logic to take care of saturation, the internal signals are all X so the logic to take care of saturation does not work.

I have seen that the values of internal signals like "addr_i" are undefined both on Vivado simulator and on Modelsim

Code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
-- Package Declaration Section
package def_pkg is
 type add_arr_unc is array (integer range <>) of signed(7 downto 0);
 
end package def_pkg;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
use work.def_pkg.all;
 
entity adder_tree_se is
 port ( 
 clk : in std_logic;
 a : in add_arr_unc;
 res : out signed(7 downto 0)
 );
end adder_tree_se;
 
architecture Behavioral of adder_tree_se is 
 component adder_tree_se
 port (
 clk : in std_logic;
 a : in add_arr_unc;
 res : out signed(7 downto 0)
 );
 end component;
 
 alias arrInput : add_arr_unc (0 TO a'Length-1) IS a;
 signal LowOp : signed(7 downto 0);
 signal HiOp : signed(7 downto 0);
 signal arrInput_s: signed(7 downto 0);
 signal add_i : signed(8 downto 0);
 signal Output_s : signed(7 downto 0);
begin 
 add_i <= (LowOp(7) & LowOp) + (HiOp(7) & HiOp); -- addition with sign extension 
 
 add_pr : process(clk)
 begin
 if(rising_edge(clk)) then
 Output_s <= add_i(7 downto 0); 
 arrInput_s <= arrInput(0); 
 end if;
 end process add_pr;
 
 GeneralCase:
 if arrInput'Length > 1 generate
 LowerTree: adder_tree_se
 port map (
 clk => clk,
 a => arrInput (0 TO arrInput'Length/2-1),
 res => LowOp
 );
 UpperTree: adder_tree_se
 port map (
 clk => clk,
 a => arrInput (arrInput'Length/2 TO arrInput'Length-1),
 res => HiOp
 );
 
 PullItAllTogether:
 res <= Output_s;
 end generate;
 
 BaseCase:
 if arrInput'Length = 1 generate
 PassThrough: res <= arrInput_s;
 end generate;
end Behavioral;
asked May 27, 2023 at 17:14
\$\endgroup\$
1
  • \$\begingroup\$ Interesting problem, it seems some sense of underflow/overflow needs to be passed up. Also what should happen when LowerTree underflows and UpperTree overflows. If you add tracking for the sense of overflow is it more complex than just maintaining the extra bits and then checking for underflow/overflow at the end with a full precision number. \$\endgroup\$ Commented May 27, 2023 at 20:55

1 Answer 1

1
\$\begingroup\$

In VHDL you can define the initial state of any signal when its declared.

 signal LowOp : signed(7 downto 0) := "00000000" ;--binary initializer
 signal HiOp : signed(7 downto 0) := X"00" ;--hex initializer
 signal arrInput_s: signed(7 downto 0) := (others => '0') ;--aggregate initializer
 signal add_i : signed(8 downto 0) := (others => '1') ;--aggregate initializer
 signal Output_s : signed(7 downto 0) := (0 => '1', others => '0');--aggregate initializer

This works both in simulation, and on may types of FPGAs. This includes all Xilinx FPGAs (which is like 90% of the market). The Vivado tools also support this for both simulation and synthesis.

You can even do this for signals on your port definitions to create default values when the signals are not connected. If they are connected, then whatever they are being driven with will of course overrided the default.

answered May 27, 2023 at 17:32
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.