OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [src_processor/] [mor1kx-5.0/] [bench/] [verilog/] [mor1kx_monitor.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
/* ****************************************************************************
2
  This Source Code Form is subject to the terms of the
3
  Open Hardware Description License, v. 1.0. If a copy
4
  of the OHDL was not distributed with this file, You
5
  can obtain one at http://juliusbaxter.net/ohdl/ohdl.txt
6
 
7
  Description: mor1kx monitor module
8
 
9
  Attaches to hooks provided in the mor1kx pipeline wrapper and provides
10
  execution trace, disassembly, and l.nop instruction functions.
11
 
12
  Copyright (C) 2012, 2013 Authors
13
 
14
  Author(s): Julius Baxter <juliusbaxter@gmail.com>
15
 
16
***************************************************************************** */
17
 
18
/* Configure these defines to point to the mor1kx instantiation */
19
`ifndef MOR1KX_INST
20
 `define MOR1KX_INST dut.mor1kx0
21
`endif
22
 
23
/* The rest of these shouldn't need changing if the wrapper hooks have been
24
 set up correctly in mor1kx_cpu. */
25
`ifndef CPU_WRAPPER
26
 `define CPU_WRAPPER `MOR1KX_INST.mor1kx_cpu
27
`endif
28
`define CPU_INST `CPU_WRAPPER.`MOR1KX_CPU_PIPELINE.mor1kx_cpu
29
`define EXECUTE_STAGE_INSN `CPU_WRAPPER.monitor_execute_insn
30
`define EXECUTE_STAGE_ADV `CPU_WRAPPER.monitor_execute_advance
31
`define CPU_clk `CPU_WRAPPER.monitor_clk
32
`define CPU_FLAG `CPU_WRAPPER.monitor_flag
33
`define CPU_SR `CPU_WRAPPER.monitor_spr_sr
34
`define EXECUTE_PC `CPU_WRAPPER.monitor_execute_pc
35
`define GPR_GET(x) `CPU_INST.get_gpr(x)
36
`define GPR_SET(x, y) `CPU_INST.set_gpr(x, y)
37
 
38
`include "mor1kx-defines.v"
39
 
40
// Pull in an ORPSoC-specific file
41
`include "test-defines.v" // indicate if we should trace or not
42
 
43
// OR1K ISA defines used in this file
44
 
45
`define OR1K_OPCODE_POS 31:26
46
`define OR1K_J_BR_IMM_POS 25:0
47
`define OR1K_RD_POS 25:21
48
`define OR1K_RA_POS 20:16
49
`define OR1K_RB_POS 15:11
50
`define OR1K_ALU_OP_POS 3:0
51
`define OR1K_SF_OP 25:21
52
`define OR1K_XSYNC_OP_POS 25:21
53
 
54
module mor1kx_monitor #(parameter LOG_DIR= "../out") ();
55
 
56
   // General output file descriptor
57
   integer    fgeneral = 0;
58
   integer    ftrace = 0;
59
   integer    insns = 0;
60
 
61
   wire clk;
62
 
63
   parameter OPTION_OPERAND_WIDTH = 32;
64
 
65
   reg  TRACE_ENABLE;
66
   initial TRACE_ENABLE = $test$plusargs("trace_enable");
67
 
68
   reg  TRACE_TO_SCREEN;
69
   initial TRACE_TO_SCREEN = $test$plusargs("trace_to_screen");
70
 
71
   assign clk = `CPU_clk;
72
 
73
   reg [63:0] cycle_counter = 0 ;
74
 
75
   /* Log file management code */
76
   initial
77
     begin
78
        $timeformat (-9, 2, " ns", 12);
79
        fgeneral = $fopen({LOG_DIR,"/",`TEST_NAME_STRING,"-general.log"});
80
        ftrace = $fopen({LOG_DIR,"/",`TEST_NAME_STRING,"-trace.log"});
81
     end
82
 
83
   /* Simulation support code */
84
 
85
   reg [1:80*8] decode_insn_disas;
86
   reg [1:80*8] execute_insn_disas;
87
   reg [OPTION_OPERAND_WIDTH-1:0] decode_pc;
88
   reg [OPTION_OPERAND_WIDTH-1:0] execute_pc;
89
 
90
   reg [`OR1K_INSN_WIDTH-1:0]      execute_insn;
91
   reg                             flag_4stage;
92
 
93
   always @(`EXECUTE_STAGE_INSN)
94
     mor1k_insn_to_string(`EXECUTE_STAGE_INSN, execute_insn_disas);
95
          //$write("%tns: decode insn PC %08h %08h %s\n",$time, pc_decode_i, 
96
          // decode_insn_i, insn_disassembled_string);
97
 
98
   always @(negedge `CPU_clk) begin
99
 
100
      cycle_counter = cycle_counter + 1;
101
 
102
      if (`EXECUTE_STAGE_ADV)
103
        begin
104
          insns = insns + 1;
105
          execute_insn = `EXECUTE_STAGE_INSN;
106
 
107
           if(TRACE_ENABLE)
108
             mor1k_trace_print(execute_insn, `CPU_SR, `EXECUTE_PC, `CPU_FLAG);
109
 
110
          // Check instructions for simulation controls
