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

Subversion Repositories neorv32

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

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 23 zero_gravi
-- # Check the processor's data sheet for more information: docs/NEORV32.pdf                       #
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 36 zero_gravi
    HW_THREAD_ID                 : std_ulogic_vector(31 downto 0) := (others => '0'); -- hardware thread id (hartid)
55 2 zero_gravi
    -- RISC-V CPU Extensions --
56 39 zero_gravi
    CPU_EXTENSION_RISCV_A        : boolean := false;  -- implement atomic extension?
57 44 zero_gravi
    CPU_EXTENSION_RISCV_B        : boolean := false;  -- implement bit manipulation extensions?
58 11 zero_gravi
    CPU_EXTENSION_RISCV_C        : boolean := false;  -- implement compressed extension?
59 8 zero_gravi
    CPU_EXTENSION_RISCV_E        : boolean := false;  -- implement embedded RF extension?
60 11 zero_gravi
    CPU_EXTENSION_RISCV_M        : boolean := false;  -- implement muld/div extension?
61 15 zero_gravi
    CPU_EXTENSION_RISCV_U        : boolean := false;  -- implement user mode extension?
62 8 zero_gravi
    CPU_EXTENSION_RISCV_Zicsr    : boolean := true;   -- implement CSR system?
63 39 zero_gravi
    CPU_EXTENSION_RISCV_Zifencei : boolean := false;  -- implement instruction stream sync.?
64 19 zero_gravi
    -- Extension Options --
65 23 zero_gravi
    FAST_MUL_EN                  : boolean := false;  -- use DSPs for M extension's multiplier
66 39 zero_gravi
    FAST_SHIFT_EN                : boolean := false;  -- use barrel shifter for shift operations
67 15 zero_gravi
    -- Physical Memory Protection (PMP) --
68 42 zero_gravi
    PMP_NUM_REGIONS              : natural := 0;      -- number of regions (0..64)
69
    PMP_MIN_GRANULARITY          : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
70
    -- Hardware Performance Monitors (HPM) --
71 47 zero_gravi
    HPM_NUM_CNTS                 : natural := 0;      -- number of implemented HPM counters (0..29)
72 23 zero_gravi
    -- Internal Instruction memory --
73 44 zero_gravi
    MEM_INT_IMEM_EN              : boolean := true;   -- implement processor-internal instruction memory
74 8 zero_gravi
    MEM_INT_IMEM_SIZE            : natural := 16*1024; -- size of processor-internal instruction memory in bytes
75
    MEM_INT_IMEM_ROM             : boolean := false;  -- implement processor-internal instruction memory as ROM
76 23 zero_gravi
    -- Internal Data memory --
77 44 zero_gravi
    MEM_INT_DMEM_EN              : boolean := true;   -- implement processor-internal data memory
78 8 zero_gravi
    MEM_INT_DMEM_SIZE            : natural := 8*1024; -- size of processor-internal data memory in bytes
79 41 zero_gravi
    -- Internal Cache memory --
80 44 zero_gravi
    ICACHE_EN                    : boolean := false;  -- implement instruction cache
81 41 zero_gravi
    ICACHE_NUM_BLOCKS            : natural := 4;      -- i-cache: number of blocks (min 1), has to be a power of 2
82
    ICACHE_BLOCK_SIZE            : natural := 64;     -- i-cache: block size in bytes (min 4), has to be a power of 2
83 45 zero_gravi
    ICACHE_ASSOCIATIVITY         : natural := 1;      -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
84 23 zero_gravi
    -- External memory interface --
85 44 zero_gravi
    MEM_EXT_EN                   : boolean := false;  -- implement external memory bus interface?
86 2 zero_gravi
    -- Processor peripherals --
87 44 zero_gravi
    IO_GPIO_EN                   : boolean := true;   -- implement general purpose input/output port unit (GPIO)?
88
    IO_MTIME_EN                  : boolean := true;   -- implement machine system timer (MTIME)?
89
    IO_UART_EN                   : boolean := true;   -- implement universal asynchronous receiver/transmitter (UART)?
90
    IO_SPI_EN                    : boolean := true;   -- implement serial peripheral interface (SPI)?
91
    IO_TWI_EN                    : boolean := true;   -- implement two-wire interface (TWI)?
92
    IO_PWM_EN                    : boolean := true;   -- implement pulse-width modulation unit (PWM)?
93
    IO_WDT_EN                    : boolean := true;   -- implement watch dog timer (WDT)?
94
    IO_TRNG_EN                   : boolean := false;  -- implement true random number generator (TRNG)?
95 47 zero_gravi
    IO_CFS_EN                    : boolean := false;  -- implement custom functions subsystem (CFS)?
96
    IO_CFS_CONFIG                : std_ulogic_vector(31 downto 0) := (others => '0') -- custom CFS configuration generic
97 2 zero_gravi
  );
98
  port (
99
    -- Global control --
100 34 zero_gravi
    clk_i       : in  std_ulogic := '0'; -- global clock, rising edge
101
    rstn_i      : in  std_ulogic := '0'; -- global reset, low-active, async
102 44 zero_gravi
    -- Wishbone bus interface (available if MEM_EXT_EN = true) --
103 36 zero_gravi
    wb_tag_o    : out std_ulogic_vector(02 downto 0); -- tag
104 34 zero_gravi
    wb_adr_o    : out std_ulogic_vector(31 downto 0); -- address
105
    wb_dat_i    : in  std_ulogic_vector(31 downto 0) := (others => '0'); -- read data
106
    wb_dat_o    : out std_ulogic_vector(31 downto 0); -- write data
107
    wb_we_o     : out std_ulogic; -- read/write
108
    wb_sel_o    : out std_ulogic_vector(03 downto 0); -- byte enable
109
    wb_stb_o    : out std_ulogic; -- strobe
110
    wb_cyc_o    : out std_ulogic; -- valid cycle
111 39 zero_gravi
    wb_lock_o   : out std_ulogic; -- locked/exclusive bus access
112 34 zero_gravi
    wb_ack_i    : in  std_ulogic := '0'; -- transfer acknowledge
113
    wb_err_i    : in  std_ulogic := '0'; -- transfer error
114 44 zero_gravi
    -- Advanced memory control signals (available if MEM_EXT_EN = true) --
115 34 zero_gravi
    fence_o     : out std_ulogic; -- indicates an executed FENCE operation
116
    fencei_o    : out std_ulogic; -- indicates an executed FENCEI operation
117 44 zero_gravi
    -- GPIO (available if IO_GPIO_EN = true) --
118 34 zero_gravi
    gpio_o      : out std_ulogic_vector(31 downto 0); -- parallel output
119
    gpio_i      : in  std_ulogic_vector(31 downto 0) := (others => '0'); -- parallel input
120 44 zero_gravi
    -- UART (available if IO_UART_EN = true) --
121 34 zero_gravi
    uart_txd_o  : out std_ulogic; -- UART send data
122
    uart_rxd_i  : in  std_ulogic := '0'; -- UART receive data
123 44 zero_gravi
    -- SPI (available if IO_SPI_EN = true) --
124 34 zero_gravi
    spi_sck_o   : out std_ulogic; -- SPI serial clock
125
    spi_sdo_o   : out std_ulogic; -- controller data out, peripheral data in
126
    spi_sdi_i   : in  std_ulogic := '0'; -- controller data in, peripheral data out
127
    spi_csn_o   : out std_ulogic_vector(07 downto 0); -- SPI CS
128 44 zero_gravi
    -- TWI (available if IO_TWI_EN = true) --
129 35 zero_gravi
    twi_sda_io  : inout std_logic; -- twi serial data line
130
    twi_scl_io  : inout std_logic; -- twi serial clock line
131 44 zero_gravi
    -- PWM (available if IO_PWM_EN = true) --
132 34 zero_gravi
    pwm_o       : out std_ulogic_vector(03 downto 0); -- pwm channels
133 47 zero_gravi
    -- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
134
    cfs_in_i    : in  std_ulogic_vector(31 downto 0) := (others => '0'); -- custom CFS inputs conduit
135
    cfs_out_o   : out std_ulogic_vector(31 downto 0); -- custom CFS outputs conduit
136 44 zero_gravi
    -- system time input from external MTIME (available if IO_MTIME_EN = false) --
137 40 zero_gravi
    mtime_i     : in  std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time
138 14 zero_gravi
    -- Interrupts --
139 48 zero_gravi
    soc_firq_i  : in  std_ulogic_vector(7 downto 0) := (others => '0'); -- fast interrupt channels
140 44 zero_gravi
    mtime_irq_i : in  std_ulogic := '0'; -- machine timer interrupt, available if IO_MTIME_EN = false
141 34 zero_gravi
    msw_irq_i   : in  std_ulogic := '0'; -- machine software interrupt
142
    mext_irq_i  : in  std_ulogic := '0'  -- machine external interrupt
143 2 zero_gravi
  );
