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

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [amber23/] [a23_decompile.v] - Blame information for rev 82

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

Line No. Rev Author Line
1 2 csantifort
//////////////////////////////////////////////////////////////////
2
//                                                              //
3
// Decompiler for Amber 2 Core                                  //
4
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9
//  Decompiler for debugging core - not synthesizable           //
10
//  Shows instruction in Execute Stage at last clock of         //
11
//  the instruction                                             //
12
//                                                              //
13
//  Author(s):                                                  //
14
//      - Conor Santifort, csantifort.amber@gmail.com           //
15
//                                                              //
16
//////////////////////////////////////////////////////////////////
17
//                                                              //
18
// Copyright (C) 2010 Authors and OPENCORES.ORG                 //
19
//                                                              //
20
// This source file may be used and distributed without         //
21
// restriction provided that this copyright statement is not    //
22
// removed from the file and that any derivative work contains  //
23
// the original copyright notice and the associated disclaimer. //
24
//                                                              //
25
// This source file is free software; you can redistribute it   //
26
// and/or modify it under the terms of the GNU Lesser General   //
27
// Public License as published by the Free Software Foundation; //
28
// either version 2.1 of the License, or (at your option) any   //
29
// later version.                                               //
30
//                                                              //
31
// This source is distributed in the hope that it will be       //
32
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
33
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
34
// PURPOSE.  See the GNU Lesser General Public License for more //
35
// details.                                                     //
36
//                                                              //
37
// You should have received a copy of the GNU Lesser General    //
38
// Public License along with this source; if not, download it   //
39
// from http://www.opencores.org/lgpl.shtml                     //
40
//                                                              //
41
//////////////////////////////////////////////////////////////////
42
 
43 82 csantifort
`include "global_timescale.vh"
44
`include "global_defines.vh"
45
`include "a23_config_defines.vh"
46
 
47 15 csantifort
module a23_decompile
48 2 csantifort
(
49
input                       i_clk,
50
input                       i_fetch_stall,
51
input       [31:0]          i_instruction,
52
input                       i_instruction_valid,
53
input                       i_instruction_undefined,
54
input                       i_instruction_execute,
55
input       [2:0]           i_interrupt,            // non-zero value means interrupt triggered
56
input                       i_interrupt_state,
57
input       [31:0]          i_instruction_address,
58
input       [1:0]           i_pc_sel,
59
input                       i_pc_wen
60
 
61
);
62
 
63 82 csantifort
`include "a23_localparams.vh"
64 2 csantifort
 
65 15 csantifort
`ifdef A23_DECOMPILE
66 2 csantifort
 
67
integer i;
68
 
69
wire    [31:0]         imm32;
70
wire    [7:0]          imm8;
71
wire    [11:0]         offset12;
72
wire    [7:0]          offset8;
73
wire    [3:0]          reg_n, reg_d, reg_m, reg_s;
74
wire    [4:0]          shift_imm;
75
wire    [3:0]          opcode;
76
wire    [3:0]          condition;
77
wire    [3:0]          type;
78
wire                   opcode_compare;
79
wire                   opcode_move;
80
wire                   no_shift;
81
wire                   shift_op_imm;
82
wire    [1:0]          mtrans_type;
83
wire                   s_bit;
84
 
85
reg     [(5*8)-1:0]    xINSTRUCTION_EXECUTE;
86
reg     [(5*8)-1:0]    xINSTRUCTION_EXECUTE_R = "---   ";
87
wire    [(8*8)-1:0]    TYPE_NAME;
88
reg     [3:0]          fchars;
89
reg     [31:0]         execute_address = 'd0;
90
reg     [2:0]          interrupt_d1;
91
reg     [31:0]         execute_instruction = 'd0;
92
reg                    execute_now = 'd0;
93
reg                    execute_valid = 'd0;
94
reg                    execute_undefined = 'd0;
95
 
96
 
97
// ========================================================
98
// Delay instruction to Execute stage
99
// ========================================================
100
always @( posedge i_clk )
101
    if ( !i_fetch_stall && i_instruction_valid )
102
        begin
103
        execute_instruction <= i_instruction;
104
        execute_address     <= i_instruction_address;
105
        execute_undefined   <= i_instruction_undefined;
106
        execute_now         <= 1'd1;
107
        end
108
    else
109
        execute_now         <= 1'd0;
110
 
111
 
112
always @ ( posedge i_clk )
113
    if ( !i_fetch_stall )
114
        execute_valid <= i_instruction_valid;
115
 
116
// ========================================================
117
// Open File
118
// ========================================================
119
integer decompile_file;
120
 
121
initial
122 15 csantifort
    #1 decompile_file = $fopen(`A23_DECOMPILE_FILE, "w");
123 2 csantifort
 
124
 
125
// ========================================================
126
// Fields within the instruction
127
// ========================================================
128
assign opcode      = execute_instruction[24:21];
129
assign condition   = execute_instruction[31:28];
130
assign s_bit       = execute_instruction[20];
131
assign reg_n       = execute_instruction[19:16];
132
assign reg_d       = execute_instruction[15:12];
133
assign reg_m       = execute_instruction[3:0];
134
assign reg_s       = execute_instruction[11:8];
135
assign shift_imm   = execute_instruction[11:7];
136
assign offset12    = execute_instruction[11:0];
137
assign offset8     = {execute_instruction[11:8], execute_instruction[3:0]};
138
assign imm8        = execute_instruction[7:0];
139
 
140
assign no_shift    = execute_instruction[11:4] == 8'h0;
141
assign mtrans_type = execute_instruction[24:23];
142
 
143
 
