OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_top.vhd] - Blame information for rev 68

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 zero_gravi
-- #################################################################################################
2 66 zero_gravi
-- # << The NEORV32 RISC-V Processor - Top Entity >>                                               #
3 2 zero_gravi
-- # ********************************************************************************************* #
4 63 zero_gravi
-- # Check out the processor's online documentation for more information:                          #
5
-- #  HQ:         https://github.com/stnolting/neorv32                                             #
6
-- #  Data Sheet: https://stnolting.github.io/neorv32                                              #
7
-- #  User Guide: https://stnolting.github.io/neorv32/ug                                           #
8 2 zero_gravi
-- # ********************************************************************************************* #
9
-- # BSD 3-Clause License                                                                          #
10
-- #                                                                                               #
11 42 zero_gravi
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved.                                     #
12 2 zero_gravi
-- #                                                                                               #
13
-- # Redistribution and use in source and binary forms, with or without modification, are          #
14
-- # permitted provided that the following conditions are met:                                     #
15
-- #                                                                                               #
16
-- # 1. Redistributions of source code must retain the above copyright notice, this list of        #
17
-- #    conditions and the following disclaimer.                                                   #
18
-- #                                                                                               #
19
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
20
-- #    conditions and the following disclaimer in the documentation and/or other materials        #
21
-- #    provided with the distribution.                                                            #
22
-- #                                                                                               #
23
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
24
-- #    endorse or promote products derived from this software without specific prior written      #
25
-- #    permission.                                                                                #
26
-- #                                                                                               #
27
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
28
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
29
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
30
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
31
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
32
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
33
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
34
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
35
-- # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
36
-- # ********************************************************************************************* #
37
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting #
38
-- #################################################################################################
39
 
40
library ieee;
41
use ieee.std_logic_1164.all;
42
use ieee.numeric_std.all;
43
 
44
library neorv32;
45
use neorv32.neorv32_package.all;
46
 
47
entity neorv32_top is
48
  generic (
49
    -- General --
50 62 zero_gravi
    CLOCK_FREQUENCY              : natural;           -- clock frequency of clk_i in Hz
51 49 zero_gravi
    HW_THREAD_ID                 : natural := 0;      -- hardware thread id (32-bit)
52 62 zero_gravi
    INT_BOOTLOADER_EN            : boolean := false;  -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
53 50 zero_gravi
 
54 59 zero_gravi
    -- On-Chip Debugger (OCD) --
55
    ON_CHIP_DEBUGGER_EN          : boolean := false;  -- implement on-chip debugger
56
 
57 2 zero_gravi
    -- RISC-V CPU Extensions --
58 39 zero_gravi
    CPU_EXTENSION_RISCV_A        : boolean := false;  -- implement atomic extension?
59 66 zero_gravi
    CPU_EXTENSION_RISCV_B        : boolean := false;  -- implement bit-manipulation extension?
60 11 zero_gravi
    CPU_EXTENSION_RISCV_C        : boolean := false;  -- implement compressed extension?
61 8 zero_gravi
    CPU_EXTENSION_RISCV_E        : boolean := false;  -- implement embedded RF extension?
62 61 zero_gravi
    CPU_EXTENSION_RISCV_M        : boolean := false;  -- implement mul/div extension?
63 15 zero_gravi
    CPU_EXTENSION_RISCV_U        : boolean := false;  -- implement user mode extension?
64 57 zero_gravi
    CPU_EXTENSION_RISCV_Zfinx    : boolean := false;  -- implement 32-bit floating-point extension (using INT regs!)
65 8 zero_gravi
    CPU_EXTENSION_RISCV_Zicsr    : boolean := true;   -- implement CSR system?
66 66 zero_gravi
    CPU_EXTENSION_RISCV_Zicntr   : boolean := true;   -- implement base counters?
67
    CPU_EXTENSION_RISCV_Zihpm    : boolean := false;  -- implement hardware performance monitors?
68 39 zero_gravi
    CPU_EXTENSION_RISCV_Zifencei : boolean := false;  -- implement instruction stream sync.?
69 61 zero_gravi
    CPU_EXTENSION_RISCV_Zmmul    : boolean := false;  -- implement multiply-only M sub-extension?
70 50 zero_gravi
 
71 19 zero_gravi
    -- Extension Options --
72 23 zero_gravi
    FAST_MUL_EN                  : boolean := false;  -- use DSPs for M extension's multiplier
73 39 zero_gravi
    FAST_SHIFT_EN                : boolean := false;  -- use barrel shifter for shift operations
74 56 zero_gravi
    CPU_CNT_WIDTH                : natural := 64;     -- total width of CPU cycle and instret counters (0..64)
75 62 zero_gravi
    CPU_IPB_ENTRIES              : natural := 2;      -- entries is instruction prefetch buffer, has to be a power of 2
76 50 zero_gravi
 
77 15 zero_gravi
    -- Physical Memory Protection (PMP) --
78 42 zero_gravi
    PMP_NUM_REGIONS              : natural := 0;      -- number of regions (0..64)
79
    PMP_MIN_GRANULARITY          : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
80 50 zero_gravi
 
81 42 zero_gravi
    -- Hardware Performance Monitors (HPM) --
82 47 zero_gravi
    HPM_NUM_CNTS                 : natural := 0;      -- number of implemented HPM counters (0..29)
83 60 zero_gravi
    HPM_CNT_WIDTH                : natural := 40;     -- total size of HPM counters (0..64)
84 50 zero_gravi
 
85 61 zero_gravi
    -- Internal Instruction memory (IMEM) --
86 62 zero_gravi
    MEM_INT_IMEM_EN              : boolean := false;  -- implement processor-internal instruction memory
87 8 zero_gravi
    MEM_INT_IMEM_SIZE            : natural := 16*1024; -- size of processor-internal instruction memory in bytes
88 50 zero_gravi
 
89 61 zero_gravi
    -- Internal Data memory (DMEM) --
90 62 zero_gravi
    MEM_INT_DMEM_EN              : boolean := false;  -- implement processor-internal data memory
91 8 zero_gravi
    MEM_INT_DMEM_SIZE            : natural := 8*1024; -- size of processor-internal data memory in bytes
92 50 zero_gravi
 
93 61 zero_gravi
    -- Internal Cache memory (iCACHE) --
94 44 zero_gravi
    ICACHE_EN                    : boolean := false;  -- implement instruction cache
95 41 zero_gravi
    ICACHE_NUM_BLOCKS            : natural := 4;      -- i-cache: number of blocks (min 1), has to be a power of 2
96
    ICACHE_BLOCK_SIZE            : natural := 64;     -- i-cache: block size in bytes (min 4), has to be a power of 2
97 45 zero_gravi
    ICACHE_ASSOCIATIVITY         : natural := 1;      -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
98 50 zero_gravi
 
99 61 zero_gravi
    -- External memory interface (WISHBONE) --
100 44 zero_gravi
    MEM_EXT_EN                   : boolean := false;  -- implement external memory bus interface?
101 57 zero_gravi
    MEM_EXT_TIMEOUT              : natural := 255;    -- cycles after a pending bus access auto-terminates (0 = disabled)
102 62 zero_gravi
    MEM_EXT_PIPE_MODE            : boolean := false;  -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
103
    MEM_EXT_BIG_ENDIAN           : boolean := false;  -- byte order: true=big-endian, false=little-endian
104
    MEM_EXT_ASYNC_RX             : boolean := false;  -- use register buffer for RX data when false
105 50 zero_gravi
 
106 61 zero_gravi
    -- Stream link interface (SLINK) --
107
    SLINK_NUM_TX                 : natural := 0;      -- number of TX links (0..8)
108
    SLINK_NUM_RX                 : natural := 0;      -- number of TX links (0..8)
109
    SLINK_TX_FIFO                : natural := 1;      -- TX fifo depth, has to be a power of two
110
    SLINK_RX_FIFO                : natural := 1;      -- RX fifo depth, has to be a power of two
111
 
112
    -- External Interrupts Controller (XIRQ) --
113
    XIRQ_NUM_CH                  : natural := 0;      -- number of external IRQ channels (0..32)
114 63 zero_gravi
    XIRQ_TRIGGER_TYPE            : std_ulogic_vector(31 downto 0) := x"ffffffff"; -- trigger type: 0=level, 1=edge
115
    XIRQ_TRIGGER_POLARITY        : std_ulogic_vector(31 downto 0) := x"ffffffff"; -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
116 61 zero_gravi
 
117 2 zero_gravi
    -- Processor peripherals --
118 62 zero_gravi
    IO_GPIO_EN                   : boolean := false;  -- implement general purpose input/output port unit (GPIO)?
119
    IO_MTIME_EN                  : boolean := false;  -- implement machine system timer (MTIME)?
120
    IO_UART0_EN                  : boolean := false;  -- implement primary universal asynchronous receiver/transmitter (UART0)?
121 65 zero_gravi
    IO_UART0_RX_FIFO             : natural := 1;      -- RX fifo depth, has to be a power of two, min 1
122
    IO_UART0_TX_FIFO             : natural := 1;      -- TX fifo depth, has to be a power of two, min 1
123 62 zero_gravi
    IO_UART1_EN                  : boolean := false;  -- implement secondary universal asynchronous receiver/transmitter (UART1)?
124 65 zero_gravi
    IO_UART1_RX_FIFO             : natural := 1;      -- RX fifo depth, has to be a power of two, min 1
125
    IO_UART1_TX_FIFO             : natural := 1;      -- TX fifo depth, has to be a power of two, min 1
126 62 zero_gravi
    IO_SPI_EN                    : boolean := false;  -- implement serial peripheral interface (SPI)?
127
    IO_TWI_EN                    : boolean := false;  -- implement two-wire interface (TWI)?
128
    IO_PWM_NUM_CH                : natural := 0;      -- number of PWM channels to implement (0..60); 0 = disabled
129
    IO_WDT_EN                    : boolean := false;  -- implement watch dog timer (WDT)?
130 44 zero_gravi
    IO_TRNG_EN                   : boolean := false;  -- implement true random number generator (TRNG)?
131 47 zero_gravi
    IO_CFS_EN                    : boolean := false;  -- implement custom functions subsystem (CFS)?
132 56 zero_gravi
    IO_CFS_CONFIG                : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic
133 52 zero_gravi
    IO_CFS_IN_SIZE               : positive := 32;    -- size of CFS input conduit in bits
134
    IO_CFS_OUT_SIZE              : positive := 32;    -- size of CFS output conduit in bits
135 62 zero_gravi
    IO_NEOLED_EN                 : boolean := false;  -- implement NeoPixel-compatible smart LED interface (NEOLED)?
136 67 zero_gravi
    IO_NEOLED_TX_FIFO            : natural := 1;      -- NEOLED TX FIFO depth, 1..32k, has to be a power of two
137
    IO_GPTMR_EN                  : boolean := false   -- implement general purpose timer (GPTMR)?
138 2 zero_gravi
  );
