Line 171... |
Line 171... |
wire instruction_adex; // address exception flag, follows the instruction
|
wire instruction_adex; // address exception flag, follows the instruction
|
wire [31:0] instruction_address; // instruction virtual address, follows
|
wire [31:0] instruction_address; // instruction virtual address, follows
|
// the instruction
|
// the instruction
|
wire [7:0] instruction_iabt_status; // abort status, follows the instruction
|
wire [7:0] instruction_iabt_status; // abort status, follows the instruction
|
wire [1:0] instruction_sel;
|
wire [1:0] instruction_sel;
|
reg [3:0] type;
|
reg [3:0] itype;
|
wire [3:0] opcode;
|
wire [3:0] opcode;
|
wire [7:0] imm8;
|
wire [7:0] imm8;
|
wire [31:0] offset12;
|
wire [31:0] offset12;
|
wire [31:0] offset24;
|
wire [31:0] offset24;
|
wire [4:0] shift_imm;
|
wire [4:0] shift_imm;
|
Line 364... |
Line 364... |
pre_fetch_instruction_adex ;
|
pre_fetch_instruction_adex ;
|
|
|
// Instruction Decode - Order is important!
|
// Instruction Decode - Order is important!
|
always @*
|
always @*
|
casez ({instruction[27:20], instruction[7:4]})
|
casez ({instruction[27:20], instruction[7:4]})
|
12'b00010?001001 : type = SWAP;
|
12'b00010?001001 : itype = SWAP;
|
12'b000000??1001 : type = MULT;
|
12'b000000??1001 : itype = MULT;
|
12'b00?????????? : type = REGOP;
|
12'b00?????????? : itype = REGOP;
|
12'b01?????????? : type = TRANS;
|
12'b01?????????? : itype = TRANS;
|
12'b100????????? : type = MTRANS;
|
12'b100????????? : itype = MTRANS;
|
12'b101????????? : type = BRANCH;
|
12'b101????????? : itype = BRANCH;
|
12'b110????????? : type = CODTRANS;
|
12'b110????????? : itype = CODTRANS;
|
12'b1110???????0 : type = COREGOP;
|
12'b1110???????0 : itype = COREGOP;
|
12'b1110???????1 : type = CORTRANS;
|
12'b1110???????1 : itype = CORTRANS;
|
default: type = SWI;
|
default: itype = SWI;
|
endcase
|
endcase
|
|
|
|
|
// ========================================================
|
// ========================================================
|
// Fixed fields within the instruction
|
// Fixed fields within the instruction
|
Line 390... |
Line 390... |
|
|
assign o_rn_sel_nxt = branch ? 4'd15 : // Use PC to calculate branch destination
|
assign o_rn_sel_nxt = branch ? 4'd15 : // Use PC to calculate branch destination
|
instruction[19:16] ;
|
instruction[19:16] ;
|
|
|
assign o_rds_sel_nxt = control_state == SWAP_WRITE ? instruction[3:0] : // Rm gets written out to memory
|
assign o_rds_sel_nxt = control_state == SWAP_WRITE ? instruction[3:0] : // Rm gets written out to memory
|
type == MTRANS ? mtrans_reg :
|
itype == MTRANS ? mtrans_reg :
|
branch ? 4'd15 : // Update the PC
|
branch ? 4'd15 : // Update the PC
|
rds_use_rs ? instruction[11:8] :
|
rds_use_rs ? instruction[11:8] :
|
instruction[15:12] ;
|
instruction[15:12] ;
|
|
|
|
|
assign shift_imm = instruction[11:7];
|
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 offset12 = { 20'h0, instruction[11:0]};
|
assign offset24 = {{6{instruction[23]}}, instruction[23:0], 2'd0 }; // sign extend
|
assign offset24 = {{6{instruction[23]}}, instruction[23:0], 2'd0 }; // sign extend
|
assign imm8 = instruction[7:0];
|
assign imm8 = instruction[7:0];
|
|
|
assign immediate_shifter_operand = instruction[25];
|
assign immediate_shifter_operand = instruction[25];
|
assign rds_use_rs = (type == REGOP && !instruction[25] && instruction[4]) ||
|
assign rds_use_rs = (itype == REGOP && !instruction[25] && instruction[4]) ||
|
(type == MULT &&
|
(itype == MULT &&
|
(control_state == MULT_PROC1 ||
|
(control_state == MULT_PROC1 ||
|
control_state == MULT_PROC2 ||
|
control_state == MULT_PROC2 ||
|
instruction_valid && !interrupt )) ;
|
instruction_valid && !interrupt )) ;
|
assign branch = type == BRANCH;
|
assign branch = itype == BRANCH;
|
assign opcode_compare =
|
assign opcode_compare =
|
opcode == CMP ||
|
opcode == CMP ||
|
opcode == CMN ||
|
opcode == CMN ||
|
opcode == TEQ ||
|
opcode == TEQ ||
|
opcode == TST ;
|
opcode == TST ;
|
|
|
|
|
assign mem_op = type == TRANS;
|
assign mem_op = itype == TRANS;
|
assign load_op = mem_op && instruction[20];
|
assign load_op = mem_op && instruction[20];
|
assign store_op = mem_op && !instruction[20];
|
assign store_op = mem_op && !instruction[20];
|
assign write_pc = pc_wen_nxt && pc_sel_nxt != 2'd0;
|
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_pre_indexed = instruction[24] && instruction[21];
|
assign mem_op_post_indexed = !instruction[24];
|
assign mem_op_post_indexed = !instruction[24];
|
|
|
assign imm32_nxt = // add 0 to Rm
|
assign imm32_nxt = // add 0 to Rm
|
type == MULT ? { 32'd0 } :
|
itype == MULT ? { 32'd0 } :
|
|
|
// 4 x number of registers
|
// 4 x number of registers
|
type == MTRANS ? { mtrans_base_reg_change } :
|
itype == MTRANS ? { mtrans_base_reg_change } :
|
type == BRANCH ? { offset24 } :
|
itype == BRANCH ? { offset24 } :
|
type == TRANS ? { offset12 } :
|
itype == TRANS ? { offset12 } :
|
instruction[11:8] == 4'h0 ? { 24'h0, imm8[7:0] } :
|
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'h1 ? { imm8[1:0], 24'h0, imm8[7:2] } :
|
instruction[11:8] == 4'h2 ? { imm8[3:0], 24'h0, imm8[7:4] } :
|
instruction[11:8] == 4'h2 ? { imm8[3:0], 24'h0, imm8[7:4] } :
|
instruction[11:8] == 4'h3 ? { imm8[5:0], 24'h0, imm8[7:6] } :
|
instruction[11:8] == 4'h3 ? { imm8[5:0], 24'h0, imm8[7:6] } :
|
instruction[11:8] == 4'h4 ? { imm8[7:0], 24'h0 } :
|
instruction[11:8] == 4'h4 ? { imm8[7:0], 24'h0 } :
|
Line 490... |
Line 494... |
16'b??10000000000000 : mtrans_reg = 4'hd ;
|
16'b??10000000000000 : mtrans_reg = 4'hd ;
|
16'b?100000000000000 : mtrans_reg = 4'he ;
|
16'b?100000000000000 : mtrans_reg = 4'he ;
|
default : mtrans_reg = 4'hf ;
|
default : mtrans_reg = 4'hf ;
|
endcase
|
endcase
|
|
|
|
|
always @*
|
always @*
|
casez (instruction[15:0])
|
casez (instruction[15:0])
|
16'b???????????????1 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 1], 1'd0};
|
16'b???????????????1 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 1], 1'd0};
|
16'b??????????????10 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 2], 2'd0};
|
16'b??????????????10 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 2], 2'd0};
|
16'b?????????????100 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 3], 3'd0};
|
16'b?????????????100 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 3], 3'd0};
|
Line 538... |
Line 543... |
// Interrupts
|
// Interrupts
|
// ========================================================
|
// ========================================================
|
|
|
assign firq_request = firq && !i_execute_status_bits[26];
|
assign firq_request = firq && !i_execute_status_bits[26];
|
assign irq_request = irq && !i_execute_status_bits[27];
|
assign irq_request = irq && !i_execute_status_bits[27];
|
assign swi_request = type == SWI;
|
assign swi_request = itype == SWI;
|
assign dabt_request = dabt_reg;
|
assign dabt_request = dabt_reg;
|
|
|
// copro15 and copro13 only supports reg trans opcodes
|
// copro15 and copro13 only supports reg trans opcodes
|
// all other opcodes involving co-processors cause an
|
// all other opcodes involving co-processors cause an
|
// undefined instrution interrupt
|
// undefined instrution interrupt
|
assign und_request = type == CODTRANS ||
|
assign und_request = itype == CODTRANS ||
|
type == COREGOP ||
|
itype == COREGOP ||
|
( type == CORTRANS && instruction[11:8] != 4'd15 );
|
( itype == CORTRANS && instruction[11:8] != 4'd15 );
|
|
|
|
|
// in order of priority !!
|
// in order of priority !!
|
// Highest
|
// Highest
|
// 1 Reset
|
// 1 Reset
|
Line 642... |
Line 647... |
status_bits_irq_mask_wen_nxt = 'd0;
|
status_bits_irq_mask_wen_nxt = 'd0;
|
status_bits_firq_mask_wen_nxt = 'd0;
|
status_bits_firq_mask_wen_nxt = 'd0;
|
|
|
if ( instruction_valid && !interrupt )
|
if ( instruction_valid && !interrupt )
|
begin
|
begin
|
if ( type == REGOP )
|
if ( itype == REGOP )
|
begin
|
begin
|
if ( !opcode_compare )
|
if ( !opcode_compare )
|
begin
|
begin
|
// Check is the load destination is the PC
|
// Check is the load destination is the PC
|
if (instruction[15:12] == 4'd15)
|
if (instruction[15:12] == 4'd15)
|
Line 676... |
Line 681... |
status_bits_sel_nxt = 3'd5;
|
status_bits_sel_nxt = 3'd5;
|
|
|
if ( opcode == ADD || opcode == CMN ) // CMN is just like an ADD
|
if ( opcode == ADD || opcode == CMN ) // CMN is just like an ADD
|
begin
|
begin
|
alu_out_sel_nxt = 4'd1; // Add
|
alu_out_sel_nxt = 4'd1; // Add
|
|
use_carry_in_nxt = shift_extend;
|
end
|
end
|
|
|
if ( opcode == ADC ) // Add with Carry
|
if ( opcode == ADC ) // Add with Carry
|
begin
|
begin
|
alu_out_sel_nxt = 4'd1; // Add
|
alu_out_sel_nxt = 4'd1; // Add
|
alu_cin_sel_nxt = 2'd2; // carry in from status_bits
|
alu_cin_sel_nxt = 2'd2; // carry in from status_bits
|
use_carry_in_nxt = 1'd1;
|
use_carry_in_nxt = shift_extend;
|
end
|
end
|
|
|
if ( opcode == SUB || opcode == CMP ) // Subtract
|
if ( opcode == SUB || opcode == CMP ) // Subtract
|
begin
|
begin
|
alu_out_sel_nxt = 4'd1; // Add
|
alu_out_sel_nxt = 4'd1; // Add
|
Line 731... |
Line 737... |
|
|
if ( opcode == EOR || opcode == TEQ ) // Logical Exclusive OR, Test Equivalence (using EOR operator)
|
if ( opcode == EOR || opcode == TEQ ) // Logical Exclusive OR, Test Equivalence (using EOR operator)
|
begin
|
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
|
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
|
|
use_carry_in_nxt = 1'd1;
|
end
|
end
|
|
|
if ( opcode == ORR )
|
if ( opcode == ORR )
|
begin
|
begin
|
alu_out_sel_nxt = 4'd7; // OR
|
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
|
end
|
|
|
if ( opcode == BIC ) // Bit Clear (using AND & NOT operators)
|
if ( opcode == BIC ) // Bit Clear (using AND & NOT operators)
|
begin
|
begin
|
alu_out_sel_nxt = 4'd8; // AND
|
alu_out_sel_nxt = 4'd8; // AND
|
alu_not_sel_nxt = 1'd1; // invert B
|
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
|
|
|
if ( opcode == MOV ) // Move
|
if ( opcode == MOV ) // Move
|
begin
|
begin
|
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
|
|
|
if ( opcode == MVN ) // Move NOT
|
if ( opcode == MVN ) // Move NOT
|
begin
|
begin
|
alu_not_sel_nxt = 1'd1; // invert B
|
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
|
end
|
end
|
|
|
// Load & Store instructions
|
// Load & Store instructions
|
if ( mem_op )
|
if ( mem_op )
|
Line 776... |
Line 787... |
end
|
end
|
|
|
if ( store_op )
|
if ( store_op )
|
begin
|
begin
|
write_data_wen_nxt = 1'd1;
|
write_data_wen_nxt = 1'd1;
|
if ( type == TRANS && instruction[22] )
|
if ( itype == TRANS && instruction[22] )
|
byte_enable_sel_nxt = 2'd1; // Save byte
|
byte_enable_sel_nxt = 2'd1; // Save byte
|
end
|
end
|
|
|
// need to update the register holding the address ?
|
// need to update the register holding the address ?
|
// This is Rn bits [19:16]
|
// This is Rn bits [19:16]
|
Line 797... |
Line 808... |
if ( mem_op_post_indexed )
|
if ( mem_op_post_indexed )
|
address_sel_nxt = 4'd4; // Rn
|
address_sel_nxt = 4'd4; // Rn
|
else
|
else
|
address_sel_nxt = 4'd1; // alu out
|
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
|
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
|
begin
|
barrel_shift_function_nxt = instruction[6:5];
|
barrel_shift_function_nxt = instruction[6:5];
|
barrel_shift_amount_sel_nxt = 2'd2; // imm_shift_amount
|
barrel_shift_amount_sel_nxt = 2'd2; // imm_shift_amount
|
end
|
end
|
end
|
end
|
|
|
if ( type == BRANCH )
|
if ( itype == BRANCH )
|
begin
|
begin
|
pc_sel_nxt = 2'd1; // alu_out
|
pc_sel_nxt = 2'd1; // alu_out
|
address_sel_nxt = 4'd1; // alu_out
|
address_sel_nxt = 4'd1; // alu_out
|
alu_out_sel_nxt = 4'd1; // Add
|
alu_out_sel_nxt = 4'd1; // Add
|
|
|
Line 820... |
Line 831... |
reg_bank_wsel_nxt = 4'd14; // Save PC to LR
|
reg_bank_wsel_nxt = 4'd14; // Save PC to LR
|
reg_write_sel_nxt = 3'd1; // pc - 32'd4
|
reg_write_sel_nxt = 3'd1; // pc - 32'd4
|
end
|
end
|
end
|
end
|
|
|
if ( type == MTRANS )
|
if ( itype == MTRANS )
|
begin
|
begin
|
saved_current_instruction_wen = 1'd1; // Save the memory access instruction to refer back to later
|
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
|
pc_wen_nxt = 1'd0; // hold current PC value
|
data_access_exec_nxt = 1'd1; // indicate that its a data read or write,
|
data_access_exec_nxt = 1'd1; // indicate that its a data read or write,
|
// rather than an instruction fetch
|
// rather than an instruction fetch
|
Line 862... |
Line 873... |
if ( !instruction[20] ) // Store
|
if ( !instruction[20] ) // Store
|
write_data_wen_nxt = 1'd1;
|
write_data_wen_nxt = 1'd1;
|
|
|
// LDM: load into user mode registers, when in priviledged mode
|
// LDM: load into user mode registers, when in priviledged mode
|
// Don't use mtrans_r15 here because its not loaded yet
|
// 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;
|
user_mode_regs_load_nxt = 1'd1;
|
|
|
// SDM: store the user mode registers, when in priviledged mode
|
// 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;
|
o_user_mode_regs_store_nxt = 1'd1;
|
|
|
// update the base register ?
|
// update the base register ?
|
if ( instruction[21] ) // the W bit
|
if ( instruction[21] ) // the W bit
|
reg_bank_wsel_nxt = o_rn_sel_nxt;
|
reg_bank_wsel_nxt = o_rn_sel_nxt;
|
end
|
end
|
|
|
|
|
if ( type == MULT )
|
if ( itype == MULT )
|
begin
|
begin
|
multiply_function_nxt[0] = 1'd1; // set enable
|
multiply_function_nxt[0] = 1'd1; // set enable
|
// some bits can be changed just below
|
// some bits can be changed just below
|
saved_current_instruction_wen = 1'd1; // Save the Multiply instruction to
|
saved_current_instruction_wen = 1'd1; // Save the Multiply instruction to
|
// refer back to later
|
// refer back to later
|
Line 889... |
Line 902... |
multiply_function_nxt[1] = 1'd1; // accumulate
|
multiply_function_nxt[1] = 1'd1; // accumulate
|
end
|
end
|
|
|
|
|
// swp - do read part first
|
// swp - do read part first
|
if ( type == SWAP )
|
if ( itype == SWAP )
|
begin
|
begin
|
saved_current_instruction_wen = 1'd1; // Save the memory access instruction to refer back to later
|
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
|
pc_wen_nxt = 1'd0; // hold current PC value
|
data_access_exec_nxt = 1'd1; // indicate that its a data read or write,
|
data_access_exec_nxt = 1'd1; // indicate that its a data read or write,
|
// rather than an instruction fetch
|
// rather than an instruction fetch
|
Line 902... |
Line 915... |
exclusive_exec_nxt = 1'd1; // signal an exclusive access
|
exclusive_exec_nxt = 1'd1; // signal an exclusive access
|
end
|
end
|
|
|
|
|
// mcr & mrc - takes two cycles
|
// mcr & mrc - takes two cycles
|
if ( type == CORTRANS && !und_request )
|
if ( itype == CORTRANS && !und_request )
|
begin
|
begin
|
saved_current_instruction_wen = 1'd1; // Save the memory access instruction to refer back to later
|
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
|
pc_wen_nxt = 1'd0; // hold current PC value
|
address_sel_nxt = 4'd3; // pc (not pc + 4)
|
address_sel_nxt = 4'd3; // pc (not pc + 4)
|
|
|
Line 920... |
Line 933... |
copro_write_data_wen_nxt = 1'd1; // Rd register value to co-processor
|
copro_write_data_wen_nxt = 1'd1; // Rd register value to co-processor
|
end
|
end
|
end
|
end
|
|
|
|
|
if ( type == SWI || und_request )
|
if ( itype == SWI || und_request )
|
begin
|
begin
|
// save address of next instruction to Supervisor Mode LR
|
// save address of next instruction to Supervisor Mode LR
|
reg_write_sel_nxt = 3'd1; // pc -4
|
reg_write_sel_nxt = 3'd1; // pc -4
|
reg_bank_wsel_nxt = 4'd14; // LR
|
reg_bank_wsel_nxt = 4'd14; // LR
|
|
|
Line 1028... |
Line 1041... |
// shift needed
|
// shift needed
|
if ( i_execute_address[1:0] != 2'd0 )
|
if ( i_execute_address[1:0] != 2'd0 )
|
barrel_shift_function_nxt = ROR;
|
barrel_shift_function_nxt = ROR;
|
|
|
// load a byte
|
// load a byte
|
if ( type == TRANS && instruction[22] )
|
if ( itype == TRANS && instruction[22] )
|
alu_out_sel_nxt = 4'd3; // zero_extend8
|
alu_out_sel_nxt = 4'd3; // zero_extend8
|
|
|
if ( !dabt ) // dont load data there is an abort on the data read
|
if ( !dabt ) // dont load data there is an abort on the data read
|
begin
|
begin
|
// Check if the load destination is the PC
|
// Check if the load destination is the PC
|
Line 1063... |
Line 1076... |
|
|
if ( !instruction[20] ) // Store
|
if ( !instruction[20] ) // Store
|
write_data_wen_nxt = 1'd1;
|
write_data_wen_nxt = 1'd1;
|
|
|
// LDM: load into user mode registers, when in priviledged mode
|
// 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;
|
user_mode_regs_load_nxt = 1'd1;
|
|
|
// SDM: store the user mode registers, when in priviledged mode
|
// 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;
|
o_user_mode_regs_store_nxt = 1'd1;
|
end
|
end
|
end
|
end
|
|
|
|
|
Line 1243... |
Line 1258... |
if ( control_state == MULT_STORE )
|
if ( control_state == MULT_STORE )
|
begin
|
begin
|
reg_write_sel_nxt = 3'd2; // multiply_out
|
reg_write_sel_nxt = 3'd2; // multiply_out
|
multiply_function_nxt = o_multiply_function;
|
multiply_function_nxt = o_multiply_function;
|
|
|
if ( type == MULT ) // 32-bit
|
if ( itype == MULT ) // 32-bit
|
reg_bank_wsel_nxt = instruction[19:16]; // Rd
|
reg_bank_wsel_nxt = instruction[19:16]; // Rd
|
else // 64-bit / Long
|
else // 64-bit / Long
|
reg_bank_wsel_nxt = instruction[15:12]; // RdLo
|
reg_bank_wsel_nxt = instruction[15:12]; // RdLo
|
|
|
if ( instruction[20] ) // the 'S' bit
|
if ( instruction[20] ) // the 'S' bit
|
Line 1482... |
Line 1497... |
|
|
if ( mem_op ) // load or store word or byte
|
if ( mem_op ) // load or store word or byte
|
control_state_nxt = MEM_WAIT1;
|
control_state_nxt = MEM_WAIT1;
|
if ( write_pc )
|
if ( write_pc )
|
control_state_nxt = PC_STALL1;
|
control_state_nxt = PC_STALL1;
|
if ( type == MTRANS )
|
if ( itype == MTRANS )
|
begin
|
begin
|
if ( mtrans_num_registers != 5'd0 )
|
if ( mtrans_num_registers != 5'd0 )
|
begin
|
begin
|
// check for LDM/STM of a single register
|
// check for LDM/STM of a single register
|
if ( mtrans_num_registers == 5'd1 )
|
if ( mtrans_num_registers == 5'd1 )
|
Line 1496... |
Line 1511... |
end
|
end
|
else
|
else
|
control_state_nxt = MTRANS_EXEC3;
|
control_state_nxt = MTRANS_EXEC3;
|
end
|
end
|
|
|
if ( type == MULT )
|
if ( itype == MULT )
|
control_state_nxt = MULT_PROC1;
|
control_state_nxt = MULT_PROC1;
|
|
|
if ( type == SWAP )
|
if ( itype == SWAP )
|
control_state_nxt = SWAP_WRITE;
|
control_state_nxt = SWAP_WRITE;
|
|
|
if ( type == CORTRANS && !und_request )
|
if ( itype == CORTRANS && !und_request )
|
control_state_nxt = COPRO_WAIT;
|
control_state_nxt = COPRO_WAIT;
|
|
|
// interrupt overrides everything else so its last
|
// interrupt overrides everything else so its last
|
if ( interrupt )
|
if ( interrupt )
|
control_state_nxt = INT_WAIT1;
|
control_state_nxt = INT_WAIT1;
|
Line 1591... |
Line 1606... |
// sometimes this is a pre-fetch instruction
|
// sometimes this is a pre-fetch instruction
|
// e.g. two ldr instructions in a row. The second ldr will be saved
|
// e.g. two ldr instructions in a row. The second ldr will be saved
|
// to the pre-fetch instruction register
|
// to the pre-fetch instruction register
|
// then when its decoded, a copy is saved to the saved_current_instruction
|
// then when its decoded, a copy is saved to the saved_current_instruction
|
// register
|
// register
|
if (type == MTRANS)
|
if (itype == MTRANS)
|
begin
|
begin
|
saved_current_instruction <= mtrans_instruction_nxt;
|
saved_current_instruction <= mtrans_instruction_nxt;
|
saved_current_instruction_iabt <= instruction_iabt;
|
saved_current_instruction_iabt <= instruction_iabt;
|
saved_current_instruction_adex <= instruction_adex;
|
saved_current_instruction_adex <= instruction_adex;
|
saved_current_instruction_address <= instruction_address;
|
saved_current_instruction_address <= instruction_address;
|