Line 84... |
Line 84... |
-- operands --
|
-- operands --
|
signal opa, opb : std_ulogic_vector(data_width_c-1 downto 0);
|
signal opa, opb : std_ulogic_vector(data_width_c-1 downto 0);
|
|
|
-- results --
|
-- results --
|
signal addsub_res : std_ulogic_vector(data_width_c downto 0);
|
signal addsub_res : std_ulogic_vector(data_width_c downto 0);
|
|
--
|
signal cp_res : std_ulogic_vector(data_width_c-1 downto 0);
|
signal cp_res : std_ulogic_vector(data_width_c-1 downto 0);
|
|
signal arith_res : std_ulogic_vector(data_width_c-1 downto 0);
|
|
signal logic_res : std_ulogic_vector(data_width_c-1 downto 0);
|
|
|
-- comparator --
|
-- comparator --
|
signal cmp_opx : std_ulogic_vector(data_width_c downto 0);
|
signal cmp_opx : std_ulogic_vector(data_width_c downto 0);
|
signal cmp_opy : std_ulogic_vector(data_width_c downto 0);
|
signal cmp_opy : std_ulogic_vector(data_width_c downto 0);
|
signal cmp_sub : std_ulogic_vector(data_width_c downto 0);
|
signal cmp_sub : std_ulogic_vector(data_width_c downto 0);
|
Line 165... |
Line 168... |
end process binary_arithmetic_core;
|
end process binary_arithmetic_core;
|
|
|
-- direct output of address result --
|
-- direct output of address result --
|
add_o <= addsub_res(data_width_c-1 downto 0);
|
add_o <= addsub_res(data_width_c-1 downto 0);
|
|
|
|
-- ALU arithmetic logic core --
|
|
arithmetic_core: process(ctrl_i, addsub_res)
|
|
begin
|
|
if (ctrl_i(ctrl_alu_arith_c) = alu_arith_cmd_addsub_c) then -- ADD/SUB
|
|
arith_res <= addsub_res(data_width_c-1 downto 0);
|
|
else -- SLT
|
|
arith_res <= (others => '0');
|
|
arith_res(0) <= addsub_res(addsub_res'left); -- => carry/borrow
|
|
end if;
|
|
end process arithmetic_core;
|
|
|
|
|
-- Shifter Unit ---------------------------------------------------------------------------
|
-- Shifter Unit ---------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
shifter_unit: process(clk_i)
|
shifter_unit: process(clk_i)
|
variable bs_input_v : std_ulogic_vector(data_width_c-1 downto 0);
|
variable bs_input_v : std_ulogic_vector(data_width_c-1 downto 0);
|
Line 274... |
Line 288... |
end if;
|
end if;
|
end if;
|
end if;
|
end process shifter_unit;
|
end process shifter_unit;
|
|
|
-- is shift operation? --
|
-- is shift operation? --
|
shifter.cmd <= '1' when (ctrl_i(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) = alu_cmd_shift_c) else '0';
|
shifter.cmd <= '1' when (ctrl_i(ctrl_alu_func1_c downto ctrl_alu_func0_c) = alu_func_cmd_shift_c) else '0';
|
shifter.start <= '1' when (shifter.cmd = '1') and (shifter.cmd_ff = '0') else '0';
|
shifter.start <= '1' when (shifter.cmd = '1') and (shifter.cmd_ff = '0') else '0';
|
|
|
-- shift operation running? --
|
-- shift operation running? --
|
shifter.run <= '1' when (or_all_f(shifter.cnt) = '1') or (shifter.start = '1') else '0';
|
shifter.run <= '1' when (or_all_f(shifter.cnt) = '1') or (shifter.start = '1') else '0';
|
shifter.halt <= '1' when (or_all_f(shifter.cnt(shifter.cnt'left downto 1)) = '1') or (shifter.start = '1') else '0';
|
shifter.halt <= '1' when (or_all_f(shifter.cnt(shifter.cnt'left downto 1)) = '1') or (shifter.start = '1') else '0';
|
Line 292... |
Line 306... |
cp_ctrl.cmd_ff <= '0';
|
cp_ctrl.cmd_ff <= '0';
|
cp_ctrl.busy <= '0';
|
cp_ctrl.busy <= '0';
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
if (CPU_EXTENSION_RISCV_M = true) then
|
if (CPU_EXTENSION_RISCV_M = true) then
|
cp_ctrl.cmd_ff <= cp_ctrl.cmd;
|
cp_ctrl.cmd_ff <= cp_ctrl.cmd;
|
if (cp_ctrl.start = '1') then
|
if ((cp0_valid_i or cp1_valid_i or cp2_valid_i or cp3_valid_i) = '1') then -- cp computation done?
|
cp_ctrl.busy <= '1';
|
|
elsif ((cp0_valid_i or cp1_valid_i or cp2_valid_i or cp3_valid_i) = '1') then -- cp computation done?
|
|
cp_ctrl.busy <= '0';
|
cp_ctrl.busy <= '0';
|
|
elsif (cp_ctrl.start = '1') then
|
|
cp_ctrl.busy <= '1';
|
end if;
|
end if;
|
else -- no co-processor(s) 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';
|
end if;
|
end if;
|
end if;
|
end if;
|
end process cp_arbiter;
|
end process cp_arbiter;
|
|
|
-- is co-processor operation? --
|
-- is co-processor operation? --
|
cp_ctrl.cmd <= '1' when (ctrl_i(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) = alu_cmd_cp_c) else '0';
|
cp_ctrl.cmd <= '1' when (ctrl_i(ctrl_alu_func1_c downto ctrl_alu_func0_c) = alu_func_cmd_copro_c) else '0';
|
cp_ctrl.start <= '1' when (cp_ctrl.cmd = '1') and (cp_ctrl.cmd_ff = '0') else '0';
|
cp_ctrl.start <= '1' when (cp_ctrl.cmd = '1') and (cp_ctrl.cmd_ff = '0') else '0';
|
cp0_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "00") else '0'; -- CP0: MULDIV CP
|
|
cp1_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "01") else '0'; -- CP1: not implemented yet
|
|
cp2_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "10") else '0'; -- CP2: not implemented yet
|
|
cp3_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "11") else '0'; -- CP3: not implemented yet
|
|
|
|
-- co-processor operation running? --
|
-- co-processor select --
|
cp_ctrl.halt <= cp_ctrl.busy or cp_ctrl.start;
|
cp0_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "00") else '0';
|
|
cp1_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "01") else '0';
|
|
cp2_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "10") else '0';
|
|
cp3_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "11") else '0';
|
|
|
|
-- co-processor operation (still) running? --
|
|
cp_ctrl.halt <= (cp_ctrl.busy and (not (cp0_valid_i or cp1_valid_i or cp2_valid_i or cp3_valid_i))) or cp_ctrl.start;
|
|
|
-- co-processor result --
|
-- co-processor result --
|
|
cp_read_back: process(clk_i)
|
|
begin
|
|
if rising_edge(clk_i) then
|
cp_res <= cp0_data_i or cp1_data_i or cp2_data_i or cp3_data_i; -- only the *actually selected* co-processor may output data != 0
|
cp_res <= cp0_data_i or cp1_data_i or cp2_data_i or cp3_data_i; -- only the *actually selected* co-processor may output data != 0
|
|
end if;
|
|
end process cp_read_back;
|
|
|
|
|
|
-- ALU Logic Core -------------------------------------------------------------------------
|
|
-- -------------------------------------------------------------------------------------------
|
|
alu_logic_core: process(ctrl_i, rs1_i, opb)
|
|
begin
|
|
case ctrl_i(ctrl_alu_logic1_c downto ctrl_alu_logic0_c) is
|
|
when alu_logic_cmd_movb_c => logic_res <= opb; -- (default)
|
|
when alu_logic_cmd_xor_c => logic_res <= rs1_i xor opb; -- only rs1 required for logic ops (opa would also contain pc)
|
|
when alu_logic_cmd_or_c => logic_res <= rs1_i or opb;
|
|
when alu_logic_cmd_and_c => logic_res <= rs1_i and opb;
|
|
when others => logic_res <= opb; -- undefined
|
|
end case;
|
|
end process alu_logic_core;
|
|
|
|
|
-- ALU Function Select --------------------------------------------------------------------
|
-- ALU Function Select --------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
alu_function_mux: process(ctrl_i, rs1_i, opb, addsub_res, cp_res, shifter.sreg)
|
alu_function_mux: process(ctrl_i, arith_res, logic_res, shifter.sreg, cp_res)
|
begin
|
begin
|
case ctrl_i(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) is
|
case ctrl_i(ctrl_alu_func1_c downto ctrl_alu_func0_c) is
|
when alu_cmd_xor_c => res_o <= rs1_i xor opb; -- only rs1 required for logic ops (opa would also contain pc)
|
when alu_func_cmd_arith_c => res_o <= arith_res; -- (default)
|
when alu_cmd_or_c => res_o <= rs1_i or opb;
|
when alu_func_cmd_logic_c => res_o <= logic_res;
|
when alu_cmd_and_c => res_o <= rs1_i and opb;
|
when alu_func_cmd_shift_c => res_o <= shifter.sreg;
|
when alu_cmd_movb_c => res_o <= opb;
|
when alu_func_cmd_copro_c => res_o <= cp_res;
|
when alu_cmd_addsub_c => res_o <= addsub_res(data_width_c-1 downto 0);
|
when others => res_o <= arith_res; -- undefined
|
when alu_cmd_cp_c => res_o <= cp_res;
|
|
when alu_cmd_shift_c => res_o <= shifter.sreg;
|
|
when alu_cmd_slt_c => res_o <= (others => '0'); res_o(0) <= addsub_res(addsub_res'left); -- => carry/borrow
|
|
when others => res_o <= opb; -- undefined
|
|
end case;
|
end case;
|
end process alu_function_mux;
|
end process alu_function_mux;
|
|
|
|
|
-- ALU Busy -------------------------------------------------------------------------------
|
-- ALU Busy -------------------------------------------------------------------------------
|