I'm trying to implement a floating point adder/subtractor. I've already achieved the code to work. When I run the simulation it works as expected.
The thing is when I try to synthesize it in Vivado I get this errors: "constant expression required width mismatch in assignment" and "target has 279 bits, source has 86 bits" on a line that says:
my_p_nt_a <= to_unsigned(0, to_integer(abs_exp_diff)) & my_p & to_unsigned(0, 2**NE - 1- to_integer(abs_exp_diff));
This corresponds to the mantissa's alignment.
Some more info:
signal my_p_nt_a: unsigned(NF + 2**NE-1 downto 0);
signal abs_exp_diff: unsigned(NE downto 0);
NE is the number of bits the exponent has.
I don't know how to solve it. I've tried different ways but I keep getting problems when synthesizing.
I'm trying to implement a floating point adder/subtractor. I've already achieved the code to work. When I run the simulation it works as expected.
The thing is when I try to synthesize it in Vivado I get this errors: "constant expression required width mismatch in assignment" and "target has 279 bits, source has 86 bits" on a line that says:
my_p_nt_a <= to_unsigned(0, to_integer(abs_exp_diff)) & my_p & to_unsigned(0, 2**NE - 1- to_integer(abs_exp_diff));
This corresponds to the mantissa's alignment.
Some more info:
signal my_p_nt_a: unsigned(NF + 2**NE-1 downto 0);
signal abs_exp_diff: unsigned(NE downto 0);
NE is the number of bits the exponent has.
I don't know how to solve it. I've tried different ways but I keep getting problems when synthesizing.
The meaning of the error message is, in Vivado synthesis you can't extend your operand by a number of 0's where the number depends on the value at abs_exp_diff. This works only, if abs_exp_diff would be a constant. I expect most of the synthesis tools will not be able to do this.
Instead you should use this solution:
entity test_shift is
end entity test_shift;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
architecture struct of test_shift is
constant NF : natural := 10; -- example value
constant NE : natural := 12; -- example value
signal abs_exp_diff : unsigned(NE downto 0);
signal my_p : unsigned(NF-1 downto 0);
signal my_p_nt_a : unsigned(NF+2**NE-1 downto 0);
begin
process(my_p, abs_exp_diff)
variable my_p_nt_a_v : unsigned(my_p_nt_a'range);
begin
my_p_nt_a_v := (others => '0');
my_p_nt_a_v(my_p'range) := my_p;
my_p_nt_a <= shift_left(my_p_nt_a_v, 2*NE-1-to_integer(abs_exp_diff));
end process;
end architecture;
Edit: You could also use a function:
function insert_my_p (my_p : in unsigned(NF-1 downto 0);
abs_exp_diff : in unsigned(NE downto 0))
return unsigned is
variable my_p_nt_a_v : unsigned(NF+2**NE-1 downto 0);
begin
my_p_nt_a_v := (others => '0');
my_p_nt_a_v(my_p'range) := my_p;
return shift_left(my_p_nt_a_v, 2*NE-1-to_integer(abs_exp_diff));
end function;