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

Subversion Repositories rv01_riscv_core

[/] [rv01_riscv_core/] [trunk/] [VHDL/] [RV01_top.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 madsilicon
-----------------------------------------------------------------
2
--                                                             --
3
-----------------------------------------------------------------
4
--                                                             --
5
-- Copyright (C) 2015 Stefano Tonello                          --
6
--                                                             --
7
-- This source file may be used and distributed without        --
8
-- restriction provided that this copyright statement is not   --
9
-- removed from the file and that any derivative work contains --
10
-- the original copyright notice and the associated disclaimer.--
11
--                                                             --
12
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY         --
13
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   --
14
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   --
15
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      --
16
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         --
17
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    --
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   --
19
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        --
20
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  --
21
-- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  --
22
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  --
23
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         --
24
-- POSSIBILITY OF SUCH DAMAGE.                                 --
25
--                                                             --
26
-----------------------------------------------------------------
27
 
28
---------------------------------------------------------------
29
-- RV01 top-level module
30
---------------------------------------------------------------
31
 
32
library IEEE;
33
use IEEE.std_logic_1164.all;
34
use IEEE.numeric_std.all;
35
use STD.textio.all;
36
 
37
library WORK;
38
use work.RV01_CONSTS_PKG.all;
39
use work.RV01_TYPES_PKG.all;
40
use work.RV01_FUNCS_PKG.all;
41
use work.RV01_PLIC_PKG.all;
42
 
43
entity RV01_TOP is
44
  generic(
45
    -- synthesis translate_off
46
    ST_FILE : string := "NONE";
47
    WB_FILE : string := "NONE";
48
    -- synthesis translate_on
49
    IMEM_SIZE : natural := 1024*32; -- 128Kb
50
    DMEM_SIZE : natural := 1024*16; -- 64Kb
51
    IOMEM_SIZE : natural := 1024; -- 4Kb
52
    IMEM_SIZE_PO2 : std_logic := '1';
53
    DMEM_SIZE_PO2 : std_logic := '1';
54
    IMEM_LOWM : std_logic := '1';
55
    BHT_SIZE : natural := 256;
56
    EI_SRC_CNT : natural := 8;
57
    EI_TRIG_TYPE : PLIC_TRIG_TYPE := LEVEL;
58
    EI_REQ_MAXCNT : natural := 16;
59
    CFG_FLAGS : std_logic_vector(16-1 downto 0) := "00000000"&"01100111";
60
    SIMULATION_ONLY : std_logic := '0'
61
  );
62
  port(
63
    CLK_i : in std_logic; -- clock
64
    RST_i : in std_logic; -- reset
65
    CHK_ENB_i : in std_logic; -- check-enable
66
    -- External Interrupt Request
67
    EI_REQ_i : std_logic_vector(EI_SRC_CNT-1 downto 0);
68
    -- Host interface
69
    MFROMHOST_WE_i : in std_logic; -- MFROMHOST write-enable
70
    MFROMHOST_i : in std_logic_vector(SDLEN-1 downto 0); -- MFROMHOST data-in
71
    -- Data port
72
    DP_WE_i : in std_logic; -- DP write-enable
73
    DP_ADR_i : in std_logic_vector(ALEN-1 downto 0); -- DP address
74
    DP_DAT_i : in std_logic_vector(SDLEN-1 downto 0); -- DP data-in
75
    -- Control port
76
    CP_RE_i : in std_logic; -- CP read-enable
77
    CP_WE_i : in std_logic; -- CP write-enable
78
    CP_ADR_i : in std_logic_vector(17-1 downto 0); -- CP address
79
    CP_DAT_i : in std_logic_vector(SDLEN-1 downto 0); -- CP data-in
80
 
81
    -- Host interface
82
    MTOHOST_OE_o : out std_logic; -- MTOHOST output-enable
83
    MTOHOST_o : out std_logic_vector(SDLEN-1 downto 0); -- MTOHOST data-out
84
    -- Data port
85
    DP_DAT_o : out std_logic_vector(SDLEN-1 downto 0); -- DP data-out
86
    -- Control port
87
    CP_DAT_o : out std_logic_vector(SDLEN-1 downto 0) -- CP data-out
88
  );
89
end RV01_TOP;
90
 
91
architecture ARC of RV01_TOP is
92
 
93
  constant L2IMEM_SIZE : natural := log2(IMEM_SIZE);
94
  constant L2DMEM_SIZE : natural := log2(DMEM_SIZE);
95
  constant L2IOMEM_SIZE : natural := log2(DMEM_SIZE);
96
 
97
  constant PARALLEL_EXECUTION_ENABLED : std_logic := CFG_FLAGS(0);
98
  constant PLIC_PRESENT : std_logic := CFG_FLAGS(6);
99
 
100
  constant PLIC_ABASE : natural := DMEM_SIZE;
101
  constant PLIC_AWIDTH : natural := log2(EI_SRC_CNT+3);
102
  constant PLIC_AMAX : natural := ((EI_SRC_CNT+3)-1);
103
 
104
  component RV01_CPU_2W is
105
    generic(
106
      -- synthesis translate_off
107
      ST_FILENAME : string := "NONE";
108
      WB_FILENAME : string := "NONE";
109
      -- synthesis translate_on
110
      IMEM_SIZE : natural := 1024*32; -- 128Kb
111
      DMEM_SIZE : natural := 1024*16; -- 64Kb
112
      IMEM_LOWM : std_logic := '1';
113
      BHT_SIZE : natural := 256;
114
      CFG_FLAGS : std_logic_vector(16-1 downto 0) := "00000000"&"01100111";
115
      SIMULATION_ONLY : std_logic := '1'
116
    );
117
    port(
118
      CLK_i : in std_logic;
119
      RST_i : in std_logic;
120
      -- instruction memory interface
121
      INSTR_i : in std_logic_vector(ILEN*2-1 downto 0);
122
      -- data memory interface
123
      DDAT0_i : in std_logic_vector(SDLEN-1 downto 0);
124
      DDAT1_i : in std_logic_vector(SDLEN-1 downto 0);
125
      IADR_ERR_i : in std_logic;
126
      DADR0_ERR_i : in std_logic;
127
      DADR1_ERR_i : in std_logic;
128
      IDADR_CFLT_i : in std_logic;
129
      -- check-enable (simulation-only)
130
      CHK_ENB_i : in std_logic;
131
      -- External Interrupt (from PLIC)
132
      EXT_INT_i : in std_logic;
133
      -- Host interface
134
      MFROMHOST_WE_i : in std_logic;
135
      MFROMHOST_i : in std_logic_vector(SDLEN-1 downto 0);
136
      -- Control port
137
      CP_RE_i : in std_logic;
138
      CP_WE_i : in std_logic;
139
      CP_ADR_i : in std_logic_vector(17-1 downto 0);
140
      CP_D_i : in std_logic_vector(SDLEN-1 downto 0);
141
 
142
      HALT_o : out std_logic;
143
      -- instruction memory interface
144
      IADR_o : out unsigned(ALEN-1 downto 0);
145
      -- data memory interface
146
      DRE_o : out std_logic_vector(2-1 downto 0);
147
      DBE_o : out std_logic_vector(4-1 downto 0);
148
      DWE0_o : out std_logic;
149
      DADR0_o : out unsigned(ALEN-1 downto 0);
150
      DADR1_o : out unsigned(ALEN-1 downto 0);
151
      DIADR0_o : out unsigned(ALEN-1 downto 0);
152
      DIADR1_o : out unsigned(ALEN-1 downto 0);
153
      DIMS_o : out std_logic_vector(2-1 downto 0);
154
      DDAT0_o : out std_logic_vector(SDLEN-1 downto 0);
155
      -- Host interface
156
      MTOHOST_OE_o : out std_logic;
157
      MTOHOST_o : out std_logic_vector(SDLEN-1 downto 0);
158
      -- Control port
159
      CP_Q_o : out std_logic_vector(SDLEN-1 downto 0)
160
    );
161
  end component;
162
 
163
  component RV01_PLIC is
164
    generic(
165
      SRC_CNT : natural := 8;
166
      TRIG_TYPE : PLIC_TRIG_TYPE := LEVEL;
167
      REQ_MAXCNT : natural := 16
168
    );
169
    port(
170
      CLK_i : in std_logic;
171
      RST_i : in std_logic;
172
      REG_A_i : in std_logic_vector(log2(SRC_CNT+1)-1 downto 0);
173
      REG_WE_i : in std_logic;
174
      REG_D_i : in std_logic_vector(SDLEN-1 downto 0);
175
      REQ_i : in std_logic_vector(SRC_CNT-1 downto 0);
176
 
177
      REG_Q_o : out std_logic_vector(SDLEN-1 downto 0);
178
      EIP_o : out std_logic
179
    );
180
  end component;
181
 
182
  component RV01_RAM_1RW1R_BE is
183
    generic(
184
      -- I/O data bus width
185
      DWIDTH : integer := 16;
186
      -- word count
187
      WCOUNT : integer := 256
188
    );
189
    port(
190
      CLK_i : in std_logic;
191
      A_i : in unsigned(log2(WCOUNT)-1 downto 0);
192
      DPRA_i : in unsigned(log2(WCOUNT)-1 downto 0);
193
      D_i : in std_logic_vector(DWIDTH-1 downto 0);
194
      BE_i : in std_logic_vector(DWIDTH/8-1 downto 0);
195
      WE_i : in std_logic;
196
 
197
      Q_o : out std_logic_vector(DWIDTH-1 downto 0);
198
      DPQ_o : out std_logic_vector(DWIDTH-1 downto 0)
199
    );
200
  end component;
201
 
202
  component RV01_RAM_1RW_BE is
203
    generic(
204
      -- I/O data bus width
205
      DWIDTH : integer := 16;
206
      -- word count
207
      WCOUNT : integer := 256
208
    );
209
    port(
210
      CLK_i : in std_logic;
211
      A_i : in unsigned(log2(WCOUNT)-1 downto 0);
212
      D_i : in std_logic_vector(DWIDTH-1 downto 0);
213
      BE_i : in std_logic_vector(DWIDTH/8-1 downto 0);
214
      WE_i : in std_logic;
215
 
216
      Q_o : out std_logic_vector(DWIDTH-1 downto 0)
217
    );
218
  end component;
219
 
220
  signal HALT : std_logic;
221
  signal EXT_INT : std_logic;
222
  signal INSTR : std_logic_vector(ILEN*2-1 downto 0);
223
  signal DDATI0 : std_logic_vector(SDLEN-1 downto 0);
224
  signal DDATI1 : std_logic_vector(SDLEN-1 downto 0);
225
  signal IWE0 : std_logic;
226
  signal IADR0 : unsigned(ALEN-1 downto 0);
227
  signal IADR1 : unsigned(ALEN-1 downto 0);
228
  signal IBE : std_logic_vector(4-1 downto 0);
229
  signal IDATI : std_logic_vector(ILEN-1 downto 0);
230
  signal DWE0 : std_logic;
231
  signal DBE : std_logic_vector(4-1 downto 0);
232
  signal DRE : std_logic_vector(2-1 downto 0);
233
  signal DADR0 : unsigned(ALEN-1 downto 0);
234
  signal DADR1 : unsigned(ALEN-1 downto 0);
235
  signal DIADR0 : unsigned(ALEN-1 downto 0);
236
  signal DIADR1 : unsigned(ALEN-1 downto 0);
237
  signal DIMS,DIMS_q : std_logic_vector(2-1 downto 0);
238
  signal DDATO : std_logic_vector(SDLEN-1 downto 0);
239
 
240
  signal IWE0_RAM : std_logic;
241
  signal IADR0_RAM : unsigned(log2(IMEM_SIZE)-1 downto 0);
242
  signal IADR1_RAM : unsigned(log2(IMEM_SIZE)-1 downto 0);
243
  signal IADR0_RAM_PX : unsigned(log2(IMEM_SIZE)-2 downto 0);
244
  signal IADR1_RAM_PX : unsigned(log2(IMEM_SIZE)-2 downto 0);
245
  signal IBE0_RAM : std_logic_vector(8-1 downto 0);
246
  signal IDATI_RAM : std_logic_vector(ILEN*2-1 downto 0);
247
  signal DWE0_RAM : std_logic;
248
  signal DADR0_RAM : unsigned(log2(DMEM_SIZE)-1 downto 0);
249
  signal DADR1_RAM : unsigned(log2(DMEM_SIZE)-1 downto 0);
250
  signal DDATI0_RAM : std_logic_vector(SDLEN-1 downto 0);
251
  signal DDATI1_RAM : std_logic_vector(SDLEN-1 downto 0);
252
  signal DBE_RAM : std_logic_vector(4-1 downto 0);
253
 
254
  signal IDI_RAM : std_logic_vector(ILEN*2-1 downto 0);
255
  signal DDI_RAM : std_logic_vector(SDLEN-1 downto 0);
256
 
257
  signal DP_ADR_MS : std_logic;
258
  signal DP_ADR_MS_q : std_logic;
259
  signal DP_IADR : unsigned(ALEN-1 downto 0);
260
  signal DP_DADR : unsigned(ALEN-1 downto 0);
261
  signal DP_IOADR_MS : std_logic;
262
  signal DP_IOADR_MS_q : std_logic;
263
  signal DP_IOADR : unsigned(ALEN-1 downto 0);
264
 
265
  signal IADR_ERR,IADR_ERR_q : std_logic;
266
  signal DADR0_ERR,DADR0_ERR_q : std_logic;
267
  signal DADR1_ERR,DADR1_ERR_q : std_logic;
268
  signal IDADR_CFLT : std_logic;
269
  signal IADR0_RAM_WS,IADR0_RAM_WS_q : std_logic;
270
 
271
  signal IOMS : std_logic_vector(2-1 downto 0);
272
  signal IOMS_q : std_logic_vector(2-1 downto 0);
273
  signal DADR_IO : unsigned(ALEN-1 downto 0);
274
  signal DWE_IO : std_logic;
275
  signal DDATI_IO : std_logic_vector(SDLEN-1 downto 0);
276
  signal DDATO_IO : std_logic_vector(SDLEN-1 downto 0);
277
 
278
  signal DADR_PLIC : std_logic_vector(PLIC_AWIDTH-1 downto 0);
279
  signal DWE_PLIC : std_logic;
280
  signal DDATI_PLIC : std_logic_vector(SDLEN-1 downto 0);
281
  signal DDATO_PLIC : std_logic_vector(SDLEN-1 downto 0);
282
 
283
begin
284
 
285
  ---------------------------------------------------
286
  -- CPU module
287
  ---------------------------------------------------
288
 
289
  U_CPU : RV01_CPU_2W
290
    generic map(
291
      -- synthesis translate_off
292
      ST_FILENAME => ST_FILE,
293
      WB_FILENAME => WB_FILE,
294
      -- synthesis translate_on
295
      IMEM_SIZE => IMEM_SIZE,
296
      DMEM_SIZE => DMEM_SIZE,
297
      IMEM_LOWM => IMEM_LOWM,
298
      BHT_SIZE => BHT_SIZE,
299
      CFG_FLAGS => CFG_FLAGS,
300
      SIMULATION_ONLY => SIMULATION_ONLY
301
    )
302
    port map(
303
      CLK_i => CLK_i,
304
      RST_i => RST_i,
305
      INSTR_i => INSTR,
306
      DDAT0_i => DDATI0,
307
      DDAT1_i => DDATI1,
308
      IADR_ERR_i => IADR_ERR_q,
309
      DADR0_ERR_i => DADR0_ERR_q,
310
      DADR1_ERR_i => DADR1_ERR_q,
311
      IDADR_CFLT_i => IDADR_CFLT,
312
      --
313
      CHK_ENB_i => CHK_ENB_i,
314
      --
315
      EXT_INT_i => EXT_INT,
316
      --
317
      MFROMHOST_WE_i => MFROMHOST_WE_i,
318
      MFROMHOST_i => MFROMHOST_i,
319
      -- 
320
      CP_RE_i => CP_RE_i,
321
      CP_WE_i => CP_WE_i,
322
      CP_ADR_i => CP_ADR_i,
323
      CP_D_i => CP_DAT_i,
324
 
325
      HALT_o => HALT,
326
      -- IRE_o => IRE, -- to be added!
327
      IADR_o => IADR1,
328
      DRE_o => DRE,
329
      DBE_o => DBE,
330
      DWE0_o => DWE0,
331
      DADR0_o => DADR0,
332
      DADR1_o => DADR1,
333
      DIADR0_o => DIADR0,
334
      DIADR1_o => DIADR1,
335
      DIMS_o => DIMS,
336
      DDAT0_o => DDATO,
337
      --
338
      MTOHOST_OE_o => MTOHOST_OE_o,
339
      MTOHOST_o => MTOHOST_o,
340
      --
341
      CP_Q_o => CP_DAT_o
342
    );
343
 
344
  ---------------------------------------------------
345
  -- Address space
346
  ---------------------------------------------------
347
 
348
  -- if IMEM_LOWM = '1', instruction memory is located
349
  -- on lower portion of address space (starting from
350
  -- address zero), with data memory located above it
351
  -- (starting from address IMEM_SIZE).
352
  -- if IMEM_LOWM = '0', data memory is located
353
  -- on lower portion of address space (starting from
354
  -- address zero), with instruction memory located
355
  -- above it (starting from address DMEM_SIZE).
356
  -- I/O memory (when present) is treated as another
357
  -- type of data memory and is always located after
358
  -- instr. and data memory.
359
  -- From the exception processing point of view, I/O
360
  -- memory is treated a data one.
361
  -- I/O memory differs from instr. and data memories
362
  -- because:
363
  -- 1) it doesn't support concurrent access from CPU,
