Line 77... |
Line 77... |
output reg o_status_bits_firq_mask = 1'd1,
|
output reg o_status_bits_firq_mask = 1'd1,
|
|
|
output reg [3:0] o_rm_sel = 'd0,
|
output reg [3:0] o_rm_sel = 'd0,
|
output reg [3:0] o_rds_sel = 'd0,
|
output reg [3:0] o_rds_sel = 'd0,
|
output reg [3:0] o_rn_sel = 'd0,
|
output reg [3:0] o_rn_sel = 'd0,
|
|
output [3:0] o_rm_sel_nxt,
|
|
output [3:0] o_rds_sel_nxt,
|
|
output [3:0] o_rn_sel_nxt,
|
output reg [1:0] o_barrel_shift_amount_sel = 'd0,
|
output reg [1:0] o_barrel_shift_amount_sel = 'd0,
|
output reg [1:0] o_barrel_shift_data_sel = 'd0,
|
output reg [1:0] o_barrel_shift_data_sel = 'd0,
|
output reg [1:0] o_barrel_shift_function = 'd0,
|
output reg [1:0] o_barrel_shift_function = 'd0,
|
output reg [8:0] o_alu_function = 'd0,
|
output reg [8:0] o_alu_function = 'd0,
|
output reg [1:0] o_multiply_function = 'd0,
|
output reg [1:0] o_multiply_function = 'd0,
|
Line 97... |
Line 100... |
output reg o_write_data_wen = 'd0,
|
output reg o_write_data_wen = 'd0,
|
output reg o_base_address_wen = 'd0, // save LDM base address register
|
output reg o_base_address_wen = 'd0, // save LDM base address register
|
// in case of data abort
|
// in case of data abort
|
output reg o_pc_wen = 1'd1,
|
output reg o_pc_wen = 1'd1,
|
output reg [14:0] o_reg_bank_wen = 'd0,
|
output reg [14:0] o_reg_bank_wen = 'd0,
|
|
output reg [3:0] o_reg_bank_wsel = 'd0,
|
output reg o_status_bits_flags_wen = 'd0,
|
output reg o_status_bits_flags_wen = 'd0,
|
output reg o_status_bits_mode_wen = 'd0,
|
output reg o_status_bits_mode_wen = 'd0,
|
output reg o_status_bits_irq_mask_wen = 'd0,
|
output reg o_status_bits_irq_mask_wen = 'd0,
|
output reg o_status_bits_firq_mask_wen = 'd0,
|
output reg o_status_bits_firq_mask_wen = 'd0,
|
|
|
Line 199... |
Line 203... |
reg [1:0] multiply_function_nxt;
|
reg [1:0] multiply_function_nxt;
|
reg [1:0] status_bits_mode_nxt;
|
reg [1:0] status_bits_mode_nxt;
|
reg status_bits_irq_mask_nxt;
|
reg status_bits_irq_mask_nxt;
|
reg status_bits_firq_mask_nxt;
|
reg status_bits_firq_mask_nxt;
|
|
|
wire [3:0] rm_sel_nxt;
|
|
wire [3:0] rds_sel_nxt;
|
|
wire [3:0] rn_sel_nxt;
|
|
reg [1:0] barrel_shift_amount_sel_nxt;
|
reg [1:0] barrel_shift_amount_sel_nxt;
|
reg [1:0] barrel_shift_data_sel_nxt;
|
reg [1:0] barrel_shift_data_sel_nxt;
|
reg [3:0] address_sel_nxt;
|
reg [3:0] address_sel_nxt;
|
reg [1:0] pc_sel_nxt;
|
reg [1:0] pc_sel_nxt;
|
reg [1:0] byte_enable_sel_nxt;
|
reg [1:0] byte_enable_sel_nxt;
|
Line 223... |
Line 224... |
|
|
reg write_data_wen_nxt;
|
reg write_data_wen_nxt;
|
reg copro_write_data_wen_nxt;
|
reg copro_write_data_wen_nxt;
|
reg base_address_wen_nxt;
|
reg base_address_wen_nxt;
|
reg pc_wen_nxt;
|
reg pc_wen_nxt;
|
reg [14:0] reg_bank_wen_nxt;
|
reg [3:0] reg_bank_wsel_nxt;
|
reg status_bits_flags_wen_nxt;
|
reg status_bits_flags_wen_nxt;
|
reg status_bits_mode_wen_nxt;
|
reg status_bits_mode_wen_nxt;
|
reg status_bits_irq_mask_wen_nxt;
|
reg status_bits_irq_mask_wen_nxt;
|
reg status_bits_firq_mask_wen_nxt;
|
reg status_bits_firq_mask_wen_nxt;
|
|
|
Line 381... |
Line 382... |
// ========================================================
|
// ========================================================
|
|
|
assign opcode = instruction[24:21];
|
assign opcode = instruction[24:21];
|
assign condition_nxt = instruction[31:28];
|
assign condition_nxt = instruction[31:28];
|
|
|
assign rm_sel_nxt = instruction[3:0];
|
assign o_rm_sel_nxt = instruction[3:0];
|
|
|
assign 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 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 :
|
type == 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] ;
|
|
|
Line 630... |
Line 631... |
// default Flop Write Enable values
|
// default Flop Write Enable values
|
write_data_wen_nxt = 'd0;
|
write_data_wen_nxt = 'd0;
|
copro_write_data_wen_nxt = 'd0;
|
copro_write_data_wen_nxt = 'd0;
|
base_address_wen_nxt = 'd0;
|
base_address_wen_nxt = 'd0;
|
pc_wen_nxt = 'd1;
|
pc_wen_nxt = 'd1;
|
reg_bank_wen_nxt = 'd0; // Don't select any
|
reg_bank_wsel_nxt = 'hF; // Don't select any
|
status_bits_flags_wen_nxt = 'd0;
|
status_bits_flags_wen_nxt = 'd0;
|
status_bits_mode_wen_nxt = 'd0;
|
status_bits_mode_wen_nxt = 'd0;
|
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;
|
|
|
Line 649... |
Line 650... |
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
|
end
|
end
|
else
|
else
|
reg_bank_wen_nxt = decode (instruction[15:12]);
|
reg_bank_wsel_nxt = instruction[15:12];
|
end
|
end
|
|
|
if ( !immediate_shifter_operand )
|
if ( !immediate_shifter_operand )
|
barrel_shift_function_nxt = instruction[6:5];
|
barrel_shift_function_nxt = instruction[6:5];
|
|
|
Line 773... |
Line 774... |
// 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]
|
if ( mem_op_pre_indexed || mem_op_post_indexed )
|
if ( mem_op_pre_indexed || mem_op_post_indexed )
|
begin
|
begin
|
// Check is the load destination is the PC
|
// Check is the load destination is the PC
|
if ( rn_sel_nxt == 4'd15 )
|
if ( o_rn_sel_nxt == 4'd15 )
|
pc_sel_nxt = 2'd1;
|
pc_sel_nxt = 2'd1;
|
else
|
else
|
reg_bank_wen_nxt = decode ( rn_sel_nxt );
|
reg_bank_wsel_nxt = o_rn_sel_nxt;
|
end
|
end
|
|
|
// if post-indexed, then use Rn rather than ALU output, as address
|
// if post-indexed, then use Rn rather than ALU output, as address
|
if ( mem_op_post_indexed )
|
if ( mem_op_post_indexed )
|
address_sel_nxt = 4'd4; // Rn
|
address_sel_nxt = 4'd4; // Rn
|
Line 803... |
Line 804... |
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
|
|
|
if ( instruction[24] ) // Link
|
if ( instruction[24] ) // Link
|
begin
|
begin
|
reg_bank_wen_nxt = decode (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 ( type == MTRANS )
|
Line 859... |
Line 860... |
if ( {instruction[22:20]} == 3'b100 )
|
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_wen_nxt = decode (rn_sel_nxt);
|
reg_bank_wsel_nxt = o_rn_sel_nxt;
|
end
|
end
|
|
|
|
|
if ( type == MULT )
|
if ( type == MULT )
|
begin
|
begin
|
Line 912... |
Line 913... |
|
|
if ( type == SWI || und_request )
|
if ( type == 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_wen_nxt = decode (4'd14); // LR
|
reg_bank_wsel_nxt = 4'd14; // LR
|
|
|
address_sel_nxt = 4'd2; // interrupt_vector
|
address_sel_nxt = 4'd2; // interrupt_vector
|
pc_sel_nxt = 2'd2; // interrupt_vector
|
pc_sel_nxt = 2'd2; // interrupt_vector
|
|
|
status_bits_mode_nxt = interrupt_mode; // e.g. Supervisor mode
|
status_bits_mode_nxt = interrupt_mode; // e.g. Supervisor mode
|
Line 968... |
Line 969... |
if ( next_interrupt == 3'd4 )
|
if ( next_interrupt == 3'd4 )
|
reg_write_sel_nxt = 3'd7; // pc
|
reg_write_sel_nxt = 3'd7; // pc
|
else
|
else
|
reg_write_sel_nxt = 3'd1; // pc -4
|
reg_write_sel_nxt = 3'd1; // pc -4
|
|
|
reg_bank_wen_nxt = decode (4'd14); // LR
|
reg_bank_wsel_nxt = 4'd14; // LR
|
|
|
address_sel_nxt = 4'd2; // interrupt_vector
|
address_sel_nxt = 4'd2; // interrupt_vector
|
pc_sel_nxt = 2'd2; // interrupt_vector
|
pc_sel_nxt = 2'd2; // interrupt_vector
|
|
|
status_bits_mode_nxt = interrupt_mode; // e.g. Supervisor mode
|
status_bits_mode_nxt = interrupt_mode; // e.g. Supervisor mode
|
Line 1028... |
Line 1029... |
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
|
end
|
end
|
else
|
else
|
reg_bank_wen_nxt = decode (instruction[15:12]);
|
reg_bank_wsel_nxt = instruction[15:12];
|
end
|
end
|
end
|
end
|
|
|
|
|
// second cycle of multiple load or store
|
// second cycle of multiple load or store
|
Line 1076... |
Line 1077... |
if ( instruction[20] ) // Load
|
if ( instruction[20] ) // Load
|
begin
|
begin
|
// Can never be loading the PC in this state, as the PC is always
|
// Can never be loading the PC in this state, as the PC is always
|
// the last register in the set to be loaded
|
// the last register in the set to be loaded
|
if ( !dabt )
|
if ( !dabt )
|
reg_bank_wen_nxt = decode (mtrans_reg_d2);
|
reg_bank_wsel_nxt = mtrans_reg_d2;
|
end
|
end
|
else // Store
|
else // 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
|
Line 1101... |
Line 1102... |
barrel_shift_data_sel_nxt = 2'd1; // load word from memory
|
barrel_shift_data_sel_nxt = 2'd1; // load word from memory
|
|
|
// Can never be loading the PC in this state, as the PC is always
|
// Can never be loading the PC in this state, as the PC is always
|
// the last register in the set to be loaded
|
// the last register in the set to be loaded
|
if ( instruction[20] && !dabt ) // Load
|
if ( instruction[20] && !dabt ) // Load
|
reg_bank_wen_nxt = decode (mtrans_reg_d2);
|
reg_bank_wsel_nxt = mtrans_reg_d2;
|
|
|
// LDM: load into user mode registers, when in priviledged mode
|
// LDM: load into user mode registers, when in priviledged mode
|
if ( {instruction[22:20],mtrans_r15} == 4'b1010 )
|
if ( {instruction[22:20],mtrans_r15} == 4'b1010 )
|
user_mode_regs_load_nxt = 1'd1;
|
user_mode_regs_load_nxt = 1'd1;
|
|
|
Line 1165... |
Line 1166... |
end
|
end
|
end
|
end
|
end
|
end
|
else
|
else
|
begin
|
begin
|
reg_bank_wen_nxt = decode (mtrans_reg_d2);
|
reg_bank_wsel_nxt = mtrans_reg_d2;
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
// we have a data abort interrupt
|
// we have a data abort interrupt
|
Line 1194... |
Line 1195... |
// Restore the Base Address, if the base register is included in the
|
// Restore the Base Address, if the base register is included in the
|
// list of registers being loaded
|
// list of registers being loaded
|
if (restore_base_address) // LDM with base address in register list
|
if (restore_base_address) // LDM with base address in register list
|
begin
|
begin
|
reg_write_sel_nxt = 3'd6; // write base_register
|
reg_write_sel_nxt = 3'd6; // write base_register
|
reg_bank_wen_nxt = decode ( instruction[19:16] ); // to Rn
|
reg_bank_wsel_nxt = instruction[19:16]; // to Rn
|
end
|
end
|
end
|
end
|
|
|
|
|
// Multiply or Multiply-Accumulate
|
// Multiply or Multiply-Accumulate
|
Line 1231... |
Line 1232... |
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 ( type == MULT ) // 32-bit
|
reg_bank_wen_nxt = decode (instruction[19:16]); // Rd
|
reg_bank_wsel_nxt = instruction[19:16]; // Rd
|
else // 64-bit / Long
|
else // 64-bit / Long
|
reg_bank_wen_nxt = decode (instruction[15:12]); // RdLo
|
reg_bank_wsel_nxt = instruction[15:12]; // RdLo
|
|
|
if ( instruction[20] ) // the 'S' bit
|
if ( instruction[20] ) // the 'S' bit
|
begin
|
begin
|
status_bits_sel_nxt = 3'd4; // { multiply_flags, status_bits_flags[1:0] }
|
status_bits_sel_nxt = 3'd4; // { multiply_flags, status_bits_flags[1:0] }
|
status_bits_flags_wen_nxt = 1'd1;
|
status_bits_flags_wen_nxt = 1'd1;
|
Line 1301... |
Line 1302... |
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
|
end
|
end
|
else
|
else
|
reg_bank_wen_nxt = decode (instruction[15:12]);
|
reg_bank_wsel_nxt = instruction[15:12];
|
end
|
end
|
end
|
end
|
|
|
// 1 cycle delay for Co-Processor Register access
|
// 1 cycle delay for Co-Processor Register access
|
if ( control_state == COPRO_WAIT && instruction_execute )
|
if ( control_state == COPRO_WAIT && instruction_execute )
|
Line 1329... |
Line 1330... |
status_bits_irq_mask_wen_nxt = 1'd1;
|
status_bits_irq_mask_wen_nxt = 1'd1;
|
status_bits_firq_mask_wen_nxt = 1'd1;
|
status_bits_firq_mask_wen_nxt = 1'd1;
|
end
|
end
|
end
|
end
|
else
|
else
|
reg_bank_wen_nxt = decode (instruction[15:12]);
|
reg_bank_wsel_nxt = instruction[15:12];
|
|
|
reg_write_sel_nxt = 3'd5; // i_copro_data
|
reg_write_sel_nxt = 3'd5; // i_copro_data
|
end
|
end
|
else // mcr instruction
|
else // mcr instruction
|
begin
|
begin
|
Line 1527... |
Line 1528... |
// execute them unconditionally
|
// execute them unconditionally
|
o_condition <= instruction_valid && !interrupt ? condition_nxt : AL;
|
o_condition <= instruction_valid && !interrupt ? condition_nxt : AL;
|
o_exclusive_exec <= exclusive_exec_nxt;
|
o_exclusive_exec <= exclusive_exec_nxt;
|
o_data_access_exec <= data_access_exec_nxt;
|
o_data_access_exec <= data_access_exec_nxt;
|
|
|
o_rm_sel <= rm_sel_nxt;
|
o_rm_sel <= o_rm_sel_nxt;
|
o_rds_sel <= rds_sel_nxt;
|
o_rds_sel <= o_rds_sel_nxt;
|
o_rn_sel <= rn_sel_nxt;
|
o_rn_sel <= o_rn_sel_nxt;
|
o_barrel_shift_amount_sel <= barrel_shift_amount_sel_nxt;
|
o_barrel_shift_amount_sel <= barrel_shift_amount_sel_nxt;
|
o_barrel_shift_data_sel <= barrel_shift_data_sel_nxt;
|
o_barrel_shift_data_sel <= barrel_shift_data_sel_nxt;
|
o_barrel_shift_function <= barrel_shift_function_nxt;
|
o_barrel_shift_function <= barrel_shift_function_nxt;
|
o_alu_function <= alu_function_nxt;
|
o_alu_function <= alu_function_nxt;
|
o_multiply_function <= multiply_function_nxt;
|
o_multiply_function <= multiply_function_nxt;
|
Line 1546... |
Line 1547... |
o_user_mode_regs_load <= user_mode_regs_load_nxt;
|
o_user_mode_regs_load <= user_mode_regs_load_nxt;
|
o_firq_not_user_mode <= firq_not_user_mode_nxt;
|
o_firq_not_user_mode <= firq_not_user_mode_nxt;
|
o_write_data_wen <= write_data_wen_nxt;
|
o_write_data_wen <= write_data_wen_nxt;
|
o_base_address_wen <= base_address_wen_nxt;
|
o_base_address_wen <= base_address_wen_nxt;
|
o_pc_wen <= pc_wen_nxt;
|
o_pc_wen <= pc_wen_nxt;
|
o_reg_bank_wen <= reg_bank_wen_nxt;
|
o_reg_bank_wsel <= reg_bank_wsel_nxt;
|
|
o_reg_bank_wen <= decode ( reg_bank_wsel_nxt );
|
o_status_bits_flags_wen <= status_bits_flags_wen_nxt;
|
o_status_bits_flags_wen <= status_bits_flags_wen_nxt;
|
o_status_bits_mode_wen <= status_bits_mode_wen_nxt;
|
o_status_bits_mode_wen <= status_bits_mode_wen_nxt;
|
o_status_bits_irq_mask_wen <= status_bits_irq_mask_wen_nxt;
|
o_status_bits_irq_mask_wen <= status_bits_irq_mask_wen_nxt;
|
o_status_bits_firq_mask_wen <= status_bits_firq_mask_wen_nxt;
|
o_status_bits_firq_mask_wen <= status_bits_firq_mask_wen_nxt;
|
|
|