URL
https://opencores.org/ocsvn/neorv32/neorv32/trunk
Subversion Repositories neorv32
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 17 to Rev 18
- ↔ Reverse comparison
Rev 17 → Rev 18
/neorv32/trunk/docs/figures/neorv32_processor.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/neorv32/trunk/docs/figures/riscv_logo.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
neorv32/trunk/docs/figures/riscv_logo.png
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: neorv32/trunk/docs/NEORV32.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: neorv32/trunk/rtl/core/neorv32_bootloader_image.vhd
===================================================================
--- neorv32/trunk/rtl/core/neorv32_bootloader_image.vhd (revision 17)
+++ neorv32/trunk/rtl/core/neorv32_bootloader_image.vhd (revision 18)
@@ -982,8 +982,8 @@
00000971 => x"3e3e2072",
00000972 => x"4c420a0a",
00000973 => x"203a5644",
- 00000974 => x"206c754a",
- 00000975 => x"32203532",
+ 00000974 => x"20677541",
+ 00000975 => x"32203320",
00000976 => x"0a303230",
00000977 => x"3a565748",
00000978 => x"00002020",
Index: neorv32/trunk/rtl/core/neorv32_cpu.vhd
===================================================================
--- neorv32/trunk/rtl/core/neorv32_cpu.vhd (revision 17)
+++ neorv32/trunk/rtl/core/neorv32_cpu.vhd (revision 18)
@@ -1,7 +1,7 @@
-- #################################################################################################
-- # << NEORV32 - CPU Top Entity >> #
-- # ********************************************************************************************* #
--- # Top NEORV32 CPU: #
+-- # NEORV32 CPU: #
-- # * neorv32_cpu.vhd : CPU top entity #
-- # * neorv32_cpu_alu.vhd : Arithmetic/logic unit #
-- # * neorv32_cpu_bus.vhd : Instruction and data bus interface unit #
@@ -9,6 +9,8 @@
-- # * neorv32_cpu_ctrl.vhd : CPU control and CSR system #
-- # * neorv32_cpu_decompressor.vhd : Compressed instructions decoder #
-- # * neorv32_cpu_regfile.vhd : Data register file #
+-- # #
+-- # Check the processor's documentary for more information: docs/NEORV32.pdf #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
@@ -149,28 +151,32 @@
if rising_edge(clk_i) then
-- CSR system --
if (CPU_EXTENSION_RISCV_Zicsr = false) then
- assert false report "NEORV32 CONFIG WARNING! No exception/interrupt/machine features available when CPU_EXTENSION_RISCV_Zicsr = false." severity warning;
+ assert false report "NEORV32 CPU CONFIG WARNING! No exception/interrupt/machine features available when CPU_EXTENSION_RISCV_Zicsr = false." severity warning;
end if;
-- U-extension requires Zicsr extension --
if (CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true) then
- assert false report "NEORV32 CONFIG ERROR! User mode requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
+ assert false report "NEORV32 CPU CONFIG ERROR! User mode requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
end if;
-- PMP requires Zicsr extension --
if (CPU_EXTENSION_RISCV_Zicsr = false) and (PMP_USE = true) then
- assert false report "NEORV32 CONFIG ERROR! Physical memory protection (PMP) requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
+ assert false report "NEORV32 CPU CONFIG ERROR! Physical memory protection (PMP) requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
end if;
-- performance counters require Zicsr extension --
if (CPU_EXTENSION_RISCV_Zicsr = false) and (CSR_COUNTERS_USE = true) then
- assert false report "NEORV32 CONFIG ERROR! Performance counter CSRs require CPU_EXTENSION_RISCV_Zicsr extension." severity error;
+ assert false report "NEORV32 CPU CONFIG ERROR! Performance counter CSRs require CPU_EXTENSION_RISCV_Zicsr extension." severity error;
end if;
-- PMP regions --
if (PMP_NUM_REGIONS > pmp_max_r_c) and (PMP_USE = true) then
- assert false report "NEORV32 CONFIG ERROR! Number of PMP regions out of valid range." severity error;
+ assert false report "NEORV32 CPU CONFIG ERROR! Number of PMP regions out of valid range." severity error;
end if;
-- PMP granulartiy --
if ((PMP_GRANULARITY < 1) or (PMP_GRANULARITY > 32)) and (PMP_USE = true) then
- assert false report "NEORV32 CONFIG ERROR! Invalid PMP granulartiy (0 < G < 33)." severity error;
+ assert false report "NEORV32 CPU CONFIG ERROR! Invalid PMP granulartiy (0 < G < 33)." severity error;
end if;
+ -- Bus timeout --
+ if (BUS_TIMEOUT < 1) then
+ assert false report "NEORV32 CPU CONFIG ERROR! Invalid bus timeout - must be at least 1 cycle." severity error;
+ end if;
end if;
end process sanity_check;
/neorv32/trunk/rtl/core/neorv32_cpu_bus.vhd
1,7 → 1,7
-- ################################################################################################# |
-- # << NEORV32 - Bus Interface Unit >> # |
-- # ********************************************************************************************* # |
-- # Instruction and data bus interfaces. # |
-- # Instruction and data bus interfaces and physical memory protection (PMP). # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
48,7 → 48,7
-- Physical memory protection (PMP) -- |
PMP_USE : boolean := false; -- implement physical memory protection? |
PMP_NUM_REGIONS : natural := 4; -- number of regions (1..4) |
PMP_GRANULARITY : natural := 16 -- granularity (0=none, 1=8B, 2=16B, 3=32B, ...) |
PMP_GRANULARITY : natural := 16 -- granularity (1=8B, 2=16B, 3=32B, ...) |
); |
port ( |
-- global control -- |
462,7 → 462,7
pmp_check_permission: process(pmp, pmp_ctrl_i, priv_mode_i) |
begin |
for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions |
if ((priv_mode_i = u_priv_mode_c) or (pmp_ctrl_i(r)(pmp_cfg_l_c) = '1')) and -- user privilege level or locked pmp entry - enforce permissions also for machine mode |
if ((priv_mode_i = u_priv_mode_c) or (pmp_ctrl_i(r)(pmp_cfg_l_c) = '1')) and -- user privilege level or locked pmp entry -> enforce permissions also for machine mode |
(pmp_ctrl_i(r)(pmp_cfg_ah_c downto pmp_cfg_al_c) /= pmp_off_mode_c) then -- active entry |
pmp.if_fault(r) <= pmp.i_match(r) and (not pmp_ctrl_i(r)(pmp_cfg_x_c)); -- fetch access match no execute permission |
pmp.ld_fault(r) <= pmp.d_match(r) and (not pmp_ctrl_i(r)(pmp_cfg_r_c)); -- load access match no read permission |
/neorv32/trunk/rtl/core/neorv32_cpu_control.vhd
514,7 → 514,7
execute_engine.state <= SYS_WAIT; |
execute_engine.sleep <= '0'; |
elsif rising_edge(clk_i) then |
execute_engine.pc <= execute_engine.pc_nxt(data_width_c-1 downto 1) & '0'; |
execute_engine.pc <= execute_engine.pc_nxt(data_width_c-1 downto 1) & '0'; |
if (execute_engine.state = EXECUTE) then |
execute_engine.last_pc <= execute_engine.pc(data_width_c-1 downto 1) & '0'; |
end if; |
537,10 → 537,10
end process execute_engine_fsm_sync; |
|
-- PC output -- |
next_pc_tmp <= std_ulogic_vector(unsigned(execute_engine.pc) + 2) when (execute_engine.is_ci = '1') else std_ulogic_vector(unsigned(execute_engine.pc) + 4); |
curr_pc_o <= execute_engine.pc(data_width_c-1 downto 1) & '0'; |
next_pc_tmp <= std_ulogic_vector(unsigned(execute_engine.pc) + 2) when (execute_engine.is_ci = '1') else std_ulogic_vector(unsigned(execute_engine.pc) + 4); |
execute_engine.next_pc <= next_pc_tmp(data_width_c-1 downto 1) & '0'; |
next_pc_o <= next_pc_tmp(data_width_c-1 downto 1) & '0'; |
curr_pc_o <= execute_engine.pc(data_width_c-1 downto 1) & '0'; |
|
|
-- CPU Control Bus Output ----------------------------------------------------------------- |
1130,11 → 1130,11
trap_ctrl.exc_buf(exception_m_envcall_c) <= (trap_ctrl.exc_buf(exception_m_envcall_c) or trap_ctrl.env_call) and (not trap_ctrl.exc_ack); |
trap_ctrl.exc_buf(exception_break_c) <= (trap_ctrl.exc_buf(exception_break_c) or trap_ctrl.break_point) and (not trap_ctrl.exc_ack); |
trap_ctrl.exc_buf(exception_iillegal_c) <= (trap_ctrl.exc_buf(exception_iillegal_c) or trap_ctrl.instr_il) and (not trap_ctrl.exc_ack); |
-- interrupt buffer (RISC-V compliant): machine software/external/timer interrupt |
-- interrupt buffer: machine software/external/timer interrupt |
trap_ctrl.irq_buf(interrupt_msw_irq_c) <= csr.mie_msie and (trap_ctrl.irq_buf(interrupt_msw_irq_c) or msw_irq_i) and (not trap_ctrl.irq_ack(interrupt_msw_irq_c)); |
trap_ctrl.irq_buf(interrupt_mext_irq_c) <= csr.mie_meie and (trap_ctrl.irq_buf(interrupt_mext_irq_c) or mext_irq_i) and (not trap_ctrl.irq_ack(interrupt_mext_irq_c)); |
trap_ctrl.irq_buf(interrupt_mtime_irq_c) <= csr.mie_mtie and (trap_ctrl.irq_buf(interrupt_mtime_irq_c) or mtime_irq_i) and (not trap_ctrl.irq_ack(interrupt_mtime_irq_c)); |
-- interrupt buffer (custom): fast interrupts |
-- interrupt buffer: custom fast interrupts |
trap_ctrl.irq_buf(interrupt_firq_0_c) <= csr.mie_firqe(0) and (trap_ctrl.irq_buf(interrupt_firq_0_c) or firq_i(0)) and (not trap_ctrl.irq_ack(interrupt_firq_0_c)); |
trap_ctrl.irq_buf(interrupt_firq_1_c) <= csr.mie_firqe(1) and (trap_ctrl.irq_buf(interrupt_firq_1_c) or firq_i(1)) and (not trap_ctrl.irq_ack(interrupt_firq_1_c)); |
trap_ctrl.irq_buf(interrupt_firq_2_c) <= csr.mie_firqe(2) and (trap_ctrl.irq_buf(interrupt_firq_2_c) or firq_i(2)) and (not trap_ctrl.irq_ack(interrupt_firq_2_c)); |
/neorv32/trunk/rtl/core/neorv32_package.vhd
41,7 → 41,7
-- Architecture Constants ----------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
constant data_width_c : natural := 32; -- data width - FIXED! |
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01030502"; -- no touchy! |
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01030600"; -- no touchy! |
constant pmp_max_r_c : natural := 8; -- max PMP regions |
|
-- Helper Functions ----------------------------------------------------------------------- |
82,9 → 82,10
constant gpio_in_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(gpio_base_c) + x"00000000"); |
constant gpio_out_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(gpio_base_c) + x"00000004"); |
|
-- RESERVED -- |
--constant ???_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF88"; -- base address, fixed! |
--constant ???_size_c : natural := 1*4; -- bytes, fixed! |
-- Dummy Device (with SIMULATION output) (DEVNULL) -- |
constant devnull_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF88"; -- base address, fixed! |
constant devnull_size_c : natural := 1*4; -- bytes, fixed! |
constant devnull_data_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(devnull_base_c) + x"00000000"); |
|
-- Watch Dog Timer (WDT) -- |
constant wdt_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF8C"; -- base address, fixed! |
129,14 → 130,9
constant trng_ctrl_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(trng_base_c) + x"00000000"); |
constant trng_data_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(trng_base_c) + x"00000004"); |
|
-- Dummy Device (with SIMULATION output) (DEVNULL) -- |
constant devnull_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFC8"; -- base address, fixed! |
constant devnull_size_c : natural := 1*4; -- bytes, fixed! |
constant devnull_data_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(devnull_base_c) + x"00000000"); |
|
-- RESERVED -- |
--constant ???_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFCC"; -- base address, fixed! |
--constant ???_size_c : natural := 5*4; -- bytes, fixed! |
--constant ???_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFC8"; -- base address, fixed! |
--constant ???_size_c : natural := 6*4; -- bytes, fixed! |
|
-- System Information Memory (with SIMULATION output) (SYSINFO) -- |
constant sysinfo_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFE0"; -- base address, fixed! |
393,10 → 389,10
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])? |
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_C : boolean := true; -- 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_M : boolean := true; -- implement muld/div extension? |
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension? |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension? |
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.? |
-- Physical Memory Protection (PMP) -- |
669,7 → 665,7
-- Physical memory protection (PMP) -- |
PMP_USE : boolean := false; -- implement physical memory protection? |
PMP_NUM_REGIONS : natural := 4; -- number of regions (1..4) |
PMP_GRANULARITY : natural := 0 -- granularity (0=none, 1=8B, 2=16B, 3=32B, ...) |
PMP_GRANULARITY : natural := 0 -- granularity (1=8B, 2=16B, 3=32B, ...) |
); |
port ( |
-- global control -- |
/neorv32/trunk/rtl/core/neorv32_sysinfo.vhd
1,8 → 1,8
-- ################################################################################################# |
-- # << NEORV32 - System/Processor Configuration Information Memory (SYSINFO) >> # |
-- # ********************************************************************************************* # |
-- # This unit provides information regarding the 'system' configuration - mostly derived from the # |
-- # top's configuration generics. # |
-- # This unit provides information regarding the 'processor system' configuration - # |
-- # mostly derived from the top's configuration generics. # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
/neorv32/trunk/rtl/core/neorv32_top.vhd
1,10 → 1,11
-- ################################################################################################# |
-- # << NEORV32 - Processor Top Entity >> # |
-- # ********************************************************************************************* # |
-- # This is the top entity of the NEORV32 Processor. Instantiate this unit in your own project # |
-- # This is the top entity of the NEORV32 PROCESSOR. Instantiate this unit in your own project # |
-- # and define all the configuration generics according to your needs. Alternatively, you can use # |
-- # one of the alternative top entities provided in the "rtl\top_templates" folder. # |
-- # Check the processor's documentary for more information: doc\NEORV32.pdf # |
-- # one of the alternative top entities provided in the "rtl/top_templates" folder. # |
-- # # |
-- # Check the processor's documentary for more information: docs/NEORV32.pdf # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
223,41 → 224,47
if rising_edge(clk_i) then |
-- internal bootloader memory -- |
if (BOOTLOADER_USE = true) and (boot_size_c > boot_max_size_c) then |
assert false report "NEORV32 CONFIG ERROR! Boot ROM size out of range." severity error; |
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Boot ROM size out of range." severity error; |
end if; |
|
-- memory system - data/instruction fetch -- |
if (MEM_EXT_USE = false) then |
if (MEM_INT_DMEM_USE = false) then |
assert false report "NEORV32 CONFIG ERROR! Core cannot fetch data without external memory interface and internal data memory." severity error; |
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Core cannot fetch data without external memory interface and internal data memory." severity error; |
end if; |
if (MEM_INT_IMEM_USE = false) and (BOOTLOADER_USE = false) then |
assert false report "NEORV32 CONFIG ERROR! Core cannot fetch instructions without external memory interface, internal data memory and bootloader." severity error; |
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Core cannot fetch instructions without external memory interface, internal data memory and bootloader." severity error; |
end if; |
end if; |
|
-- memory system -- |
if (MEM_ISPACE_BASE(1 downto 0) /= "00") then |
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Instruction memory space base address must be 4-byte-aligned." severity error; |
end if; |
if (MEM_DSPACE_BASE(1 downto 0) /= "00") then |
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Data memory space base address must be 4-byte-aligned." severity error; |
end if; |
if (MEM_INT_IMEM_USE = true) and (MEM_INT_IMEM_SIZE > MEM_ISPACE_SIZE) then |
assert false report "NEORV32 CONFIG ERROR! Internal instruction memory (IMEM) cannot be greater than total instruction address space." severity error; |
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Internal instruction memory (IMEM) cannot be greater than total instruction address space." severity error; |
end if; |
if (MEM_INT_DMEM_USE = true) and (MEM_INT_DMEM_SIZE > MEM_DSPACE_SIZE) then |
assert false report "NEORV32 CONFIG ERROR! Internal data memory (DMEM) cannot be greater than total data address space." severity error; |
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Internal data memory (DMEM) cannot be greater than total data address space." severity error; |
end if; |
if (MEM_EXT_TIMEOUT < 1) then |
assert false report "NEORV32 CONFIG ERROR! Invalid bus timeout. Processor-internal components have 1 cycle delay." severity error; |
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Invalid bus timeout. Processor-internal components have 1 cycle delay." severity error; |
end if; |
|
-- clock -- |
if (CLOCK_FREQUENCY = 0) then |
assert false report "NEORV32 CONFIG ERROR! Core clock frequency (CLOCK_FREQUENCY) not specified." severity error; |
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Core clock frequency (CLOCK_FREQUENCY) not specified." severity error; |
end if; |
|
-- memory layout notifier -- |
if (MEM_ISPACE_BASE /= x"00000000") then |
assert false report "NEORV32 CONFIG WARNING! Non-default base address for instruction address space. Make sure this is sync with the software framwork." severity warning; |
assert false report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for instruction address space. Make sure this is sync with the software framwork." severity warning; |
end if; |
if (MEM_DSPACE_BASE /= x"80000000") then |
assert false report "NEORV32 CONFIG WARNING! Non-default base address for data address space. Make sure this is sync with the software framwork." severity warning; |
assert false report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for data address space. Make sure this is sync with the software framwork." severity warning; |
end if; |
end if; |
end process sanity_check; |
/neorv32/trunk/rtl/top_templates/neorv32_test_setup.vhd
74,7 → 74,7
CSR_COUNTERS_USE => true, -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])? |
USER_CODE => x"00000000", -- custom user code |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_C => false, -- implement compressed extension? |
CPU_EXTENSION_RISCV_C => true, -- implement compressed extension? |
CPU_EXTENSION_RISCV_E => false, -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M => false, -- implement muld/div extension? |
CPU_EXTENSION_RISCV_U => false, -- implement user mode extension? |
/neorv32/trunk/sim/vivado/neorv32_tb_behav.wcfg
12,13 → 12,13
</db_ref> |
</db_ref_list> |
<zoom_setting> |
<ZoomStartTime time="1233000084fs"></ZoomStartTime> |
<ZoomEndTime time="1233509585fs"></ZoomEndTime> |
<Cursor1Time time="1233085000fs"></Cursor1Time> |
<ZoomStartTime time="2254750fs"></ZoomStartTime> |
<ZoomEndTime time="2357051fs"></ZoomEndTime> |
<Cursor1Time time="2305000fs"></Cursor1Time> |
</zoom_setting> |
<column_width_setting> |
<NameColumnWidth column_width="203"></NameColumnWidth> |
<ValueColumnWidth column_width="100"></ValueColumnWidth> |
<ValueColumnWidth column_width="96"></ValueColumnWidth> |
</column_width_setting> |
<WVObjectSize size="131" /> |
<wvobject type="divider" fp_name="divider273"> |
69,6 → 69,7
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ipb" type="array"> |
<obj_property name="ElementShortName">ipb</obj_property> |
<obj_property name="ObjectShortName">ipb</obj_property> |
<obj_property name="isExpanded"></obj_property> |
</wvobject> |
<wvobject type="divider" fp_name="divider273"> |
<obj_property name="label">CPU: Control.EXE</obj_property> |
174,6 → 175,72
<obj_property name="ElementShortName">execute_engine</obj_property> |
<obj_property name="ObjectShortName">execute_engine</obj_property> |
<obj_property name="isExpanded"></obj_property> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.state" type="other"> |
<obj_property name="ElementShortName">.state</obj_property> |
<obj_property name="ObjectShortName">.state</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.state_nxt" type="other"> |
<obj_property name="ElementShortName">.state_nxt</obj_property> |
<obj_property name="ObjectShortName">.state_nxt</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.i_reg" type="array"> |
<obj_property name="ElementShortName">.i_reg[31:0]</obj_property> |
<obj_property name="ObjectShortName">.i_reg[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.i_reg_nxt" type="array"> |
<obj_property name="ElementShortName">.i_reg_nxt[31:0]</obj_property> |
<obj_property name="ObjectShortName">.i_reg_nxt[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_ci" type="logic"> |
<obj_property name="ElementShortName">.is_ci</obj_property> |
<obj_property name="ObjectShortName">.is_ci</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_ci_nxt" type="logic"> |
<obj_property name="ElementShortName">.is_ci_nxt</obj_property> |
<obj_property name="ObjectShortName">.is_ci_nxt</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_jump" type="logic"> |
<obj_property name="ElementShortName">.is_jump</obj_property> |
<obj_property name="ObjectShortName">.is_jump</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_jump_nxt" type="logic"> |
<obj_property name="ElementShortName">.is_jump_nxt</obj_property> |
<obj_property name="ObjectShortName">.is_jump_nxt</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.branch_taken" type="logic"> |
<obj_property name="ElementShortName">.branch_taken</obj_property> |
<obj_property name="ObjectShortName">.branch_taken</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.pc" type="array"> |
<obj_property name="ElementShortName">.pc[31:0]</obj_property> |
<obj_property name="ObjectShortName">.pc[31:0]</obj_property> |
<obj_property name="CustomSignalColor">#FFFFFF</obj_property> |
<obj_property name="UseCustomSignalColor">true</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.pc_nxt" type="array"> |
<obj_property name="ElementShortName">.pc_nxt[31:0]</obj_property> |
<obj_property name="ObjectShortName">.pc_nxt[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.next_pc" type="array"> |
<obj_property name="ElementShortName">.next_pc[31:0]</obj_property> |
<obj_property name="ObjectShortName">.next_pc[31:0]</obj_property> |
<obj_property name="CustomSignalColor">#FFFFFF</obj_property> |
<obj_property name="UseCustomSignalColor">true</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.last_pc" type="array"> |
<obj_property name="ElementShortName">.last_pc[31:0]</obj_property> |
<obj_property name="ObjectShortName">.last_pc[31:0]</obj_property> |
<obj_property name="CustomSignalColor">#FFFFFF</obj_property> |
<obj_property name="UseCustomSignalColor">true</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.sleep" type="logic"> |
<obj_property name="ElementShortName">.sleep</obj_property> |
<obj_property name="ObjectShortName">.sleep</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.sleep_nxt" type="logic"> |
<obj_property name="ElementShortName">.sleep_nxt</obj_property> |
<obj_property name="ObjectShortName">.sleep_nxt</obj_property> |
</wvobject> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/CPU_EXTENSION_RISCV_C" type="other"> |
<obj_property name="ElementShortName">CPU_EXTENSION_RISCV_C</obj_property> |
212,115 → 279,6
<obj_property name="ElementShortName">csr</obj_property> |
<obj_property name="ObjectShortName">csr</obj_property> |
<obj_property name="isExpanded"></obj_property> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.we" type="logic"> |
<obj_property name="ElementShortName">.we</obj_property> |
<obj_property name="ObjectShortName">.we</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.we_nxt" type="logic"> |
<obj_property name="ElementShortName">.we_nxt</obj_property> |
<obj_property name="ObjectShortName">.we_nxt</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.re" type="logic"> |
<obj_property name="ElementShortName">.re</obj_property> |
<obj_property name="ObjectShortName">.re</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.re_nxt" type="logic"> |
<obj_property name="ElementShortName">.re_nxt</obj_property> |
<obj_property name="ObjectShortName">.re_nxt</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mstatus_mie" type="logic"> |
<obj_property name="ElementShortName">.mstatus_mie</obj_property> |
<obj_property name="ObjectShortName">.mstatus_mie</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mstatus_mpie" type="logic"> |
<obj_property name="ElementShortName">.mstatus_mpie</obj_property> |
<obj_property name="ObjectShortName">.mstatus_mpie</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mie_msie" type="logic"> |
<obj_property name="ElementShortName">.mie_msie</obj_property> |
<obj_property name="ObjectShortName">.mie_msie</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mie_meie" type="logic"> |
<obj_property name="ElementShortName">.mie_meie</obj_property> |
<obj_property name="ObjectShortName">.mie_meie</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mie_mtie" type="logic"> |
<obj_property name="ElementShortName">.mie_mtie</obj_property> |
<obj_property name="ObjectShortName">.mie_mtie</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mie_firqe" type="array"> |
<obj_property name="ElementShortName">.mie_firqe[3:0]</obj_property> |
<obj_property name="ObjectShortName">.mie_firqe[3:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mpp" type="array"> |
<obj_property name="ElementShortName">.mpp[1:0]</obj_property> |
<obj_property name="ObjectShortName">.mpp[1:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.privilege" type="array"> |
<obj_property name="ElementShortName">.privilege[1:0]</obj_property> |
<obj_property name="ObjectShortName">.privilege[1:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mepc" type="array"> |
<obj_property name="ElementShortName">.mepc[31:0]</obj_property> |
<obj_property name="ObjectShortName">.mepc[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mcause" type="array"> |
<obj_property name="ElementShortName">.mcause[31:0]</obj_property> |
<obj_property name="ObjectShortName">.mcause[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mtvec" type="array"> |
<obj_property name="ElementShortName">.mtvec[31:0]</obj_property> |
<obj_property name="ObjectShortName">.mtvec[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mtval" type="array"> |
<obj_property name="ElementShortName">.mtval[31:0]</obj_property> |
<obj_property name="ObjectShortName">.mtval[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mscratch" type="array"> |
<obj_property name="ElementShortName">.mscratch[31:0]</obj_property> |
<obj_property name="ObjectShortName">.mscratch[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mcycle" type="array"> |
<obj_property name="ElementShortName">.mcycle[32:0]</obj_property> |
<obj_property name="ObjectShortName">.mcycle[32:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.minstret" type="array"> |
<obj_property name="ElementShortName">.minstret[32:0]</obj_property> |
<obj_property name="ObjectShortName">.minstret[32:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.mcycleh" type="array"> |
<obj_property name="ElementShortName">.mcycleh[19:0]</obj_property> |
<obj_property name="ObjectShortName">.mcycleh[19:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.minstreth" type="array"> |
<obj_property name="ElementShortName">.minstreth[19:0]</obj_property> |
<obj_property name="ObjectShortName">.minstreth[19:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.pmpcfg" type="array"> |
<obj_property name="ElementShortName">.pmpcfg[0:3][7:0]</obj_property> |
<obj_property name="ObjectShortName">.pmpcfg[0:3][7:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.pmpaddr" type="array"> |
<obj_property name="ElementShortName">.pmpaddr[0:3][31:0]</obj_property> |
<obj_property name="ObjectShortName">.pmpaddr[0:3][31:0]</obj_property> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.pmpaddr[0]" type="array"> |
<obj_property name="ElementShortName">[0][31:0]</obj_property> |
<obj_property name="ObjectShortName">[0][31:0]</obj_property> |
<obj_property name="isExpanded"></obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.pmpaddr[1]" type="array"> |
<obj_property name="ElementShortName">[1][31:0]</obj_property> |
<obj_property name="ObjectShortName">[1][31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.pmpaddr[2]" type="array"> |
<obj_property name="ElementShortName">[2][31:0]</obj_property> |
<obj_property name="ObjectShortName">[2][31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.pmpaddr[3]" type="array"> |
<obj_property name="ElementShortName">[3][31:0]</obj_property> |
<obj_property name="ObjectShortName">[3][31:0]</obj_property> |
</wvobject> |
</wvobject> |
</wvobject> |
<wvobject type="divider" fp_name="divider139"> |
<obj_property name="label">CPU: RegFile</obj_property> |
/neorv32/trunk/sw/lib/include/neorv32.h
81,6 → 81,7
|
CSR_MCYCLE = 0xb00, /**< 0xb00 - mcycle (r/w): Machine cycle counter low word */ |
CSR_MINSTRET = 0xb02, /**< 0xb02 - minstret (r/w): Machine instructions-retired counter low word */ |
|
CSR_MCYCLEH = 0xb80, /**< 0xb80 - mcycleh (r/w): Machine cycle counter high word - only 20-bit wide!*/ |
CSR_MINSTRETH = 0xb82, /**< 0xb82 - minstreth (r/w): Machine instructions-retired counter high word - only 20-bit wide! */ |
|
242,6 → 243,15
|
|
/**********************************************************************//** |
* @name IO Device: Dummy Device (DEVNULL) |
**************************************************************************/ |
/**@{*/ |
/** DEVNULL data register (r/w) */ |
#define DEVNULL_DATA (*(IO_REG32 0xFFFFFF88UL)) |
/**@}*/ |
|
|
/**********************************************************************//** |
* @name IO Device: Watchdog Timer (WDT) |
**************************************************************************/ |
/**@{*/ |
455,15 → 465,6
|
|
/**********************************************************************//** |
* @name IO Device: Dummy Device (DEVNULL) |
**************************************************************************/ |
/**@{*/ |
/** DEVNULL data register (r/w) */ |
#define DEVNULL_DATA (*(IO_REG32 0xFFFFFFC8UL)) |
/**@}*/ |
|
|
/**********************************************************************//** |
* @name IO Device: System Configuration Info Memory (SYSINFO) |
**************************************************************************/ |
/**@{*/ |
/neorv32/trunk/sw/lib/source/neorv32_cpu.c
242,15 → 242,14
* Switch from privilege mode MACHINE to privilege mode USER. |
* |
* @note This function requires the U extension to be implemented. |
* @note Maybe you should do a fencei after this. |
* @note Maybe you should do a fence.i after this. |
**************************************************************************/ |
void __attribute__((naked)) neorv32_cpu_goto_user_mode(void) { |
|
register uint32_t mask = (1<<CPU_MSTATUS_MPP_H) | (1<<CPU_MSTATUS_MPP_L); |
mask = ~mask; |
asm volatile ("csrrc zero, mstatus, %[input_j]" : : [input_j] "r" (mask)); |
|
// return and switch to user mode |
// return switching to user mode |
asm volatile ("csrw mepc, ra"); |
asm volatile ("mret"); |
} |
/neorv32/trunk/sw/lib/source/neorv32_rte.c
82,7 → 82,7
* |
* @param[in] id Identifier (type) of the targeted exception. See #NEORV32_RTE_TRAP_enum. |
* @param[in] handler The actual handler function for the specified exception (function MUST be of type "void function(void);"). |
* return 0 if success, 1 if error (invalid id or targeted exception not supported). |
* @return 0 if success, 1 if error (invalid id or targeted exception not supported). |
**************************************************************************/ |
int neorv32_rte_exception_install(uint8_t id, void (*handler)(void)) { |
|
109,7 → 109,7
* and/or the global interrupt enable bit mstatus.mie via neorv32_cpu_dint(void). |
* |
* @param[in] id Identifier (type) of the targeted exception. See #NEORV32_RTE_TRAP_enum. |
* return 0 if success, 1 if error (invalid id or targeted exception not supported). |
* @return 0 if success, 1 if error (invalid id or targeted exception not supported). |
**************************************************************************/ |
int neorv32_rte_exception_uninstall(uint8_t id) { |
|
201,19 → 201,19
case TRAP_CODE_I_MISALIGNED: neorv32_uart_printf("Instruction address misaligned"); break; |
case TRAP_CODE_I_ACCESS: neorv32_uart_printf("Instruction access fault"); break; |
case TRAP_CODE_I_ILLEGAL: neorv32_uart_printf("Illegal instruction"); break; |
case TRAP_CODE_BREAKPOINT: neorv32_uart_printf("Breakpoint (EBREAK)"); break; |
case TRAP_CODE_BREAKPOINT: neorv32_uart_printf("Breakpoint"); break; |
case TRAP_CODE_L_MISALIGNED: neorv32_uart_printf("Load address misaligned"); break; |
case TRAP_CODE_L_ACCESS: neorv32_uart_printf("Load access fault"); break; |
case TRAP_CODE_S_MISALIGNED: neorv32_uart_printf("Store address misaligned"); break; |
case TRAP_CODE_S_ACCESS: neorv32_uart_printf("Store access fault"); break; |
case TRAP_CODE_MENV_CALL: neorv32_uart_printf("Environment call from M-mode"); break; |
case TRAP_CODE_MENV_CALL: neorv32_uart_printf("Environment call"); break; |
case TRAP_CODE_MSI: neorv32_uart_printf("Machine software interrupt"); break; |
case TRAP_CODE_MTI: neorv32_uart_printf("Machine timer interrupt"); break; |
case TRAP_CODE_MEI: neorv32_uart_printf("Machine external interrupt"); break; |
case TRAP_CODE_FIRQ_0: neorv32_uart_printf("Fast interrupt channel 0"); break; |
case TRAP_CODE_FIRQ_1: neorv32_uart_printf("Fast interrupt channel 1"); break; |
case TRAP_CODE_FIRQ_2: neorv32_uart_printf("Fast interrupt channel 2"); break; |
case TRAP_CODE_FIRQ_3: neorv32_uart_printf("Fast interrupt channel 3"); break; |
case TRAP_CODE_FIRQ_0: neorv32_uart_printf("Fast interrupt 0"); break; |
case TRAP_CODE_FIRQ_1: neorv32_uart_printf("Fast interrupt 1"); break; |
case TRAP_CODE_FIRQ_2: neorv32_uart_printf("Fast interrupt 2"); break; |
case TRAP_CODE_FIRQ_3: neorv32_uart_printf("Fast interrupt 3"); break; |
default: neorv32_uart_printf("Unknown (0x%x)", trap_cause); break; |
} |
|
231,7 → 231,7
trap_addr -= 2; |
} |
} |
neorv32_uart_printf(" @0x%x, MTVAL=0x%x </RTE>", trap_addr, neorv32_cpu_csr_read(CSR_MTVAL)); |
neorv32_uart_printf(" @ 0x%x, MTVAL=0x%x </RTE>", trap_addr, neorv32_cpu_csr_read(CSR_MTVAL)); |
} |
|
|
/neorv32/trunk/README.md
63,6 → 63,7
* Plain VHDL without technology-specific parts like attributes, macros or primitives. |
* Easy to use – working out of the box. |
* Clean synchronous design, no wacky combinatorial interfaces. |
* Be as small as possible – but with a reasonable size-speed tradeoff. |
* The processor has to fit in a Lattice iCE40 UltraPlus 5k FPGA running at 20+ MHz. |
|
|
86,7 → 87,7
* `misa` CSR is read-only - no dynamic enabling/disabling of implemented CPU extensions during runtime |
* `mcause` CSR is read-only |
* The `[m]cycleh` and `[m]instreth` CSR counters are only 20-bit wide (in contrast to original 32-bit) |
* The physical memory protection (**PMP**) only supports `NAPOT` mode and only up to 8 regions |
* The physical memory protection (**PMP**) only supports `NAPOT` mode, a minimal granularity of 8 bytes and only up to 8 regions |
|
|
### Custom CPU Extensions |
194,7 → 195,7
**Privileged architecture / FENCE.I** (`Zifencei` extension): |
* System instructions: `FENCE.I` |
|
**Physical memory protection** (`PMP`, requires `Zicsr` extension): |
**Privileged architecture / Physical memory protection** (`PMP`, requires `Zicsr` extension): |
* Additional machine CSRs: `pmpcfgx` `pmpaddrx` |
|
|
279,11 → 280,11
Peripherals: UART for printing the results |
~~~ |
|
| CPU | Executable Size | Optimization | CoreMark Score | CoreMarks/MHz | |
|:---------------------------------|:---------------:|:------------:|:--------------:|:-------------:| |
| `rv32i` + `Zicsr` + `Zifencei` | 21 600 bytes | `-O2` | 27.02 | 0.2702 | |
| `rv32im` + `Zicsr` + `Zifencei` | 20 976 bytes | `-O2` | 57.14 | 0.5714 | |
| `rv32imc` + `Zicsr` + `Zifencei` | 16 348 bytes | `-O2` | 57.14 | 0.5714 | |
| CPU | Executable Size | Optimization | CoreMark Score | CoreMarks/MHz | |
|:----------|:---------------:|:------------:|:--------------:|:-------------:| |
| `rv32i` | 21 600 bytes | `-O2` | 27.02 | 0.2702 | |
| `rv32im` | 20 976 bytes | `-O2` | 57.14 | 0.5714 | |
| `rv32imc` | 16 348 bytes | `-O2` | 57.14 | 0.5714 | |
|
|
### Instruction Cycles |
303,11 → 304,11
|
Results generated for hardware version: `1.3.0.0` |
|
| CPU | Required Clock Cycles | Executed Instructions | Average CPI | |
|:---------------------------------|----------------------:|----------------------:|:-----------:| |
| `rv32i` + `Zicsr` + `Zifencei` | 7 433 933 906 | 1 494 298 800 | 4.97 | |
| `rv32im` + `Zicsr` + `Zifencei` | 3 589 861 906 | 628 281 454 | 5.71 | |
| `rv32imc` + `Zicsr` + `Zifencei` | 3 587 131 226 | 628 282 016 | 5.70 | |
| CPU | Required Clock Cycles | Executed Instructions | Average CPI | |
|:----------|----------------------:|----------------------:|:-----------:| |
| `rv32i` | 7 433 933 906 | 1 494 298 800 | 4.97 | |
| `rv32im` | 3 589 861 906 | 628 281 454 | 5.71 | |
| `rv32imc` | 3 587 131 226 | 628 282 016 | 5.70 | |
|
|
|
664,8 → 665,10
"AXI" and "AXI-Lite" are trademarks of Arm Holdings plc. |
|
|
## Acknowledgement |
## Acknowledgements |
|
[![RISC-V](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/riscv_logo.png)](https://riscv.org/) |
|
[RISC-V](https://riscv.org/) - Instruction Sets Want To Be Free :heart: |
|
[![Continous Integration provided by Travis CI](https://travis-ci.com/images/logos/TravisCI-Full-Color.png)](https://travis-ci.com/stnolting/neorv32) |