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

Subversion Repositories rv01_riscv_core

[/] [rv01_riscv_core/] [trunk/] [VHDL/] [SELF_TEST/] [RV01_selftest.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) 2017 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 self-test 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_CFG_PKG.all;
42
use work.RV01_CSR_PKG.all;
43
use work.RV01_PLIC_PKG.all;
44
 
45
entity RV01_SELFTEST is
46
  port(
47
    CLK_i : in std_logic;
48
    RST_i : in std_logic;
49
 
50
    DONE_o : out std_logic;
51
    PASS_o : out std_logic
52
  );
53
end RV01_SELFTEST;
54
 
55
architecture ARC of RV01_SELFTEST is
56
 
57
  constant CFG_FLAGS : std_logic_vector(8-1 downto 0) := (
58
    '0',
59
    PLIC_PRESENT,
60
    DM_PRESENT,
61
    FPU_PRESENT,
62
    JALR_PREDICTION_ENABLED,
63
    BRANCH_PREDICTION_ENABLED,
64
    DELAYED_EXECUTION_ENABLED,
65
    PARALLEL_EXECUTION_ENABLED
66
  );
67
 
68
  constant CCS_HALTED : natural := 19;
69
 
70
  -- Number of Dhrystone runs to performs (max. 500)
71
  constant CNTR_MAX : natural := 30;
72
 
73
  -- Address to stop at after every run
74
  constant HALT_ADR1 : ADR_T := to_unsigned(17652,ALEN);
75
 
76
  -- Final address to stop at
77
  constant HALT_ADRF : ADR_T := to_unsigned(3360,ALEN);
78
 
79
  -- Number of data word to be read from RV01 memory
80
  -- (these are the check data)
81
  constant CNTD_R_INIT : natural := 12;
82
 
83
  -- Number of data word to be written to RV01 memory
84
  -- (this is the Dhrystone executable)
85
  constant CNTD_W_INIT : natural := 8150;
86
 
87
  -- Run-To-End flag, if this flag is asserted, the 
88
  -- test program runs until completion (500 Dhrystone
89
  -- loop iterations), otherwise the test stops after
90
  -- CNTR_MAX iterations.
91
  constant RUN_TO_END : std_logic := '0';
92
 
93
  -- ext. FSM state type
94
  type XS_T is (
95
    XS_IDLE,
96
    XS_INIT1,
97
    XS_INIT2,
98
    XS_WRITE,
99
    XS_WRTCP1,
100
    XS_WRTCP2,
101
    XS_WRTCP6,
102
    XS_WRTCP7,
103
    XS_WRTCP8,
104
    XS_WAIT5,
105
    XS_WAIT6,
106
    XS_WAIT7,
107
    XS_WAIT8,
108
    XS_RUN3,
109
    XS_RUN4,
110
    XS_READ,
111
    XS_STOP
112
  );
113
 
114
  -- write FSM state type
115
  type WS_T is (
116
    WS_IDLE,
117
    WS_WRITI,
118
    WS_WRITD,
119
    WS_WAIT1,
120
    WS_WAIT2,
121
    WS_WAIT3
122
  );
123
 
124
  -- read FSM state type
125
  type RS_T is (
126
    RS_IDLE,
127
    RS_READ,
128
    RS_WAIT1,
129
    RS_WAIT2
130
  );
131
 
132
  component RV01_TOP_NOHOST is
133
    generic(
134
      -- synthesis translate_off
135
      ST_FILE : string := "NONE";
136
      WB_FILE : string := "NONE";
137
      -- synthesis translate_on
138
      IMEM_SIZE : natural := 1024*32; -- 128Kb
139
      DMEM_SIZE : natural := 1024*16; -- 64Kb
140
      IOMEM_SIZE : natural := 1024; -- 4Kb
141
      IMEM_SIZE_PO2 : std_logic := '1';
142
      DMEM_SIZE_PO2 : std_logic := '1';
143
      IMEM_LOWM : std_logic := '1';
144
      BHT_SIZE : natural := 256;
145
      EI_SRC_CNT : natural := 8;
146
      EI_TRIG_TYPE : PLIC_TRIG_TYPE := LEVEL;
147
      EI_REQ_MAXCNT : natural := 16;
148
      CFG_FLAGS : std_logic_vector(16-1 downto 0) := "00000000"&"01100111";
149
      SIMULATION_ONLY : std_logic := '0'
150
    );