364
  -- and byte-write.
365
  -- 2) no check is performed that actual storage is
366
  -- available for a given address (e.g. reads from
367
  -- un-mapped addresses return garbage, without
368
  -- triggering any exception).
369
 
370
  ---------------------------------------------------
371
  -- Instruction/Data Memory Selection flags
372
  ---------------------------------------------------
373
 
374
  -- Instructions/data memory selection flags tell which
375
  -- type of RAM (instruction vs. data) is the target of
376
  -- a load/store instruction or a DP operation.
377
  -- For load/store instructions these flags are provided
378
  -- by CPU using DIMS_o output) while for DP operations
379
  -- selection flag is generated here.
380
 
381
  -- DP_ADR_MS selects between instruction and data memories.
382
  -- if DP_ADR_MS = '0', address belong to instr. memory,
383
  -- if DP_ADR_MS = '1', address belong to data memory.
384
  -- DP_IOADR_MS selects between I/O and data memory.
385
  -- if DP_IOADR_MS = '1', address belong to I/O memory,
386
  -- if DP_IOADR_MS = '0', address belong to true data memory.
387
 
388
  -- DP_ADR_MS | DP_IOADR_MS | mem. type
389
  --------------------------------------
390
  --         0 |           x | instr. memory
391
  --         1 |           0 | "true" data memory
