Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rtl] CPU: use record as main control bus type #489

Merged
merged 3 commits into from
Feb 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ mimpid = 0x01040312 => Version 01.04.03.12 => v1.4.3.12

| Date (*dd.mm.yyyy*) | Version | Comment |
|:-------------------:|:-------:|:--------|
| 10.02.2023 | 1.8.0.4 | replace CPU-internal control bus by a VHDL `record` (much cleaner code); minor control optimizations; add 6ht CPU co-processor slot (yet unused); [#489](https://github.com/stnolting/neorv32/pull/489) |
| 05.02.2023 | 1.8.0.3 | CPU control optimizations; [#487](https://github.com/stnolting/neorv32/pull/487) |
| 04.02.2023 | 1.8.0.2 | fix RISC-V-incompatible behavior of `mip` CSR; [#486](https://github.com/stnolting/neorv32/pull/486) |
| 01.02.2023 | 1.8.0.1 | clean-up CPU's interrupt controller; fix race condition in FIRQ trigger/acknowledge; [#484](https://github.com/stnolting/neorv32/pull/484) |
Expand Down
26 changes: 12 additions & 14 deletions rtl/core/neorv32_cpu.vhd
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
-- #################################################################################################
-- # << NEORV32 - CPU Top Entity >> #
-- # ********************************************************************************************* #
-- # Check out the CPU's online documentation for more information: #
-- # HQ: https://github.com/stnolting/neorv32 #
-- # Data Sheet: https://stnolting.github.io/neorv32 #
-- # User Guide: https://stnolting.github.io/neorv32/ug #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2023, Stephan Nolting. All rights reserved. #
Expand Down Expand Up @@ -34,7 +29,7 @@
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
-- # OF THE POSSIBILITY OF SUCH DAMAGE. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- # The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################

library ieee;
Expand Down Expand Up @@ -129,7 +124,7 @@ architecture neorv32_cpu_rtl of neorv32_cpu is
constant ipb_depth_c : natural := cond_sel_natural_f(ipb_override_c, 2, CPU_IPB_ENTRIES);

-- local signals --
signal ctrl : std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
signal ctrl : ctrl_bus_t; -- main control bus
signal imm : std_ulogic_vector(XLEN-1 downto 0); -- immediate
signal rs1 : std_ulogic_vector(XLEN-1 downto 0); -- source register 1
signal rs2 : std_ulogic_vector(XLEN-1 downto 0); -- source register 2
Expand All @@ -139,7 +134,8 @@ architecture neorv32_cpu_rtl of neorv32_cpu is
signal alu_add : std_ulogic_vector(XLEN-1 downto 0); -- alu address result
signal alu_cmp : std_ulogic_vector(1 downto 0); -- comparator result
signal mem_rdata : std_ulogic_vector(XLEN-1 downto 0); -- memory read data
signal alu_idone : std_ulogic; -- iterative alu operation done
signal cp_done : std_ulogic; -- ALU co-prefetch operation done
signal alu_exc : std_ulogic; -- ALU exception
signal bus_d_wait : std_ulogic; -- wait for current bus data access
signal csr_rdata : std_ulogic_vector(XLEN-1 downto 0); -- csr read data
signal mar : std_ulogic_vector(XLEN-1 downto 0); -- current memory address register
Expand Down Expand Up @@ -304,7 +300,8 @@ begin
i_bus_err_i => i_bus_err_i, -- bus transfer error
i_pmp_fault_i => i_pmp_fault, -- instruction fetch pmp fault
-- status input --
alu_idone_i => alu_idone, -- ALU iterative operation done
alu_cp_done_i => cp_done, -- ALU iterative operation done
alu_exc_i => alu_exc, -- ALU exception
bus_d_wait_i => bus_d_wait, -- wait for bus
-- data input --
cmp_i => alu_cmp, -- comparator status
Expand Down Expand Up @@ -337,13 +334,13 @@ begin
);

-- CPU state --
sleep_o <= ctrl(ctrl_sleep_c); -- set when CPU is sleeping (after WFI)
debug_o <= ctrl(ctrl_debug_running_c); -- set when CPU is in debug mode
sleep_o <= ctrl.cpu_sleep; -- set when CPU is sleeping (after WFI)
debug_o <= ctrl.cpu_debug; -- set when CPU is in debug mode

-- instruction fetch interface --
i_bus_addr_o <= fetch_pc;
i_bus_fence_o <= ctrl(ctrl_bus_fencei_c);
i_bus_priv_o <= ctrl(ctrl_priv_mode_c);
i_bus_fence_o <= ctrl.bus_fencei;
i_bus_priv_o <= ctrl.cpu_priv;


-- Register File --------------------------------------------------------------------------
Expand Down Expand Up @@ -405,7 +402,8 @@ begin
add_o => alu_add, -- address computation result
fpu_flags_o => fpu_flags, -- FPU exception flags
-- status --
idone_o => alu_idone -- iterative processing units done?
exc_o => alu_exc, -- ALU exception
cp_done_o => cp_done -- iterative processing units done?
);


Expand Down
46 changes: 29 additions & 17 deletions rtl/core/neorv32_cpu_alu.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
-- # OF THE POSSIBILITY OF SUCH DAMAGE. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- # The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################

library ieee;
Expand All @@ -58,7 +58,7 @@ entity neorv32_cpu_alu is
-- global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
ctrl_i : in std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
ctrl_i : in ctrl_bus_t; -- main control bus
-- data input --
rs1_i : in std_ulogic_vector(XLEN-1 downto 0); -- rf source 1
rs2_i : in std_ulogic_vector(XLEN-1 downto 0); -- rf source 2
Expand All @@ -72,7 +72,8 @@ entity neorv32_cpu_alu is
add_o : out std_ulogic_vector(XLEN-1 downto 0); -- address computation result
fpu_flags_o : out std_ulogic_vector(4 downto 0); -- FPU exception flags
-- status --
idone_o : out std_ulogic -- iterative processing units done?
exc_o : out std_ulogic; -- ALU exception
cp_done_o : out std_ulogic -- co-processor operation done?
);
end neorv32_cpu_alu;

