Line 72... |
Line 72... |
wire [7:0] offset8;
|
wire [7:0] offset8;
|
wire [3:0] reg_n, reg_d, reg_m, reg_s;
|
wire [3:0] reg_n, reg_d, reg_m, reg_s;
|
wire [4:0] shift_imm;
|
wire [4:0] shift_imm;
|
wire [3:0] opcode;
|
wire [3:0] opcode;
|
wire [3:0] condition;
|
wire [3:0] condition;
|
wire [3:0] type;
|
wire [3:0] itype;
|
wire opcode_compare;
|
wire opcode_compare;
|
wire opcode_move;
|
wire opcode_move;
|
wire no_shift;
|
wire no_shift;
|
wire shift_op_imm;
|
wire shift_op_imm;
|
wire [1:0] mtrans_type;
|
wire [1:0] mtrans_itype;
|
wire s_bit;
|
wire s_bit;
|
|
|
reg [(5*8)-1:0] xINSTRUCTION_EXECUTE;
|
reg [(5*8)-1:0] xINSTRUCTION_EXECUTE;
|
reg [(5*8)-1:0] xINSTRUCTION_EXECUTE_R = "--- ";
|
reg [(5*8)-1:0] xINSTRUCTION_EXECUTE_R = "--- ";
|
wire [(8*8)-1:0] TYPE_NAME;
|
wire [(8*8)-1:0] TYPE_NAME;
|
Line 136... |
Line 136... |
assign offset12 = execute_instruction[11:0];
|
assign offset12 = execute_instruction[11:0];
|
assign offset8 = {execute_instruction[11:8], execute_instruction[3:0]};
|
assign offset8 = {execute_instruction[11:8], execute_instruction[3:0]};
|
assign imm8 = execute_instruction[7:0];
|
assign imm8 = execute_instruction[7:0];
|
|
|
assign no_shift = execute_instruction[11:4] == 8'h0;
|
assign no_shift = execute_instruction[11:4] == 8'h0;
|
assign mtrans_type = execute_instruction[24:23];
|
assign mtrans_itype = execute_instruction[24:23];
|
|
|
|
|
assign opcode_compare =
|
assign opcode_compare =
|
opcode == CMP ||
|
opcode == CMP ||
|
opcode == CMN ||
|
opcode == CMN ||
|
Line 149... |
Line 149... |
|
|
assign opcode_move =
|
assign opcode_move =
|
opcode == MOV ||
|
opcode == MOV ||
|
opcode == MVN ;
|
opcode == MVN ;
|
|
|
assign shift_op_imm = type == REGOP && execute_instruction[25] == 1'd1;
|
assign shift_op_imm = itype == REGOP && execute_instruction[25] == 1'd1;
|
|
|
assign imm32 = execute_instruction[11:8] == 4'h0 ? { 24'h0, imm8[7:0] } :
|
assign imm32 = execute_instruction[11:8] == 4'h0 ? { 24'h0, imm8[7:0] } :
|
execute_instruction[11:8] == 4'h1 ? { imm8[1:0], 24'h0, imm8[7:2] } :
|
execute_instruction[11:8] == 4'h1 ? { imm8[1:0], 24'h0, imm8[7:2] } :
|
execute_instruction[11:8] == 4'h2 ? { imm8[3:0], 24'h0, imm8[7:4] } :
|
execute_instruction[11:8] == 4'h2 ? { imm8[3:0], 24'h0, imm8[7:4] } :
|
execute_instruction[11:8] == 4'h3 ? { imm8[5:0], 24'h0, imm8[7:6] } :
|
execute_instruction[11:8] == 4'h3 ? { imm8[5:0], 24'h0, imm8[7:6] } :
|
Line 173... |
Line 173... |
|
|
// ========================================================
|
// ========================================================
|
// Instruction decode
|
// Instruction decode
|
// ========================================================
|
// ========================================================
|
// the order of these matters
|
// the order of these matters
|
assign type =
|
assign itype =
|
{execute_instruction[27:23], execute_instruction[21:20], execute_instruction[11:4] } == { 5'b00010, 2'b00, 8'b00001001 } ? SWAP : // Before REGOP
|
{execute_instruction[27:23], execute_instruction[21:20], execute_instruction[11:4] } == { 5'b00010, 2'b00, 8'b00001001 } ? SWAP : // Before REGOP
|
{execute_instruction[27:22], execute_instruction[7:4] } == { 6'b000000, 4'b1001 } ? MULT : // Before REGOP
|
{execute_instruction[27:22], execute_instruction[7:4] } == { 6'b000000, 4'b1001 } ? MULT : // Before REGOP
|
{execute_instruction[27:26] } == { 2'b00 } ? REGOP :
|
{execute_instruction[27:26] } == { 2'b00 } ? REGOP :
|
{execute_instruction[27:26] } == { 2'b01 } ? TRANS :
|
{execute_instruction[27:26] } == { 2'b01 } ? TRANS :
|
{execute_instruction[27:25] } == { 3'b100 } ? MTRANS :
|
{execute_instruction[27:25] } == { 3'b100 } ? MTRANS :
|
Line 190... |
Line 190... |
|
|
//
|
//
|
// Convert some important signals to ASCII
|
// Convert some important signals to ASCII
|
// so their values can easily be displayed on a waveform viewer
|
// so their values can easily be displayed on a waveform viewer
|
//
|
//
|
assign TYPE_NAME = type == REGOP ? "REGOP " :
|
assign TYPE_NAME = itype == REGOP ? "REGOP " :
|
type == MULT ? "MULT " :
|
itype == MULT ? "MULT " :
|
type == SWAP ? "SWAP " :
|
itype == SWAP ? "SWAP " :
|
type == TRANS ? "TRANS " :
|
itype == TRANS ? "TRANS " :
|
type == MTRANS ? "MTRANS " :
|
itype == MTRANS ? "MTRANS " :
|
type == BRANCH ? "BRANCH " :
|
itype == BRANCH ? "BRANCH " :
|
type == CODTRANS ? "CODTRANS" :
|
itype == CODTRANS ? "CODTRANS" :
|
type == COREGOP ? "COREGOP " :
|
itype == COREGOP ? "COREGOP " :
|
type == CORTRANS ? "CORTRANS" :
|
itype == CORTRANS ? "CORTRANS" :
|
type == SWI ? "SWI " :
|
itype == SWI ? "SWI " :
|
"UNKNOWN " ;
|
"UNKNOWN " ;
|
|
|
|
|
always @*
|
always @*
|
begin
|
begin
|
Line 211... |
Line 211... |
if ( !execute_now )
|
if ( !execute_now )
|
begin
|
begin
|
xINSTRUCTION_EXECUTE = xINSTRUCTION_EXECUTE_R;
|
xINSTRUCTION_EXECUTE = xINSTRUCTION_EXECUTE_R;
|
end // stalled
|
end // stalled
|
|
|
else if ( type == REGOP && opcode == ADC ) xINSTRUCTION_EXECUTE = "adc ";
|
else if ( itype == REGOP && opcode == ADC ) xINSTRUCTION_EXECUTE = "adc ";
|
else if ( type == REGOP && opcode == ADD ) xINSTRUCTION_EXECUTE = "add ";
|
else if ( itype == REGOP && opcode == ADD ) xINSTRUCTION_EXECUTE = "add ";
|
else if ( type == REGOP && opcode == AND ) xINSTRUCTION_EXECUTE = "and ";
|
else if ( itype == REGOP && opcode == AND ) xINSTRUCTION_EXECUTE = "and ";
|
else if ( type == BRANCH && execute_instruction[24] == 1'b0 ) xINSTRUCTION_EXECUTE = "b ";
|
else if ( itype == BRANCH && execute_instruction[24] == 1'b0 ) xINSTRUCTION_EXECUTE = "b ";
|
else if ( type == REGOP && opcode == BIC ) xINSTRUCTION_EXECUTE = "bic ";
|
else if ( itype == REGOP && opcode == BIC ) xINSTRUCTION_EXECUTE = "bic ";
|
else if ( type == BRANCH && execute_instruction[24] == 1'b1 ) xINSTRUCTION_EXECUTE = "bl ";
|
else if ( itype == BRANCH && execute_instruction[24] == 1'b1 ) xINSTRUCTION_EXECUTE = "bl ";
|
else if ( type == COREGOP ) xINSTRUCTION_EXECUTE = "cdp ";
|
else if ( itype == COREGOP ) xINSTRUCTION_EXECUTE = "cdp ";
|
else if ( type == REGOP && opcode == CMN ) xINSTRUCTION_EXECUTE = "cmn ";
|
else if ( itype == REGOP && opcode == CMN ) xINSTRUCTION_EXECUTE = "cmn ";
|
else if ( type == REGOP && opcode == CMP ) xINSTRUCTION_EXECUTE = "cmp ";
|
else if ( itype == REGOP && opcode == CMP ) xINSTRUCTION_EXECUTE = "cmp ";
|
else if ( type == REGOP && opcode == EOR ) xINSTRUCTION_EXECUTE = "eor ";
|
else if ( itype == REGOP && opcode == EOR ) xINSTRUCTION_EXECUTE = "eor ";
|
else if ( type == CODTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldc ";
|
else if ( itype == CODTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldc ";
|
else if ( type == MTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldm ";
|
else if ( itype == MTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldm ";
|
else if ( type == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b0, 1'b1} ) xINSTRUCTION_EXECUTE = "ldr ";
|
else if ( itype == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b0, 1'b1} ) xINSTRUCTION_EXECUTE = "ldr ";
|
else if ( type == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b1, 1'b1} ) xINSTRUCTION_EXECUTE = "ldrb ";
|
else if ( itype == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b1, 1'b1} ) xINSTRUCTION_EXECUTE = "ldrb ";
|
else if ( type == CORTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "mcr ";
|
else if ( itype == CORTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "mcr ";
|
else if ( type == MULT && execute_instruction[21] == 1'b1 ) xINSTRUCTION_EXECUTE = "mla ";
|
else if ( itype == MULT && execute_instruction[21] == 1'b1 ) xINSTRUCTION_EXECUTE = "mla ";
|
else if ( type == REGOP && opcode == MOV ) xINSTRUCTION_EXECUTE = "mov ";
|
else if ( itype == REGOP && opcode == MOV ) xINSTRUCTION_EXECUTE = "mov ";
|
else if ( type == CORTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "mrc ";
|
else if ( itype == CORTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "mrc ";
|
else if ( type == MULT && execute_instruction[21] == 1'b0 ) xINSTRUCTION_EXECUTE = "mul ";
|
else if ( itype == MULT && execute_instruction[21] == 1'b0 ) xINSTRUCTION_EXECUTE = "mul ";
|
else if ( type == REGOP && opcode == MVN ) xINSTRUCTION_EXECUTE = "mvn ";
|
else if ( itype == REGOP && opcode == MVN ) xINSTRUCTION_EXECUTE = "mvn ";
|
else if ( type == REGOP && opcode == ORR ) xINSTRUCTION_EXECUTE = "orr ";
|
else if ( itype == REGOP && opcode == ORR ) xINSTRUCTION_EXECUTE = "orr ";
|
else if ( type == REGOP && opcode == RSB ) xINSTRUCTION_EXECUTE = "rsb ";
|
else if ( itype == REGOP && opcode == RSB ) xINSTRUCTION_EXECUTE = "rsb ";
|
else if ( type == REGOP && opcode == RSC ) xINSTRUCTION_EXECUTE = "rsc ";
|
else if ( itype == REGOP && opcode == RSC ) xINSTRUCTION_EXECUTE = "rsc ";
|
else if ( type == REGOP && opcode == SBC ) xINSTRUCTION_EXECUTE = "sbc ";
|
else if ( itype == REGOP && opcode == SBC ) xINSTRUCTION_EXECUTE = "sbc ";
|
else if ( type == CODTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stc ";
|
else if ( itype == CODTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stc ";
|
else if ( type == MTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stm ";
|
else if ( itype == MTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stm ";
|
else if ( type == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b0, 1'b0} ) xINSTRUCTION_EXECUTE = "str ";
|
else if ( itype == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b0, 1'b0} ) xINSTRUCTION_EXECUTE = "str ";
|
else if ( type == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b1, 1'b0} ) xINSTRUCTION_EXECUTE = "strb ";
|
else if ( itype == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b1, 1'b0} ) xINSTRUCTION_EXECUTE = "strb ";
|
else if ( type == REGOP && opcode == SUB ) xINSTRUCTION_EXECUTE = "sub ";
|
else if ( itype == REGOP && opcode == SUB ) xINSTRUCTION_EXECUTE = "sub ";
|
else if ( type == SWI ) xINSTRUCTION_EXECUTE = "swi ";
|
else if ( itype == SWI ) xINSTRUCTION_EXECUTE = "swi ";
|
else if ( type == SWAP && execute_instruction[22] == 1'b0 ) xINSTRUCTION_EXECUTE = "swp ";
|
else if ( itype == SWAP && execute_instruction[22] == 1'b0 ) xINSTRUCTION_EXECUTE = "swp ";
|
else if ( type == SWAP && execute_instruction[22] == 1'b1 ) xINSTRUCTION_EXECUTE = "swpb ";
|
else if ( itype == SWAP && execute_instruction[22] == 1'b1 ) xINSTRUCTION_EXECUTE = "swpb ";
|
else if ( type == REGOP && opcode == TEQ ) xINSTRUCTION_EXECUTE = "teq ";
|
else if ( itype == REGOP && opcode == TEQ ) xINSTRUCTION_EXECUTE = "teq ";
|
else if ( type == REGOP && opcode == TST ) xINSTRUCTION_EXECUTE = "tst ";
|
else if ( itype == REGOP && opcode == TST ) xINSTRUCTION_EXECUTE = "tst ";
|
else xINSTRUCTION_EXECUTE = "unkow";
|
else xINSTRUCTION_EXECUTE = "unkow";
|
end
|
end
|
|
|
always @ ( posedge i_clk )
|
always @ ( posedge i_clk )
|
xINSTRUCTION_EXECUTE_R <= xINSTRUCTION_EXECUTE;
|
xINSTRUCTION_EXECUTE_R <= xINSTRUCTION_EXECUTE;
|
Line 275... |
Line 275... |
// Mark that the instruction is not being executed
|
// Mark that the instruction is not being executed
|
// condition field in execute stage allows instruction to execute ?
|
// condition field in execute stage allows instruction to execute ?
|
if (!i_instruction_execute)
|
if (!i_instruction_execute)
|
begin
|
begin
|
$fwrite(decompile_file,"-");
|
$fwrite(decompile_file,"-");
|
if ( type == SWI )
|
if ( itype == SWI )
|
$display ("Cycle %09d SWI not taken *************", `U_TB.clk_count);
|
$display ("Cycle %09d SWI not taken *************", `U_TB.clk_count);
|
end
|
end
|
else
|
else
|
$fwrite(decompile_file," ");
|
$fwrite(decompile_file," ");
|
|
|
Line 294... |
Line 294... |
default: $fwrite(decompile_file,"%s", xINSTRUCTION_EXECUTE[39: 0] );
|
default: $fwrite(decompile_file,"%s", xINSTRUCTION_EXECUTE[39: 0] );
|
endcase
|
endcase
|
|
|
fchars = 8 - numchars(xINSTRUCTION_EXECUTE);
|
fchars = 8 - numchars(xINSTRUCTION_EXECUTE);
|
|
|
// Print the Multiple transfer type
|
// Print the Multiple transfer itype
|
if (type == MTRANS )
|
if (itype == MTRANS )
|
begin
|
begin
|
w_mtrans_type;
|
w_mtrans_type;
|
fchars = fchars - 2;
|
fchars = fchars - 2;
|
end
|
end
|
|
|
// Print the s bit
|
// Print the s bit
|
if ( ((type == REGOP && !opcode_compare) || type == MULT ) && s_bit == 1'b1 )
|
if ( ((itype == REGOP && !opcode_compare) || itype == MULT ) && s_bit == 1'b1 )
|
begin
|
begin
|
$fwrite(decompile_file,"s");
|
$fwrite(decompile_file,"s");
|
fchars = fchars - 1;
|
fchars = fchars - 1;
|
end
|
end
|
|
|
// Print the p bit
|
// Print the p bit
|
if ( type == REGOP && opcode_compare && s_bit == 1'b1 && reg_d == 4'd15 )
|
if ( itype == REGOP && opcode_compare && s_bit == 1'b1 && reg_d == 4'd15 )
|
begin
|
begin
|
$fwrite(decompile_file,"p");
|
$fwrite(decompile_file,"p");
|
fchars = fchars - 1;
|
fchars = fchars - 1;
|
end
|
end
|
|
|
Line 339... |
Line 339... |
endcase
|
endcase
|
|
|
// ========================================
|
// ========================================
|
// print the arguments for the instruction
|
// print the arguments for the instruction
|
// ========================================
|
// ========================================
|
case ( type )
|
case ( itype )
|
REGOP: regop_args;
|
REGOP: regop_args;
|
TRANS: trans_args;
|
TRANS: trans_args;
|
MTRANS: mtrans_args;
|
MTRANS: mtrans_args;
|
BRANCH: branch_args;
|
BRANCH: branch_args;
|
MULT: mult_args;
|
MULT: mult_args;
|
Line 371... |
Line 371... |
$fwrite( decompile_file,", return addr " );
|
$fwrite( decompile_file,", return addr " );
|
$fwrite( decompile_file,"%08x\n", pcf(get_reg_val(5'd21)-4'd4) );
|
$fwrite( decompile_file,"%08x\n", pcf(get_reg_val(5'd21)-4'd4) );
|
end
|
end
|
|
|
// Software Interrupt
|
// Software Interrupt
|
if ( i_instruction_execute && type == SWI )
|
if ( i_instruction_execute && itype == SWI )
|
begin
|
begin
|
$fwrite( decompile_file,"%09d interrupt swi", `U_TB.clk_count );
|
$fwrite( decompile_file,"%09d interrupt swi", `U_TB.clk_count );
|
$fwrite( decompile_file,", return addr " );
|
$fwrite( decompile_file,", return addr " );
|
$fwrite( decompile_file,"%08x\n", pcf(get_reg_val(5'd21)-4'd4) );
|
$fwrite( decompile_file,"%08x\n", pcf(get_reg_val(5'd21)-4'd4) );
|
end
|
end
|
Line 395... |
Line 395... |
3'd1: $fwrite( decompile_file,"data abort" );
|
3'd1: $fwrite( decompile_file,"data abort" );
|
3'd2: $fwrite( decompile_file,"firq" );
|
3'd2: $fwrite( decompile_file,"firq" );
|
3'd3: $fwrite( decompile_file,"irq" );
|
3'd3: $fwrite( decompile_file,"irq" );
|
3'd4: $fwrite( decompile_file,"address exception" );
|
3'd4: $fwrite( decompile_file,"address exception" );
|
3'd5: $fwrite( decompile_file,"instruction abort" );
|
3'd5: $fwrite( decompile_file,"instruction abort" );
|
default: $fwrite( decompile_file,"unknown type" );
|
default: $fwrite( decompile_file,"unknown itype" );
|
endcase
|
endcase
|
$fwrite( decompile_file,", return addr " );
|
$fwrite( decompile_file,", return addr " );
|
|
|
case ( interrupt_d1 )
|
case ( interrupt_d1 )
|
3'd1: $fwrite(decompile_file,"%08h\n", pcf(get_reg_val(5'd16)));
|
3'd1: $fwrite(decompile_file,"%08h\n", pcf(get_reg_val(5'd16)));
|
Line 422... |
Line 422... |
i_pc_wen &&
|
i_pc_wen &&
|
!i_fetch_stall &&
|
!i_fetch_stall &&
|
i_instruction_execute &&
|
i_instruction_execute &&
|
i_interrupt == 3'd0 &&
|
i_interrupt == 3'd0 &&
|
!execute_undefined &&
|
!execute_undefined &&
|
type != SWI &&
|
itype != SWI &&
|
execute_address != get_32bit_signal(0) // Don't print jump to same address
|
execute_address != get_32bit_signal(0) // Don't print jump to same address
|
)
|
)
|
begin
|
begin
|
$fwrite(decompile_file,"%09d jump from ", `U_TB.clk_count);
|
$fwrite(decompile_file,"%09d jump from ", `U_TB.clk_count);
|
fwrite_hex_drop_zeros(decompile_file, pcf(execute_address));
|
fwrite_hex_drop_zeros(decompile_file, pcf(execute_address));
|
Line 508... |
Line 508... |
endtask
|
endtask
|
|
|
// ldm and stm types
|
// ldm and stm types
|
task w_mtrans_type;
|
task w_mtrans_type;
|
begin
|
begin
|
case( mtrans_type )
|
case( mtrans_itype )
|
4'h0: $fwrite(decompile_file,"da");
|
4'h0: $fwrite(decompile_file,"da");
|
4'h1: $fwrite(decompile_file,"ia");
|
4'h1: $fwrite(decompile_file,"ia");
|
4'h2: $fwrite(decompile_file,"db");
|
4'h2: $fwrite(decompile_file,"db");
|
4'h3: $fwrite(decompile_file,"ib");
|
4'h3: $fwrite(decompile_file,"ib");
|
default: $fwrite(decompile_file,"xx");
|
default: $fwrite(decompile_file,"xx");
|