Line 60... |
Line 60... |
-- data output --
|
-- data output --
|
cmp_o : out std_ulogic_vector(1 downto 0); -- comparator status
|
cmp_o : out std_ulogic_vector(1 downto 0); -- comparator status
|
add_o : out std_ulogic_vector(data_width_c-1 downto 0); -- OPA + OPB
|
add_o : out std_ulogic_vector(data_width_c-1 downto 0); -- OPA + OPB
|
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- ALU result
|
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- ALU result
|
-- co-processor interface --
|
-- co-processor interface --
|
|
cp_opa_o : out std_ulogic_vector(data_width_c-1 downto 0); -- co-processor operand a
|
|
cp_opb_o : out std_ulogic_vector(data_width_c-1 downto 0); -- co-processor operand b
|
cp0_start_o : out std_ulogic; -- trigger co-processor 0
|
cp0_start_o : out std_ulogic; -- trigger co-processor 0
|
cp0_data_i : in std_ulogic_vector(data_width_c-1 downto 0); -- co-processor 0 result
|
cp0_data_i : in std_ulogic_vector(data_width_c-1 downto 0); -- co-processor 0 result
|
cp0_valid_i : in std_ulogic; -- co-processor 0 result valid
|
cp0_valid_i : in std_ulogic; -- co-processor 0 result valid
|
cp1_start_o : out std_ulogic; -- trigger co-processor 1
|
cp1_start_o : out std_ulogic; -- trigger co-processor 1
|
cp1_data_i : in std_ulogic_vector(data_width_c-1 downto 0); -- co-processor 1 result
|
cp1_data_i : in std_ulogic_vector(data_width_c-1 downto 0); -- co-processor 1 result
|
Line 79... |
Line 81... |
signal opa, opb, opc : std_ulogic_vector(data_width_c-1 downto 0);
|
signal opa, opb, opc : std_ulogic_vector(data_width_c-1 downto 0);
|
|
|
-- results --
|
-- results --
|
signal add_res : std_ulogic_vector(data_width_c-1 downto 0);
|
signal add_res : std_ulogic_vector(data_width_c-1 downto 0);
|
signal alu_res : std_ulogic_vector(data_width_c-1 downto 0);
|
signal alu_res : std_ulogic_vector(data_width_c-1 downto 0);
|
|
signal cp_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 106... |
Line 109... |
type cp_ctrl_t is record
|
type cp_ctrl_t is record
|
cmd_ff : std_ulogic;
|
cmd_ff : std_ulogic;
|
busy : std_ulogic;
|
busy : std_ulogic;
|
start : std_ulogic;
|
start : std_ulogic;
|
halt : std_ulogic;
|
halt : std_ulogic;
|
rb_ff0 : 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 164... |
Line 162... |
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
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 231... |
Line 216... |
cp_arbiter: process(rstn_i, clk_i)
|
cp_arbiter: process(rstn_i, clk_i)
|
begin
|
begin
|
if (rstn_i = '0') then
|
if (rstn_i = '0') then
|
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_ff1 <= '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 <= ctrl_i(ctrl_cp_use_c);
|
cp_ctrl.cmd_ff <= ctrl_i(ctrl_cp_use_c);
|
cp_ctrl.rb_ff0 <= '0';
|
|
cp_ctrl.rb_ff1 <= cp_ctrl.rb_ff0;
|
|
if (cp_ctrl.start = '1') then
|
if (cp_ctrl.start = '1') then
|
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';
|
|
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';
|
cp_ctrl.rb_ff0 <= '0';
|
|
cp_ctrl.rb_ff1 <= '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? --
|
Line 261... |
Line 239... |
cp1_start_o <= '0'; -- not yet implemented
|
cp1_start_o <= '0'; -- not yet implemented
|
|
|
-- co-processor operation running? --
|
-- co-processor operation running? --
|
cp_ctrl.halt <= cp_ctrl.busy or cp_ctrl.start;
|
cp_ctrl.halt <= cp_ctrl.busy or cp_ctrl.start;
|
|
|
|
-- co-processor operands --
|
|
cp_opa_o <= opa;
|
|
cp_opb_o <= opb;
|
|
|
|
-- co-processor result --
|
|
cp_res <= cp0_data_i or cp1_data_i; -- only the selcted cp may output data != 0
|
|
|
|
|
-- ALU Function Select --------------------------------------------------------------------
|
-- ALU Function Select --------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
alu_function_mux: process(ctrl_i, opa, opb, add_res, sub_res, cmp_less, shifter, bitm_res)
|
alu_function_mux: process(ctrl_i, opa, opb, add_res, sub_res, cmp_less, shifter)
|
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_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_bclr_c => alu_res <= opa and (not 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;
|
when alu_cmd_shift_c => alu_res <= shifter.sreg;
|
when alu_cmd_shift_c => alu_res <= shifter.sreg;
|
when alu_cmd_slt_c => alu_res <= (others => '0'); alu_res(0) <= cmp_less;
|
when alu_cmd_slt_c => alu_res <= (others => '0'); alu_res(0) <= cmp_less;
|
when others => alu_res <= (others => '0'); -- undefined
|
when others => alu_res <= (others => '0'); -- undefined
|
Line 283... |
Line 268... |
|
|
|
|
-- ALU Result -----------------------------------------------------------------------------
|
-- ALU Result -----------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
wait_o <= shifter.halt or cp_ctrl.halt; -- wait until iterative units have completed
|
wait_o <= shifter.halt or cp_ctrl.halt; -- wait until iterative units have completed
|
res_o <= (cp0_data_i or cp1_data_i) when (cp_ctrl.rb_ff1 = '1') else alu_res; -- FIXME
|
res_o <= cp_res when (ctrl_i(ctrl_cp_use_c) = '1') else alu_res; -- FIXME?
|
|
|
|
|
end neorv32_cpu_cpu_rtl;
|
end neorv32_cpu_cpu_rtl;
|
|
|
No newline at end of file
|
No newline at end of file
|