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

Subversion Repositories neorv32

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

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