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

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [amber25/] [a25_decompile.v] - Blame information for rev 87

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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