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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 6 julius
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3 360 julius
////  or1200_monitor                                              ////
4
////                                                              ////
5
////  OR1200 processor monitor module                             ////
6
////                                                              ////
7
//////////////////////////////////////////////////////////////////////
8
////                                                              ////
9 348 julius
//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG           ////
10 6 julius
////                                                              ////
11
//// This source file may be used and distributed without         ////
12
//// restriction provided that this copyright statement is not    ////
13
//// removed from the file and that any derivative work contains  ////
14
//// the original copyright notice and the associated disclaimer. ////
15
////                                                              ////
16
//// This source file is free software; you can redistribute it   ////
17
//// and/or modify it under the terms of the GNU Lesser General   ////
18
//// Public License as published by the Free Software Foundation; ////
19
//// either version 2.1 of the License, or (at your option) any   ////
20
//// later version.                                               ////
21
////                                                              ////
22
//// This source is distributed in the hope that it will be       ////
23
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
24
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
25
//// PURPOSE.  See the GNU Lesser General Public License for more ////
26
//// details.                                                     ////
27
////                                                              ////
28
//// You should have received a copy of the GNU Lesser General    ////
29
//// Public License along with this source; if not, download it   ////
30
//// from http://www.opencores.org/lgpl.shtml                     ////
31
////                                                              ////
32
//////////////////////////////////////////////////////////////////////
33 67 julius
 
34 55 julius
`include "timescale.v"
35 6 julius
`include "or1200_defines.v"
36 360 julius
`include "orpsoc-testbench-defines.v"
37
`include "test-defines.v"
38 351 julius
 
39 6 julius
//
40
// Top of OR1200 inside test bench
41
//
42 360 julius
`define OR1200_TOP orpsoc_testbench.dut.or1200_top
43
 
44 397 julius
//
45
// Define to enable lookup file generation
46
//
47
//`define OR1200_MONITOR_LOOKUP
48 360 julius
 
49 6 julius
//
50 397 julius
// Define to enable SPR access log file generation
51 6 julius
//
52 397 julius
//`define OR1200_MONITOR_SPRS
53 6 julius
 
54 348 julius
//
55 397 julius
// Enable logging of state during execution
56 351 julius
//
57 397 julius
//`define OR1200_MONITOR_EXEC_STATE
58
 
59
//
60
// Enable disassembly of instructions in execution state log
61
//
62 360 julius
//`define OR1200_MONITOR_PRINT_DISASSEMBLY
63 351 julius
 
64 397 julius
// Can either individually enable things above, or usually have the scripts
65
// running the simulation pass the PROCESSOR_MONITOR_ENABLE_LOGS define to
66
// enable them all.
67 351 julius
 
68 397 julius
`ifdef PROCESSOR_MONITOR_ENABLE_LOGS
69
 `define OR1200_MONITOR_EXEC_STATE
70
 `define OR1200_MONITOR_SPRS
71
 `define OR1200_MONITOR_LOOKUP
72
`endif
73
 
74 351 julius
//
75 348 julius
// Top of OR1200 inside test bench
76
//
77
`define CPU or1200
78
`define CPU_cpu or1200_cpu
79
`define CPU_rf or1200_rf
80
`define CPU_except or1200_except
81
`define CPU_ctrl or1200_ctrl
82
`define CPU_sprs or1200_sprs
83
 
84 6 julius
module or1200_monitor;
85
 
86
   integer fexe;
87
   reg [23:0] ref;
88 397 julius
`ifdef OR1200_MONITOR_SPRS
89 6 julius
   integer    fspr;
90 397 julius
`endif
91 6 julius
   integer    fgeneral;
92 397 julius
`ifdef OR1200_MONITOR_LOOKUP
93 6 julius
   integer    flookup;
94 397 julius
`endif
95 6 julius
   integer    r3;
96
   integer    insns;
97
 
98 348 julius
 
99 6 julius
   //
100
   // Initialization
101
   //
102
   initial begin
103
      ref = 0;
104 397 julius
`ifdef OR1200_MONITOR_EXEC_STATE
105 360 julius
      fexe = $fopen({"../out/",`TEST_NAME_STRING,"-executed.log"});
106 397 julius
`endif
107 6 julius
      $timeformat (-9, 2, " ns", 12);
108 397 julius
`ifdef OR1200_MONITOR_SPRS
109 360 julius
      fspr = $fopen({"../out/",`TEST_NAME_STRING,"-sprs.log"});
110 397 julius
`endif
111 360 julius
      fgeneral = $fopen({"../out/",`TEST_NAME_STRING,"-general.log"});
112 397 julius
`ifdef OR1200_MONITOR_LOOKUP
113 360 julius
      flookup = $fopen({"../out/",`TEST_NAME_STRING,"-lookup.log"});
114 397 julius
`endif
115 6 julius
      insns = 0;
116
 
117
   end
118
 
119
   //
120
   // Get GPR
121
   //
122
   task get_gpr;
123
      input     [4:0]    gpr_no;
124
      output [31:0]      gpr;
125
      integer           j;
126
      begin
127 348 julius
 
128
 `ifdef OR1200_RFRAM_GENERIC
129 6 julius
         for(j = 0; j < 32; j = j + 1) begin
130 348 julius
            gpr[j] = `OR1200_TOP.`CPU_cpu.`CPU_rf.rf_a.mem[gpr_no*32+j];
131 6 julius
         end
132 348 julius
 
133 67 julius
 `else
134 348 julius
         //gpr = `OR1200_TOP.`CPU_cpu.`CPU_rf.rf_a.mem[gpr_no];
