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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [bench/] [verilog/] [or1200_monitor.v] - Blame information for rev 348

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 348 julius
//
2
// Or1200 Monitor
3
//
4 6 julius
//////////////////////////////////////////////////////////////////////
5
////                                                              ////
6 348 julius
//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG           ////
7 6 julius
////                                                              ////
8
//// This source file may be used and distributed without         ////
9
//// restriction provided that this copyright statement is not    ////
10
//// removed from the file and that any derivative work contains  ////
11
//// the original copyright notice and the associated disclaimer. ////
12
////                                                              ////
13
//// This source file is free software; you can redistribute it   ////
14
//// and/or modify it under the terms of the GNU Lesser General   ////
15
//// Public License as published by the Free Software Foundation; ////
16
//// either version 2.1 of the License, or (at your option) any   ////
17
//// later version.                                               ////
18
////                                                              ////
19
//// This source is distributed in the hope that it will be       ////
20
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
21
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
22
//// PURPOSE.  See the GNU Lesser General Public License for more ////
23
//// details.                                                     ////
24
////                                                              ////
25
//// You should have received a copy of the GNU Lesser General    ////
26
//// Public License along with this source; if not, download it   ////
27
//// from http://www.opencores.org/lgpl.shtml                     ////
28
////                                                              ////
29
//////////////////////////////////////////////////////////////////////
30 67 julius
 
31 55 julius
`include "timescale.v"
32 6 julius
`include "or1200_defines.v"
33
 
34
//
35
// Top of OR1200 inside test bench
36
//
37 67 julius
`ifndef OR1200_TOP
38
 `define OR1200_TOP orpsoc_testbench.dut.i_or1k.i_or1200_top
39
 `include "orpsoc_testbench_defines.v"
40
`else
41
 `include `TESTBENCH_DEFINES
42
`endif
43 6 julius
//
44
// Enable display_arch_state task
45
//
46
//`define OR1200_DISPLAY_ARCH_STATE
47
 
48 348 julius
//
49
// Top of OR1200 inside test bench
50
//
51
`define CPU or1200
52
`define CPU_cpu or1200_cpu
53
`define CPU_rf or1200_rf
54
`define CPU_except or1200_except
55
`define CPU_ctrl or1200_ctrl
56
`define CPU_sprs or1200_sprs
57
 
58 6 julius
module or1200_monitor;
59
 
60
   integer fexe;
61
   reg [23:0] ref;
62
   integer    fspr;
63
   integer    fgeneral;
64
   integer    flookup;
65
   integer    r3;
66
   integer    insns;
67
 
68 348 julius
 
69 6 julius
   //
70
   // Initialization
71
   //
72
   initial begin
73
      ref = 0;
74
      fexe = $fopen({`TEST_RESULTS_DIR,`TEST_NAME_STRING,"-executed.log"});
75
      $timeformat (-9, 2, " ns", 12);
76
      fspr = $fopen({`TEST_RESULTS_DIR,`TEST_NAME_STRING,"-sprs.log"});
77
      fgeneral = $fopen({`TEST_RESULTS_DIR,`TEST_NAME_STRING,"-general.log"});
78
      flookup = $fopen({`TEST_RESULTS_DIR,`TEST_NAME_STRING,"-lookup.log"});
79
      insns = 0;
80
 
81
   end
82
 
83
   //
84
   // Get GPR
85
   //
86
   task get_gpr;
87
      input     [4:0]    gpr_no;
88
      output [31:0]      gpr;
89
      integer           j;
90
      begin
91 348 julius
 
92
 `ifdef OR1200_RFRAM_GENERIC
93 6 julius
         for(j = 0; j < 32; j = j + 1) begin
94 348 julius
            gpr[j] = `OR1200_TOP.`CPU_cpu.`CPU_rf.rf_a.mem[gpr_no*32+j];
95 6 julius
         end
96 348 julius
 
97 67 julius
 `else
98 348 julius
         //gpr = `OR1200_TOP.`CPU_cpu.`CPU_rf.rf_a.mem[gpr_no];