139
  port (
140
    -- Global control --
141 62 zero_gravi
    clk_i          : in  std_ulogic; -- global clock, rising edge
142
    rstn_i         : in  std_ulogic; -- global reset, low-active, async
143 50 zero_gravi
 
144 59 zero_gravi
    -- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --
145 62 zero_gravi
    jtag_trst_i    : in  std_ulogic := 'U'; -- low-active TAP reset (optional)
146
    jtag_tck_i     : in  std_ulogic := 'U'; -- serial clock
147
    jtag_tdi_i     : in  std_ulogic := 'U'; -- serial data input
148 61 zero_gravi
    jtag_tdo_o     : out std_ulogic;        -- serial data output
149 62 zero_gravi
    jtag_tms_i     : in  std_ulogic := 'U'; -- mode select
150 59 zero_gravi
 
151 44 zero_gravi
    -- Wishbone bus interface (available if MEM_EXT_EN = true) --
152 61 zero_gravi
    wb_tag_o       : out std_ulogic_vector(02 downto 0); -- request tag
153
    wb_adr_o       : out std_ulogic_vector(31 downto 0); -- address
154 62 zero_gravi
    wb_dat_i       : in  std_ulogic_vector(31 downto 0) := (others => 'U'); -- read data
155 61 zero_gravi
    wb_dat_o       : out std_ulogic_vector(31 downto 0); -- write data
156
    wb_we_o        : out std_ulogic; -- read/write
157
    wb_sel_o       : out std_ulogic_vector(03 downto 0); -- byte enable
158
    wb_stb_o       : out std_ulogic; -- strobe
159
    wb_cyc_o       : out std_ulogic; -- valid cycle
160
    wb_lock_o      : out std_ulogic; -- exclusive access request
161 62 zero_gravi
    wb_ack_i       : in  std_ulogic := 'L'; -- transfer acknowledge
162
    wb_err_i       : in  std_ulogic := 'L'; -- transfer error
163 50 zero_gravi
 
164 44 zero_gravi
    -- Advanced memory control signals (available if MEM_EXT_EN = true) --
165 61 zero_gravi
    fence_o        : out std_ulogic; -- indicates an executed FENCE operation
166
    fencei_o       : out std_ulogic; -- indicates an executed FENCEI operation
167 50 zero_gravi
 
168 61 zero_gravi
    -- TX stream interfaces (available if SLINK_NUM_TX > 0) --
169
    slink_tx_dat_o : out sdata_8x32_t; -- output data
170
    slink_tx_val_o : out std_ulogic_vector(7 downto 0); -- valid output
171 62 zero_gravi
    slink_tx_rdy_i : in  std_ulogic_vector(7 downto 0) := (others => 'L'); -- ready to send
172 61 zero_gravi
 
173
    -- RX stream interfaces (available if SLINK_NUM_RX > 0) --
174 62 zero_gravi
    slink_rx_dat_i : in  sdata_8x32_t := (others => (others => 'U')); -- input data
175
    slink_rx_val_i : in  std_ulogic_vector(7 downto 0) := (others => 'L'); -- valid input
176 61 zero_gravi
    slink_rx_rdy_o : out std_ulogic_vector(7 downto 0); -- ready to receive
177
 
178 44 zero_gravi
    -- GPIO (available if IO_GPIO_EN = true) --
179 61 zero_gravi
    gpio_o         : out std_ulogic_vector(63 downto 0); -- parallel output
180 62 zero_gravi
    gpio_i         : in  std_ulogic_vector(63 downto 0) := (others => 'U'); -- parallel input
181 50 zero_gravi
 
182
    -- primary UART0 (available if IO_UART0_EN = true) --
183 61 zero_gravi
    uart0_txd_o    : out std_ulogic; -- UART0 send data
184 62 zero_gravi
    uart0_rxd_i    : in  std_ulogic := 'U'; -- UART0 receive data
185 61 zero_gravi
    uart0_rts_o    : out std_ulogic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
186 62 zero_gravi
    uart0_cts_i    : in  std_ulogic := 'L'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional
187 50 zero_gravi
 
188
    -- secondary UART1 (available if IO_UART1_EN = true) --
189 61 zero_gravi
    uart1_txd_o    : out std_ulogic; -- UART1 send data
190 62 zero_gravi
    uart1_rxd_i    : in  std_ulogic := 'U'; -- UART1 receive data
191 61 zero_gravi
    uart1_rts_o    : out std_ulogic; -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional
192 62 zero_gravi
    uart1_cts_i    : in  std_ulogic := 'L'; -- hw flow control: UART1.TX allowed to transmit, low-active, optional
193 50 zero_gravi
 
194 44 zero_gravi
    -- SPI (available if IO_SPI_EN = true) --
195 61 zero_gravi
    spi_sck_o      : out std_ulogic; -- SPI serial clock
196
    spi_sdo_o      : out std_ulogic; -- controller data out, peripheral data in
197 62 zero_gravi
    spi_sdi_i      : in  std_ulogic := 'U'; -- controller data in, peripheral data out
198 61 zero_gravi
    spi_csn_o      : out std_ulogic_vector(07 downto 0); -- chip-select
199 50 zero_gravi
 
200 44 zero_gravi
    -- TWI (available if IO_TWI_EN = true) --
201 62 zero_gravi
    twi_sda_io     : inout std_logic := 'U'; -- twi serial data line
202
    twi_scl_io     : inout std_logic := 'U'; -- twi serial clock line
203 50 zero_gravi
 
204 60 zero_gravi
    -- PWM (available if IO_PWM_NUM_CH > 0) --
205 61 zero_gravi
    pwm_o          : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels
206 50 zero_gravi
 
207 47 zero_gravi
    -- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
208 62 zero_gravi
    cfs_in_i       : in  std_ulogic_vector(IO_CFS_IN_SIZE-1  downto 0) := (others => 'U'); -- custom CFS inputs conduit
209 61 zero_gravi
    cfs_out_o      : out std_ulogic_vector(IO_CFS_OUT_SIZE-1 downto 0); -- custom CFS outputs conduit
210 50 zero_gravi
 
211 52 zero_gravi
    -- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
212 61 zero_gravi
    neoled_o       : out std_ulogic; -- async serial data line
213 52 zero_gravi
 
214 59 zero_gravi
    -- System time --
215 62 zero_gravi
    mtime_i        : in  std_ulogic_vector(63 downto 0) := (others => 'U'); -- current system time from ext. MTIME (if IO_MTIME_EN = false)
216 61 zero_gravi
    mtime_o        : out std_ulogic_vector(63 downto 0); -- current system time from int. MTIME (if IO_MTIME_EN = true)
217 50 zero_gravi
 
218 61 zero_gravi
    -- External platform interrupts (available if XIRQ_NUM_CH > 0) --
219 62 zero_gravi
    xirq_i         : in  std_ulogic_vector(XIRQ_NUM_CH-1 downto 0) := (others => 'L'); -- IRQ channels
220 61 zero_gravi
 
221
    -- CPU interrupts --
222 62 zero_gravi
    mtime_irq_i    : in  std_ulogic := 'L'; -- machine timer interrupt, available if IO_MTIME_EN = false
223
    msw_irq_i      : in  std_ulogic := 'L'; -- machine software interrupt
224
    mext_irq_i     : in  std_ulogic := 'L'  -- machine external interrupt
225 2 zero_gravi
  );
226
end neorv32_top;
227
 
228
architecture neorv32_top_rtl of neorv32_top is
229
 
230 61 zero_gravi
  -- CPU boot configuration --
231
  constant cpu_boot_addr_c : std_ulogic_vector(31 downto 0) := cond_sel_stdulogicvector_f(INT_BOOTLOADER_EN, boot_rom_base_c, ispace_base_c);
232 12 zero_gravi
 
233 29 zero_gravi
  -- alignment check for internal memories --
234
  constant imem_align_check_c : std_ulogic_vector(index_size_f(MEM_INT_IMEM_SIZE)-1 downto 0) := (others => '0');
235
  constant dmem_align_check_c : std_ulogic_vector(index_size_f(MEM_INT_DMEM_SIZE)-1 downto 0) := (others => '0');
236
 
237 61 zero_gravi
  -- helpers --
238
  constant io_slink_en_c : boolean := boolean(SLINK_NUM_RX > 0) or boolean(SLINK_NUM_TX > 0); -- implement slink at all?
239
 
240 2 zero_gravi
  -- reset generator --
241 63 zero_gravi
  signal rstn_gen : std_ulogic_vector(7 downto 0) := (others => '0'); -- initialize (=reset) via  (for FPGAs only)
242 60 zero_gravi
  signal ext_rstn : std_ulogic;
243
  signal sys_rstn : std_ulogic;
244
  signal wdt_rstn : std_ulogic;
245 2 zero_gravi
 
246
  -- clock generator --
247
  signal clk_div    : std_ulogic_vector(11 downto 0);
248
  signal clk_div_ff : std_ulogic_vector(11 downto 0);
249
  signal clk_gen    : std_ulogic_vector(07 downto 0);
250 67 zero_gravi
  signal clk_gen_en : std_ulogic_vector(08 downto 0);
251 47 zero_gravi
  --
252 52 zero_gravi
  signal wdt_cg_en    : std_ulogic;
253
  signal uart0_cg_en  : std_ulogic;
254
  signal uart1_cg_en  : std_ulogic;
255
  signal spi_cg_en    : std_ulogic;
256
  signal twi_cg_en    : std_ulogic;
257
  signal pwm_cg_en    : std_ulogic;
258
  signal cfs_cg_en    : std_ulogic;
259
  signal neoled_cg_en : std_ulogic;
260 67 zero_gravi
  signal gptmr_cg_en  : std_ulogic;
261 2 zero_gravi
 
262 12 zero_gravi
  -- bus interface --
263
  type bus_interface_t is record
264 11 zero_gravi
    addr   : std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
265
    rdata  : std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
266
    wdata  : std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
267
    ben    : std_ulogic_vector(03 downto 0); -- byte enable
268
    we     : std_ulogic; -- write enable
269
    re     : std_ulogic; -- read enable
270
    ack    : std_ulogic; -- bus transfer acknowledge
271
    err    : std_ulogic; -- bus transfer error
272 12 zero_gravi
    fence  : std_ulogic; -- fence(i) instruction executed
273 35 zero_gravi
    priv   : std_ulogic_vector(1 downto 0); -- current privilege level
274 40 zero_gravi
    src    : std_ulogic; -- access source (1=instruction fetch, 0=data access)
275 57 zero_gravi
    lock   : std_ulogic; -- exclusive access request
276 11 zero_gravi
  end record;
277 41 zero_gravi
  signal cpu_i, i_cache, cpu_d, p_bus : bus_interface_t;
278 2 zero_gravi
 
279 68 zero_gravi
  -- bus access error (from BUSKEEPER) --
280
  signal bus_error : std_ulogic;
281
 
282 59 zero_gravi
  -- debug core interface (DCI) --
283
  signal dci_ndmrstn  : std_ulogic;
284
  signal dci_halt_req : std_ulogic;
285
 
286
  -- debug module interface (DMI) --
287
  type dmi_t is record
288
    rstn       : std_ulogic;
289
    req_valid  : std_ulogic;
290
    req_ready  : std_ulogic; -- DMI is allowed to make new requests when set
291
    req_addr   : std_ulogic_vector(06 downto 0);
292
    req_op     : std_ulogic; -- 0=read, 1=write
293
    req_data   : std_ulogic_vector(31 downto 0);
294
    resp_valid : std_ulogic; -- response valid when set
295
    resp_ready : std_ulogic; -- ready to receive respond
296
    resp_data  : std_ulogic_vector(31 downto 0);
297
    resp_err   : std_ulogic; -- 0=ok, 1=error
298
  end record;
299
  signal dmi : dmi_t;
300
 
301 2 zero_gravi
  -- io space access --
302
  signal io_acc  : std_ulogic;
303
  signal io_rden : std_ulogic;
304
  signal io_wren : std_ulogic;
305
 
306 60 zero_gravi
  -- module response bus - entry type --
307
  type resp_bus_entry_t is record
308
    rdata : std_ulogic_vector(data_width_c-1 downto 0);
309
    ack   : std_ulogic;
310
    err   : std_ulogic;
311
  end record;
312
  constant resp_bus_entry_terminate_c : resp_bus_entry_t := (rdata => (others => '0'), ack => '0', err => '0');
313 2 zero_gravi
 
314 60 zero_gravi
  -- module response bus - device ID --
315 66 zero_gravi
  type resp_bus_id_t is (RESP_BUSKEEPER, RESP_IMEM, RESP_DMEM, RESP_BOOTROM, RESP_WISHBONE, RESP_GPIO, RESP_MTIME, RESP_UART0, RESP_UART1, RESP_SPI,
316 67 zero_gravi
                         RESP_TWI, RESP_PWM, RESP_WDT, RESP_TRNG, RESP_CFS, RESP_NEOLED, RESP_SYSINFO, RESP_OCD, RESP_SLINK, RESP_XIRQ, RESP_GPTMR);
317 60 zero_gravi
 
318
  -- module response bus --
319
  type resp_bus_t is array (resp_bus_id_t) of resp_bus_entry_t;
320
  signal resp_bus : resp_bus_t := (others => resp_bus_entry_terminate_c);
321
 
322 2 zero_gravi
  -- IRQs --
323 59 zero_gravi
  signal fast_irq      : std_ulogic_vector(15 downto 0);
324 60 zero_gravi
  signal mtime_irq     : std_ulogic;
325 50 zero_gravi
  signal wdt_irq       : std_ulogic;
326
  signal uart0_rxd_irq : std_ulogic;
327
  signal uart0_txd_irq : std_ulogic;
328
  signal uart1_rxd_irq : std_ulogic;
329
  signal uart1_txd_irq : std_ulogic;
330
  signal spi_irq       : std_ulogic;
331
  signal twi_irq       : std_ulogic;
332
  signal cfs_irq       : std_ulogic;
333 52 zero_gravi
  signal neoled_irq    : std_ulogic;
334 61 zero_gravi
  signal slink_tx_irq  : std_ulogic;
335
  signal slink_rx_irq  : std_ulogic;
336
  signal xirq_irq      : std_ulogic;
337 67 zero_gravi
  signal gptmr_irq     : std_ulogic;
338 2 zero_gravi
 
339 11 zero_gravi
  -- misc --
340 68 zero_gravi
  signal mtime_time  : std_ulogic_vector(63 downto 0); -- current system time from MTIME
341
  signal ext_timeout : std_ulogic;
342
  signal ext_access  : std_ulogic;
343 11 zero_gravi
 
344 2 zero_gravi
begin
345
 
346 61 zero_gravi
  -- Processor IO/Peripherals Configuration -------------------------------------------------
347
  -- -------------------------------------------------------------------------------------------
348
  assert false report
349
  "NEORV32 PROCESSOR IO Configuration: " &
350
  cond_sel_string_f(IO_GPIO_EN, "GPIO ", "") &
351
  cond_sel_string_f(IO_MTIME_EN, "MTIME ", "") &
352
  cond_sel_string_f(IO_UART0_EN, "UART0 ", "") &
353
  cond_sel_string_f(IO_UART1_EN, "UART1 ", "") &
354
  cond_sel_string_f(IO_SPI_EN, "SPI ", "") &
355
  cond_sel_string_f(IO_TWI_EN, "TWI ", "") &
356
  cond_sel_string_f(boolean(IO_PWM_NUM_CH > 0), "PWM ", "") &
357
  cond_sel_string_f(IO_WDT_EN, "WDT ", "") &
358
  cond_sel_string_f(IO_TRNG_EN, "TRNG ", "") &
359
  cond_sel_string_f(IO_CFS_EN, "CFS ", "") &
360
  cond_sel_string_f(io_slink_en_c, "SLINK ", "") &
361
  cond_sel_string_f(IO_NEOLED_EN, "NEOLED ", "") &