135
         gpr = `OR1200_TOP.`CPU_cpu.`CPU_rf.rf_a.get_gpr(gpr_no);
136
 
137
 `endif
138 6 julius
 
139 348 julius
 
140
      end
141
   endtask
142
 
143 6 julius
   //
144
   // Write state of the OR1200 registers into a file
145
   //
146
   // Limitation: only a small subset of register file RAMs
147
   // are supported
148
   //
149
   task display_arch_state;
150
      reg [5:0] i;
151
      reg [31:0] r;
152
      integer    j;
153
      begin
154 397 julius
`ifdef OR1200_MONITOR_EXEC_STATE
155 6 julius
         ref = ref + 1;
156 397 julius
 `ifdef OR1200_MONITOR_LOOKUP
157 6 julius
         $fdisplay(flookup, "Instruction %d: %t", insns, $time);
158 397 julius
 `endif
159 351 julius
         $fwrite(fexe, "\nEXECUTED(%d): %h:  %h", insns,
160
                 `OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc,
161
                 `OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn);
162
 `ifdef OR1200_MONITOR_PRINT_DISASSEMBLY
163
         $fwrite(fexe,"\t");
164
         // Decode the instruction, print it out
165
         or1200_print_op(`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn);
166
 `endif
167 6 julius
         for(i = 0; i < 32; i = i + 1) begin
168
            if (i % 4 == 0)
169
              $fdisplay(fexe);
170
            get_gpr(i, r);
171
            $fwrite(fexe, "GPR%d: %h  ", i, r);
172
         end
173
         $fdisplay(fexe);
174 348 julius
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.sr;
175 6 julius
         $fwrite(fexe, "SR   : %h  ", r);
176 348 julius
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.epcr;
177 6 julius
         $fwrite(fexe, "EPCR0: %h  ", r);
178 348 julius
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.eear;
179 6 julius
         $fwrite(fexe, "EEAR0: %h  ", r);
180 348 julius
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.esr;
181 6 julius
         $fdisplay(fexe, "ESR0 : %h", r);
182 397 julius
`endif //  `ifdef OR1200_MONITOR_EXEC_STATE
183 348 julius
`ifdef OR1200_DISPLAY_EXECUTED
184
         ref = ref + 1;
185 397 julius
 `ifdef OR1200_MONITOR_LOOKUP
186 348 julius
         $fdisplay(flookup, "Instruction %d: %t", insns, $time);
187 397 julius
 `endif
188 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);
189 6 julius
`endif
190 348 julius
         insns = insns + 1;
191 6 julius
end
192
   endtask // display_arch_state
193
 
194
   /* Keep a trace buffer of the last lot of instructions and addresses
195
    * "executed",as read from the writeback stage, and cause a $finish if we hit
196
    * an instruction that is invalid, such as all zeros.
197
    * Currently, only breaks on an all zero instruction, but should probably be
198
    * made to break for anything with an X in it too. And of course ideally this
199
    * shouldn't be needed - but is handy if someone changes something and stops
200
    * the test continuing forever.
201
    */
202 49 julius
   integer num_nul_inst;
203
   initial num_nul_inst = 0;
204
 
205 6 julius
   task monitor_for_crash;
206 348 julius
`define OR1200_MONITOR_CRASH_TRACE_SIZE 32
207
      //Trace buffer of 32 instructions
208
      reg [31:0] insn_trace [0:`OR1200_MONITOR_CRASH_TRACE_SIZE-1];
209
      //Trace buffer of the addresses of those instructions
210
      reg [31:0] addr_trace [0:`OR1200_MONITOR_CRASH_TRACE_SIZE-1];
211 6 julius
      integer i;
212
 
213
     begin
214 348 julius
        if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h00000000)
215 49 julius
          num_nul_inst = num_nul_inst + 1;
216 348 julius
        else
217
          num_nul_inst = 0; // Reset it
218 49 julius
 
219
        if (num_nul_inst == 1000) // Sat a loop a bit too long...
220 6 julius
          begin
221 348 julius
             $fdisplay(fgeneral, "ERROR - no instruction at PC %h",
222
                       `OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc);
223
             $fdisplay(fgeneral, "Crash trace: Last %d instructions: ",
224
                       `OR1200_MONITOR_CRASH_TRACE_SIZE);
225 6 julius
 
226
             $fdisplay(fgeneral, "PC\t\tINSTR");
227
             for(i=`OR1200_MONITOR_CRASH_TRACE_SIZE-1;i>=0;i=i-1) begin
228
                $fdisplay(fgeneral, "%h\t%h",addr_trace[i], insn_trace[i]);
229
             end
230
             #100 $finish;
231
          end
232
        else
233
          begin
