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

Subversion Repositories neorv32

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

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