URL
https://opencores.org/ocsvn/amber/amber/trunk
Subversion Repositories amber
Compare Revisions
- This comparison shows the changes necessary to convert path
/amber/trunk/hw/vlog
- from Rev 86 to Rev 87
- ↔ Reverse comparison
Rev 86 → Rev 87
/amber23/a23_decode.v
173,7 → 173,7
// the instruction |
wire [7:0] instruction_iabt_status; // abort status, follows the instruction |
wire [1:0] instruction_sel; |
reg [3:0] type; |
reg [3:0] itype; |
wire [3:0] opcode; |
wire [7:0] imm8; |
wire [31:0] offset12; |
366,16 → 366,16
// Instruction Decode - Order is important! |
always @* |
casez ({instruction[27:20], instruction[7:4]}) |
12'b00010?001001 : type = SWAP; |
12'b000000??1001 : type = MULT; |
12'b00?????????? : type = REGOP; |
12'b01?????????? : type = TRANS; |
12'b100????????? : type = MTRANS; |
12'b101????????? : type = BRANCH; |
12'b110????????? : type = CODTRANS; |
12'b1110???????0 : type = COREGOP; |
12'b1110???????1 : type = CORTRANS; |
default: type = SWI; |
12'b00010?001001 : itype = SWAP; |
12'b000000??1001 : itype = MULT; |
12'b00?????????? : itype = REGOP; |
12'b01?????????? : itype = TRANS; |
12'b100????????? : itype = MTRANS; |
12'b101????????? : itype = BRANCH; |
12'b110????????? : itype = CODTRANS; |
12'b1110???????0 : itype = COREGOP; |
12'b1110???????1 : itype = CORTRANS; |
default: itype = SWI; |
endcase |
|
|
388,28 → 388,32
|
assign o_rm_sel_nxt = instruction[3:0]; |
|
assign o_rn_sel_nxt = branch ? 4'd15 : // Use PC to calculate branch destination |
instruction[19:16] ; |
assign o_rn_sel_nxt = branch ? 4'd15 : // Use PC to calculate branch destination |
instruction[19:16] ; |
|
assign o_rds_sel_nxt = control_state == SWAP_WRITE ? instruction[3:0] : // Rm gets written out to memory |
type == MTRANS ? mtrans_reg : |
branch ? 4'd15 : // Update the PC |
rds_use_rs ? instruction[11:8] : |
instruction[15:12] ; |
itype == MTRANS ? mtrans_reg : |
branch ? 4'd15 : // Update the PC |
rds_use_rs ? instruction[11:8] : |
instruction[15:12] ; |
|
|
assign shift_imm = instruction[11:7]; |
|
// this is used for RRX |
assign shift_extend = !instruction[25] && !instruction[4] && !(|instruction[11:7]) && instruction[6:5] == 2'b11; |
|
assign offset12 = { 20'h0, instruction[11:0]}; |
assign offset24 = {{6{instruction[23]}}, instruction[23:0], 2'd0 }; // sign extend |
assign imm8 = instruction[7:0]; |
|
assign immediate_shifter_operand = instruction[25]; |
assign rds_use_rs = (type == REGOP && !instruction[25] && instruction[4]) || |
(type == MULT && |
assign rds_use_rs = (itype == REGOP && !instruction[25] && instruction[4]) || |
(itype == MULT && |
(control_state == MULT_PROC1 || |
control_state == MULT_PROC2 || |
instruction_valid && !interrupt )) ; |
assign branch = type == BRANCH; |
assign branch = itype == BRANCH; |
assign opcode_compare = |
opcode == CMP || |
opcode == CMN || |
417,22 → 421,22
opcode == TST ; |
|
|
assign mem_op = type == TRANS; |
assign mem_op = itype == TRANS; |
assign load_op = mem_op && instruction[20]; |
assign store_op = mem_op && !instruction[20]; |
assign write_pc = pc_wen_nxt && pc_sel_nxt != 2'd0; |
assign regop_set_flags = type == REGOP && instruction[20]; |
assign regop_set_flags = itype == REGOP && instruction[20]; |
|
assign mem_op_pre_indexed = instruction[24] && instruction[21]; |
assign mem_op_post_indexed = !instruction[24]; |
|
assign imm32_nxt = // add 0 to Rm |
type == MULT ? { 32'd0 } : |
itype == MULT ? { 32'd0 } : |
|
// 4 x number of registers |
type == MTRANS ? { mtrans_base_reg_change } : |
type == BRANCH ? { offset24 } : |
type == TRANS ? { offset12 } : |
itype == MTRANS ? { mtrans_base_reg_change } : |
itype == BRANCH ? { offset24 } : |
itype == TRANS ? { offset12 } : |
instruction[11:8] == 4'h0 ? { 24'h0, imm8[7:0] } : |
instruction[11:8] == 4'h1 ? { imm8[1:0], 24'h0, imm8[7:2] } : |
instruction[11:8] == 4'h2 ? { imm8[3:0], 24'h0, imm8[7:4] } : |
492,6 → 496,7
default : mtrans_reg = 4'hf ; |
endcase |
|
|
always @* |
casez (instruction[15:0]) |
16'b???????????????1 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 1], 1'd0}; |
540,15 → 545,15
|
assign firq_request = firq && !i_execute_status_bits[26]; |
assign irq_request = irq && !i_execute_status_bits[27]; |
assign swi_request = type == SWI; |
assign swi_request = itype == SWI; |
assign dabt_request = dabt_reg; |
|
// copro15 and copro13 only supports reg trans opcodes |
// all other opcodes involving co-processors cause an |
// undefined instrution interrupt |
assign und_request = type == CODTRANS || |
type == COREGOP || |
( type == CORTRANS && instruction[11:8] != 4'd15 ); |
assign und_request = itype == CODTRANS || |
itype == COREGOP || |
( itype == CORTRANS && instruction[11:8] != 4'd15 ); |
|
|
// in order of priority !! |
644,7 → 649,7
|
if ( instruction_valid && !interrupt ) |
begin |
if ( type == REGOP ) |
if ( itype == REGOP ) |
begin |
if ( !opcode_compare ) |
begin |
678,6 → 683,7
if ( opcode == ADD || opcode == CMN ) // CMN is just like an ADD |
begin |
alu_out_sel_nxt = 4'd1; // Add |
use_carry_in_nxt = shift_extend; |
end |
|
if ( opcode == ADC ) // Add with Carry |
684,7 → 690,7
begin |
alu_out_sel_nxt = 4'd1; // Add |
alu_cin_sel_nxt = 2'd2; // carry in from status_bits |
use_carry_in_nxt = 1'd1; |
use_carry_in_nxt = shift_extend; |
end |
|
if ( opcode == SUB || opcode == CMP ) // Subtract |
731,14 → 737,16
|
if ( opcode == EOR || opcode == TEQ ) // Logical Exclusive OR, Test Equivalence (using EOR operator) |
begin |
alu_out_sel_nxt = 4'd6; // XOR |
alu_out_sel_nxt = 4'd6; // XOR |
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry |
use_carry_in_nxt = 1'd1; |
end |
|
if ( opcode == ORR ) |
begin |
alu_out_sel_nxt = 4'd7; // OR |
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry |
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry |
use_carry_in_nxt = 1'd1; |
end |
|
if ( opcode == BIC ) // Bit Clear (using AND & NOT operators) |
746,17 → 754,20
alu_out_sel_nxt = 4'd8; // AND |
alu_not_sel_nxt = 1'd1; // invert B |
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry |
use_carry_in_nxt = 1'd1; |
end |
|
if ( opcode == MOV ) // Move |
begin |
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry |
use_carry_in_nxt = 1'd1; |
end |
|
if ( opcode == MVN ) // Move NOT |
begin |
alu_not_sel_nxt = 1'd1; // invert B |
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry |
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry |
use_carry_in_nxt = 1'd1; |
end |
end |
|
778,7 → 789,7
if ( store_op ) |
begin |
write_data_wen_nxt = 1'd1; |
if ( type == TRANS && instruction[22] ) |
if ( itype == TRANS && instruction[22] ) |
byte_enable_sel_nxt = 2'd1; // Save byte |
end |
|
799,10 → 810,10
else |
address_sel_nxt = 4'd1; // alu out |
|
if ( instruction[25] && type == TRANS ) |
if ( instruction[25] && itype == TRANS ) |
barrel_shift_data_sel_nxt = 2'd2; // Shift value from Rm register |
|
if ( type == TRANS && instruction[25] && shift_imm != 5'd0 ) |
if ( itype == TRANS && instruction[25] && shift_imm != 5'd0 ) |
begin |
barrel_shift_function_nxt = instruction[6:5]; |
barrel_shift_amount_sel_nxt = 2'd2; // imm_shift_amount |
809,7 → 820,7
end |
end |
|
if ( type == BRANCH ) |
if ( itype == BRANCH ) |
begin |
pc_sel_nxt = 2'd1; // alu_out |
address_sel_nxt = 4'd1; // alu_out |
822,7 → 833,7
end |
end |
|
if ( type == MTRANS ) |
if ( itype == MTRANS ) |
begin |
saved_current_instruction_wen = 1'd1; // Save the memory access instruction to refer back to later |
pc_wen_nxt = 1'd0; // hold current PC value |
864,11 → 875,13
|
// LDM: load into user mode registers, when in priviledged mode |
// Don't use mtrans_r15 here because its not loaded yet |
if ( {instruction[22],instruction[20],instruction[15]} == 3'b110 ) |
//if ( {instruction[22],instruction[20],instruction[15]} == 3'b110 ) |
if ( {instruction[22:20],instruction[15]} == 4'b1010 ) |
user_mode_regs_load_nxt = 1'd1; |
|
|
// SDM: store the user mode registers, when in priviledged mode |
if ( {instruction[22],instruction[20]} == 3'b10 ) |
//if ( {instruction[22],instruction[20]} == 3'b10 ) |
if ( {instruction[22:20]} == 3'b100 ) |
o_user_mode_regs_store_nxt = 1'd1; |
|
// update the base register ? |
877,7 → 890,7
end |
|
|
if ( type == MULT ) |
if ( itype == MULT ) |
begin |
multiply_function_nxt[0] = 1'd1; // set enable |
// some bits can be changed just below |
891,7 → 904,7
|
|
// swp - do read part first |
if ( type == SWAP ) |
if ( itype == SWAP ) |
begin |
saved_current_instruction_wen = 1'd1; // Save the memory access instruction to refer back to later |
pc_wen_nxt = 1'd0; // hold current PC value |
904,7 → 917,7
|
|
// mcr & mrc - takes two cycles |
if ( type == CORTRANS && !und_request ) |
if ( itype == CORTRANS && !und_request ) |
begin |
saved_current_instruction_wen = 1'd1; // Save the memory access instruction to refer back to later |
pc_wen_nxt = 1'd0; // hold current PC value |
922,7 → 935,7
end |
|
|
if ( type == SWI || und_request ) |
if ( itype == SWI || und_request ) |
begin |
// save address of next instruction to Supervisor Mode LR |
reg_write_sel_nxt = 3'd1; // pc -4 |
1030,7 → 1043,7
barrel_shift_function_nxt = ROR; |
|
// load a byte |
if ( type == TRANS && instruction[22] ) |
if ( itype == TRANS && instruction[22] ) |
alu_out_sel_nxt = 4'd3; // zero_extend8 |
|
if ( !dabt ) // dont load data there is an abort on the data read |
1065,11 → 1078,13
write_data_wen_nxt = 1'd1; |
|
// LDM: load into user mode registers, when in priviledged mode |
if ( {instruction[22],instruction[20],mtrans_r15} == 3'b110 ) |
//if ( {instruction[22],instruction[20],mtrans_r15} == 3'b110 ) |
if ( {instruction[22:20],mtrans_r15} == 4'b1010 ) |
user_mode_regs_load_nxt = 1'd1; |
|
// SDM: store the user mode registers, when in priviledged mode |
if ( {instruction[22],instruction[20]} == 2'b10 ) |
//if ( {instruction[22],instruction[20]} == 2'b10 ) |
if ( {instruction[22:20]} == 3'b100 ) |
o_user_mode_regs_store_nxt = 1'd1; |
end |
end |
1245,7 → 1260,7
reg_write_sel_nxt = 3'd2; // multiply_out |
multiply_function_nxt = o_multiply_function; |
|
if ( type == MULT ) // 32-bit |
if ( itype == MULT ) // 32-bit |
reg_bank_wsel_nxt = instruction[19:16]; // Rd |
else // 64-bit / Long |
reg_bank_wsel_nxt = instruction[15:12]; // RdLo |
1484,7 → 1499,7
control_state_nxt = MEM_WAIT1; |
if ( write_pc ) |
control_state_nxt = PC_STALL1; |
if ( type == MTRANS ) |
if ( itype == MTRANS ) |
begin |
if ( mtrans_num_registers != 5'd0 ) |
begin |
1498,13 → 1513,13
control_state_nxt = MTRANS_EXEC3; |
end |
|
if ( type == MULT ) |
if ( itype == MULT ) |
control_state_nxt = MULT_PROC1; |
|
if ( type == SWAP ) |
if ( itype == SWAP ) |
control_state_nxt = SWAP_WRITE; |
|
if ( type == CORTRANS && !und_request ) |
if ( itype == CORTRANS && !und_request ) |
control_state_nxt = COPRO_WAIT; |
|
// interrupt overrides everything else so its last |
1593,7 → 1608,7
// to the pre-fetch instruction register |
// then when its decoded, a copy is saved to the saved_current_instruction |
// register |
if (type == MTRANS) |
if (itype == MTRANS) |
begin |
saved_current_instruction <= mtrans_instruction_nxt; |
saved_current_instruction_iabt <= instruction_iabt; |
/amber23/a23_decompile.v
74,12 → 74,12
wire [4:0] shift_imm; |
wire [3:0] opcode; |
wire [3:0] condition; |
wire [3:0] type; |
wire [3:0] itype; |
wire opcode_compare; |
wire opcode_move; |
wire no_shift; |
wire shift_op_imm; |
wire [1:0] mtrans_type; |
wire [1:0] mtrans_itype; |
wire s_bit; |
|
reg [(5*8)-1:0] xINSTRUCTION_EXECUTE; |
138,7 → 138,7
assign imm8 = execute_instruction[7:0]; |
|
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 = |
151,7 → 151,7
opcode == MOV || |
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] } : |
execute_instruction[11:8] == 4'h1 ? { imm8[1:0], 24'h0, imm8[7:2] } : |
175,7 → 175,7
// Instruction decode |
// ======================================================== |
// 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:22], execute_instruction[7:4] } == { 6'b000000, 4'b1001 } ? MULT : // Before REGOP |
{execute_instruction[27:26] } == { 2'b00 } ? REGOP : |
192,16 → 192,16
// Convert some important signals to ASCII |
// so their values can easily be displayed on a waveform viewer |
// |
assign TYPE_NAME = type == REGOP ? "REGOP " : |
type == MULT ? "MULT " : |
type == SWAP ? "SWAP " : |
type == TRANS ? "TRANS " : |
type == MTRANS ? "MTRANS " : |
type == BRANCH ? "BRANCH " : |
type == CODTRANS ? "CODTRANS" : |
type == COREGOP ? "COREGOP " : |
type == CORTRANS ? "CORTRANS" : |
type == SWI ? "SWI " : |
assign TYPE_NAME = itype == REGOP ? "REGOP " : |
itype == MULT ? "MULT " : |
itype == SWAP ? "SWAP " : |
itype == TRANS ? "TRANS " : |
itype == MTRANS ? "MTRANS " : |
itype == BRANCH ? "BRANCH " : |
itype == CODTRANS ? "CODTRANS" : |
itype == COREGOP ? "COREGOP " : |
itype == CORTRANS ? "CORTRANS" : |
itype == SWI ? "SWI " : |
"UNKNOWN " ; |
|
|
213,40 → 213,40
xINSTRUCTION_EXECUTE = xINSTRUCTION_EXECUTE_R; |
end // stalled |
|
else if ( type == REGOP && opcode == ADC ) xINSTRUCTION_EXECUTE = "adc "; |
else if ( type == REGOP && opcode == ADD ) xINSTRUCTION_EXECUTE = "add "; |
else if ( type == REGOP && opcode == AND ) xINSTRUCTION_EXECUTE = "and "; |
else if ( type == BRANCH && execute_instruction[24] == 1'b0 ) xINSTRUCTION_EXECUTE = "b "; |
else if ( type == REGOP && opcode == BIC ) xINSTRUCTION_EXECUTE = "bic "; |
else if ( type == BRANCH && execute_instruction[24] == 1'b1 ) xINSTRUCTION_EXECUTE = "bl "; |
else if ( type == COREGOP ) xINSTRUCTION_EXECUTE = "cdp "; |
else if ( type == REGOP && opcode == CMN ) xINSTRUCTION_EXECUTE = "cmn "; |
else if ( type == REGOP && opcode == CMP ) xINSTRUCTION_EXECUTE = "cmp "; |
else if ( type == REGOP && opcode == EOR ) xINSTRUCTION_EXECUTE = "eor "; |
else if ( type == CODTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldc "; |
else if ( type == 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 ( type == 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 ( type == MULT && execute_instruction[21] == 1'b1 ) xINSTRUCTION_EXECUTE = "mla "; |
else if ( type == REGOP && opcode == MOV ) xINSTRUCTION_EXECUTE = "mov "; |
else if ( type == CORTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "mrc "; |
else if ( type == MULT && execute_instruction[21] == 1'b0 ) xINSTRUCTION_EXECUTE = "mul "; |
else if ( type == REGOP && opcode == MVN ) xINSTRUCTION_EXECUTE = "mvn "; |
else if ( type == REGOP && opcode == ORR ) xINSTRUCTION_EXECUTE = "orr "; |
else if ( type == REGOP && opcode == RSB ) xINSTRUCTION_EXECUTE = "rsb "; |
else if ( type == REGOP && opcode == RSC ) xINSTRUCTION_EXECUTE = "rsc "; |
else if ( type == REGOP && opcode == SBC ) xINSTRUCTION_EXECUTE = "sbc "; |
else if ( type == CODTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stc "; |
else if ( type == 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 ( type == 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 ( type == SWI ) xINSTRUCTION_EXECUTE = "swi "; |
else if ( type == SWAP && execute_instruction[22] == 1'b0 ) xINSTRUCTION_EXECUTE = "swp "; |
else if ( type == SWAP && execute_instruction[22] == 1'b1 ) xINSTRUCTION_EXECUTE = "swpb "; |
else if ( type == REGOP && opcode == TEQ ) xINSTRUCTION_EXECUTE = "teq "; |
else if ( type == REGOP && opcode == TST ) xINSTRUCTION_EXECUTE = "tst "; |
else if ( itype == REGOP && opcode == ADC ) xINSTRUCTION_EXECUTE = "adc "; |
else if ( itype == REGOP && opcode == ADD ) xINSTRUCTION_EXECUTE = "add "; |
else if ( itype == REGOP && opcode == AND ) xINSTRUCTION_EXECUTE = "and "; |
else if ( itype == BRANCH && execute_instruction[24] == 1'b0 ) xINSTRUCTION_EXECUTE = "b "; |
else if ( itype == REGOP && opcode == BIC ) xINSTRUCTION_EXECUTE = "bic "; |
else if ( itype == BRANCH && execute_instruction[24] == 1'b1 ) xINSTRUCTION_EXECUTE = "bl "; |
else if ( itype == COREGOP ) xINSTRUCTION_EXECUTE = "cdp "; |
else if ( itype == REGOP && opcode == CMN ) xINSTRUCTION_EXECUTE = "cmn "; |
else if ( itype == REGOP && opcode == CMP ) xINSTRUCTION_EXECUTE = "cmp "; |
else if ( itype == REGOP && opcode == EOR ) xINSTRUCTION_EXECUTE = "eor "; |
else if ( itype == CODTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldc "; |
else if ( itype == MTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldm "; |
else if ( itype == 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'b1, 1'b1} ) xINSTRUCTION_EXECUTE = "ldrb "; |
else if ( itype == CORTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "mcr "; |
else if ( itype == MULT && execute_instruction[21] == 1'b1 ) xINSTRUCTION_EXECUTE = "mla "; |
else if ( itype == REGOP && opcode == MOV ) xINSTRUCTION_EXECUTE = "mov "; |
else if ( itype == CORTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "mrc "; |
else if ( itype == MULT && execute_instruction[21] == 1'b0 ) xINSTRUCTION_EXECUTE = "mul "; |
else if ( itype == REGOP && opcode == MVN ) xINSTRUCTION_EXECUTE = "mvn "; |
else if ( itype == REGOP && opcode == ORR ) xINSTRUCTION_EXECUTE = "orr "; |
else if ( itype == REGOP && opcode == RSB ) xINSTRUCTION_EXECUTE = "rsb "; |
else if ( itype == REGOP && opcode == RSC ) xINSTRUCTION_EXECUTE = "rsc "; |
else if ( itype == REGOP && opcode == SBC ) xINSTRUCTION_EXECUTE = "sbc "; |
else if ( itype == CODTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stc "; |
else if ( itype == MTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stm "; |
else if ( itype == 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'b1, 1'b0} ) xINSTRUCTION_EXECUTE = "strb "; |
else if ( itype == REGOP && opcode == SUB ) xINSTRUCTION_EXECUTE = "sub "; |
else if ( itype == SWI ) xINSTRUCTION_EXECUTE = "swi "; |
else if ( itype == SWAP && execute_instruction[22] == 1'b0 ) xINSTRUCTION_EXECUTE = "swp "; |
else if ( itype == SWAP && execute_instruction[22] == 1'b1 ) xINSTRUCTION_EXECUTE = "swpb "; |
else if ( itype == REGOP && opcode == TEQ ) xINSTRUCTION_EXECUTE = "teq "; |
else if ( itype == REGOP && opcode == TST ) xINSTRUCTION_EXECUTE = "tst "; |
else xINSTRUCTION_EXECUTE = "unkow"; |
end |
|
277,7 → 277,7
if (!i_instruction_execute) |
begin |
$fwrite(decompile_file,"-"); |
if ( type == SWI ) |
if ( itype == SWI ) |
$display ("Cycle %09d SWI not taken *************", `U_TB.clk_count); |
end |
else |
296,8 → 296,8
|
fchars = 8 - numchars(xINSTRUCTION_EXECUTE); |
|
// Print the Multiple transfer type |
if (type == MTRANS ) |
// Print the Multiple transfer itype |
if (itype == MTRANS ) |
begin |
w_mtrans_type; |
fchars = fchars - 2; |
304,7 → 304,7
end |
|
// 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 |
$fwrite(decompile_file,"s"); |
fchars = fchars - 1; |
311,7 → 311,7
end |
|
// 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 |
$fwrite(decompile_file,"p"); |
fchars = fchars - 1; |
341,7 → 341,7
// ======================================== |
// print the arguments for the instruction |
// ======================================== |
case ( type ) |
case ( itype ) |
REGOP: regop_args; |
TRANS: trans_args; |
MTRANS: mtrans_args; |
373,7 → 373,7
end |
|
// Software Interrupt |
if ( i_instruction_execute && type == SWI ) |
if ( i_instruction_execute && itype == SWI ) |
begin |
$fwrite( decompile_file,"%09d interrupt swi", `U_TB.clk_count ); |
$fwrite( decompile_file,", return addr " ); |
397,7 → 397,7
3'd3: $fwrite( decompile_file,"irq" ); |
3'd4: $fwrite( decompile_file,"address exception" ); |
3'd5: $fwrite( decompile_file,"instruction abort" ); |
default: $fwrite( decompile_file,"unknown type" ); |
default: $fwrite( decompile_file,"unknown itype" ); |
endcase |
$fwrite( decompile_file,", return addr " ); |
|
424,7 → 424,7
i_instruction_execute && |
i_interrupt == 3'd0 && |
!execute_undefined && |
type != SWI && |
itype != SWI && |
execute_address != get_32bit_signal(0) // Don't print jump to same address |
) |
begin |
510,7 → 510,7
// ldm and stm types |
task w_mtrans_type; |
begin |
case( mtrans_type ) |
case( mtrans_itype ) |
4'h0: $fwrite(decompile_file,"da"); |
4'h1: $fwrite(decompile_file,"ia"); |
4'h2: $fwrite(decompile_file,"db"); |
/amber23/a23_execute.v
494,6 → 494,11
); |
|
|
wire barrel_shift_carry_real; |
assign barrel_shift_carry_real = i_barrel_shift_data_sel == 2'd0 ? |
(i_imm_shift_amount[4:1] == 0 ? status_bits_flags[1] : i_imm32[31]) : |
barrel_shift_carry; |
|
// ======================================================== |
// Instantiate ALU |
// ======================================================== |
500,7 → 505,8
a23_alu u_alu ( |
.i_a_in ( rn ), |
.i_b_in ( barrel_shift_out ), |
.i_barrel_shift_carry ( barrel_shift_carry ), |
//.i_barrel_shift_carry ( barrel_shift_carry ), |
.i_barrel_shift_carry ( barrel_shift_carry_real ), |
.i_status_bits_carry ( status_bits_flags[1] ), |
.i_function ( i_alu_function ), |
|
/amber25/a25_decompile.v
73,12 → 73,12
wire [4:0] shift_imm; |
wire [3:0] opcode; |
wire [3:0] condition; |
wire [3:0] type; |
wire [3:0] itype; |
wire opcode_compare; |
wire opcode_move; |
wire no_shift; |
wire shift_op_imm; |
wire [1:0] mtrans_type; |
wire [1:0] mtrans_itype; |
wire s_bit; |
|
reg [(5*8)-1:0] xINSTRUCTION_EXECUTE; |
124,22 → 124,20
// ======================================================== |
// Fields within the instruction |
// ======================================================== |
assign opcode = execute_instruction[24:21]; |
assign condition = execute_instruction[31:28]; |
assign s_bit = execute_instruction[20]; |
assign reg_n = execute_instruction[19:16]; |
assign reg_d = execute_instruction[15:12]; |
assign reg_m = execute_instruction[3:0]; |
assign reg_s = execute_instruction[11:8]; |
assign shift_imm = execute_instruction[11:7]; |
assign offset12 = execute_instruction[11:0]; |
assign offset8 = {execute_instruction[11:8], execute_instruction[3:0]}; |
assign imm8 = execute_instruction[7:0]; |
assign opcode = execute_instruction[24:21]; |
assign condition = execute_instruction[31:28]; |
assign s_bit = execute_instruction[20]; |
assign reg_n = execute_instruction[19:16]; |
assign reg_d = execute_instruction[15:12]; |
assign reg_m = execute_instruction[3:0]; |
assign reg_s = execute_instruction[11:8]; |
assign shift_imm = execute_instruction[11:7]; |
assign offset12 = execute_instruction[11:0]; |
assign offset8 = {execute_instruction[11:8], execute_instruction[3:0]}; |
assign imm8 = execute_instruction[7:0]; |
assign no_shift = execute_instruction[11:4] == 8'h0; |
assign mtrans_itype = execute_instruction[24:23]; |
|
assign no_shift = execute_instruction[11:4] == 8'h0; |
assign mtrans_type = execute_instruction[24:23]; |
|
|
assign opcode_compare = |
opcode == CMP || |
opcode == CMN || |
150,7 → 148,7
opcode == MOV || |
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] } : |
execute_instruction[11:8] == 4'h1 ? { imm8[1:0], 24'h0, imm8[7:2] } : |
174,7 → 172,7
// Instruction decode |
// ======================================================== |
// 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:22], execute_instruction[7:4] } == { 6'b000000, 4'b1001 } ? MULT : // Before REGOP |
{execute_instruction[27:26] } == { 2'b00 } ? REGOP : |
191,16 → 189,16
// Convert some important signals to ASCII |
// so their values can easily be displayed on a waveform viewer |
// |
assign TYPE_NAME = type == REGOP ? "REGOP " : |
type == MULT ? "MULT " : |
type == SWAP ? "SWAP " : |
type == TRANS ? "TRANS " : |
type == MTRANS ? "MTRANS " : |
type == BRANCH ? "BRANCH " : |
type == CODTRANS ? "CODTRANS" : |
type == COREGOP ? "COREGOP " : |
type == CORTRANS ? "CORTRANS" : |
type == SWI ? "SWI " : |
assign TYPE_NAME = itype == REGOP ? "REGOP " : |
itype == MULT ? "MULT " : |
itype == SWAP ? "SWAP " : |
itype == TRANS ? "TRANS " : |
itype == MTRANS ? "MTRANS " : |
itype == BRANCH ? "BRANCH " : |
itype == CODTRANS ? "CODTRANS" : |
itype == COREGOP ? "COREGOP " : |
itype == CORTRANS ? "CORTRANS" : |
itype == SWI ? "SWI " : |
"UNKNOWN " ; |
|
|
212,41 → 210,41
xINSTRUCTION_EXECUTE = xINSTRUCTION_EXECUTE_R; |
end // stalled |
|
else if ( type == REGOP && opcode == ADC ) xINSTRUCTION_EXECUTE = "adc "; |
else if ( type == REGOP && opcode == ADD ) xINSTRUCTION_EXECUTE = "add "; |
else if ( type == REGOP && opcode == AND ) xINSTRUCTION_EXECUTE = "and "; |
else if ( type == BRANCH && execute_instruction[24] == 1'b0 ) xINSTRUCTION_EXECUTE = "b "; |
else if ( type == REGOP && opcode == BIC ) xINSTRUCTION_EXECUTE = "bic "; |
else if ( type == BRANCH && execute_instruction[24] == 1'b1 ) xINSTRUCTION_EXECUTE = "bl "; |
else if ( type == COREGOP ) xINSTRUCTION_EXECUTE = "cdp "; |
else if ( type == REGOP && opcode == CMN ) xINSTRUCTION_EXECUTE = "cmn "; |
else if ( type == REGOP && opcode == CMP ) xINSTRUCTION_EXECUTE = "cmp "; |
else if ( type == REGOP && opcode == EOR ) xINSTRUCTION_EXECUTE = "eor "; |
else if ( type == CODTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldc "; |
else if ( type == 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 ( type == 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 ( type == MULT && execute_instruction[21] == 1'b1 ) xINSTRUCTION_EXECUTE = "mla "; |
else if ( type == REGOP && opcode == MOV ) xINSTRUCTION_EXECUTE = "mov "; |
else if ( type == CORTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "mrc "; |
else if ( type == MULT && execute_instruction[21] == 1'b0 ) xINSTRUCTION_EXECUTE = "mul "; |
else if ( type == REGOP && opcode == MVN ) xINSTRUCTION_EXECUTE = "mvn "; |
else if ( type == REGOP && opcode == ORR ) xINSTRUCTION_EXECUTE = "orr "; |
else if ( type == REGOP && opcode == RSB ) xINSTRUCTION_EXECUTE = "rsb "; |
else if ( type == REGOP && opcode == RSC ) xINSTRUCTION_EXECUTE = "rsc "; |
else if ( type == REGOP && opcode == SBC ) xINSTRUCTION_EXECUTE = "sbc "; |
else if ( type == CODTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stc "; |
else if ( type == 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 ( type == 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 ( type == SWI ) xINSTRUCTION_EXECUTE = "swi "; |
else if ( type == SWAP && execute_instruction[22] == 1'b0 ) xINSTRUCTION_EXECUTE = "swp "; |
else if ( type == SWAP && execute_instruction[22] == 1'b1 ) xINSTRUCTION_EXECUTE = "swpb "; |
else if ( type == REGOP && opcode == TEQ ) xINSTRUCTION_EXECUTE = "teq "; |
else if ( type == REGOP && opcode == TST ) xINSTRUCTION_EXECUTE = "tst "; |
else xINSTRUCTION_EXECUTE = "unkow"; |
else if ( itype == REGOP && opcode == ADC ) xINSTRUCTION_EXECUTE = "adc "; |
else if ( itype == REGOP && opcode == ADD ) xINSTRUCTION_EXECUTE = "add "; |
else if ( itype == REGOP && opcode == AND ) xINSTRUCTION_EXECUTE = "and "; |
else if ( itype == BRANCH && execute_instruction[24] == 1'b0 ) xINSTRUCTION_EXECUTE = "b "; |
else if ( itype == REGOP && opcode == BIC ) xINSTRUCTION_EXECUTE = "bic "; |
else if ( itype == BRANCH && execute_instruction[24] == 1'b1 ) xINSTRUCTION_EXECUTE = "bl "; |
else if ( itype == COREGOP ) xINSTRUCTION_EXECUTE = "cdp "; |
else if ( itype == REGOP && opcode == CMN ) xINSTRUCTION_EXECUTE = "cmn "; |
else if ( itype == REGOP && opcode == CMP ) xINSTRUCTION_EXECUTE = "cmp "; |
else if ( itype == REGOP && opcode == EOR ) xINSTRUCTION_EXECUTE = "eor "; |
else if ( itype == CODTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldc "; |
else if ( itype == MTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldm "; |
else if ( itype == 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'b1, 1'b1} ) xINSTRUCTION_EXECUTE = "ldrb "; |
else if ( itype == CORTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "mcr "; |
else if ( itype == MULT && execute_instruction[21] == 1'b1 ) xINSTRUCTION_EXECUTE = "mla "; |
else if ( itype == REGOP && opcode == MOV ) xINSTRUCTION_EXECUTE = "mov "; |
else if ( itype == CORTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "mrc "; |
else if ( itype == MULT && execute_instruction[21] == 1'b0 ) xINSTRUCTION_EXECUTE = "mul "; |
else if ( itype == REGOP && opcode == MVN ) xINSTRUCTION_EXECUTE = "mvn "; |
else if ( itype == REGOP && opcode == ORR ) xINSTRUCTION_EXECUTE = "orr "; |
else if ( itype == REGOP && opcode == RSB ) xINSTRUCTION_EXECUTE = "rsb "; |
else if ( itype == REGOP && opcode == RSC ) xINSTRUCTION_EXECUTE = "rsc "; |
else if ( itype == REGOP && opcode == SBC ) xINSTRUCTION_EXECUTE = "sbc "; |
else if ( itype == CODTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stc "; |
else if ( itype == MTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stm "; |
else if ( itype == 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'b1, 1'b0} ) xINSTRUCTION_EXECUTE = "strb "; |
else if ( itype == REGOP && opcode == SUB ) xINSTRUCTION_EXECUTE = "sub "; |
else if ( itype == SWI ) xINSTRUCTION_EXECUTE = "swi "; |
else if ( itype == SWAP && execute_instruction[22] == 1'b0 ) xINSTRUCTION_EXECUTE = "swp "; |
else if ( itype == SWAP && execute_instruction[22] == 1'b1 ) xINSTRUCTION_EXECUTE = "swpb "; |
else if ( itype == REGOP && opcode == TEQ ) xINSTRUCTION_EXECUTE = "teq "; |
else if ( itype == REGOP && opcode == TST ) xINSTRUCTION_EXECUTE = "tst "; |
else xINSTRUCTION_EXECUTE = "unkow"; |
end |
|
always @ ( posedge i_clk ) |
313,7 → 311,7
if (!i_instruction_execute) |
begin |
$fwrite(decompile_file,"-"); |
if ( type == SWI ) |
if ( itype == SWI ) |
$display ("Cycle %09d SWI not taken *************", `U_TB.clk_count); |
end |
else |
332,8 → 330,8
|
fchars = 8 - numchars(xINSTRUCTION_EXECUTE); |
|
// Print the Multiple transfer type |
if (type == MTRANS ) |
// Print the Multiple transfer itype |
if (itype == MTRANS ) |
begin |
w_mtrans_type; |
fchars = fchars - 2; |
340,7 → 338,7
end |
|
// 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 |
$fwrite(decompile_file,"s"); |
fchars = fchars - 1; |
347,7 → 345,7
end |
|
// 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 |
$fwrite(decompile_file,"p"); |
fchars = fchars - 1; |
377,7 → 375,7
// ======================================== |
// print the arguments for the instruction |
// ======================================== |
case ( type ) |
case ( itype ) |
REGOP: regop_args; |
TRANS: trans_args; |
MTRANS: mtrans_args; |
409,7 → 407,7
end |
|
// Software Interrupt |
if ( i_instruction_execute && type == SWI ) |
if ( i_instruction_execute && itype == SWI ) |
begin |
$fwrite( decompile_file,"%09d interrupt swi", `U_TB.clk_count ); |
$fwrite( decompile_file,", return addr " ); |
462,7 → 460,7
i_instruction_execute && |
i_interrupt == 3'd0 && |
!execute_undefined && |
type != SWI && |
itype != SWI && |
execute_address != get_32bit_signal(0) // Don't print jump to same address |
) |
begin |
506,7 → 504,7
// ldm and stm types |
task w_mtrans_type; |
begin |
case( mtrans_type ) |
case( mtrans_itype ) |
4'h0: $fwrite(decompile_file,"da"); |
4'h1: $fwrite(decompile_file,"ia"); |
4'h2: $fwrite(decompile_file,"db"); |