392
  --         1 |           1 | I/O data memory
393
 
394
  GL1: if IMEM_LOWM = '1' generate
395
    -- instr. memory is located on lower portion of address space,
396
    -- I/O memory (if present) is located after data memory.
397
    DP_ADR_MS <= '0' when (to_unsigned(DP_ADR_i)/4 < IMEM_SIZE) else '1';
398
    DP_IADR <= to_unsigned(DP_ADR_i);
399
    DP_DADR <= to_unsigned(DP_ADR_i) - IMEM_SIZE*4;
400
    DP_IOADR_MS <= '0' when (to_unsigned(DP_ADR_i)/4 < IMEM_SIZE+DMEM_SIZE) else '1';
401
    --DP_IOADR <= to_unsigned(DP_ADR_i) - (IMEM_SIZE*4 - DMEM_SIZE*4);
402
  end generate;
403
 
404
  GL0: if IMEM_LOWM = '0' generate
405
    -- instr. memory is located on upper portion of address space,
406
    -- I/O memory (if present) is located after instr. memory.
407
    DP_ADR_MS <= '0' when (to_unsigned(DP_ADR_i)/4 > DMEM_SIZE) else '1';
408
    DP_IADR <= to_unsigned(DP_ADR_i) - DMEM_SIZE*4;