99
         gpr = `OR1200_TOP.`CPU_cpu.`CPU_rf.rf_a.get_gpr(gpr_no);
100
 
101
 `endif
102 6 julius
 
103 348 julius
 
104
      end
105
   endtask
106
 
107 6 julius
   //
108
   // Write state of the OR1200 registers into a file
109
   //
110
   // Limitation: only a small subset of register file RAMs
111
   // are supported
112
   //
113
   task display_arch_state;
114
      reg [5:0] i;
115
      reg [31:0] r;
116
      integer    j;
117
      begin
118
`ifdef OR1200_DISPLAY_ARCH_STATE
119
         ref = ref + 1;
120
         $fdisplay(flookup, "Instruction %d: %t", insns, $time);
121 348 julius
         $fwrite(fexe, "\nEXECUTED(%d): %h:  %h", insns, `OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc, `OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn);
122 6 julius
         for(i = 0; i < 32; i = i + 1) begin
123
            if (i % 4 == 0)
124
              $fdisplay(fexe);
125
            get_gpr(i, r);
126
            $fwrite(fexe, "GPR%d: %h  ", i, r);
127
         end
128
         $fdisplay(fexe);
129 348 julius
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.sr;
130 6 julius
         $fwrite(fexe, "SR   : %h  ", r);
131 348 julius
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.epcr;
132 6 julius
         $fwrite(fexe, "EPCR0: %h  ", r);
133 348 julius
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.eear;
134 6 julius
         $fwrite(fexe, "EEAR0: %h  ", r);
135 348 julius
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.esr;
136 6 julius
         $fdisplay(fexe, "ESR0 : %h", r);
137 348 julius
`endif //  `ifdef OR1200_DISPLAY_ARCH_STATE
138
`ifdef OR1200_DISPLAY_EXECUTED
139
         ref = ref + 1;
140
         $fdisplay(flookup, "Instruction %d: %t", insns, $time);
141
         $fwrite(fexe, "\nEXECUTED(%d): %h:  %h", insns, `OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc, `OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn);
142 6 julius
`endif
143 348 julius
         insns = insns + 1;
144 6 julius
end
145
   endtask // display_arch_state
146
 
147
   /* Keep a trace buffer of the last lot of instructions and addresses
148
    * "executed",as read from the writeback stage, and cause a $finish if we hit
149
    * an instruction that is invalid, such as all zeros.
150
    * Currently, only breaks on an all zero instruction, but should probably be
151
    * made to break for anything with an X in it too. And of course ideally this
152
    * shouldn't be needed - but is handy if someone changes something and stops
153
    * the test continuing forever.
154
    */
155 49 julius
   integer num_nul_inst;
156
   initial num_nul_inst = 0;
157
 
158 6 julius
   task monitor_for_crash;
159 348 julius
`define OR1200_MONITOR_CRASH_TRACE_SIZE 32
160
      //Trace buffer of 32 instructions
161
      reg [31:0] insn_trace [0:`OR1200_MONITOR_CRASH_TRACE_SIZE-1];
162
      //Trace buffer of the addresses of those instructions
163
      reg [31:0] addr_trace [0:`OR1200_MONITOR_CRASH_TRACE_SIZE-1];
164 6 julius
      integer i;
165
 
166
     begin
167 348 julius
        if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h00000000)
168 49 julius
          num_nul_inst = num_nul_inst + 1;
169 348 julius
        else
170
          num_nul_inst = 0; // Reset it
171 49 julius
 
172
        if (num_nul_inst == 1000) // Sat a loop a bit too long...
173 6 julius
          begin
174 348 julius
             $fdisplay(fgeneral, "ERROR - no instruction at PC %h",
175
                       `OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc);
176
             $fdisplay(fgeneral, "Crash trace: Last %d instructions: ",
177
                       `OR1200_MONITOR_CRASH_TRACE_SIZE);
178 6 julius
 
179
             $fdisplay(fgeneral, "PC\t\tINSTR");
180
             for(i=`OR1200_MONITOR_CRASH_TRACE_SIZE-1;i>=0;i=i-1) begin