234
             for(i=`OR1200_MONITOR_CRASH_TRACE_SIZE-1;i>0;i=i-1) begin
235
                insn_trace[i] = insn_trace[i-1];
236
                addr_trace[i] = addr_trace[i-1];
237
             end
238 348 julius
             insn_trace[0] = `OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn;
239
             addr_trace[0] = `OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc;
240 6 julius
          end
241
 
242
     end
243
   endtask // monitor_for_crash
244 348 julius
 
245 6 julius
 
246 348 julius
   //
247
   // Write state of the OR1200 registers into a file; version for exception
248
   //
249
   task display_arch_state_except;
250
      reg [5:0] i;
251
      reg [31:0] r;
252
      integer    j;
253
      begin
254 397 julius
`ifdef OR1200_MONITOR_EXEC_STATE
255 348 julius
         ref = ref + 1;
256 397 julius
 `ifdef OR1200_MONITOR_LOOKUP
257 348 julius
         $fdisplay(flookup, "Instruction %d: %t", insns, $time);
258 397 julius
 `endif
259 348 julius
         $fwrite(fexe, "\nEXECUTED(%d): %h:  %h  (exception)", insns, `OR1200_TOP.`CPU_cpu.`CPU_except.ex_pc, `OR1200_TOP.`CPU_cpu.`CPU_ctrl.ex_insn);
260
         for(i = 0; i < 32; i = i + 1) begin
261
            if (i % 4 == 0)
262
              $fdisplay(fexe);
263
            get_gpr(i, r);
264
            $fwrite(fexe, "GPR%d: %h  ", i, r);
265
         end
266
         $fdisplay(fexe);
267
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.sr;
268
         $fwrite(fexe, "SR   : %h  ", r);
269
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.epcr;
270
         $fwrite(fexe, "EPCR0: %h  ", r);
271
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.eear;
272
         $fwrite(fexe, "EEAR0: %h  ", r);
273
         r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.esr;
274
         $fdisplay(fexe, "ESR0 : %h", r);
275
         insns = insns + 1;
276 397 julius
`endif //  `ifdef OR1200_MONITOR_EXEC_STATE
277 348 julius
`ifdef OR1200_DISPLAY_EXECUTED
278
         ref = ref + 1;
279 397 julius
 `ifdef OR1200_MONITOR_LOOKUP
280 348 julius
         $fdisplay(flookup, "Instruction %d: %t", insns, $time);
281 397 julius
 `endif
282 348 julius
         $fwrite(fexe, "\nEXECUTED(%d): %h:  %h  (exception)", insns,
283
                 `OR1200_TOP.`CPU_cpu.`CPU_except.ex_pc,
284
                 `OR1200_TOP.`CPU_cpu.`CPU_ctrl.ex_insn);
285
         insns = insns + 1;
286
`endif
287
 
288
end
289
   endtask
290
 
291 6 julius
   integer iwb_progress;
292
   reg [31:0] iwb_progress_addr;
293
   //
294
   // WISHBONE bus checker
295
   //
296
   always @(posedge `OR1200_TOP.iwb_clk_i)
297
     if (`OR1200_TOP.iwb_rst_i) begin
298
        iwb_progress = 0;
299
        iwb_progress_addr = `OR1200_TOP.iwb_adr_o;
300
     end
301
     else begin
302
        if (`OR1200_TOP.iwb_cyc_o && (iwb_progress != 2)) begin
303
           iwb_progress = 1;
304
        end
305
        if (`OR1200_TOP.iwb_stb_o) begin
306
           if (iwb_progress >= 1) begin
307
              if (iwb_progress == 1)
308
                iwb_progress_addr = `OR1200_TOP.iwb_adr_o;
309
              iwb_progress = 2;
310
           end
311
           else begin
312
              $fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.iwb_stb_o raised without `OR1200_TOP.iwb_cyc_o, at %t\n", $time);
313
              #100 $finish;
314
           end
315
        end
316
        if (`OR1200_TOP.iwb_ack_i & `OR1200_TOP.iwb_err_i) begin
317
           $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);
318
        end
319
        if ((iwb_progress == 2) && (iwb_progress_addr != `OR1200_TOP.iwb_adr_o)) begin
320
           $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);
321
           #100 $finish;
322
        end
323
        if (`OR1200_TOP.iwb_ack_i | `OR1200_TOP.iwb_err_i)
324
          if (iwb_progress == 2) begin
325
             iwb_progress = 0;
326
             iwb_progress_addr = `OR1200_TOP.iwb_adr_o;
327
          end
328
          else begin
329
             $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);
330
             #100 $finish;
331
          end
332
        if ((iwb_progress == 2) && !`OR1200_TOP.iwb_stb_o) begin
333
           $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);
334 348 julius
           #100 $finish;
335 6 julius
        end
336
     end
337
 
338
   integer dwb_progress;
339
reg [31:0] dwb_progress_addr;
340
//
341
// WISHBONE bus checker
342
//
343
always @(posedge `OR1200_TOP.dwb_clk_i)
344
  if (`OR1200_TOP.dwb_rst_i)
345
    dwb_progress = 0;
346
  else begin
347
     if (`OR1200_TOP.dwb_cyc_o && (dwb_progress != 2))
348
       dwb_progress = 1;
349
     if (`OR1200_TOP.dwb_stb_o)
350
       if (dwb_progress >= 1) begin
351
          if (dwb_progress == 1)
352
            dwb_progress_addr = `OR1200_TOP.dwb_adr_o;
353
          dwb_progress = 2;
354
       end
355
       else begin
356
          $fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.dwb_stb_o raised without `OR1200_TOP.dwb_cyc_o, at %t\n", $time);
357
          #100 $finish;
358
       end
359
     if (`OR1200_TOP.dwb_ack_i & `OR1200_TOP.dwb_err_i) begin
360
        $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);
361
     end