409
    DP_DADR <= to_unsigned(DP_ADR_i);
410
    DP_IOADR_MS <= '0' when (to_unsigned(DP_ADR_i)/4 < IMEM_SIZE+DMEM_SIZE) else '1';
411
    --DP_IOADR <= to_unsigned(DP_ADR_i) - (IMEM_SIZE*4 - DMEM_SIZE*4);
412
  end generate;
413
 
414
  -- Note: DADR0 and DADR1 are data memory addresses, so there's no need to
415
  -- subtract IMEM_SIZE from them!  
416
 
417
  -- I/O memory selection flags
418
 
419
  GIOM0_GT0: if(IOMEM_SIZE > 0) generate
420
  IOMS(0) <= '1' when (DADR0(ALEN-1 downto 2) >= DMEM_SIZE) else '0';
421
  IOMS(1) <= '1' when (DADR1(ALEN-1 downto 2) >= DMEM_SIZE) else '0';
422
  end generate;
423
 
424
  GIOM0_EQ0: if(IOMEM_SIZE = 0) generate
425
  IOMS(0) <= '0';
426
  IOMS(1) <= '0';
427
  end generate;
428
 
429
  -- Memory Selection flag registers: these registers are
430
  -- needed to mux instruction and data RAM's output during
431
  -- load or DP read operations (because of synchronous
432
  -- behavior of RAM's, output data is available with a
433
  -- delay of one cycle, requiring a similarly delayed
434
  -- version of selection flags).
435
 
436
  process(CLK_i)
437
  begin
438
    if(CLK_i = '1' and CLK_i'event) then
439
      DP_ADR_MS_q <= DP_ADR_MS;
440
      DP_IOADR_MS_q <= DP_IOADR_MS;
441
      DIMS_q <= DIMS;
442
      IOMS_q <= IOMS;
443
    end if;
444
  end process;
445
 
446
  ---------------------------------------------------
447
  -- Address error and conflict flags
448
  ---------------------------------------------------
449
 
450
  -- An instruction address triggers an error if it
451
  -- simply falls outside of the instruction address space
452
  -- given by [0:IMEM_SIZE*4-4)
453
 
454
  -- A load/store address triggers an error if:
455
  -- 1) it targets instruction RAM (DIMS* = '1') and it
456
  -- falls outside of the instruction address space
457
  -- given by [0:IMEM_SIZE*4-4), OR
458
  -- 2) it targets data RAM (DIMS* = '0') and it falls
459
  -- outside of the data address space given by 
460
  -- [0:(DMEM_SIZE+IOMEM_SIZE)*4-4).
461
 
462
  -- This flag gets asserted if data port #0 address is
463
  -- outside of address space.
464
 
465
  DADR0_ERR <= '1' when (
466
    (DIMS(0) = '0' and DIADR0(ALEN-1 downto 2) >= IMEM_SIZE) or
467
    (DIMS(0) = '1' and DADR0(ALEN-1 downto 2) >= DMEM_SIZE + IOMEM_SIZE)
468
  ) else '0';
469
 
470
  -- This flag gets asserted if data port #1 address is
471
  -- outside of address space.
472
 
473
  DADR1_ERR <= '1' when (
474
    (DIMS(1) = '0' and DIADR1(ALEN-1 downto 2) >= IMEM_SIZE) or
475
    (DIMS(1) = '1' and DADR1(ALEN-1 downto 2) >= DMEM_SIZE + IOMEM_SIZE)
476
  ) else '0';
477
 
478
  -- This flag gets asserted if instruction port address
479
  -- is outside of address space.
480
 
481
  IADR_ERR <= '1' when (
482
    IADR1(ALEN-3 downto 3) >= IMEM_SIZE/2
483
  ) else '0';
484
 
485
  -- Error flag pipe registers (added to relax
486
  -- timing constraints).
487
 
488
  process(CLK_i)
489
  begin