181
                $fdisplay(fgeneral, "%h\t%h",addr_trace[i], insn_trace[i]);
182
             end
183
             #100 $finish;
184
          end
185
        else
186
          begin
187
             for(i=`OR1200_MONITOR_CRASH_TRACE_SIZE-1;i>0;i=i-1) begin
188
                insn_trace[i] = insn_trace[i-1];
189
                addr_trace[i] = addr_trace[i-1];
190
             end
191 348 julius
             insn_trace[0] = `OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn;
192
             addr_trace[0] = `OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc;
193 6 julius
          end
194
 
195
     end
196
   endtask // monitor_for_crash
197 348 julius
 
198 6 julius
 
199 348 julius
   //
200
   // Write state of the OR1200 registers into a file; version for exception
201
   //
202
   task display_arch_state_except;
203
      reg [5:0] i;
204
      reg [31:0] r;
205
      integer    j;
206
      begin
207
`ifdef OR1200_DISPLAY_ARCH_STATE
208
         ref = ref + 1;
209
         $fdisplay(flookup, "Instruction %d: %t", insns, $time);
210
         $fwrite(fexe, "\nEXECUTED(%d): %h:  %h  (exception)", insns, `OR1200_TOP.`CPU_cpu.`CPU_except.ex_pc, `OR1200_TOP.`CPU_cpu.`CPU_ctrl.ex_insn);
211
         for(i = 0; i < 32; i = i + 1) begin
212
            if (i % 4 == 0)
213
              $fdisplay(fexe);
214
            get_gpr(i, r);
215
            $fwrite(fexe, "GPR%d: %h  ", i, r);
216
         end
217
         $fdisplay(fexe);
218
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.sr;
219
         $fwrite(fexe, "SR   : %h  ", r);
220
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.epcr;
221
         $fwrite(fexe, "EPCR0: %h  ", r);
222
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.eear;
223
         $fwrite(fexe, "EEAR0: %h  ", r);
224
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.esr;
225
         $fdisplay(fexe, "ESR0 : %h", r);
226
         insns = insns + 1;
227
`endif //  `ifdef OR1200_DISPLAY_ARCH_STATE
228
`ifdef OR1200_DISPLAY_EXECUTED
229
         ref = ref + 1;
230
         $fdisplay(flookup, "Instruction %d: %t", insns, $time);
231
         $fwrite(fexe, "\nEXECUTED(%d): %h:  %h  (exception)", insns,
232
                 `OR1200_TOP.`CPU_cpu.`CPU_except.ex_pc,
233
                 `OR1200_TOP.`CPU_cpu.`CPU_ctrl.ex_insn);
234
         insns = insns + 1;
235
`endif
236
 
237
end
238
   endtask
239
 
240 6 julius
   integer iwb_progress;
241
   reg [31:0] iwb_progress_addr;
242
   //
243
   // WISHBONE bus checker
244
   //
245
   always @(posedge `OR1200_TOP.iwb_clk_i)
246
     if (`OR1200_TOP.iwb_rst_i) begin
247
        iwb_progress = 0;
248
        iwb_progress_addr = `OR1200_TOP.iwb_adr_o;
249
     end
250
     else begin
251
        if (`OR1200_TOP.iwb_cyc_o && (iwb_progress != 2)) begin
252
           iwb_progress = 1;
253
        end
