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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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