758 lines
29 KiB
Verilog
758 lines
29 KiB
Verilog
|
|
// #################################################################################################
|
|
// # << NEORV32 - Processor Top Entity with AXI4-Lite Compatible Host Interface >> #
|
|
// # ********************************************************************************************* #
|
|
// # (c) "AXI", "AXI4", "AXI4-Lite" and "AXI-Stream" are trademarks of ARM Holdings plc. #
|
|
// # ********************************************************************************************* #
|
|
// # BSD 3-Clause License #
|
|
// # #
|
|
// # The NEORV32 RISC-V Processor, https://github.com/stnolting/neorv32 #
|
|
// # Copyright (c) 2024, 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. #
|
|
// #################################################################################################
|
|
// no timescale needed
|
|
|
|
module neorv32_SystemTop_axi4lite(
|
|
input wire m_axi_aclk,
|
|
input wire m_axi_aresetn,
|
|
output wire [31:0] m_axi_awaddr,
|
|
output wire [2:0] m_axi_awprot,
|
|
output wire m_axi_awvalid,
|
|
input wire m_axi_awready,
|
|
output wire [31:0] m_axi_wdata,
|
|
output wire [3:0] m_axi_wstrb,
|
|
output wire m_axi_wvalid,
|
|
input wire m_axi_wready,
|
|
output wire [31:0] m_axi_araddr,
|
|
output wire [2:0] m_axi_arprot,
|
|
output wire m_axi_arvalid,
|
|
input wire m_axi_arready,
|
|
input wire [31:0] m_axi_rdata,
|
|
input wire [1:0] m_axi_rresp,
|
|
input wire m_axi_rvalid,
|
|
output wire m_axi_rready,
|
|
input wire [1:0] m_axi_bresp,
|
|
input wire m_axi_bvalid,
|
|
output wire m_axi_bready,
|
|
output wire [31:0] s0_axis_tdata,
|
|
output wire s0_axis_tvalid,
|
|
output wire s0_axis_tlast,
|
|
input wire s0_axis_tready,
|
|
input wire [31:0] s1_axis_tdata,
|
|
input wire s1_axis_tvalid,
|
|
input wire s1_axis_tlast,
|
|
output wire s1_axis_tready,
|
|
input wire jtag_trst_i,
|
|
input wire jtag_tck_i,
|
|
input wire jtag_tdi_i,
|
|
output wire jtag_tdo_o,
|
|
input wire jtag_tms_i,
|
|
output wire xip_csn_o,
|
|
output wire xip_clk_o,
|
|
input wire xip_dat_i,
|
|
output wire xip_dat_o,
|
|
output wire [63:0] gpio_o,
|
|
input wire [63:0] gpio_i,
|
|
output wire uart0_txd_o,
|
|
input wire uart0_rxd_i,
|
|
output wire uart0_rts_o,
|
|
input wire uart0_cts_i,
|
|
output wire uart1_txd_o,
|
|
input wire uart1_rxd_i,
|
|
output wire uart1_rts_o,
|
|
input wire uart1_cts_i,
|
|
output wire spi_clk_o,
|
|
output wire spi_dat_o,
|
|
input wire spi_dat_i,
|
|
output wire [7:0] spi_csn_o,
|
|
input wire sdi_clk_i,
|
|
output wire sdi_dat_o,
|
|
input wire sdi_dat_i,
|
|
input wire sdi_csn_i,
|
|
input wire twi_sda_i,
|
|
output wire twi_sda_o,
|
|
input wire twi_scl_i,
|
|
output wire twi_scl_o,
|
|
input wire onewire_i,
|
|
output wire onewire_o,
|
|
output wire [11:0] pwm_o,
|
|
input wire [IO_CFS_IN_SIZE - 1:0] cfs_in_i,
|
|
output wire [IO_CFS_OUT_SIZE - 1:0] cfs_out_o,
|
|
output wire neoled_o,
|
|
input wire [31:0] xirq_i,
|
|
input wire mtime_irq_i,
|
|
input wire msw_irq_i,
|
|
input wire mext_irq_i
|
|
);
|
|
|
|
// ------------------------------------------------------------
|
|
// Configuration Generics --
|
|
// ------------------------------------------------------------
|
|
// General --
|
|
parameter [31:0] CLOCK_FREQUENCY=0;
|
|
parameter [31:0] HART_ID=32'h00000000;
|
|
parameter [31:0] VENDOR_ID=32'h00000000;
|
|
parameter INT_BOOTLOADER_EN=true;
|
|
parameter ON_CHIP_DEBUGGER_EN=false;
|
|
parameter DM_LEGACY_MODE=false;
|
|
parameter CPU_EXTENSION_RISCV_A=false;
|
|
parameter CPU_EXTENSION_RISCV_B=false;
|
|
parameter CPU_EXTENSION_RISCV_C=false;
|
|
parameter CPU_EXTENSION_RISCV_E=false;
|
|
parameter CPU_EXTENSION_RISCV_M=false;
|
|
parameter CPU_EXTENSION_RISCV_U=false;
|
|
parameter CPU_EXTENSION_RISCV_Zfinx=false;
|
|
parameter CPU_EXTENSION_RISCV_Zicntr=true;
|
|
parameter CPU_EXTENSION_RISCV_Zihpm=false;
|
|
parameter CPU_EXTENSION_RISCV_Zmmul=false;
|
|
parameter CPU_EXTENSION_RISCV_Zxcfu=false;
|
|
parameter FAST_MUL_EN=false;
|
|
parameter FAST_SHIFT_EN=false;
|
|
parameter [31:0] PMP_NUM_REGIONS=0;
|
|
parameter [31:0] PMP_MIN_GRANULARITY=4;
|
|
parameter [31:0] HPM_NUM_CNTS=0;
|
|
parameter [31:0] HPM_CNT_WIDTH=40;
|
|
parameter [31:0] AMO_RVS_GRANULARITY=4;
|
|
parameter MEM_INT_IMEM_EN=true;
|
|
parameter [31:0] MEM_INT_IMEM_SIZE=16 * 1024;
|
|
parameter MEM_INT_DMEM_EN=true;
|
|
parameter [31:0] MEM_INT_DMEM_SIZE=8 * 1024;
|
|
parameter ICACHE_EN=false;
|
|
parameter [31:0] ICACHE_NUM_BLOCKS=4;
|
|
parameter [31:0] ICACHE_BLOCK_SIZE=64;
|
|
parameter [31:0] ICACHE_ASSOCIATIVITY=1;
|
|
parameter DCACHE_EN=false;
|
|
parameter [31:0] DCACHE_NUM_BLOCKS=4;
|
|
parameter [31:0] DCACHE_BLOCK_SIZE=64;
|
|
parameter XIP_EN=false;
|
|
parameter XIP_CACHE_EN=false;
|
|
parameter [31:0] XIP_CACHE_NUM_BLOCKS=8;
|
|
parameter [31:0] XIP_CACHE_BLOCK_SIZE=256;
|
|
parameter [31:0] XIRQ_NUM_CH=0;
|
|
parameter [31:0] XIRQ_TRIGGER_TYPE=32'hFFFFFFFF;
|
|
parameter [31:0] XIRQ_TRIGGER_POLARITY=32'hFFFFFFFF;
|
|
parameter [31:0] IO_GPIO_NUM=0;
|
|
parameter IO_MTIME_EN=true;
|
|
parameter IO_UART0_EN=true;
|
|
parameter [31:0] IO_UART0_RX_FIFO=1;
|
|
parameter [31:0] IO_UART0_TX_FIFO=1;
|
|
parameter IO_UART1_EN=true;
|
|
parameter [31:0] IO_UART1_RX_FIFO=1;
|
|
parameter [31:0] IO_UART1_TX_FIFO=1;
|
|
parameter IO_SPI_EN=true;
|
|
parameter [31:0] IO_SPI_FIFO=1;
|
|
parameter IO_SDI_EN=false;
|
|
parameter [31:0] IO_SDI_FIFO=1;
|
|
parameter IO_TWI_EN=true;
|
|
parameter [31:0] IO_PWM_NUM_CH=0;
|
|
parameter IO_WDT_EN=true;
|
|
parameter IO_TRNG_EN=true;
|
|
parameter [31:0] IO_TRNG_FIFO=1;
|
|
parameter IO_CFS_EN=false;
|
|
parameter [31:0] IO_CFS_CONFIG=32'h00000000;
|
|
parameter [31:0] IO_CFS_IN_SIZE=32;
|
|
parameter [31:0] IO_CFS_OUT_SIZE=32;
|
|
parameter IO_NEOLED_EN=true;
|
|
parameter [31:0] IO_NEOLED_TX_FIFO=1;
|
|
parameter IO_GPTMR_EN=false;
|
|
parameter IO_ONEWIRE_EN=false;
|
|
parameter IO_DMA_EN=false;
|
|
parameter IO_SLINK_EN=false;
|
|
parameter [31:0] IO_SLINK_RX_FIFO=1;
|
|
parameter [31:0] IO_SLINK_TX_FIFO=1;
|
|
parameter IO_CRC_EN=false;
|
|
// implement cyclic redundancy check unit (CRC)?
|
|
// ------------------------------------------------------------
|
|
// AXI4-Lite-Compatible Master Interface --
|
|
// ------------------------------------------------------------
|
|
// Clock and Reset --
|
|
// Write Address Channel --
|
|
// Write Data Channel --
|
|
// Read Address Channel --
|
|
// Read Data Channel --
|
|
// Write Response Channel --
|
|
// ------------------------------------------------------------
|
|
// AXI4-Stream-Compatible Interface --
|
|
// ------------------------------------------------------------
|
|
// Source --
|
|
// Sink --
|
|
// ------------------------------------------------------------
|
|
// JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --
|
|
// ------------------------------------------------------------
|
|
// low-active TAP reset (optional)
|
|
// serial clock
|
|
// serial data input
|
|
// serial data output
|
|
// mode select
|
|
// ------------------------------------------------------------
|
|
// Processor IO --
|
|
// ------------------------------------------------------------
|
|
// XIP (execute in place via SPI) signals (available if IO_XIP_EN = true) --
|
|
// chip-select, low-active
|
|
// serial clock
|
|
// device data input
|
|
// controller data output
|
|
// GPIO (available if IO_GPIO_EN = true) --
|
|
// parallel output
|
|
// parallel input
|
|
// primary UART0 (available if IO_UART0_EN = true) --
|
|
// UART0 send data
|
|
// UART0 receive data
|
|
// HW flow control: UART0.RX ready to receive ("RTR"), low-active, optional
|
|
// HW flow control: UART0.TX allowed to transmit, low-active, optional
|
|
// secondary UART1 (available if IO_UART1_EN = true) --
|
|
// UART1 send data
|
|
// UART1 receive data
|
|
// HW flow control: UART1.RX ready to receive ("RTR"), low-active, optional
|
|
// HW flow control: UART1.TX allowed to transmit, low-active, optional
|
|
// SPI (available if IO_SPI_EN = true) --
|
|
// SPI serial clock
|
|
// controller data out, peripheral data in
|
|
// controller data in, peripheral data out
|
|
// SPI CS
|
|
// SDI (available if IO_SDI_EN = true) --
|
|
// SDI serial clock
|
|
// controller data out, peripheral data in
|
|
// controller data in, peripheral data out
|
|
// chip-select
|
|
// TWI (available if IO_TWI_EN = true) --
|
|
// serial data line sense input
|
|
// serial data line output (pull low only)
|
|
// serial clock line sense input
|
|
// serial clock line output (pull low only)
|
|
// 1-Wire Interface (available if IO_ONEWIRE_EN = true) --
|
|
// 1-wire bus sense input
|
|
// 1-wire bus output (pull low only)
|
|
// PWM (available if IO_PWM_NUM_CH > 0) --
|
|
// pwm channels
|
|
// Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
|
|
// custom inputs
|
|
// custom outputs
|
|
// NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
|
|
// async serial data line
|
|
// External platform interrupts (available if XIRQ_NUM_CH > 0) --
|
|
// IRQ channels
|
|
// CPU Interrupts --
|
|
// machine timer interrupt, available if IO_MTIME_EN = false
|
|
// machine software interrupt
|
|
// machine external interrupt
|
|
|
|
|
|
|
|
// type conversion --
|
|
parameter IO_CFS_CONFIG_INT = IO_CFS_CONFIG;
|
|
parameter XIRQ_TRIGGER_TYPE_INT = XIRQ_TRIGGER_TYPE;
|
|
parameter XIRQ_TRIGGER_POLARITY_INT = XIRQ_TRIGGER_POLARITY; //
|
|
wire clk_i_int;
|
|
wire rstn_i_int; //
|
|
wire [31:0] s0_axis_tdata_int;
|
|
wire s0_axis_tvalid_int;
|
|
wire s0_axis_tlast_int;
|
|
wire s0_axis_tready_int;
|
|
wire [31:0] s1_axis_tdata_int;
|
|
wire s1_axis_tvalid_int;
|
|
wire s1_axis_tlast_int;
|
|
wire s1_axis_tready_int; //
|
|
wire jtag_trst_i_int;
|
|
wire jtag_tck_i_int;
|
|
wire jtag_tdi_i_int;
|
|
wire jtag_tdo_o_int;
|
|
wire jtag_tms_i_int; //
|
|
wire xip_csn_o_int;
|
|
wire xip_clk_o_int;
|
|
wire xip_dat_i_int;
|
|
wire xip_dat_o_int; //
|
|
wire [63:0] gpio_o_int;
|
|
wire [63:0] gpio_i_int; //
|
|
wire uart0_txd_o_int;
|
|
wire uart0_rxd_i_int;
|
|
wire uart0_rts_o_int;
|
|
wire uart0_cts_i_int; //
|
|
wire uart1_txd_o_int;
|
|
wire uart1_rxd_i_int;
|
|
wire uart1_rts_o_int;
|
|
wire uart1_cts_i_int; //
|
|
wire spi_clk_o_int;
|
|
wire spi_dat_o_int;
|
|
wire spi_dat_i_int;
|
|
wire [7:0] spi_csn_o_int; //
|
|
wire [11:0] pwm_o_int; //
|
|
wire [IO_CFS_IN_SIZE - 1:0] cfs_in_i_int;
|
|
wire [IO_CFS_OUT_SIZE - 1:0] cfs_out_o_int; //
|
|
wire neoled_o_int; //
|
|
wire twi_sda_i_int;
|
|
wire twi_sda_o_int;
|
|
wire twi_scl_i_int;
|
|
wire twi_scl_o_int; //
|
|
wire onewire_i_int;
|
|
wire onewire_o_int; //
|
|
wire [31:0] xirq_i_int; //
|
|
wire mtime_irq_i_int;
|
|
wire msw_irq_i_int;
|
|
wire mext_irq_i_int;
|
|
wire ack_read; wire ack_write; // normal transfer termination
|
|
wire err_read; wire err_write; // error transfer termination
|
|
|
|
// The Core Of The Problem ----------------------------------------------------------------
|
|
// -------------------------------------------------------------------------------------------
|
|
neorv32_top #(
|
|
// General --
|
|
.CLOCK_FREQUENCY(CLOCK_FREQUENCY),
|
|
// clock frequency of clk_i in Hz
|
|
.HART_ID(HART_ID),
|
|
// hardware thread ID
|
|
.VENDOR_ID(VENDOR_ID),
|
|
// vendor's JEDEC ID
|
|
.INT_BOOTLOADER_EN(INT_BOOTLOADER_EN),
|
|
// boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
|
|
// On-Chip Debugger (OCD) --
|
|
.ON_CHIP_DEBUGGER_EN(ON_CHIP_DEBUGGER_EN),
|
|
// implement on-chip debugger
|
|
.DM_LEGACY_MODE(DM_LEGACY_MODE),
|
|
// debug module spec version: false = v1.0, true = v0.13
|
|
// RISC-V CPU Extensions --
|
|
.CPU_EXTENSION_RISCV_A(CPU_EXTENSION_RISCV_A),
|
|
// implement atomic memory operations extension?
|
|
.CPU_EXTENSION_RISCV_B(CPU_EXTENSION_RISCV_B),
|
|
// implement bit-manipulation 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_M(CPU_EXTENSION_RISCV_M),
|
|
// implement mul/div extension?
|
|
.CPU_EXTENSION_RISCV_U(CPU_EXTENSION_RISCV_U),
|
|
// implement user mode extension?
|
|
.CPU_EXTENSION_RISCV_Zfinx(CPU_EXTENSION_RISCV_Zfinx),
|
|
// implement 32-bit floating-point extension (using INT reg!)
|
|
.CPU_EXTENSION_RISCV_Zicntr(CPU_EXTENSION_RISCV_Zicntr),
|
|
// implement base counters?
|
|
.CPU_EXTENSION_RISCV_Zihpm(CPU_EXTENSION_RISCV_Zihpm),
|
|
// implement hardware performance monitors?
|
|
.CPU_EXTENSION_RISCV_Zmmul(CPU_EXTENSION_RISCV_Zmmul),
|
|
// implement multiply-only M sub-extension?
|
|
.CPU_EXTENSION_RISCV_Zxcfu(CPU_EXTENSION_RISCV_Zxcfu),
|
|
// implement custom (instr.) functions unit?
|
|
// Extension Options --
|
|
.FAST_MUL_EN(FAST_MUL_EN),
|
|
// use DSPs for M extension's multiplier
|
|
.FAST_SHIFT_EN(FAST_SHIFT_EN),
|
|
// use barrel shifter for shift operations
|
|
// Physical Memory Protection (PMP) --
|
|
.PMP_NUM_REGIONS(PMP_NUM_REGIONS),
|
|
// number of regions (0..16)
|
|
.PMP_MIN_GRANULARITY(PMP_MIN_GRANULARITY),
|
|
// minimal region granularity in bytes, has to be a power of 2, min 4 bytes
|
|
// Hardware Performance Monitors (HPM) --
|
|
.HPM_NUM_CNTS(HPM_NUM_CNTS),
|
|
// number of implemented HPM counters (0..29)
|
|
.HPM_CNT_WIDTH(HPM_CNT_WIDTH),
|
|
// total size of HPM counters (0..64)
|
|
// Atomic Memory Access - Reservation Set Granularity --
|
|
.AMO_RVS_GRANULARITY(AMO_RVS_GRANULARITY),
|
|
// size in bytes, has to be a power of 2, min 4
|
|
// Internal Instruction memory --
|
|
.MEM_INT_IMEM_EN(MEM_INT_IMEM_EN),
|
|
// implement processor-internal instruction memory
|
|
.MEM_INT_IMEM_SIZE(MEM_INT_IMEM_SIZE),
|
|
// size of processor-internal instruction memory in bytes
|
|
// Internal Data memory --
|
|
.MEM_INT_DMEM_EN(MEM_INT_DMEM_EN),
|
|
// implement processor-internal data memory
|
|
.MEM_INT_DMEM_SIZE(MEM_INT_DMEM_SIZE),
|
|
// size of processor-internal data memory in bytes
|
|
// Internal Cache memory --
|
|
.ICACHE_EN(ICACHE_EN),
|
|
// implement instruction cache
|
|
.ICACHE_NUM_BLOCKS(ICACHE_NUM_BLOCKS),
|
|
// i-cache: number of blocks (min 1), has to be a power of 2
|
|
.ICACHE_BLOCK_SIZE(ICACHE_BLOCK_SIZE),
|
|
// i-cache: block size in bytes (min 4), has to be a power of 2
|
|
.ICACHE_ASSOCIATIVITY(ICACHE_ASSOCIATIVITY),
|
|
// i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
|
|
// Internal Data Cache (dCACHE) --
|
|
.DCACHE_EN(DCACHE_EN),
|
|
// implement data cache
|
|
.DCACHE_NUM_BLOCKS(DCACHE_NUM_BLOCKS),
|
|
// d-cache: number of blocks (min 1), has to be a power of 2
|
|
.DCACHE_BLOCK_SIZE(DCACHE_BLOCK_SIZE),
|
|
// d-cache: block size in bytes (min 4), has to be a power of 2
|
|
// External memory interface --
|
|
.MEM_EXT_EN(true),
|
|
// implement external memory bus interface?
|
|
.MEM_EXT_TIMEOUT(0),
|
|
// cycles after a pending bus access auto-terminates (0 = disabled)
|
|
.MEM_EXT_PIPE_MODE(false),
|
|
// protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
|
|
.MEM_EXT_BIG_ENDIAN(false),
|
|
// byte order: true=big-endian, false=little-endian
|
|
.MEM_EXT_ASYNC_RX(false),
|
|
// use register buffer for RX data when false
|
|
.MEM_EXT_ASYNC_TX(false),
|
|
// use register buffer for TX data when false
|
|
// Execute in-place module (XIP) --
|
|
.XIP_EN(XIP_EN),
|
|
// implement execute in place module (XIP)?
|
|
.XIP_CACHE_EN(XIP_CACHE_EN),
|
|
// implement XIP cache?
|
|
.XIP_CACHE_NUM_BLOCKS(XIP_CACHE_NUM_BLOCKS),
|
|
// number of blocks (min 1), has to be a power of 2
|
|
.XIP_CACHE_BLOCK_SIZE(XIP_CACHE_BLOCK_SIZE),
|
|
// block size in bytes (min 4), has to be a power of 2
|
|
// External Interrupts Controller (XIRQ) --
|
|
.XIRQ_NUM_CH(XIRQ_NUM_CH),
|
|
// number of external IRQ channels (0..32)
|
|
.XIRQ_TRIGGER_TYPE(XIRQ_TRIGGER_TYPE_INT),
|
|
// trigger type: 0=level, 1=edge
|
|
.XIRQ_TRIGGER_POLARITY(XIRQ_TRIGGER_POLARITY_INT),
|
|
// trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
|
|
// Processor peripherals --
|
|
.IO_GPIO_NUM(IO_GPIO_NUM),
|
|
// number of GPIO input/output pairs (0..64)
|
|
.IO_MTIME_EN(IO_MTIME_EN),
|
|
// implement machine system timer (MTIME)?
|
|
.IO_UART0_EN(IO_UART0_EN),
|
|
// implement primary universal asynchronous receiver/transmitter (UART0)?
|
|
.IO_UART0_RX_FIFO(IO_UART0_RX_FIFO),
|
|
// RX fifo depth, has to be a power of two, min 1
|
|
.IO_UART0_TX_FIFO(IO_UART0_TX_FIFO),
|
|
// TX fifo depth, has to be a power of two, min 1
|
|
.IO_UART1_EN(IO_UART1_EN),
|
|
// implement secondary universal asynchronous receiver/transmitter (UART1)?
|
|
.IO_UART1_RX_FIFO(IO_UART1_RX_FIFO),
|
|
// RX fifo depth, has to be a power of two, min 1
|
|
.IO_UART1_TX_FIFO(IO_UART1_TX_FIFO),
|
|
// TX fifo depth, has to be a power of two, min 1
|
|
.IO_SPI_EN(IO_SPI_EN),
|
|
// implement serial peripheral interface (SPI)?
|
|
.IO_SPI_FIFO(IO_SPI_FIFO),
|
|
// SPI RTX fifo depth, has to be a power of two, min 1
|
|
.IO_SDI_EN(IO_SDI_EN),
|
|
// implement serial data interface (SDI)?
|
|
.IO_SDI_FIFO(IO_SDI_FIFO),
|
|
// RTX fifo depth, has to be zero or a power of two, min 1
|
|
.IO_TWI_EN(IO_TWI_EN),
|
|
// implement two-wire interface (TWI)?
|
|
.IO_PWM_NUM_CH(IO_PWM_NUM_CH),
|
|
// number of PWM channels to implement (0..12); 0 = disabled
|
|
.IO_WDT_EN(IO_WDT_EN),
|
|
// implement watch dog timer (WDT)?
|
|
.IO_TRNG_EN(IO_TRNG_EN),
|
|
// implement true random number generator (TRNG)?
|
|
.IO_TRNG_FIFO(IO_TRNG_FIFO),
|
|
// TRNG fifo depth, has to be a power of two, min 1
|
|
.IO_CFS_EN(IO_CFS_EN),
|
|
// implement custom functions subsystem (CFS)?
|
|
.IO_CFS_CONFIG(IO_CFS_CONFIG_INT),
|
|
// custom CFS configuration generic
|
|
.IO_CFS_IN_SIZE(IO_CFS_IN_SIZE),
|
|
// size of CFS input conduit in bits
|
|
.IO_CFS_OUT_SIZE(IO_CFS_OUT_SIZE),
|
|
// size of CFS output conduit in bits
|
|
.IO_NEOLED_EN(IO_NEOLED_EN),
|
|
// implement NeoPixel-compatible smart LED interface (NEOLED)?
|
|
.IO_NEOLED_TX_FIFO(IO_NEOLED_TX_FIFO),
|
|
// NEOLED TX FIFO depth, 1..32k, has to be a power of two
|
|
.IO_GPTMR_EN(IO_GPTMR_EN),
|
|
// implement general purpose timer (GPTMR)?
|
|
.IO_ONEWIRE_EN(IO_ONEWIRE_EN),
|
|
// implement 1-wire interface (ONEWIRE)?
|
|
.IO_DMA_EN(IO_DMA_EN),
|
|
// implement direct memory access controller (DMA)?
|
|
.IO_SLINK_EN(IO_SLINK_EN),
|
|
// implement stream link interface (SLINK)?
|
|
.IO_SLINK_RX_FIFO(IO_SLINK_RX_FIFO),
|
|
// RX fifo depth, has to be a power of two, min 1
|
|
.IO_SLINK_TX_FIFO(IO_SLINK_TX_FIFO),
|
|
// TX fifo depth, has to be a power of two, min 1
|
|
.IO_CRC_EN(IO_CRC_EN))
|
|
neorv32_top_inst(
|
|
// Global control --
|
|
.clk_i(clk_i_int),
|
|
// global clock, rising edge
|
|
.rstn_i(rstn_i_int),
|
|
// global reset, low-active, async
|
|
// JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --
|
|
.jtag_trst_i(jtag_trst_i_int),
|
|
// low-active TAP reset (optional)
|
|
.jtag_tck_i(jtag_tck_i_int),
|
|
// serial clock
|
|
.jtag_tdi_i(jtag_tdi_i_int),
|
|
// serial data input
|
|
.jtag_tdo_o(jtag_tdo_o_int),
|
|
// serial data output
|
|
.jtag_tms_i(jtag_tms_i_int),
|
|
// mode select
|
|
// Wishbone bus interface (available if MEM_EXT_EN = true) --
|
|
.wb_tag_o(wb_core.tag),
|
|
// tag
|
|
.wb_adr_o(wb_core.adr),
|
|
// address
|
|
.wb_dat_i(wb_core.di),
|
|
// read data
|
|
.wb_dat_o(wb_core.do),
|
|
// write data
|
|
.wb_we_o(wb_core.we),
|
|
// read/write
|
|
.wb_sel_o(wb_core.sel),
|
|
// byte enable
|
|
.wb_stb_o(wb_core.stb),
|
|
// strobe
|
|
.wb_cyc_o(wb_core.cyc),
|
|
// valid cycle
|
|
.wb_ack_i(wb_core.ack),
|
|
// transfer acknowledge
|
|
.wb_err_i(wb_core.err),
|
|
// transfer error
|
|
// Stream Link Interface (available if IO_SLINK_EN = true) --
|
|
.slink_rx_dat_i(s1_axis_tdata_int),
|
|
// RX input data
|
|
.slink_rx_val_i(s1_axis_tvalid_int),
|
|
// RX valid input
|
|
.slink_rx_lst_i(s1_axis_tlast_int),
|
|
// last element of stream
|
|
.slink_rx_rdy_o(s1_axis_tready_int),
|
|
// RX ready to receive
|
|
.slink_tx_dat_o(s0_axis_tdata_int),
|
|
// TX output data
|
|
.slink_tx_val_o(s0_axis_tvalid_int),
|
|
// TX valid output
|
|
.slink_tx_lst_o(s0_axis_tlast_int),
|
|
// last element of stream
|
|
.slink_tx_rdy_i(s0_axis_tready_int),
|
|
// TX ready to send
|
|
// XIP (execute in place via SPI) signals (available if IO_XIP_EN = true) --
|
|
.xip_csn_o(xip_csn_o_int),
|
|
// chip-select, low-active
|
|
.xip_clk_o(xip_clk_o_int),
|
|
// serial clock
|
|
.xip_dat_i(xip_dat_i_int),
|
|
// device data input
|
|
.xip_dat_o(xip_dat_o_int),
|
|
// controller data output
|
|
// GPIO (available if IO_GPIO_NUM > 0) --
|
|
.gpio_o(gpio_o_int),
|
|
// parallel output
|
|
.gpio_i(gpio_i_int),
|
|
// parallel input
|
|
// primary UART0 (available if IO_UART0_EN = true) --
|
|
.uart0_txd_o(uart0_txd_o_int),
|
|
// UART0 send data
|
|
.uart0_rxd_i(uart0_rxd_i_int),
|
|
// UART0 receive data
|
|
.uart0_rts_o(uart0_rts_o_int),
|
|
// HW flow control: UART0.RX ready to receive ("RTR"), low-active, optional
|
|
.uart0_cts_i(uart0_cts_i_int),
|
|
// HW flow control: UART0.TX allowed to transmit, low-active, optional
|
|
// secondary UART1 (available if IO_UART1_EN = true) --
|
|
.uart1_txd_o(uart1_txd_o_int),
|
|
// UART1 send data
|
|
.uart1_rxd_i(uart1_rxd_i_int),
|
|
// UART1 receive data
|
|
.uart1_rts_o(uart1_rts_o_int),
|
|
// HW flow control: UART1.RX ready to receive ("RTR"), low-active, optional
|
|
.uart1_cts_i(uart1_cts_i_int),
|
|
// HW flow control: UART1.TX allowed to transmit, low-active, optional
|
|
// SPI (available if IO_SPI_EN = true) --
|
|
.spi_clk_o(spi_clk_o_int),
|
|
// SPI serial clock
|
|
.spi_dat_o(spi_dat_o_int),
|
|
// controller data out, peripheral data in
|
|
.spi_dat_i(spi_dat_i_int),
|
|
// controller data in, peripheral data out
|
|
.spi_csn_o(spi_csn_o_int),
|
|
// SPI CS
|
|
// TWI (available if IO_TWI_EN = true) --
|
|
.twi_sda_i(twi_sda_i_int),
|
|
// serial data line sense input
|
|
.twi_sda_o(twi_sda_o_int),
|
|
// serial data line output (pull low only)
|
|
.twi_scl_i(twi_scl_i_int),
|
|
// serial clock line sense input
|
|
.twi_scl_o(twi_scl_o_int),
|
|
// serial clock line output (pull low only)
|
|
// 1-Wire Interface (available if IO_ONEWIRE_EN = true) --
|
|
.onewire_i(onewire_i_int),
|
|
// 1-wire bus sense input
|
|
.onewire_o(onewire_o_int),
|
|
// 1-wire bus output (pull low only)
|
|
// PWM available if IO_PWM_NUM_CH > 0) --
|
|
.pwm_o(pwm_o_int),
|
|
// pwm channels
|
|
// Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
|
|
.cfs_in_i(cfs_in_i_int),
|
|
// custom inputs
|
|
.cfs_out_o(cfs_out_o_int),
|
|
// custom outputs
|
|
// NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
|
|
.neoled_o(neoled_o_int),
|
|
// async serial data line
|
|
// External platform interrupts (available if XIRQ_NUM_CH > 0) --
|
|
.xirq_i(xirq_i_int),
|
|
// IRQ channels
|
|
// CPU Interrupts --
|
|
.mtime_irq_i(mtime_irq_i_int),
|
|
// machine timer interrupt, available if IO_MTIME_EN = false
|
|
.msw_irq_i(msw_irq_i_int),
|
|
// machine software interrupt
|
|
.mext_irq_i(mext_irq_i_int));
|
|
|
|
// type conversion --
|
|
assign s0_axis_tdata = s0_axis_tdata_int;
|
|
assign s0_axis_tvalid = s0_axis_tvalid_int;
|
|
assign s0_axis_tlast = s0_axis_tlast_int;
|
|
assign s0_axis_tready_int = s0_axis_tready;
|
|
assign s1_axis_tdata_int = s1_axis_tdata;
|
|
assign s1_axis_tvalid_int = s1_axis_tvalid;
|
|
assign s1_axis_tlast_int = s1_axis_tlast;
|
|
assign s1_axis_tready = s1_axis_tready_int;
|
|
assign xip_csn_o = xip_csn_o_int;
|
|
assign xip_clk_o = xip_clk_o_int;
|
|
assign xip_dat_i_int = xip_dat_i;
|
|
assign xip_dat_o = xip_dat_o_int;
|
|
assign gpio_o = gpio_o_int;
|
|
assign gpio_i_int = gpio_i;
|
|
assign jtag_trst_i_int = jtag_trst_i;
|
|
assign jtag_tck_i_int = jtag_tck_i;
|
|
assign jtag_tdi_i_int = jtag_tdi_i;
|
|
assign jtag_tdo_o = jtag_tdo_o_int;
|
|
assign jtag_tms_i_int = jtag_tms_i;
|
|
assign uart0_txd_o = uart0_txd_o_int;
|
|
assign uart0_rxd_i_int = uart0_rxd_i;
|
|
assign uart0_rts_o = uart0_rts_o_int;
|
|
assign uart0_cts_i_int = uart0_cts_i;
|
|
assign uart1_txd_o = uart1_txd_o_int;
|
|
assign uart1_rxd_i_int = uart1_rxd_i;
|
|
assign uart1_rts_o = uart1_rts_o_int;
|
|
assign uart1_cts_i_int = uart1_cts_i;
|
|
assign spi_clk_o = spi_clk_o_int;
|
|
assign spi_dat_o = spi_dat_o_int;
|
|
assign spi_dat_i_int = spi_dat_i;
|
|
assign spi_csn_o = spi_csn_o_int;
|
|
assign pwm_o = pwm_o_int;
|
|
assign cfs_in_i_int = cfs_in_i;
|
|
assign cfs_out_o = cfs_out_o_int;
|
|
assign neoled_o = neoled_o_int;
|
|
assign twi_sda_i_int = twi_sda_i;
|
|
assign twi_sda_o = twi_sda_o_int;
|
|
assign twi_scl_i_int = twi_scl_i;
|
|
assign twi_scl_o = twi_scl_o_int;
|
|
assign onewire_i_int = onewire_i;
|
|
assign onewire_o = onewire_o_int;
|
|
assign xirq_i_int = xirq_i;
|
|
assign mtime_irq_i_int = mtime_irq_i;
|
|
assign msw_irq_i_int = msw_irq_i;
|
|
assign mext_irq_i_int = mext_irq_i;
|
|
// Wishbone to AXI4-Lite Bridge -----------------------------------------------------------
|
|
// -------------------------------------------------------------------------------------------
|
|
// access arbiter --
|
|
always @(posedge rstn_i_int, posedge clk_i_int) begin
|
|
if((rstn_i_int == 1'b0)) begin
|
|
ctrl.radr_received <= 1'b0;
|
|
ctrl.wadr_received <= 1'b0;
|
|
ctrl.wdat_received <= 1'b0;
|
|
end else begin
|
|
if((wb_core.cyc == 1'b0)) begin
|
|
// idle
|
|
ctrl.radr_received <= 1'b0;
|
|
ctrl.wadr_received <= 1'b0;
|
|
ctrl.wdat_received <= 1'b0;
|
|
end
|
|
else begin
|
|
// busy
|
|
// "read address received" flag --
|
|
if((wb_core.we == 1'b0)) begin
|
|
// pending READ
|
|
if((m_axi_arready == 1'b1)) begin
|
|
// read address received by interconnect?
|
|
ctrl.radr_received <= 1'b1;
|
|
end
|
|
end
|
|
// "write address received" flag --
|
|
if((wb_core.we == 1'b1)) begin
|
|
// pending WRITE
|
|
if((m_axi_awready == 1'b1)) begin
|
|
// write address received by interconnect?
|
|
ctrl.wadr_received <= 1'b1;
|
|
end
|
|
end
|
|
// "write data received" flag --
|
|
if((wb_core.we == 1'b1)) begin
|
|
// pending WRITE
|
|
if((m_axi_wready == 1'b1)) begin
|
|
// write data received by interconnect?
|
|
ctrl.wdat_received <= 1'b1;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
// AXI4-Lite Global Signals --
|
|
assign clk_i_int = m_axi_aclk;
|
|
assign rstn_i_int = m_axi_aresetn;
|
|
// AXI4-Lite Read Address Channel --
|
|
assign m_axi_araddr = wb_core.adr;
|
|
assign m_axi_arvalid = (wb_core.cyc & ( ~wb_core.we)) & ( ~ctrl.radr_received);
|
|
//m_axi_arprot <= "000"; -- recommended by Xilinx
|
|
assign m_axi_arprot[0] = wb_core.tag[0];
|
|
// 0:unprivileged access, 1:privileged access
|
|
assign m_axi_arprot[1] = wb_core.tag[1];
|
|
// 0:secure access, 1:non-secure access
|
|
assign m_axi_arprot[2] = wb_core.tag[2];
|
|
// 0:data access, 1:instruction access
|
|
// AXI4-Lite Read Data Channel --
|
|
assign m_axi_rready = wb_core.cyc & ( ~wb_core.we);
|
|
assign wb_core.di = m_axi_rdata;
|
|
assign ack_read = m_axi_rvalid;
|
|
assign err_read = (m_axi_rresp == 2'b00) ? 1'b0 : 1'b1;
|
|
// read response = ok? check this signal only when m_axi_rvalid = '1'
|
|
// AXI4-Lite Write Address Channel --
|
|
assign m_axi_awaddr = wb_core.adr;
|
|
assign m_axi_awvalid = (wb_core.cyc & wb_core.we) & ( ~ctrl.wadr_received);
|
|
//m_axi_awprot <= "000"; -- recommended by Xilinx
|
|
assign m_axi_awprot[0] = wb_core.tag[0];
|
|
// 0:unprivileged access, 1:privileged access
|
|
assign m_axi_awprot[1] = wb_core.tag[1];
|
|
// 0:secure access, 1:non-secure access
|
|
assign m_axi_awprot[2] = wb_core.tag[2];
|
|
// 0:data access, 1:instruction access
|
|
// AXI4-Lite Write Data Channel --
|
|
assign m_axi_wdata = wb_core.do;
|
|
assign m_axi_wvalid = (wb_core.cyc & wb_core.we) & ( ~ctrl.wdat_received);
|
|
assign m_axi_wstrb = wb_core.sel;
|
|
// byte-enable
|
|
// AXI4-Lite Write Response Channel --
|
|
assign m_axi_bready = wb_core.cyc & wb_core.we;
|
|
assign ack_write = m_axi_bvalid;
|
|
assign err_write = (m_axi_bresp == 2'b00) ? 1'b0 : 1'b1;
|
|
// write response = ok? check this signal only when m_axi_bvalid = '1'
|
|
// Wishbone transfer termination --
|
|
assign wb_core.ack = ack_read | ack_write;
|
|
assign wb_core.err = (ack_read & err_read) | (ack_write & err_write);
|
|
|
|
endmodule
|