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

Subversion Repositories neorv32

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

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