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

Subversion Repositories neorv32

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

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

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