144
assign opcode_compare =
145
            opcode == CMP ||
146
            opcode == CMN ||
147
            opcode == TEQ ||
148
            opcode == TST ;
149
 
150
assign opcode_move =
151
            opcode == MOV ||
152
            opcode == MVN ;
153
 
154
assign shift_op_imm = type == REGOP && execute_instruction[25] == 1'd1;
155
 
156
assign imm32 =  execute_instruction[11:8] == 4'h0 ? {            24'h0, imm8[7:0] } :
157
                execute_instruction[11:8] == 4'h1 ? { imm8[1:0], 24'h0, imm8[7:2] } :
158
                execute_instruction[11:8] == 4'h2 ? { imm8[3:0], 24'h0, imm8[7:4] } :
159
                execute_instruction[11:8] == 4'h3 ? { imm8[5:0], 24'h0, imm8[7:6] } :
160
                execute_instruction[11:8] == 4'h4 ? { imm8[7:0], 24'h0            } :
161
                execute_instruction[11:8] == 4'h5 ? { 2'h0,  imm8[7:0], 22'h0 }     :
162
                execute_instruction[11:8] == 4'h6 ? { 4'h0,  imm8[7:0], 20'h0 }     :
163
                execute_instruction[11:8] == 4'h7 ? { 6'h0,  imm8[7:0], 18'h0 }     :
164
                execute_instruction[11:8] == 4'h8 ? { 8'h0,  imm8[7:0], 16'h0 }     :
165
                execute_instruction[11:8] == 4'h9 ? { 10'h0, imm8[7:0], 14'h0 }     :
166
                execute_instruction[11:8] == 4'ha ? { 12'h0, imm8[7:0], 12'h0 }     :
167
                execute_instruction[11:8] == 4'hb ? { 14'h0, imm8[7:0], 10'h0 }     :
168
                execute_instruction[11:8] == 4'hc ? { 16'h0, imm8[7:0], 8'h0  }     :
169
                execute_instruction[11:8] == 4'hd ? { 18'h0, imm8[7:0], 6'h0  }     :
170
                execute_instruction[11:8] == 4'he ? { 20'h0, imm8[7:0], 4'h0  }     :
171
                                                    { 22'h0, imm8[7:0], 2'h0  }     ;
172
 
173
 