111
          if (execute_insn == 32'h15_00_00_01)
112
            begin
113
               $fdisplay(fgeneral,"%0t:exit(0x%08h);",$time,`GPR_GET(3));
114
               $fdisplay(ftrace,"exit(0x%08h);",`GPR_GET(3));
115
               $display("exit(0x%08h);",`GPR_GET(3));
116
               $finish;
117
            end
118
          if (execute_insn == 32'h15_00_00_02)
119
            begin
120
               $fdisplay(fgeneral,"%0t:report(0x%08h);",$time,`GPR_GET(3));
121
               $fdisplay(ftrace,"report(0x%08h);",`GPR_GET(3));
122
               $display("report(0x%08h);",`GPR_GET(3));
123
            end
124
          if (execute_insn == 32'h15_00_00_04)
125
            begin
126
               $write("%c",`GPR_GET(3));
127
               $fdisplay(fgeneral, "%0t: l.nop putc (%c)", $time,`GPR_GET(3));
128
            end
129
          if (execute_insn == 32'h15_00_00_05)
130
            begin
131
               cycle_counter = 0;
132
               $fdisplay(fgeneral, "%0t: l.nop reset counter", $time);
133
            end
134
           if (execute_insn == 32'h15_00_00_06)
135
             begin
136
                $fdisplay(fgeneral, "%0t: l.nop report cycle counter: %d", $time, cycle_counter);
137
                `GPR_SET(11,cycle_counter[31:0]);
138
                `GPR_SET(12,cycle_counter[63:32]);
139
            end
140
 
141
          if (execute_insn == 32'h15_00_00_0c)
142
            begin
143
               // Silent exit
144
               $finish;
145
 
146
            end
147
 
148
       end // if (`EXECUTE_STAGE_ADV)
149
   end
150
 
151
   task mor1k_trace_print;
152
      input [31:0] insn;
153
      input [31:0] sr;
154
      input [31:0] pc;
155
      input        flag;
156
 
157
 
158
      reg          rD_used;
159
      reg [4:0]    rD_num, rA_num, rB_num;
160
      reg [15:0]   imm_16bit;
161
      reg [25:0]   imm_26bit;
162
      reg [31:0]   signext_imm_16bit;
163
 
164
      reg [1:80*8] insn_disas;
165
      // Actual things happening
166
      reg [15:0]   regimm_chars;
167
      reg [31:0]   addr_result;
168
      begin
169
 
170
         // Get instruction info
171
         mor1kx_insn_info(insn,rA_num,rB_num,rD_num,rD_used,imm_16bit,
172
                          imm_26bit,regimm_chars);
173
 
174
         /* Sign-extend the 16-bit immediate to 32-bit so we can add it to other
175
          32-bit numbers and it should subtract if necessary */
176
         signext_imm_16bit = {{16{imm_16bit[15]}},imm_16bit};
177
 
178
         // Display useful line of stuff, like or1ksim trace
179
         if (sr[`OR1K_SPR_SR_SM] === 1'b0)
180
           begin
181
              $fwrite(ftrace,"U ");
182
              if(TRACE_TO_SCREEN)
183
                $write("U ");
184
           end
185
         else
186
           begin
187
              $fwrite(ftrace,"S ");
188
              if(TRACE_TO_SCREEN)
189
                $write("S ");
190
           end
191
 
192
         // PC next
193
         $fwrite(ftrace,"%08h: ", pc);
194
         if(TRACE_TO_SCREEN)
195
           $write("%08h: ", pc);
196
 
197
         // Instruction raw
198
         $fwrite(ftrace,"%08h ",insn);
199
         if(TRACE_TO_SCREEN)
200
           $write("%08h ",insn);
201
 
202
         mor1k_insn_to_string(insn, insn_disas);
203
 
204
         // Instruction, disassembled
205
         $fwrite(ftrace,"%0s", insn_disas);
206
         if(TRACE_TO_SCREEN)
207
           $write("%0s", insn_disas);
208
 
209
         for (regimm_chars=regimm_chars;
210
              regimm_chars < 16; regimm_chars = regimm_chars + 1)
211
           begin
212
              $fwrite(ftrace," ");
213
              if(TRACE_TO_SCREEN)
214
                $write(" ");
215
           end
216
 
217
         if (rD_used)
218
           begin
219
              if (insn[`OR1K_OPCODE_SELECT]===`OR1K_OPCODE_MFSPR)
220
                begin
221
                   // Wait 1 cycle for MFSPR result
222
                   @(posedge `CPU_clk);
223
                   $fwrite(ftrace,"r%0d",rD_num);
224
                   if(TRACE_TO_SCREEN)
225
                     $write("r%0d",rD_num);
226
                end
227
              else
228
                begin
229
                   $fwrite(ftrace,"r%0d",rD_num);
230
                   if(TRACE_TO_SCREEN)
231
                     $write("r%0d",rD_num);
232
                end // else: !if(insn[`OR1K_OPCODE_SELECT]===`OR1K_OPCODE_MFSPR)
233
 
234
              // Tab 1 more if we're a single-number register 
235
              if (rD_num < 10) begin
236
                 $fwrite(ftrace,"\t\t");
237
                 if(TRACE_TO_SCREEN)
238
                   $write("\t\t");
239
              end
240
              else begin
241
                 $fwrite(ftrace,"\t");
242
                 if(TRACE_TO_SCREEN)
243
                   $write("\t");
244
              end
245
 
246
              // Finally write what ended up in the in rD
247
              $fwrite(ftrace,"= %08h  ",`GPR_GET(rD_num));
248
              if(TRACE_TO_SCREEN)
249
                $write("= %08h  ",`GPR_GET(rD_num));
250
           end
251
         else if (insn[`OR1K_OPCODE_SELECT]===`OR1K_OPCODE_MTSPR)
252
           begin
253
              // Clobber imm_16bit here to calculate MTSPR
254
              imm_16bit = imm_16bit | `GPR_GET(rA_num);
255
              $fwrite(ftrace,"SPR[%04x]  = %08h  ", imm_16bit, `GPR_GET(rB_num));
256
              if(TRACE_TO_SCREEN)
257
                $write("SPR[%04x]  = %08h  ", imm_16bit, `GPR_GET(rB_num));
258
 
259
           end // if (insn[`OR1K_OPCODE_SELECT]===`OR1K_OPCODE_MTSPR)
260
         else if (insn[`OR1K_OPCODE_SELECT]>=`OR1K_OPCODE_SD &&
261
                  insn[`OR1K_OPCODE_SELECT]<=`OR1K_OPCODE_SH)
262
           begin
263
              addr_result = signext_imm_16bit + `GPR_GET(rA_num);
264
              $fwrite(ftrace,"[%08h] = %08h  ",addr_result[31:0],
265
                     `GPR_GET(rB_num));
266
              if(TRACE_TO_SCREEN)
267
                $write("[%08h] = %08h  ",addr_result[31:0],
268
                       `GPR_GET(rB_num));
269
           end
270
         else
271
           begin
272
              // Skip destination field
273
              $fwrite(ftrace,"\t\t\t    ");
274
              if(TRACE_TO_SCREEN)
275
                $write("\t\t\t    ");
276
           end
277
 
278
         /* Write flag */
279
         $fwrite(ftrace,"flag: %0d", flag);
280
         if(TRACE_TO_SCREEN)
281
           $write("flag: %0d", flag);
282
 
283
         /* End of line */
284
         $fwrite(ftrace,"\n");
285
         if(TRACE_TO_SCREEN)
286
           $write("\n");
287
 
288
      end
289
   endtask // mor1k_trace_print
290
 
291
   task mor1kx_insn_info;
292
      input [31:0] insn;
293
      output [4:0] rA_num;
294
      output [4:0] rB_num;
295
      output [4:0] rD_num;
296
      output       rD_used;
297
      output [15:0] imm_16bit;
298
      output [25:0] imm_26bit;
299
 
300
      output [7:0]  num_chars;
301
 
302
      // To count how long disassembled immediates/regs
303
      // are - what a pain!
304
      reg           rA_used, rB_used, imm_16bit_used,
305
                    imm_26bit_used;
306
 
307
      reg [5:0]     opcode;
308
 
309
      reg           opc_store;
310
 
311
      begin
312
 
313
         // Register numbers (D, A and B)
314
         rD_num = insn[`OR1K_RD_POS];
315
         rA_num = insn[`OR1K_RA_POS];
316
         rB_num = insn[`OR1K_RB_POS];
317
 
318
         opcode = insn[`OR1K_OPCODE_POS];
319
 
320
 
321
         opc_store = (opcode==`OR1K_OPCODE_SD) ||
322
                     (opcode==`OR1K_OPCODE_SW) ||
323
                     (opcode==`OR1K_OPCODE_SB) ||
324
                     (opcode==`OR1K_OPCODE_SH);
325
 
326
         case (opcode)
327
           `OR1K_OPCODE_LWZ,
328
             `OR1K_OPCODE_LBZ,
329
             `OR1K_OPCODE_LBS,
330
             `OR1K_OPCODE_LHZ,
331
             `OR1K_OPCODE_LHS,
332
             `OR1K_OPCODE_MFSPR,
333
             `OR1K_OPCODE_MOVHI,
334
             `OR1K_OPCODE_ADDI,
335
             `OR1K_OPCODE_ADDIC,
336
             `OR1K_OPCODE_ANDI,
337
             `OR1K_OPCODE_ORI,
338
             `OR1K_OPCODE_XORI,
339
             `OR1K_OPCODE_MULI,
340
             `OR1K_OPCODE_ALU,
341
             `OR1K_OPCODE_SHRTI:
342
               rD_used = 1;
343
           default:
344
             rD_used=0;
345
         endcase // case (opcode)
346
 
347
         case (opcode)
348
           `OR1K_OPCODE_J    ,
349
             `OR1K_OPCODE_JAL  ,
350
             `OR1K_OPCODE_BNF  ,
351
             `OR1K_OPCODE_BF   ,
352
             `OR1K_OPCODE_NOP  ,
353
             `OR1K_OPCODE_MOVHI,
354
             `OR1K_OPCODE_MACRC,
355
             `OR1K_OPCODE_SYSTRAPSYNC,
356
             `OR1K_OPCODE_RFE,
357
             `OR1K_OPCODE_JR,
358
             `OR1K_OPCODE_JALR:
359
             /*
360
              rD of store insns, is in rA field
361
             `OR1K_OPCODE_SD,
362
             `OR1K_OPCODE_SW,
363
             `OR1K_OPCODE_SB,
364
             `OR1K_OPCODE_SH
365
              */
366
               rA_used = 0;
367
           default:
368
             rA_used=1;
369
         endcase // case (opcode)
370
 
371
         case (opcode)
372
           `OR1K_OPCODE_JR,
373
             `OR1K_OPCODE_JALR,
374
             `OR1K_OPCODE_MTSPR,
375
             `OR1K_OPCODE_MAC,
376
             `OR1K_OPCODE_MSB,
377
             `OR1K_OPCODE_SD,
378
             `OR1K_OPCODE_SW,
379
             `OR1K_OPCODE_SB,
380
             `OR1K_OPCODE_SH,
381
             `OR1K_OPCODE_SF:
382
               rB_used = 1;
383
           `OR1K_OPCODE_ALU:
384
             case(insn[`OR1K_ALU_OPC_SELECT])
385
               `OR1K_ALU_OPC_EXTBH,
386
                 `OR1K_ALU_OPC_EXTW,
387
                 `OR1K_ALU_OPC_FFL1:
388
                   rB_used = 0;
389
               default:
390
                 rB_used = 1;
391
             endcase // case (insn[`OR1K_ALU_OPC_SELECT])
