Line 111... |
Line 111... |
rb_ff0 : std_ulogic;
|
rb_ff0 : std_ulogic;
|
rb_ff1 : std_ulogic;
|
rb_ff1 : std_ulogic;
|
end record;
|
end record;
|
signal cp_ctrl : cp_ctrl_t;
|
signal cp_ctrl : cp_ctrl_t;
|
|
|
|
-- bit manipulation --
|
|
signal bitm_res : std_ulogic_vector(31 downto 0);
|
|
|
begin
|
begin
|
|
|
-- Operand Mux ----------------------------------------------------------------------------
|
-- Operand Mux ----------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
input_op_mux: process(ctrl_i, csr_i, pc2_i, rs1_i, rs2_i, imm_i)
|
input_op_mux: process(ctrl_i, csr_i, pc2_i, rs1_i, rs2_i, imm_i)
|
Line 161... |
Line 164... |
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
add_res <= std_ulogic_vector(unsigned(opa) + unsigned(opb));
|
add_res <= std_ulogic_vector(unsigned(opa) + unsigned(opb));
|
add_o <= add_res; -- direct output
|
add_o <= add_res; -- direct output
|
|
|
|
|
|
-- Bit Manipulation Unit ------------------------------------------------------------------
|
|
-- -------------------------------------------------------------------------------------------
|
|
|
|
-- ------------------ --
|
|
-- UNDER CONSTRUCTION --
|
|
-- ------------------ --
|
|
|
|
--bitm_minmax <= rs1_i when ((cmp_less xor ???) = '1') else rs2_i; -- min[u] / max[u]
|
|
|
|
-- result of bit manipulation operation --
|
|
bitm_res <= opa and (not opb); -- ANDN
|
|
|
|
|
-- Iterative Shifter Unit -----------------------------------------------------------------
|
-- Iterative Shifter Unit -----------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
shifter_unit: process(rstn_i, clk_i)
|
shifter_unit: process(rstn_i, clk_i)
|
begin
|
begin
|
if (rstn_i = '0') then
|
if (rstn_i = '0') then
|
Line 175... |
Line 191... |
shifter.cmd_ff <= shifter.cmd;
|
shifter.cmd_ff <= shifter.cmd;
|
if (shifter.start = '1') then -- trigger new shift
|
if (shifter.start = '1') then -- trigger new shift
|
shifter.sreg <= opa; -- shift operand
|
shifter.sreg <= opa; -- shift operand
|
shifter.cnt <= opb(index_size_f(data_width_c)-1 downto 0); -- shift amount
|
shifter.cnt <= opb(index_size_f(data_width_c)-1 downto 0); -- shift amount
|
elsif (shifter.run = '1') then -- running shift
|
elsif (shifter.run = '1') then -- running shift
|
-- coarse shift -> multiples of 4 --
|
-- coarse shift: multiples of 4 --
|
if (or_all_f(shifter.cnt(shifter.cnt'left downto 2)) = '1') then -- shift amount >= 4
|
if (or_all_f(shifter.cnt(shifter.cnt'left downto 2)) = '1') then -- shift amount >= 4
|
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 4);
|
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 4);
|
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical
|
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical
|
shifter.sreg <= shifter.sreg(shifter.sreg'left-4 downto 0) & "0000";
|
shifter.sreg <= shifter.sreg(shifter.sreg'left-4 downto 0) & "0000";
|
else -- SRL: shift right logical / SRA: shift right arithmetical
|
else -- SRL: shift right logical / SRA: shift right arithmetical
|
shifter.sreg <= (shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) &
|
shifter.sreg <= (shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) &
|
(shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) &
|
(shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) &
|
(shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) &
|
(shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) &
|
(shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & shifter.sreg(shifter.sreg'left downto 4);
|
(shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & shifter.sreg(shifter.sreg'left downto 4);
|
end if;
|
end if;
|
-- fine shift -> 0..3 --
|
-- fine shift: single shifts, 0..3 times --
|
else
|
else
|
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 1);
|
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 1);
|
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical
|
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical
|
shifter.sreg <= shifter.sreg(shifter.sreg'left-1 downto 0) & '0';
|
shifter.sreg <= shifter.sreg(shifter.sreg'left-1 downto 0) & '0';
|
else -- SRL: shift right logical / SRA: shift right arithmetical
|
else -- SRL: shift right logical / SRA: shift right arithmetical
|
Line 228... |
Line 244... |
cp_ctrl.busy <= '1';
|
cp_ctrl.busy <= '1';
|
elsif ((cp0_valid_i or cp1_valid_i) = '1') then -- cp computation done?
|
elsif ((cp0_valid_i or cp1_valid_i) = '1') then -- cp computation done?
|
cp_ctrl.busy <= '0';
|
cp_ctrl.busy <= '0';
|
cp_ctrl.rb_ff0 <= '1';
|
cp_ctrl.rb_ff0 <= '1';
|
end if;
|
end if;
|
else -- no co-processors implemented
|
else -- no co-processor(s) implemented
|
cp_ctrl.cmd_ff <= '0';
|
cp_ctrl.cmd_ff <= '0';
|
cp_ctrl.busy <= '0';
|
cp_ctrl.busy <= '0';
|
cp_ctrl.rb_ff0 <= '0';
|
cp_ctrl.rb_ff0 <= '0';
|
cp_ctrl.rb_ff1 <= '0';
|
cp_ctrl.rb_ff1 <= '0';
|
end if;
|
end if;
|
Line 248... |
Line 264... |
cp_ctrl.halt <= cp_ctrl.busy or cp_ctrl.start;
|
cp_ctrl.halt <= cp_ctrl.busy or cp_ctrl.start;
|
|
|
|
|
-- ALU Function Select --------------------------------------------------------------------
|
-- ALU Function Select --------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
alu_function_mux: process(ctrl_i, opa, opb, add_res, sub_res, cmp_less, shifter)
|
alu_function_mux: process(ctrl_i, opa, opb, add_res, sub_res, cmp_less, shifter, bitm_res)
|
begin
|
begin
|
case ctrl_i(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) is
|
case ctrl_i(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) is
|
when alu_cmd_bitc_c => alu_res <= opa and (not opb); -- bit clear (for CSR modifications only)
|
when alu_cmd_bitm_c => alu_res <= bitm_res;
|
when alu_cmd_xor_c => alu_res <= opa xor opb;
|
when alu_cmd_xor_c => alu_res <= opa xor opb;
|
when alu_cmd_or_c => alu_res <= opa or opb;
|
when alu_cmd_or_c => alu_res <= opa or opb;
|
when alu_cmd_and_c => alu_res <= opa and opb;
|
when alu_cmd_and_c => alu_res <= opa and opb;
|
when alu_cmd_sub_c => alu_res <= sub_res;
|
when alu_cmd_sub_c => alu_res <= sub_res;
|
when alu_cmd_add_c => alu_res <= add_res;
|
when alu_cmd_add_c => alu_res <= add_res;
|