490
    if(CLK_i = '1' and CLK_i'event) then
491
      if(RST_i = '1') then
492
        IADR_ERR_q <= '0';
493
        DADR0_ERR_q <= '0';
494
        DADR1_ERR_q <= '0';
495
      else
496
        IADR_ERR_q <= IADR_ERR;
497
        DADR0_ERR_q <= DADR0_ERR;
498
        DADR1_ERR_q <= DADR1_ERR;
499
      end if;
500
    end if;
501
  end process;
502
 
503
  -- This flag gets asserted if a concurrent access from
504
  -- data ports is attemped on instruction sub-space or
505
  -- on I/O sub-space.
506
 
507
  IDADR_CFLT <= '1' when (
508
    (
509
      (DIMS(0) = '0' and DRE(0) = '1') and
510
      (DIMS(1) = '0' and DRE(1) = '1')
511
    ) or (
512
      (DIMS(0) = '0' and DWE0 = '1') and
513
      (DIMS(1) = '0' and DRE(1) = '1')
514
    ) or (
515
      (IOMS(0) = '1' and DRE(0) = '1') and
516
      (IOMS(1) = '1' and DRE(1) = '1')
517
    ) or (
518
      (IOMS(0) = '1' and DWE0 = '1') and
519
      (IOMS(1) = '1' and DRE(1) = '1')
520
    )
521
  ) else '0';
522
 
523
  ---------------------------------------------------
524
  -- Instruction RAM
525
  ---------------------------------------------------
526
 
527
  -- Instruction RAM is dual-port RAM with 1 read/write
528
  -- port and 1 read-only port. 
529
  -- Read-only port id used for instructions fecthing,
530
  -- read/write port is used to access memory through
531
  -- load/store operations.
532
 
533
  GPX0_1 : if(PARALLEL_EXECUTION_ENABLED = '1') generate
534
 
535
  -- Instruction RAM word width is twice data RAM one
536
  -- because instructions RAM must provides two
537
  -- adjacent instructions per cycle.
538
 
539
  U_RAMI : RV01_RAM_1RW1R_BE
540
    generic map(
541
      DWIDTH => ILEN*2,
542
      WCOUNT => IMEM_SIZE/2
543
    )
544
    port map(
545
      CLK_i => CLK_i,
546
      A_i => IADR0_RAM_PX(log2(IMEM_SIZE)-2 downto 0),
547
      DPRA_i => IADR1_RAM_PX(log2(IMEM_SIZE)-2 downto 0),
548
      D_i => IDI_RAM,
549
      WE_i => IWE0_RAM,
550
      BE_i => IBE0_RAM,
551
 
552
      Q_o => IDATI_RAM,
553
      DPQ_o => INSTR
554
    );
555
 
556
  end generate; -- GPX0_1
557
 
558
  GPX0_0 : if(PARALLEL_EXECUTION_ENABLED = '0') generate
559
 
560
  -- Instruction RAM word width equals data RAM one
561
  -- because instructions RAM must provides one
562
  -- instruction per cycle.
563
 
564
  U_RAMI : RV01_RAM_1RW1R_BE
565
    generic map(
566
      DWIDTH => ILEN,
567
      WCOUNT => IMEM_SIZE
568
    )
569
    port map(
570
      CLK_i => CLK_i,
571
      A_i => IADR0_RAM,
572
      DPRA_i => IADR1_RAM,
573
      D_i => IDI_RAM(ILEN-1 downto 0),
574
      WE_i => IWE0_RAM,
575
      BE_i => IBE0_RAM(4-1 downto 0),
576
 
577
      Q_o => IDATI_RAM(ILEN-1 downto 0),
578
      DPQ_o => INSTR(ILEN-1 downto 0)
579
    );
580
 
581
  IDATI_RAM(ILEN*2-1 downto ILEN) <= (others => '0');
582
  INSTR(ILEN*2-1 downto ILEN) <= (others => '0');
583
 
584
  end generate; -- GPX0_0
585
 
586
  ---------------------------------------------------
587
  -- Instruction memory signals
588
  ---------------------------------------------------
589
 
590
  -- inst. RAM read/write port address
591
 
592
  GPX5_1 : if(PARALLEL_EXECUTION_ENABLED = '1') generate
593
 
594
  -- Inst. RAM read/write address has three possible
595
  -- sources:
596
  -- 1) DP port address
597
  -- 2) data port #0 address
598
  -- 3) data port #1 address
599
 
600
  GPO_1 : if(IMEM_SIZE_PO2 = '1') generate
601
 
602
  -- Inst. memory size is a power-of-2: address is generated
603
  -- as a simple subset of DIADR0, DIADR0 or DP_IADR.
604
 
605
  process(DIMS(0),DIMS(1),DRE,DWE0,HALT,DIADR0,DIADR1,DP_IADR,DBE)
606
  begin
607
    if(HALT = '0') then
608
      -- cpu data memory ports address
609
      if(DIMS(0) = '0' and (DRE(0) = '1' or DWE0 = '1')) then
610
        -- port #0 address
611
        IADR0_RAM_PX <= DIADR0(L2IMEM_SIZE+2-1 downto 3);
612
        IADR0_RAM_WS <= DIADR0(2);
613
      else
614
        -- port #1 address
615
        IADR0_RAM_PX <= DIADR1(L2IMEM_SIZE+2-1 downto 3);
616
        IADR0_RAM_WS <= DIADR1(2);
617
      end if;
618
      IBE <= DBE;
619
    else
620
      -- DP port address
621
      IADR0_RAM_PX <= DP_IADR(L2IMEM_SIZE+2-1 downto 3);
622
      IADR0_RAM_WS <= DP_IADR(2);
623
      IBE <= (others => '1');
624
    end if;
625
  end process;
626
 
627
  end generate; -- GPO_1
628
 
629
  GPO_0 : if(IMEM_SIZE_PO2 = '0') generate
630
 
631
  -- Inst. memory size is NOT a power-of-2: address is generated
632
  -- as a subset of DIADR0, DIADR0 or DP_IADR, except when it exceeds
633
  -- memory size (when this occur, address is forced to all-0).
634
 
635
  process(DIMS(0),DIMS(1),DRE,DWE0,HALT,DIADR0,DIADR1,DP_IADR,DBE)
636
  begin
637
    if(HALT = '0') then
638
      -- cpu data memory ports address
639
      if(DIMS(0) = '0' and (DRE(0) = '1' or DWE0 = '1')) then
640
        -- port #0 address
641
        if(DIADR0(L2IMEM_SIZE+2-1 downto 3) < IMEM_SIZE/2) then
642
          IADR0_RAM_PX <= DIADR0(L2IMEM_SIZE+2-1 downto 3);
643
        else
644
          IADR0_RAM_PX <= (others => '0');
645
        end if;
646
        IADR0_RAM_WS <= DIADR0(2);
647
      else
648
        -- port #1 address
649
        if(DIADR1(L2IMEM_SIZE+2-1 downto 3) < IMEM_SIZE/2) then
650
          IADR0_RAM_PX <= DIADR1(L2IMEM_SIZE+2-1 downto 3);
651
        else
652
          IADR0_RAM_PX <= (others => '0');
653
        end if;
654
        IADR0_RAM_WS <= DIADR1(2);
655
      end if;
656
      IBE <= DBE;
657
    else
658
      -- DP port address
659
      if(DP_IADR(L2IMEM_SIZE+2-1 downto 3) < IMEM_SIZE/2) then
660
        IADR0_RAM_PX <= DP_IADR(L2IMEM_SIZE+2-1 downto 3);
661
      else
662
        IADR0_RAM_PX <= (others => '0');