151
    port(
152
      CLK_i : in std_logic; -- clock
153
      RST_i : in std_logic; -- reset
154
      -- External Interrupt Request
155
      EI_REQ_i : std_logic_vector(EI_SRC_CNT-1 downto 0);
156
      -- Data port interface
157
      DP_WE_i : in std_logic; -- DP write-enable
158
      DP_ADR_i : in std_logic_vector(ALEN-1 downto 0);
159
      DP_DAT_i : in std_logic_vector(SDLEN-1 downto 0); -- DP data-in
160
      -- Control port interface
161
      CP_RE_i : in std_logic;
162
      CP_WE_i : in std_logic;
163
      CP_ADR_i : in std_logic_vector(17-1 downto 0);
164
      CP_DAT_i : in std_logic_vector(SDLEN-1 downto 0);
165
 
166
      -- Data port interface
167
      DP_DAT_o : out std_logic_vector(SDLEN-1 downto 0); -- DP data-out
168
      -- Control port interface
169
      CP_DAT_o : out std_logic_vector(SDLEN-1 downto 0)
170
    );
171
  end component ;
172
 
173
  component RV01_STI_ROM is
174
    port(
175
      CLK_i : in std_logic;
176
      A_i : in unsigned(13-1 downto 0);
177
      Q_o : out std_logic_vector(SDLEN*2-1 downto 0)
178
    );
179
  end component;
180
 
181
  component RV01_STO_ROM is
182
    port(
183
      CLK_i : in std_logic;
184
      A_i : in unsigned(4-1 downto 0);
185
      Q_o : out std_logic_vector(SDLEN*2+4-1 downto 0)
186
    );
187
  end component;
188
 
189
  signal EI_REQ : std_logic_vector(0 downto 0) := (others => '0');
190
  signal DP_WE : std_logic;
191
  signal DP_ADR : std_logic_vector(ALEN-1 downto 0) := (others => '0');
192
  signal DP_DATI : std_logic_vector(SDLEN-1 downto 0) := (others => '0');
193
  signal DP_DATO : std_logic_vector(SDLEN-1 downto 0);
194
  signal DP_DAT_CHK,DP_DAT_CHK_q : std_logic_vector(SDLEN-1 downto 0);
195
  signal XS,XS_q : XS_T;
196
  signal WS,WS_q : WS_T;
197
  signal RS,RS_q : RS_T;
198
  signal WRITE_OP,WRITE_END,WRITE_END_q : std_logic;
199
  signal WRITIF,WRITIF_q : std_logic;
200
  signal WRITDF,WRITDF_q : std_logic;
201
  signal CNTI_RST_i,CNTD_RST_i : std_logic;
202
  signal CNTI_q : natural range 0 to IMEM_SIZE-1;
203
  signal CNTI_INIT : natural range 0 to ASPC_SIZE/2-1;
204
  signal CNTD_q : natural range 0 to (IMEM_SIZE+DMEM_SIZE)-1;
205
  signal CNTD_INIT : natural range 0 to (IMEM_SIZE+DMEM_SIZE)-1;
206
  signal READ_OP,READ_END : std_logic;
207
  signal READF,READF_q,READF_q2 : std_logic;
208
  signal CHKC_OP,CHKD_OP : std_logic;
209
  signal CHKF,CHKF_q : std_logic;
210
  signal PASS,PASS_q : std_logic;
211
  signal DONE,DONE_q : std_logic;
212
  signal RADR,WADR : std_logic_vector(ALEN-1 downto 0);
213
  signal CP_WE : std_logic;
214
  signal CP_RE : std_logic;
215
  signal CP_ADR: std_logic_vector(17-1 downto 0);
216
  signal CP_DATI : std_logic_vector(SDLEN-1 downto 0);
217
  signal CP_DATO : std_logic_vector(SDLEN-1 downto 0);
218
  signal CNTR_END,CNTR_INC : std_logic;
219
  signal CNTR_q : natural range 0 to 200-1;