144
end neorv32_top;
145
 
146
architecture neorv32_top_rtl of neorv32_top is
147
 
148 12 zero_gravi
  -- CPU boot address --
149 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);
150 12 zero_gravi
 
151 41 zero_gravi
  -- Bus timeout --
152
  constant bus_timeout_temp_c : natural := 2**index_size_f(bus_timeout_c); -- round to next power-of-two
153 44 zero_gravi
  constant bus_timeout_proc_c : natural := cond_sel_natural_f(ICACHE_EN, ((ICACHE_BLOCK_SIZE/4)*bus_timeout_temp_c)-1, bus_timeout_c);
154 41 zero_gravi
 
155 29 zero_gravi
  -- alignment check for internal memories --
156
  constant imem_align_check_c : std_ulogic_vector(index_size_f(MEM_INT_IMEM_SIZE)-1 downto 0) := (others => '0');
157
  constant dmem_align_check_c : std_ulogic_vector(index_size_f(MEM_INT_DMEM_SIZE)-1 downto 0) := (others => '0');
158
 
159 2 zero_gravi
  -- reset generator --
160
  signal rstn_i_sync0 : std_ulogic;
161
  signal rstn_i_sync1 : std_ulogic;
162
  signal rstn_i_sync2 : std_ulogic;
163
  signal rstn_gen     : std_ulogic_vector(3 downto 0);
164
  signal ext_rstn     : std_ulogic;
165
  signal sys_rstn     : std_ulogic;
166
  signal wdt_rstn     : std_ulogic;
167
 
168
  -- clock generator --
169
  signal clk_div    : std_ulogic_vector(11 downto 0);
170
  signal clk_div_ff : std_ulogic_vector(11 downto 0);
171
  signal clk_gen    : std_ulogic_vector(07 downto 0);
172 47 zero_gravi
  --
173 2 zero_gravi
  signal wdt_cg_en  : std_ulogic;
174
  signal uart_cg_en : std_ulogic;
175
  signal spi_cg_en  : std_ulogic;
176
  signal twi_cg_en  : std_ulogic;
177
  signal pwm_cg_en  : std_ulogic;
178 47 zero_gravi
  signal cfs_cg_en  : std_ulogic;
179 2 zero_gravi
 
180 12 zero_gravi
  -- bus interface --
181
  type bus_interface_t is record
182 11 zero_gravi
    addr   : std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
183
    rdata  : std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
184
    wdata  : std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
185
    ben    : std_ulogic_vector(03 downto 0); -- byte enable
186
    we     : std_ulogic; -- write enable
187
    re     : std_ulogic; -- read enable
188
    cancel : std_ulogic; -- cancel current transfer
189
    ack    : std_ulogic; -- bus transfer acknowledge
190
    err    : std_ulogic; -- bus transfer error
191 12 zero_gravi
    fence  : std_ulogic; -- fence(i) instruction executed
192 35 zero_gravi
    priv   : std_ulogic_vector(1 downto 0); -- current privilege level
193 40 zero_gravi
    src    : std_ulogic; -- access source (1=instruction fetch, 0=data access)
194 39 zero_gravi
    lock   : std_ulogic; -- locked/exclusive (=atomic) access
195 11 zero_gravi
  end record;
196 41 zero_gravi
  signal cpu_i, i_cache, cpu_d, p_bus : bus_interface_t;
197 2 zero_gravi
 
198
  -- io space access --
199
  signal io_acc  : std_ulogic;
200
  signal io_rden : std_ulogic;
201
  signal io_wren : std_ulogic;
202
 
203
  -- read-back busses -
204
  signal imem_rdata     : std_ulogic_vector(data_width_c-1 downto 0);
205
  signal imem_ack       : std_ulogic;
206
  signal dmem_rdata     : std_ulogic_vector(data_width_c-1 downto 0);
207
  signal dmem_ack       : std_ulogic;
208
  signal bootrom_rdata  : std_ulogic_vector(data_width_c-1 downto 0);
209
  signal bootrom_ack    : std_ulogic;
210
  signal wishbone_rdata : std_ulogic_vector(data_width_c-1 downto 0);
211
  signal wishbone_ack   : std_ulogic;
212
  signal wishbone_err   : std_ulogic;
213
  signal gpio_rdata     : std_ulogic_vector(data_width_c-1 downto 0);
214
  signal gpio_ack       : std_ulogic;
215
  signal mtime_rdata    : std_ulogic_vector(data_width_c-1 downto 0);
216
  signal mtime_ack      : std_ulogic;
217
  signal uart_rdata     : std_ulogic_vector(data_width_c-1 downto 0);
218
  signal uart_ack       : std_ulogic;
219
  signal spi_rdata      : std_ulogic_vector(data_width_c-1 downto 0);
220
  signal spi_ack        : std_ulogic;
221
  signal twi_rdata      : std_ulogic_vector(data_width_c-1 downto 0);
222
  signal twi_ack        : std_ulogic;
223
  signal pwm_rdata      : std_ulogic_vector(data_width_c-1 downto 0);
224
  signal pwm_ack        : std_ulogic;
225
  signal wdt_rdata      : std_ulogic_vector(data_width_c-1 downto 0);
226
  signal wdt_ack        : std_ulogic;
227
  signal trng_rdata     : std_ulogic_vector(data_width_c-1 downto 0);
228
  signal trng_ack       : std_ulogic;
229 47 zero_gravi
  signal cfs_rdata      : std_ulogic_vector(data_width_c-1 downto 0);
230
  signal cfs_err        : std_ulogic;
231
  signal cfs_ack        : std_ulogic;
232 12 zero_gravi
  signal sysinfo_rdata  : std_ulogic_vector(data_width_c-1 downto 0);
233
  signal sysinfo_ack    : std_ulogic;
234 2 zero_gravi
 
235
  -- IRQs --
236 48 zero_gravi
  signal mtime_irq    : std_ulogic;
237 47 zero_gravi
  --
238 48 zero_gravi
  signal fast_irq     : std_ulogic_vector(15 downto 0);
239
  signal fast_irq_ack : std_ulogic_vector(15 downto 0);
240
  --
241 47 zero_gravi
  signal gpio_irq     : std_ulogic;
242
  signal wdt_irq      : std_ulogic;
243 48 zero_gravi
  signal uart_rxd_irq : std_ulogic;
244
  signal uart_txd_irq : std_ulogic;
245 47 zero_gravi
  signal spi_irq      : std_ulogic;
246
  signal twi_irq      : std_ulogic;
247
  signal cfs_irq      : std_ulogic;
248 48 zero_gravi
  signal cfs_irq_ack  : std_ulogic;
249 2 zero_gravi
 
250 11 zero_gravi
  -- misc --
251
  signal mtime_time : std_ulogic_vector(63 downto 0); -- current system time from MTIME
252 47 zero_gravi
  signal cpu_sleep  : std_ulogic; -- CPU is in sleep mode when set
253 11 zero_gravi
 
254 2 zero_gravi
begin
255
 
256
  -- Sanity Checks --------------------------------------------------------------------------
257
  -- -------------------------------------------------------------------------------------------
258 36 zero_gravi
  -- clock --
259
  assert not (CLOCK_FREQUENCY = 0) report "NEORV32 PROCESSOR CONFIG ERROR! Core clock frequency (CLOCK_FREQUENCY) not specified." severity error;