663
      end if;
664
      IADR0_RAM_WS <= DP_IADR(2);
665
      IBE <= (others => '1');
666
    end if;
667
  end process;
668
 
669
  end generate; -- GPO_0
670
 
671
  end generate; -- GPX5_1
672
 
673
  GPX5_0 : if(PARALLEL_EXECUTION_ENABLED = '0') generate
674
 
675
  -- Inst. RAM read/write address has two possible
676
  -- sources:
677
  -- 1) DP port address
678
  -- 2) data port #0 address
679
 
680
  GPO_1 : if(IMEM_SIZE_PO2 = '1') generate
681
 
682
  -- Inst. memory size is a power-of-2: address is generated
683
  -- as a simple subset of DIADR0, DIADR0 or DP_IADR.
684
 
685
  process(DIMS(0),DIMS(1),DRE,DWE0,HALT,DIADR0,DIADR1,DP_IADR,DBE)
686
  begin
687
    if(HALT = '0') then
688
      -- cpu data memory ports address
689
      if(DIMS(0) = '0' and (DRE(0) = '1' or DWE0 = '1')) then
690
        -- port #0 address
691
        IADR0_RAM <= DIADR0(L2IMEM_SIZE+2-1 downto 2);
692
      else
693
        -- port #1 address
694
        IADR0_RAM <= DIADR1(L2IMEM_SIZE+2-1 downto 2);
695
      end if;
696
      IBE <= DBE;
697
    else
698
      -- DP port address
699
      IADR0_RAM <= DP_IADR(L2IMEM_SIZE+2-1 downto 2);
700
      IBE <= (others => '1');
701
    end if;
702
    IADR0_RAM_WS <= '0';
703
  end process;
704
 
705
  end generate; -- GPO_1
706
 
707
  GPO_0 : if(IMEM_SIZE_PO2 = '0') generate
708
 
709
  -- Inst. memory size is NOT a power-of-2: address is generated
710
  -- as a subset of DIADR0, DIADR0 or DP_IADR, except when it exceeds
711
  -- memory size (when this occur, address is forced to all-0).
712
 
713
  process(DIMS(0),DIMS(1),DRE,DWE0,HALT,DIADR0,DIADR1,DP_IADR,DBE)
714
  begin
715
    if(HALT = '0') then
716
      -- cpu data memory ports address
717
      if(DIMS(0) = '0' and (DRE(0) = '1' or DWE0 = '1')) then
718
        -- port #0 address
719
        if(DIADR0(L2IMEM_SIZE+2-1 downto 2) < IMEM_SIZE) then
720
          IADR0_RAM <= DIADR0(L2IMEM_SIZE+2-1 downto 2);
721
        else
722
          IADR0_RAM <= (others => '0');
723
        end if;
724
      else
725
        -- port #1 address
726
        if(DIADR1(L2IMEM_SIZE+2-1 downto 2) < IMEM_SIZE) then
727
          IADR0_RAM <= DIADR1(L2IMEM_SIZE+2-1 downto 2);
728
        else
729
          IADR0_RAM <= (others => '0');
730
        end if;
731
      end if;
732
      IBE <= DBE;
733
    else
734
      -- DP port address
735
      if(DP_IADR(L2IMEM_SIZE+2-1 downto 2) < IMEM_SIZE) then
736
        IADR0_RAM <= DP_IADR(L2IMEM_SIZE+2-1 downto 2);
737
      else
738
        IADR0_RAM <= (others => '0');
739
      end if;
740
      IBE <= (others => '1');
741
    end if;
742
    IADR0_RAM_WS <= '0';
743
  end process;
744
 
745
  end generate; -- GPO_0
746
 
747
  end generate; -- GPX5_0
748
 
749
  -- Inst. RAM read/write port WE has two possible
750
  -- sources:
751
  -- 1) DP port WE
752
  -- 2) data port #0 WE
753
 
754
  -- inst. RAM read/write port write-enable
755
  IWE0_RAM <= (DWE0 and not DIMS(0)) when (HALT = '0') else
756
    (DP_WE_i and not DP_ADR_MS);
757
 
758
  -- DP port and data port #0 provide only SDLEN bit
759
  -- of data, which are mapped both the lower and upper
760
  -- halves of instruction RAM data word, the selection
761
  -- of the half to be actually written to memory being
762
  -- performed through byte-enable signals.
763
 
764
  -- inst. RAM data-in
765
  IDI_RAM(ILEN-1 downto 0) <= DDATO when (HALT = '0') else DP_DAT_i;
766
 
767
  GPX1_1 : if(PARALLEL_EXECUTION_ENABLED = '1') generate
768
  IDI_RAM(ILEN*2-1 downto ILEN) <= DDATO when (HALT = '0') else DP_DAT_i;
769
  end generate; -- GPX1_1
770
 
771
  GPX1_0 : if(PARALLEL_EXECUTION_ENABLED = '0') generate
772
  IDI_RAM(ILEN*2-1 downto ILEN) <= (others => '0');
773
  end generate; -- GPX1_0
774
 
775
  -- Inst. RAM byte-enable signals, in every cycle only
776
  -- the lower 4 bits or the upper 4 bits can be non-zero.
777
  -- Mapping of DP port or data port DBE signals on
778
  -- lower/upper 4 bits being controlled by DP or data
779
  -- port address LSb.
780
 
781
  GPX2_1 : if(PARALLEL_EXECUTION_ENABLED = '1') generate
782
 
783
  IBE0_RAM(4-1 downto 0) <=
784
    IBE when (IADR0_RAM_WS = '0') else (others => '0');
785
 
786
  IBE0_RAM(8-1 downto 4) <=
787
    IBE when (IADR0_RAM_WS = '1') else (others => '0');
788
 
789
  end generate; -- GPX2_1
790
 
791
  GPX2_0 : if(PARALLEL_EXECUTION_ENABLED = '0') generate
792
 
793
  IBE0_RAM(4-1 downto 0) <= IBE;
794
 
795
  IBE0_RAM(8-1 downto 4) <= (others => '0');
796
 
797
  end generate; -- GPX2_0
798
 
799
  GPX3_1 : if(PARALLEL_EXECUTION_ENABLED = '1') generate
800
 
801
  -- Inst. RAM read-only address (2-word address) 
802
  IADR1_RAM_PX <= IADR1(L2IMEM_SIZE+2-1 downto 3);
803
 