362
     if ((dwb_progress == 2) && (dwb_progress_addr != `OR1200_TOP.dwb_adr_o)) begin
363
        $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);
364
        #100 $finish;
365
     end
366
     if (`OR1200_TOP.dwb_ack_i | `OR1200_TOP.dwb_err_i)
367
       if (dwb_progress == 2) begin
368
          dwb_progress = 0;
369
          dwb_progress_addr = `OR1200_TOP.dwb_adr_o;
370
       end
371
       else begin
372
          $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);
373
          #100 $finish;
374
       end
375
     if ((dwb_progress == 2) && !`OR1200_TOP.dwb_stb_o) begin
376
        $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);
377
        #100 $finish;
378
     end
379
       end
380
 
381
//
382
// Hooks for:
383
// - displaying registers
384
// - end of simulation
385
// - access to SPRs
386
//
387 348 julius
   always @(posedge `OR1200_TOP.`CPU_cpu.`CPU_ctrl.clk)
388
     if (!`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_freeze) begin
389
//      #2;
390
        if (((`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn[31:26] != `OR1200_OR32_NOP)
391
             | !`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn[16])
392
            & !(`OR1200_TOP.`CPU_cpu.`CPU_except.except_flushpipe &
393
                `OR1200_TOP.`CPU_cpu.`CPU_except.ex_dslot))
394 6 julius
          begin
395
             display_arch_state;
396
             monitor_for_crash;
397
          end
398
        else