174
// ========================================================
175
// Instruction decode
176
// ========================================================
177
// the order of these matters
178
assign type =
179
    {execute_instruction[27:23], execute_instruction[21:20], execute_instruction[11:4] } == { 5'b00010, 2'b00, 8'b00001001 } ? SWAP     :  // Before REGOP
180
    {execute_instruction[27:22], execute_instruction[7:4]                              } == { 6'b000000, 4'b1001           } ? MULT     :  // Before REGOP
181
    {execute_instruction[27:26]                                                        } == { 2'b00                        } ? REGOP    :
182
    {execute_instruction[27:26]                                                        } == { 2'b01                        } ? TRANS    :
183
    {execute_instruction[27:25]                                                        } == { 3'b100                       } ? MTRANS   :
184
    {execute_instruction[27:25]                                                        } == { 3'b101                       } ? BRANCH   :
185
    {execute_instruction[27:25]                                                        } == { 3'b110                       } ? CODTRANS :
186
    {execute_instruction[27:24], execute_instruction[4]                                } == { 4'b1110, 1'b0                } ? COREGOP  :
187
    {execute_instruction[27:24], execute_instruction[4]                                } == { 4'b1110, 1'b1                } ? CORTRANS :
188
                                                                                                                               SWI      ;
189
 
190
 
191
//
192
// Convert some important signals to ASCII
193
// so their values can easily be displayed on a waveform viewer
194
//
195
assign TYPE_NAME    = type == REGOP    ? "REGOP   " :
196
                      type == MULT     ? "MULT    " :
197
                      type == SWAP     ? "SWAP    " :
198
                      type == TRANS    ? "TRANS   " :
199
                      type == MTRANS   ? "MTRANS  " :
200
                      type == BRANCH   ? "BRANCH  " :
201
                      type == CODTRANS ? "CODTRANS" :
202
                      type == COREGOP  ? "COREGOP " :
203
                      type == CORTRANS ? "CORTRANS" :
204
                      type == SWI      ? "SWI     " :
205
                                         "UNKNOWN " ;
206
 
207
 
208
always @*
209
    begin
210
 
211
    if ( !execute_now )
212
        begin
213
        xINSTRUCTION_EXECUTE =  xINSTRUCTION_EXECUTE_R;
214
        end // stalled
215
 
216
    else if ( type == REGOP    && opcode == ADC                                                          ) xINSTRUCTION_EXECUTE = "adc  ";
217
    else if ( type == REGOP    && opcode == ADD                                                          ) xINSTRUCTION_EXECUTE = "add  ";
218
    else if ( type == REGOP    && opcode == AND                                                          ) xINSTRUCTION_EXECUTE = "and  ";
219
    else if ( type == BRANCH   && execute_instruction[24] == 1'b0                                        ) xINSTRUCTION_EXECUTE = "b    ";
220
    else if ( type == REGOP    && opcode == BIC                                                          ) xINSTRUCTION_EXECUTE = "bic  ";
221
    else if ( type == BRANCH   && execute_instruction[24] == 1'b1                                        ) xINSTRUCTION_EXECUTE = "bl   ";
222
    else if ( type == COREGOP                                                                            ) xINSTRUCTION_EXECUTE = "cdp  ";
223
    else if ( type == REGOP    && opcode == CMN                                                          ) xINSTRUCTION_EXECUTE = "cmn  ";
224
    else if ( type == REGOP    && opcode == CMP                                                          ) xINSTRUCTION_EXECUTE = "cmp  ";
225
    else if ( type == REGOP    && opcode == EOR                                                          ) xINSTRUCTION_EXECUTE = "eor  ";
226
    else if ( type == CODTRANS && execute_instruction[20] == 1'b1                                        ) xINSTRUCTION_EXECUTE = "ldc  ";
227
    else if ( type == MTRANS   && execute_instruction[20] == 1'b1                                        ) xINSTRUCTION_EXECUTE = "ldm  ";
228
    else if ( type == TRANS    && {execute_instruction[22],execute_instruction[20]}    == {1'b0, 1'b1}   ) xINSTRUCTION_EXECUTE = "ldr  ";
229
    else if ( type == TRANS    && {execute_instruction[22],execute_instruction[20]}    == {1'b1, 1'b1}   ) xINSTRUCTION_EXECUTE = "ldrb ";
230
    else if ( type == CORTRANS && execute_instruction[20] == 1'b0                                        ) xINSTRUCTION_EXECUTE = "mcr  ";
231
    else if ( type == MULT     && execute_instruction[21] == 1'b1                                        ) xINSTRUCTION_EXECUTE = "mla  ";
232
    else if ( type == REGOP    && opcode == MOV                                                          ) xINSTRUCTION_EXECUTE = "mov  ";
233
    else if ( type == CORTRANS && execute_instruction[20] == 1'b1                                        ) xINSTRUCTION_EXECUTE = "mrc  ";
234
    else if ( type == MULT     && execute_instruction[21] == 1'b0                                        ) xINSTRUCTION_EXECUTE = "mul  ";
235
    else if ( type == REGOP    && opcode == MVN                                                          ) xINSTRUCTION_EXECUTE = "mvn  ";
236
    else if ( type == REGOP    && opcode == ORR                                                          ) xINSTRUCTION_EXECUTE = "orr  ";
237
    else if ( type == REGOP    && opcode == RSB                                                          ) xINSTRUCTION_EXECUTE = "rsb  ";
238
    else if ( type == REGOP    && opcode == RSC                                                          ) xINSTRUCTION_EXECUTE = "rsc  ";
239
    else if ( type == REGOP    && opcode == SBC                                                          ) xINSTRUCTION_EXECUTE = "sbc  ";
240
    else if ( type == CODTRANS && execute_instruction[20] == 1'b0                                        ) xINSTRUCTION_EXECUTE = "stc  ";
241
    else if ( type == MTRANS   && execute_instruction[20] == 1'b0                                        ) xINSTRUCTION_EXECUTE = "stm  ";
242
    else if ( type == TRANS    && {execute_instruction[22],execute_instruction[20]}    == {1'b0, 1'b0}   ) xINSTRUCTION_EXECUTE = "str  ";
243
    else if ( type == TRANS    && {execute_instruction[22],execute_instruction[20]}    == {1'b1, 1'b0}   ) xINSTRUCTION_EXECUTE = "strb ";
244
    else if ( type == REGOP    && opcode == SUB                                                          ) xINSTRUCTION_EXECUTE = "sub  ";
245
    else if ( type == SWI                                                                                ) xINSTRUCTION_EXECUTE = "swi  ";
246
    else if ( type == SWAP     && execute_instruction[22] == 1'b0                                        ) xINSTRUCTION_EXECUTE = "swp  ";
247
    else if ( type == SWAP     && execute_instruction[22] == 1'b1                                        ) xINSTRUCTION_EXECUTE = "swpb ";
248
    else if ( type == REGOP    && opcode == TEQ                                                          ) xINSTRUCTION_EXECUTE = "teq  ";
249
    else if ( type == REGOP    && opcode == TST                                                          ) xINSTRUCTION_EXECUTE = "tst  ";
250
    else                                                                                                   xINSTRUCTION_EXECUTE = "unkow";
251
    end
252
 
253
always @ ( posedge i_clk )
254
    xINSTRUCTION_EXECUTE_R <= xINSTRUCTION_EXECUTE;
255
 
256
always @( posedge i_clk )
257
    if ( execute_now )
258
        begin
259
 
260
            // Interrupts override instructions that are just starting
261
        if ( interrupt_d1 == 3'd0 || interrupt_d1 == 3'd7 )
262
            begin
263 58 csantifort
            $fwrite(decompile_file,"%09d  ", `U_TB.clk_count);
264 2 csantifort
 
265
            // Right justify the address
266
            if      ( execute_address < 32'h10)        $fwrite(decompile_file,"       %01x:  ", {execute_address[ 3:1], 1'd0});
267
            else if ( execute_address < 32'h100)       $fwrite(decompile_file,"      %02x:  ",  {execute_address[ 7:1], 1'd0});
268
            else if ( execute_address < 32'h1000)      $fwrite(decompile_file,"     %03x:  ",   {execute_address[11:1], 1'd0});
269
            else if ( execute_address < 32'h10000)     $fwrite(decompile_file,"    %04x:  ",    {execute_address[15:1], 1'd0});
270
            else if ( execute_address < 32'h100000)    $fwrite(decompile_file,"   %05x:  ",     {execute_address[19:1], 1'd0});
271
            else if ( execute_address < 32'h1000000)   $fwrite(decompile_file,"  %06x:  ",      {execute_address[23:1], 1'd0});
272
            else if ( execute_address < 32'h10000000)  $fwrite(decompile_file," %07x:  ",       {execute_address[27:1], 1'd0});
273
            else                                       $fwrite(decompile_file,"%8x:  ",         {execute_address[31:1], 1'd0});
274
 
275
            // Mark that the instruction is not being executed 
276
            // condition field in execute stage allows instruction to execute ?
277
            if (!i_instruction_execute)
278
                begin
279
                $fwrite(decompile_file,"-");
280
                if ( type == SWI )
281 58 csantifort
                    $display ("Cycle %09d  SWI not taken *************", `U_TB.clk_count);
282 2 csantifort
                end
283
            else
284
                $fwrite(decompile_file," ");
285
 
286
            // ========================================
287
            // print the instruction name
288
            // ========================================
289
            case (numchars( xINSTRUCTION_EXECUTE ))
290
                4'd1: $fwrite(decompile_file,"%s", xINSTRUCTION_EXECUTE[39:32] );
291
                4'd2: $fwrite(decompile_file,"%s", xINSTRUCTION_EXECUTE[39:24] );
292
                4'd3: $fwrite(decompile_file,"%s", xINSTRUCTION_EXECUTE[39:16] );
293
                4'd4: $fwrite(decompile_file,"%s", xINSTRUCTION_EXECUTE[39: 8] );
294
            default:  $fwrite(decompile_file,"%s", xINSTRUCTION_EXECUTE[39: 0] );
295
            endcase
296
 
297
            fchars = 8 - numchars(xINSTRUCTION_EXECUTE);
298
 
299
            // Print the Multiple transfer type
300
            if (type   == MTRANS )
301
                begin
302
                w_mtrans_type;
303
                fchars = fchars - 2;
304
                end
305
 
306
            // Print the s bit
307
           if ( ((type == REGOP && !opcode_compare) || type == MULT ) && s_bit == 1'b1 )
308
                begin
309
                $fwrite(decompile_file,"s");
310
                fchars = fchars - 1;
311
                end
312
 
313
            // Print the p bit
314
           if ( type == REGOP && opcode_compare && s_bit == 1'b1 && reg_d == 4'd15 )
315
                begin
316
                $fwrite(decompile_file,"p");
317
                fchars = fchars - 1;
318
                end
319
 
320
            // Print the condition code
321
            if ( condition != AL )
322
                begin
323
                wcond;
324
                fchars = fchars - 2;
325
                end
326
 
327
            // Align spaces after instruction    
328
            case ( fchars )
329
                4'd0: $fwrite(decompile_file,"");
330
                4'd1: $fwrite(decompile_file," ");
331
                4'd2: $fwrite(decompile_file,"  ");
332
                4'd3: $fwrite(decompile_file,"   ");
333
                4'd4: $fwrite(decompile_file,"    ");
334
                4'd5: $fwrite(decompile_file,"     ");
335
                4'd6: $fwrite(decompile_file,"      ");
336
                4'd7: $fwrite(decompile_file,"       ");
337
                4'd8: $fwrite(decompile_file,"        ");
338
            default:  $fwrite(decompile_file,"         ");
339
            endcase
340
 
341
            // ========================================
342
            // print the arguments for the instruction
343
            // ========================================
344
            case ( type )
345
                REGOP:     regop_args;
346
                TRANS:     trans_args;
347
                MTRANS:    mtrans_args;
348
                BRANCH:    branch_args;
349
                MULT:      mult_args;
350
                SWAP:      swap_args;
351
                CODTRANS:  codtrans_args;
352
                COREGOP:   begin
353
                           // `TB_ERROR_MESSAGE
354
                           $write("Coregop not implemented in decompiler yet\n");
355
                           end
356
                CORTRANS:  cortrans_args;
357
                SWI:       $fwrite(decompile_file,"#0x%06h", execute_instruction[23:0]);
358
                default: begin
359
                         `TB_ERROR_MESSAGE
360
                         $write("Unknown Instruction Type ERROR\n");
361
                         end
362
            endcase
363
 
364
            $fwrite( decompile_file,"\n" );
365
            end
366
 
367
        // Undefined Instruction Interrupts    
368
        if ( i_instruction_execute && execute_undefined )
369
            begin
370 58 csantifort
            $fwrite( decompile_file,"%09d              interrupt undefined instruction", `U_TB.clk_count );
371 2 csantifort
            $fwrite( decompile_file,", return addr " );
372
            $fwrite( decompile_file,"%08x\n",  pcf(get_reg_val(5'd21)-4'd4) );
373
            end
374
 
375
        // Software Interrupt  
376
        if ( i_instruction_execute && type == SWI )
377
            begin
378 58 csantifort
            $fwrite( decompile_file,"%09d              interrupt swi", `U_TB.clk_count );
379 2 csantifort
            $fwrite( decompile_file,", return addr " );
380
            $fwrite( decompile_file,"%08x\n",  pcf(get_reg_val(5'd21)-4'd4) );
381
            end
382
        end
383
 
384
 
385
always @( posedge i_clk )
386
    if ( !i_fetch_stall )
387
        begin
388
        interrupt_d1 <= i_interrupt;
389
 
390
        // Asynchronous Interrupts    
391
        if ( interrupt_d1 != 3'd0 && i_interrupt_state )
392
            begin
393 58 csantifort
            $fwrite( decompile_file,"%09d              interrupt ", `U_TB.clk_count );
394 2 csantifort
            case ( interrupt_d1 )
395
                3'd1:    $fwrite( decompile_file,"data abort" );
396
                3'd2:    $fwrite( decompile_file,"firq" );
397
                3'd3:    $fwrite( decompile_file,"irq" );
398
                3'd4:    $fwrite( decompile_file,"address exception" );
399
                3'd5:    $fwrite( decompile_file,"instruction abort" );
400
                default: $fwrite( decompile_file,"unknown type" );
401
            endcase
402
            $fwrite( decompile_file,", return addr " );
403
 
404
            case ( interrupt_d1 )
405
                3'd1:    $fwrite(decompile_file,"%08h\n",  pcf(get_reg_val(5'd16)));
406
                3'd2:    $fwrite(decompile_file,"%08h\n",  pcf(get_reg_val(5'd17)));
407
                3'd3:    $fwrite(decompile_file,"%08h\n",  pcf(get_reg_val(5'd18)));
408
                3'd4:    $fwrite(decompile_file,"%08h\n",  pcf(get_reg_val(5'd19)));
409
                3'd5:    $fwrite(decompile_file,"%08h\n",  pcf(get_reg_val(5'd19)));
410
                3'd7:    $fwrite(decompile_file,"%08h\n",  pcf(get_reg_val(5'd20)));
411
                default: ;
412
            endcase
413
            end
414
        end
415
 
416
 
417
// jump
418
// Dont print a jump message for interrupts
419
always @( posedge i_clk )
420
        if (
421
             i_pc_sel != 2'd0 &&
422
             i_pc_wen &&
423
             !i_fetch_stall &&
424
             i_instruction_execute &&
425
             i_interrupt == 3'd0 &&
426
             !execute_undefined &&
427
             type != SWI &&
428
             execute_address != get_32bit_signal(0)  // Don't print jump to same address
429
             )
430
            begin
431 58 csantifort
            $fwrite(decompile_file,"%09d              jump    from ", `U_TB.clk_count);
432 2 csantifort
            fwrite_hex_drop_zeros(decompile_file,  pcf(execute_address));
433
            $fwrite(decompile_file," to ");
434
            fwrite_hex_drop_zeros(decompile_file,  pcf(get_32bit_signal(0)) ); // u_execute.pc_nxt
435
            $fwrite(decompile_file,", r0 %08h, ",  get_reg_val ( 5'd0 ));
436
            $fwrite(decompile_file,"r1 %08h\n",    get_reg_val ( 5'd1 ));
437
            end
438
 
439
// =================================================================================
440
// Memory Writes - Peek into fetch module
441
// =================================================================================
442
 
443
reg [31:0] tmp_address;
444
 
445
    // Data access
446
always @( posedge i_clk )
447
    // Data Write    
448
    if ( get_1bit_signal(0) && !get_1bit_signal(1) )
449
        begin
450
 
451 58 csantifort
        $fwrite(decompile_file, "%09d              write   addr ", `U_TB.clk_count);
452 2 csantifort
        tmp_address = get_32bit_signal(2);
453
        fwrite_hex_drop_zeros(decompile_file, {tmp_address [31:2], 2'd0} );
454
 
455
        $fwrite(decompile_file, ", data %08h, be %h",
456
                get_32bit_signal(3),    // u_cache.i_write_data
457
                get_4bit_signal (0));   // u_cache.i_byte_enable
458
 
459
        if ( get_1bit_signal(2) ) // Abort! address translation failed
460
            $fwrite(decompile_file, " aborted!\n");
461
        else
462
            $fwrite(decompile_file, "\n");
463
        end
464
 
465
    // Data Read    
466
    else if (get_1bit_signal(3) && !get_1bit_signal(0)  && !get_1bit_signal(1))
467
        begin
468
 
469 58 csantifort
        $fwrite(decompile_file, "%09d              read    addr ", `U_TB.clk_count);
470 2 csantifort
        tmp_address = get_32bit_signal(2);
471
        fwrite_hex_drop_zeros(decompile_file, {tmp_address[31:2], 2'd0} );
472
 
473
        $fwrite(decompile_file, ", data %08h", get_32bit_signal(4));  // u_decode.i_read_data
474
 
475
        if ( get_1bit_signal(2) ) // Abort! address translation failed
476
            $fwrite(decompile_file, " aborted!\n");
477
        else
478
            $fwrite(decompile_file, "\n");
479
        end
480
 
481
 
482
// =================================================================================
483
// Tasks
484
// =================================================================================
485
 
486
// Write Condition field
487
task wcond;
488
    begin
489
    case( condition)
490
        4'h0:    $fwrite(decompile_file,"eq");
491
        4'h1:    $fwrite(decompile_file,"ne");
492
        4'h2:    $fwrite(decompile_file,"cs");
493
        4'h3:    $fwrite(decompile_file,"cc");
494
        4'h4:    $fwrite(decompile_file,"mi");
495
        4'h5:    $fwrite(decompile_file,"pl");
496
        4'h6:    $fwrite(decompile_file,"vs");
497
        4'h7:    $fwrite(decompile_file,"vc");
498
        4'h8:    $fwrite(decompile_file,"hi");
499
        4'h9:    $fwrite(decompile_file,"ls");
500
        4'ha:    $fwrite(decompile_file,"ge");
501
        4'hb:    $fwrite(decompile_file,"lt");
502
        4'hc:    $fwrite(decompile_file,"gt");
503
        4'hd:    $fwrite(decompile_file,"le");
504
        4'he:    $fwrite(decompile_file,"  ");  // Always
505
        default: $fwrite(decompile_file,"nv");  // Never
506
    endcase
507
    end
508
endtask
509
 
510
// ldm and stm types
511
task w_mtrans_type;
512
    begin
513
    case( mtrans_type )
514
        4'h0:    $fwrite(decompile_file,"da");
515
        4'h1:    $fwrite(decompile_file,"ia");
516
        4'h2:    $fwrite(decompile_file,"db");
517
        4'h3:    $fwrite(decompile_file,"ib");
518
        default: $fwrite(decompile_file,"xx");
519
    endcase
520
    end
521
endtask
522
 
523 15 csantifort
// e.g. mrc     15, 0, r9, cr0, cr0, {0}
524 2 csantifort
task cortrans_args;
525
    begin
526
    // Co-Processor Number
527 15 csantifort
    $fwrite(decompile_file,"%1d, ", execute_instruction[11:8]);
528 2 csantifort
    // opcode1
529
    $fwrite(decompile_file,"%1d, ", execute_instruction[23:21]);
530
    // Rd [15:12]
531
    warmreg(reg_d);
532
    // CRn [19:16]
533 15 csantifort
    $fwrite(decompile_file,", cr%1d", execute_instruction[19:16]);
534 2 csantifort
    // CRm [3:0]
535 15 csantifort
    $fwrite(decompile_file,", cr%1d", execute_instruction[3:0]);
536 2 csantifort
    // Opcode2 [7:5]
537 15 csantifort
    $fwrite(decompile_file,", {%1d}",   execute_instruction[7:5]);
538 2 csantifort
    end
539
endtask
540
 
541
 
542
// ldc  15, 0, r9, cr0, cr0, {0}
543
task codtrans_args;
544
    begin
545
    // Co-Processor Number
546 15 csantifort
    $fwrite(decompile_file,"%1d, ", execute_instruction[11:8]);
547 2 csantifort
    // CRd [15:12]
548 15 csantifort
    $fwrite(decompile_file,"cr%1d, ", execute_instruction[15:12]);
549 2 csantifort
    // Rd [19:16]
550
    warmreg(reg_n);
551
    end
552
endtask
553
 
554
 
555
task branch_args;
556
reg [31:0] shift_amount;
557
    begin
558
    if (execute_instruction[23]) // negative
559
        shift_amount = {~execute_instruction[23:0] + 24'd1, 2'd0};
560
    else
561
        shift_amount = {execute_instruction[23:0], 2'd0};
562
 
563
    if (execute_instruction[23]) // negative
564
        fwrite_hex_drop_zeros ( decompile_file, get_reg_val( 5'd21 ) - shift_amount );
565
    else
566
        fwrite_hex_drop_zeros ( decompile_file, get_reg_val( 5'd21 ) + shift_amount );
567
    end
568
endtask
569
 
570
 
571
task mult_args;
572
    begin
573
    warmreg(reg_n);  // Rd is in the Rn position for MULT instructions
574
    $fwrite(decompile_file,", ");
575
    warmreg(reg_m);
576
    $fwrite(decompile_file,", ");
577
    warmreg(reg_s);
578
 
579
    if (execute_instruction[21]) // MLA
580
        begin
581
        $fwrite(decompile_file,", ");
582
        warmreg(reg_d);
583
        end
584
    end
585
endtask
586
 
587
 
588
task swap_args;
589
    begin
590
    warmreg(reg_d);
591
    $fwrite(decompile_file,", ");
592
    warmreg(reg_m);
593
    $fwrite(decompile_file,", [");
594
    warmreg(reg_n);
595
    $fwrite(decompile_file,"]");
596
    end
597
endtask
598
 
599
 
600
task regop_args;
601
    begin
602
    if (!opcode_compare)
603
        warmreg(reg_d);
604
 
605
    if (!opcode_move )
606
        begin
607
        if (!opcode_compare)
608
            begin
609
            $fwrite(decompile_file,", ");
610
            if (reg_d < 4'd10 || reg_d > 4'd12)
611
                $fwrite(decompile_file," ");
612
            end
613
        warmreg(reg_n);
614
        $fwrite(decompile_file,", ");
615
        if (reg_n < 4'd10 || reg_n > 4'd12)
616
            $fwrite(decompile_file," ");
617
        end
618
    else
619
        begin
620
        $fwrite(decompile_file,", ");
621
        if (reg_d < 4'd10 || reg_d > 4'd12)
622
            $fwrite(decompile_file," ");
623
        end
624
 
625
    if (shift_op_imm)
626
        begin
627
        if (|imm32[31:15])
628
            $fwrite(decompile_file,"#0x%08h", imm32);
629
        else
630
            $fwrite(decompile_file,"#%1d", imm32);
631
        end
632
    else // Rm
633
        begin
634
        warmreg(reg_m);
635
        if (execute_instruction[4])
636
            // Register Shifts
637
            wshiftreg;
638
        else
639
            // Immediate shifts
640
            wshift;
641
        end
642
    end
643
endtask
644
 
645
 
646
task trans_args;
647
    begin
648
    warmreg(reg_d);   // Destination register
649
 
650
    casez ({execute_instruction[25:23], execute_instruction[21], no_shift, offset12==12'd0})
651
           6'b0100?0 : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,", #-%1d]" , offset12); end
652
           6'b0110?0 : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,", #%1d]"  , offset12); end
653
           6'b0100?1 : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"]"); end
654
           6'b0110?1 : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"]"); end
655
           6'b0101?? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,", #-%1d]!", offset12); end
656
           6'b0111?? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,", #%1d]!" , offset12); end
657
 
658
           6'b0000?0 : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"], #-%1d", offset12); end
659
           6'b0010?0 : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"], #%1d" , offset12); end
660
           6'b0001?0 : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"], #-%1d", offset12); end
661
           6'b0011?0 : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"], #%1d" , offset12); end
662
 
663
           6'b0000?1 : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"]"); end
664
           6'b0010?1 : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"]"); end
665
           6'b0001?1 : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"]"); end
666
           6'b0011?1 : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"]"); end
667
 
668
           6'b11001? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,", -");  warmreg(reg_m); $fwrite(decompile_file,"]");  end
669
           6'b11101? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,", ");   warmreg(reg_m); $fwrite(decompile_file,"]");  end
670
           6'b11011? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,", -");  warmreg(reg_m); $fwrite(decompile_file,"]!"); end
671
           6'b11111? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,", ");   warmreg(reg_m); $fwrite(decompile_file,"]!"); end
672
 
673
           6'b10001? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"], -"); warmreg(reg_m);  end
674
           6'b10101? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"], ");  warmreg(reg_m);  end
675
           6'b10011? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"], -"); warmreg(reg_m);  end
676
           6'b10111? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"], ");  warmreg(reg_m);  end
677
 
678
           6'b11000? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,", -");  warmreg(reg_m); wshift; $fwrite(decompile_file,"]"); end
679
           6'b11100? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,", ");   warmreg(reg_m); wshift; $fwrite(decompile_file,"]"); end
680
           6'b11010? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,", -");  warmreg(reg_m); wshift; $fwrite(decompile_file,"]!");end
681
           6'b11110? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,", ");   warmreg(reg_m); wshift; $fwrite(decompile_file,"]!");end
682
 
683
           6'b10000? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"], -"); warmreg(reg_m); wshift; end
684
           6'b10100? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"], ");  warmreg(reg_m); wshift; end
685
           6'b10010? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"], -"); warmreg(reg_m); wshift; end
686
           6'b10110? : begin $fwrite(decompile_file,", ["); warmreg(reg_n); $fwrite(decompile_file,"], ");  warmreg(reg_m); wshift; end
687
 
688
    endcase
689
    end
690
endtask
691
 
692
 
693
task mtrans_args;
694
    begin
695
    warmreg(reg_n);
696
    if (execute_instruction[21]) $fwrite(decompile_file,"!");
697
    $fwrite(decompile_file,", {");
698
    for (i=0;i<16;i=i+1)
699
        if (execute_instruction[i])
700
            begin
701
            warmreg(i);
702
            if (more_to_come(execute_instruction[15:0], i))
703
                $fwrite(decompile_file,", ");
704
            end
705
    $fwrite(decompile_file,"}");
706
    // SDM: store the user mode registers, when in priviledged mode     
707
    if (execute_instruction[22:20] == 3'b100)
708
        $fwrite(decompile_file,"^");
709
    end
710
endtask
711
 
712
 
713
task wshift;
714
    begin
715
    // Check that its a valid shift operation. LSL by #0 is the null operator                                    
716
    if (execute_instruction[6:5] != LSL || shift_imm != 5'd0)
717
        begin
718
        case(execute_instruction[6:5])
719
            2'd0: $fwrite(decompile_file,", lsl");
720
            2'd1: $fwrite(decompile_file,", lsr");
721
            2'd2: $fwrite(decompile_file,", asr");
722
            2'd3: if (shift_imm == 5'd0) $fwrite(decompile_file,", rrx"); else $fwrite(decompile_file,", ror");
723
        endcase
724
 
725
       if (execute_instruction[6:5] != 2'd3 || shift_imm != 5'd0)
726
           $fwrite(decompile_file," #%1d", shift_imm);
727
       end
728
    end
729
endtask
730
 
731
 
732
task wshiftreg;
733
    begin
734
    case(execute_instruction[6:5])
735
        2'd0: $fwrite(decompile_file,", lsl ");
736
        2'd1: $fwrite(decompile_file,", lsr ");
737
        2'd2: $fwrite(decompile_file,", asr ");
738
        2'd3: $fwrite(decompile_file,", ror ");
739
    endcase
740
 
741
    warmreg(reg_s);
742
    end
743
endtask
744
 
745
 
746
task warmreg;
747
input [3:0] regnum;
748
    begin
749 15 csantifort
    if (regnum < 4'd12)
750 2 csantifort
        $fwrite(decompile_file,"r%1d", regnum);
751
    else
752
    case (regnum)
753 15 csantifort
        4'd12   : $fwrite(decompile_file,"ip");
754 2 csantifort
        4'd13   : $fwrite(decompile_file,"sp");
755
        4'd14   : $fwrite(decompile_file,"lr");
756
        4'd15   : $fwrite(decompile_file,"pc");
757
    endcase
758
    end
759
endtask
760
 
761
 
762
task fwrite_hex_drop_zeros;
763
input [31:0] file;
764
input [31:0] num;
765
    begin
766
    if (num[31:28] != 4'd0)
767
        $fwrite(file, "%x", num);
768
    else if (num[27:24] != 4'd0)
769
        $fwrite(file, "%x", num[27:0]);
770
    else if (num[23:20] != 4'd0)
771
        $fwrite(file, "%x", num[23:0]);
772
    else if (num[19:16] != 4'd0)
773
        $fwrite(file, "%x", num[19:0]);
774
    else if (num[15:12] != 4'd0)
775
        $fwrite(file, "%x", num[15:0]);
776
    else if (num[11:8] != 4'd0)
777
        $fwrite(file, "%x", num[11:0]);
778
    else if (num[7:4] != 4'd0)
779
        $fwrite(file, "%x", num[7:0]);
780
    else
781
        $fwrite(file, "%x", num[3:0]);
782
 
783
    end
784
endtask
785
 
786
 
787
 
788
// =================================================================================
789
// Functions
790
// =================================================================================
791
 
792
// Get current value of register
793
function [31:0] get_reg_val;
794
input [4:0] regnum;
795
begin
796
    case (regnum)
797
        5'd0   : get_reg_val = `U_REGISTER_BANK.r0_out;
798
        5'd1   : get_reg_val = `U_REGISTER_BANK.r1_out;
799
        5'd2   : get_reg_val = `U_REGISTER_BANK.r2_out;
800
        5'd3   : get_reg_val = `U_REGISTER_BANK.r3_out;
801
        5'd4   : get_reg_val = `U_REGISTER_BANK.r4_out;
802
        5'd5   : get_reg_val = `U_REGISTER_BANK.r5_out;
803
        5'd6   : get_reg_val = `U_REGISTER_BANK.r6_out;
804
        5'd7   : get_reg_val = `U_REGISTER_BANK.r7_out;
805
        5'd8   : get_reg_val = `U_REGISTER_BANK.r8_out;
806
        5'd9   : get_reg_val = `U_REGISTER_BANK.r9_out;
807
        5'd10  : get_reg_val = `U_REGISTER_BANK.r10_out;
808
        5'd11  : get_reg_val = `U_REGISTER_BANK.r11_out;
809
        5'd12  : get_reg_val = `U_REGISTER_BANK.r12_out;
810
        5'd13  : get_reg_val = `U_REGISTER_BANK.r13_out;
811
        5'd14  : get_reg_val = `U_REGISTER_BANK.r14_out;
812
        5'd15  : get_reg_val = `U_REGISTER_BANK.r15_out_rm; // the version of pc with status bits 
813
 
814
        5'd16  : get_reg_val = `U_REGISTER_BANK.r14_svc;
815
        5'd17  : get_reg_val = `U_REGISTER_BANK.r14_firq;
816
        5'd18  : get_reg_val = `U_REGISTER_BANK.r14_irq;
817
        5'd19  : get_reg_val = `U_REGISTER_BANK.r14_svc;
818
        5'd20  : get_reg_val = `U_REGISTER_BANK.r14_svc;
819
        5'd21  : get_reg_val = `U_REGISTER_BANK.r15_out_rn; // the version of pc without status bits 
820
    endcase
821
end
822
endfunction
823
 
824
 
825
function [31:0] get_32bit_signal;
826
input [2:0] num;
827
begin
828
    case (num)
829
        3'd0: get_32bit_signal = `U_EXECUTE.pc_nxt;
830
        3'd1: get_32bit_signal = `U_FETCH.i_address;
831
        3'd2: get_32bit_signal = `U_FETCH.i_address;
832
        3'd3: get_32bit_signal = `U_CACHE.i_write_data;
833
        3'd4: get_32bit_signal = `U_DECODE.i_read_data;
834
    endcase
835
end
836
endfunction
837
 
838
 
839
function get_1bit_signal;
840
input [2:0] num;
841
begin
842
    case (num)
843
        3'd0: get_1bit_signal = `U_FETCH.i_write_enable;
844
        3'd1: get_1bit_signal = `U_AMBER.fetch_stall;
845
        3'd2: get_1bit_signal = 1'd0;
846
        3'd3: get_1bit_signal = `U_FETCH.i_data_access;
847
    endcase
848
end
849
endfunction
850
 
851
 
852
function [3:0] get_4bit_signal;
853
input [2:0] num;
854
begin
855
    case (num)
856
        3'd0: get_4bit_signal = `U_CACHE.i_byte_enable;
857
    endcase
858
end
859
endfunction
860
 
861
 
862
function [3:0] numchars;
863
input [(5*8)-1:0] xINSTRUCTION_EXECUTE;
864
begin
865
     if (xINSTRUCTION_EXECUTE[31:0] == "    ")
866
    numchars = 4'd1;
867
else if (xINSTRUCTION_EXECUTE[23:0] == "   ")
868
    numchars = 4'd2;
869
else if (xINSTRUCTION_EXECUTE[15:0] == "  ")
870
    numchars = 4'd3;
871
else if (xINSTRUCTION_EXECUTE[7:0]  == " ")
872
    numchars = 4'd4;
873
else
874
    numchars = 4'd5;
875
end
876
endfunction
877
 
878
 
879
function more_to_come;
880
input [15:0] regs;
881
input [31:0] i;
882
begin
883
case (i)
884
    15 : more_to_come = 1'd0;
885
    14 : more_to_come =  regs[15]    ? 1'd1 : 1'd0;
886
    13 : more_to_come = |regs[15:14] ? 1'd1 : 1'd0;
887
    12 : more_to_come = |regs[15:13] ? 1'd1 : 1'd0;
888
    11 : more_to_come = |regs[15:12] ? 1'd1 : 1'd0;
889
    10 : more_to_come = |regs[15:11] ? 1'd1 : 1'd0;
890
     9 : more_to_come = |regs[15:10] ? 1'd1 : 1'd0;
891
     8 : more_to_come = |regs[15: 9] ? 1'd1 : 1'd0;
892
     7 : more_to_come = |regs[15: 8] ? 1'd1 : 1'd0;
893
     6 : more_to_come = |regs[15: 7] ? 1'd1 : 1'd0;
894
     5 : more_to_come = |regs[15: 6] ? 1'd1 : 1'd0;
895
     4 : more_to_come = |regs[15: 5] ? 1'd1 : 1'd0;
896
     3 : more_to_come = |regs[15: 4] ? 1'd1 : 1'd0;
897
     2 : more_to_come = |regs[15: 3] ? 1'd1 : 1'd0;
898
     1 : more_to_come = |regs[15: 2] ? 1'd1 : 1'd0;
899
 
900
endcase
901
end
902
endfunction
903
 
904
`endif
905
 
906
endmodule
907
 

powered by: WebSVN 2.1.0

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