Expand All @@ -91,17 +92,17 @@ architecture neorv32_cpu_cpu_rtl of neorv32_cpu_alu is
signal cp_res : std_ulogic_vector(XLEN-1 downto 0);

-- co-processor interface --
type cp_data_if_t is array (0 to 4) of std_ulogic_vector(XLEN-1 downto 0);
type cp_data_if_t is array (0 to 5) of std_ulogic_vector(XLEN-1 downto 0);
signal cp_result : cp_data_if_t; -- co-processor result
signal cp_start : std_ulogic_vector(4 downto 0); -- trigger co-processor
signal cp_valid : std_ulogic_vector(4 downto 0); -- co-processor done
signal cp_start : std_ulogic_vector(5 downto 0); -- trigger co-processor
signal cp_valid : std_ulogic_vector(5 downto 0); -- co-processor done

begin

-- Comparator Unit (for conditional branches) ---------------------------------------------
-- -------------------------------------------------------------------------------------------
cmp_rs1 <= (rs1_i(rs1_i'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & rs1_i; -- optional sign-extension
cmp_rs2 <= (rs2_i(rs2_i'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & rs2_i; -- optional sign-extension
cmp_rs1 <= (rs1_i(rs1_i'left) and (not ctrl_i.alu_unsigned)) & rs1_i; -- optional sign-extension
cmp_rs2 <= (rs2_i(rs2_i'left) and (not ctrl_i.alu_unsigned)) & rs2_i; -- optional sign-extension

cmp(cmp_equal_c) <= '1' when (rs1_i = rs2_i) else '0';
cmp(cmp_less_c) <= '1' when (signed(cmp_rs1) < signed(cmp_rs2)) else '0'; -- signed or unsigned comparison
Expand All @@ -110,8 +111,8 @@ begin

-- ALU Input Operand Select ---------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
opa <= pc_i when (ctrl_i(ctrl_alu_opa_mux_c) = '1') else rs1_i;
opb <= imm_i when (ctrl_i(ctrl_alu_opb_mux_c) = '1') else rs2_i;
opa <= pc_i when (ctrl_i.alu_opa_mux = '1') else rs1_i;
opb <= imm_i when (ctrl_i.alu_opb_mux = '1') else rs2_i;


-- Adder/Subtracter Core ------------------------------------------------------------------
Expand All @@ -120,10 +121,10 @@ begin
variable opa_v, opb_v : std_ulogic_vector(XLEN downto 0);
begin
-- operand sign-extension --
opa_v := (opa(opa'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & opa;
opb_v := (opb(opb'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & opb;
opa_v := (opa(opa'left) and (not ctrl_i.alu_unsigned)) & opa;
opb_v := (opb(opb'left) and (not ctrl_i.alu_unsigned)) & opb;
-- add/sub(slt) select --
if (ctrl_i(ctrl_alu_op0_c) = '1') then
if (ctrl_i.alu_op(0) = '1') then
addsub_res <= std_ulogic_vector(unsigned(opa_v) - unsigned(opb_v));
else
addsub_res <= std_ulogic_vector(unsigned(opa_v) + unsigned(opb_v));
Expand All @@ -138,7 +139,7 @@ begin
-- -------------------------------------------------------------------------------------------
alu_core: process(ctrl_i, addsub_res, cp_res, rs1_i, opb)
begin
case ctrl_i(ctrl_alu_op2_c downto ctrl_alu_op0_c) is
case ctrl_i.alu_op is
when alu_op_add_c => res_o <= addsub_res(XLEN-1 downto 0); -- default
when alu_op_sub_c => res_o <= addsub_res(XLEN-1 downto 0);
when alu_op_cp_c => res_o <= cp_res;
Expand All @@ -156,17 +157,22 @@ begin
-- ALU Co-Processors
-- **************************************************************************************************************************

-- Co-Processor Control -------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- ALU processing exception --
exc_o <= '0'; -- not used yet

-- co-processor select / start trigger --
-- > "cp_start" is high for one cycle to trigger operation of the according co-processor
cp_start(4 downto 0) <= ctrl_i(ctrl_cp_trig4_c downto ctrl_cp_trig0_c);
cp_start(5 downto 0) <= ctrl_i.alu_cp_trig;

-- (iterative) co-processor operation done? --
-- > "cp_valid" signal has to be set (for one cycle) one cycle before CP output data (cp_result) is valid
idone_o <= cp_valid(0) or cp_valid(1) or cp_valid(2) or cp_valid(3) or cp_valid(4);
cp_done_o <= cp_valid(0) or cp_valid(1) or cp_valid(2) or cp_valid(3) or cp_valid(4) or cp_valid(5);

-- co-processor result --
-- > "cp_result" data has to be always zero unless the specific co-processor has been actually triggered
cp_res <= cp_result(0) or cp_result(1) or cp_result(2) or cp_result(3) or cp_result(4);
cp_res <= cp_result(0) or cp_result(1) or cp_result(2) or cp_result(3) or cp_result(4) or cp_result(5);


-- Co-Processor 0: Shifter Unit ('I'/'E' Base ISA) ----------------------------------------
Expand Down Expand Up @@ -322,4 +328,10 @@ begin
end generate;


-- Co-Processor 5: Reserved ---------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
cp_result(5) <= (others => '0');
cp_valid(5) <= '0';


end neorv32_cpu_cpu_rtl;
Loading