From 1f1d9f5c0e0b89a6cf60cc1c5be555e0bd49ecc6 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 29 Jun 2022 15:45:48 +0200 Subject: [PATCH 1/3] cpu/neorv32: Initial switch to neorv32_litex_core_complex. Status: - Minimal/Lite variants working; Standard/Full are not (Related to cache?). - GHDL does not seems to be able to convert VHDL to Verilog and keep parametrization; we'll have to implement a workaround to be able to select variant and enable debug. --- litex/soc/cores/cpu/neorv32/core.py | 184 +++++++------- .../cores/cpu/neorv32/neorv32_cpu_wrapper.vhd | 151 ------------ .../neorv32/neorv32_litex_core_complex.vhd | 225 ++++++++++++++++++ 3 files changed, 306 insertions(+), 254 deletions(-) delete mode 100644 litex/soc/cores/cpu/neorv32/neorv32_cpu_wrapper.vhd create mode 100644 litex/soc/cores/cpu/neorv32/neorv32_litex_core_complex.vhd diff --git a/litex/soc/cores/cpu/neorv32/core.py b/litex/soc/cores/cpu/neorv32/core.py index 390a5ccd2..3a7dbeed9 100644 --- a/litex/soc/cores/cpu/neorv32/core.py +++ b/litex/soc/cores/cpu/neorv32/core.py @@ -54,92 +54,44 @@ class NEORV32(CPU): self.platform = platform self.variant = variant self.reset = Signal() - self.ibus = ibus = wishbone.Interface() - self.dbus = dbus = wishbone.Interface() - self.periph_buses = [ibus, dbus] # Peripheral buses (Connected to main SoC's bus). - self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM). + self.ibus = idbus = wishbone.Interface() + self.periph_buses = [idbus] # Peripheral buses (Connected to main SoC's bus). + self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM). # # # class Open(Signal) : pass - # IBus Adaptations. FIXME: Works but not optimal (latency). - ibus_we = Signal() - ibus_re = Signal() - self.sync += [ - # Clear Cyc/Stb on Ack. - If(ibus.ack, - ibus.cyc.eq(0), - ibus.stb.eq(0), - ), - # Set Cyc/Stb on We/Re. - If(ibus_we | ibus_re, - ibus.cyc.eq(1), - ibus.stb.eq(1), - ibus.we.eq(ibus_we) - ) - ] + # CPU LiteX Core Complex Wrapper + self.specials += Instance("neorv32_litex_core_complex", + # Parameters. + #p_CONFIG = 2, + #p_DEBUG = False, - # DBus Adaptations. FIXME: Works but not optimal (latency). - dbus_we = Signal() - dbus_re = Signal() - self.sync += [ - # Clear Cyc/Stb on Ack. - If(dbus.ack, - dbus.cyc.eq(0), - dbus.stb.eq(0), - ), - # Set Cyc/Stb on We/Re. - If(dbus_we | dbus_re, - dbus.cyc.eq(1), - dbus.stb.eq(1), - dbus.we.eq(dbus_we) - ) - ] + # Clk/Rst. + i_clk_i = ClockSignal("sys"), + i_rstn_i = ~(ResetSignal() | self.reset), - # CPU Instance. - self.specials += Instance("neorv32_cpu_wrapper", - # Global Control. - i_clk_i = ClockSignal("sys"), - i_rstn_i = ~(ResetSignal() | self.reset), - o_sleep_o = Open(), - o_debug_o = Open(), - i_db_halt_req_i = 0, + # JTAG. + i_jtag_trst_i = 0, + i_jtag_tck_i = 0, + i_jtag_tdi_i = 0, + o_jtag_tdo_o = Open(), + i_jtag_tms_i = 0, - # Instruction Bus. - o_i_bus_addr_o = Cat(Signal(2), ibus.adr), - i_i_bus_rdata_i = ibus.dat_r, - o_i_bus_wdata_o = ibus.dat_w, - o_i_bus_ben_o = ibus.sel, - o_i_bus_we_o = ibus_we, - o_i_bus_re_o = ibus_re, - o_i_bus_lock_o = Open(), # FIXME. - i_i_bus_ack_i = ibus.ack, - i_i_bus_err_i = ibus.err, - o_i_bus_fence_o = Open(), # FIXME. - o_i_bus_priv_o = Open(), # FIXME. + # Interrupt. + i_mext_irq_i = 0, - # Data Bus. - o_d_bus_addr_o = Cat(Signal(2), dbus.adr), - i_d_bus_rdata_i = dbus.dat_r, - o_d_bus_wdata_o = dbus.dat_w, - o_d_bus_ben_o = dbus.sel, - o_d_bus_we_o = dbus_we, - o_d_bus_re_o = dbus_re, - o_d_bus_lock_o = Open(), # FIXME. - i_d_bus_ack_i = dbus.ack, - i_d_bus_err_i = dbus.err, - o_d_bus_fence_o = Open(), # FIXME. - o_d_bus_priv_o = Open(), # FIXME. - - # System Time. - i_time_i = 0, # FIXME. - - # Interrupts. - i_msw_irq_i = 0, # FIXME. - i_mext_irq_i = 0, # FIXME. - i_mtime_irq_i = 0, # FIXME. - i_firq_i = 0 # FIXME. + # I/D Wishbone Bus. + o_wb_adr_o = Cat(Signal(2), idbus.adr), + i_wb_dat_i = idbus.dat_r, + o_wb_dat_o = idbus.dat_w, + o_wb_we_o = idbus.we, + o_wb_sel_o = idbus.sel, + o_wb_stb_o = idbus.stb, + o_wb_cyc_o = idbus.cyc, + i_wb_ack_i = idbus.ack, + i_wb_err_i = idbus.err, ) # Add Verilog sources @@ -153,27 +105,52 @@ class NEORV32(CPU): def add_sources(platform): cdir = os.path.abspath(os.path.dirname(__file__)) # List VHDL sources. - sources = [ - "neorv32_package.vhd", # Main CPU & Processor package file. - "neorv32_fifo.vhd", # FIFO. - "neorv32_cpu.vhd", # CPU top entity. - "neorv32_cpu_alu.vhd", # Arithmetic/logic unit. - "neorv32_cpu_cp_bitmanip.vhd", # Bit-manipulation co-processor. - "neorv32_cpu_cp_cfu.vhd", # Custom instructions co-processor. - "neorv32_cpu_cp_fpu.vhd", # Single-precision FPU co-processor. - "neorv32_cpu_cp_muldiv.vhd", # Integer multiplier/divider co-processor. - "neorv32_cpu_cp_shifter.vhd", # Base ISA shifter unit. - "neorv32_cpu_bus.vhd", # Instruction and data bus interface unit. - "neorv32_cpu_control.vhd", # CPU control and CSR system. - "neorv32_cpu_decompressor.vhd", # Compressed instructions decoder. - "neorv32_cpu_regfile.vhd", # Data register file. - "neorv32_cpu_wrapper.vhd", # CPU top entity + default generics. - ] + sources = { + "core" : [ + # CPU & Processors Packages/Cores. + "neorv32_package.vhd", + "neorv32_fifo.vhd", + + # CPU components. + "neorv32_cpu.vhd", + "neorv32_cpu_alu.vhd", + "neorv32_cpu_cp_bitmanip.vhd", + "neorv32_cpu_cp_cfu.vhd", + "neorv32_cpu_cp_fpu.vhd", + "neorv32_cpu_cp_muldiv.vhd", + "neorv32_cpu_cp_shifter.vhd", + "neorv32_cpu_bus.vhd", + "neorv32_cpu_control.vhd", + "neorv32_cpu_decompressor.vhd", + "neorv32_cpu_regfile.vhd", + + # Processor components. + "neorv32_top.vhd", + "neorv32_icache.vhd", + "neorv32_busswitch.vhd", + "neorv32_bus_keeper.vhd", + "neorv32_wishbone.vhd", + "neorv32_mtime.vhd", + "neorv32_sysinfo.vhd", + "neorv32_debug_dm.vhd", + "neorv32_debug_dtm.vhd", + ], + + "core/mem": [ + "neorv32_imem.default.vhd", + "neorv32_dmem.default.vhd", + ], + + "system_integration": [ + "neorv32_litex_core_complex.vhd", + ], + } # Download VHDL sources (if not already present). - for source in sources: - if not os.path.exists(os.path.join(cdir, source)): - os.system(f"wget https://raw.githubusercontent.com/stnolting/neorv32/main/rtl/core/{source} -P {cdir}") + for directory, vhds in sources.items(): + for vhd in vhds: + if not os.path.exists(os.path.join(cdir, vhd)): + os.system(f"wget https://raw.githubusercontent.com/stnolting/neorv32/main/rtl/{directory}/{vhd} -P {cdir}") # Convert VHDL to Verilog through GHDL/Yosys. from litex.build import tools @@ -181,15 +158,16 @@ class NEORV32(CPU): cdir = os.path.dirname(__file__) ys = [] ys.append("ghdl --ieee=synopsys -fexplicit -frelaxed-rules --std=08 --work=neorv32 \\") - for source in sources: - ys.append(os.path.join(cdir, source) + " \\") - ys.append("-e neorv32_cpu_wrapper") + for directory, vhds in sources.items(): + for vhd in vhds: + ys.append(os.path.join(cdir, vhd) + " \\") + ys.append("-e neorv32_litex_core_complex") ys.append("chformal -assert -remove") - ys.append("write_verilog {}".format(os.path.join(cdir, "neorv32.v"))) - tools.write_to_file(os.path.join(cdir, "neorv32.ys"), "\n".join(ys)) - if subprocess.call(["yosys", "-q", "-m", "ghdl", os.path.join(cdir, "neorv32.ys")]): + ys.append("write_verilog {}".format(os.path.join(cdir, "neorv32_litex_core_complex.v"))) + tools.write_to_file(os.path.join(cdir, "neorv32_litex_core_complex.ys"), "\n".join(ys)) + if subprocess.call(["yosys", "-q", "-m", "ghdl", os.path.join(cdir, "neorv32_litex_core_complex.ys")]): raise OSError("Unable to convert NEORV32 CPU to verilog, please check your GHDL-Yosys-plugin install.") - platform.add_source(os.path.join(cdir, "neorv32.v")) + platform.add_source(os.path.join(cdir, "neorv32_litex_core_complex.v")) def do_finalize(self): assert hasattr(self, "reset_address") diff --git a/litex/soc/cores/cpu/neorv32/neorv32_cpu_wrapper.vhd b/litex/soc/cores/cpu/neorv32/neorv32_cpu_wrapper.vhd deleted file mode 100644 index 386f4dd37..000000000 --- a/litex/soc/cores/cpu/neorv32/neorv32_cpu_wrapper.vhd +++ /dev/null @@ -1,151 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library neorv32; -use neorv32.neorv32_package.all; - -entity neorv32_cpu_wrapper is - generic ( - -- General -- - HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit) - CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0) := x"00000000"; -- cpu boot address - CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0) := x"00000000"; -- cpu debug mode start address - -- RISC-V CPU Extensions -- - CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? - CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation 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 := true; -- implement user mode extension? - CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!) - CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? - CPU_EXTENSION_RISCV_Zicntr : boolean := true; -- implement base counters? - CPU_EXTENSION_RISCV_Zihpm : boolean := false; -- implement hardware performance monitors? - CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? - CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension? - CPU_EXTENSION_RISCV_Zxcfu : boolean := false; -- implement custom (instr.) functions unit? - CPU_EXTENSION_RISCV_DEBUG : boolean := false; -- implement CPU debug mode? - -- Extension Options -- - FAST_MUL_EN : boolean := true; -- use DSPs for M extension's multiplier - FAST_SHIFT_EN : boolean := true; -- use barrel shifter for shift operations - CPU_CNT_WIDTH : natural := 32; -- total width of CPU cycle and instret counters (0..64) - CPU_IPB_ENTRIES : natural := 4; -- entries is instruction prefetch buffer, has to be a power of 2 - -- Physical Memory Protection (PMP) -- - PMP_NUM_REGIONS : natural := 4; -- number of regions (0..64) - PMP_MIN_GRANULARITY : natural := 8; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes - -- Hardware Performance Monitors (HPM) -- - HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29) - HPM_CNT_WIDTH : natural := 32 -- total size of HPM counters (0..64) - ); - port ( - -- global control -- - clk_i : in std_ulogic; -- global clock, rising edge - rstn_i : in std_ulogic; -- global reset, low-active, async - sleep_o : out std_ulogic; -- cpu is in sleep mode when set - debug_o : out std_ulogic; -- cpu is in debug mode when set - -- instruction bus interface -- - i_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address - i_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data - i_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data - i_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable - i_bus_we_o : out std_ulogic; -- write enable - i_bus_re_o : out std_ulogic; -- read enable - i_bus_lock_o : out std_ulogic; -- exclusive access request - i_bus_ack_i : in std_ulogic; -- bus transfer acknowledge - i_bus_err_i : in std_ulogic; -- bus transfer error - i_bus_fence_o : out std_ulogic; -- executed FENCEI operation - i_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level - -- data bus interface -- - 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); -- bus read 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_we_o : out std_ulogic; -- write enable - d_bus_re_o : out std_ulogic; -- read enable - d_bus_lock_o : out std_ulogic; -- exclusive access request - d_bus_ack_i : in std_ulogic; -- bus transfer acknowledge - d_bus_err_i : in std_ulogic; -- bus transfer error - d_bus_fence_o : out std_ulogic; -- executed FENCE operation - d_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level - -- system time input from MTIME -- - time_i : in std_ulogic_vector(63 downto 0); -- current system time - -- interrupts (risc-v compliant) -- - msw_irq_i : in std_ulogic;-- machine software interrupt - mext_irq_i : in std_ulogic;-- machine external interrupt - mtime_irq_i : in std_ulogic;-- machine timer interrupt - -- fast interrupts (custom) -- - firq_i : in std_ulogic_vector(15 downto 0); - -- debug mode (halt) request -- - db_halt_req_i : in std_ulogic - ); -end neorv32_cpu_wrapper; - -architecture neorv32_cpu_wrapper_rtl of neorv32_cpu_wrapper is - -begin - - neorv32_cpu_inst: neorv32_cpu - generic map ( - HW_THREAD_ID => HW_THREAD_ID , - CPU_BOOT_ADDR => CPU_BOOT_ADDR , - CPU_DEBUG_ADDR => CPU_DEBUG_ADDR , - CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A , - CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B , - CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C , - CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E , - CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M , - CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U , - CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx , - CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr , - CPU_EXTENSION_RISCV_Zicntr => CPU_EXTENSION_RISCV_Zicntr , - CPU_EXTENSION_RISCV_Zihpm => CPU_EXTENSION_RISCV_Zihpm , - CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, - CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul , - CPU_EXTENSION_RISCV_Zxcfu => CPU_EXTENSION_RISCV_Zxcfu , - CPU_EXTENSION_RISCV_DEBUG => CPU_EXTENSION_RISCV_DEBUG , - FAST_MUL_EN => FAST_MUL_EN , - FAST_SHIFT_EN => FAST_SHIFT_EN , - CPU_CNT_WIDTH => CPU_CNT_WIDTH , - CPU_IPB_ENTRIES => CPU_IPB_ENTRIES , - PMP_NUM_REGIONS => PMP_NUM_REGIONS , - PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY , - HPM_NUM_CNTS => HPM_NUM_CNTS , - HPM_CNT_WIDTH => HPM_CNT_WIDTH - ) - port map ( - clk_i => clk_i , - rstn_i => rstn_i , - sleep_o => sleep_o , - debug_o => debug_o , - i_bus_addr_o => i_bus_addr_o , - i_bus_rdata_i => i_bus_rdata_i, - i_bus_wdata_o => i_bus_wdata_o, - i_bus_ben_o => i_bus_ben_o , - i_bus_we_o => i_bus_we_o , - i_bus_re_o => i_bus_re_o , - i_bus_lock_o => i_bus_lock_o , - i_bus_ack_i => i_bus_ack_i , - i_bus_err_i => i_bus_err_i , - i_bus_fence_o => i_bus_fence_o, - i_bus_priv_o => i_bus_priv_o , - d_bus_addr_o => d_bus_addr_o , - d_bus_rdata_i => d_bus_rdata_i, - d_bus_wdata_o => d_bus_wdata_o, - d_bus_ben_o => d_bus_ben_o , - d_bus_we_o => d_bus_we_o , - d_bus_re_o => d_bus_re_o , - d_bus_lock_o => d_bus_lock_o , - d_bus_ack_i => d_bus_ack_i , - d_bus_err_i => d_bus_err_i , - d_bus_fence_o => d_bus_fence_o, - d_bus_priv_o => d_bus_priv_o , - time_i => time_i , - msw_irq_i => msw_irq_i , - mext_irq_i => mext_irq_i , - mtime_irq_i => mtime_irq_i , - firq_i => firq_i , - db_halt_req_i => db_halt_req_i - ); - -end neorv32_cpu_wrapper_rtl; diff --git a/litex/soc/cores/cpu/neorv32/neorv32_litex_core_complex.vhd b/litex/soc/cores/cpu/neorv32/neorv32_litex_core_complex.vhd new file mode 100644 index 000000000..87aa5d0f2 --- /dev/null +++ b/litex/soc/cores/cpu/neorv32/neorv32_litex_core_complex.vhd @@ -0,0 +1,225 @@ +-- ################################################################################################# +-- # << The NEORV32 RISC-V Processor - LiteX NEORV32 Core Complex Wrapper >> # +-- # ********************************************************************************************* # +-- # __ _ __ _ __ # +-- # / / (_) /____ | |/_/ # +-- # / /__/ / __/ -_)> < # +-- # /____/_/\__/\__/_/|_| # +-- # Build your hardware, easily! # +-- # # +-- # Unless otherwise noted, LiteX is copyright (C) 2012-2022 Enjoy-Digital. All rights reserved. # +-- # LiteX HQ: https://github.com/enjoy-digital/litex # +-- # # +-- # ********************************************************************************************* # +-- # NEORV32 Core Complex wrapper for the LiteX SoC builder framework. # +-- # https://github.com/enjoy-digital/litex/tree/master/litex/soc/cores/cpu/neorv32 # +-- # # +-- # This wrapper provides four pre-configured core complex configurations: "minimal", "lite", # +-- # "standard" and "full". See the 'configs_c' table for more details which RISC-V ISA extensions # +-- # and module parameters are used by each of the these configurations. All configurations can be # +-- # used with the RISC-V-compatible on-chip debugger. # +-- # # +-- # === Bus Interface === # +-- # This wrappers uses the "pipelined" Wishbone b4 protocol for the bus interface. See the # +-- # "global configuration" constants for further bus configuration parameters (endianness, # +-- # timeout, etc.). # +-- # # +-- # === Interrupt ==== # +-- # The external interrupt signal is delegated to the CPU as RISC-V "machine external interrupt # +-- # (MTI)". Note that this IRQ signal is high-active - once set the signal has to stay high until # +-- # the interrupt request is explicitly acknowledged (e.g. writing to a memory-mapped register)! # +-- # # +-- # === Core Complex Address Space === # +-- # Note that the NEORV32 core complex occupies a small fraction of the total 32-bit address # +-- # space for internal components (machine timer, on-chip-debugger, ...). This address space # +-- # starts at address 0xffff0000 and ends at 0xffffffff. Any CPU access to this address space # +-- # will NOT be delegated to bus interface of the core complex! # +-- # ********************************************************************************************* # +-- # BSD 3-Clause License # +-- # # +-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. # +-- # # +-- # Redistribution and use in source and binary forms, with or without modification, are # +-- # permitted provided that the following conditions are met: # +-- # # +-- # 1. Redistributions of source code must retain the above copyright notice, this list of # +-- # conditions and the following disclaimer. # +-- # # +-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # +-- # conditions and the following disclaimer in the documentation and/or other materials # +-- # provided with the distribution. # +-- # # +-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # +-- # endorse or promote products derived from this software without specific prior written # +-- # permission. # +-- # # +-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # +-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # +-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # +-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # +-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # +-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # +-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # +-- # 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 # +-- ################################################################################################# + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library neorv32; +use neorv32.neorv32_package.all; + +entity neorv32_litex_core_complex is + generic ( + CONFIG : natural := 1; -- configuration select (0=minimal, 1=lite, 2=standard, 3=full) + DEBUG : boolean := False -- enable on-chip debugger, valid for all configurations + ); + port ( + -- Global control -- + clk_i : in std_ulogic; -- global clock, rising edge + rstn_i : in std_ulogic; -- global reset, low-active, async + + -- JTAG on-chip debugger interface -- + jtag_trst_i : in std_ulogic; -- low-active TAP reset (optional) + jtag_tck_i : in std_ulogic; -- serial clock + jtag_tdi_i : in std_ulogic; -- serial data input + jtag_tdo_o : out std_ulogic; -- serial data output + jtag_tms_i : in std_ulogic; -- mode select + + -- Wishbone bus interface -- + wb_adr_o : out std_ulogic_vector(31 downto 0); -- address + wb_dat_i : in std_ulogic_vector(31 downto 0); -- read data + wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data + wb_we_o : out std_ulogic; -- read/write + wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable + wb_stb_o : out std_ulogic; -- strobe + wb_cyc_o : out std_ulogic; -- valid cycle + wb_ack_i : in std_ulogic; -- transfer acknowledge + wb_err_i : in std_ulogic; -- transfer error + + -- CPU interrupt -- + mext_irq_i : in std_ulogic -- RISC-V machine external interrupt (MEI) + ); +end neorv32_litex_core_complex; + +architecture neorv32_litex_core_complex_rtl of neorv32_litex_core_complex is + + -- global configuration -- + constant num_configs_c : natural := 4; -- number of pre-defined configurations + constant wb_timeout_c : natural := 4096; -- external bus interface timeout cycles + constant big_endian_c : boolean := false; -- external bus interface endianness; default is little-endian + + -- helpers -- + type bool_t is array (0 to num_configs_c-1) of boolean; + type natural_t is array (0 to num_configs_c-1) of natural; + type configs_t is record + riscv_c : bool_t; + riscv_m : bool_t; + riscv_u : bool_t; + riscv_zicntr : bool_t; + riscv_zihpm : bool_t; + fast_ops : bool_t; + ipb : natural_t; + pmp_nr : natural_t; + hpm_nr : natural_t; + icache_en : bool_t; + icache_nb : natural_t; + icache_bs : natural_t; + icache_as : natural_t; + mtime : bool_t; + end record; + + -- core complex configurations -- + constant configs_c : configs_t := ( + -- minimal lite standard full + riscv_c => ( false, true, true, true ), -- RISC-V compressed instructions 'C' + riscv_m => ( false, true, true, true ), -- RISC-V hardware mul/div 'M' + riscv_u => ( false, false, false, true ), -- RISC-V user mode 'U' + riscv_zicntr => ( false, false, true, true ), -- RISC-V standard CPU counters 'Zicntr' + riscv_zihpm => ( false, false, false, true ), -- RISC-V hardware performance monitors 'Zihpm' + fast_ops => ( false, false, true, true ), -- use DSPs and barrel-shifters + ipb => ( 2, 2, 4, 8 ), -- instruction prefetch buffer depth, power of two, min 2 + pmp_nr => ( 0, 0, 0, 8 ), -- number of PMP regions (0..16) + hpm_nr => ( 0, 0, 0, 8 ), -- number of HPM counters (0..29) + icache_en => ( false, false, true, true ), -- instruction cache enabled + icache_nb => ( 0, 0, 4, 8 ), -- number of cache blocks (lines), power of two + icache_bs => ( 0, 0, 128, 256 ), -- size of cache clock (lines) in bytes, power of two + icache_as => ( 1, 1, 1, 2 ), -- associativity (1 or 2) + mtime => ( false, true, true, true ) -- RISC-V machine system timers + ); + +begin + + -- NEORV32 Core Complex ------------------------------------------------------------------- + -- ------------------------------------------------------------------------------------------- + neorv32_core_complex: neorv32_top + generic map ( + -- General -- + CLOCK_FREQUENCY => 0, -- clock frequency of clk_i in Hz [not required by the core complex] + -- On-Chip Debugger (OCD) -- + ON_CHIP_DEBUGGER_EN => DEBUG, -- implement on-chip debugger + -- RISC-V CPU Extensions -- + CPU_EXTENSION_RISCV_C => configs_c.riscv_c(CONFIG), -- implement compressed extension? + CPU_EXTENSION_RISCV_M => configs_c.riscv_m(CONFIG), -- implement mul/div extension? + CPU_EXTENSION_RISCV_U => configs_c.riscv_u(CONFIG), -- implement user mode extension? + CPU_EXTENSION_RISCV_Zicsr => true, -- implement CSR system? + CPU_EXTENSION_RISCV_Zicntr => configs_c.riscv_zicntr(CONFIG), -- implement base counters? + CPU_EXTENSION_RISCV_Zihpm => configs_c.riscv_zihpm(CONFIG), -- implement hardware performance monitors? + CPU_EXTENSION_RISCV_Zifencei => true, -- implement instruction stream sync.? + -- Tuning Options -- + FAST_MUL_EN => configs_c.fast_ops(CONFIG), -- use DSPs for M extension's multiplier + FAST_SHIFT_EN => configs_c.fast_ops(CONFIG), -- use barrel shifter for shift operations + CPU_CNT_WIDTH => 64, -- total width of CPU cycle and instret counters (0..64) + CPU_IPB_ENTRIES => configs_c.ipb(CONFIG), -- entries in instruction prefetch buffer, has to be a power of 2, min 2 + -- Physical Memory Protection (PMP) -- + PMP_NUM_REGIONS => configs_c.pmp_nr(CONFIG), -- number of regions (0..16) + PMP_MIN_GRANULARITY => 4, -- minimal region granularity in bytes, has to be a power of 2, min 4 bytes + -- Hardware Performance Monitors (HPM) -- + HPM_NUM_CNTS => configs_c.hpm_nr(CONFIG), -- number of implemented HPM counters (0..29) + HPM_CNT_WIDTH => 64, -- total size of HPM counters (0..64) + -- Internal Instruction Cache (iCACHE) -- + ICACHE_EN => configs_c.icache_en(CONFIG), -- implement instruction cache + ICACHE_NUM_BLOCKS => configs_c.icache_nb(CONFIG), -- i-cache: number of blocks (min 1), has to be a power of 2 + ICACHE_BLOCK_SIZE => configs_c.icache_bs(CONFIG), -- i-cache: block size in bytes (min 4), has to be a power of 2 + ICACHE_ASSOCIATIVITY => configs_c.icache_as(CONFIG), -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 + -- External memory interface (WISHBONE) -- + MEM_EXT_EN => true, -- implement external memory bus interface? + MEM_EXT_TIMEOUT => wb_timeout_c, -- cycles after a pending bus access auto-terminates (0 = disabled) + MEM_EXT_PIPE_MODE => true, -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode + MEM_EXT_BIG_ENDIAN => big_endian_c, -- byte order: true=big-endian, false=little-endian + MEM_EXT_ASYNC_RX => true, -- use register buffer for RX data when false + MEM_EXT_ASYNC_TX => true, -- use register buffer for TX data when false + -- Processor peripherals -- + IO_MTIME_EN => configs_c.mtime(CONFIG) -- implement machine system timer (MTIME)? + ) + port map ( + -- Global control -- + clk_i => clk_i, -- global clock, rising edge + rstn_i => rstn_i, -- global reset, low-active, async + -- JTAG on-chip debugger interface -- + jtag_trst_i => jtag_trst_i, -- low-active TAP reset (optional) + jtag_tck_i => jtag_tck_i, -- serial clock + jtag_tdi_i => jtag_tdi_i, -- serial data input + jtag_tdo_o => jtag_tdo_o, -- serial data output + jtag_tms_i => jtag_tms_i, -- mode select + -- Wishbone bus interface -- + wb_tag_o => open, -- request tag + wb_adr_o => wb_adr_o, -- address + wb_dat_i => wb_dat_i, -- read data + wb_dat_o => wb_dat_o, -- write data + wb_we_o => wb_we_o, -- read/write + wb_sel_o => wb_sel_o, -- byte enable + wb_stb_o => wb_stb_o, -- strobe + wb_cyc_o => wb_cyc_o, -- valid cycle + wb_ack_i => wb_ack_i, -- transfer acknowledge + wb_err_i => wb_err_i, -- transfer error + -- CPU Interrupts -- + mext_irq_i => mext_irq_i -- machine external interrupt + ); + + +end neorv32_litex_core_complex_rtl; From 7687b977a317a713b9a7653f0f9e70e02260c944 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 18 Jul 2022 15:18:15 +0200 Subject: [PATCH 2/3] cpu/neorv32: Remove litex_core_complex (Can now directly use upstream version). --- .../neorv32/neorv32_litex_core_complex.vhd | 225 ------------------ 1 file changed, 225 deletions(-) delete mode 100644 litex/soc/cores/cpu/neorv32/neorv32_litex_core_complex.vhd diff --git a/litex/soc/cores/cpu/neorv32/neorv32_litex_core_complex.vhd b/litex/soc/cores/cpu/neorv32/neorv32_litex_core_complex.vhd deleted file mode 100644 index 87aa5d0f2..000000000 --- a/litex/soc/cores/cpu/neorv32/neorv32_litex_core_complex.vhd +++ /dev/null @@ -1,225 +0,0 @@ --- ################################################################################################# --- # << The NEORV32 RISC-V Processor - LiteX NEORV32 Core Complex Wrapper >> # --- # ********************************************************************************************* # --- # __ _ __ _ __ # --- # / / (_) /____ | |/_/ # --- # / /__/ / __/ -_)> < # --- # /____/_/\__/\__/_/|_| # --- # Build your hardware, easily! # --- # # --- # Unless otherwise noted, LiteX is copyright (C) 2012-2022 Enjoy-Digital. All rights reserved. # --- # LiteX HQ: https://github.com/enjoy-digital/litex # --- # # --- # ********************************************************************************************* # --- # NEORV32 Core Complex wrapper for the LiteX SoC builder framework. # --- # https://github.com/enjoy-digital/litex/tree/master/litex/soc/cores/cpu/neorv32 # --- # # --- # This wrapper provides four pre-configured core complex configurations: "minimal", "lite", # --- # "standard" and "full". See the 'configs_c' table for more details which RISC-V ISA extensions # --- # and module parameters are used by each of the these configurations. All configurations can be # --- # used with the RISC-V-compatible on-chip debugger. # --- # # --- # === Bus Interface === # --- # This wrappers uses the "pipelined" Wishbone b4 protocol for the bus interface. See the # --- # "global configuration" constants for further bus configuration parameters (endianness, # --- # timeout, etc.). # --- # # --- # === Interrupt ==== # --- # The external interrupt signal is delegated to the CPU as RISC-V "machine external interrupt # --- # (MTI)". Note that this IRQ signal is high-active - once set the signal has to stay high until # --- # the interrupt request is explicitly acknowledged (e.g. writing to a memory-mapped register)! # --- # # --- # === Core Complex Address Space === # --- # Note that the NEORV32 core complex occupies a small fraction of the total 32-bit address # --- # space for internal components (machine timer, on-chip-debugger, ...). This address space # --- # starts at address 0xffff0000 and ends at 0xffffffff. Any CPU access to this address space # --- # will NOT be delegated to bus interface of the core complex! # --- # ********************************************************************************************* # --- # BSD 3-Clause License # --- # # --- # Copyright (c) 2022, Stephan Nolting. All rights reserved. # --- # # --- # Redistribution and use in source and binary forms, with or without modification, are # --- # permitted provided that the following conditions are met: # --- # # --- # 1. Redistributions of source code must retain the above copyright notice, this list of # --- # conditions and the following disclaimer. # --- # # --- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # --- # conditions and the following disclaimer in the documentation and/or other materials # --- # provided with the distribution. # --- # # --- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # --- # endorse or promote products derived from this software without specific prior written # --- # permission. # --- # # --- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # --- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # --- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # --- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # --- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # --- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # --- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # --- # 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 # --- ################################################################################################# - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library neorv32; -use neorv32.neorv32_package.all; - -entity neorv32_litex_core_complex is - generic ( - CONFIG : natural := 1; -- configuration select (0=minimal, 1=lite, 2=standard, 3=full) - DEBUG : boolean := False -- enable on-chip debugger, valid for all configurations - ); - port ( - -- Global control -- - clk_i : in std_ulogic; -- global clock, rising edge - rstn_i : in std_ulogic; -- global reset, low-active, async - - -- JTAG on-chip debugger interface -- - jtag_trst_i : in std_ulogic; -- low-active TAP reset (optional) - jtag_tck_i : in std_ulogic; -- serial clock - jtag_tdi_i : in std_ulogic; -- serial data input - jtag_tdo_o : out std_ulogic; -- serial data output - jtag_tms_i : in std_ulogic; -- mode select - - -- Wishbone bus interface -- - wb_adr_o : out std_ulogic_vector(31 downto 0); -- address - wb_dat_i : in std_ulogic_vector(31 downto 0); -- read data - wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data - wb_we_o : out std_ulogic; -- read/write - wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable - wb_stb_o : out std_ulogic; -- strobe - wb_cyc_o : out std_ulogic; -- valid cycle - wb_ack_i : in std_ulogic; -- transfer acknowledge - wb_err_i : in std_ulogic; -- transfer error - - -- CPU interrupt -- - mext_irq_i : in std_ulogic -- RISC-V machine external interrupt (MEI) - ); -end neorv32_litex_core_complex; - -architecture neorv32_litex_core_complex_rtl of neorv32_litex_core_complex is - - -- global configuration -- - constant num_configs_c : natural := 4; -- number of pre-defined configurations - constant wb_timeout_c : natural := 4096; -- external bus interface timeout cycles - constant big_endian_c : boolean := false; -- external bus interface endianness; default is little-endian - - -- helpers -- - type bool_t is array (0 to num_configs_c-1) of boolean; - type natural_t is array (0 to num_configs_c-1) of natural; - type configs_t is record - riscv_c : bool_t; - riscv_m : bool_t; - riscv_u : bool_t; - riscv_zicntr : bool_t; - riscv_zihpm : bool_t; - fast_ops : bool_t; - ipb : natural_t; - pmp_nr : natural_t; - hpm_nr : natural_t; - icache_en : bool_t; - icache_nb : natural_t; - icache_bs : natural_t; - icache_as : natural_t; - mtime : bool_t; - end record; - - -- core complex configurations -- - constant configs_c : configs_t := ( - -- minimal lite standard full - riscv_c => ( false, true, true, true ), -- RISC-V compressed instructions 'C' - riscv_m => ( false, true, true, true ), -- RISC-V hardware mul/div 'M' - riscv_u => ( false, false, false, true ), -- RISC-V user mode 'U' - riscv_zicntr => ( false, false, true, true ), -- RISC-V standard CPU counters 'Zicntr' - riscv_zihpm => ( false, false, false, true ), -- RISC-V hardware performance monitors 'Zihpm' - fast_ops => ( false, false, true, true ), -- use DSPs and barrel-shifters - ipb => ( 2, 2, 4, 8 ), -- instruction prefetch buffer depth, power of two, min 2 - pmp_nr => ( 0, 0, 0, 8 ), -- number of PMP regions (0..16) - hpm_nr => ( 0, 0, 0, 8 ), -- number of HPM counters (0..29) - icache_en => ( false, false, true, true ), -- instruction cache enabled - icache_nb => ( 0, 0, 4, 8 ), -- number of cache blocks (lines), power of two - icache_bs => ( 0, 0, 128, 256 ), -- size of cache clock (lines) in bytes, power of two - icache_as => ( 1, 1, 1, 2 ), -- associativity (1 or 2) - mtime => ( false, true, true, true ) -- RISC-V machine system timers - ); - -begin - - -- NEORV32 Core Complex ------------------------------------------------------------------- - -- ------------------------------------------------------------------------------------------- - neorv32_core_complex: neorv32_top - generic map ( - -- General -- - CLOCK_FREQUENCY => 0, -- clock frequency of clk_i in Hz [not required by the core complex] - -- On-Chip Debugger (OCD) -- - ON_CHIP_DEBUGGER_EN => DEBUG, -- implement on-chip debugger - -- RISC-V CPU Extensions -- - CPU_EXTENSION_RISCV_C => configs_c.riscv_c(CONFIG), -- implement compressed extension? - CPU_EXTENSION_RISCV_M => configs_c.riscv_m(CONFIG), -- implement mul/div extension? - CPU_EXTENSION_RISCV_U => configs_c.riscv_u(CONFIG), -- implement user mode extension? - CPU_EXTENSION_RISCV_Zicsr => true, -- implement CSR system? - CPU_EXTENSION_RISCV_Zicntr => configs_c.riscv_zicntr(CONFIG), -- implement base counters? - CPU_EXTENSION_RISCV_Zihpm => configs_c.riscv_zihpm(CONFIG), -- implement hardware performance monitors? - CPU_EXTENSION_RISCV_Zifencei => true, -- implement instruction stream sync.? - -- Tuning Options -- - FAST_MUL_EN => configs_c.fast_ops(CONFIG), -- use DSPs for M extension's multiplier - FAST_SHIFT_EN => configs_c.fast_ops(CONFIG), -- use barrel shifter for shift operations - CPU_CNT_WIDTH => 64, -- total width of CPU cycle and instret counters (0..64) - CPU_IPB_ENTRIES => configs_c.ipb(CONFIG), -- entries in instruction prefetch buffer, has to be a power of 2, min 2 - -- Physical Memory Protection (PMP) -- - PMP_NUM_REGIONS => configs_c.pmp_nr(CONFIG), -- number of regions (0..16) - PMP_MIN_GRANULARITY => 4, -- minimal region granularity in bytes, has to be a power of 2, min 4 bytes - -- Hardware Performance Monitors (HPM) -- - HPM_NUM_CNTS => configs_c.hpm_nr(CONFIG), -- number of implemented HPM counters (0..29) - HPM_CNT_WIDTH => 64, -- total size of HPM counters (0..64) - -- Internal Instruction Cache (iCACHE) -- - ICACHE_EN => configs_c.icache_en(CONFIG), -- implement instruction cache - ICACHE_NUM_BLOCKS => configs_c.icache_nb(CONFIG), -- i-cache: number of blocks (min 1), has to be a power of 2 - ICACHE_BLOCK_SIZE => configs_c.icache_bs(CONFIG), -- i-cache: block size in bytes (min 4), has to be a power of 2 - ICACHE_ASSOCIATIVITY => configs_c.icache_as(CONFIG), -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 - -- External memory interface (WISHBONE) -- - MEM_EXT_EN => true, -- implement external memory bus interface? - MEM_EXT_TIMEOUT => wb_timeout_c, -- cycles after a pending bus access auto-terminates (0 = disabled) - MEM_EXT_PIPE_MODE => true, -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode - MEM_EXT_BIG_ENDIAN => big_endian_c, -- byte order: true=big-endian, false=little-endian - MEM_EXT_ASYNC_RX => true, -- use register buffer for RX data when false - MEM_EXT_ASYNC_TX => true, -- use register buffer for TX data when false - -- Processor peripherals -- - IO_MTIME_EN => configs_c.mtime(CONFIG) -- implement machine system timer (MTIME)? - ) - port map ( - -- Global control -- - clk_i => clk_i, -- global clock, rising edge - rstn_i => rstn_i, -- global reset, low-active, async - -- JTAG on-chip debugger interface -- - jtag_trst_i => jtag_trst_i, -- low-active TAP reset (optional) - jtag_tck_i => jtag_tck_i, -- serial clock - jtag_tdi_i => jtag_tdi_i, -- serial data input - jtag_tdo_o => jtag_tdo_o, -- serial data output - jtag_tms_i => jtag_tms_i, -- mode select - -- Wishbone bus interface -- - wb_tag_o => open, -- request tag - wb_adr_o => wb_adr_o, -- address - wb_dat_i => wb_dat_i, -- read data - wb_dat_o => wb_dat_o, -- write data - wb_we_o => wb_we_o, -- read/write - wb_sel_o => wb_sel_o, -- byte enable - wb_stb_o => wb_stb_o, -- strobe - wb_cyc_o => wb_cyc_o, -- valid cycle - wb_ack_i => wb_ack_i, -- transfer acknowledge - wb_err_i => wb_err_i, -- transfer error - -- CPU Interrupts -- - mext_irq_i => mext_irq_i -- machine external interrupt - ); - - -end neorv32_litex_core_complex_rtl; From 2faef0eedca60330700bb4d4cfe7c961cd50d99d Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 18 Jul 2022 15:51:35 +0200 Subject: [PATCH 3/3] cpu/neorv32/core: Add variants support. --- litex/soc/cores/cpu/neorv32/core.py | 46 +++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/litex/soc/cores/cpu/neorv32/core.py b/litex/soc/cores/cpu/neorv32/core.py index 3a7dbeed9..6053a5f8e 100644 --- a/litex/soc/cores/cpu/neorv32/core.py +++ b/litex/soc/cores/cpu/neorv32/core.py @@ -13,7 +13,7 @@ from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV32 # Variants ----------------------------------------------------------------------------------------- -CPU_VARIANTS = ["standard"] +CPU_VARIANTS = ["minimal", "lite", "standard", "full"] # GCC Flags ---------------------------------------------------------------------------------------- @@ -25,7 +25,10 @@ GCC_FLAGS = { # ||||/--- Single-Precision Floating-Point # |||||/-- Double-Precision Floating-Point # imacfd - "standard": "-march=rv32i -mabi=ilp32", + "minimal": "-march=rv32i -mabi=ilp32", + "lite": "-march=rv32imc -mabi=ilp32", + "standard": "-march=rv32imc -mabi=ilp32", + "full": "-march=rv32imc -mabi=ilp32", } # NEORV32 ------------------------------------------------------------------------------------------ @@ -34,7 +37,6 @@ class NEORV32(CPU): category = "softcore" family = "riscv" name = "neorv32" - human_name = "NEORV32" variants = CPU_VARIANTS data_width = 32 endianness = "little" @@ -53,6 +55,7 @@ class NEORV32(CPU): def __init__(self, platform, variant="standard"): self.platform = platform self.variant = variant + self.human_name = f"NEORV32-{variant}" self.reset = Signal() self.ibus = idbus = wishbone.Interface() self.periph_buses = [idbus] # Peripheral buses (Connected to main SoC's bus). @@ -95,14 +98,14 @@ class NEORV32(CPU): ) # Add Verilog sources - self.add_sources(platform) + self.add_sources(platform, variant) def set_reset_address(self, reset_address): self.reset_address = reset_address assert reset_address == 0x0000_0000 @staticmethod - def add_sources(platform): + def add_sources(platform, variant): cdir = os.path.abspath(os.path.dirname(__file__)) # List VHDL sources. sources = { @@ -152,6 +155,39 @@ class NEORV32(CPU): if not os.path.exists(os.path.join(cdir, vhd)): os.system(f"wget https://raw.githubusercontent.com/stnolting/neorv32/main/rtl/{directory}/{vhd} -P {cdir}") + def configure_litex_core_complex(filename, variant): + # Read Wrapper. + lines = [] + f = open(filename) + for l in f: + lines.append(l) + f.close() + + # Configure. + _lines = [] + for l in lines: + if "constant CONFIG" in l: + config = { + "minimal" : "0", + "lite" : "1", + "standard" : "2", + "full" : "3" + }[variant] + l = f"\tconstant CONFIG : natural := {config};\n" + _lines.append(l) + lines = _lines + + # Write Wrapper. + f = open(filename, "w") + for l in lines: + f.write(l) + f.close() + + configure_litex_core_complex( + filename = os.path.join(cdir, "neorv32_litex_core_complex.vhd"), + variant = variant, + ) + # Convert VHDL to Verilog through GHDL/Yosys. from litex.build import tools import subprocess