220
  signal ERROR : std_logic := '0';
221
  signal ERR_CNT_q : natural := 0;
222
  signal MSK_CHK,MSK_CHK_q : std_logic_vector(4-1 downto 0);
223
  signal RTE : std_logic := RUN_TO_END;
224
 
225
  signal STI_ROM_ADR_q : unsigned(13-1 downto 0);
226
  signal STI_ROM_Q : std_logic_vector(SDLEN*2-1 downto 0);
227
  signal STO_ROM_ADR_q,STO_ROM_ADR_q2 : unsigned(4-1 downto 0);
228
  signal STO_ROM_Q : std_logic_vector(SDLEN*2+4-1 downto 0);
229
  signal DAT4_CHK : std_logic_vector(SDLEN-1 downto 0);
230
 
231
begin
232
 
233
  ---------------------------------------------------
234
  -- Self-test module operations
235
  ---------------------------------------------------
236
 
237
  -- This self-test module performs the following
238
  -- operations:
239
  -- 1) Write core instruction memory to all-zero
240
  -- 2) Write test program (instruction + data) from
241
  -- ROM to core memory.
242
  -- 3) Configure core halt module to stop at
243
  -- HALT_ADR1 address and then starts test program
244
  -- execution.
245
  -- 4) When program execution stops, read memory
246
  -- locations holding Dhrystone loop single-iteration
247
  -- results and compare their content to ROM check
248
  -- data, counting errors (if present).
249
  -- 5) Resume test program execution.
250
 
251
  -- Steps 4 and 5 are repeated CNTR_MAX times, then
252
  -- if RTE (Run-To-End) flag is set, test program
253
  -- execution restarts and run until completion
254
  -- without further stops, otherwise test program
255
  -- execution remains stopped indefinitely.
256
 
257
  ---------------------------------------------------
258
  -- Test control FSM
259
  ---------------------------------------------------
260
 
261
  -- MRV01HC register
262
  -- bit  | description
263
  -- 0    | haltstate (R)
264
  -- 1    | start (W)
265
  -- 2    | resume (W)
266
  -- 3    | halt unconditionally (W)
267
  -- 4    | halt on break (R/W)
268
  -- 5    | halt on address (R/W)
269
 
270
  process(CLK_i)
271
  begin