392
           default:
393
             rB_used = 0;
394
         endcase // case (opcode)
395
 
396
         case (opcode)
397
           `OR1K_OPCODE_MOVHI,
398
             `OR1K_OPCODE_NOP,
399
             `OR1K_OPCODE_SD,
400
             `OR1K_OPCODE_SW,
401
             `OR1K_OPCODE_SB,
402
             `OR1K_OPCODE_SH,
403
             `OR1K_OPCODE_LD   ,
404
             `OR1K_OPCODE_LWZ  ,
405
             `OR1K_OPCODE_LWS  ,
406
             `OR1K_OPCODE_LBZ  ,
407
             `OR1K_OPCODE_LBS  ,
408
             `OR1K_OPCODE_LHZ  ,
409
             `OR1K_OPCODE_LHS  ,
410
             `OR1K_OPCODE_ADDI ,
411
             `OR1K_OPCODE_ADDIC,
412
             `OR1K_OPCODE_ANDI ,
413
             `OR1K_OPCODE_ORI  ,
414
             `OR1K_OPCODE_XORI ,
415
             `OR1K_OPCODE_MULI ,
416
             `OR1K_OPCODE_MACI ,
417
             `OR1K_OPCODE_SFIMM,
418
             `OR1K_OPCODE_MTSPR,