362
  cond_sel_string_f(boolean(XIRQ_NUM_CH > 0), "XIRQ ", "") &
363 67 zero_gravi
  cond_sel_string_f(IO_GPTMR_EN, "GPTMR ", "") &
364 61 zero_gravi
  ""
365
  severity note;
366
 
367
 
368 2 zero_gravi
  -- Sanity Checks --------------------------------------------------------------------------
369
  -- -------------------------------------------------------------------------------------------
370 61 zero_gravi
  -- boot configuration --
371
  assert not (INT_BOOTLOADER_EN = true) report "NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Indirect boot via bootloader (processor-internal BOOTROM)." severity note;
372
  assert not ((INT_BOOTLOADER_EN = false) and (MEM_INT_IMEM_EN = true)) report "NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Direct boot from memory (processor-internal IMEM)." severity note;
373
  assert not ((INT_BOOTLOADER_EN = false) and (MEM_INT_IMEM_EN = false)) report "NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Direct boot from memory (processor-external (I)MEM)." severity note;
374
  --
375
  assert not ((MEM_EXT_EN = false) and (MEM_INT_DMEM_EN = false)) report "NEORV32 PROCESSOR CONFIG ERROR! Core cannot fetch data without external memory interface and internal IMEM." severity error;
376
  assert not ((MEM_EXT_EN = false) and (MEM_INT_IMEM_EN = false) and (INT_BOOTLOADER_EN = false)) report "NEORV32 PROCESSOR CONFIG ERROR! Core cannot fetch instructions without external memory interface, internal IMEM and bootloader." severity error;
377
 
378 36 zero_gravi
  -- memory system - size --
379 44 zero_gravi
  assert not ((MEM_INT_DMEM_EN = true) and (is_power_of_two_f(MEM_INT_IMEM_SIZE) = false)) report "NEORV32 PROCESSOR CONFIG WARNING! MEM_INT_IMEM_SIZE should be a power of 2 to allow optimal hardware mapping." severity warning;
380
  assert not ((MEM_INT_IMEM_EN = true) and (is_power_of_two_f(MEM_INT_DMEM_SIZE) = false)) report "NEORV32 PROCESSOR CONFIG WARNING! MEM_INT_DMEM_SIZE should be a power of 2 to allow optimal hardware mapping." severity warning;
381 61 zero_gravi
 
382 29 zero_gravi
  -- memory system - alignment --
383
  assert not (ispace_base_c(1 downto 0) /= "00") report "NEORV32 PROCESSOR CONFIG ERROR! Instruction memory space base address must be 4-byte-aligned." severity error;
384
  assert not (dspace_base_c(1 downto 0) /= "00") report "NEORV32 PROCESSOR CONFIG ERROR! Data memory space base address must be 4-byte-aligned." severity error;
385 44 zero_gravi
  assert not ((ispace_base_c(index_size_f(MEM_INT_IMEM_SIZE)-1 downto 0) /= imem_align_check_c) and (MEM_INT_IMEM_EN = true)) report "NEORV32 PROCESSOR CONFIG ERROR! Instruction memory space base address has to be aligned to IMEM size." severity error;
386
  assert not ((dspace_base_c(index_size_f(MEM_INT_DMEM_SIZE)-1 downto 0) /= dmem_align_check_c) and (MEM_INT_DMEM_EN = true)) report "NEORV32 PROCESSOR CONFIG ERROR! Data memory space base address has to be aligned to DMEM size." severity error;
387 61 zero_gravi
 
388 36 zero_gravi
  -- memory system - layout warning --
389 29 zero_gravi
  assert not (ispace_base_c /= x"00000000") report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for instruction address space. Make sure this is sync with the software framework." severity warning;
390
  assert not (dspace_base_c /= x"80000000") report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for data address space. Make sure this is sync with the software framework." severity warning;
391 61 zero_gravi
 
392 41 zero_gravi
  -- memory system - the i-cache is intended to accelerate instruction fetch via the external memory interface only --
393 44 zero_gravi
  assert not ((ICACHE_EN = true) and (MEM_EXT_EN = false)) report "NEORV32 PROCESSOR CONFIG NOTE. Implementing i-cache without having the external memory interface implemented. The i-cache is intended to accelerate instruction fetch via the external memory interface." severity note;
394 61 zero_gravi
 
395 59 zero_gravi
  -- on-chip debugger --
396 61 zero_gravi
  assert not (ON_CHIP_DEBUGGER_EN = true) report "NEORV32 PROCESSOR CONFIG NOTE: Implementing on-chip debugger (OCD)." severity note;
397 2 zero_gravi
 
398 59 zero_gravi
 
399 2 zero_gravi
  -- Reset Generator ------------------------------------------------------------------------
400
  -- -------------------------------------------------------------------------------------------
401 60 zero_gravi
  reset_generator: process(rstn_i, clk_i)
402 2 zero_gravi
  begin
403 60 zero_gravi
    if (rstn_i = '0') then
404 2 zero_gravi
      rstn_gen <= (others => '0');
405 60 zero_gravi
      sys_rstn <= '0';
406 2 zero_gravi
    elsif rising_edge(clk_i) then
407 60 zero_gravi
      -- keep internal reset active for at least <rstn_gen'size> clock cycles --
