Line 1... |
Line 1... |
-- #################################################################################################
|
-- #################################################################################################
|
-- # << NEORV32 - CPU Top Entity >> #
|
-- # << NEORV32 - CPU Top Entity >> #
|
-- # ********************************************************************************************* #
|
-- # ********************************************************************************************* #
|
-- # NEORV32 CPU: #
|
-- # NEORV32 CPU: #
|
-- # * neorv32_cpu.vhd : CPU top entity #
|
-- # * neorv32_cpu.vhd - CPU top entity #
|
-- # * neorv32_cpu_alu.vhd : Arithmetic/logic unit #
|
-- # * neorv32_cpu_alu.vhd - Arithmetic/logic unit #
|
-- # * neorv32_cpu_bus.vhd : Instruction and data bus interface unit #
|
-- # * neorv32_cpu_bus.vhd - Instruction and data bus interface unit #
|
-- # * neorv32_cpu_cp_muldiv.vhd : MULDIV co-processor #
|
-- # * neorv32_cpu_cp_muldiv.vhd - MULDIV co-processor #
|
-- # * neorv32_cpu_ctrl.vhd : CPU control and CSR system #
|
-- # * neorv32_cpu_ctrl.vhd - CPU control and CSR system #
|
-- # * neorv32_cpu_decompressor.vhd : Compressed instructions decoder #
|
-- # * neorv32_cpu_decompressor.vhd - Compressed instructions decoder #
|
-- # * neorv32_cpu_regfile.vhd : Data register file #
|
-- # * neorv32_cpu_regfile.vhd - Data register file #
|
-- # #
|
-- # #
|
-- # Check out the processor's data sheet for more information: docs/NEORV32.pdf #
|
-- # Check out the processor's data sheet for more information: docs/NEORV32.pdf #
|
-- # ********************************************************************************************* #
|
-- # ********************************************************************************************* #
|
-- # BSD 3-Clause License #
|
-- # BSD 3-Clause License #
|
-- # #
|
-- # #
|
Line 115... |
Line 115... |
signal ctrl : std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
|
signal ctrl : std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
|
signal alu_cmp : std_ulogic_vector(1 downto 0); -- alu comparator result
|
signal alu_cmp : std_ulogic_vector(1 downto 0); -- alu comparator result
|
signal imm : std_ulogic_vector(data_width_c-1 downto 0); -- immediate
|
signal imm : std_ulogic_vector(data_width_c-1 downto 0); -- immediate
|
signal instr : std_ulogic_vector(data_width_c-1 downto 0); -- new instruction
|
signal instr : std_ulogic_vector(data_width_c-1 downto 0); -- new instruction
|
signal rs1, rs2 : std_ulogic_vector(data_width_c-1 downto 0); -- source registers
|
signal rs1, rs2 : std_ulogic_vector(data_width_c-1 downto 0); -- source registers
|
|
signal alu_opb : std_ulogic_vector(data_width_c-1 downto 0); -- ALU operand b
|
signal alu_res : std_ulogic_vector(data_width_c-1 downto 0); -- alu result
|
signal alu_res : std_ulogic_vector(data_width_c-1 downto 0); -- alu result
|
|
signal alu_add : std_ulogic_vector(data_width_c-1 downto 0); -- alu address result
|
signal rdata : std_ulogic_vector(data_width_c-1 downto 0); -- memory read data
|
signal rdata : std_ulogic_vector(data_width_c-1 downto 0); -- memory read data
|
signal alu_wait : std_ulogic; -- alu is busy due to iterative unit
|
signal alu_wait : std_ulogic; -- alu is busy due to iterative unit
|
signal bus_i_wait : std_ulogic; -- wait for current bus instruction fetch
|
signal bus_i_wait : std_ulogic; -- wait for current bus instruction fetch
|
signal bus_d_wait : std_ulogic; -- wait for current bus data access
|
signal bus_d_wait : std_ulogic; -- wait for current bus data access
|
signal csr_rdata : std_ulogic_vector(data_width_c-1 downto 0); -- csr read data
|
signal csr_rdata : std_ulogic_vector(data_width_c-1 downto 0); -- csr read data
|
Line 133... |
Line 135... |
signal fetch_pc : std_ulogic_vector(data_width_c-1 downto 0); -- pc for instruction fetch
|
signal fetch_pc : std_ulogic_vector(data_width_c-1 downto 0); -- pc for instruction fetch
|
signal curr_pc : std_ulogic_vector(data_width_c-1 downto 0); -- current pc (for current executed instruction)
|
signal curr_pc : std_ulogic_vector(data_width_c-1 downto 0); -- current pc (for current executed instruction)
|
signal next_pc : std_ulogic_vector(data_width_c-1 downto 0); -- next pc (for next to-be-executed instruction)
|
signal next_pc : std_ulogic_vector(data_width_c-1 downto 0); -- next pc (for next to-be-executed instruction)
|
|
|
-- co-processor interface --
|
-- co-processor interface --
|
signal cp0_data, cp1_data : std_ulogic_vector(data_width_c-1 downto 0);
|
signal cp0_data, cp1_data, cp2_data, cp3_data : std_ulogic_vector(data_width_c-1 downto 0);
|
signal cp0_valid, cp1_valid : std_ulogic;
|
signal cp0_valid, cp1_valid, cp2_valid, cp3_valid : std_ulogic;
|
signal cp0_start, cp1_start : std_ulogic;
|
signal cp0_start, cp1_start, cp2_start, cp3_start : std_ulogic;
|
|
|
-- pmp interface --
|
-- pmp interface --
|
signal pmp_addr : pmp_addr_if_t;
|
signal pmp_addr : pmp_addr_if_t;
|
signal pmp_ctrl : pmp_ctrl_if_t;
|
signal pmp_ctrl : pmp_ctrl_if_t;
|
signal priv_mode : std_ulogic_vector(1 downto 0); -- current CPU privilege level
|
|
|
|
begin
|
begin
|
|
|
-- Sanity Checks --------------------------------------------------------------------------
|
-- Sanity Checks --------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- CSR system --
|
-- CSR system --
|
assert not (CPU_EXTENSION_RISCV_Zicsr = false) report "NEORV32 CPU CONFIG WARNING! No exception/interrupt/machine features available when CPU_EXTENSION_RISCV_Zicsr = false." severity warning;
|
assert not (CPU_EXTENSION_RISCV_Zicsr = false) report "NEORV32 CPU CONFIG WARNING! No exception/interrupt/trap/machine features available when CPU_EXTENSION_RISCV_Zicsr = false." severity warning;
|
-- U-extension requires Zicsr extension --
|
-- U-extension requires Zicsr extension --
|
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true)) report "NEORV32 CPU CONFIG ERROR! User mode requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
|
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true)) report "NEORV32 CPU CONFIG ERROR! User mode requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
|
-- PMP requires Zicsr extension --
|
-- PMP requires Zicsr extension --
|
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Physical memory protection (PMP) requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
|
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Physical memory protection (PMP) requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
|
-- PMP regions --
|
-- PMP regions --
|
assert not ((PMP_NUM_REGIONS > pmp_max_r_c) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Number of PMP regions out of valid range." severity error;
|
assert not ((PMP_NUM_REGIONS > pmp_max_r_c) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Number of PMP regions out of valid range." severity error;
|
-- PMP granulartiy --
|
-- PMP granulartiy --
|
assert not (((PMP_GRANULARITY < 1) or (PMP_GRANULARITY > 32)) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Invalid PMP granulartiy (0 < G < 33)." severity error;
|
assert not (((PMP_GRANULARITY < 1) or (PMP_GRANULARITY > 32)) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Invalid PMP granulartiy (0 < PMP_GRANULARITY < 33)." severity error;
|
|
|
|
|
-- Control Unit ---------------------------------------------------------------------------
|
-- Control Unit ---------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
neorv32_cpu_control_inst: neorv32_cpu_control
|
neorv32_cpu_control_inst: neorv32_cpu_control
|
Line 189... |
Line 190... |
bus_i_wait_i => bus_i_wait, -- wait for bus
|
bus_i_wait_i => bus_i_wait, -- wait for bus
|
bus_d_wait_i => bus_d_wait, -- wait for bus
|
bus_d_wait_i => bus_d_wait, -- wait for bus
|
-- data input --
|
-- data input --
|
instr_i => instr, -- instruction
|
instr_i => instr, -- instruction
|
cmp_i => alu_cmp, -- comparator status
|
cmp_i => alu_cmp, -- comparator status
|
alu_res_i => alu_res, -- ALU processing result
|
alu_add_i => alu_add, -- ALU address result
|
|
rs1_i => rs1, -- rf source 1
|
-- data output --
|
-- data output --
|
imm_o => imm, -- immediate
|
imm_o => imm, -- immediate
|
fetch_pc_o => fetch_pc, -- PC for instruction fetch
|
fetch_pc_o => fetch_pc, -- PC for instruction fetch
|
curr_pc_o => curr_pc, -- current PC (corresponding to current instruction)
|
curr_pc_o => curr_pc, -- current PC (corresponding to current instruction)
|
next_pc_o => next_pc, -- next PC (corresponding to current instruction
|
next_pc_o => next_pc, -- next PC (corresponding to current instruction
|
Line 207... |
Line 209... |
-- system time input from MTIME --
|
-- system time input from MTIME --
|
time_i => time_i, -- current system time
|
time_i => time_i, -- current system time
|
-- physical memory protection --
|
-- physical memory protection --
|
pmp_addr_o => pmp_addr, -- addresses
|
pmp_addr_o => pmp_addr, -- addresses
|
pmp_ctrl_o => pmp_ctrl, -- configs
|
pmp_ctrl_o => pmp_ctrl, -- configs
|
priv_mode_o => priv_mode, -- current CPU privilege level
|
|
-- bus access exceptions --
|
-- bus access exceptions --
|
mar_i => mar, -- memory address register
|
mar_i => mar, -- memory address register
|
ma_instr_i => ma_instr, -- misaligned instruction address
|
ma_instr_i => ma_instr, -- misaligned instruction address
|
ma_load_i => ma_load, -- misaligned load data address
|
ma_load_i => ma_load, -- misaligned load data address
|
ma_store_i => ma_store, -- misaligned store data address
|
ma_store_i => ma_store, -- misaligned store data address
|
Line 260... |
Line 261... |
pc2_i => curr_pc, -- delayed PC
|
pc2_i => curr_pc, -- delayed PC
|
imm_i => imm, -- immediate
|
imm_i => imm, -- immediate
|
-- data output --
|
-- data output --
|
cmp_o => alu_cmp, -- comparator status
|
cmp_o => alu_cmp, -- comparator status
|
res_o => alu_res, -- ALU result
|
res_o => alu_res, -- ALU result
|
|
add_o => alu_add, -- address computation result
|
|
opb_o => alu_opb, -- ALU operand B
|
-- co-processor interface --
|
-- co-processor interface --
|
cp0_start_o => cp0_start, -- trigger co-processor 0
|
cp0_start_o => cp0_start, -- trigger co-processor 0
|
cp0_data_i => cp0_data, -- co-processor 0 result
|
cp0_data_i => cp0_data, -- co-processor 0 result
|
cp0_valid_i => cp0_valid, -- co-processor 0 result valid
|
cp0_valid_i => cp0_valid, -- co-processor 0 result valid
|
cp1_start_o => cp1_start, -- trigger co-processor 1
|
cp1_start_o => cp1_start, -- trigger co-processor 1
|
cp1_data_i => cp1_data, -- co-processor 1 result
|
cp1_data_i => cp1_data, -- co-processor 1 result
|
cp1_valid_i => cp1_valid, -- co-processor 1 result valid
|
cp1_valid_i => cp1_valid, -- co-processor 1 result valid
|
|
cp2_start_o => cp2_start, -- trigger co-processor 2
|
|
cp2_data_i => cp2_data, -- co-processor 2 result
|
|
cp2_valid_i => cp2_valid, -- co-processor 2 result valid
|
|
cp3_start_o => cp3_start, -- trigger co-processor 3
|
|
cp3_data_i => cp3_data, -- co-processor 3 result
|
|
cp3_valid_i => cp3_valid, -- co-processor 3 result valid
|
-- status --
|
-- status --
|
wait_o => alu_wait -- busy due to iterative processing units
|
wait_o => alu_wait -- busy due to iterative processing units
|
);
|
);
|
|
|
|
|
Line 285... |
Line 294... |
port map (
|
port map (
|
-- global control --
|
-- global control --
|
clk_i => clk_i, -- global clock, rising edge
|
clk_i => clk_i, -- global clock, rising edge
|
rstn_i => rstn_i, -- global reset, low-active, async
|
rstn_i => rstn_i, -- global reset, low-active, async
|
ctrl_i => ctrl, -- main control bus
|
ctrl_i => ctrl, -- main control bus
|
-- data input --
|
|
start_i => cp0_start, -- trigger operation
|
start_i => cp0_start, -- trigger operation
|
|
-- data input --
|
rs1_i => rs1, -- rf source 1
|
rs1_i => rs1, -- rf source 1
|
rs2_i => rs2, -- rf source 2
|
rs2_i => rs2, -- rf source 2
|
-- result and status --
|
-- result and status --
|
res_o => cp0_data, -- operation result
|
res_o => cp0_data, -- operation result
|
valid_o => cp0_valid -- data output valid
|
valid_o => cp0_valid -- data output valid
|
Line 302... |
Line 311... |
cp0_data <= (others => '0');
|
cp0_data <= (others => '0');
|
cp0_valid <= '0';
|
cp0_valid <= '0';
|
end generate;
|
end generate;
|
|
|
|
|
-- Co-Processor 1: Not Implemented Yet ----------------------------------------------------
|
-- Co-Processor 1: Not implemented yet ----------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
|
-- control: ctrl cp1_start
|
|
-- inputs: rs1 rs2 alu_cmp alu_opb
|
cp1_data <= (others => '0');
|
cp1_data <= (others => '0');
|
cp1_valid <= '0';
|
cp1_valid <= '0';
|
|
|
|
|
|
-- Co-Processor 2: Not implemented yet ----------------------------------------------------
|
|
-- -------------------------------------------------------------------------------------------
|
|
-- control: ctrl cp2_start
|
|
-- inputs: rs1 rs2 alu_cmp alu_opb
|
|
cp2_data <= (others => '0');
|
|
cp2_valid <= '0';
|
|
|
|
|
|
-- Co-Processor 3: Not implemented yet ----------------------------------------------------
|
|
-- -------------------------------------------------------------------------------------------
|
|
-- control: ctrl cp3_start
|
|
-- inputs: rs1 rs2 alu_cmp alu_opb
|
|
cp3_data <= (others => '0');
|
|
cp3_valid <= '0';
|
|
|
|
|
-- Bus Interface Unit ---------------------------------------------------------------------
|
-- Bus Interface Unit ---------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
neorv32_cpu_bus_inst: neorv32_cpu_bus
|
neorv32_cpu_bus_inst: neorv32_cpu_bus
|
generic map (
|
generic map (
|
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
|
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
|
Line 321... |
Line 348... |
PMP_GRANULARITY => PMP_GRANULARITY -- granularity (0=none, 1=8B, 2=16B, 3=32B, ...)
|
PMP_GRANULARITY => PMP_GRANULARITY -- granularity (0=none, 1=8B, 2=16B, 3=32B, ...)
|
)
|
)
|
port map (
|
port map (
|
-- global control --
|
-- global control --
|
clk_i => clk_i, -- global clock, rising edge
|
clk_i => clk_i, -- global clock, rising edge
|
rstn_i => rstn_i, -- global reset, low-active, async
|
|
ctrl_i => ctrl, -- main control bus
|
ctrl_i => ctrl, -- main control bus
|
-- cpu instruction fetch interface --
|
-- cpu instruction fetch interface --
|
fetch_pc_i => fetch_pc, -- PC for instruction fetch
|
fetch_pc_i => fetch_pc, -- PC for instruction fetch
|
instr_o => instr, -- instruction
|
instr_o => instr, -- instruction
|
i_wait_o => bus_i_wait, -- wait for fetch to complete
|
i_wait_o => bus_i_wait, -- wait for fetch to complete
|
Line 344... |
Line 370... |
be_load_o => be_load, -- bus error on load data access
|
be_load_o => be_load, -- bus error on load data access
|
be_store_o => be_store, -- bus error on store data access
|
be_store_o => be_store, -- bus error on store data access
|
-- physical memory protection --
|
-- physical memory protection --
|
pmp_addr_i => pmp_addr, -- addresses
|
pmp_addr_i => pmp_addr, -- addresses
|
pmp_ctrl_i => pmp_ctrl, -- configs
|
pmp_ctrl_i => pmp_ctrl, -- configs
|
priv_mode_i => priv_mode, -- current CPU privilege level
|
|
-- instruction bus --
|
-- instruction bus --
|
i_bus_addr_o => i_bus_addr_o, -- bus access address
|
i_bus_addr_o => i_bus_addr_o, -- bus access address
|
i_bus_rdata_i => i_bus_rdata_i, -- bus read data
|
i_bus_rdata_i => i_bus_rdata_i, -- bus read data
|
i_bus_wdata_o => i_bus_wdata_o, -- bus write data
|
i_bus_wdata_o => i_bus_wdata_o, -- bus write data
|
i_bus_ben_o => i_bus_ben_o, -- byte enable
|
i_bus_ben_o => i_bus_ben_o, -- byte enable
|
Line 370... |
Line 395... |
d_bus_err_i => d_bus_err_i, -- bus transfer error
|
d_bus_err_i => d_bus_err_i, -- bus transfer error
|
d_bus_fence_o => d_bus_fence_o -- fence operation
|
d_bus_fence_o => d_bus_fence_o -- fence operation
|
);
|
);
|
|
|
-- current privilege level --
|
-- current privilege level --
|
i_bus_priv_o <= priv_mode;
|
i_bus_priv_o <= ctrl(ctrl_priv_lvl_msb_c downto ctrl_priv_lvl_lsb_c);
|
d_bus_priv_o <= priv_mode;
|
d_bus_priv_o <= ctrl(ctrl_priv_lvl_msb_c downto ctrl_priv_lvl_lsb_c);
|
|
|
|
|
end neorv32_cpu_rtl;
|
end neorv32_cpu_rtl;
|
|
|
No newline at end of file
|
No newline at end of file
|