260 23 zero_gravi
  -- internal bootloader ROM --
261 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;
262
  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;
263 23 zero_gravi
  -- memory system - data/instruction fetch --
264 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;
265
  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;
266 36 zero_gravi
  -- memory system - size --
267 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;
268
  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;
269 29 zero_gravi
  -- memory system - alignment --
270
  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;
271
  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;
272 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;
273
  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;
274 36 zero_gravi
  -- memory system - layout warning --
275 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;
276
  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;
277 41 zero_gravi
  -- memory system - the i-cache is intended to accelerate instruction fetch via the external memory interface only --
278 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;
279 41 zero_gravi
  -- memory system - cached instruction fetch latency check --
280 44 zero_gravi
  assert not (ICACHE_EN = true) report "NEORV32 PROCESSOR CONFIG WARNING! Implementing i-cache. Increasing bus access timeout from " & integer'image(bus_timeout_c) & " cycles to " & integer'image(bus_timeout_proc_c) & " cycles." severity warning;
281 2 zero_gravi
 
282
 
283
  -- Reset Generator ------------------------------------------------------------------------
284
  -- -------------------------------------------------------------------------------------------
285
  reset_generator_sync: process(clk_i)
286
  begin
287
    -- make sure the external reset is free of metastability and has a minimal duration of 1 clock cycle
288
    if rising_edge(clk_i) then
289
      rstn_i_sync0 <= rstn_i;
290
      rstn_i_sync1 <= rstn_i_sync0;
291
      rstn_i_sync2 <= rstn_i_sync1;
292
    end if;
293
  end process reset_generator_sync;
294
 
295
  -- keep internal reset active for at least 4 clock cycles
296
  reset_generator: process(rstn_i_sync1, rstn_i_sync2, clk_i)
297
  begin
298 23 zero_gravi
    if ((rstn_i_sync1 and rstn_i_sync2) = '0') then -- signal stable?
299 2 zero_gravi
      rstn_gen <= (others => '0');
300
    elsif rising_edge(clk_i) then
