Line 56... |
Line 56... |
generic (
|
generic (
|
-- General --
|
-- General --
|
HW_THREAD_ID : std_ulogic_vector(31 downto 0):= (others => '0'); -- hardware thread id
|
HW_THREAD_ID : std_ulogic_vector(31 downto 0):= (others => '0'); -- hardware thread id
|
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0):= (others => '0'); -- cpu boot address
|
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0):= (others => '0'); -- cpu boot address
|
-- RISC-V CPU Extensions --
|
-- RISC-V CPU Extensions --
|
|
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
|
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
|
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
|
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
|
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
|
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
Line 86... |
Line 87... |
i_bus_cancel_o : out std_ulogic; -- cancel current bus transaction
|
i_bus_cancel_o : out std_ulogic; -- cancel current bus transaction
|
i_bus_ack_i : in std_ulogic := '0'; -- bus transfer acknowledge
|
i_bus_ack_i : in std_ulogic := '0'; -- bus transfer acknowledge
|
i_bus_err_i : in std_ulogic := '0'; -- bus transfer error
|
i_bus_err_i : in std_ulogic := '0'; -- bus transfer error
|
i_bus_fence_o : out std_ulogic; -- executed FENCEI operation
|
i_bus_fence_o : out std_ulogic; -- executed FENCEI operation
|
i_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
|
i_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
|
|
i_bus_lock_o : out std_ulogic; -- locked/exclusive access
|
-- data bus interface --
|
-- data bus interface --
|
d_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
|
d_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
|
d_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0) := (others => '0'); -- bus read data
|
d_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0) := (others => '0'); -- bus read data
|
d_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
|
d_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
|
d_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
|
d_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
|
Line 98... |
Line 100... |
d_bus_cancel_o : out std_ulogic; -- cancel current bus transaction
|
d_bus_cancel_o : out std_ulogic; -- cancel current bus transaction
|
d_bus_ack_i : in std_ulogic := '0'; -- bus transfer acknowledge
|
d_bus_ack_i : in std_ulogic := '0'; -- bus transfer acknowledge
|
d_bus_err_i : in std_ulogic := '0'; -- bus transfer error
|
d_bus_err_i : in std_ulogic := '0'; -- bus transfer error
|
d_bus_fence_o : out std_ulogic; -- executed FENCE operation
|
d_bus_fence_o : out std_ulogic; -- executed FENCE operation
|
d_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
|
d_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
|
|
d_bus_lock_o : out std_ulogic; -- locked/exclusive access
|
-- system time input from MTIME --
|
-- system time input from MTIME --
|
time_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time
|
time_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time
|
-- interrupts (risc-v compliant) --
|
-- interrupts (risc-v compliant) --
|
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt
|
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt
|
mext_irq_i : in std_ulogic := '0'; -- machine external interrupt
|
mext_irq_i : in std_ulogic := '0'; -- machine external interrupt
|
Line 134... |
Line 137... |
signal be_instr : std_ulogic; -- bus error on instruction access
|
signal be_instr : std_ulogic; -- bus error on instruction access
|
signal be_load : std_ulogic; -- bus error on load data access
|
signal be_load : std_ulogic; -- bus error on load data access
|
signal be_store : std_ulogic; -- bus error on store data access
|
signal be_store : std_ulogic; -- bus error on store data access
|
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)
|
|
|
|
-- co-processor interface --
|
-- co-processor interface --
|
signal cp0_data, cp1_data, cp2_data, cp3_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, cp2_valid, cp3_valid : std_ulogic;
|
signal cp0_valid, cp1_valid, cp2_valid, cp3_valid : std_ulogic;
|
signal cp0_start, cp1_start, cp2_start, cp3_start : std_ulogic;
|
signal cp0_start, cp1_start, cp2_start, cp3_start : std_ulogic;
|
Line 161... |
Line 163... |
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 < PMP_GRANULARITY < 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;
|
-- Instruction prefetch buffer size --
|
-- Instruction prefetch buffer size --
|
assert not (is_power_of_two_f(ipb_entries_c) = false) report "NEORV32 CPU CONFIG ERROR! Number of entries in instruction prefetch buffer <ipb_entries_c> has to be a power of two." severity error;
|
assert not (is_power_of_two_f(ipb_entries_c) = false) report "NEORV32 CPU CONFIG ERROR! Number of entries in instruction prefetch buffer <ipb_entries_c> has to be a power of two." severity error;
|
|
-- A extension - only lr.w and sc.w supported yet --
|
|
assert not (CPU_EXTENSION_RISCV_A = true) report "NEORV32 CPU CONFIG WARNING! Atomic operations extension (A) only supports >lr.w< and >sc.w< instructions yet." severity warning;
|
|
|
|
|
-- Control Unit ---------------------------------------------------------------------------
|
-- Control Unit ---------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
neorv32_cpu_control_inst: neorv32_cpu_control
|
neorv32_cpu_control_inst: neorv32_cpu_control
|
generic map (
|
generic map (
|
-- General --
|
-- General --
|
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id
|
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id
|
CPU_BOOT_ADDR => CPU_BOOT_ADDR, -- cpu boot address
|
CPU_BOOT_ADDR => CPU_BOOT_ADDR, -- cpu boot address
|
-- RISC-V CPU Extensions --
|
-- RISC-V CPU Extensions --
|
|
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
|
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
|
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
|
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
|
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
|
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
|
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
|
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
|
Line 200... |
Line 205... |
rs1_i => rs1, -- rf source 1
|
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
|
|
csr_rdata_o => csr_rdata, -- CSR read data
|
csr_rdata_o => csr_rdata, -- CSR read data
|
-- interrupts (risc-v compliant) --
|
-- interrupts (risc-v compliant) --
|
msw_irq_i => msw_irq_i, -- machine software interrupt
|
msw_irq_i => msw_irq_i, -- machine software interrupt
|
mext_irq_i => mext_irq_i, -- machine external interrupt
|
mext_irq_i => mext_irq_i, -- machine external interrupt
|
mtime_irq_i => mtime_irq_i, -- machine timer interrupt
|
mtime_irq_i => mtime_irq_i, -- machine timer interrupt
|
Line 238... |
Line 242... |
ctrl_i => ctrl, -- main control bus
|
ctrl_i => ctrl, -- main control bus
|
-- data input --
|
-- data input --
|
mem_i => rdata, -- memory read data
|
mem_i => rdata, -- memory read data
|
alu_i => alu_res, -- ALU result
|
alu_i => alu_res, -- ALU result
|
csr_i => csr_rdata, -- CSR read data
|
csr_i => csr_rdata, -- CSR read data
|
pc_i => next_pc, -- next pc (for linking)
|
|
-- data output --
|
-- data output --
|
rs1_o => rs1, -- operand 1
|
rs1_o => rs1, -- operand 1
|
rs2_o => rs2 -- operand 2
|
rs2_o => rs2 -- operand 2
|
);
|
);
|
|
|
Line 315... |
Line 318... |
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: Atomic Memory Access (SC - store-conditional) --------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- control: ctrl cp1_start
|
atomic_op_cp: process(ctrl, cp1_start)
|
-- inputs: rs1 rs2 alu_cmp alu_opb
|
begin
|
|
-- "fake" co-processor for atomic operations
|
|
-- used to get the result of a store-conditional operation into the data path
|
|
if (CPU_EXTENSION_RISCV_A = true) and (cp1_start = '1') then
|
|
cp1_data <= (others => '0');
|
|
cp1_data(0) <= not ctrl(ctrl_bus_lock_c);
|
|
cp1_valid <= '1';
|
|
else
|
cp1_data <= (others => '0');
|
cp1_data <= (others => '0');
|
cp1_valid <= '0';
|
cp1_valid <= '0';
|
|
end if;
|
|
end process;
|
|
|
|
|
-- Co-Processor 2: Not implemented (yet) --------------------------------------------------
|
-- Co-Processor 2: Not implemented (yet) --------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- control: ctrl cp2_start
|
-- control: ctrl cp2_start
|
Line 362... |
Line 374... |
i_wait_o => bus_i_wait, -- wait for fetch to complete
|
i_wait_o => bus_i_wait, -- wait for fetch to complete
|
--
|
--
|
ma_instr_o => ma_instr, -- misaligned instruction address
|
ma_instr_o => ma_instr, -- misaligned instruction address
|
be_instr_o => be_instr, -- bus error on instruction access
|
be_instr_o => be_instr, -- bus error on instruction access
|
-- cpu data access interface --
|
-- cpu data access interface --
|
addr_i => alu_res, -- ALU result -> access address
|
addr_i => alu_add, -- ALU.add result -> access address
|
wdata_i => rs2, -- write data
|
wdata_i => rs2, -- write data
|
rdata_o => rdata, -- read data
|
rdata_o => rdata, -- read data
|
mar_o => mar, -- current memory address register
|
mar_o => mar, -- current memory address register
|
d_wait_o => bus_d_wait, -- wait for access to complete
|
d_wait_o => bus_d_wait, -- wait for access to complete
|
--
|
--
|
Line 386... |
Line 398... |
i_bus_re_o => i_bus_re_o, -- read enable
|
i_bus_re_o => i_bus_re_o, -- read enable
|
i_bus_cancel_o => i_bus_cancel_o, -- cancel current bus transaction
|
i_bus_cancel_o => i_bus_cancel_o, -- cancel current bus transaction
|
i_bus_ack_i => i_bus_ack_i, -- bus transfer acknowledge
|
i_bus_ack_i => i_bus_ack_i, -- bus transfer acknowledge
|
i_bus_err_i => i_bus_err_i, -- bus transfer error
|
i_bus_err_i => i_bus_err_i, -- bus transfer error
|
i_bus_fence_o => i_bus_fence_o, -- fence operation
|
i_bus_fence_o => i_bus_fence_o, -- fence operation
|
|
i_bus_lock_o => i_bus_lock_o, -- locked/exclusive access
|
-- data bus --
|
-- data bus --
|
d_bus_addr_o => d_bus_addr_o, -- bus access address
|
d_bus_addr_o => d_bus_addr_o, -- bus access address
|
d_bus_rdata_i => d_bus_rdata_i, -- bus read data
|
d_bus_rdata_i => d_bus_rdata_i, -- bus read data
|
d_bus_wdata_o => d_bus_wdata_o, -- bus write data
|
d_bus_wdata_o => d_bus_wdata_o, -- bus write data
|
d_bus_ben_o => d_bus_ben_o, -- byte enable
|
d_bus_ben_o => d_bus_ben_o, -- byte enable
|
d_bus_we_o => d_bus_we_o, -- write enable
|
d_bus_we_o => d_bus_we_o, -- write enable
|
d_bus_re_o => d_bus_re_o, -- read enable
|
d_bus_re_o => d_bus_re_o, -- read enable
|
d_bus_cancel_o => d_bus_cancel_o, -- cancel current bus transaction
|
d_bus_cancel_o => d_bus_cancel_o, -- cancel current bus transaction
|
d_bus_ack_i => d_bus_ack_i, -- bus transfer acknowledge
|
d_bus_ack_i => d_bus_ack_i, -- bus transfer acknowledge
|
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
|
|
d_bus_lock_o => d_bus_lock_o -- locked/exclusive access
|
);
|
);
|
|
|
-- current privilege level --
|
-- current privilege level --
|
i_bus_priv_o <= ctrl(ctrl_priv_lvl_msb_c downto ctrl_priv_lvl_lsb_c);
|
i_bus_priv_o <= ctrl(ctrl_priv_lvl_msb_c downto ctrl_priv_lvl_lsb_c);
|
d_bus_priv_o <= ctrl(ctrl_priv_lvl_msb_c downto ctrl_priv_lvl_lsb_c);
|
d_bus_priv_o <= ctrl(ctrl_priv_lvl_msb_c downto ctrl_priv_lvl_lsb_c);
|