is_32bit => '0', is_signed => '0', xerc => xerc_init, reserve => '0', br_pred => '0',
byte_reverse => '0', sign_extend => '0', update => '0', nia => (others => '0'), read_data1 => (others => '0'), read_data2 => (others => '0'), read_data3 => (others => '0'), cr => (others => '0'), insn => (others => '0'), data_len => (others => '0'), others => (others => '0'));
- type Execute1ToMultiplyType is record
+ type MultiplyInputType is record
valid: std_ulogic;
data1: std_ulogic_vector(63 downto 0);
data2: std_ulogic_vector(63 downto 0);
+ addend: std_ulogic_vector(127 downto 0);
is_32bit: std_ulogic;
- neg_result: std_ulogic;
+ not_result: std_ulogic;
+ end record;
+ constant MultiplyInputInit : MultiplyInputType := (valid => '0',
+ is_32bit => '0', not_result => '0',
+ others => (others => '0'));
+
+ type MultiplyOutputType is record
+ valid: std_ulogic;
+ result: std_ulogic_vector(127 downto 0);
+ overflow : std_ulogic;
end record;
- constant Execute1ToMultiplyInit : Execute1ToMultiplyType := (valid => '0',
- is_32bit => '0', neg_result => '0',
- others => (others => '0'));
+ constant MultiplyOutputInit : MultiplyOutputType := (valid => '0', overflow => '0',
+ others => (others => '0'));
type Execute1ToDividerType is record
valid: std_ulogic;
write_cr_data => (others => '0'), write_reg => (others => '0'),
exc_write_reg => (others => '0'), exc_write_data => (others => '0'));
- type MultiplyToExecute1Type is record
- valid: std_ulogic;
- result: std_ulogic_vector(127 downto 0);
- overflow : std_ulogic;
- end record;
- constant MultiplyToExecute1Init : MultiplyToExecute1Type := (valid => '0', overflow => '0',
- others => (others => '0'));
-
type DividerToExecute1Type is record
valid: std_ulogic;
write_reg_data: std_ulogic_vector(63 downto 0);
signal countzero_result: std_ulogic_vector(63 downto 0);
-- multiply signals
- signal x_to_multiply: Execute1ToMultiplyType;
- signal multiply_to_x: MultiplyToExecute1Type;
+ signal x_to_multiply: MultiplyInputType;
+ signal multiply_to_x: MultiplyOutputType;
-- divider signals
signal x_to_divider: Execute1ToDividerType;
abs2 := - signed(b_in);
end if;
- x_to_multiply <= Execute1ToMultiplyInit;
+ x_to_multiply <= MultiplyInputInit;
x_to_multiply.is_32bit <= e_in.is_32bit;
x_to_divider <= Execute1ToDividerInit;
x_to_divider.is_modulus <= '1';
end if;
- x_to_multiply.neg_result <= sign1 xor sign2;
+ x_to_multiply.not_result <= sign1 xor sign2;
+ x_to_multiply.addend <= (others => sign1 xor sign2);
x_to_divider.neg_result <= sign1 xor (sign2 and not x_to_divider.is_modulus);
if e_in.is_32bit = '0' then
-- 64-bit forms
port (
clk : in std_logic;
- m_in : in Execute1ToMultiplyType;
- m_out : out MultiplyToExecute1Type
+ m_in : in MultiplyInputType;
+ m_out : out MultiplyOutputType
);
end entity multiply;
architecture behaviour of multiply is
- signal m: Execute1ToMultiplyType := Execute1ToMultiplyInit;
+ signal m: MultiplyInputType := MultiplyInputInit;
type multiply_pipeline_stage is record
valid : std_ulogic;
data : unsigned(127 downto 0);
is_32bit : std_ulogic;
- neg_res : std_ulogic;
+ not_res : std_ulogic;
end record;
constant MultiplyPipelineStageInit : multiply_pipeline_stage := (valid => '0',
- is_32bit => '0', neg_res => '0',
+ is_32bit => '0', not_res => '0',
data => (others => '0'));
type multiply_pipeline_type is array(0 to PIPELINE_DEPTH-1) of multiply_pipeline_stage;
variable d2 : std_ulogic_vector(63 downto 0);
variable ov : std_ulogic;
begin
+ v := r;
v.multiply_pipeline(0).valid := m.valid;
- v.multiply_pipeline(0).data := unsigned(m.data1) * unsigned(m.data2);
+ v.multiply_pipeline(0).data := (unsigned(m.data1) * unsigned(m.data2)) + unsigned(m.addend);
v.multiply_pipeline(0).is_32bit := m.is_32bit;
- v.multiply_pipeline(0).neg_res := m.neg_result;
+ v.multiply_pipeline(0).not_res := m.not_result;
loop_0: for i in 1 to PIPELINE_DEPTH-1 loop
v.multiply_pipeline(i) := r.multiply_pipeline(i-1);
end loop;
- if v.multiply_pipeline(PIPELINE_DEPTH-1).neg_res = '0' then
- d := std_ulogic_vector(v.multiply_pipeline(PIPELINE_DEPTH-1).data);
- else
- d := std_ulogic_vector(- signed(v.multiply_pipeline(PIPELINE_DEPTH-1).data));
+ d := std_ulogic_vector(v.multiply_pipeline(PIPELINE_DEPTH-1).data);
+ if v.multiply_pipeline(PIPELINE_DEPTH-1).not_res = '1' then
+ d := not d;
end if;
ov := '0';
constant pipeline_depth : integer := 4;
- signal m1 : Execute1ToMultiplyType := Execute1ToMultiplyInit;
- signal m2 : MultiplyToExecute1Type;
+ signal m1 : MultiplyInputType := MultiplyInputInit;
+ signal m2 : MultiplyOutputType;
function absval(x: std_ulogic_vector) return std_ulogic_vector is
begin
stim_process: process
variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0);
variable si: std_ulogic_vector(15 downto 0);
+ variable sign: std_ulogic;
begin
wait for clk_period;
m1.data1 <= absval(ra);
m1.data2 <= absval(rb);
- m1.neg_result <= ra(63) xor rb(63);
+ sign := ra(63) xor rb(63);
+ m1.not_result <= sign;
+ m1.addend <= (others => sign);
m1.valid <= '1';
wait for clk_period;
m1.data1 <= ra;
m1.data2 <= rb;
- m1.neg_result <= '0';
+ m1.not_result <= '0';
+ m1.addend <= (others => '0');
m1.valid <= '1';
wait for clk_period;
m1.data1 <= absval(ra);
m1.data2 <= absval(rb);
- m1.neg_result <= ra(63) xor rb(63);
+ sign := ra(63) xor rb(63);
+ m1.not_result <= sign;
+ m1.addend <= (others => sign);
m1.valid <= '1';
wait for clk_period;
m1.data1(31 downto 0) <= absval(ra(31 downto 0));
m1.data2 <= (others => '0');
m1.data2(31 downto 0) <= absval(rb(31 downto 0));
- m1.neg_result <= ra(31) xor rb(31);
+ sign := ra(31) xor rb(31);
+ m1.not_result <= sign;
+ m1.addend <= (others => sign);
m1.valid <= '1';
wait for clk_period;
m1.data1(31 downto 0) <= absval(ra(31 downto 0));
m1.data2 <= (others => '0');
m1.data2(31 downto 0) <= absval(rb(31 downto 0));
- m1.neg_result <= ra(31) xor rb(31);
+ sign := ra(31) xor rb(31);
+ m1.not_result <= sign;
+ m1.addend <= (others => sign);
m1.valid <= '1';
wait for clk_period;
m1.data1(31 downto 0) <= ra(31 downto 0);
m1.data2 <= (others => '0');
m1.data2(31 downto 0) <= rb(31 downto 0);
- m1.neg_result <= '0';
+ m1.not_result <= '0';
+ m1.addend <= (others => '0');
m1.valid <= '1';
wait for clk_period;
m1.data1 <= absval(ra);
m1.data2 <= (others => '0');
m1.data2(15 downto 0) <= absval(si);
- m1.neg_result <= ra(63) xor si(15);
+ sign := ra(63) xor si(15);
+ m1.not_result <= sign;
+ m1.addend <= (others => sign);
m1.valid <= '1';
wait for clk_period;
port (
clk : in std_logic;
- m_in : in Execute1ToMultiplyType;
- m_out : out MultiplyToExecute1Type
+ m_in : in MultiplyInputType;
+ m_out : out MultiplyOutputType
);
end entity multiply;
signal p1_pat, p1_patb : std_ulogic;
signal req_32bit, r32_1 : std_ulogic;
- signal req_neg, rneg_1 : std_ulogic;
+ signal req_not, rnot_1 : std_ulogic;
signal valid_1 : std_ulogic;
begin
- addend <= (others => m_in.neg_result);
+ addend <= m_in.addend;
m00: DSP48E1
generic map (
CECTRL => '0',
CED => '0',
CEINMODE => '0',
- CEM => '1',
+ CEM => m_in.valid,
CEP => '0',
CLK => clk,
D => (others => '0'),
CECTRL => '0',
CED => '0',
CEINMODE => '0',
- CEM => '1',
+ CEM => m_in.valid,
CEP => '0',
CLK => clk,
D => (others => '0'),
CECTRL => '0',
CED => '0',
CEINMODE => '0',
- CEM => '1',
+ CEM => m_in.valid,
CEP => '0',
CLK => clk,
D => (others => '0'),
CECTRL => '0',
CED => '0',
CEINMODE => '0',
- CEM => '1',
+ CEM => m_in.valid,
CEP => '0',
CLK => clk,
D => (others => '0'),
CECTRL => '0',
CED => '0',
CEINMODE => '0',
- CEM => '1',
+ CEM => m_in.valid,
CEP => '0',
CLK => clk,
D => (others => '0'),
CECTRL => '0',
CED => '0',
CEINMODE => '0',
- CEM => '1',
+ CEM => m_in.valid,
CEP => '0',
CLK => clk,
D => (others => '0'),
CECTRL => '0',
CED => '0',
CEINMODE => '0',
- CEM => '1',
+ CEM => m_in.valid,
CEP => '0',
CLK => clk,
D => (others => '0'),
CECTRL => '0',
CED => '0',
CEINMODE => '0',
- CEM => '1',
+ CEM => m_in.valid,
CEP => '0',
CLK => clk,
D => (others => '0'),
CECTRL => '0',
CED => '0',
CEINMODE => '0',
- CEM => '1',
+ CEM => m_in.valid,
CEP => '0',
CLK => clk,
D => (others => '0'),
CECTRL => '0',
CED => '0',
CEINMODE => '0',
- CEM => '1',
+ CEM => m_in.valid,
CEP => '0',
CLK => clk,
D => (others => '0'),
CECTRL => '0',
CED => '0',
CEINMODE => '0',
- CEM => '1',
+ CEM => m_in.valid,
CEP => '0',
CLK => clk,
D => (others => '0'),
CECTRL => '0',
CED => '0',
CEINMODE => '0',
- CEM => '1',
+ CEM => m_in.valid,
CEP => '0',
CLK => clk,
D => (others => '0'),
CARRYINSEL => "000",
CARRYOUT => s0_carry,
CEA1 => '0',
- CEA2 => '1',
+ CEA2 => valid_1,
CEAD => '0',
CEALUMODE => '0',
CEB1 => '0',
- CEB2 => '1',
- CEC => '1',
+ CEB2 => valid_1,
+ CEC => valid_1,
CECARRYIN => '0',
CECTRL => '0',
CED => '0',
CARRYIN => s0_carry(3),
CARRYINSEL => "000",
CEA1 => '0',
- CEA2 => '1',
+ CEA2 => valid_1,
CEAD => '0',
CEALUMODE => '0',
CEB1 => '0',
- CEB2 => '1',
- CEC => '1',
+ CEB2 => valid_1,
+ CEC => valid_1,
CECARRYIN => '0',
CECTRL => '0',
CED => '0',
port map (
A => m21_p(22 downto 0) & m03_p(5 downto 0) & '0',
ACIN => (others => '0'),
- ALUMODE => "00" & rneg_1 & '0',
+ ALUMODE => "00" & rnot_1 & '0',
B => (others => '0'),
BCIN => (others => '0'),
C => p0_mask,
CARRYINSEL => "000",
CARRYOUT => p0_carry,
CEA1 => '0',
- CEA2 => '1',
+ CEA2 => valid_1,
CEAD => '0',
- CEALUMODE => '1',
+ CEALUMODE => valid_1,
CEB1 => '0',
- CEB2 => '1',
- CEC => '1',
+ CEB2 => valid_1,
+ CEC => valid_1,
CECARRYIN => '0',
CECTRL => '0',
CED => '0',
port map (
A => x"0000000" & '0' & m21_p(41),
ACIN => (others => '0'),
- ALUMODE => "00" & rneg_1 & '0',
+ ALUMODE => "00" & rnot_1 & '0',
B => m21_p(40 downto 23),
BCIN => (others => '0'),
C => (others => '0'),
CARRYIN => p0_carry(3),
CARRYINSEL => "000",
CEA1 => '0',
- CEA2 => '1',
+ CEA2 => valid_1,
CEAD => '0',
- CEALUMODE => '1',
+ CEALUMODE => valid_1,
CEB1 => '0',
- CEB2 => '1',
+ CEB2 => valid_1,
CEC => '0',
CECARRYIN => '0',
CECTRL => '0',
RSTP => '0'
);
- product(31 downto 0) <= product_lo xor (31 downto 0 => req_neg);
+ product(31 downto 0) <= product_lo xor (31 downto 0 => req_not);
mult_out: process(all)
variable ov : std_ulogic;
valid_1 <= m_in.valid;
req_32bit <= r32_1;
r32_1 <= m_in.is_32bit;
- req_neg <= rneg_1;
- rneg_1 <= m_in.neg_result;
+ req_not <= rnot_1;
+ rnot_1 <= m_in.not_result;
end if;
end process;