399 348 julius
          if (`OR1200_TOP.`CPU_cpu.`CPU_except.except_flushpipe)
400 6 julius
            display_arch_state_except;
401 348 julius
        // small hack to stop simulation (l.nop 1):
402
        if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_0001) begin
403 6 julius
           get_gpr(3, r3);
404
           $fdisplay(fgeneral, "%t: l.nop exit (%h)", $time, r3);
405
           $finish;
406
        end
407 348 julius
        // debug if test (l.nop 10)
408
        if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_000a) begin
409 6 julius
           $fdisplay(fgeneral, "%t: l.nop dbg_if_test", $time);
410
        end
411 348 julius
        // simulation reports (l.nop 2)
412
        if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_0002) begin
413 6 julius
           get_gpr(3, r3);
414 348 julius
           $fdisplay(fgeneral, "%t: l.nop report (%h)", $time, r3);
415
        end
416
        // simulation printfs (l.nop 3)
417
        if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_0003) begin
418
           get_gpr(3, r3);
419 6 julius
           $fdisplay(fgeneral, "%t: l.nop printf (%h)", $time, r3);
420
        end
421 348 julius
        if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_0004) begin
422
           // simulation putc (l.nop 4)
423
           get_gpr(3, r3);
424
           $write("%c", r3);
425
           $fdisplay(fgeneral, "%t: l.nop putc (%c)", $time, r3);
426
        end
427 397 julius
`ifdef OR1200_MONITOR_SPRS
428
        if (`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_we)
429 6 julius
          $fdisplay(fspr, "%t: Write to SPR : [%h] <- %h", $time,
430 397 julius
                    `OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_addr,
431 348 julius
                    `OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_dat_o);
432 397 julius
        if ((|`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_cs) &
433
            !`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_we)
434 6 julius
          $fdisplay(fspr, "%t: Read from SPR: [%h] -> %h", $time,
435 348 julius
                    `OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_addr,
436
                    `OR1200_TOP.`CPU_cpu.`CPU_sprs.to_wbmux);
437 397 julius
`endif
438 6 julius
     end
439
 
440 348 julius
 
441
`ifdef VERSATILE_SDRAM
442
 `define SDRAM_TOP design_testbench.sdram0
443
   // Bit selects to define the bank
444
   // 32 MB part with 4 banks
445
 `define SDRAM_BANK_SEL_BITS 24:23
446
 `define SDRAM_WORD_SEL_TOP_BIT 22
447
   // Gets instruction word from correct bank
448
   task get_insn_from_sdram;
449
      input [31:0] addr;
450
      output [31:0] insn;
451
      reg [`SDRAM_WORD_SEL_TOP_BIT-1:0] word_addr;
452
 
453
      begin
454
         word_addr = addr[`SDRAM_WORD_SEL_TOP_BIT:2];
455
         if (addr[`SDRAM_BANK_SEL_BITS] == 2'b00)
456
           begin
457
 
458
              //$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}]);         
459
              insn[15:0] = `SDRAM_TOP.Bank0[{word_addr,1'b1}];
460
              insn[31:16] = `SDRAM_TOP.Bank0[{word_addr,1'b0}];
461
           end
462
      end
463
 
464
   endtask // get_insn_from_sdram
465
`endif //  `ifdef VERSATILE_SDRAM
466
 
467
`ifdef XILINX_DDR2
468
 `define DDR2_TOP design_testbench.gen_cs[0]
469
   // Gets instruction word from correct bank
470
   task get_insn_from_xilinx_ddr2;
471
      input [31:0] addr;
472
      output [31:0] insn;
473
      reg [16*8-1:0] ddr2_array_line0,ddr2_array_line1,ddr2_array_line2,ddr2_array_line3;
474
      integer        word_in_line_num;
475
      begin
476
        // Get our 4 128-bit chunks (8 half-words in each!! Confused yet?), 16 words total
477
         `DDR2_TOP.gen[0].u_mem0.memory_read(addr[28:27],addr[26:13],{addr[12:6],3'd0},ddr2_array_line0);
478
         `DDR2_TOP.gen[1].u_mem0.memory_read(addr[28:27],addr[26:13],{addr[12:6],3'd0},ddr2_array_line1);
479
         `DDR2_TOP.gen[2].u_mem0.memory_read(addr[28:27],addr[26:13],{addr[12:6],3'd0},ddr2_array_line2);
480
         `DDR2_TOP.gen[3].u_mem0.memory_read(addr[28:27],addr[26:13],{addr[12:6],3'd0},ddr2_array_line3);
481
         case (addr[5:2])
482
           4'h0:
483
             begin
484
                insn[15:0] = ddr2_array_line0[15:0];
485
                insn[31:16] = ddr2_array_line1[15:0];
486
             end
487
           4'h1:
488
             begin
489
                insn[15:0] = ddr2_array_line2[15:0];
490
                insn[31:16] = ddr2_array_line3[15:0];
491
             end
492
           4'h2:
493
             begin
494
                insn[15:0] = ddr2_array_line0[31:16];
495
                insn[31:16] = ddr2_array_line1[31:16];
496
             end
497
           4'h3:
498
             begin
499
                insn[15:0] = ddr2_array_line2[31:16];
500
                insn[31:16] = ddr2_array_line3[31:16];
501
             end
502
           4'h4:
503
             begin
504
                insn[15:0] = ddr2_array_line0[47:32];
505
                insn[31:16] = ddr2_array_line1[47:32];
506
             end
507
           4'h5:
508
             begin
509
                insn[15:0] = ddr2_array_line2[47:32];
510
                insn[31:16] = ddr2_array_line3[47:32];
511
             end
512
           4'h6:
513
             begin
514
                insn[15:0] = ddr2_array_line0[63:48];
515
                insn[31:16] = ddr2_array_line1[63:48];
516
             end
517
           4'h7:
518
             begin
519
                insn[15:0] = ddr2_array_line2[63:48];
520
                insn[31:16] = ddr2_array_line3[63:48];
521
             end
522
           4'h8:
523
             begin
524
                insn[15:0] = ddr2_array_line0[79:64];
525
                insn[31:16] = ddr2_array_line1[79:64];
526
             end
527
           4'h9:
528
             begin
529
                insn[15:0] = ddr2_array_line2[79:64];
530
                insn[31:16] = ddr2_array_line3[79:64];
531
             end
532
           4'ha:
533
             begin
534
                insn[15:0] = ddr2_array_line0[95:80];
535
                insn[31:16] = ddr2_array_line1[95:80];
536
             end
537
           4'hb:
538
             begin
539
                insn[15:0] = ddr2_array_line2[95:80];
540
                insn[31:16] = ddr2_array_line3[95:80];
541
             end
542
           4'hc:
543
             begin
544
                insn[15:0] = ddr2_array_line0[111:96];
545
                insn[31:16] = ddr2_array_line1[111:96];
546
             end
547
           4'hd:
548
             begin
549
                insn[15:0] = ddr2_array_line2[111:96];
550
                insn[31:16] = ddr2_array_line3[111:96];
551
             end
552
           4'he:
553
             begin
554
                insn[15:0] = ddr2_array_line0[127:112];
555
                insn[31:16] = ddr2_array_line1[127:112];
556
             end
557
           4'hf:
558
             begin
559
                insn[15:0] = ddr2_array_line2[127:112];
560
                insn[31:16] = ddr2_array_line3[127:112];
561
             end
562
         endcase // case (addr[5:2])
563
      end
564
   endtask // get_insn_from_xilinx_ddr2
565
`endif
566
 
567
 
568
   task get_insn_from_memory;
569
      input [31:0] id_pc;
570
      output [31:0] insn;
571
      begin
572
         // do a decode of which server we should look in
573
         case (id_pc[31:28])
574
`ifdef VERSATILE_SDRAM
575
           4'h0:
576
             get_insn_from_sdram(id_pc, insn);
577
`endif
578
`ifdef XILINX_DDR2
579
           4'h0:
580
             get_insn_from_xilinx_ddr2(id_pc, insn);
581
`endif
582
           4'hf:
583
             // Flash isn't stored in a memory, it's an FSM so just skip/ignore
584
             insn = `OR1200_TOP.`CPU_cpu.`CPU_ctrl.id_insn;
585
           default:
586
             begin
587
                $fdisplay(fgeneral, "%t: Unknown memory server for address 0x%h", $time,id_pc);
588
                insn = 32'hxxxxxxxx; // Unknown server
589
             end
590
         endcase // case (id_pc[31:28])
591
      end
592
   endtask // get_insn_from_memory
593
 
594
 
595
    reg [31:0] mem_word;
596
   reg [31:0] last_addr = 0;
597
   reg [31:0] last_mem_word;
598
 
599
//`define TRIGGER_FOR_CHECK (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.id_void === 1'b0)
600
   // Disabled:
601
`define TRIGGER_FOR_CHECK 0
602
`define INSN_TO_CHECK `OR1200_TOP.`CPU_cpu.`CPU_ctrl.id_insn
603
`define PC_TO_CHECK `OR1200_TOP.`CPU_cpu.`CPU_except.id_pc
604
 
605
   // Check instruction in decode stage is what is in the RAM
606
   always @(posedge `OR1200_TOP.`CPU_cpu.`CPU_ctrl.clk)
607
     begin
608
        if (`TRIGGER_FOR_CHECK)
609
          begin
610
             // Check if it's a new PC - will also get triggered if the
611
             // instruction has changed since we last checked it
612
             if ((`PC_TO_CHECK !== last_addr) ||
613
                 (last_mem_word != `INSN_TO_CHECK))
614
               begin
615
                  // Decode stage not void, check instruction
616
                  // get PC
617
                  get_insn_from_memory(`PC_TO_CHECK, mem_word);
618
 
619
                  // Debugging output to prove it's doing something!
620
                  //$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);
621
 
622
                  if (mem_word !== `INSN_TO_CHECK)
623
                    begin
624
                       $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);
625
                       #20
626
                         $finish;
627
                    end
628
                  last_addr = `PC_TO_CHECK;
629
                  last_mem_word = mem_word;
630
               end // if (`PC_TO_CHECK !== last_addr)
631
          end
632
     end // always @ (posedge `OR1200_TOP.`CPU_cpu.`CPU_ctrl.clk)
633
 
634
 
635
 
636 351 julius
   /////////////////////////////////////////////////////////////////////////
637
   // Instruction decode task
638
   /////////////////////////////////////////////////////////////////////////
639 348 julius
 
640 351 julius
 
641
`define OR32_OPCODE_POS 31:26
642
`define OR32_J_BR_IMM_POS 25:0
643
`define OR32_RD_POS 25:21
644
`define OR32_RA_POS 20:16
645
`define OR32_RB_POS 15:11
646
`define OR32_ALU_OP_POS 3:0
647 348 julius
 
648 351 julius
`define OR32_SHROT_OP_POS 7:6
649
`define OR32_SHROTI_IMM_POS 5:0
650
`define OR32_SF_OP 25:21
651
 
652
`define OR32_XSYNC_OP_POS 25:21
653
 
654
 
655
// Switch between outputting to execution file or STD out for instruction
656
// decoding task.
657
//`define PRINT_OP_WRITE $write(
658
`define PRINT_OP_WRITE $fwrite(fexe,
659
 
660
   task or1200_print_op;
661
      input [31:0] insn;
662
 
663
      reg [5:0]    opcode;
664
 
665
      reg [25:0]   j_imm;
666
      reg [25:0]   br_imm;
667
 
668
      reg [4:0]    rD_num, rA_num, rB_num;
669
      reg [31:0]   rA_val, rB_val;
670
      reg [15:0]   imm_16bit;
671
      reg [10:0]   imm_split16bit;
672
 
673
      reg [3:0]    alu_op;
674
      reg [1:0]    shrot_op;
675
 
676
      reg [5:0]    shroti_imm;
677
 
678
    reg [5:0]       sf_op;
679
 
680
    reg [5:0]       xsync_op;
681
 
682
      begin
683
         // Instruction opcode
684
         opcode = insn[`OR32_OPCODE_POS];
685
         // Immediates for jump or branch instructions
686
         j_imm = insn[`OR32_J_BR_IMM_POS];
687
         br_imm = insn[`OR32_J_BR_IMM_POS];
688
         // Register numbers (D, A and B)
689
         rD_num = insn[`OR32_RD_POS];
690
         rA_num = insn[`OR32_RA_POS];
691
         rB_num = insn[`OR32_RB_POS];
692
         // Bottom 16 bits when used as immediates in various instructions
693
         imm_16bit = insn[15:0];
694
         // Bottom 11 bits used as immediates for l.sX instructions
695
 
696
         // Split 16-bit immediate for l.mtspr/l.sX instructions
697
         imm_split16bit = {insn[25:21],insn[10:0]};
698
         // ALU op for ALU instructions
699
         alu_op = insn[`OR32_ALU_OP_POS];
700
         // Shift-rotate op for SHROT ALU instructions
701
         shrot_op = insn[`OR32_SHROT_OP_POS];
702
         shroti_imm = insn[`OR32_SHROTI_IMM_POS];
703
 
704
         // Set flag op
705
         sf_op = insn[`OR32_SF_OP];
706
 
707
         // Xsync/syscall/trap opcode
708
         xsync_op = insn[`OR32_XSYNC_OP_POS];
709
 
710
         case (opcode)
711
           `OR1200_OR32_J:
712
             begin
713
                `PRINT_OP_WRITE"l.j 0x%h", {j_imm,2'b00});
714
             end
715
 
716
           `OR1200_OR32_JAL:
717
             begin
718
                `PRINT_OP_WRITE"l.jal 0x%h", {j_imm,2'b00});
719
             end
720
 
721
           `OR1200_OR32_BNF:
722
             begin
723
                `PRINT_OP_WRITE"l.bnf 0x%h", {br_imm,2'b00});
724
             end
725
 
726
           `OR1200_OR32_BF:
727
             begin
728
                `PRINT_OP_WRITE"l.bf 0x%h", {br_imm,2'b00});
729
             end
730
 
731
           `OR1200_OR32_RFE:
732
             begin
733
                `PRINT_OP_WRITE"l.rfe");
734
             end
735
 
736
           `OR1200_OR32_JR:
737
             begin
738
                `PRINT_OP_WRITE"l.jr r%0d",rB_num);
739
             end
740
 
741
           `OR1200_OR32_JALR:
742
             begin
743
                `PRINT_OP_WRITE"l.jalr r%0d",rB_num);
744
             end
745
 
746
           `OR1200_OR32_LWZ:
747
             begin
748
                `PRINT_OP_WRITE"l.lwz r%0d,0x%0h(r%0d)",rD_num,imm_16bit,rA_num);
749
             end
750
 
751
           `OR1200_OR32_LBZ:
752
             begin
753
                `PRINT_OP_WRITE"l.lbz r%0d,0x%0h(r%0d)",rD_num,imm_16bit,rA_num);
754
             end
755
 
756
           `OR1200_OR32_LBS:
757
             begin
758
                `PRINT_OP_WRITE"l.lbs r%0d,0x%0h(r%0d)",rD_num,imm_16bit,rA_num);
759
             end
760
 
761
           `OR1200_OR32_LHZ:
762
             begin
763
                `PRINT_OP_WRITE"l.lhz r%0d,0x%0h(r%0d)",rD_num,imm_16bit,rA_num);
764
             end
765
 
766
           `OR1200_OR32_LHS:
767
             begin
768
                `PRINT_OP_WRITE"l.lhs r%0d,0x%0h(r%0d)",rD_num,imm_16bit,rA_num);
769
             end
770
 
771
           `OR1200_OR32_SW:
772
             begin
773
                `PRINT_OP_WRITE"l.sw 0x%0h(r%0d),r%0d",imm_split16bit,rA_num,rB_num);
774
             end
775
 
776
           `OR1200_OR32_SB:
777
             begin
778
                `PRINT_OP_WRITE"l.sb 0x%0h(r%0d),r%0d",imm_split16bit,rA_num,rB_num);
779
             end
780
 
781
           `OR1200_OR32_SH:
782
             begin
783
                `PRINT_OP_WRITE"l.sh 0x%0h(r%0d),r%0d",imm_split16bit,rA_num,rB_num);
784
             end
785
 
786
           `OR1200_OR32_MFSPR:
787
             begin
788
                `PRINT_OP_WRITE"l.mfspr r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit,);
789
             end
790
 
791
           `OR1200_OR32_MTSPR:
792
             begin
793
                `PRINT_OP_WRITE"l.mtspr r%0d,r%0d,0x%h",rA_num,rB_num,imm_split16bit);