272
    if(CLK_i = '1' and CLK_i'event) then
273
      if(RST_i = '1') then
274
        DONE_q <= '0';
275
        XS_q <= XS_IDLE;
276
      else
277
        DONE_q <= DONE;
278
        XS_q <= XS;
279
      end if;
280
    end if;
281
  end process;
282
 
283
  process(XS_q,WRITE_END_q,CP_DATO,READ_END,CNTR_END,RTE)
284
  begin
285
 
286
    CNTI_RST_i <= '0';
287
    CNTD_RST_i <= '0';
288
    WRITE_OP <= '0';
289
    READ_OP <= '0';
290
    DONE <= '0';
291
    CP_RE <= '0';
292
    CP_WE <= '0';
293
    CP_ADR <= '1' & X"0000";
294
    CP_DATI <= X"00000000";
295
    CNTR_INC <= '0';
296
 
297
    case XS_q is
298
 
299
         -- Do nothing while reset is on
300
      when XS_IDLE =>
301
        XS <= XS_INIT1;
302
 
303
         -- Reset instruction/data counters
304
      when XS_INIT1 =>
305
        CNTI_RST_i <= '1';
306
        CNTD_RST_i <= '1';
307
        XS <= XS_INIT2;
308
 
309
         -- Start writing input data & test program to core memory
310
      when XS_INIT2 =>
311
        -- assert write operation start flag
312
        WRITE_OP <= '1';
313
        XS <= XS_WRITE;
314
 
315
         -- Write core memory
316
      when XS_WRITE =>
317
        -- check write operation end flag...
318
        if(WRITE_END_q = '1') then
319
          -- write operation completed
320
          XS <= XS_WRTCP1;
321
        else
322
          -- write operation still in progress
323
          XS <= XS_WRITE;
324
        end if;
325
 
326
      -- Write control port
327
      when XS_WRTCP1 =>
328
        -- set halt address to HALT_ADR1
329
        CP_WE <= '1';
330
        CP_ADR <= "100" & to_std_logic_vector(MRV01HA_ADR) & "00";
331
        CP_DATI <= to_std_logic_vector(HALT_ADR1);
332
        XS <= XS_WRTCP2;
333
 
334
      -- Write control port
335
      when XS_WRTCP2 =>
336
        -- start execution and enable halt-on-address
337
        CP_WE <= '1';
338
        CP_ADR <= "100" & to_std_logic_vector(MRV01HC_ADR) & "00";
339
        -- start = 1, haltoadr = 1
340
        CP_DATI <= X"00000022";
341
        XS <= XS_WAIT5;
342
 
343
         -- Check loop iteration results
344
      when XS_READ =>
345
        -- check read operation end flag...
346
        if(READ_END = '1') then
347
          -- check if run count has reached end value
348
          if(CNTR_END = '1') then
349
            -- stop test
350
            XS <= XS_STOP;
351
          else
352
            -- increment run count
353
            CNTR_INC <= '1';
354
            -- start next test run
355
            XS <= XS_WRTCP6;
356
          end if;
357
        else
358
          XS <= XS_READ;
359
        end if;
360
 
361
      -- Write control port
362
      when XS_WRTCP6 =>
363
        -- start execution and enable halt-on-address
364
        CP_WE <= '1';
365
        CP_ADR <= "100" & to_std_logic_vector(MRV01HC_ADR) & "00";
366
        -- start = 1, resume = 1, haltoadr = 1
367
        CP_DATI <= X"00000026";
368
        XS <= XS_WAIT5;
369
 
370
      -- Give haltstate time to be updated.
371
      when XS_WAIT5 =>
372
        CP_ADR <= "100" & to_std_logic_vector(MRV01HC_ADR) & "00";
373
        XS <= XS_WAIT6;
374
 
375
      -- Give haltstate time to be updated.
376
      when XS_WAIT6 =>
377
        CP_ADR <= "100" & to_std_logic_vector(MRV01HC_ADR) & "00";
378
        XS <= XS_RUN3;
379
 
380
      -- Run test program
381
      when XS_RUN3 =>
382
        -- wait for execution to halt, polling
383
        -- MRV01HC register
384
        if(CP_DATO(0) = '1') then
385
          -- check if there're data to be read from
386
          -- core memory...
387
          if(CNTD_R_INIT > 0) then
388
            -- assert read operation start flag
389
            READ_OP <= '1';
390
            XS <= XS_READ;
391
          -- check if run count has reached end value
392
          elsif(CNTR_END = '1') then
393
            -- check if Run-To-End flag is asserted...
394
            if(RTE = '1') then
395
              -- re-start test
396
              XS <= XS_WRTCP7;
397
            else
398
              -- stop test
399
              XS <= XS_STOP;
400
            end if;
401
          else
402
            -- increment run count
403
            CNTR_INC <= '1';
404
            -- start next test run
405
            XS <= XS_WRTCP6;
406
          end if;
407
        else
408
          -- keep register MTV01HC selected for read
409
          CP_ADR <= "100" & to_std_logic_vector(MRV01HC_ADR) & "00";
410
          XS <= XS_RUN3;
411
        end if;
412
 
413
      -- write control port
414
      when XS_WRTCP7 =>
415
        -- set halt address
416
        CP_WE <= '1';
417
        CP_ADR <= "100" & to_std_logic_vector(MRV01HA_ADR) & "00";
418
        CP_DATI <= to_std_logic_vector(HALT_ADRF);
419
        XS <= XS_WRTCP8;
420
 
421
      -- write control port
422
      when XS_WRTCP8 =>
423
        -- start execution and enable halt-on-address
424
        CP_WE <= '1';
425
        CP_ADR <= "100" & to_std_logic_vector(MRV01HC_ADR) & "00";
426
        -- start = 1, resume = 1, haltoadr = 1
427
        CP_DATI <= X"00000026";
428
        XS <= XS_WAIT7;
429
 
430
      -- Give haltstate time to be updated.
431
      when XS_WAIT7 =>
432
        -- keep register MTV01HC selected for read
433
        CP_ADR <= "100" & to_std_logic_vector(MRV01HC_ADR) & "00";
434
        XS <= XS_WAIT8;
435
 
436
      -- Give haltstate time to be updated.
437
      when XS_WAIT8 =>
438
        -- keep register MTV01HC selected for read
439
        CP_ADR <= "100" & to_std_logic_vector(MRV01HC_ADR) & "00";
440
        XS <= XS_RUN4;
441
 
442
      -- Run test program to end
443
      when XS_RUN4 =>
444
        -- wait for execution to halt, polling
445
        -- MRV01HC register
446
        if(CP_DATO(0) = '1') then
447
          -- stop test
448
          XS <= XS_STOP;
449
        else
450
          -- keep register MTV01HC selected for read
451
          CP_ADR <= "100" & to_std_logic_vector(MRV01HC_ADR) & "00";
452
          XS <= XS_RUN4;
453
        end if;
454
 
455
      when XS_STOP =>
456
        -- assert done flag
457
        DONE <= '1';
458
        XS <= XS_STOP;
459
 
460
      when others =>
461
        XS <= XS_IDLE;
462
 
463
    end case;
464
  end process;
465
 
466
  ---------------------------------------------------
467
  -- Write FSM
468
  ---------------------------------------------------
469
 
470
  -- This FSM controls writing of test program (read
471
  -- from STI_ROM memory) into RV01 core internal memory.
472
 
473
  -- The FRM writes core memory in two steps: during
474
  -- first step (FSM in state WS_WRITI) instruction
475
  -- memory is written to all-zero, while during second
476
  -- step (FSM in state WS_WRITD) the test program
477
  -- (instructions + data) is loaded into memory (thus
478
  -- overwriting some of the memory locations set to
479
  -- zero in the first step).
480
 
481
  process(CLK_i)
482
  begin
483
    if(CLK_i = '1' and CLK_i'event) then
484
      if(RST_i = '1') then
485
        WRITIF_q <= '0';
486
        WRITDF_q <= '0';
487
        WRITE_END_q <= '0';
488
        WS_q <= WS_IDLE;
489
      else
490
        WRITIF_q <= WRITIF;
491
        WRITDF_q <= WRITDF;
492
        WRITE_END_q <= WRITE_END;
493
        WS_q <= WS;
494
      end if;
495
    end if;
496
  end process;
497
 
498
  process(WS_q,WRITE_OP,CNTI_q,CNTD_q)
499
  begin
500
    WRITIF <= '0';
501
    WRITDF <= '0';
502
    WRITE_END <= '0';
503
    case WS_q is
504
 
505
      when WS_IDLE =>
506
        if(WRITE_OP = '1') then
507
          WRITIF <= '1';
508
          WS <= WS_WRITI;
509
        else
510
          WS <= WS_IDLE;
511
        end if;
512
 
513
      when WS_WRITI =>
514
        if(CNTI_q = 0) then
515
          WRITIF <= '1';
516
          WS <= WS_WAIT3;
517
        else
518
          WRITIF <= '1';
519
          WS <= WS_WRITI;
520
        end if;
521
 
522
      when WS_WAIT3 =>
523
        WRITDF <= '1';
524
        WS <= WS_WRITD;
525
 
526
      when WS_WRITD =>
527
        if(CNTD_q = 0) then
528
          WS <= WS_WAIT1;
529
        else
530
          WRITDF <= '1';
531
          WS <= WS_WRITD;
532
        end if;
533
 
534
      when WS_WAIT1 =>
535
        WS <= WS_WAIT2;
536
 
537
      when WS_WAIT2 =>
538
        WRITE_END <= '1';
539
        WS <= WS_IDLE;
540
 
541
      when others =>
542
        WS <= WS_IDLE;
543
    end case;
544
  end process;
545
 
546
  -- Data port write-enable flag
547
 
548
  DP_WE <= WRITIF_q or WRITDF_q;
549
 
550
  ---------------------------------------------------
551
  -- Read input data from RAM
552
  ---------------------------------------------------
553
 
554
  -- Whole instructions memory is written to all-0
555
  -- pattern, then instructions and data are written
556
  -- over, reading them from STI ROM memory.
557
 
558
  -- STI ROM address generator
559
 
560
  process(CLK_i)
561
  begin
562
    if(CLK_i = '1' and CLK_i'event) then
563
      if(RST_i = '1') then
564
        STI_ROM_ADR_q <= (others => '0');
565
      elsif(WRITDF = '1') then
566
        STI_ROM_ADR_q <= STI_ROM_ADR_q + 1;
567
      end if;
568
    end if;
569
  end process;
570
 
571
  -- Self-Test Input (STI) ROM
572
 
573
  U_STIROM : RV01_STI_ROM
574
    port map(
575
      CLK_i => CLK_i,
576
      A_i => STI_ROM_ADR_q,
577
      Q_o => STI_ROM_Q
578
    );
579
 
580
  -- Write address mux, when writing instruction
581
  -- memory to all-zero, address is generated 
582
  -- through a counter, while when writing
583
  -- test program, bott address and data are
584
  -- supplied by STI ROM.
585
 
586
  process(WRITIF,CNTI_q,STI_ROM_Q)
587
  begin
588
    if(WRITIF = '1') then
589
      -- address generated through counter
590
      WADR <= to_std_logic_vector(to_unsigned((IMEM_SIZE-1-CNTI_q)*4,ALEN));
591
      -- all-zero data
592
      DP_DATI <= (others => '0');
593
    else
594
      -- data and address supplied by STI ROM output
595
      WADR <= STI_ROM_Q(SDLEN*2-1 downto SDLEN);
596
      DP_DATI <= STI_ROM_Q(SDLEN-1 downto 0);
597
    end if;
598
  end process;
599
 
600
  ---------------------------------------------------
601
  -- Read (check data) FSM
602
  ---------------------------------------------------
603
 
604
  -- This FSM control read operations from core
605
  -- memory.
606
 
607
  process(CLK_i)
608
  begin
609
    if(CLK_i = '1' and CLK_i'event) then
610
      if(RST_i = '1') then
611
        READF_q <= '0';
612
        RS_q <= RS_IDLE;
613
      else
614
        READF_q <= READF;
615
        RS_q <= RS;
616
      end if;
617
    end if;
618
  end process;
619
 
620
  process(RS_q,READ_OP,CNTD_q)
621
  begin
622
    READF <= '0';
623
    READ_END <= '0';
624
    case RS_q is
625
 
626
      when RS_IDLE =>
627
        if(READ_OP = '1') then
628
          READF <= '1';
629
          RS <= RS_READ;
630
        else
631
          RS <= RS_IDLE;
632
        end if;
633
 
634
      when RS_READ =>
635
        if(CNTD_q = 0) then
636
          RS <= RS_WAIT1;
637
        else
638
          READF <= '1';
639
          RS <= RS_READ;
640
        end if;
641
 
642
      when RS_WAIT1 =>
643
        RS <= RS_WAIT2;
644
 
645
      when RS_WAIT2 =>
646
        READ_END <= '1';
647
        RS <= RS_IDLE;
648
 
649
      when others =>
650
        RS <= RS_IDLE;
651
 
652
    end case;
653
  end process;
654
 
655
  -- delay write flag by 1 cycle.
656
  process(CLK_i)
657
  begin
658
    if(CLK_i = '1' and CLK_i'event) then
659
      if(RST_i = '1') then
660
        READF_q2 <= '0';
661
      else
662
        READF_q2 <= READF_q;
663
      end if;
664
    end if;
665
  end process;
666
 
667
  ---------------------------------------------------
668
  -- Read output/check data from ROM
669
  ---------------------------------------------------
670
 
671
  -- STO ROM address generator
672
 
673
  process(CLK_i)
674
  begin
675
    if(CLK_i = '1' and CLK_i'event) then
676
      if(RST_i = '1' or READ_OP = '1') then
677
        STO_ROM_ADR_q <= (others => '0');
678
      elsif(READF = '1') then
679
        STO_ROM_ADR_q <= STO_ROM_ADR_q + 1;
680
      end if;
681
      STO_ROM_ADR_q2 <= STO_ROM_ADR_q;
682
    end if;
683
  end process;
684
 
685
  -- Self-Test Output (STO) ROM
686
 
687
  U_STOROM : RV01_STO_ROM
688
    port map(
689
      CLK_i => CLK_i,
690
      A_i => STO_ROM_ADR_q,
691
      Q_o => STO_ROM_Q
692
    );
693
 
694
  -- STO ROM output consists of 3 bit fields:
695
  -- [3:0] byte check mask.
696
  -- [35:4] check data.
697
  -- [67:36] read address.
698
 
699
  -- Byte check mask
700
  MSK_CHK <= STO_ROM_Q(4-1 downto 0);
701
 
702
  -- Check data don't change across loop iterations,
703
  -- except for 4th word, which is dependent from the
704
  -- current run count. 
705
 
706
  DAT4_CHK <= to_std_logic_vector(to_signed(STO_ROM_Q(SDLEN+4-1 downto 4)) + CNTR_q);
707
 
708
  -- Check data (4th word is set to DAT4_CHK value)
709
  DP_DAT_CHK <=
710
    DAT4_CHK when (STO_ROM_ADR_q2 = 4) else STO_ROM_Q(SDLEN+4-1 downto 4);
711
 
712
  -- Memory read address
713
  RADR <= STO_ROM_Q(SDLEN*2+4-1 downto SDLEN+4);
714
 
715
  -- Data from core memory is available with 1-cycle delay,
716
  -- save check data and byte mask for comparison.
717
 
718
  process(CLK_i)
719
  begin
720
    if(CLK_i = '1' and CLK_i'event) then
721
      DP_DAT_CHK_q <= DP_DAT_CHK;
722
      MSK_CHK_q <= MSK_CHK;
723
    end if;
724
  end process;
725
 
726
  ---------------------------------------------------
727
  -- Compare output and check data
728
  ---------------------------------------------------
729
 
730
  -- Compare data read from core memory locations
731
  -- storing Dhrystone core loop results to check
732
  -- data stored into ROM, counting errors.
733
 
734
  -- Note: comparison accounts for the byte check mask
735
  -- described above.
736
 
737
  process(DP_DATO,DP_DAT_CHK_q,MSK_CHK_q)
738
    variable B : std_logic_vector(8-1 downto 0);
739
    variable B_CHK : std_logic_vector(8-1 downto 0);
740
    variable ERRV : std_logic_vector(4-1 downto 0);
741
  begin
742
    for k in 0 to 4-1 loop
743
      -- get k-th byte from actual and expected results
744
      B := DP_DATO((k+1)*8-1 downto k*8);
745
      B_CHK := DP_DAT_CHK_q((k+1)*8-1 downto k*8);
746
      -- compare them
747
      if(B /= B_CHK) then
748
        ERRV(k) := MSK_CHK_q(k);
749
      else
750
        ERRV(k) := '0';
751
      end if;
752
    end loop;
753
    -- get overall error flag
754
    if(ERRV = "0000") then
755
      ERROR <= '0';
756
    else
757
      ERROR <= '1';
758
     end if;
759
  end process;
760
 
761
  -- Error count register
762
 
763
  process(CLK_i)
764
  begin
765
    if(CLK_i = '1' and CLK_i'event) then
766
      if(RST_i = '1') then
767
        ERR_CNT_q <= 0;
768
      elsif(READF_q2 = '1' and ERROR = '1') then
769
        ERR_CNT_q <= ERR_CNT_q + 1;
770
      end if;
771
    end if;
772
  end process;
773
 
774
  -- Test pass flag register (test is a pass
775
  -- if error count is zero when test completes)
776
 
777
  process(CLK_i)
778
  begin
779
    if(CLK_i = '1' and CLK_i'event) then
780
      if(RST_i = '1') then
781
        PASS_q <= '0';
782
      elsif(DONE = '1' and ERR_CNT_q = 0) then
783
        PASS_q <= '1';
784
      end if;
785
    end if;
786
  end process;
787
 
788
  PASS_o <= PASS_q;
789
  DONE_o <= DONE_q;
790
 
791
  ---------------------------------------------------
792
  -- Read/Write word (down-) counter
793
  ---------------------------------------------------
794
 
795
  -- This counter counts the data/instructions words
796
  -- to be read from memory, or written to memory.
797
 
798
  -- Data word start count
799
  CNTD_INIT <=
800
    CNTD_W_INIT when (WRITDF_q = '0' and WRITDF = '1') else
801
    CNTD_R_INIT;
802
 
803
  -- Instruction word start count
804
  CNTI_INIT <= IMEM_SIZE-1;
805
 
806
  -- Instruction word down-counter
807
  process(CLK_i)
808
  begin
809
    if(CLK_i = '1' and CLK_i'event) then
810
      if(CNTI_RST_i = '1') then
811
        CNTI_q <= CNTI_INIT;
812
      elsif(CNTI_q > 0) then
813
        CNTI_q <= CNTI_q - 1;
814
      end if;
815
    end if;
816
  end process;
817
 
818
  -- Data word down-counter
819
  process(CLK_i)
820
  begin
821
    if(CLK_i = '1' and CLK_i'event) then
822
      if(CNTD_RST_i = '1') then
823
        CNTD_q <= 0;
824
      elsif(
825
        (WRITDF_q = '0' and WRITDF = '1') or
826
        (READF_q = '0' and READ_OP = '1')
827
      ) then
828
        CNTD_q <= CNTD_INIT;
829
      elsif(CNTD_q > 0) then
830
        CNTD_q <= CNTD_q - 1;
831
      end if;
832
    end if;
833
  end process;
834
 
835
  ---------------------------------------------------
836
  -- Run counter
837
  ---------------------------------------------------
838
 
839
  -- This counter counts Dhrystone core loop iterations,
840
  -- when count reaches CNTR_MAX-1 value, CNTR_END flag
841
  -- is set to '1'.
842
 
843
  process(CLK_i)
844
  begin
845
    if(CLK_i = '1' and CLK_i'event) then
846
      if(RST_i = '1') then
847
        CNTR_q <= 0;
848
      elsif(CNTR_INC = '1' and CNTR_q < CNTR_MAX - 1) then
849
        CNTR_q <= CNTR_q + 1;
850
      end if;
851
    end if;
852
  end process;
853
 
854
  CNTR_END <= '1' when (CNTR_q = CNTR_MAX - 1) else '0';
855
 
856
  ---------------------------------------------------
857
  -- RV01 core instance
858
  ---------------------------------------------------
859
 
860
  DP_ADR <= WADR when (WRITIF_q = '1' or WRITDF_q = '1') else RADR;
861
 
862
  U_RVTOP : RV01_TOP_NOHOST
863
    generic map(
864
      -- synthesis translate_off
865
      ST_FILE => "NONE",
866
      WB_FILE => "NONE",
867
      -- synthesis translate_on
868
      IMEM_SIZE => IMEM_SIZE,
869
      DMEM_SIZE => DMEM_SIZE,
870
      IOMEM_SIZE => IOMEM_SIZE,
871
      IMEM_SIZE_PO2 => IMEM_SIZE_PO2,
872
      DMEM_SIZE_PO2 => DMEM_SIZE_PO2,
873
      IMEM_LOWM => IMEM_LOWM,
874
      BHT_SIZE => BHT_SIZE,
875
      EI_SRC_CNT => EI_SRC_CNT,
876
      EI_TRIG_TYPE => EI_TRIG_TYPE,
877
      EI_REQ_MAXCNT => EI_REQ_MAXCNT,
878
      CFG_FLAGS => "00000000"&CFG_FLAGS,
879
      SIMULATION_ONLY => '0'
880
    )
881
    port map(
882
      CLK_i => CLK_i,
883
      RST_i => RST_i,
884
      EI_REQ_i => EI_REQ,
885
      DP_WE_i => DP_WE,
886
      DP_ADR_i => DP_ADR,
887
      DP_DAT_i => DP_DATI,
888
      CP_RE_i => CP_RE,
889
      CP_WE_i => CP_WE,
890
      CP_ADR_i => CP_ADR,
891
      CP_DAT_i => CP_DATI,
892
 
893
      DP_DAT_o => DP_DATO,
894
      CP_DAT_o => CP_DATO
895
    );
896
 
897
end ARC;

powered by: WebSVN 2.1.0

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