419
             `OR1K_OPCODE_MFSPR:
420
               imm_16bit_used = 1;
421
           default:
422
             imm_16bit_used = 0;
423
         endcase // case (opcode)
424
 
425
         case (opcode)
426
           `OR1K_OPCODE_J  ,
427
             `OR1K_OPCODE_JAL,
428
             `OR1K_OPCODE_BNF,
429
             `OR1K_OPCODE_BF:
430
               imm_26bit_used = 1;
431
           default:
432
             imm_26bit_used = 0;
433
         endcase
434
 
435
         // Extract immediate
436
         case (opcode)
437
           `OR1K_OPCODE_SW,
438
             `OR1K_OPCODE_SB,
439
             `OR1K_OPCODE_SH,
440
             `OR1K_OPCODE_SD,
441
             `OR1K_OPCODE_MTSPR:
442
               imm_16bit = {insn[25:21],insn[10:0]};
443
           default:
444
             imm_16bit = insn[15:0];
445
         endcase // case (opcode)
446
 
447
         imm_26bit = insn[25:0];
448
 
449
         // Extra chars (commas, brackets)
450
         case (opcode)
451
/*
452
           `OR1K_OPCODE_J    :
453
             num_chars = 0;
454
           `OR1K_OPCODE_JAL  :
455
             num_chars = 0;
456
           `OR1K_OPCODE_BNF  :
457
             num_chars = 0;
458
           `OR1K_OPCODE_BF   :
459
             num_chars = 0;
460
           `OR1K_OPCODE_MACRC:
461
             num_chars = 0;
462
           `OR1K_OPCODE_SYSTRAPSYNC:
463
             num_chars = 0;
464
           `OR1K_OPCODE_RFE:
465
             num_chars = 0;
466
           `OR1K_OPCODE_JR   :
467
             num_chars = 0;
468
           `OR1K_OPCODE_JALR :
469
             num_chars = 0;
470
           `OR1K_OPCODE_CUST1:
471
             num_chars = 0;
472
           `OR1K_OPCODE_CUST2:
473
             num_chars = 0;
474
           `OR1K_OPCODE_CUST3:
475
             num_chars = 0;
476
           `OR1K_OPCODE_CUST4:
477
             num_chars = 0;
478
           `OR1K_OPCODE_NOP  :
479
             num_chars = 0;
480
 */
481
           `OR1K_OPCODE_MOVHI:
482
             num_chars = 1;
483
           `OR1K_OPCODE_MACI :