794
             end
795
 
796
           `OR1200_OR32_MOVHI:
797
             begin
798
                if (!insn[16])
799
                  `PRINT_OP_WRITE"l.movhi r%0d,0x%h",rD_num,imm_16bit);
800
                else
801
                  `PRINT_OP_WRITE"l.macrc r%0d",rD_num);
802
             end
803
 
804
           `OR1200_OR32_ADDI:
805
             begin
806
                `PRINT_OP_WRITE"l.addi r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit);
807
             end
808
 
809
           `OR1200_OR32_ADDIC:
810
             begin
811
                `PRINT_OP_WRITE"l.addic r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit);
812
             end
813
 
814
           `OR1200_OR32_ANDI:
815
             begin
816
                `PRINT_OP_WRITE"l.andi r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit);
817
             end
818
 
819
           `OR1200_OR32_ORI:
820
             begin
821
                `PRINT_OP_WRITE"l.ori r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit);
822
             end
823
 
824
           `OR1200_OR32_XORI:
825
             begin
826
                `PRINT_OP_WRITE"l.xori r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit);
827
             end
828
 
829
           `OR1200_OR32_MULI:
830
             begin
831
                `PRINT_OP_WRITE"l.muli r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit);
832
             end
833
 
834
           `OR1200_OR32_ALU:
835
             begin
836
                case(alu_op)
837
                  `OR1200_ALUOP_ADD:
838
                    `PRINT_OP_WRITE"l.add ");
839
                  `OR1200_ALUOP_ADDC:
840
                    `PRINT_OP_WRITE"l.addc ");
841
                  `OR1200_ALUOP_SUB:
842
                    `PRINT_OP_WRITE"l.sub ");
843
                  `OR1200_ALUOP_AND:
844
                    `PRINT_OP_WRITE"l.and ");
845
                  `OR1200_ALUOP_OR:
846
                    `PRINT_OP_WRITE"l.or ");
847
                  `OR1200_ALUOP_XOR:
848
                    `PRINT_OP_WRITE"l.xor ");
849
                  `OR1200_ALUOP_MUL:
850
                    `PRINT_OP_WRITE"l.mul ");
851
                  `OR1200_ALUOP_SHROT:
852
                    begin
853
                       case(shrot_op)
854
                         `OR1200_SHROTOP_SLL:
855
                           `PRINT_OP_WRITE"l.sll ");
856
                         `OR1200_SHROTOP_SRL:
857
                           `PRINT_OP_WRITE"l.srl ");
858
                         `OR1200_SHROTOP_SRA:
859
                           `PRINT_OP_WRITE"l.sra ");
860
                         `OR1200_SHROTOP_ROR:
861
                           `PRINT_OP_WRITE"l.ror ");
862
                       endcase // case (shrot_op)
863
                    end
864
                  `OR1200_ALUOP_DIV:
865
                    `PRINT_OP_WRITE"l.div ");
866
                  `OR1200_ALUOP_DIVU:
867
                    `PRINT_OP_WRITE"l.divu ");
868
                  `OR1200_ALUOP_CMOV:
869
                    `PRINT_OP_WRITE"l.cmov ");
870
                endcase // case (alu_op)
871
                `PRINT_OP_WRITE"r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
872
             end
873
 
874
           `OR1200_OR32_SH_ROTI:
875
             begin
876
                case(shrot_op)
877
                  `OR1200_SHROTOP_SLL:
878
                    `PRINT_OP_WRITE"l.slli ");
879
                  `OR1200_SHROTOP_SRL:
880
                    `PRINT_OP_WRITE"l.srli ");
881
                  `OR1200_SHROTOP_SRA:
882
                    `PRINT_OP_WRITE"l.srai ");
883
                  `OR1200_SHROTOP_ROR:
884
                    `PRINT_OP_WRITE"l.rori ");
885
                endcase // case (shrot_op)
886
                `PRINT_OP_WRITE"r%0d,r%0d,0x%h",rD_num,rA_num,shroti_imm);
887
             end
888
 
889
           `OR1200_OR32_SFXXI:
890
             begin
891
                case(sf_op[2:0])
892
                  `OR1200_COP_SFEQ:
893
                    `PRINT_OP_WRITE"l.sfeqi ");
894
                  `OR1200_COP_SFNE:
