11-17-2009 02:41 AM
I am working on a VHDL project, in which i need to multiply two numbers, M1 et M2.
M1 is defined on 8 bits as a signed fixed point number : "0 0.000000"
M2 is a 16 bits signed integer "0 000000000000000"
Mathematically speaking the answer of the multiplication should be coded on 24 bit ("0 00000000000000000000000")
In VHDL, can we multiply two numbers that do not have the same length?
If not, we must then extend the smallest with its sign bit.
M1' <= (M1(7)& M1(7)& M1(7)& M1(7)& M1(7)& M1(7)& M1(7)& M1(7)&M1);
It induces a multiplication result (M1'xM2) of 32 bits but 24 are enough to code the "real" resul...
Therefore, i tried that :
Res : std_logic_vector ( 23 downto 0); ... Res <= ((M1(7)& M1(7)& M1(7)& M1(7)& M1(7)& M1(7)& M1(7)& M1(7)&M1))*M2;
But in this case, i have warning in the synthesys, telling that i have a lenght missmatch...
I then wrote that :
entity Synchro_voies is PORT ( Clk : in std_logic; Raz : in std_logic; M1 : in std_logic_vector (15 downto 0); M2 : in std_logic_vector (7 downto 0); Res : in std_logic_vector (23 downto 0) ); end Synchro_voies; architecture Behavioral of Synchro_voies is signal Res1 : std_logic_vector (31 downto 0); begin Res <= Res1 (23 downto 0); Phase_treat : process (Clk, RAZ) begin if Raz = '1' then Res1 <= (others => '0'); elsif Clk'event and Clk = '1' then Res1 <= ((M2(7)&M2(7)&M2(7)&M2(7)&M2(7)&M2(7)&M2(7)&M2(7)&M2)*M1); end if; end process; end Behavioral;
But in this case, is the Res1 registrer mandatory/usefull???
11-17-2009 04:14 AM - edited 11-17-2009 04:18 AM
instead of concatenating I would suggest you have a look at function RESIZE. Plus, in ieee.numeric_std there are quite alot other functions defined as well. Like for example arithmetic operators for signed based signals.
So you could declare two signals:
signal A : signed (15 downto 0);
signal B : signed (15 downto 0);
And then resize M1 on the fly while assigning it
A <= RESIZE(signed(M1),16)
Resize will preserve the signed MSB bit.
function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
-- Result subtype: SIGNED(NEW_SIZE-1 downto 0)
-- Result: Resizes the SIGNED vector ARG to the specified size.
-- To create a larger vector, the new [leftmost] bit positions
-- are filled with the sign bit (ARG'LEFT). When truncating,
-- the sign bit is retained along with the rightmost part.
Hope that helps.
I forgot to add. Yes, that result register might not be a bad idea. Though, if you would assign the result to the output port within the synchronous process, it should result into a registered assignement as well. One more thing, remember that you might want to handle fixed point values differently than integer based values.
11-17-2009 08:48 AM
>In VHDL, can we multiply two numbers that do not have the same length?
Yes, that's perfectly OK. signed data type is supported by XST, all you need is to use the IEEE numeric_std package. e.g.
signal mult_a : signed(7 downto 0);
signal mult_b : signed(15 downto 0);
signal mult_p : signed(23 downto 0);
mult_p <= mult_a * mult_b;
07-12-2019 05:01 AM
Dear @ywu I had a rather primitive question about this part,
when you have an A-bit signed multiplied by a B-bit signed, each will have 1 bit representing the sign and (A-1) and (B-1) bits of values. So the multiplication will need (A-1)+(B-1) bits for the value and 1 bit for the sign, which will be A+B-1 in total. But in your example, mult_p has A+B bits. Is there an automatic sign extension involved? I just want to know what is the arrangement of bits and the sign in this result.
07-12-2019 05:22 AM
Strongly suggest u open a new question of your own, not add to this old post.