408 2 zero_gravi
      rstn_gen <= rstn_gen(rstn_gen'left-1 downto 0) & '1';
409 60 zero_gravi
      -- system reset: can also be triggered by watchdog and debug module --
410
      sys_rstn <= ext_rstn and wdt_rstn and dci_ndmrstn;
411 2 zero_gravi
    end if;
412
  end process reset_generator;
413
 
414 60 zero_gravi
  -- beautified external reset signal --
415
  ext_rstn <= rstn_gen(rstn_gen'left);
416 2 zero_gravi
 
417
 
418
  -- Clock Generator ------------------------------------------------------------------------
419
  -- -------------------------------------------------------------------------------------------
420
  clock_generator: process(sys_rstn, clk_i)
421
  begin
422
    if (sys_rstn = '0') then
423 60 zero_gravi
      clk_gen_en <= (others => '-');
424 2 zero_gravi
      clk_div    <= (others => '0');
425 60 zero_gravi
      clk_div_ff <= (others => '-');
426
      clk_gen    <= (others => '-');
427 2 zero_gravi
    elsif rising_edge(clk_i) then
428 23 zero_gravi
      -- fresh clocks anyone? --
429 50 zero_gravi
      clk_gen_en(0) <= wdt_cg_en;
430
      clk_gen_en(1) <= uart0_cg_en;
431
      clk_gen_en(2) <= uart1_cg_en;
432
      clk_gen_en(3) <= spi_cg_en;
433
      clk_gen_en(4) <= twi_cg_en;
434
      clk_gen_en(5) <= pwm_cg_en;
435
      clk_gen_en(6) <= cfs_cg_en;
436 61 zero_gravi
      clk_gen_en(7) <= neoled_cg_en;
437 67 zero_gravi
      clk_gen_en(8) <= gptmr_cg_en;
438 60 zero_gravi
      -- actual clock generator --
439
      if (or_reduce_f(clk_gen_en) = '1') then
440 23 zero_gravi
        clk_div <= std_ulogic_vector(unsigned(clk_div) + 1);
441 2 zero_gravi
      end if;
442 60 zero_gravi
      -- clock enables: rising edge detectors --
443 23 zero_gravi
      clk_div_ff <= clk_div;
444
      clk_gen(clk_div2_c)    <= clk_div(0)  and (not clk_div_ff(0));  -- CLK/2
445
      clk_gen(clk_div4_c)    <= clk_div(1)  and (not clk_div_ff(1));  -- CLK/4
446
      clk_gen(clk_div8_c)    <= clk_div(2)  and (not clk_div_ff(2));  -- CLK/8
447
      clk_gen(clk_div64_c)   <= clk_div(5)  and (not clk_div_ff(5));  -- CLK/64
448
      clk_gen(clk_div128_c)  <= clk_div(6)  and (not clk_div_ff(6));  -- CLK/128
449
      clk_gen(clk_div1024_c) <= clk_div(9)  and (not clk_div_ff(9));  -- CLK/1024
450
      clk_gen(clk_div2048_c) <= clk_div(10) and (not clk_div_ff(10)); -- CLK/2048
451
      clk_gen(clk_div4096_c) <= clk_div(11) and (not clk_div_ff(11)); -- CLK/4096
452
    end if;
453 60 zero_gravi
  end process clock_generator;
454 2 zero_gravi
 
455
 
456 45 zero_gravi
  -- CPU Core -------------------------------------------------------------------------------
457 2 zero_gravi
  -- -------------------------------------------------------------------------------------------
458
  neorv32_cpu_inst: neorv32_cpu
459
  generic map (
460
    -- General --
461 41 zero_gravi
    HW_THREAD_ID                 => HW_THREAD_ID,        -- hardware thread id
462
    CPU_BOOT_ADDR                => cpu_boot_addr_c,     -- cpu boot address
463 59 zero_gravi
    CPU_DEBUG_ADDR               => dm_base_c,           -- cpu debug mode start address
464 2 zero_gravi
    -- RISC-V CPU Extensions --
465 39 zero_gravi
    CPU_EXTENSION_RISCV_A        => CPU_EXTENSION_RISCV_A,        -- implement atomic extension?
466 66 zero_gravi
    CPU_EXTENSION_RISCV_B        => CPU_EXTENSION_RISCV_B,        -- implement bit-manipulation extension?
467 8 zero_gravi
    CPU_EXTENSION_RISCV_C        => CPU_EXTENSION_RISCV_C,        -- implement compressed extension?
468
    CPU_EXTENSION_RISCV_E        => CPU_EXTENSION_RISCV_E,        -- implement embedded RF extension?
469
    CPU_EXTENSION_RISCV_M        => CPU_EXTENSION_RISCV_M,        -- implement muld/div extension?
470 15 zero_gravi
    CPU_EXTENSION_RISCV_U        => CPU_EXTENSION_RISCV_U,        -- implement user mode extension?
471 55 zero_gravi
    CPU_EXTENSION_RISCV_Zfinx    => CPU_EXTENSION_RISCV_Zfinx,    -- implement 32-bit floating-point extension (using INT reg!)
472 8 zero_gravi
    CPU_EXTENSION_RISCV_Zicsr    => CPU_EXTENSION_RISCV_Zicsr,    -- implement CSR system?
473 66 zero_gravi
    CPU_EXTENSION_RISCV_Zicntr   => CPU_EXTENSION_RISCV_Zicntr,   -- implement base counters?
474
    CPU_EXTENSION_RISCV_Zihpm    => CPU_EXTENSION_RISCV_Zihpm,    -- implement hardware performance monitors?
475 8 zero_gravi
    CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
476 61 zero_gravi
    CPU_EXTENSION_RISCV_Zmmul    => CPU_EXTENSION_RISCV_Zmmul,    -- implement multiply-only M sub-extension?
477 59 zero_gravi
    CPU_EXTENSION_RISCV_DEBUG    => ON_CHIP_DEBUGGER_EN,          -- implement CPU debug mode?
478 19 zero_gravi
    -- Extension Options --
479 41 zero_gravi
    FAST_MUL_EN                  => FAST_MUL_EN,         -- use DSPs for M extension's multiplier
480
    FAST_SHIFT_EN                => FAST_SHIFT_EN,       -- use barrel shifter for shift operations
481 56 zero_gravi
    CPU_CNT_WIDTH                => CPU_CNT_WIDTH,       -- total width of CPU cycle and instret counters (0..64)
482 62 zero_gravi
    CPU_IPB_ENTRIES              => CPU_IPB_ENTRIES,     -- entries is instruction prefetch buffer, has to be a power of 2
483 15 zero_gravi
    -- Physical Memory Protection (PMP) --
484 42 zero_gravi
    PMP_NUM_REGIONS              => PMP_NUM_REGIONS,     -- number of regions (0..64)
485
    PMP_MIN_GRANULARITY          => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
486
    -- Hardware Performance Monitors (HPM) --
487 56 zero_gravi
    HPM_NUM_CNTS                 => HPM_NUM_CNTS,        -- number of implemented HPM counters (0..29)
488 60 zero_gravi
    HPM_CNT_WIDTH                => HPM_CNT_WIDTH        -- total size of HPM counters (0..64)
489 2 zero_gravi
  )
490
  port map (
491
    -- global control --
492 12 zero_gravi
    clk_i          => clk_i,        -- global clock, rising edge
493
    rstn_i         => sys_rstn,     -- global reset, low-active, async
494 65 zero_gravi
    sleep_o        => open,         -- cpu is in sleep mode when set
495 12 zero_gravi
    -- instruction bus interface --
496
    i_bus_addr_o   => cpu_i.addr,   -- bus access address
497
    i_bus_rdata_i  => cpu_i.rdata,  -- bus read data
498
    i_bus_wdata_o  => cpu_i.wdata,  -- bus write data
499
    i_bus_ben_o    => cpu_i.ben,    -- byte enable
500
    i_bus_we_o     => cpu_i.we,     -- write enable
501
    i_bus_re_o     => cpu_i.re,     -- read enable
502 57 zero_gravi
    i_bus_lock_o   => cpu_i.lock,   -- exclusive access request
503 12 zero_gravi
    i_bus_ack_i    => cpu_i.ack,    -- bus transfer acknowledge
504
    i_bus_err_i    => cpu_i.err,    -- bus transfer error
505
    i_bus_fence_o  => cpu_i.fence,  -- executed FENCEI operation
506 35 zero_gravi
    i_bus_priv_o   => cpu_i.priv,   -- privilege level
507 12 zero_gravi
    -- data bus interface --
508
    d_bus_addr_o   => cpu_d.addr,   -- bus access address
509
    d_bus_rdata_i  => cpu_d.rdata,  -- bus read data
510
    d_bus_wdata_o  => cpu_d.wdata,  -- bus write data
511
    d_bus_ben_o    => cpu_d.ben,    -- byte enable
512
    d_bus_we_o     => cpu_d.we,     -- write enable
513
    d_bus_re_o     => cpu_d.re,     -- read enable
514 57 zero_gravi
    d_bus_lock_o   => cpu_d.lock,   -- exclusive access request
515 12 zero_gravi
    d_bus_ack_i    => cpu_d.ack,    -- bus transfer acknowledge
516
    d_bus_err_i    => cpu_d.err,    -- bus transfer error
517
    d_bus_fence_o  => cpu_d.fence,  -- executed FENCE operation
518 35 zero_gravi
    d_bus_priv_o   => cpu_d.priv,   -- privilege level
519 11 zero_gravi
    -- system time input from MTIME --
520 12 zero_gravi
    time_i         => mtime_time,   -- current system time
521 58 zero_gravi
    -- non-maskable interrupt --
522 64 zero_gravi
    msw_irq_i      => msw_irq_i,    -- machine software interrupt
523
    mext_irq_i     => mext_irq_i,   -- machine external interrupt request
524 14 zero_gravi
    mtime_irq_i    => mtime_irq,    -- machine timer interrupt
525
    -- fast interrupts (custom) --
526 47 zero_gravi
    firq_i         => fast_irq,     -- fast interrupt trigger
527 59 zero_gravi
    -- debug mode (halt) request --
528
    db_halt_req_i  => dci_halt_req
529 2 zero_gravi
  );
530
 
531 36 zero_gravi
  -- misc --
532 57 zero_gravi
  cpu_i.src <= '1'; -- initialized but unused
533
  cpu_d.src <= '0'; -- initialized but unused
534 36 zero_gravi
 
535 14 zero_gravi
  -- advanced memory control --
536
  fence_o  <= cpu_d.fence; -- indicates an executed FENCE operation
537
  fencei_o <= cpu_i.fence; -- indicates an executed FENCEI operation
538 2 zero_gravi
 
539 68 zero_gravi
  -- fast interrupt requests (FIRQs) --
540
  -- these stay asserted until explicitly acknowledged --
541
  fast_irq(00) <= wdt_irq;       -- HIGHEST PRIORITY - watchdog
542 50 zero_gravi
  fast_irq(01) <= cfs_irq;       -- custom functions subsystem
543 68 zero_gravi
  fast_irq(02) <= uart0_rxd_irq; -- primary UART (UART0) RX
544
  fast_irq(03) <= uart0_txd_irq; -- primary UART (UART0) TX
545
  fast_irq(04) <= uart1_rxd_irq; -- secondary UART (UART1) RX
546
  fast_irq(05) <= uart1_txd_irq; -- secondary UART (UART1) TX
547
  fast_irq(06) <= spi_irq;       -- SPI
548
  fast_irq(07) <= twi_irq;       -- TWI
549 61 zero_gravi
  fast_irq(08) <= xirq_irq;      -- external interrupt controller
550 52 zero_gravi
  fast_irq(09) <= neoled_irq;    -- NEOLED buffer free
551 68 zero_gravi
  fast_irq(10) <= slink_rx_irq;  -- SLINK RX
552
  fast_irq(11) <= slink_tx_irq;  -- SLINK TX
553 67 zero_gravi
  fast_irq(12) <= gptmr_irq;     -- general purpose timer
554 61 zero_gravi
  --
555 62 zero_gravi
  fast_irq(13) <= '0'; -- reserved
556
  fast_irq(14) <= '0'; -- reserved
557 66 zero_gravi
  fast_irq(15) <= '0'; -- LOWEST PRIORITY - reserved
558 14 zero_gravi
 
559
 
560 41 zero_gravi
  -- CPU Instruction Cache ------------------------------------------------------------------
561
  -- -------------------------------------------------------------------------------------------
562
  neorv32_icache_inst_true:
563 44 zero_gravi
  if (ICACHE_EN = true) generate
564 45 zero_gravi
    neorv32_icache_inst: neorv32_icache
565 41 zero_gravi
    generic map (
566 47 zero_gravi
      ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS,   -- number of blocks (min 2), has to be a power of 2
567
      ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE,   -- block size in bytes (min 4), has to be a power of 2
568
      ICACHE_NUM_SETS   => ICACHE_ASSOCIATIVITY -- associativity / number of sets (1=direct_mapped), has to be a power of 2
569 41 zero_gravi
    )
570
    port map (
571
      -- global control --
572
      clk_i         => clk_i,          -- global clock, rising edge
573
      rstn_i        => sys_rstn,       -- global reset, low-active, async
574
      clear_i       => cpu_i.fence,    -- cache clear
575
      -- host controller interface --
576
      host_addr_i   => cpu_i.addr,     -- bus access address
577
      host_rdata_o  => cpu_i.rdata,    -- bus read data
578
      host_wdata_i  => cpu_i.wdata,    -- bus write data
579
      host_ben_i    => cpu_i.ben,      -- byte enable
580
      host_we_i     => cpu_i.we,       -- write enable
581
      host_re_i     => cpu_i.re,       -- read enable
582
      host_ack_o    => cpu_i.ack,      -- bus transfer acknowledge
583
      host_err_o    => cpu_i.err,      -- bus transfer error
584
      -- peripheral bus interface --
585
      bus_addr_o    => i_cache.addr,   -- bus access address
586
      bus_rdata_i   => i_cache.rdata,  -- bus read data
587
      bus_wdata_o   => i_cache.wdata,  -- bus write data
588
      bus_ben_o     => i_cache.ben,    -- byte enable
589
      bus_we_o      => i_cache.we,     -- write enable
590
      bus_re_o      => i_cache.re,     -- read enable
591
      bus_ack_i     => i_cache.ack,    -- bus transfer acknowledge
592
      bus_err_i     => i_cache.err     -- bus transfer error
593
    );
594
  end generate;
595
 
596 57 zero_gravi
  -- TODO: do not use LOCKED instruction fetch --
597
  i_cache.lock <= '0';
598
 
599 41 zero_gravi
  neorv32_icache_inst_false:
600 44 zero_gravi
  if (ICACHE_EN = false) generate
601 57 zero_gravi
    i_cache.addr  <= cpu_i.addr;
602
    cpu_i.rdata   <= i_cache.rdata;
603
    i_cache.wdata <= cpu_i.wdata;
604
    i_cache.ben   <= cpu_i.ben;
605
    i_cache.we    <= cpu_i.we;
606
    i_cache.re    <= cpu_i.re;
607
    cpu_i.ack     <= i_cache.ack;
608
    cpu_i.err     <= i_cache.err;
609 41 zero_gravi
  end generate;
610
 
611
 
612 45 zero_gravi
  -- CPU Bus Switch -------------------------------------------------------------------------
613 12 zero_gravi
  -- -------------------------------------------------------------------------------------------
614
  neorv32_busswitch_inst: neorv32_busswitch
615
  generic map (
616
    PORT_CA_READ_ONLY => false, -- set if controller port A is read-only
617
    PORT_CB_READ_ONLY => true   -- set if controller port B is read-only
618
  )
619
  port map (
620
    -- global control --
621 41 zero_gravi
    clk_i           => clk_i,          -- global clock, rising edge
622
    rstn_i          => sys_rstn,       -- global reset, low-active, async
623 12 zero_gravi
    -- controller interface a --
624 41 zero_gravi
    ca_bus_addr_i   => cpu_d.addr,     -- bus access address
625
    ca_bus_rdata_o  => cpu_d.rdata,    -- bus read data
626
    ca_bus_wdata_i  => cpu_d.wdata,    -- bus write data
627
    ca_bus_ben_i    => cpu_d.ben,      -- byte enable
628
    ca_bus_we_i     => cpu_d.we,       -- write enable
629
    ca_bus_re_i     => cpu_d.re,       -- read enable
630 57 zero_gravi
    ca_bus_lock_i   => cpu_d.lock,     -- exclusive access request
631 41 zero_gravi
    ca_bus_ack_o    => cpu_d.ack,      -- bus transfer acknowledge
632
    ca_bus_err_o    => cpu_d.err,      -- bus transfer error
633 12 zero_gravi
    -- controller interface b --
634 41 zero_gravi
    cb_bus_addr_i   => i_cache.addr,   -- bus access address
635
    cb_bus_rdata_o  => i_cache.rdata,  -- bus read data
636
    cb_bus_wdata_i  => i_cache.wdata,  -- bus write data
637
    cb_bus_ben_i    => i_cache.ben,    -- byte enable
638
    cb_bus_we_i     => i_cache.we,     -- write enable
639
    cb_bus_re_i     => i_cache.re,     -- read enable
640 57 zero_gravi
    cb_bus_lock_i   => i_cache.lock,   -- exclusive access request
641 41 zero_gravi
    cb_bus_ack_o    => i_cache.ack,    -- bus transfer acknowledge
642
    cb_bus_err_o    => i_cache.err,    -- bus transfer error
643 12 zero_gravi
    -- peripheral bus --
644 41 zero_gravi
    p_bus_src_o     => p_bus.src,      -- access source: 0 = A (data), 1 = B (instructions)
645
    p_bus_addr_o    => p_bus.addr,     -- bus access address
646
    p_bus_rdata_i   => p_bus.rdata,    -- bus read data
647
    p_bus_wdata_o   => p_bus.wdata,    -- bus write data
648
    p_bus_ben_o     => p_bus.ben,      -- byte enable
649
    p_bus_we_o      => p_bus.we,       -- write enable
650
    p_bus_re_o      => p_bus.re,       -- read enable
651 57 zero_gravi
    p_bus_lock_o    => p_bus.lock,     -- exclusive access request
652 41 zero_gravi
    p_bus_ack_i     => p_bus.ack,      -- bus transfer acknowledge
653 68 zero_gravi
    p_bus_err_i     => bus_error       -- bus transfer error
654 12 zero_gravi
  );
655 2 zero_gravi
 
656 60 zero_gravi
  -- current CPU privilege level --
657
  p_bus.priv <= cpu_i.priv; -- note: cpu_i.priv == cpu_d.priv
658 53 zero_gravi
 
659 60 zero_gravi
  -- fence operation (unused) --
660
  p_bus.fence <= cpu_d.fence or cpu_i.fence;
661 2 zero_gravi
 
662 60 zero_gravi
  -- bus response --
663 66 zero_gravi
  bus_response: process(resp_bus)
664 60 zero_gravi
    variable rdata_v : std_ulogic_vector(data_width_c-1 downto 0);
665
    variable ack_v   : std_ulogic;
666
    variable err_v   : std_ulogic;
667
  begin
668
    rdata_v := (others => '0');
669
    ack_v   := '0';
670
    err_v   := '0';
671
    for i in resp_bus'range loop
672
      rdata_v := rdata_v or resp_bus(i).rdata; -- read data
673
      ack_v   := ack_v   or resp_bus(i).ack;   -- acknowledge
674
      err_v   := err_v   or resp_bus(i).err;   -- error
675
    end loop; -- i
676
    p_bus.rdata <= rdata_v; -- processor bus: CPU transfer data input
677
    p_bus.ack   <= ack_v;   -- processor bus: CPU transfer ACK input
678 66 zero_gravi
    p_bus.err   <= err_v;   -- processor bus: CPU transfer data bus error input
679 60 zero_gravi
  end process;
680 12 zero_gravi
 
681
 
682 66 zero_gravi
  -- Bus Keeper (BUSKEEPER) -----------------------------------------------------------------
683 57 zero_gravi
  -- -------------------------------------------------------------------------------------------
684
  neorv32_bus_keeper_inst: neorv32_bus_keeper
685
  port map (
686
    -- host access --
687 66 zero_gravi
    clk_i      => clk_i,                          -- global clock line
688
    rstn_i     => sys_rstn,                       -- global reset line, low-active, use as async
689
    addr_i     => p_bus.addr,                     -- address
690
    rden_i     => io_rden,                        -- read enable
691
    wren_i     => io_wren,                        -- byte write enable
692
    data_o     => resp_bus(RESP_BUSKEEPER).rdata, -- data out
693
    ack_o      => resp_bus(RESP_BUSKEEPER).ack,   -- transfer acknowledge
694 68 zero_gravi
    err_o      => bus_error,                      -- transfer error
695 66 zero_gravi
    -- bus monitoring --
696
    bus_addr_i => p_bus.addr,                     -- address
697
    bus_rden_i => p_bus.re,                       -- read enable
698
    bus_wren_i => p_bus.we,                       -- write enable
699
    bus_ack_i  => p_bus.ack,                      -- transfer acknowledge from bus system
700 68 zero_gravi
    bus_err_i  => p_bus.err,                      -- transfer error from bus system
701
    bus_tmo_i  => ext_timeout,                    -- transfer timeout (external interface)
702
    bus_ext_i  => ext_access                      -- external bus access
703 57 zero_gravi
  );
704 36 zero_gravi
 
705 68 zero_gravi
  -- unused, BUSKEEPER **directly** issues error to the CPU --
706
  resp_bus(RESP_BUSKEEPER).err <= '0';
707 57 zero_gravi
 
708 68 zero_gravi
 
709 2 zero_gravi
  -- Processor-Internal Instruction Memory (IMEM) -------------------------------------------
710
  -- -------------------------------------------------------------------------------------------
711
  neorv32_int_imem_inst_true:
712 68 zero_gravi
  if (MEM_INT_IMEM_EN = true) and (MEM_INT_IMEM_SIZE > 0) generate
713 2 zero_gravi
    neorv32_int_imem_inst: neorv32_imem
714
    generic map (
715 61 zero_gravi
      IMEM_BASE    => imem_base_c,          -- memory base address
716
      IMEM_SIZE    => MEM_INT_IMEM_SIZE,    -- processor-internal instruction memory size in bytes
717
      IMEM_AS_IROM => not INT_BOOTLOADER_EN -- implement IMEM as pre-initialized read-only memory?
718 2 zero_gravi
    )
719
    port map (
720 60 zero_gravi
      clk_i  => clk_i,                     -- global clock line
721
      rden_i => p_bus.re,                  -- read enable
722
      wren_i => p_bus.we,                  -- write enable
723
      ben_i  => p_bus.ben,                 -- byte write enable
724
      addr_i => p_bus.addr,                -- address
725
      data_i => p_bus.wdata,               -- data in
726
      data_o => resp_bus(RESP_IMEM).rdata, -- data out
727
      ack_o  => resp_bus(RESP_IMEM).ack    -- transfer acknowledge
728 2 zero_gravi
    );
729 60 zero_gravi
    resp_bus(RESP_IMEM).err <= '0'; -- no access error possible
730 2 zero_gravi
  end generate;
731
 
732
  neorv32_int_imem_inst_false:
733 68 zero_gravi
  if (MEM_INT_IMEM_EN = false) or (MEM_INT_IMEM_SIZE = 0) generate
734 60 zero_gravi
    resp_bus(RESP_IMEM) <= resp_bus_entry_terminate_c;
735 2 zero_gravi
  end generate;
736
 
737
 
738
  -- Processor-Internal Data Memory (DMEM) --------------------------------------------------
739
  -- -------------------------------------------------------------------------------------------
740
  neorv32_int_dmem_inst_true:
741 68 zero_gravi
  if (MEM_INT_DMEM_EN = true) and (MEM_INT_DMEM_SIZE > 0) generate
742 2 zero_gravi
    neorv32_int_dmem_inst: neorv32_dmem
743
    generic map (
744 23 zero_gravi
      DMEM_BASE => dmem_base_c,      -- memory base address
745 2 zero_gravi
      DMEM_SIZE => MEM_INT_DMEM_SIZE -- processor-internal data memory size in bytes
746
    )
747
    port map (
748 60 zero_gravi
      clk_i  => clk_i,                     -- global clock line
749
      rden_i => p_bus.re,                  -- read enable
750
      wren_i => p_bus.we,                  -- write enable
751
      ben_i  => p_bus.ben,                 -- byte write enable
752
      addr_i => p_bus.addr,                -- address
753
      data_i => p_bus.wdata,               -- data in
754
      data_o => resp_bus(RESP_DMEM).rdata, -- data out
755
      ack_o  => resp_bus(RESP_DMEM).ack    -- transfer acknowledge
756 2 zero_gravi
    );
757 60 zero_gravi
    resp_bus(RESP_DMEM).err <= '0'; -- no access error possible
758 2 zero_gravi
  end generate;
759
 
760
  neorv32_int_dmem_inst_false:
761 68 zero_gravi
  if (MEM_INT_DMEM_EN = false) or (MEM_INT_DMEM_SIZE = 0) generate
762 60 zero_gravi
    resp_bus(RESP_DMEM) <= resp_bus_entry_terminate_c;
763 2 zero_gravi
  end generate;
764
 
765
 
766
  -- Processor-Internal Bootloader ROM (BOOTROM) --------------------------------------------
767
  -- -------------------------------------------------------------------------------------------
768
  neorv32_boot_rom_inst_true:
769 61 zero_gravi
  if (INT_BOOTLOADER_EN = true) generate
770 2 zero_gravi
    neorv32_boot_rom_inst: neorv32_boot_rom
771 23 zero_gravi
    generic map (
772 61 zero_gravi
      BOOTROM_BASE => boot_rom_base_c -- boot ROM base address
773 23 zero_gravi
    )
774 2 zero_gravi
    port map (
775 60 zero_gravi
      clk_i  => clk_i,                        -- global clock line
776
      rden_i => p_bus.re,                     -- read enable
777
      addr_i => p_bus.addr,                   -- address
778
      data_o => resp_bus(RESP_BOOTROM).rdata, -- data out
779
      ack_o  => resp_bus(RESP_BOOTROM).ack    -- transfer acknowledge
780 2 zero_gravi
    );
781 60 zero_gravi
    resp_bus(RESP_BOOTROM).err <= '0'; -- no access error possible
782 2 zero_gravi
  end generate;
783
 
784
  neorv32_boot_rom_inst_false:
785 61 zero_gravi
  if (INT_BOOTLOADER_EN = false) generate
786 60 zero_gravi
    resp_bus(RESP_BOOTROM) <= resp_bus_entry_terminate_c;
787 2 zero_gravi
  end generate;
788
 
789
 
790
  -- External Wishbone Gateway (WISHBONE) ---------------------------------------------------
791
  -- -------------------------------------------------------------------------------------------
792
  neorv32_wishbone_inst_true:
793 44 zero_gravi
  if (MEM_EXT_EN = true) generate
794 2 zero_gravi
    neorv32_wishbone_inst: neorv32_wishbone
795
    generic map (
796 23 zero_gravi
      -- Internal instruction memory --
797 62 zero_gravi
      MEM_INT_IMEM_EN   => MEM_INT_IMEM_EN,    -- implement processor-internal instruction memory
798
      MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE,  -- size of processor-internal instruction memory in bytes
799 23 zero_gravi
      -- Internal data memory --
800 62 zero_gravi
      MEM_INT_DMEM_EN   => MEM_INT_DMEM_EN,    -- implement processor-internal data memory
801
      MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE,  -- size of processor-internal data memory in bytes
802
      -- Interface Configuration --
803
      BUS_TIMEOUT       => MEM_EXT_TIMEOUT,    -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception
804
      PIPE_MODE         => MEM_EXT_PIPE_MODE,  -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
805
      BIG_ENDIAN        => MEM_EXT_BIG_ENDIAN, -- byte order: true=big-endian, false=little-endian
806
      ASYNC_RX          => MEM_EXT_ASYNC_RX    -- use register buffer for RX data when false
807 2 zero_gravi
    )
808
    port map (
809
      -- global control --
810 60 zero_gravi
      clk_i     => clk_i,                         -- global clock line
811
      rstn_i    => sys_rstn,                      -- global reset line, low-active
812 2 zero_gravi
      -- host access --
813 60 zero_gravi
      src_i     => p_bus.src,                     -- access type (0: data, 1:instruction)
814
      addr_i    => p_bus.addr,                    -- address
815
      rden_i    => p_bus.re,                      -- read enable
816
      wren_i    => p_bus.we,                      -- write enable
817
      ben_i     => p_bus.ben,                     -- byte write enable
818
      data_i    => p_bus.wdata,                   -- data in
819
      data_o    => resp_bus(RESP_WISHBONE).rdata, -- data out
820
      lock_i    => p_bus.lock,                    -- exclusive access request
821
      ack_o     => resp_bus(RESP_WISHBONE).ack,   -- transfer acknowledge
822
      err_o     => resp_bus(RESP_WISHBONE).err,   -- transfer error
823 68 zero_gravi
      tmo_o     => ext_timeout,                   -- transfer timeout
824 60 zero_gravi
      priv_i    => p_bus.priv,                    -- current CPU privilege level
825 68 zero_gravi
      ext_o     => ext_access,                    -- active external access
826 2 zero_gravi
      -- wishbone interface --
827 60 zero_gravi
      wb_tag_o  => wb_tag_o,                      -- request tag
828
      wb_adr_o  => wb_adr_o,                      -- address
829
      wb_dat_i  => wb_dat_i,                      -- read data
830
      wb_dat_o  => wb_dat_o,                      -- write data
831
      wb_we_o   => wb_we_o,                       -- read/write
832
      wb_sel_o  => wb_sel_o,                      -- byte enable
833
      wb_stb_o  => wb_stb_o,                      -- strobe
834
      wb_cyc_o  => wb_cyc_o,                      -- valid cycle
835
      wb_lock_o => wb_lock_o,                     -- exclusive access request
836
      wb_ack_i  => wb_ack_i,                      -- transfer acknowledge
837
      wb_err_i  => wb_err_i                       -- transfer error
838 2 zero_gravi
    );
839
  end generate;
840
 
841
  neorv32_wishbone_inst_false:
842 44 zero_gravi
  if (MEM_EXT_EN = false) generate
843 60 zero_gravi
    resp_bus(RESP_WISHBONE) <= resp_bus_entry_terminate_c;
844 68 zero_gravi
    ext_timeout <= '0';
845
    ext_access  <= '0';
846 2 zero_gravi
    --
847 60 zero_gravi
    wb_adr_o  <= (others => '0');
848
    wb_dat_o  <= (others => '0');
849
    wb_we_o   <= '0';
850
    wb_sel_o  <= (others => '0');
851
    wb_stb_o  <= '0';
852
    wb_cyc_o  <= '0';
853
    wb_lock_o <= '0';
854
    wb_tag_o  <= (others => '0');
855 2 zero_gravi
  end generate;
856
 
857
 
858
  -- IO Access? -----------------------------------------------------------------------------
859
  -- -------------------------------------------------------------------------------------------
860 12 zero_gravi
  io_acc  <= '1' when (p_bus.addr(data_width_c-1 downto index_size_f(io_size_c)) = io_base_c(data_width_c-1 downto index_size_f(io_size_c))) else '0';
861 40 zero_gravi
  io_rden <= io_acc and p_bus.re and (not p_bus.src); -- PMA: no_execute for IO region
862 47 zero_gravi
  -- the default NEORV32 peripheral/IO devices in the IO area can only be written in word mode (reduces HW complexity)
863 60 zero_gravi
  io_wren <= io_acc and p_bus.we and and_reduce_f(p_bus.ben) and (not p_bus.src); -- PMA: write32 only, no_execute for IO region
864 2 zero_gravi
 
865
 
866 47 zero_gravi
  -- Custom Functions Subsystem (CFS) -------------------------------------------------------
867
  -- -------------------------------------------------------------------------------------------
868
  neorv32_cfs_inst_true:
869
  if (IO_CFS_EN = true) generate
870
    neorv32_cfs_inst: neorv32_cfs
871
    generic map (
872 61 zero_gravi
      CFS_CONFIG   => IO_CFS_CONFIG,  -- custom CFS configuration generic
873 52 zero_gravi
      CFS_IN_SIZE  => IO_CFS_IN_SIZE, -- size of CFS input conduit in bits
874
      CFS_OUT_SIZE => IO_CFS_OUT_SIZE -- size of CFS output conduit in bits
875 47 zero_gravi
    )
876
    port map (
877
      -- host access --
878 60 zero_gravi
      clk_i       => clk_i,                    -- global clock line
879
      rstn_i      => sys_rstn,                 -- global reset line, low-active, use as async
880
      addr_i      => p_bus.addr,               -- address
881
      rden_i      => io_rden,                  -- read enable
882
      wren_i      => io_wren,                  -- byte write enable
883
      data_i      => p_bus.wdata,              -- data in
884
      data_o      => resp_bus(RESP_CFS).rdata, -- data out
885
      ack_o       => resp_bus(RESP_CFS).ack,   -- transfer acknowledge
886 68 zero_gravi
      err_o       => resp_bus(RESP_CFS).err,   -- access error
887 47 zero_gravi
      -- clock generator --
888 60 zero_gravi
      clkgen_en_o => cfs_cg_en,                -- enable clock generator
889
      clkgen_i    => clk_gen,                  -- "clock" inputs
890 47 zero_gravi
      -- interrupt --
891 60 zero_gravi
      irq_o       => cfs_irq,                  -- interrupt request
892 47 zero_gravi
      -- custom io (conduit) --
893 60 zero_gravi
      cfs_in_i    => cfs_in_i,                 -- custom inputs
894
      cfs_out_o   => cfs_out_o                 -- custom outputs
895 47 zero_gravi
    );
896
  end generate;
897
 
898
  neorv32_cfs_inst_false:
899
  if (IO_CFS_EN = false) generate
900 60 zero_gravi
    resp_bus(RESP_CFS) <= resp_bus_entry_terminate_c;
901 47 zero_gravi
    cfs_cg_en <= '0';
902
    cfs_irq   <= '0';
903
    cfs_out_o <= (others => '0');
904
  end generate;
905
 
906
 
907 2 zero_gravi
  -- General Purpose Input/Output Port (GPIO) -----------------------------------------------
908
  -- -------------------------------------------------------------------------------------------
909
  neorv32_gpio_inst_true:
910 44 zero_gravi
  if (IO_GPIO_EN = true) generate
911 2 zero_gravi
    neorv32_gpio_inst: neorv32_gpio
912
    port map (
913
      -- host access --
914 60 zero_gravi
      clk_i  => clk_i,                     -- global clock line
915
      addr_i => p_bus.addr,                -- address
916
      rden_i => io_rden,                   -- read enable
917
      wren_i => io_wren,                   -- write enable
918
      data_i => p_bus.wdata,               -- data in
919
      data_o => resp_bus(RESP_GPIO).rdata, -- data out
920
      ack_o  => resp_bus(RESP_GPIO).ack,   -- transfer acknowledge
921 2 zero_gravi
      -- parallel io --
922
      gpio_o => gpio_o,
923 61 zero_gravi
      gpio_i => gpio_i
924 2 zero_gravi
    );
925 60 zero_gravi
    resp_bus(RESP_GPIO).err <= '0'; -- no access error possible
926 2 zero_gravi
  end generate;
927
 
928
  neorv32_gpio_inst_false:
929 44 zero_gravi
  if (IO_GPIO_EN = false) generate
930 60 zero_gravi
    resp_bus(RESP_GPIO) <= resp_bus_entry_terminate_c;
931 61 zero_gravi
    gpio_o <= (others => '0');
932 2 zero_gravi
  end generate;
933
 
934
 
935
  -- Watch Dog Timer (WDT) ------------------------------------------------------------------
936
  -- -------------------------------------------------------------------------------------------
937
  neorv32_wdt_inst_true:
938 44 zero_gravi
  if (IO_WDT_EN = true) generate
939 2 zero_gravi
    neorv32_wdt_inst: neorv32_wdt
940
    port map (
941
      -- host access --
942 60 zero_gravi
      clk_i       => clk_i,                    -- global clock line
943
      rstn_i      => ext_rstn,                 -- global reset line, low-active
944
      rden_i      => io_rden,                  -- read enable
945
      wren_i      => io_wren,                  -- write enable
946
      addr_i      => p_bus.addr,               -- address
947
      data_i      => p_bus.wdata,              -- data in
948
      data_o      => resp_bus(RESP_WDT).rdata, -- data out
949
      ack_o       => resp_bus(RESP_WDT).ack,   -- transfer acknowledge
950 2 zero_gravi
      -- clock generator --
951 60 zero_gravi
      clkgen_en_o => wdt_cg_en,                -- enable clock generator
952 2 zero_gravi
      clkgen_i    => clk_gen,
953
      -- timeout event --
954 60 zero_gravi
      irq_o       => wdt_irq,                  -- timeout IRQ
955
      rstn_o      => wdt_rstn                  -- timeout reset, low_active, use it as async!
956 2 zero_gravi
    );
957 60 zero_gravi
    resp_bus(RESP_WDT).err <= '0'; -- no access error possible
958 2 zero_gravi
  end generate;
959
 
960
  neorv32_wdt_inst_false:
961 44 zero_gravi
  if (IO_WDT_EN = false) generate
962 60 zero_gravi
    resp_bus(RESP_WDT) <= resp_bus_entry_terminate_c;
963 2 zero_gravi
    wdt_irq   <= '0';
964
    wdt_rstn  <= '1';
965
    wdt_cg_en <= '0';
966
  end generate;
967
 
968
 
969
  -- Machine System Timer (MTIME) -----------------------------------------------------------
970
  -- -------------------------------------------------------------------------------------------
971
  neorv32_mtime_inst_true:
972 44 zero_gravi
  if (IO_MTIME_EN = true) generate
973 2 zero_gravi
    neorv32_mtime_inst: neorv32_mtime
974
    port map (
975
      -- host access --
976 60 zero_gravi
      clk_i  => clk_i,                      -- global clock line
977
      addr_i => p_bus.addr,                 -- address
978
      rden_i => io_rden,                    -- read enable
979
      wren_i => io_wren,                    -- write enable
980
      data_i => p_bus.wdata,                -- data in
981
      data_o => resp_bus(RESP_MTIME).rdata, -- data out
982
      ack_o  => resp_bus(RESP_MTIME).ack,   -- transfer acknowledge
983 11 zero_gravi
      -- time output for CPU --
984 60 zero_gravi
      time_o => mtime_time,                 -- current system time
985 2 zero_gravi
      -- interrupt --
986 60 zero_gravi
      irq_o  => mtime_irq                   -- interrupt request
987 2 zero_gravi
    );
988 60 zero_gravi
    resp_bus(RESP_MTIME).err <= '0'; -- no access error possible
989 2 zero_gravi
  end generate;
990
 
991
  neorv32_mtime_inst_false:
992 44 zero_gravi
  if (IO_MTIME_EN = false) generate
993 60 zero_gravi
    resp_bus(RESP_MTIME) <= resp_bus_entry_terminate_c;
994
    mtime_time <= mtime_i; -- use external machine timer time signal
995 64 zero_gravi
    mtime_irq  <= mtime_irq_i; -- use external machine timer interrupt
996 2 zero_gravi
  end generate;
997
 
998
 
999 60 zero_gravi
  -- system time output LO --
1000
  mtime_sync: process(clk_i)
1001
  begin
1002
    if rising_edge(clk_i) then
1003
      -- buffer low word one clock cycle to compensate for MTIME's 1-cycle delay
1004
      -- when overflowing from low-word to high-word -> only relevant for processor-external devices
1005
      -- processor-internal devices (= the CPU) do not care about this delay offset as 64-bit MTIME.TIME
1006
      -- cannot be accessed within a single cycle
1007
      if (IO_MTIME_EN = true) then
1008
        mtime_o(31 downto 0) <= mtime_time(31 downto 0);
1009
      else
1010
        mtime_o(31 downto 0) <= (others => '0');
1011
      end if;
1012
    end if;
1013
  end process mtime_sync;
1014 59 zero_gravi
 
1015 60 zero_gravi
  -- system time output HI --
1016
  mtime_o(63 downto 32) <= mtime_time(63 downto 32) when (IO_MTIME_EN = true) else (others => '0');
1017
 
1018
 
1019 51 zero_gravi
  -- Primary Universal Asynchronous Receiver/Transmitter (UART0) ----------------------------
1020 2 zero_gravi
  -- -------------------------------------------------------------------------------------------
1021 50 zero_gravi
  neorv32_uart0_inst_true:
1022
  if (IO_UART0_EN = true) generate
1023
    neorv32_uart0_inst: neorv32_uart
1024
    generic map (
1025 65 zero_gravi
      UART_PRIMARY => true,             -- true = primary UART (UART0), false = secondary UART (UART1)
1026
      UART_RX_FIFO => IO_UART0_RX_FIFO, -- RX fifo depth, has to be a power of two, min 1
1027
      UART_TX_FIFO => IO_UART0_TX_FIFO  -- TX fifo depth, has to be a power of two, min 1
1028 50 zero_gravi
    )
1029 2 zero_gravi
    port map (
1030
      -- host access --
1031 60 zero_gravi
      clk_i       => clk_i,                      -- global clock line
1032
      addr_i      => p_bus.addr,                 -- address
1033
      rden_i      => io_rden,                    -- read enable
1034
      wren_i      => io_wren,                    -- write enable
1035
      data_i      => p_bus.wdata,                -- data in
1036
      data_o      => resp_bus(RESP_UART0).rdata, -- data out
1037
      ack_o       => resp_bus(RESP_UART0).ack,   -- transfer acknowledge
1038 2 zero_gravi
      -- clock generator --
1039 60 zero_gravi
      clkgen_en_o => uart0_cg_en,                -- enable clock generator
1040 2 zero_gravi
      clkgen_i    => clk_gen,
1041
      -- com lines --
1042 50 zero_gravi
      uart_txd_o  => uart0_txd_o,
1043
      uart_rxd_i  => uart0_rxd_i,
1044 51 zero_gravi
      -- hardware flow control --
1045 60 zero_gravi
      uart_rts_o  => uart0_rts_o,                -- UART.RX ready to receive ("RTR"), low-active, optional
1046
      uart_cts_i  => uart0_cts_i,                -- UART.TX allowed to transmit, low-active, optional
1047 2 zero_gravi
      -- interrupts --
1048 60 zero_gravi
      irq_rxd_o   => uart0_rxd_irq,              -- uart data received interrupt
1049
      irq_txd_o   => uart0_txd_irq               -- uart transmission done interrupt
1050 2 zero_gravi
    );
1051 60 zero_gravi
    resp_bus(RESP_UART0).err <= '0'; -- no access error possible
1052 2 zero_gravi
  end generate;
1053
 
1054 50 zero_gravi
  neorv32_uart0_inst_false:
1055
  if (IO_UART0_EN = false) generate
1056 60 zero_gravi
    resp_bus(RESP_UART0) <= resp_bus_entry_terminate_c;
1057 50 zero_gravi
    uart0_txd_o   <= '0';
1058 51 zero_gravi
    uart0_rts_o   <= '0';
1059 50 zero_gravi
    uart0_cg_en   <= '0';
1060
    uart0_rxd_irq <= '0';
1061
    uart0_txd_irq <= '0';
1062 2 zero_gravi
  end generate;
1063
 
1064
 
1065 51 zero_gravi
  -- Secondary Universal Asynchronous Receiver/Transmitter (UART1) --------------------------
1066 50 zero_gravi
  -- -------------------------------------------------------------------------------------------
1067
  neorv32_uart1_inst_true:
1068
  if (IO_UART1_EN = true) generate
1069
    neorv32_uart1_inst: neorv32_uart
1070
    generic map (
1071 65 zero_gravi
      UART_PRIMARY => false,            -- true = primary UART (UART0), false = secondary UART (UART1)
1072
      UART_RX_FIFO => IO_UART1_RX_FIFO, -- RX fifo depth, has to be a power of two, min 1
1073
      UART_TX_FIFO => IO_UART1_TX_FIFO  -- TX fifo depth, has to be a power of two, min 1
1074 50 zero_gravi
    )
1075
    port map (
1076
      -- host access --
1077 60 zero_gravi
      clk_i       => clk_i,                      -- global clock line
1078
      addr_i      => p_bus.addr,                 -- address
1079
      rden_i      => io_rden,                    -- read enable
1080
      wren_i      => io_wren,                    -- write enable
1081
      data_i      => p_bus.wdata,                -- data in
1082
      data_o      => resp_bus(RESP_UART1).rdata, -- data out
1083
      ack_o       => resp_bus(RESP_UART1).ack,   -- transfer acknowledge
1084 50 zero_gravi
      -- clock generator --
1085 60 zero_gravi
      clkgen_en_o => uart1_cg_en,                -- enable clock generator
1086 50 zero_gravi
      clkgen_i    => clk_gen,
1087
      -- com lines --
1088
      uart_txd_o  => uart1_txd_o,
1089
      uart_rxd_i  => uart1_rxd_i,
1090 51 zero_gravi
      -- hardware flow control --
1091 60 zero_gravi
      uart_rts_o  => uart1_rts_o,                -- UART.RX ready to receive ("RTR"), low-active, optional
1092
      uart_cts_i  => uart1_cts_i,                -- UART.TX allowed to transmit, low-active, optional
1093 50 zero_gravi
      -- interrupts --
1094 60 zero_gravi
      irq_rxd_o   => uart1_rxd_irq,              -- uart data received interrupt
1095
      irq_txd_o   => uart1_txd_irq               -- uart transmission done interrupt
1096 50 zero_gravi
    );
1097 60 zero_gravi
    resp_bus(RESP_UART1).err <= '0'; -- no access error possible
1098 50 zero_gravi
  end generate;
1099
 
1100
  neorv32_uart1_inst_false:
1101
  if (IO_UART1_EN = false) generate
1102 60 zero_gravi
    resp_bus(RESP_UART1) <= resp_bus_entry_terminate_c;
1103 50 zero_gravi
    uart1_txd_o   <= '0';
1104 51 zero_gravi
    uart1_rts_o   <= '0';
1105 50 zero_gravi
    uart1_cg_en   <= '0';
1106
    uart1_rxd_irq <= '0';
1107
    uart1_txd_irq <= '0';
1108
  end generate;
1109
 
1110
 
1111 2 zero_gravi
  -- Serial Peripheral Interface (SPI) ------------------------------------------------------
1112
  -- -------------------------------------------------------------------------------------------
1113
  neorv32_spi_inst_true:
1114 44 zero_gravi
  if (IO_SPI_EN = true) generate
1115 2 zero_gravi
    neorv32_spi_inst: neorv32_spi
1116
    port map (
1117
      -- host access --
1118 60 zero_gravi
      clk_i       => clk_i,                    -- global clock line
1119
      addr_i      => p_bus.addr,               -- address
1120
      rden_i      => io_rden,                  -- read enable
1121
      wren_i      => io_wren,                  -- write enable
1122
      data_i      => p_bus.wdata,              -- data in
1123
      data_o      => resp_bus(RESP_SPI).rdata, -- data out
1124
      ack_o       => resp_bus(RESP_SPI).ack,   -- transfer acknowledge
1125 2 zero_gravi
      -- clock generator --
1126 60 zero_gravi
      clkgen_en_o => spi_cg_en,                -- enable clock generator
1127 2 zero_gravi
      clkgen_i    => clk_gen,
1128
      -- com lines --
1129 60 zero_gravi
      spi_sck_o   => spi_sck_o,                -- SPI serial clock
1130
      spi_sdo_o   => spi_sdo_o,                -- controller data out, peripheral data in
1131
      spi_sdi_i   => spi_sdi_i,                -- controller data in, peripheral data out
1132
      spi_csn_o   => spi_csn_o,                -- SPI CS
1133 2 zero_gravi
      -- interrupt --
1134 60 zero_gravi
      irq_o       => spi_irq                   -- transmission done interrupt
1135 2 zero_gravi
    );
1136 60 zero_gravi
    resp_bus(RESP_SPI).err <= '0'; -- no access error possible
1137 2 zero_gravi
  end generate;
1138
 
1139
  neorv32_spi_inst_false:
1140 44 zero_gravi
  if (IO_SPI_EN = false) generate
1141 60 zero_gravi
    resp_bus(RESP_SPI) <= resp_bus_entry_terminate_c;
1142
    spi_sck_o <= '0';
1143
    spi_sdo_o <= '0';
1144
    spi_csn_o <= (others => '1'); -- CSn lines are low-active
1145
    spi_cg_en <= '0';
1146
    spi_irq   <= '0';
1147 2 zero_gravi
  end generate;
1148
 
1149
 
1150
  -- Two-Wire Interface (TWI) ---------------------------------------------------------------
1151
  -- -------------------------------------------------------------------------------------------
1152
  neorv32_twi_inst_true:
1153 44 zero_gravi
  if (IO_TWI_EN = true) generate
1154 2 zero_gravi
    neorv32_twi_inst: neorv32_twi
1155
    port map (
1156
      -- host access --
1157 60 zero_gravi
      clk_i       => clk_i,                    -- global clock line
1158
      addr_i      => p_bus.addr,               -- address
1159
      rden_i      => io_rden,                  -- read enable
1160
      wren_i      => io_wren,                  -- write enable
1161
      data_i      => p_bus.wdata,              -- data in
1162
      data_o      => resp_bus(RESP_TWI).rdata, -- data out
1163
      ack_o       => resp_bus(RESP_TWI).ack,   -- transfer acknowledge
1164 2 zero_gravi
      -- clock generator --
1165 60 zero_gravi
      clkgen_en_o => twi_cg_en,                -- enable clock generator
1166 2 zero_gravi
      clkgen_i    => clk_gen,
1167
      -- com lines --
1168 60 zero_gravi
      twi_sda_io  => twi_sda_io,               -- serial data line
1169
      twi_scl_io  => twi_scl_io,               -- serial clock line
1170 2 zero_gravi
      -- interrupt --
1171 60 zero_gravi
      irq_o       => twi_irq                   -- transfer done IRQ
1172 2 zero_gravi
    );
1173 60 zero_gravi
    resp_bus(RESP_TWI).err <= '0'; -- no access error possible
1174 2 zero_gravi
  end generate;
1175
 
1176
  neorv32_twi_inst_false:
1177 44 zero_gravi
  if (IO_TWI_EN = false) generate
1178 60 zero_gravi
    resp_bus(RESP_TWI) <= resp_bus_entry_terminate_c;
1179 65 zero_gravi
    twi_sda_io <= 'Z';
1180
    twi_scl_io <= 'Z';
1181 2 zero_gravi
    twi_cg_en  <= '0';
1182
    twi_irq    <= '0';
1183
  end generate;
1184
 
1185
 
1186
  -- Pulse-Width Modulation Controller (PWM) ------------------------------------------------
1187
  -- -------------------------------------------------------------------------------------------
1188
  neorv32_pwm_inst_true:
1189 60 zero_gravi
  if (IO_PWM_NUM_CH > 0) generate
1190 2 zero_gravi
    neorv32_pwm_inst: neorv32_pwm
1191 60 zero_gravi
    generic map (
1192
      NUM_CHANNELS => IO_PWM_NUM_CH -- number of PWM channels (0..60)
1193
    )
1194 2 zero_gravi
    port map (
1195
      -- host access --
1196 60 zero_gravi
      clk_i       => clk_i,                    -- global clock line
1197
      addr_i      => p_bus.addr,               -- address
1198
      rden_i      => io_rden,                  -- read enable
1199
      wren_i      => io_wren,                  -- write enable
1200
      data_i      => p_bus.wdata,              -- data in
1201
      data_o      => resp_bus(RESP_PWM).rdata, -- data out
1202
      ack_o       => resp_bus(RESP_PWM).ack,   -- transfer acknowledge
1203 2 zero_gravi
      -- clock generator --
1204 60 zero_gravi
      clkgen_en_o => pwm_cg_en,                -- enable clock generator
1205 2 zero_gravi
      clkgen_i    => clk_gen,
1206
      -- pwm output channels --
1207
      pwm_o       => pwm_o
1208
    );
1209 60 zero_gravi
    resp_bus(RESP_PWM).err <= '0'; -- no access error possible
1210 2 zero_gravi
  end generate;
1211
 
1212
  neorv32_pwm_inst_false:
1213 60 zero_gravi
  if (IO_PWM_NUM_CH = 0) generate
1214
    resp_bus(RESP_PWM) <= resp_bus_entry_terminate_c;
1215 2 zero_gravi
    pwm_cg_en <= '0';
1216
    pwm_o     <= (others => '0');
1217
  end generate;
1218
 
1219
 
1220
  -- True Random Number Generator (TRNG) ----------------------------------------------------
1221
  -- -------------------------------------------------------------------------------------------
1222
  neorv32_trng_inst_true:
1223 44 zero_gravi
  if (IO_TRNG_EN = true) generate
1224 2 zero_gravi
    neorv32_trng_inst: neorv32_trng
1225
    port map (
1226
      -- host access --
1227 60 zero_gravi
      clk_i  => clk_i,                     -- global clock line
1228
      addr_i => p_bus.addr,                -- address
1229
      rden_i => io_rden,                   -- read enable
1230
      wren_i => io_wren,                   -- write enable
1231
      data_i => p_bus.wdata,               -- data in
1232
      data_o => resp_bus(RESP_TRNG).rdata, -- data out
1233
      ack_o  => resp_bus(RESP_TRNG).ack    -- transfer acknowledge
1234 2 zero_gravi
    );
1235 60 zero_gravi
    resp_bus(RESP_TRNG).err <= '0'; -- no access error possible
1236 2 zero_gravi
  end generate;
1237
 
1238
  neorv32_trng_inst_false:
1239 44 zero_gravi
  if (IO_TRNG_EN = false) generate
1240 60 zero_gravi
    resp_bus(RESP_TRNG) <= resp_bus_entry_terminate_c;
1241 2 zero_gravi
  end generate;
1242
 
1243
 
1244 52 zero_gravi
  -- Smart LED (WS2811/WS2812) Interface (NEOLED) -------------------------------------------
1245
  -- -------------------------------------------------------------------------------------------
1246
  neorv32_neoled_inst_true:
1247
  if (IO_NEOLED_EN = true) generate
1248
    neorv32_neoled_inst: neorv32_neoled
1249 62 zero_gravi
    generic map (
1250
      FIFO_DEPTH => IO_NEOLED_TX_FIFO -- TX FIFO depth (1..32k, power of two)
1251
    )
1252 52 zero_gravi
    port map (
1253
      -- host access --
1254 60 zero_gravi
      clk_i       => clk_i,                       -- global clock line
1255
      addr_i      => p_bus.addr,                  -- address
1256
      rden_i      => io_rden,                     -- read enable
1257
      wren_i      => io_wren,                     -- write enable
1258
      data_i      => p_bus.wdata,                 -- data in
1259
      data_o      => resp_bus(RESP_NEOLED).rdata, -- data out
1260
      ack_o       => resp_bus(RESP_NEOLED).ack,   -- transfer acknowledge
1261 52 zero_gravi
      -- clock generator --
1262 60 zero_gravi
      clkgen_en_o => neoled_cg_en,                -- enable clock generator
1263 52 zero_gravi
      clkgen_i    => clk_gen,
1264
      -- interrupt --
1265 60 zero_gravi
      irq_o       => neoled_irq,                  -- interrupt request
1266 52 zero_gravi
      -- NEOLED output --
1267 60 zero_gravi
      neoled_o    => neoled_o                     -- serial async data line
1268 52 zero_gravi
    );
1269 60 zero_gravi
    resp_bus(RESP_NEOLED).err <= '0'; -- no access error possible
1270 52 zero_gravi
  end generate;
1271
 
1272
  neorv32_neoled_inst_false:
1273
  if (IO_NEOLED_EN = false) generate
1274 60 zero_gravi
    resp_bus(RESP_NEOLED) <= resp_bus_entry_terminate_c;
1275 52 zero_gravi
    neoled_cg_en <= '0';
1276
    neoled_irq   <= '0';
1277
    neoled_o     <= '0';
1278
  end generate;
1279
 
1280
 
1281 61 zero_gravi
  -- Stream Link Interface (SLINK) ----------------------------------------------------------
1282
  -- -------------------------------------------------------------------------------------------
1283
  neorv32_slink_inst_true:
1284
  if (io_slink_en_c = true) generate
1285
    neorv32_slink_inst: neorv32_slink
1286
    generic map (
1287
      SLINK_NUM_TX  => SLINK_NUM_TX,  -- number of TX links (0..8)
1288
      SLINK_NUM_RX  => SLINK_NUM_RX,  -- number of TX links (0..8)
1289
      SLINK_TX_FIFO => SLINK_TX_FIFO, -- TX fifo depth, has to be a power of two
1290
      SLINK_RX_FIFO => SLINK_RX_FIFO  -- RX fifo depth, has to be a power of two
1291
    )
1292
    port map (
1293
      -- host access --
1294
      clk_i          => clk_i,                      -- global clock line
1295
      addr_i         => p_bus.addr,                 -- address
1296
      rden_i         => io_rden,                    -- read enable
1297
      wren_i         => io_wren,                    -- write enable
1298
      data_i         => p_bus.wdata,                -- data in
1299
      data_o         => resp_bus(RESP_SLINK).rdata, -- data out
1300
      ack_o          => resp_bus(RESP_SLINK).ack,   -- transfer acknowledge
1301
      -- interrupt --
1302
      irq_tx_o       => slink_tx_irq,               -- transmission done
1303
      irq_rx_o       => slink_rx_irq,               -- data received
1304
      -- TX stream interfaces --
1305
      slink_tx_dat_o => slink_tx_dat_o,             -- output data
1306
      slink_tx_val_o => slink_tx_val_o,             -- valid output
1307
      slink_tx_rdy_i => slink_tx_rdy_i,             -- ready to send
1308
      -- RX stream interfaces --
1309
      slink_rx_dat_i => slink_rx_dat_i,             -- input data
1310
      slink_rx_val_i => slink_rx_val_i,             -- valid input
1311
      slink_rx_rdy_o => slink_rx_rdy_o              -- ready to receive
1312
    );
1313
    resp_bus(RESP_SLINK).err <= '0'; -- no access error possible
1314
  end generate;
1315
 
1316
  neorv32_slink_inst_false:
1317
  if (io_slink_en_c = false) generate
1318
    resp_bus(RESP_SLINK) <= resp_bus_entry_terminate_c;
1319
    slink_tx_irq   <= '0';
1320
    slink_rx_irq   <= '0';
1321
    slink_tx_dat_o <= (others => (others => '0'));
1322
    slink_tx_val_o <= (others => '0');
1323
    slink_rx_rdy_o <= (others => '0');
1324
  end generate;
1325
 
1326
 
1327
  -- External Interrupt Controller (XIRQ) ---------------------------------------------------
1328
  -- -------------------------------------------------------------------------------------------
1329
  neorv32_xirq_inst_true:
1330
  if (XIRQ_NUM_CH > 0) generate
1331
    neorv32_slink_inst: neorv32_xirq
1332
    generic map (
1333
      XIRQ_NUM_CH           => XIRQ_NUM_CH,          -- number of external IRQ channels (0..32)
1334
      XIRQ_TRIGGER_TYPE     => XIRQ_TRIGGER_TYPE,    -- trigger type: 0=level, 1=edge
1335
      XIRQ_TRIGGER_POLARITY => XIRQ_TRIGGER_POLARITY -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
1336
    )
1337
    port map (
1338
      -- host access --
1339
      clk_i     => clk_i,                     -- global clock line
1340
      addr_i    => p_bus.addr,                -- address
1341
      rden_i    => io_rden,                   -- read enable
1342
      wren_i    => io_wren,                   -- write enable
1343
      data_i    => p_bus.wdata,               -- data in
1344
      data_o    => resp_bus(RESP_XIRQ).rdata, -- data out
1345
      ack_o     => resp_bus(RESP_XIRQ).ack,   -- transfer acknowledge
1346
      -- external interrupt lines --
1347
      xirq_i    => xirq_i,
1348
      -- CPU interrupt --
1349
      cpu_irq_o => xirq_irq
1350
    );
1351
    resp_bus(RESP_XIRQ).err <= '0'; -- no access error possible
1352
  end generate;
1353
 
1354
  neorv32_xirq_inst_false:
1355
  if (XIRQ_NUM_CH = 0) generate
1356
    resp_bus(RESP_XIRQ) <= resp_bus_entry_terminate_c;
1357
    xirq_irq <= '0';
1358
  end generate;
1359
 
1360
 
1361 67 zero_gravi
  -- General Purpose Timer (GPTMR) ----------------------------------------------------------
1362
  -- -------------------------------------------------------------------------------------------
1363
  neorv32_gptmr_inst_true:
1364
  if (IO_GPTMR_EN = true) generate
1365
    neorv32_gptmr_inst: neorv32_gptmr
1366
    port map (
1367
      -- host access --
1368
      clk_i     => clk_i,                      -- global clock line
1369
      addr_i    => p_bus.addr,                 -- address
1370
      rden_i    => io_rden,                    -- read enable
1371
      wren_i    => io_wren,                    -- write enable
1372
      data_i    => p_bus.wdata,                -- data in
1373
      data_o    => resp_bus(RESP_GPTMR).rdata, -- data out
1374
      ack_o     => resp_bus(RESP_GPTMR).ack,   -- transfer acknowledge
1375
      -- clock generator --
1376
      clkgen_en_o => gptmr_cg_en,              -- enable clock generator
1377
      clkgen_i    => clk_gen,
1378
      -- interrupt --
1379
      irq_o       => gptmr_irq                 -- transmission done interrupt
1380
    );
1381
    resp_bus(RESP_GPTMR).err <= '0'; -- no access error possible
1382
  end generate;
1383
 
1384
  neorv32_gptmr_inst_false:
1385
  if (IO_GPTMR_EN = false) generate
1386
    resp_bus(RESP_GPTMR) <= resp_bus_entry_terminate_c;
1387
    gptmr_cg_en          <= '0';
1388
    gptmr_irq            <= '0';
1389
  end generate;
1390
 
1391
 
1392 12 zero_gravi
  -- System Configuration Information Memory (SYSINFO) --------------------------------------
1393
  -- -------------------------------------------------------------------------------------------
1394
  neorv32_sysinfo_inst: neorv32_sysinfo
1395
  generic map (
1396
    -- General --
1397 63 zero_gravi
    CLOCK_FREQUENCY              => CLOCK_FREQUENCY,      -- clock frequency of clk_i in Hz
1398
    INT_BOOTLOADER_EN            => INT_BOOTLOADER_EN,    -- implement processor-internal bootloader?
1399
    -- RISC-V CPU Extensions --
1400
    CPU_EXTENSION_RISCV_Zfinx    => CPU_EXTENSION_RISCV_Zfinx,    -- implement 32-bit floating-point extension (using INT reg!)
1401
    CPU_EXTENSION_RISCV_Zicsr    => CPU_EXTENSION_RISCV_Zicsr,    -- implement CSR system?
1402 66 zero_gravi
    CPU_EXTENSION_RISCV_Zicntr   => CPU_EXTENSION_RISCV_Zicntr,   -- implement base counters?
1403
    CPU_EXTENSION_RISCV_Zihpm    => CPU_EXTENSION_RISCV_Zihpm,    -- implement hardware performance monitors?
1404 63 zero_gravi
    CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
1405
    CPU_EXTENSION_RISCV_Zmmul    => CPU_EXTENSION_RISCV_Zmmul,    -- implement multiply-only M sub-extension?
1406
    CPU_EXTENSION_RISCV_DEBUG    => ON_CHIP_DEBUGGER_EN,          -- implement CPU debug mode?
1407
    -- Extension Options --
1408
    FAST_MUL_EN                  => FAST_MUL_EN,          -- use DSPs for M extension's multiplier
1409
    FAST_SHIFT_EN                => FAST_SHIFT_EN,        -- use barrel shifter for shift operations
1410
    CPU_CNT_WIDTH                => CPU_CNT_WIDTH,        -- total width of CPU cycle and instret counters (0..64)
1411
    -- Physical memory protection (PMP) --
1412
    PMP_NUM_REGIONS              => PMP_NUM_REGIONS,      -- number of regions (0..64)
1413 23 zero_gravi
    -- internal Instruction memory --
1414 63 zero_gravi
    MEM_INT_IMEM_EN              => MEM_INT_IMEM_EN,      -- implement processor-internal instruction memory
1415
    MEM_INT_IMEM_SIZE            => MEM_INT_IMEM_SIZE,    -- size of processor-internal instruction memory in bytes
1416 23 zero_gravi
    -- Internal Data memory --
1417 63 zero_gravi
    MEM_INT_DMEM_EN              => MEM_INT_DMEM_EN,      -- implement processor-internal data memory
1418
    MEM_INT_DMEM_SIZE            => MEM_INT_DMEM_SIZE,    -- size of processor-internal data memory in bytes
1419 41 zero_gravi
    -- Internal Cache memory --
1420 63 zero_gravi
    ICACHE_EN                    => ICACHE_EN,            -- implement instruction cache
1421
    ICACHE_NUM_BLOCKS            => ICACHE_NUM_BLOCKS,    -- i-cache: number of blocks (min 2), has to be a power of 2
1422
    ICACHE_BLOCK_SIZE            => ICACHE_BLOCK_SIZE,    -- i-cache: block size in bytes (min 4), has to be a power of 2
1423
    ICACHE_ASSOCIATIVITY         => ICACHE_ASSOCIATIVITY, -- i-cache: associativity (min 1), has to be a power 2
1424 23 zero_gravi
    -- External memory interface --
1425 63 zero_gravi
    MEM_EXT_EN                   => MEM_EXT_EN,           -- implement external memory bus interface?
1426
    MEM_EXT_BIG_ENDIAN           => MEM_EXT_BIG_ENDIAN,   -- byte order: true=big-endian, false=little-endian
1427 59 zero_gravi
    -- On-Chip Debugger --
1428 63 zero_gravi
    ON_CHIP_DEBUGGER_EN          => ON_CHIP_DEBUGGER_EN,  -- implement OCD?
1429 12 zero_gravi
    -- Processor peripherals --
1430 63 zero_gravi
    IO_GPIO_EN                   => IO_GPIO_EN,           -- implement general purpose input/output port unit (GPIO)?
1431
    IO_MTIME_EN                  => IO_MTIME_EN,          -- implement machine system timer (MTIME)?
1432
    IO_UART0_EN                  => IO_UART0_EN,          -- implement primary universal asynchronous receiver/transmitter (UART0)?
1433
    IO_UART1_EN                  => IO_UART1_EN,          -- implement secondary universal asynchronous receiver/transmitter (UART1)?
1434
    IO_SPI_EN                    => IO_SPI_EN,            -- implement serial peripheral interface (SPI)?
1435
    IO_TWI_EN                    => IO_TWI_EN,            -- implement two-wire interface (TWI)?
1436
    IO_PWM_NUM_CH                => IO_PWM_NUM_CH,        -- number of PWM channels to implement
1437
    IO_WDT_EN                    => IO_WDT_EN,            -- implement watch dog timer (WDT)?
1438
    IO_TRNG_EN                   => IO_TRNG_EN,           -- implement true random number generator (TRNG)?
1439
    IO_CFS_EN                    => IO_CFS_EN,            -- implement custom functions subsystem (CFS)?
1440
    IO_SLINK_EN                  => io_slink_en_c,        -- implement stream link interface?
1441
    IO_NEOLED_EN                 => IO_NEOLED_EN,         -- implement NeoPixel-compatible smart LED interface (NEOLED)?
1442 67 zero_gravi
    IO_XIRQ_NUM_CH               => XIRQ_NUM_CH,          -- number of external interrupt (XIRQ) channels to implement
1443
    IO_GPTMR_EN                  => IO_GPTMR_EN           -- implement general purpose timer (GPTMR)?
1444 12 zero_gravi
  )
1445
  port map (
1446
    -- host access --
1447 60 zero_gravi
    clk_i  => clk_i,                        -- global clock line
1448
    addr_i => p_bus.addr,                   -- address
1449
    rden_i => io_rden,                      -- read enable
1450
    data_o => resp_bus(RESP_SYSINFO).rdata, -- data out
1451
    ack_o  => resp_bus(RESP_SYSINFO).ack    -- transfer acknowledge
1452 12 zero_gravi
  );
1453
 
1454 60 zero_gravi
  resp_bus(RESP_SYSINFO).err <= '0'; -- no access error possible
1455 12 zero_gravi
 
1456 60 zero_gravi
 
1457 59 zero_gravi
  -- **************************************************************************************************************************
1458
  -- On-Chip Debugger Complex
1459
  -- **************************************************************************************************************************
1460
 
1461
 
1462
  -- On-Chip Debugger - Debug Module (DM) ---------------------------------------------------
1463
  -- -------------------------------------------------------------------------------------------
1464
  neorv32_neorv32_debug_dm_true:
1465
  if (ON_CHIP_DEBUGGER_EN = true) generate
1466
    neorv32_debug_dm_inst: neorv32_debug_dm
1467
    port map (
1468
      -- global control --
1469 60 zero_gravi
      clk_i            => clk_i,                    -- global clock line
1470
      rstn_i           => ext_rstn,                 -- external reset, low-active
1471 59 zero_gravi
      -- debug module interface (DMI) --
1472
      dmi_rstn_i       => dmi.rstn,
1473
      dmi_req_valid_i  => dmi.req_valid,
1474
      dmi_req_ready_o  => dmi.req_ready,
1475
      dmi_req_addr_i   => dmi.req_addr,
1476
      dmi_req_op_i     => dmi.req_op,
1477
      dmi_req_data_i   => dmi.req_data,
1478 60 zero_gravi
      dmi_resp_valid_o => dmi.resp_valid,           -- response valid when set
1479
      dmi_resp_ready_i => dmi.resp_ready,           -- ready to receive respond
1480 59 zero_gravi
      dmi_resp_data_o  => dmi.resp_data,
1481 60 zero_gravi
      dmi_resp_err_o   => dmi.resp_err,             -- 0=ok, 1=error
1482 59 zero_gravi
      -- CPU bus access --
1483 60 zero_gravi
      cpu_addr_i       => p_bus.addr,               -- address
1484
      cpu_rden_i       => p_bus.re,                 -- read enable
1485
      cpu_wren_i       => p_bus.we,                 -- write enable
1486
      cpu_data_i       => p_bus.wdata,              -- data in
1487
      cpu_data_o       => resp_bus(RESP_OCD).rdata, -- data out
1488
      cpu_ack_o        => resp_bus(RESP_OCD).ack,   -- transfer acknowledge
1489 59 zero_gravi
      -- CPU control --
1490 60 zero_gravi
      cpu_ndmrstn_o    => dci_ndmrstn,              -- soc reset
1491
      cpu_halt_req_o   => dci_halt_req              -- request hart to halt (enter debug mode)
1492 59 zero_gravi
    );
1493 60 zero_gravi
    resp_bus(RESP_OCD).err <= '0'; -- no access error possible
1494 59 zero_gravi
  end generate;
1495
 
1496
  neorv32_debug_dm_false:
1497
  if (ON_CHIP_DEBUGGER_EN = false) generate
1498
    dmi.req_ready  <= '0';
1499
    dmi.resp_valid <= '0';
1500
    dmi.resp_data  <= (others => '0');
1501
    dmi.resp_err   <= '0';
1502
    --
1503 60 zero_gravi
    resp_bus(RESP_OCD) <= resp_bus_entry_terminate_c;
1504
    dci_ndmrstn  <= '1';
1505
    dci_halt_req <= '0';
1506 59 zero_gravi
  end generate;
1507
 
1508
 
1509
  -- On-Chip Debugger - Debug Transport Module (DTM) ----------------------------------------
1510
  -- -------------------------------------------------------------------------------------------
1511
  neorv32_neorv32_debug_dtm_true:
1512
  if (ON_CHIP_DEBUGGER_EN = true) generate
1513
    neorv32_debug_dtm_inst: neorv32_debug_dtm
1514
    generic map (
1515
      IDCODE_VERSION => jtag_tap_idcode_version_c, -- version
1516
      IDCODE_PARTID  => jtag_tap_idcode_partid_c,  -- part number
1517
      IDCODE_MANID   => jtag_tap_idcode_manid_c    -- manufacturer id
1518
    )
1519
    port map (
1520
      -- global control --
1521
      clk_i            => clk_i,          -- global clock line
1522
      rstn_i           => ext_rstn,       -- external reset, low-active
1523
      -- jtag connection --
1524
      jtag_trst_i      => jtag_trst_i,
1525
      jtag_tck_i       => jtag_tck_i,
1526
      jtag_tdi_i       => jtag_tdi_i,
1527
      jtag_tdo_o       => jtag_tdo_o,
1528
      jtag_tms_i       => jtag_tms_i,
1529
      -- debug module interface (DMI) --
1530
      dmi_rstn_o       => dmi.rstn,
1531
      dmi_req_valid_o  => dmi.req_valid,
1532
      dmi_req_ready_i  => dmi.req_ready,  -- DMI is allowed to make new requests when set
1533
      dmi_req_addr_o   => dmi.req_addr,
1534
      dmi_req_op_o     => dmi.req_op,     -- 0=read, 1=write
1535
      dmi_req_data_o   => dmi.req_data,
1536
      dmi_resp_valid_i => dmi.resp_valid, -- response valid when set
1537
      dmi_resp_ready_o => dmi.resp_ready, -- ready to receive respond
1538
      dmi_resp_data_i  => dmi.resp_data,
1539
      dmi_resp_err_i   => dmi.resp_err    -- 0=ok, 1=error
1540
    );
1541
  end generate;
1542
 
1543
  neorv32_debug_dtm_false:
1544
  if (ON_CHIP_DEBUGGER_EN = false) generate
1545
    jtag_tdo_o <= jtag_tdi_i; -- feed-through
1546
    --
1547
    dmi.rstn       <= '0';
1548
    dmi.req_valid  <= '0';
1549
    dmi.req_addr   <= (others => '0');
1550
    dmi.req_op     <= '0';
1551
    dmi.req_data   <= (others => '0');
1552
    dmi.resp_ready <= '0';
1553
  end generate;
1554
 
1555
 
1556 2 zero_gravi
end neorv32_top_rtl;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.