Reputation: 854
I have a question on synthesis in VHDL that I'm hoping some of you can help me with. I have the following model for a adder :
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
ENTITY Q3a IS
PORT (A_MSB,B_MSB,A_LSB,B_LSB : IN std_logic_vector(3 DOWNTO 0):="0000";
SEL : IN std_logic:='0';
CARRY : OUT std_logic:='0';
OUTPUT : OUT std_logic_vector(7 DOWNTO 0):="00000000");
END ENTITY Q3a;
ARCHITECTURE behavioral OF Q3a IS
SIGNAL A,B,SUM,B_NEG : std_logic_vector(8 DOWNTO 0);
BEGIN
A <= (A_MSB(3) & '0' & A_MSB(2 DOWNTO 0) & A_LSB) WHEN A_MSB(3) = '0' ELSE
(A_MSB(3) & '1' & A_MSB(2 DOWNTO 0) & A_LSB);
B <= (B_MSB(3) & '0' & B_MSB(2 DOWNTO 0) & B_LSB) WHEN B_MSB(3) = '0' ELSE
(B_MSB(3) & '1' & B_MSB(2 DOWNTO 0) & B_LSB);
B_NEG <= std_logic_vector(signed(not(B_MSB(3) & '0' & B_MSB(2 DOWNTO 0) & B_LSB))+1);
SUM <= std_logic_vector(signed(A)+ signed(B)) WHEN SEL = '0' ELSE
std_logic_vector(signed(A)+ signed(B_NEG));
CARRY <= SUM(7);
OUTPUT <= SUM(8) & SUM(6 DOWNTO 0);
END ARCHITECTURE behavioral;
The model works OK'ish a few glitches. When I look at it though I see 3 multiplexers, one for A, one for B, and one for input selection to the adder. When I open the model with RTL viewer on Quartus II. I get this:
Which to me looks like 4 adders and a multiplexer. Can anyone share some light with me on this? Cheers D
Upvotes: 0
Views: 467
Reputation: 56
If I understand you correctly, you want one adder for a+b and a+b_neg, and a mux that selects between b or b_neg. You didn't write it explicitly, you need to write it like so
architecture behavioral of Q3a is
signal a,b,sum,b_neg : std_logic_vector(8 downto 0);
signal b_addr : std_logic_vector(8 downto 0);
begin
a <= (a_msb(3) & a_msb & a_lsb);
b <= (b_msb(3) & b_msb & b_lsb);
b_neg <= std_logic_vector(-signed(b));
b_addr <= b when sel = '0' else b_neg;
sum <= std_logic_vector(signed(a)+ signed(b_addr));
carry <= sum(7);
output <= sum(8) & sum(6 downto 0);
end architecture behavioral;
Hopes that help you.
Upvotes: 3
Reputation: 854
After making the changes I have the following Architecture:
ARCHITECTURE behavioral OF Q3a IS
SIGNAL A,B,SUM,B_NEG : std_logic_vector(8 DOWNTO 0);
BEGIN
A <= (A_MSB(3) & A_MSB & A_LSB);
B <= (B_MSB(3) & B_MSB & B_LSB);
B_NEG <= std_logic_vector(-signed(B));
SUM <= std_logic_vector(signed(A)+ signed(B)) WHEN SEL = '0' ELSE
std_logic_vector(signed(A)+ signed(B_NEG));
CARRY <= SUM(7);
OUTPUT <= SUM(8) & SUM(6 DOWNTO 0);
END ARCHITECTURE behavioral;
The RTL synthesis diagram has changed to:
Just like Jonathan suggested it would. I understand it needs 1 adder for B_NEG, but, but is their a reason for it having separate adders for A+B and A+B_NEG followed by a Mux, instead of having a Mux and two adders? Something more like this:
Is this just synthesis choice?
Upvotes: 0
Reputation: 3388
There is a single mux in your design, as Brian noted the logic for A
is simplified to A <= A_MSB(3) & A_MSG & A_LSB
, which doesn't have a mux.
Your logic for B_neg
is wrong, as it will only give you -B
when B
is positive. If you use B_neg <= std_logic_vector(signed(not(B))+1);
you will have different synthesis results.
There should be 3 adders, one for B_neg
, one for A+B
and one for A+B_neg
. However, I suspect because of the way you define B_neg
with a constant '0'
, the synthesizer outsmart you and divide the B_neg
adder into 2 smaller adder.
You don't have to define B_neg
as "not B + 1", i.e. two's complement unary minus definition. It is better, for readability to use B_neg <= std_logic_vector(-signed(B));
or SUM <= std_logic_vector(signed(A)+signed(B)) when SEL = '0' else std_logic_vector(signed(A)-signed(B));
Upvotes: 1