484
             num_chars = 1;
485
           `OR1K_OPCODE_LD   :
486
             num_chars = 3;
487
           `OR1K_OPCODE_LWZ  :
488
             num_chars = 3;
489
           `OR1K_OPCODE_LWS  :
490
             num_chars = 3;
491
           `OR1K_OPCODE_LBZ  :
492
             num_chars = 3;
493
           `OR1K_OPCODE_LBS  :
494
             num_chars = 3;
495
           `OR1K_OPCODE_LHZ  :
496
             num_chars = 3;
497
           `OR1K_OPCODE_LHS  :
498
             num_chars = 3;
499
           `OR1K_OPCODE_ADDI :
500
             num_chars = 2;
501
           `OR1K_OPCODE_ADDIC:
502
             num_chars = 2;
503
           `OR1K_OPCODE_ANDI :
504
             num_chars = 2;
505
           `OR1K_OPCODE_ORI  :
506
             num_chars = 2;
507
           `OR1K_OPCODE_XORI :
508
             num_chars = 2;
509
           `OR1K_OPCODE_MULI :
510
             num_chars = 2;
511
           `OR1K_OPCODE_MFSPR:
512
             num_chars = 2;
513
           `OR1K_OPCODE_SFIMM:
514
             num_chars = 1;
515
           `OR1K_OPCODE_MTSPR  :
516
             num_chars = 2;
517
           `OR1K_OPCODE_MAC    :
518
             num_chars = 1;
519
           `OR1K_OPCODE_MSB  :
520
             num_chars = 1;
521
           `OR1K_OPCODE_SD   :
522
             num_chars = 3;
523
           `OR1K_OPCODE_SW   :
524
             num_chars = 3;
525
           `OR1K_OPCODE_SB   :
526
             num_chars = 3;
527
           `OR1K_OPCODE_SH:
528
             num_chars = 3;
529
           `OR1K_OPCODE_ALU:
530
             case(insn[`OR1K_ALU_OPC_SELECT])
531
               `OR1K_ALU_OPC_EXTBH,
532
                 `OR1K_ALU_OPC_EXTW,
533
                 `OR1K_ALU_OPC_FFL1:
534
                   num_chars = 1;
535
               default:
536
                 num_chars = 2;
537
             endcase // case (insn[`OR1K_ALU_OPC_SELECT])
538
           `OR1K_OPCODE_SF:
539
             num_chars =1;
540
           `OR1K_OPCODE_SHRTI:
541
             /*
542
             if (insn[5:0] < 6'h10)
543
               num_chars = 5;
544
             else
545
              */
546
               num_chars = 6;
547
 
548
           default:
549
             num_chars = 0;
550
 
551
         endcase // case (opcode)
552
 
553
 
554
         // Determine length of register/immediate
555
         // disassembly in characters
556
         if (rA_used)
557
           num_chars = (rA_num > 9) ? num_chars + 3 :
558
                       num_chars + 2;
559
 
560
         if (rB_used)
561
           num_chars = (rB_num > 9) ? num_chars + 3 :
562
                       num_chars + 2;
563
 
564
         if (rD_used)
565
           num_chars = (rD_num > 9) ? num_chars + 3 :
566
                       num_chars + 2;
567
 
568
         if (imm_16bit_used)
569
           num_chars = num_chars + 6;
570
 
571
         if (imm_26bit_used)
572
           num_chars = num_chars + 9;
573
 
574
         /*
575
         $write("%b %b %b %b %b\n",rA_used, rB_used, rD_used, imm_16bit_used,
576
                imm_26bit_used);
577
          */
578
         //$write("%0d\n",num_chars);
579
 
580
      end
581
   endtask // mor1k_insn_info
582
 
583
 
584
 
585
 
586
 
587
   task mor1k_insn_to_string;
588
      input [31:0] insn;
589
      output [80*8:1] insnstring;
590
 
591
      reg [5:0]    opcode;
592
 
593
      reg [25:0]   j_imm;
594
 
595
      reg [25:0]   br_imm;
596
 
597
      reg [31:0]   rA_val, rB_val;
598
 
599
      reg [3:0]    alu_op;
600
 
601
      reg [5:0]    sf_op;
602
 
603
      reg [5:0]    xsync_op;
604
 
605
      reg [4:0]    rD_num, rA_num, rB_num;
606
 
607
      reg [15:0]   imm_16bit;
608
      reg [15:0]   imm_split16bit;
609
 
610
 
611
      begin
612
 
613
         // Instruction opcode
614
         opcode = insn[`OR1K_OPCODE_POS];
615
         // Immediates for jump or branch instructions
616
         j_imm = insn[`OR1K_J_BR_IMM_POS];
617
         br_imm = insn[`OR1K_J_BR_IMM_POS];
618
         // Register numbers (D, A and B)
619
         rD_num = insn[`OR1K_RD_POS];
620
         rA_num = insn[`OR1K_RA_POS];
621
         rB_num = insn[`OR1K_RB_POS];
622
         // Bottom 16 bits when used as immediates in various instructions
623
         imm_16bit = insn[15:0];
624
         // Bottom 11 bits used as immediates for l.sX instructions
625
 
626
         // Split 16-bit immediate for l.mtspr/l.sX instructions