254
        if (`OR1200_TOP.iwb_stb_o) begin
255
           if (iwb_progress >= 1) begin
256
              if (iwb_progress == 1)
257
                iwb_progress_addr = `OR1200_TOP.iwb_adr_o;
258
              iwb_progress = 2;
259
           end
260
           else begin
261
              $fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.iwb_stb_o raised without `OR1200_TOP.iwb_cyc_o, at %t\n", $time);
262
              #100 $finish;
263
           end
264
        end
265
        if (`OR1200_TOP.iwb_ack_i & `OR1200_TOP.iwb_err_i) begin
266
           $fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.iwb_ack_i and `OR1200_TOP.iwb_err_i raised at the same time, at %t\n", $time);
267
        end
268
        if ((iwb_progress == 2) && (iwb_progress_addr != `OR1200_TOP.iwb_adr_o)) begin
269
           $fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.iwb_adr_o changed while waiting for `OR1200_TOP.iwb_err_i/`OR1200_TOP.iwb_ack_i, at %t\n", $time);
270
           #100 $finish;
271
        end
272
        if (`OR1200_TOP.iwb_ack_i | `OR1200_TOP.iwb_err_i)
273
          if (iwb_progress == 2) begin
274
             iwb_progress = 0;
275
             iwb_progress_addr = `OR1200_TOP.iwb_adr_o;
276
          end
277
          else begin
278
             $fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.iwb_ack_i/`OR1200_TOP.iwb_err_i raised without `OR1200_TOP.iwb_cyc_i/`OR1200_TOP.iwb_stb_i, at %t\n", $time);
279
             #100 $finish;
280
          end
281
        if ((iwb_progress == 2) && !`OR1200_TOP.iwb_stb_o) begin
282
           $fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.iwb_stb_o lowered without `OR1200_TOP.iwb_err_i/`OR1200_TOP.iwb_ack_i, at %t\n", $time);
283 348 julius
           #100 $finish;
284 6 julius
        end
285
     end
286
 
287
   integer dwb_progress;
288
reg [31:0] dwb_progress_addr;
289
//
290
// WISHBONE bus checker
291
//
292
always @(posedge `OR1200_TOP.dwb_clk_i)
293
  if (`OR1200_TOP.dwb_rst_i)
294
    dwb_progress = 0;
295
  else begin
296
     if (`OR1200_TOP.dwb_cyc_o && (dwb_progress != 2))
297
       dwb_progress = 1;
298
     if (`OR1200_TOP.dwb_stb_o)
299
       if (dwb_progress >= 1) begin
300
          if (dwb_progress == 1)
301
            dwb_progress_addr = `OR1200_TOP.dwb_adr_o;
302
          dwb_progress = 2;
303
       end
304
       else begin
305
          $fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.dwb_stb_o raised without `OR1200_TOP.dwb_cyc_o, at %t\n", $time);
306
          #100 $finish;
307
       end
308
     if (`OR1200_TOP.dwb_ack_i & `OR1200_TOP.dwb_err_i) begin
309
        $fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.dwb_ack_i and `OR1200_TOP.dwb_err_i raised at the same time, at %t\n", $time);
310
     end
311
     if ((dwb_progress == 2) && (dwb_progress_addr != `OR1200_TOP.dwb_adr_o)) begin
312
        $fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.dwb_adr_o changed while waiting for `OR1200_TOP.dwb_err_i/`OR1200_TOP.dwb_ack_i, at %t\n", $time);
313
        #100 $finish;
314
     end
315
     if (`OR1200_TOP.dwb_ack_i | `OR1200_TOP.dwb_err_i)
316
       if (dwb_progress == 2) begin
317
          dwb_progress = 0;
318
          dwb_progress_addr = `OR1200_TOP.dwb_adr_o;
319
       end
320
       else begin
321
          $fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.dwb_ack_i/`OR1200_TOP.dwb_err_i raised without `OR1200_TOP.dwb_cyc_i/`OR1200_TOP.dwb_stb_i, at %t\n", $time);
322
          #100 $finish;
323
       end
324
     if ((dwb_progress == 2) && !`OR1200_TOP.dwb_stb_o) begin
325
        $fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.dwb_stb_o lowered without `OR1200_TOP.dwb_err_i/`OR1200_TOP.dwb_ack_i, at %t\n", $time);
326
        #100 $finish;
327
     end
328
       end
329
 
330
//
331
// Hooks for:
332
// - displaying registers
333
// - end of simulation
334
// - access to SPRs
335
//
336 348 julius
   always @(posedge `OR1200_TOP.`CPU_cpu.`CPU_ctrl.clk)