804
  end generate; -- GPX3_1
805
 
806
  GPX3_0 : if(PARALLEL_EXECUTION_ENABLED = '0') generate
807
 
808
  -- Inst. RAM read-only address (1-word address)
809
  IADR1_RAM <= IADR1(L2IMEM_SIZE+2-1 downto 2);
810
 
811
  end generate; -- GPX3_0
812
 
813
  -- Data-out word selector must be latched to account for
814
  -- RAM sync. behavior.
815
 
816
  process(CLK_i)
817
  begin
818
    if(CLK_i = '1' and CLK_i'event) then
819
      IADR0_RAM_WS_q <= IADR0_RAM_WS;
820
    end if;
821
  end process;
822
 
823
  GPX4_1 : if(PARALLEL_EXECUTION_ENABLED = '1') generate
824
 
825
  -- Select word of instruction memory data-out (2 words)
826
  -- to be sent to CPU.
827
 
828
  IDATI <= IDATI_RAM(ILEN*2-1 downto ILEN) when IADR0_RAM_WS_q = '1'
829
  else IDATI_RAM(ILEN-1 downto 0);
830
 
831
  end generate; -- GPX4_1
832
 
833
  GPX4_0 : if(PARALLEL_EXECUTION_ENABLED = '0') generate
834
 
835
  IDATI <= IDATI_RAM(ILEN-1 downto 0);
836
 
837
  end generate; -- GPX4_0
838
 
839
  ---------------------------------------------------
840
  -- Data memory signals
841
  ---------------------------------------------------
842
 
843
  -- Data RAM port #0 is used for DP and therfore the related
844
  -- address, data-in and write-enable signals are driven by
845
  -- DP port when DMA-enable signals HALT is asserted.
846
 
847
  -- Data RAM port #0 is a read-only port and thus doesn't have
848
  -- associated data-in and write-enable signals. 
849
 
850
  -- Note: DADR0/1 are byte addresses, while data RAM is accessed
851
  -- using word addresses, therefore DADR0/1 LS 2 bits must be
852
  -- discarded.
853
 
854
  GPO2_1: if(DMEM_SIZE_PO2 = '1') generate
855
 
856
  -- Data memory size is a power-of-2: address is generated
857
  -- as a simple subset of DADR0 or DP_ADR.
858
 
859
  DADR0_RAM <= DADR0(L2DMEM_SIZE+2-1 downto 2) when (HALT = '0') else
860
    DP_DADR(L2DMEM_SIZE+2-1 downto 2);
861
 
862
  GPX_1 : if(PARALLEL_EXECUTION_ENABLED = '1') generate
863
  DADR1_RAM <= DADR1(L2DMEM_SIZE+2-1 downto 2);
864
  end generate;
865
 
866
  GPX_0 : if(PARALLEL_EXECUTION_ENABLED = '0') generate
867
  DADR1_RAM <= (others => '0');
868
  end generate;
869
 
870
  end generate;
871
 
872
  GPO2_0: if(DMEM_SIZE_PO2 = '0') generate
873
 
874
  -- Data memory size is NOT a power-of-2: address is generated
875
  -- as a subset of DADR0 or DP_ADR, except when it exceeds
876
  -- memory size (when this occur, address is forced to all-0).
877
 
878
  process(DADR0,DP_DADR,HALT)
879
  begin
880
    if(HALT = '0') then
881
      if(DADR0((L2DMEM_SIZE+2)-1 downto 2) < DMEM_SIZE) then
882
        DADR0_RAM <= DADR0((L2DMEM_SIZE+2)-1 downto 2);
883
      else
884
        DADR0_RAM <= (others => '0');
885
      end if;
886
    else
887
      if(DP_DADR((L2DMEM_SIZE+2)-1 downto 2) < DMEM_SIZE) then
888
        DADR0_RAM <= DP_DADR((L2DMEM_SIZE+2)-1 downto 2);
889
      else
890
        DADR0_RAM <= (others => '0');
891
      end if;
892
    end if;
893
  end process;
894
 
895
  GPX_1 : if(PARALLEL_EXECUTION_ENABLED = '1') generate
896
 
897
  process(DADR1)
898
  begin
899
    if(DADR1((L2DMEM_SIZE+2)-1 downto 2)  < DMEM_SIZE) then
900
      DADR1_RAM <= DADR1((L2DMEM_SIZE+2)-1 downto 2);
901
    else
902
      DADR1_RAM <= (others => '0');
903
    end if;
904
  end process;
905
 
906
  end generate;
907
 
908
  GPX_0 : if(PARALLEL_EXECUTION_ENABLED = '0') generate
909
  DADR1_RAM <= (others => '0');
910
  end generate;
911
 
912
  end generate;
913
 
914
  -- data RAM write-enable
915
  DWE0_RAM <= (DWE0 and DIMS(0) and not(IOMS(0))) when (HALT = '0') else
916
    (DP_WE_i and DP_ADR_MS and not(DP_IOADR_MS));
917
 
918
  -- data RAM data-in
919
  DDI_RAM <= DDATO when HALT = '0' else DP_DAT_i;
920
 
921
  -- CPU data-in (supplied either by instruction memory, data memory
922
  -- or some I/O module)
923
 
924
  DDATI0 <=
925
    DDATI0_RAM when (DIMS_q(0) = '1' and IOMS_q(0) = '0') else
926
    DDATO_PLIC when (DIMS_q(0) = '1' and IOMS_q(0) = '1') else
927
    IDATI;
928
 
929
  GPX6_1 : if(PARALLEL_EXECUTION_ENABLED = '1') generate
930
  DDATI1 <=
931
    DDATI1_RAM when (DIMS_q(1) = '1' and IOMS_q(1) = '0') else
932
    DDATO_PLIC when (DIMS_q(1) = '1' and IOMS_q(1) = '1') else
933
    IDATI;
934
  end generate;
935
 
936
  GPX6_0 : if(PARALLEL_EXECUTION_ENABLED = '0') generate
937
  DDATI1 <= (others => '0');
938
  end generate;
939
 
940
  DBE_RAM <= DBE when (HALT = '0') else (others => '1');
941
 
942
  ---------------------------------------------------
943
  -- Data RAM
944
  ---------------------------------------------------
945
 
946
  GPX7_1 : if(PARALLEL_EXECUTION_ENABLED = '1') generate
947
 
948
  -- data RAM is dual-port RAM with 1 read/write port and
949
  -- 1 read-only port (two reads, or one read and one write
950
  -- can be performed in parallel).
951
 
952
  U_RAMD : RV01_RAM_1RW1R_BE
953
    generic map(
954
      DWIDTH => SDLEN,
955
      WCOUNT => DMEM_SIZE
956
    )
957
    port map(
958
      CLK_i => CLK_i,
959
      A_i => DADR0_RAM,
960
      DPRA_i => DADR1_RAM,
961
      D_i => DDI_RAM,
962
      WE_i => DWE0_RAM,
963
      BE_i => DBE_RAM,
964
 
965
      Q_o => DDATI0_RAM,
966
      DPQ_o => DDATI1_RAM
967
    );
968
 
969
  end generate;
970
 
971
  GPX7_0 : if(PARALLEL_EXECUTION_ENABLED = '0') generate
972
 
973
  -- data RAM is single-port RAM with 1 read/write port.
974
 
975
  U_RAMD : RV01_RAM_1RW_BE
976
    generic map(
977
      DWIDTH => SDLEN,
978
      WCOUNT => DMEM_SIZE
979
    )
980
    port map(
981
      CLK_i => CLK_i,
982
      A_i => DADR0_RAM,
983
      D_i => DDI_RAM,
984
      WE_i => DWE0_RAM,
985
      BE_i => DBE_RAM,
986
 
987
      Q_o => DDATI0_RAM
988
    );
989
 
990
    DDATI1_RAM <= (others => '0');
991
 
992
  end generate;
993
 
994
  ---------------------------------------------------
995
  -- I/O memory signals
996
  ---------------------------------------------------
997
 
998
  GPX8_1 : if(PARALLEL_EXECUTION_ENABLED = '1') generate
999
 
1000
  process(IOMS,DRE,DWE0,HALT,DADR0,DADR1,DP_ADR_i)
1001
  begin
1002
    if(HALT = '0') then
1003
      -- cpu data memory ports address
1004
      if(IOMS(0) = '1' and (DRE(0) = '1' or DWE0 = '1')) then
1005
        -- port #0 address
1006
        DADR_IO <= DADR0;
1007
      else
1008
        -- port #1 address
1009
        DADR_IO <= DADR1;
1010
      end if;
1011
    else
1012
      -- DP port address
1013
      DADR_IO <= to_unsigned(DP_ADR_i);
1014
    end if;
1015
  end process;
1016
 
1017
  end generate;
1018
 
1019
  GPX8_0 : if(PARALLEL_EXECUTION_ENABLED = '0') generate
1020
 
1021
  process(IOMS,DRE,DWE0,HALT,DADR0,DP_ADR_i)
1022
  begin
1023
    if(HALT = '0') then
1024
      -- port #0 address
1025
      DADR_IO <= DADR0;
1026
    else
1027
      -- DP port address
1028
      DADR_IO <= to_unsigned(DP_ADR_i);
1029
    end if;
1030
  end process;
1031
 
1032
  end generate;
1033
 
1034
  -- I/O memory write-enable
1035
  DWE_IO <= (DWE0 and DIMS(0) and IOMS(0)) when (HALT = '0') else
1036
    (DP_WE_i and DP_ADR_MS and DP_IOADR_MS);
1037
 
1038
  -- I/O memory data-in
1039
  DDATI_IO <= DDATO when HALT = '0' else DP_DAT_i;
1040
 
1041
  ---------------------------------------------------
1042
  -- I/O modules
1043
  ---------------------------------------------------
1044
 
1045
  GPLIC_1 : if(PLIC_PRESENT = '1') generate
1046
 
1047
  -- PLIC Module
1048
 
1049
  U_PLIC : RV01_PLIC
1050
    generic map(
1051
      SRC_CNT => EI_SRC_CNT,
1052
      TRIG_TYPE => EI_TRIG_TYPE,
1053
      REQ_MAXCNT => EI_REQ_MAXCNT
1054
    )
1055
    port map(
1056
      CLK_i => CLK_i,
1057
      RST_i => RST_i,
1058
      REG_A_i => DADR_PLIC,
1059
      REG_WE_i => DWE_PLIC,
1060
      REG_D_i => DDATI_IO,
1061
      REQ_i => EI_REQ_i,
1062
 
1063
      REG_Q_o => DDATO_PLIC,
1064
      EIP_o => EXT_INT
1065
    );
1066
 
1067
  -- PLIC address is a subset of I/O address space.
1068
 
1069
  process(DADR_IO)
1070
    variable TMP : unsigned(ALEN-1 downto 0);
1071
  begin
1072
    TMP := DADR_IO/4 - PLIC_ABASE;
1073
    DADR_PLIC <= to_std_logic_vector(TMP(PLIC_AWIDTH-1 downto 0));
1074
  end process;
1075
 
1076
  -- PLIC write-enable is set to DWE_IO when I/O address
1077
  -- falls in PLIC address range.
1078
 
1079
  DWE_PLIC <= DWE_IO when (to_unsigned(DADR_PLIC) <= PLIC_AMAX) else '0';
1080
 
1081
  -- PLIC is the only I/O module present, so I/O
1082
  -- memory data-out is coincident with PLIC data-out.
1083
 
1084
  DDATO_IO <= DDATO_PLIC;
1085
 
1086
  end generate; -- GPLIC_1
1087
 
1088
  GPLIC_0 : if(PLIC_PRESENT = '0') generate
1089
    DDATO_PLIC <= (others => '0');
1090
    EXT_INT <= '0';
1091
    DDATO_IO <= (others => '0');
1092
  end generate; -- GPLIC_0
1093
 
1094
  ---------------------------------------------------
1095
  -- DP port data-out (same as data RAM data-out)
1096
  ---------------------------------------------------
1097
 
1098
  GIOM1_GT0 : if(IOMEM_SIZE > 0) generate
1099
  DP_DAT_o <=
1100
    DDATI0_RAM when (DP_ADR_MS_q = '1' and DP_IOADR_MS_q = '0') else
1101
    DDATO_IO when (DP_ADR_MS_q = '1' and DP_IOADR_MS_q = '1') else
1102
    IDATI;
1103
  end generate;
1104
 
1105
  GIOM1_EQ0 : if(IOMEM_SIZE = 0) generate
1106
  DP_DAT_o <=
1107
    DDATI0_RAM when (DP_ADR_MS_q = '1') else
1108
    IDATI;
1109
  end generate;
1110
 
1111
end ARC;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.