627
         imm_split16bit = {insn[25:21],insn[10:0]};
628
         // ALU op for ALU instructions
629
         alu_op = insn[`OR1K_ALU_OP_POS];
630
 
631
 
632
         // Set flag op
633
         sf_op = insn[`OR1K_SF_OP];
634
 
635
         // Xsync/syscall/trap opcode
636
         xsync_op = insn[`OR1K_XSYNC_OP_POS];
637
 
638
         case (opcode)
639
           `OR1K_OPCODE_J:
640
             begin
641
                $sformat(insnstring, "l.j     0x%07h", j_imm);
642
             end
643
 
644
           `OR1K_OPCODE_JAL:
645
             begin
646
                $sformat(insnstring, "l.jal   0x%07h", j_imm);
647
             end
648
 
649
           `OR1K_OPCODE_BNF:
650
             begin
651
                $sformat(insnstring, "l.bnf   0x%07h", br_imm);
652
             end
653
 
654
           `OR1K_OPCODE_BF:
655
             begin
656
                $sformat(insnstring, "l.bf    0x%07h", br_imm);
657
             end
658
 
659
           `OR1K_OPCODE_RFE:
660
             begin
661
                $sformat(insnstring, "l.rfe   ");
662
             end
663
 
664
           `OR1K_OPCODE_JR:
665
             begin
666
                $sformat(insnstring, "l.jr    r%0d",rB_num);
667
             end
668
 
669
           `OR1K_OPCODE_JALR:
670
             begin
671
                $sformat(insnstring, "l.jalr  r%0d",rB_num);
672
             end
673
 
674
           `OR1K_OPCODE_LWZ:
675
             begin
676
                $sformat(insnstring, "l.lwz   r%0d,0x%04h(r%0d)",rD_num,imm_16bit,rA_num);
677
             end
678
 
679
           `OR1K_OPCODE_LBZ:
680
             begin
681
                $sformat(insnstring, "l.lbz   r%0d,0x%04h(r%0d)",rD_num,imm_16bit,rA_num);
682
             end
683
 
684
           `OR1K_OPCODE_LBS:
685
             begin
686
                $sformat(insnstring, "l.lbs   r%0d,0x%04h(r%0d)",rD_num,imm_16bit,rA_num);
687
             end
688
 
689
           `OR1K_OPCODE_LHZ:
690
             begin
691
                $sformat(insnstring, "l.lhz   r%0d,0x%04h(r%0d)",rD_num,imm_16bit,rA_num);
692
             end
693
 
694
           `OR1K_OPCODE_LHS:
695
             begin
696
                $sformat(insnstring, "l.lhs   r%0d,0x%04h(r%0d)",rD_num,imm_16bit,rA_num);
697
             end
698
 
699
           `OR1K_OPCODE_SW:
700
             begin
701
                $sformat(insnstring, "l.sw    0x%04h(r%0d),r%0d",imm_split16bit,rA_num,rB_num);
702
             end
703
 
704
           `OR1K_OPCODE_SB:
705
             begin
706
                $sformat(insnstring, "l.sb    0x%04h(r%0d),r%0d",imm_split16bit,rA_num,rB_num);
707
             end
708
 
709
           `OR1K_OPCODE_SH:
710
             begin
711
                $sformat(insnstring, "l.sh    0x%04h(r%0d),r%0d",imm_split16bit,rA_num,rB_num);
712
             end
713
 
714
           `OR1K_OPCODE_MFSPR:
715
             begin
716
                $sformat(insnstring, "l.mfspr r%0d,r%0d,0x%04h",rD_num,rA_num,imm_16bit);
717
             end
718
 
719
           `OR1K_OPCODE_MTSPR:
720
             begin
721
                $sformat(insnstring, "l.mtspr r%0d,r%0d,0x%04h",rA_num,rB_num,imm_split16bit);
722
             end
723
 
724
           `OR1K_OPCODE_MOVHI:
725
             begin
726
                if (!insn[16])begin
727
                   $sformat(insnstring, "l.movhi r%0d,0x%04h",rD_num,imm_16bit);
728
                end
729
                else
730
                  $sformat(insnstring, "l.macrc r%0d",rD_num);
731
             end
732
 
733
           `OR1K_OPCODE_ADDI:
734
             begin
735
                $sformat(insnstring, "l.addi  r%0d,r%0d,0x%04h",rD_num,rA_num,imm_16bit);
736
             end
737
 
738
           `OR1K_OPCODE_ADDIC:
739
             begin
740
                $sformat(insnstring, "l.addic r%0d,r%0d,0x%04h",rD_num,rA_num,imm_16bit);
741
             end
742
 
743
           `OR1K_OPCODE_ANDI:
744
             begin
745
                $sformat(insnstring, "l.andi  r%0d,r%0d,0x%04h",rD_num,rA_num,imm_16bit);
746
             end
747
 
748
           `OR1K_OPCODE_ORI:
749
             begin
750
                $sformat(insnstring, "l.ori   r%0d,r%0d,0x%04h",rD_num,rA_num,imm_16bit);
751
             end
752
 
753
           `OR1K_OPCODE_XORI:
754
             begin
755
                $sformat(insnstring, "l.xori  r%0d,r%0d,0x%04h",rD_num,rA_num,imm_16bit);
756
             end
757
 
758
           `OR1K_OPCODE_MULI:
759
             begin
760
                $sformat(insnstring, "l.muli  r%0d,r%0d,0x%04h",rD_num,rA_num,imm_16bit);
761
             end
762
 
763
           `OR1K_OPCODE_ALU:
764
             begin
765
                case(insn[`OR1K_ALU_OPC_SELECT])
766
                  `OR1K_ALU_OPC_ADD:
767
                    $sformat(insnstring, "l.add   r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
768
                  `OR1K_ALU_OPC_ADDC:
769
                    $sformat(insnstring, "l.addc  r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
770
                  `OR1K_ALU_OPC_SUB:
771
                    $sformat(insnstring, "l.sub   r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
772
                  `OR1K_ALU_OPC_AND:
773
                    $sformat(insnstring, "l.and   r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
774
                  `OR1K_ALU_OPC_OR:
775
                    $sformat(insnstring, "l.or    r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
776
                  `OR1K_ALU_OPC_XOR:
777
                    $sformat(insnstring, "l.xor   r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
778
                  `OR1K_ALU_OPC_MUL:
779
                    $sformat(insnstring, "l.mul   r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
780
                  `OR1K_ALU_OPC_SHRT:
781
                    begin
782
                       case(insn[`OR1K_ALU_OPC_SECONDARY_SELECT])
783
                         `OR1K_ALU_OPC_SECONDARY_SHRT_SLL:
784
                           $sformat(insnstring, "l.sll   r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
785
                         `OR1K_ALU_OPC_SECONDARY_SHRT_SRL:
786
                           $sformat(insnstring, "l.srl   r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
787
                         `OR1K_ALU_OPC_SECONDARY_SHRT_SRA:
788
                           $sformat(insnstring, "l.sra   r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
789
                         `OR1K_ALU_OPC_SECONDARY_SHRT_ROR:
790
                           $sformat(insnstring, "l.ror   r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
791
                       endcase // case (insn[`OR1K_ALU_OPC_SECONDARY_SELECT])
792
                    end
793
                  `OR1K_ALU_OPC_DIV:
794
                    $sformat(insnstring, "l.div   r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
795
                  `OR1K_ALU_OPC_DIVU:
796
                    $sformat(insnstring, "l.divu  r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
797
                  `OR1K_ALU_OPC_MULU:
798
                    $sformat(insnstring, "l.mulu  r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
799
                  `OR1K_ALU_OPC_CMOV:
800
                    $sformat(insnstring, "l.cmov  r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
801
                  `OR1K_ALU_OPC_FFL1:
802
                    begin
803
                       case(insn[8])
804
                         0:
805
                           $sformat(insnstring, "l.ff1   r%0d,r%0d",rD_num,rA_num);
806
                         1:
807
                           $sformat(insnstring, "l.fl1   r%0d,r%0d",rD_num,rA_num);
808
                       endcase // case (insn[8])
809
                    end
810
 
811
                endcase // case (alu_op)
812
                //$sformat(insnstring, "r%0d,r%0d,r%0d",rD_num,rA_num,rB_num);
813
             end
814
 
815
           `OR1K_OPCODE_SHRTI:
816
             begin
817
                case(insn[`OR1K_ALU_OPC_SECONDARY_SELECT])
818
                  `OR1K_ALU_OPC_SECONDARY_SHRT_SLL:
819
                    $sformat(insnstring, "l.slli  r%0d,r%0d,0x%01h",rD_num,rA_num,insn[5:0]);
820
                  `OR1K_ALU_OPC_SECONDARY_SHRT_SRL:
821
                    $sformat(insnstring, "l.srli  r%0d,r%0d,0x%01h",rD_num,rA_num,insn[5:0]);
822
                  `OR1K_ALU_OPC_SECONDARY_SHRT_SRA:
823
                    $sformat(insnstring, "l.srai  r%0d,r%0d,0x%01h",rD_num,rA_num,insn[5:0]);
824
                  `OR1K_ALU_OPC_SECONDARY_SHRT_ROR:
825
                    $sformat(insnstring, "l.rori  r%0d,r%0d,0x%01h",rD_num,rA_num,insn[5:0]);
826
                endcase // case (insn[`OR1K_ALU_OPC_SECONDARY_SELECT])
827
                //$sformat(insnstring, "r%0d,r%0d,0x%0h",rD_num,rA_num,insn[5:0]);                              
828
             end // case: `OR1K_OPCODE_SHRTI
829
 
830
           `OR1K_OPCODE_SFIMM:
831
             begin
832
                case(insn[`OR1K_COMP_OPC_SELECT])
833
                  `OR1K_COMP_OPC_EQ:
834
                    $sformat(insnstring, "l.sfeqi r%0d,0x%04h",rA_num, imm_16bit);
835
                  `OR1K_COMP_OPC_NE:
836
                    $sformat(insnstring, "l.sfnei r%0d,0x%04h",rA_num, imm_16bit);
837
                  `OR1K_COMP_OPC_GTU:
838
                    $sformat(insnstring, "l.sfgtuir%0d,0x%04h",rA_num, imm_16bit);
839
                  `OR1K_COMP_OPC_GEU:
840
                    $sformat(insnstring, "l.sfgeuir%0d,0x%04h",rA_num, imm_16bit);
841
                  `OR1K_COMP_OPC_LTU:
842
                    $sformat(insnstring, "l.sfltuir%0d,0x%04h",rA_num, imm_16bit);
843
                  `OR1K_COMP_OPC_LEU:
844
                    $sformat(insnstring, "l.sfleuir%0d,0x%04h",rA_num, imm_16bit);
845
                  `OR1K_COMP_OPC_GTS:
846
                    $sformat(insnstring, "l.sfgtsir%0d,0x%04h",rA_num, imm_16bit);
847
                  `OR1K_COMP_OPC_GES:
848
                    $sformat(insnstring, "l.sfgesir%0d,0x%04h",rA_num, imm_16bit);
849
                  `OR1K_COMP_OPC_LTS:
850
                    $sformat(insnstring, "l.sfltsir%0d,0x%04h",rA_num, imm_16bit);
851
                  `OR1K_COMP_OPC_LES:
852
                    $sformat(insnstring, "l.sflesir%0d,0x%04h",rA_num, imm_16bit);
853
                endcase // case (sf_op[2:0])
854
 
855
                //$sformat(insnstring, "r%0d,0x%0h",rA_num, imm_16bit);
856
 
857
             end // case: `OR1K_OPCODE_SFXXI
858
 
859
           `OR1K_OPCODE_SF:
860
             begin
861
                case(insn[`OR1K_COMP_OPC_SELECT])
862
                  `OR1K_COMP_OPC_EQ:
863
                    $sformat(insnstring, "l.sfeq  r%0d,r%0d",rA_num, rB_num);
864
                  `OR1K_COMP_OPC_NE:
865
                    $sformat(insnstring, "l.sfne  r%0d,r%0d",rA_num, rB_num);
866
                  `OR1K_COMP_OPC_GTU:
867
                    $sformat(insnstring, "l.sfgtu r%0d,r%0d",rA_num, rB_num);
868
                  `OR1K_COMP_OPC_GEU:
869
                    $sformat(insnstring, "l.sfgeu r%0d,r%0d",rA_num, rB_num);
870
                  `OR1K_COMP_OPC_LTU:
871
                    $sformat(insnstring, "l.sfltu r%0d,r%0d",rA_num, rB_num);
872
                  `OR1K_COMP_OPC_LEU:
873
                    $sformat(insnstring, "l.sfleu r%0d,r%0d",rA_num, rB_num);
874
                  `OR1K_COMP_OPC_GTS:
875
                    $sformat(insnstring, "l.sfgts r%0d,r%0d",rA_num, rB_num);
876
                  `OR1K_COMP_OPC_GES:
877
                    $sformat(insnstring, "l.sfges r%0d,r%0d",rA_num, rB_num);
878
                  `OR1K_COMP_OPC_LTS:
879
                    $sformat(insnstring, "l.sflts r%0d,r%0d",rA_num, rB_num);
880
                  `OR1K_COMP_OPC_LES:
881
                    $sformat(insnstring, "l.sfles r%0d,r%0d",rA_num, rB_num);
882
                endcase // case (sf_op[2:0])
883
                //$sformat(insnstring, "r%0d,r%0d",rA_num, rB_num);
884
 
885
             end
886
 
887
           `OR1K_OPCODE_MACI:
888
             begin
889
                $sformat(insnstring, "l.maci r%0d,0x%04h",rA_num,imm_16bit);
890
             end
891
 
892
           `OR1K_OPCODE_NOP:
893
             begin
894
                $sformat(insnstring, "l.nop   0x%04h",imm_16bit);
895
             end
896
 
897
           `OR1K_OPCODE_SYSTRAPSYNC:
898
             begin
899
                case (insn[`OR1K_SYSTRAPSYNC_OPC_SELECT])
900
                  `OR1K_SYSTRAPSYNC_OPC_SYSCALL:
901
                    $sformat(insnstring, "l.sys   0x%04h",imm_16bit);
902
                  `OR1K_SYSTRAPSYNC_OPC_TRAP:
903
                    $sformat(insnstring, "l.trap  0x%04h",imm_16bit);
904
                  `OR1K_SYSTRAPSYNC_OPC_MSYNC:
905
                    $sformat(insnstring, "l.msync");
906
                  `OR1K_SYSTRAPSYNC_OPC_PSYNC:
907
                    $sformat(insnstring, "l.psync");
908
                  `OR1K_SYSTRAPSYNC_OPC_CSYNC:
909
                    $sformat(insnstring, "l.csync");
910
                endcase // case (insn[`OR1K_SYSTRAPSYNC_OPC_SELECT])
911
             end
912
           default:
913
             begin
914
                $sformat(insnstring, "%t: Unknown opcode 0x%0h",$time,opcode);
915
                $sformat(insnstring, "%t: Unknown opcode 0x%0h",$time,opcode);
916
             end
917
 
918
         endcase // case (opcode)
919
 
920
      end
921
   endtask // mor1k_insn_to_string
922
 
923
endmodule // mor1kx_module

powered by: WebSVN 2.1.0

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