337
     if (!`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_freeze) begin
338
//      #2;
339
        if (((`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn[31:26] != `OR1200_OR32_NOP)
340
             | !`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn[16])
341
            & !(`OR1200_TOP.`CPU_cpu.`CPU_except.except_flushpipe &
342
                `OR1200_TOP.`CPU_cpu.`CPU_except.ex_dslot))
343 6 julius
          begin
344
             display_arch_state;
345
             monitor_for_crash;
346
          end
347
        else
348 348 julius
          if (`OR1200_TOP.`CPU_cpu.`CPU_except.except_flushpipe)
349 6 julius
            display_arch_state_except;
350 348 julius
        // small hack to stop simulation (l.nop 1):
351
        if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_0001) begin
352 6 julius
           get_gpr(3, r3);
353
           $fdisplay(fgeneral, "%t: l.nop exit (%h)", $time, r3);
354
           $finish;
355
        end
356 348 julius
        // debug if test (l.nop 10)
357
        if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_000a) begin
358 6 julius
           $fdisplay(fgeneral, "%t: l.nop dbg_if_test", $time);
359
`ifdef DBG_IF_MODEL
360
           xess_top.i_xess_fpga.dbg_if_model.dbg_if_test_go = 1;
361
`endif
362
        end
363 348 julius
        // simulation reports (l.nop 2)
364
        if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_0002) begin
365 6 julius
           get_gpr(3, r3);
366 348 julius
           $fdisplay(fgeneral, "%t: l.nop report (%h)", $time, r3);
367
        end
368
        // simulation printfs (l.nop 3)
369
        if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_0003) begin
370
           get_gpr(3, r3);
371 6 julius
           $fdisplay(fgeneral, "%t: l.nop printf (%h)", $time, r3);
372
        end
373 348 julius
        if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_0004) begin
374
           // simulation putc (l.nop 4)
375
           get_gpr(3, r3);
376
           $write("%c", r3);
377
           $fdisplay(fgeneral, "%t: l.nop putc (%c)", $time, r3);
378
        end
379
        if (`OR1200_TOP.`CPU_cpu.alu_op/*`CPU_sprs.sprs_op*/ ==
380
            `OR1200_ALUOP_MTSR)  // l.mtspr
381 6 julius
          $fdisplay(fspr, "%t: Write to SPR : [%h] <- %h", $time,
382 348 julius
                    `OR1200_TOP.`CPU_cpu.alu_op/*`CPU_sprs.spr_addr*/,
383
                    `OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_dat_o);
384
        if (`OR1200_TOP.`CPU_cpu.alu_op/*`CPU_sprs.sprs_op*/ ==
385
            `OR1200_ALUOP_MFSR)  // l.mfspr
386 6 julius
          $fdisplay(fspr, "%t: Read from SPR: [%h] -> %h", $time,
387 348 julius
                    `OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_addr,
388
                    `OR1200_TOP.`CPU_cpu.`CPU_sprs.to_wbmux);
389 6 julius
     end
390
 
391 348 julius
 
392
`ifdef VERSATILE_SDRAM
393
 `define SDRAM_TOP design_testbench.sdram0
394
   // Bit selects to define the bank
395
   // 32 MB part with 4 banks
396
 `define SDRAM_BANK_SEL_BITS 24:23
397
 `define SDRAM_WORD_SEL_TOP_BIT 22
398
   // Gets instruction word from correct bank
399
   task get_insn_from_sdram;
400
      input [31:0] addr;
401
      output [31:0] insn;
402
      reg [`SDRAM_WORD_SEL_TOP_BIT-1:0] word_addr;
403
 
404
      begin
405
         word_addr = addr[`SDRAM_WORD_SEL_TOP_BIT:2];
406
         if (addr[`SDRAM_BANK_SEL_BITS] == 2'b00)
407
           begin
408
 
409
              //$display("%t: get_insn_from_sdram bank0, word 0x%h, (%h and %h in SDRAM)", $time, word_addr, `SDRAM_TOP.Bank0[{word_addr,1'b0}], `SDRAM_TOP.Bank0[{word_addr,1'b1}]);         
