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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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