895
                    `PRINT_OP_WRITE"l.sfnei ");
896
                  `OR1200_COP_SFGT:
897
                    begin
898
                       if (sf_op[`OR1200_SIGNED_COMPARE])
899
                         `PRINT_OP_WRITE"l.sfgtsi ");
900
                       else
901
                         `PRINT_OP_WRITE"l.sfgtui ");
902
                    end
903
                  `OR1200_COP_SFGE:
904
                    begin
905
                       if (sf_op[`OR1200_SIGNED_COMPARE])
906
                         `PRINT_OP_WRITE"l.sfgesi ");
907
                       else
908
                         `PRINT_OP_WRITE"l.sfgeui ");
909
                    end
910
                  `OR1200_COP_SFLT:
911
                    begin
912
                       if (sf_op[`OR1200_SIGNED_COMPARE])
913
                         `PRINT_OP_WRITE"l.sfltsi ");
914
                       else
915
                         `PRINT_OP_WRITE"l.sfltui ");
916
                    end
917
                  `OR1200_COP_SFLE:
918
                    begin
919
                       if (sf_op[`OR1200_SIGNED_COMPARE])
920
                         `PRINT_OP_WRITE"l.sflesi ");
921
                       else
922
                         `PRINT_OP_WRITE"l.sfleui ");
923
                    end
924
                endcase // case (sf_op[2:0])
925
 
926
                `PRINT_OP_WRITE"r%0d,0x%h",rA_num, imm_16bit);
927
 
928
             end // case: `OR1200_OR32_SFXXI
929
 
930
           `OR1200_OR32_SFXX:
931
             begin
932
                case(sf_op[2:0])
933
                  `OR1200_COP_SFEQ:
934
                    `PRINT_OP_WRITE"l.sfeq ");
935
                  `OR1200_COP_SFNE:
936
                    `PRINT_OP_WRITE"l.sfne ");
937
                  `OR1200_COP_SFGT:
938
                    begin
939
                       if (sf_op[`OR1200_SIGNED_COMPARE])
940
                         `PRINT_OP_WRITE"l.sfgts ");
941
                       else
942
                         `PRINT_OP_WRITE"l.sfgtu ");
943
                    end
944
                  `OR1200_COP_SFGE:
945
                    begin
946
                       if (sf_op[`OR1200_SIGNED_COMPARE])
947
                         `PRINT_OP_WRITE"l.sfges ");
948
                       else
949
                         `PRINT_OP_WRITE"l.sfgeu ");
950
                    end
951
                  `OR1200_COP_SFLT:
952
                    begin
953
                       if (sf_op[`OR1200_SIGNED_COMPARE])
954
                         `PRINT_OP_WRITE"l.sflts ");
955
                       else
956
                         `PRINT_OP_WRITE"l.sfltu ");
957
                    end
958
                  `OR1200_COP_SFLE:
959
                    begin
960
                       if (sf_op[`OR1200_SIGNED_COMPARE])
961
                         `PRINT_OP_WRITE"l.sfles ");
962
                       else
963
                         `PRINT_OP_WRITE"l.sfleu ");
964
                    end
965
 
966
                endcase // case (sf_op[2:0])
967
 
968
                `PRINT_OP_WRITE"r%0d,r%0d",rA_num, rB_num);
969
 
970
             end
971
 
972
           `OR1200_OR32_MACI:
973
             begin
974
                `PRINT_OP_WRITE"l.maci r%0d,0x%h",rA_num,imm_16bit);
975
             end
976
 
977
           `OR1200_OR32_MACMSB:
978
             begin
979
                if(insn[3:0] == 4'h1)
980
                  `PRINT_OP_WRITE"l.mac ");
981
                else if(insn[3:0] == 4'h2)
982
                  `PRINT_OP_WRITE"l.msb ");
983
 
984
                `PRINT_OP_WRITE"r%0d,r%0d",rA_num,rB_num);
985
             end
986
 
987
           `OR1200_OR32_NOP:
988
             begin
989
                `PRINT_OP_WRITE"l.nop 0x%0h",imm_16bit);
990
             end
991
 
992
           `OR1200_OR32_XSYNC:
993
             begin
994
                case (xsync_op)
995
                  5'd0:
996
                    `PRINT_OP_WRITE"l.sys 0x%h",imm_16bit);
997
                  5'd8:
998
                    `PRINT_OP_WRITE"l.trap 0x%h",imm_16bit);
999
                  5'd16:
1000
                    `PRINT_OP_WRITE"l.msync");
1001
                  5'd20:
1002
                    `PRINT_OP_WRITE"l.psync");
1003
                  5'd24:
1004
                    `PRINT_OP_WRITE"l.csync");
1005
                  default:
1006
                    begin
1007
                       $display("%t: Instruction with opcode 0x%h has bad specific type information: 0x%h",$time,opcode,insn);
1008
                       `PRINT_OP_WRITE"%t: Instruction with opcode 0x%h has has bad specific type information: 0x%h",$time,opcode,insn);
1009
                    end
1010
                endcase // case (xsync_op)
1011
             end
1012
 
1013
           default:
1014
             begin
1015
                $display("%t: Unknown opcode 0x%h",$time,opcode);
1016
                `PRINT_OP_WRITE"%t: Unknown opcode 0x%h",$time,opcode);
1017
             end
1018
 
1019
         endcase // case (opcode)
1020
 
1021
      end
1022
   endtask // or1200_print_op
1023
 
1024
 
1025
 
1026 6 julius
endmodule

powered by: WebSVN 2.1.0

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