410
              insn[15:0] = `SDRAM_TOP.Bank0[{word_addr,1'b1}];
411
              insn[31:16] = `SDRAM_TOP.Bank0[{word_addr,1'b0}];
412
           end
413
      end
414
 
415
   endtask // get_insn_from_sdram
416
`endif //  `ifdef VERSATILE_SDRAM
417
 
418
`ifdef XILINX_DDR2
419
 `define DDR2_TOP design_testbench.gen_cs[0]
420
   // Gets instruction word from correct bank
421
   task get_insn_from_xilinx_ddr2;
422
      input [31:0] addr;
423
      output [31:0] insn;
424
      reg [16*8-1:0] ddr2_array_line0,ddr2_array_line1,ddr2_array_line2,ddr2_array_line3;
425
      integer        word_in_line_num;
426
      begin
427
        // Get our 4 128-bit chunks (8 half-words in each!! Confused yet?), 16 words total
428
         `DDR2_TOP.gen[0].u_mem0.memory_read(addr[28:27],addr[26:13],{addr[12:6],3'd0},ddr2_array_line0);
429
         `DDR2_TOP.gen[1].u_mem0.memory_read(addr[28:27],addr[26:13],{addr[12:6],3'd0},ddr2_array_line1);
430
         `DDR2_TOP.gen[2].u_mem0.memory_read(addr[28:27],addr[26:13],{addr[12:6],3'd0},ddr2_array_line2);
431
         `DDR2_TOP.gen[3].u_mem0.memory_read(addr[28:27],addr[26:13],{addr[12:6],3'd0},ddr2_array_line3);
432
         case (addr[5:2])
433
           4'h0:
434
             begin
435
                insn[15:0] = ddr2_array_line0[15:0];
436
                insn[31:16] = ddr2_array_line1[15:0];
437
             end
438
           4'h1:
439
             begin
440
                insn[15:0] = ddr2_array_line2[15:0];
441
                insn[31:16] = ddr2_array_line3[15:0];
442
             end
443
           4'h2:
444
             begin
445
                insn[15:0] = ddr2_array_line0[31:16];
446
                insn[31:16] = ddr2_array_line1[31:16];
447
             end
448
           4'h3:
449
             begin
450
                insn[15:0] = ddr2_array_line2[31:16];
451
                insn[31:16] = ddr2_array_line3[31:16];
452
             end
453
           4'h4:
454
             begin
455
                insn[15:0] = ddr2_array_line0[47:32];
456
                insn[31:16] = ddr2_array_line1[47:32];
457
             end
458
           4'h5:
459
             begin
460
                insn[15:0] = ddr2_array_line2[47:32];
461
                insn[31:16] = ddr2_array_line3[47:32];
462
             end
463
           4'h6:
464
             begin
465
                insn[15:0] = ddr2_array_line0[63:48];
466
                insn[31:16] = ddr2_array_line1[63:48];
467
             end
468
           4'h7:
469
             begin
470
                insn[15:0] = ddr2_array_line2[63:48];
471
                insn[31:16] = ddr2_array_line3[63:48];
472
             end
473
           4'h8:
474
             begin
475
                insn[15:0] = ddr2_array_line0[79:64];
476
                insn[31:16] = ddr2_array_line1[79:64];
477
             end
478
           4'h9:
479
             begin
480
                insn[15:0] = ddr2_array_line2[79:64];
481
                insn[31:16] = ddr2_array_line3[79:64];
482
             end
483
           4'ha:
484
             begin
485
                insn[15:0] = ddr2_array_line0[95:80];
486
                insn[31:16] = ddr2_array_line1[95:80];
487
             end
488
           4'hb:
489
             begin
490
                insn[15:0] = ddr2_array_line2[95:80];
491
                insn[31:16] = ddr2_array_line3[95:80];
492
             end
493
           4'hc:
494
             begin
495
                insn[15:0] = ddr2_array_line0[111:96];
496
                insn[31:16] = ddr2_array_line1[111:96];
497
             end
498
           4'hd:
499
             begin
500
                insn[15:0] = ddr2_array_line2[111:96];
501
                insn[31:16] = ddr2_array_line3[111:96];
502
             end
503
           4'he:
504
             begin
505
                insn[15:0] = ddr2_array_line0[127:112];
506
                insn[31:16] = ddr2_array_line1[127:112];
507
             end
508
           4'hf:
509
             begin
510
                insn[15:0] = ddr2_array_line2[127:112];
511
                insn[31:16] = ddr2_array_line3[127:112];
512
             end
513
         endcase // case (addr[5:2])
514
      end
515
   endtask // get_insn_from_xilinx_ddr2
516
`endif
517
 
518
 
519
   task get_insn_from_memory;
520
      input [31:0] id_pc;
521
      output [31:0] insn;
522
      begin
523
         // do a decode of which server we should look in
524
         case (id_pc[31:28])
525
`ifdef VERSATILE_SDRAM
526
           4'h0:
527
             get_insn_from_sdram(id_pc, insn);
528
`endif
529
`ifdef XILINX_DDR2
530
           4'h0:
531
             get_insn_from_xilinx_ddr2(id_pc, insn);
532
`endif
533
           4'hf:
534
             // Flash isn't stored in a memory, it's an FSM so just skip/ignore
535
             insn = `OR1200_TOP.`CPU_cpu.`CPU_ctrl.id_insn;
536
           default:
537
             begin
538
                $fdisplay(fgeneral, "%t: Unknown memory server for address 0x%h", $time,id_pc);
539
                insn = 32'hxxxxxxxx; // Unknown server
540
             end
541
         endcase // case (id_pc[31:28])
542
      end
543
   endtask // get_insn_from_memory
544
 
545
 
546
    reg [31:0] mem_word;
547
   reg [31:0] last_addr = 0;
548
   reg [31:0] last_mem_word;
549
 
550
//`define TRIGGER_FOR_CHECK (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.id_void === 1'b0)
551
   // Disabled:
552
`define TRIGGER_FOR_CHECK 0
553
`define INSN_TO_CHECK `OR1200_TOP.`CPU_cpu.`CPU_ctrl.id_insn
554
`define PC_TO_CHECK `OR1200_TOP.`CPU_cpu.`CPU_except.id_pc
555
 
556
   // Check instruction in decode stage is what is in the RAM
557
   always @(posedge `OR1200_TOP.`CPU_cpu.`CPU_ctrl.clk)
558
     begin
559
        if (`TRIGGER_FOR_CHECK)
560
          begin
561
             // Check if it's a new PC - will also get triggered if the
562
             // instruction has changed since we last checked it
563
             if ((`PC_TO_CHECK !== last_addr) ||
564
                 (last_mem_word != `INSN_TO_CHECK))
565
               begin
566
                  // Decode stage not void, check instruction
567
                  // get PC
568
                  get_insn_from_memory(`PC_TO_CHECK, mem_word);
569
 
570
                  // Debugging output to prove it's doing something!
571
                  //$display("%t: Checking instruction for address 0x%h - memory had 0x%h, CPU had 0x%h", $time, `PC_TO_CHECK, mem_word, `INSN_TO_CHECK);
572
 
573
                  if (mem_word !== `INSN_TO_CHECK)
574
                    begin
575
                       $fdisplay(fgeneral, "%t: Instruction mismatch for address 0x%h - memory had 0x%h, CPU had 0x%h", $time, `PC_TO_CHECK, mem_word, `INSN_TO_CHECK);
576
                       #20
577
                         $finish;
578
                    end
579
                  last_addr = `PC_TO_CHECK;
580
                  last_mem_word = mem_word;
581
               end // if (`PC_TO_CHECK !== last_addr)
582
          end
583
     end // always @ (posedge `OR1200_TOP.`CPU_cpu.`CPU_ctrl.clk)
584
 
585
 
586
 
587
 
588
 
589 6 julius
endmodule

powered by: WebSVN 2.1.0

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