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

Subversion Repositories neorv32

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

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