301
      rstn_gen <= rstn_gen(rstn_gen'left-1 downto 0) & '1';
302
    end if;
303
  end process reset_generator;
304
 
305
  ext_rstn <= rstn_gen(rstn_gen'left); -- the beautified external reset signal
306 23 zero_gravi
  sys_rstn <= ext_rstn and wdt_rstn;   -- system reset - can also be triggered by watchdog
307 2 zero_gravi
 
308
 
309
  -- Clock Generator ------------------------------------------------------------------------
310
  -- -------------------------------------------------------------------------------------------
311
  clock_generator: process(sys_rstn, clk_i)
312
  begin
313
    if (sys_rstn = '0') then
314
      clk_div    <= (others => '0');
315
      clk_div_ff <= (others => '0');
316
    elsif rising_edge(clk_i) then
317 23 zero_gravi
      -- fresh clocks anyone? --
318 47 zero_gravi
      if ((wdt_cg_en or uart_cg_en or spi_cg_en or twi_cg_en or pwm_cg_en or cfs_cg_en) = '1') then
319 23 zero_gravi
        clk_div <= std_ulogic_vector(unsigned(clk_div) + 1);
320 2 zero_gravi
      end if;
321 23 zero_gravi
      clk_div_ff <= clk_div;
322 2 zero_gravi
    end if;
323
  end process clock_generator;
324
 
325 23 zero_gravi
  -- clock enables: rising edge detectors --
326
  clock_generator_edge: process(clk_i)
327
  begin
328
    if rising_edge(clk_i) then
329
      clk_gen(clk_div2_c)    <= clk_div(0)  and (not clk_div_ff(0));  -- CLK/2
330
      clk_gen(clk_div4_c)    <= clk_div(1)  and (not clk_div_ff(1));  -- CLK/4
331
      clk_gen(clk_div8_c)    <= clk_div(2)  and (not clk_div_ff(2));  -- CLK/8
332
      clk_gen(clk_div64_c)   <= clk_div(5)  and (not clk_div_ff(5));  -- CLK/64
333
      clk_gen(clk_div128_c)  <= clk_div(6)  and (not clk_div_ff(6));  -- CLK/128
334
      clk_gen(clk_div1024_c) <= clk_div(9)  and (not clk_div_ff(9));  -- CLK/1024
335
      clk_gen(clk_div2048_c) <= clk_div(10) and (not clk_div_ff(10)); -- CLK/2048
336
      clk_gen(clk_div4096_c) <= clk_div(11) and (not clk_div_ff(11)); -- CLK/4096
337
    end if;
338
  end process clock_generator_edge;
339 2 zero_gravi
 
340
 
341 45 zero_gravi
  -- CPU Core -------------------------------------------------------------------------------
342 2 zero_gravi
  -- -------------------------------------------------------------------------------------------
343
  neorv32_cpu_inst: neorv32_cpu
344
  generic map (
345
    -- General --
346 41 zero_gravi
    HW_THREAD_ID                 => HW_THREAD_ID,        -- hardware thread id
347
    CPU_BOOT_ADDR                => cpu_boot_addr_c,     -- cpu boot address
348
    BUS_TIMEOUT                  => bus_timeout_proc_c,  -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception
349 2 zero_gravi
    -- RISC-V CPU Extensions --
350 39 zero_gravi
    CPU_EXTENSION_RISCV_A        => CPU_EXTENSION_RISCV_A,        -- implement atomic extension?
351 44 zero_gravi
    CPU_EXTENSION_RISCV_B        => CPU_EXTENSION_RISCV_B,        -- implement bit manipulation extensions?
352 8 zero_gravi
    CPU_EXTENSION_RISCV_C        => CPU_EXTENSION_RISCV_C,        -- implement compressed extension?
353
    CPU_EXTENSION_RISCV_E        => CPU_EXTENSION_RISCV_E,        -- implement embedded RF extension?
354
    CPU_EXTENSION_RISCV_M        => CPU_EXTENSION_RISCV_M,        -- implement muld/div extension?
355 15 zero_gravi
    CPU_EXTENSION_RISCV_U        => CPU_EXTENSION_RISCV_U,        -- implement user mode extension?
356 8 zero_gravi
    CPU_EXTENSION_RISCV_Zicsr    => CPU_EXTENSION_RISCV_Zicsr,    -- implement CSR system?
357
    CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
358 19 zero_gravi
    -- Extension Options --
359 41 zero_gravi
    FAST_MUL_EN                  => FAST_MUL_EN,         -- use DSPs for M extension's multiplier
360
    FAST_SHIFT_EN                => FAST_SHIFT_EN,       -- use barrel shifter for shift operations
361 15 zero_gravi
    -- Physical Memory Protection (PMP) --
362 42 zero_gravi
    PMP_NUM_REGIONS              => PMP_NUM_REGIONS,     -- number of regions (0..64)
363
    PMP_MIN_GRANULARITY          => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
364
    -- Hardware Performance Monitors (HPM) --
365 47 zero_gravi
    HPM_NUM_CNTS                 => HPM_NUM_CNTS         -- number of implemented HPM counters (0..29)
366 2 zero_gravi
  )
367
  port map (
368
    -- global control --
369 12 zero_gravi
    clk_i          => clk_i,        -- global clock, rising edge
370
    rstn_i         => sys_rstn,     -- global reset, low-active, async
371 47 zero_gravi
    sleep_o        => cpu_sleep,    -- cpu is in sleep mode when set
372 12 zero_gravi
    -- instruction bus interface --
373
    i_bus_addr_o   => cpu_i.addr,   -- bus access address
374
    i_bus_rdata_i  => cpu_i.rdata,  -- bus read data
375
    i_bus_wdata_o  => cpu_i.wdata,  -- bus write data
376
    i_bus_ben_o    => cpu_i.ben,    -- byte enable
377
    i_bus_we_o     => cpu_i.we,     -- write enable
378
    i_bus_re_o     => cpu_i.re,     -- read enable
379
    i_bus_cancel_o => cpu_i.cancel, -- cancel current bus transaction
380
    i_bus_ack_i    => cpu_i.ack,    -- bus transfer acknowledge
381
    i_bus_err_i    => cpu_i.err,    -- bus transfer error
382
    i_bus_fence_o  => cpu_i.fence,  -- executed FENCEI operation
383 35 zero_gravi
    i_bus_priv_o   => cpu_i.priv,   -- privilege level
384 39 zero_gravi
    i_bus_lock_o   => cpu_i.lock,   -- locked/exclusive access
385 12 zero_gravi
    -- data bus interface --
386
    d_bus_addr_o   => cpu_d.addr,   -- bus access address
387
    d_bus_rdata_i  => cpu_d.rdata,  -- bus read data
388
    d_bus_wdata_o  => cpu_d.wdata,  -- bus write data
389
    d_bus_ben_o    => cpu_d.ben,    -- byte enable
390
    d_bus_we_o     => cpu_d.we,     -- write enable
391
    d_bus_re_o     => cpu_d.re,     -- read enable
392
    d_bus_cancel_o => cpu_d.cancel, -- cancel current bus transaction
393
    d_bus_ack_i    => cpu_d.ack,    -- bus transfer acknowledge
394
    d_bus_err_i    => cpu_d.err,    -- bus transfer error
395
    d_bus_fence_o  => cpu_d.fence,  -- executed FENCE operation
396 35 zero_gravi
    d_bus_priv_o   => cpu_d.priv,   -- privilege level
397 39 zero_gravi
    d_bus_lock_o   => cpu_d.lock,   -- locked/exclusive access
398 11 zero_gravi
    -- system time input from MTIME --
399 12 zero_gravi
    time_i         => mtime_time,   -- current system time
400 14 zero_gravi
    -- interrupts (risc-v compliant) --
401
    msw_irq_i      => msw_irq_i,    -- machine software interrupt
402
    mext_irq_i     => mext_irq_i,   -- machine external interrupt request
403
    mtime_irq_i    => mtime_irq,    -- machine timer interrupt
404
    -- fast interrupts (custom) --
405 47 zero_gravi
    firq_i         => fast_irq,     -- fast interrupt trigger
406
    firq_ack_o     => fast_irq_ack  -- fast interrupt acknowledge mask
407 2 zero_gravi
  );
408
 
409 36 zero_gravi
  -- misc --
410 40 zero_gravi
  cpu_i.src <= '1'; -- initialized but unused
411
  cpu_d.src <= '0'; -- initialized but unused
412 36 zero_gravi
 
413 14 zero_gravi
  -- advanced memory control --
414
  fence_o  <= cpu_d.fence; -- indicates an executed FENCE operation
415
  fencei_o <= cpu_i.fence; -- indicates an executed FENCEI operation
416 2 zero_gravi
 
417 47 zero_gravi
  -- fast interrupts - processor-internal --
418 48 zero_gravi
  fast_irq(00) <= wdt_irq;      -- HIGHEST PRIORITY - watchdog timeout
419
  fast_irq(01) <= '0';          -- reserved
420
  fast_irq(02) <= cfs_irq;      -- custom functions subsystem
421
  fast_irq(03) <= uart_rxd_irq; -- UART data received
422
  fast_irq(04) <= uart_txd_irq; -- UART transmission done
423
  fast_irq(05) <= spi_irq;      -- SPI transmission done
424
  fast_irq(06) <= twi_irq;      -- TWI transmission done
425
  fast_irq(07) <= gpio_irq;     -- GPIO pin-change
426 14 zero_gravi
 
427 48 zero_gravi
  -- fast interrupts - platform level (for custom use) --
428
  fast_irq(08) <= soc_firq_i(0);
429
  fast_irq(09) <= soc_firq_i(1);
430
  fast_irq(10) <= soc_firq_i(2);
431
  fast_irq(11) <= soc_firq_i(3);
432
  fast_irq(12) <= soc_firq_i(4);
433
  fast_irq(13) <= soc_firq_i(5);
434
  fast_irq(14) <= soc_firq_i(6);
435
  fast_irq(15) <= soc_firq_i(7);
436 14 zero_gravi
 
437 48 zero_gravi
  -- IRQ acknowledge --
438
  cfs_irq_ack <= fast_irq_ack(2);
439
 
440
 
441 41 zero_gravi
  -- CPU Instruction Cache ------------------------------------------------------------------
442
  -- -------------------------------------------------------------------------------------------
443
  neorv32_icache_inst_true:
444 44 zero_gravi
  if (ICACHE_EN = true) generate
445 45 zero_gravi
    neorv32_icache_inst: neorv32_icache
446 41 zero_gravi
    generic map (
447 47 zero_gravi
      ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS,   -- number of blocks (min 2), has to be a power of 2
448
      ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE,   -- block size in bytes (min 4), has to be a power of 2
449
      ICACHE_NUM_SETS   => ICACHE_ASSOCIATIVITY -- associativity / number of sets (1=direct_mapped), has to be a power of 2
450 41 zero_gravi
    )
451
    port map (
452
      -- global control --
453
      clk_i         => clk_i,          -- global clock, rising edge
454
      rstn_i        => sys_rstn,       -- global reset, low-active, async
455
      clear_i       => cpu_i.fence,    -- cache clear
456
      -- host controller interface --
457
      host_addr_i   => cpu_i.addr,     -- bus access address
458
      host_rdata_o  => cpu_i.rdata,    -- bus read data
459
      host_wdata_i  => cpu_i.wdata,    -- bus write data
460
      host_ben_i    => cpu_i.ben,      -- byte enable
461
      host_we_i     => cpu_i.we,       -- write enable
462
      host_re_i     => cpu_i.re,       -- read enable
463
      host_cancel_i => cpu_i.cancel,   -- cancel current bus transaction
464
      host_lock_i   => cpu_i.lock,     -- locked/exclusive access
465
      host_ack_o    => cpu_i.ack,      -- bus transfer acknowledge
466
      host_err_o    => cpu_i.err,      -- bus transfer error
467
      -- peripheral bus interface --
468
      bus_addr_o    => i_cache.addr,   -- bus access address
469
      bus_rdata_i   => i_cache.rdata,  -- bus read data
470
      bus_wdata_o   => i_cache.wdata,  -- bus write data
471
      bus_ben_o     => i_cache.ben,    -- byte enable
472
      bus_we_o      => i_cache.we,     -- write enable
473
      bus_re_o      => i_cache.re,     -- read enable
474
      bus_cancel_o  => i_cache.cancel, -- cancel current bus transaction
475
      bus_lock_o    => i_cache.lock,   -- locked/exclusive access
476
      bus_ack_i     => i_cache.ack,    -- bus transfer acknowledge
477
      bus_err_i     => i_cache.err     -- bus transfer error
478
    );
479
  end generate;
480
 
481
  neorv32_icache_inst_false:
482 44 zero_gravi
  if (ICACHE_EN = false) generate
483 41 zero_gravi
    i_cache.addr   <= cpu_i.addr;
484
    cpu_i.rdata    <= i_cache.rdata;
485
    i_cache.wdata  <= cpu_i.wdata;
486
    i_cache.ben    <= cpu_i.ben;
487
    i_cache.we     <= cpu_i.we;
488
    i_cache.re     <= cpu_i.re;
489
    i_cache.cancel <= cpu_i.cancel;
490
    i_cache.lock   <= cpu_i.lock;
491
    cpu_i.ack      <= i_cache.ack;
492
    cpu_i.err      <= i_cache.err;
493
  end generate;
494
 
495
 
496 45 zero_gravi
  -- CPU Bus Switch -------------------------------------------------------------------------
497 12 zero_gravi
  -- -------------------------------------------------------------------------------------------
498
  neorv32_busswitch_inst: neorv32_busswitch
499
  generic map (
500
    PORT_CA_READ_ONLY => false, -- set if controller port A is read-only
501
    PORT_CB_READ_ONLY => true   -- set if controller port B is read-only
502
  )
503
  port map (
504
    -- global control --
505 41 zero_gravi
    clk_i           => clk_i,          -- global clock, rising edge
506
    rstn_i          => sys_rstn,       -- global reset, low-active, async
507 12 zero_gravi
    -- controller interface a --
508 41 zero_gravi
    ca_bus_addr_i   => cpu_d.addr,     -- bus access address
509
    ca_bus_rdata_o  => cpu_d.rdata,    -- bus read data
510
    ca_bus_wdata_i  => cpu_d.wdata,    -- bus write data
511
    ca_bus_ben_i    => cpu_d.ben,      -- byte enable
512
    ca_bus_we_i     => cpu_d.we,       -- write enable
513
    ca_bus_re_i     => cpu_d.re,       -- read enable
514
    ca_bus_cancel_i => cpu_d.cancel,   -- cancel current bus transaction
515
    ca_bus_lock_i   => cpu_d.lock,     -- locked/exclusive access
516
    ca_bus_ack_o    => cpu_d.ack,      -- bus transfer acknowledge
517
    ca_bus_err_o    => cpu_d.err,      -- bus transfer error
518 12 zero_gravi
    -- controller interface b --
519 41 zero_gravi
    cb_bus_addr_i   => i_cache.addr,   -- bus access address
520
    cb_bus_rdata_o  => i_cache.rdata,  -- bus read data
521
    cb_bus_wdata_i  => i_cache.wdata,  -- bus write data
522
    cb_bus_ben_i    => i_cache.ben,    -- byte enable
523
    cb_bus_we_i     => i_cache.we,     -- write enable
524
    cb_bus_re_i     => i_cache.re,     -- read enable
525
    cb_bus_cancel_i => i_cache.cancel, -- cancel current bus transaction
526
    cb_bus_lock_i   => i_cache.lock,   -- locked/exclusive access
527
    cb_bus_ack_o    => i_cache.ack,    -- bus transfer acknowledge
528
    cb_bus_err_o    => i_cache.err,    -- bus transfer error
529 12 zero_gravi
    -- peripheral bus --
530 41 zero_gravi
    p_bus_src_o     => p_bus.src,      -- access source: 0 = A (data), 1 = B (instructions)
531
    p_bus_addr_o    => p_bus.addr,     -- bus access address
532
    p_bus_rdata_i   => p_bus.rdata,    -- bus read data
533
    p_bus_wdata_o   => p_bus.wdata,    -- bus write data
534
    p_bus_ben_o     => p_bus.ben,      -- byte enable
535
    p_bus_we_o      => p_bus.we,       -- write enable
536
    p_bus_re_o      => p_bus.re,       -- read enable
537
    p_bus_cancel_o  => p_bus.cancel,   -- cancel current bus transaction
538
    p_bus_lock_o    => p_bus.lock,     -- locked/exclusive access
539
    p_bus_ack_i     => p_bus.ack,      -- bus transfer acknowledge
540
    p_bus_err_i     => p_bus.err       -- bus transfer error
541 12 zero_gravi
  );
542 2 zero_gravi
 
543 14 zero_gravi
  -- processor bus: CPU data input --
544 12 zero_gravi
  p_bus.rdata <= (imem_rdata or dmem_rdata or bootrom_rdata) or wishbone_rdata or (gpio_rdata or mtime_rdata or uart_rdata or
545 47 zero_gravi
                 spi_rdata or twi_rdata or pwm_rdata or wdt_rdata or trng_rdata or cfs_rdata or sysinfo_rdata);
546 2 zero_gravi
 
547 14 zero_gravi
  -- processor bus: CPU data ACK input --
548 12 zero_gravi
  p_bus.ack <= (imem_ack or dmem_ack or bootrom_ack) or wishbone_ack or (gpio_ack or mtime_ack or uart_ack or
549 47 zero_gravi
               spi_ack or twi_ack or pwm_ack or wdt_ack or trng_ack or cfs_ack or sysinfo_ack);
550 12 zero_gravi
 
551 14 zero_gravi
  -- processor bus: CPU data bus error input --
552 47 zero_gravi
  p_bus.err <= wishbone_err or cfs_err;
553 12 zero_gravi
 
554 36 zero_gravi
  -- current CPU privilege level --
555
  p_bus.priv <= cpu_i.priv; -- cpu_i.priv == cpu_d.priv
556 12 zero_gravi
 
557 36 zero_gravi
 
558 2 zero_gravi
  -- Processor-Internal Instruction Memory (IMEM) -------------------------------------------
559
  -- -------------------------------------------------------------------------------------------
560
  neorv32_int_imem_inst_true:
561 44 zero_gravi
  if (MEM_INT_IMEM_EN = true) generate
562 2 zero_gravi
    neorv32_int_imem_inst: neorv32_imem
563
    generic map (
564 23 zero_gravi
      IMEM_BASE      => imem_base_c,       -- memory base address
565 2 zero_gravi
      IMEM_SIZE      => MEM_INT_IMEM_SIZE, -- processor-internal instruction memory size in bytes
566
      IMEM_AS_ROM    => MEM_INT_IMEM_ROM,  -- implement IMEM as read-only memory?
567 45 zero_gravi
      BOOTLOADER_EN  => BOOTLOADER_EN      -- implement and use bootloader?
568 2 zero_gravi
    )
569
    port map (
570 12 zero_gravi
      clk_i  => clk_i,       -- global clock line
571
      rden_i => p_bus.re,    -- read enable
572
      wren_i => p_bus.we,    -- write enable
573
      ben_i  => p_bus.ben,   -- byte write enable
574
      addr_i => p_bus.addr,  -- address
575
      data_i => p_bus.wdata, -- data in
576
      data_o => imem_rdata,  -- data out
577
      ack_o  => imem_ack     -- transfer acknowledge
578 2 zero_gravi
    );
579
  end generate;
580
 
581
  neorv32_int_imem_inst_false:
582 44 zero_gravi
  if (MEM_INT_IMEM_EN = false) generate
583 2 zero_gravi
    imem_rdata <= (others => '0');
584
    imem_ack   <= '0';
585
  end generate;
586
 
587
 
588
  -- Processor-Internal Data Memory (DMEM) --------------------------------------------------
589
  -- -------------------------------------------------------------------------------------------
590
  neorv32_int_dmem_inst_true:
591 44 zero_gravi
  if (MEM_INT_DMEM_EN = true) generate
592 2 zero_gravi
    neorv32_int_dmem_inst: neorv32_dmem
593
    generic map (
594 23 zero_gravi
      DMEM_BASE => dmem_base_c,      -- memory base address
595 2 zero_gravi
      DMEM_SIZE => MEM_INT_DMEM_SIZE -- processor-internal data memory size in bytes
596
    )
597
    port map (
598 12 zero_gravi
      clk_i  => clk_i,       -- global clock line
599
      rden_i => p_bus.re,    -- read enable
600
      wren_i => p_bus.we,    -- write enable
601
      ben_i  => p_bus.ben,   -- byte write enable
602
      addr_i => p_bus.addr,  -- address
603
      data_i => p_bus.wdata, -- data in
604
      data_o => dmem_rdata,  -- data out
605
      ack_o  => dmem_ack     -- transfer acknowledge
606 2 zero_gravi
    );
607
  end generate;
608
 
609
  neorv32_int_dmem_inst_false:
610 44 zero_gravi
  if (MEM_INT_DMEM_EN = false) generate
611 2 zero_gravi
    dmem_rdata <= (others => '0');
612
    dmem_ack   <= '0';
613
  end generate;
614
 
615
 
616
  -- Processor-Internal Bootloader ROM (BOOTROM) --------------------------------------------
617
  -- -------------------------------------------------------------------------------------------
618
  neorv32_boot_rom_inst_true:
619 44 zero_gravi
  if (BOOTLOADER_EN = true) generate
620 2 zero_gravi
    neorv32_boot_rom_inst: neorv32_boot_rom
621 23 zero_gravi
    generic map (
622
      BOOTROM_BASE => boot_rom_base_c, -- boot ROM base address
623
      BOOTROM_SIZE => boot_rom_size_c  -- processor-internal boot TOM memory size in bytes
624
    )
625 2 zero_gravi
    port map (
626
      clk_i  => clk_i,         -- global clock line
627 12 zero_gravi
      rden_i => p_bus.re,      -- read enable
628
      addr_i => p_bus.addr,    -- address
629 2 zero_gravi
      data_o => bootrom_rdata, -- data out
630
      ack_o  => bootrom_ack    -- transfer acknowledge
631
    );
632
  end generate;
633
 
634
  neorv32_boot_rom_inst_false:
635 44 zero_gravi
  if (BOOTLOADER_EN = false) generate
636 2 zero_gravi
    bootrom_rdata <= (others => '0');
637
    bootrom_ack   <= '0';
638
  end generate;
639
 
640
 
641
  -- External Wishbone Gateway (WISHBONE) ---------------------------------------------------
642
  -- -------------------------------------------------------------------------------------------
643
  neorv32_wishbone_inst_true:
644 44 zero_gravi
  if (MEM_EXT_EN = true) generate
645 2 zero_gravi
    neorv32_wishbone_inst: neorv32_wishbone
646
    generic map (
647 45 zero_gravi
      WB_PIPELINED_MODE => wb_pipe_mode_c,    -- false: classic/standard wishbone mode, true: pipelined wishbone mode
648 23 zero_gravi
      -- Internal instruction memory --
649 45 zero_gravi
      MEM_INT_IMEM_EN   => MEM_INT_IMEM_EN,   -- implement processor-internal instruction memory
650
      MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
651 23 zero_gravi
      -- Internal data memory --
652 45 zero_gravi
      MEM_INT_DMEM_EN   => MEM_INT_DMEM_EN,   -- implement processor-internal data memory
653
      MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE  -- size of processor-internal data memory in bytes
654 2 zero_gravi
    )
655
    port map (
656
      -- global control --
657 39 zero_gravi
      clk_i     => clk_i,          -- global clock line
658
      rstn_i    => sys_rstn,       -- global reset line, low-active
659 2 zero_gravi
      -- host access --
660 39 zero_gravi
      src_i     => p_bus.src,      -- access type (0: data, 1:instruction)
661
      addr_i    => p_bus.addr,     -- address
662
      rden_i    => p_bus.re,       -- read enable
663
      wren_i    => p_bus.we,       -- write enable
664
      ben_i     => p_bus.ben,      -- byte write enable
665
      data_i    => p_bus.wdata,    -- data in
666
      data_o    => wishbone_rdata, -- data out
667
      cancel_i  => p_bus.cancel,   -- cancel current transaction
668
      lock_i    => p_bus.lock,     -- locked/exclusive bus access
669
      ack_o     => wishbone_ack,   -- transfer acknowledge
670
      err_o     => wishbone_err,   -- transfer error
671
      priv_i    => p_bus.priv,     -- current CPU privilege level
672 2 zero_gravi
      -- wishbone interface --
673 39 zero_gravi
      wb_tag_o  => wb_tag_o,       -- tag
674
      wb_adr_o  => wb_adr_o,       -- address
675
      wb_dat_i  => wb_dat_i,       -- read data
676
      wb_dat_o  => wb_dat_o,       -- write data
677
      wb_we_o   => wb_we_o,        -- read/write
678
      wb_sel_o  => wb_sel_o,       -- byte enable
679
      wb_stb_o  => wb_stb_o,       -- strobe
680
      wb_cyc_o  => wb_cyc_o,       -- valid cycle
681
      wb_lock_o => wb_lock_o,      -- locked/exclusive bus access
682
      wb_ack_i  => wb_ack_i,       -- transfer acknowledge
683
      wb_err_i  => wb_err_i        -- transfer error
684 2 zero_gravi
    );
685
  end generate;
686
 
687
  neorv32_wishbone_inst_false:
688 44 zero_gravi
  if (MEM_EXT_EN = false) generate
689 2 zero_gravi
    wishbone_rdata <= (others => '0');
690
    wishbone_ack   <= '0';
691
    wishbone_err   <= '0';
692
    --
693 39 zero_gravi
    wb_adr_o  <= (others => '0');
694
    wb_dat_o  <= (others => '0');
695
    wb_we_o   <= '0';
696
    wb_sel_o  <= (others => '0');
697
    wb_stb_o  <= '0';
698
    wb_cyc_o  <= '0';
699
    wb_lock_o <= '0';
700
    wb_tag_o  <= (others => '0');
701 2 zero_gravi
  end generate;
702
 
703
 
704
  -- IO Access? -----------------------------------------------------------------------------
705
  -- -------------------------------------------------------------------------------------------
706 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';
707 40 zero_gravi
  io_rden <= io_acc and p_bus.re and (not p_bus.src); -- PMA: no_execute for IO region
708 47 zero_gravi
  -- the default NEORV32 peripheral/IO devices in the IO area can only be written in word mode (reduces HW complexity)
709
  io_wren <= io_acc and p_bus.we and and_all_f(p_bus.ben) and (not p_bus.src); -- PMA: write32 only, no_execute for IO region
710 2 zero_gravi
 
711
 
712 47 zero_gravi
  -- Custom Functions Subsystem (CFS) -------------------------------------------------------
713
  -- -------------------------------------------------------------------------------------------
714
  neorv32_cfs_inst_true:
715
  if (IO_CFS_EN = true) generate
716
    neorv32_cfs_inst: neorv32_cfs
717
    generic map (
718
      CFS_CONFIG => IO_CFS_CONFIG     -- custom CFS configuration generic
719
    )
720
    port map (
721
      -- host access --
722
      clk_i       => clk_i,           -- global clock line
723
      rstn_i      => sys_rstn,        -- global reset line, low-active, use as async
724
      addr_i      => p_bus.addr,      -- address
725
      rden_i      => io_rden,         -- read enable
726
      wren_i      => io_wren,         -- byte write enable
727
      data_i      => p_bus.wdata,     -- data in
728
      data_o      => cfs_rdata,       -- data out
729
      ack_o       => cfs_ack,         -- transfer acknowledge
730
      err_o       => cfs_err,         -- transfer error
731
      -- clock generator --
732
      clkgen_en_o => cfs_cg_en,       -- enable clock generator
733
      clkgen_i    => clk_gen,         -- "clock" inputs
734
      -- CPU state --
735
      sleep_i     => cpu_sleep,       -- set if cpu is in sleep mode
736
      -- interrupt --
737
      irq_o       => cfs_irq,         -- interrupt request
738 48 zero_gravi
      irq_ack_i   => cfs_irq_ack,     -- interrupt acknowledge
739 47 zero_gravi
      -- custom io (conduit) --
740
      cfs_in_i    => cfs_in_i,        -- custom inputs
741
      cfs_out_o   => cfs_out_o        -- custom outputs
742
    );
743
  end generate;
744
 
745
  neorv32_cfs_inst_false:
746
  if (IO_CFS_EN = false) generate
747
    cfs_rdata <= (others => '0');
748
    cfs_ack   <= '0';
749
    cfs_err   <= '0';
750
    cfs_cg_en <= '0';
751
    cfs_irq   <= '0';
752
    cfs_out_o <= (others => '0');
753
  end generate;
754
 
755
 
756 2 zero_gravi
  -- General Purpose Input/Output Port (GPIO) -----------------------------------------------
757
  -- -------------------------------------------------------------------------------------------
758
  neorv32_gpio_inst_true:
759 44 zero_gravi
  if (IO_GPIO_EN = true) generate
760 2 zero_gravi
    neorv32_gpio_inst: neorv32_gpio
761
    port map (
762
      -- host access --
763 12 zero_gravi
      clk_i  => clk_i,       -- global clock line
764
      addr_i => p_bus.addr,  -- address
765
      rden_i => io_rden,     -- read enable
766
      wren_i => io_wren,     -- write enable
767
      data_i => p_bus.wdata, -- data in
768
      data_o => gpio_rdata,  -- data out
769
      ack_o  => gpio_ack,    -- transfer acknowledge
770 2 zero_gravi
      -- parallel io --
771
      gpio_o => gpio_o,
772
      gpio_i => gpio_i,
773
      -- interrupt --
774 12 zero_gravi
      irq_o  => gpio_irq     -- pin-change interrupt
775 2 zero_gravi
    );
776
  end generate;
777
 
778
  neorv32_gpio_inst_false:
779 44 zero_gravi
  if (IO_GPIO_EN = false) generate
780 2 zero_gravi
    gpio_rdata <= (others => '0');
781
    gpio_ack   <= '0';
782
    gpio_o     <= (others => '0');
783
    gpio_irq   <= '0';
784
  end generate;
785
 
786
 
787
  -- Watch Dog Timer (WDT) ------------------------------------------------------------------
788
  -- -------------------------------------------------------------------------------------------
789
  neorv32_wdt_inst_true:
790 44 zero_gravi
  if (IO_WDT_EN = true) generate
791 2 zero_gravi
    neorv32_wdt_inst: neorv32_wdt
792
    port map (
793
      -- host access --
794 12 zero_gravi
      clk_i       => clk_i,       -- global clock line
795
      rstn_i      => ext_rstn,    -- global reset line, low-active
796
      rden_i      => io_rden,     -- read enable
797
      wren_i      => io_wren,     -- write enable
798
      addr_i      => p_bus.addr,  -- address
799
      data_i      => p_bus.wdata, -- data in
800
      data_o      => wdt_rdata,   -- data out
801
      ack_o       => wdt_ack,     -- transfer acknowledge
802 2 zero_gravi
      -- clock generator --
803 12 zero_gravi
      clkgen_en_o => wdt_cg_en,   -- enable clock generator
804 2 zero_gravi
      clkgen_i    => clk_gen,
805
      -- timeout event --
806 12 zero_gravi
      irq_o       => wdt_irq,     -- timeout IRQ
807
      rstn_o      => wdt_rstn     -- timeout reset, low_active, use it as async!
808 2 zero_gravi
    );
809
  end generate;
810
 
811
  neorv32_wdt_inst_false:
812 44 zero_gravi
  if (IO_WDT_EN = false) generate
813 2 zero_gravi
    wdt_rdata <= (others => '0');
814
    wdt_ack   <= '0';
815
    wdt_irq   <= '0';
816
    wdt_rstn  <= '1';
817
    wdt_cg_en <= '0';
818
  end generate;
819
 
820
 
821
  -- Machine System Timer (MTIME) -----------------------------------------------------------
822
  -- -------------------------------------------------------------------------------------------
823
  neorv32_mtime_inst_true:
824 44 zero_gravi
  if (IO_MTIME_EN = true) generate
825 2 zero_gravi
    neorv32_mtime_inst: neorv32_mtime
826
    port map (
827
      -- host access --
828 12 zero_gravi
      clk_i     => clk_i,       -- global clock line
829
      rstn_i    => sys_rstn,    -- global reset, low-active, async
830
      addr_i    => p_bus.addr,  -- address
831
      rden_i    => io_rden,     -- read enable
832
      wren_i    => io_wren,     -- write enable
833
      data_i    => p_bus.wdata, -- data in
834
      data_o    => mtime_rdata, -- data out
835
      ack_o     => mtime_ack,   -- transfer acknowledge
836 11 zero_gravi
      -- time output for CPU --
837 12 zero_gravi
      time_o    => mtime_time,  -- current system time
838 2 zero_gravi
      -- interrupt --
839 12 zero_gravi
      irq_o     => mtime_irq    -- interrupt request
840 2 zero_gravi
    );
841
  end generate;
842
 
843
  neorv32_mtime_inst_false:
844 44 zero_gravi
  if (IO_MTIME_EN = false) generate
845 2 zero_gravi
    mtime_rdata <= (others => '0');
846 40 zero_gravi
    mtime_time  <= mtime_i; -- use external machine timer time signal
847 2 zero_gravi
    mtime_ack   <= '0';
848 34 zero_gravi
    mtime_irq   <= mtime_irq_i; -- use external machine timer interrupt
849 2 zero_gravi
  end generate;
850
 
851
 
852
  -- Universal Asynchronous Receiver/Transmitter (UART) -------------------------------------
853
  -- -------------------------------------------------------------------------------------------
854
  neorv32_uart_inst_true:
855 44 zero_gravi
  if (IO_UART_EN = true) generate
856 2 zero_gravi
    neorv32_uart_inst: neorv32_uart
857
    port map (
858
      -- host access --
859 48 zero_gravi
      clk_i       => clk_i,        -- global clock line
860
      addr_i      => p_bus.addr,   -- address
861
      rden_i      => io_rden,      -- read enable
862
      wren_i      => io_wren,      -- write enable
863
      data_i      => p_bus.wdata,  -- data in
864
      data_o      => uart_rdata,   -- data out
865
      ack_o       => uart_ack,     -- transfer acknowledge
866 2 zero_gravi
      -- clock generator --
867 48 zero_gravi
      clkgen_en_o => uart_cg_en,   -- enable clock generator
868 2 zero_gravi
      clkgen_i    => clk_gen,
869
      -- com lines --
870
      uart_txd_o  => uart_txd_o,
871
      uart_rxd_i  => uart_rxd_i,
872
      -- interrupts --
873 48 zero_gravi
      irq_rxd_o   => uart_rxd_irq, -- uart data received interrupt
874
      irq_txd_o   => uart_txd_irq  -- uart transmission done interrupt
875 2 zero_gravi
    );
876
  end generate;
877
 
878
  neorv32_uart_inst_false:
879 44 zero_gravi
  if (IO_UART_EN = false) generate
880 48 zero_gravi
    uart_rdata   <= (others => '0');
881
    uart_ack     <= '0';
882
    uart_txd_o   <= '0';
883
    uart_cg_en   <= '0';
884
    uart_rxd_irq <= '0';
885
    uart_txd_irq <= '0';
886 2 zero_gravi
  end generate;
887
 
888
 
889
  -- Serial Peripheral Interface (SPI) ------------------------------------------------------
890
  -- -------------------------------------------------------------------------------------------
891
  neorv32_spi_inst_true:
892 44 zero_gravi
  if (IO_SPI_EN = true) generate
893 2 zero_gravi
    neorv32_spi_inst: neorv32_spi
894
    port map (
895
      -- host access --
896 12 zero_gravi
      clk_i       => clk_i,       -- global clock line
897
      addr_i      => p_bus.addr,  -- address
898
      rden_i      => io_rden,     -- read enable
899
      wren_i      => io_wren,     -- write enable
900
      data_i      => p_bus.wdata, -- data in
901
      data_o      => spi_rdata,   -- data out
902
      ack_o       => spi_ack,     -- transfer acknowledge
903 2 zero_gravi
      -- clock generator --
904 12 zero_gravi
      clkgen_en_o => spi_cg_en,   -- enable clock generator
905 2 zero_gravi
      clkgen_i    => clk_gen,
906
      -- com lines --
907 12 zero_gravi
      spi_sck_o   => spi_sck_o,   -- SPI serial clock
908
      spi_sdo_o   => spi_sdo_o,   -- controller data out, peripheral data in
909
      spi_sdi_i   => spi_sdi_i,   -- controller data in, peripheral data out
910
      spi_csn_o   => spi_csn_o,   -- SPI CS
911 2 zero_gravi
      -- interrupt --
912 48 zero_gravi
      irq_o       => spi_irq      -- transmission done interrupt
913 2 zero_gravi
    );
914
  end generate;
915
 
916
  neorv32_spi_inst_false:
917 44 zero_gravi
  if (IO_SPI_EN = false) generate
918 2 zero_gravi
    spi_rdata  <= (others => '0');
919
    spi_ack    <= '0';
920 6 zero_gravi
    spi_sck_o  <= '0';
921
    spi_sdo_o  <= '0';
922 2 zero_gravi
    spi_csn_o  <= (others => '1'); -- CSn lines are low-active
923
    spi_cg_en  <= '0';
924
    spi_irq    <= '0';
925
  end generate;
926
 
927
 
928
  -- Two-Wire Interface (TWI) ---------------------------------------------------------------
929
  -- -------------------------------------------------------------------------------------------
930
  neorv32_twi_inst_true:
931 44 zero_gravi
  if (IO_TWI_EN = true) generate
932 2 zero_gravi
    neorv32_twi_inst: neorv32_twi
933
    port map (
934
      -- host access --
935 12 zero_gravi
      clk_i       => clk_i,       -- global clock line
936
      addr_i      => p_bus.addr,  -- address
937
      rden_i      => io_rden,     -- read enable
938
      wren_i      => io_wren,     -- write enable
939
      data_i      => p_bus.wdata, -- data in
940
      data_o      => twi_rdata,   -- data out
941
      ack_o       => twi_ack,     -- transfer acknowledge
942 2 zero_gravi
      -- clock generator --
943 12 zero_gravi
      clkgen_en_o => twi_cg_en,   -- enable clock generator
944 2 zero_gravi
      clkgen_i    => clk_gen,
945
      -- com lines --
946 12 zero_gravi
      twi_sda_io  => twi_sda_io,  -- serial data line
947
      twi_scl_io  => twi_scl_io,  -- serial clock line
948 2 zero_gravi
      -- interrupt --
949 48 zero_gravi
      irq_o       => twi_irq      -- transfer done IRQ
950 2 zero_gravi
    );
951
  end generate;
952
 
953
  neorv32_twi_inst_false:
954 44 zero_gravi
  if (IO_TWI_EN = false) generate
955 2 zero_gravi
    twi_rdata  <= (others => '0');
956
    twi_ack    <= '0';
957 35 zero_gravi
--  twi_sda_io <= 'Z';
958
--  twi_scl_io <= 'Z';
959 2 zero_gravi
    twi_cg_en  <= '0';
960
    twi_irq    <= '0';
961
  end generate;
962
 
963
 
964
  -- Pulse-Width Modulation Controller (PWM) ------------------------------------------------
965
  -- -------------------------------------------------------------------------------------------
966
  neorv32_pwm_inst_true:
967 44 zero_gravi
  if (IO_PWM_EN = true) generate
968 2 zero_gravi
    neorv32_pwm_inst: neorv32_pwm
969
    port map (
970
      -- host access --
971 12 zero_gravi
      clk_i       => clk_i,       -- global clock line
972
      addr_i      => p_bus.addr,  -- address
973
      rden_i      => io_rden,     -- read enable
974
      wren_i      => io_wren,     -- write enable
975
      data_i      => p_bus.wdata, -- data in
976
      data_o      => pwm_rdata,   -- data out
977
      ack_o       => pwm_ack,     -- transfer acknowledge
978 2 zero_gravi
      -- clock generator --
979 12 zero_gravi
      clkgen_en_o => pwm_cg_en,   -- enable clock generator
980 2 zero_gravi
      clkgen_i    => clk_gen,
981
      -- pwm output channels --
982
      pwm_o       => pwm_o
983
    );
984
  end generate;
985
 
986
  neorv32_pwm_inst_false:
987 44 zero_gravi
  if (IO_PWM_EN = false) generate
988 2 zero_gravi
    pwm_rdata <= (others => '0');
989
    pwm_ack   <= '0';
990
    pwm_cg_en <= '0';
991
    pwm_o     <= (others => '0');
992
  end generate;
993
 
994
 
995
  -- True Random Number Generator (TRNG) ----------------------------------------------------
996
  -- -------------------------------------------------------------------------------------------
997
  neorv32_trng_inst_true:
998 44 zero_gravi
  if (IO_TRNG_EN = true) generate
999 2 zero_gravi
    neorv32_trng_inst: neorv32_trng
1000
    port map (
1001
      -- host access --
1002 12 zero_gravi
      clk_i  => clk_i,       -- global clock line
1003
      addr_i => p_bus.addr,  -- address
1004
      rden_i => io_rden,     -- read enable
1005
      wren_i => io_wren,     -- write enable
1006
      data_i => p_bus.wdata, -- data in
1007
      data_o => trng_rdata,  -- data out
1008
      ack_o  => trng_ack     -- transfer acknowledge
1009 2 zero_gravi
    );
1010
  end generate;
1011
 
1012
  neorv32_trng_inst_false:
1013 44 zero_gravi
  if (IO_TRNG_EN = false) generate
1014 2 zero_gravi
    trng_rdata <= (others => '0');
1015
    trng_ack   <= '0';
1016
  end generate;
1017
 
1018
 
1019 12 zero_gravi
  -- System Configuration Information Memory (SYSINFO) --------------------------------------
1020
  -- -------------------------------------------------------------------------------------------
1021
  neorv32_sysinfo_inst: neorv32_sysinfo
1022
  generic map (
1023
    -- General --
1024 45 zero_gravi
    CLOCK_FREQUENCY      => CLOCK_FREQUENCY,      -- clock frequency of clk_i in Hz
1025
    BOOTLOADER_EN        => BOOTLOADER_EN,        -- implement processor-internal bootloader?
1026
    USER_CODE            => USER_CODE,            -- custom user code
1027 23 zero_gravi
    -- internal Instruction memory --
1028 45 zero_gravi
    MEM_INT_IMEM_EN      => MEM_INT_IMEM_EN,      -- implement processor-internal instruction memory
1029
    MEM_INT_IMEM_SIZE    => MEM_INT_IMEM_SIZE,    -- size of processor-internal instruction memory in bytes
1030
    MEM_INT_IMEM_ROM     => MEM_INT_IMEM_ROM,     -- implement processor-internal instruction memory as ROM
1031 23 zero_gravi
    -- Internal Data memory --
1032 45 zero_gravi
    MEM_INT_DMEM_EN      => MEM_INT_DMEM_EN,      -- implement processor-internal data memory
1033
    MEM_INT_DMEM_SIZE    => MEM_INT_DMEM_SIZE,    -- size of processor-internal data memory in bytes
1034 41 zero_gravi
    -- Internal Cache memory --
1035 45 zero_gravi
    ICACHE_EN            => ICACHE_EN,            -- implement instruction cache
1036
    ICACHE_NUM_BLOCKS    => ICACHE_NUM_BLOCKS,    -- i-cache: number of blocks (min 2), has to be a power of 2
1037
    ICACHE_BLOCK_SIZE    => ICACHE_BLOCK_SIZE,    -- i-cache: block size in bytes (min 4), has to be a power of 2
1038
    ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity (min 1), has to be a power 2
1039 23 zero_gravi
    -- External memory interface --
1040 45 zero_gravi
    MEM_EXT_EN           => MEM_EXT_EN,           -- implement external memory bus interface?
1041 12 zero_gravi
    -- Processor peripherals --
1042 45 zero_gravi
    IO_GPIO_EN           => IO_GPIO_EN,           -- implement general purpose input/output port unit (GPIO)?
1043
    IO_MTIME_EN          => IO_MTIME_EN,          -- implement machine system timer (MTIME)?
1044
    IO_UART_EN           => IO_UART_EN,           -- implement universal asynchronous receiver/transmitter (UART)?
1045
    IO_SPI_EN            => IO_SPI_EN,            -- implement serial peripheral interface (SPI)?
1046
    IO_TWI_EN            => IO_TWI_EN,            -- implement two-wire interface (TWI)?
1047
    IO_PWM_EN            => IO_PWM_EN,            -- implement pulse-width modulation unit (PWM)?
1048
    IO_WDT_EN            => IO_WDT_EN,            -- implement watch dog timer (WDT)?
1049
    IO_TRNG_EN           => IO_TRNG_EN,           -- implement true random number generator (TRNG)?
1050 47 zero_gravi
    IO_CFS_EN            => IO_CFS_EN             -- implement custom functions subsystem (CFS)?
1051 12 zero_gravi
  )
1052
  port map (
1053
    -- host access --
1054
    clk_i  => clk_i,         -- global clock line
1055
    addr_i => p_bus.addr,    -- address
1056
    rden_i => io_rden,       -- read enable
1057
    data_o => sysinfo_rdata, -- data out
1058
    ack_o  => sysinfo_ack    -- transfer acknowledge
1059
  );
1060
 
1061
 
1062 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.