Line 62... |
Line 62... |
// Control signals to execute stage
|
// Control signals to execute stage
|
// --------------------------------------------------
|
// --------------------------------------------------
|
output reg [31:0] o_imm32 = 'd0,
|
output reg [31:0] o_imm32 = 'd0,
|
output reg [4:0] o_imm_shift_amount = 'd0,
|
output reg [4:0] o_imm_shift_amount = 'd0,
|
output reg o_shift_imm_zero = 'd0,
|
output reg o_shift_imm_zero = 'd0,
|
output reg [3:0] o_condition = 4'he, // 4'he = al
|
output wire [3:0] o_condition,
|
output reg o_decode_exclusive = 'd0, // exclusive access request ( swap instruction )
|
output reg o_decode_exclusive = 'd0, // exclusive access request ( swap instruction )
|
output reg o_decode_iaccess = 1'd1, // Indicates an instruction access
|
output wire o_decode_iaccess, // Indicates an instruction access
|
output reg o_decode_daccess = 'd0, // Indicates a data access
|
output reg o_decode_daccess = 'd0, // Indicates a data access
|
output reg [1:0] o_status_bits_mode = 2'b11, // SVC
|
output wire [1:0] o_status_bits_mode,
|
output reg o_status_bits_irq_mask = 1'd1,
|
output wire o_status_bits_irq_mask,
|
output reg o_status_bits_firq_mask = 1'd1,
|
output wire o_status_bits_firq_mask,
|
|
|
output reg [3:0] o_rm_sel = 'd0,
|
output reg [3:0] o_rm_sel = 'd0,
|
output reg [3:0] o_rs_sel = 'd0,
|
output reg [3:0] o_rs_sel = 'd0,
|
output reg [7:0] o_load_rd = 'd0, // [7] load flags with PC
|
output reg [7:0] o_load_rd = 'd0, // [7] load flags with PC
|
// [6] load status bits with PC
|
// [6] load status bits with PC
|
Line 84... |
Line 84... |
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,
|
output reg [2:0] o_interrupt_vector_sel = 'd0,
|
output reg [2:0] o_interrupt_vector_sel = 'd0,
|
output reg [3:0] o_iaddress_sel = 4'd2,
|
output wire [3:0] o_iaddress_sel,
|
output reg [3:0] o_daddress_sel = 4'd2,
|
output wire [3:0] o_daddress_sel,
|
output reg [2:0] o_pc_sel = 3'd2,
|
output wire [2:0] o_pc_sel,
|
output reg [1:0] o_byte_enable_sel = 'd0, // byte, halfword or word write
|
output reg [1:0] o_byte_enable_sel = 'd0, // byte, halfword or word write
|
output reg [2:0] o_status_bits_sel = 'd0,
|
output reg [2:0] o_status_bits_sel = 'd0,
|
output reg [2:0] o_reg_write_sel,
|
output reg [2:0] o_reg_write_sel,
|
output reg o_user_mode_regs_store_nxt,
|
output reg o_user_mode_regs_store_nxt,
|
output reg o_firq_not_user_mode,
|
output reg o_firq_not_user_mode,
|
output reg o_use_carry_in,
|
output reg o_use_carry_in,
|
|
|
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 wire o_pc_wen,
|
output reg [14:0] o_reg_bank_wen = 'd0,
|
output reg [14:0] o_reg_bank_wen = '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 339... |
Line 339... |
reg rn_conflict1_r = 'd0;
|
reg rn_conflict1_r = 'd0;
|
reg rm_conflict1_r = 'd0;
|
reg rm_conflict1_r = 'd0;
|
reg rs_conflict1_r = 'd0;
|
reg rs_conflict1_r = 'd0;
|
reg rd_conflict1_r = 'd0;
|
reg rd_conflict1_r = 'd0;
|
|
|
|
// ========================================================
|
|
// registers for output ports with non-zero initial values
|
|
// ========================================================
|
|
reg [3:0] condition_r = 4'he; // 4'he = al
|
|
reg decode_iaccess_r = 1'd1; // Indicates an instruction access
|
|
reg [1:0] status_bits_mode_r = 2'b11; // SVC
|
|
reg status_bits_irq_mask_r = 1'd1;
|
|
reg status_bits_firq_mask_r = 1'd1;
|
|
reg [3:0] iaddress_sel_r = 4'd2;
|
|
reg [3:0] daddress_sel_r = 4'd2;
|
|
reg [2:0] pc_sel_r = 3'd2;
|
|
reg pc_wen_r = 1'd1;
|
|
|
|
|
|
assign o_condition = condition_r;
|
|
assign o_decode_iaccess = decode_iaccess_r;
|
|
assign o_status_bits_mode = status_bits_mode_r;
|
|
assign o_status_bits_irq_mask = status_bits_irq_mask_r;
|
|
assign o_status_bits_firq_mask = status_bits_firq_mask_r;
|
|
assign o_iaddress_sel = iaddress_sel_r;
|
|
assign o_daddress_sel = daddress_sel_r;
|
|
assign o_pc_sel = pc_sel_r;
|
|
assign o_pc_wen = pc_wen_r;
|
|
|
|
|
|
|
// ========================================================
|
// ========================================================
|
// Instruction Abort and Data Abort outputs
|
// Instruction Abort and Data Abort outputs
|
// ========================================================
|
// ========================================================
|
|
|
assign o_iabt_trigger = instruction_iabt && o_status_bits_mode == SVC && control_state == INT_WAIT1;
|
assign o_iabt_trigger = instruction_iabt && status_bits_mode_r == SVC && control_state == INT_WAIT1;
|
assign o_iabt_address = instruction_address;
|
assign o_iabt_address = instruction_address;
|
assign o_iabt_status = instruction_iabt_status;
|
assign o_iabt_status = instruction_iabt_status;
|
|
|
assign o_dabt_trigger = dabt_reg && !dabt_reg_d1;
|
assign o_dabt_trigger = dabt_reg && !dabt_reg_d1;
|
assign o_dabt_address = fetch_address_r;
|
assign o_dabt_address = fetch_address_r;
|
Line 732... |
Line 757... |
always @*
|
always @*
|
begin
|
begin
|
// default mode
|
// default mode
|
status_bits_mode_nxt = i_execute_status_bits[1:0]; // change to mode in execute stage get reflected
|
status_bits_mode_nxt = i_execute_status_bits[1:0]; // change to mode in execute stage get reflected
|
// back to this stage automatically
|
// back to this stage automatically
|
status_bits_irq_mask_nxt = o_status_bits_irq_mask;
|
status_bits_irq_mask_nxt = status_bits_irq_mask_r;
|
status_bits_firq_mask_nxt = o_status_bits_firq_mask;
|
status_bits_firq_mask_nxt = status_bits_firq_mask_r;
|
decode_exclusive_nxt = 1'd0;
|
decode_exclusive_nxt = 1'd0;
|
decode_daccess_nxt = 1'd0;
|
decode_daccess_nxt = 1'd0;
|
decode_iaccess_nxt = 1'd1;
|
decode_iaccess_nxt = 1'd1;
|
copro_operation_nxt = 'd0;
|
copro_operation_nxt = 'd0;
|
|
|
Line 1426... |
Line 1451... |
// creates a 1 cycle gap with the old mode
|
// creates a 1 cycle gap with the old mode
|
// coming back from execute into instruction_decode
|
// coming back from execute into instruction_decode
|
// So squash that old mode value during this
|
// So squash that old mode value during this
|
// cycle of the interrupt transition
|
// cycle of the interrupt transition
|
if ( control_state == INT_WAIT1 )
|
if ( control_state == INT_WAIT1 )
|
status_bits_mode_nxt = o_status_bits_mode; // Supervisor mode
|
status_bits_mode_nxt = status_bits_mode_r; // Supervisor mode
|
|
|
end
|
end
|
|
|
|
|
// Speed up the long path from u_decode/fetch_instruction_r to u_register_bank/r8_firq
|
// Speed up the long path from u_decode/fetch_instruction_r to u_register_bank/r8_firq
|
Line 1441... |
Line 1466... |
// ========================================================
|
// ========================================================
|
// Next State Logic
|
// Next State Logic
|
// ========================================================
|
// ========================================================
|
|
|
// this replicates the current value of the execute signal in the execute stage
|
// this replicates the current value of the execute signal in the execute stage
|
assign instruction_execute = conditional_execute ( o_condition, i_execute_status_bits[31:28] );
|
assign instruction_execute = conditional_execute ( condition_r, i_execute_status_bits[31:28] );
|
|
|
|
|
// First state of executing a new instruction
|
// First state of executing a new instruction
|
// Its complex because of conditional execution of multi-cycle instructions
|
// Its complex because of conditional execution of multi-cycle instructions
|
assign instruction_valid = ((control_state == EXECUTE || control_state == PRE_FETCH_EXEC) ||
|
assign instruction_valid = ((control_state == EXECUTE || control_state == PRE_FETCH_EXEC) ||
|
Line 1593... |
Line 1618... |
iabt_reg <= i_iabt;
|
iabt_reg <= i_iabt;
|
adex_reg <= i_adex;
|
adex_reg <= i_adex;
|
abt_status_reg <= i_abt_status;
|
abt_status_reg <= i_abt_status;
|
end
|
end
|
|
|
o_status_bits_mode <= status_bits_mode_nxt;
|
status_bits_mode_r <= status_bits_mode_nxt;
|
o_status_bits_irq_mask <= status_bits_irq_mask_nxt;
|
status_bits_irq_mask_r <= status_bits_irq_mask_nxt;
|
o_status_bits_firq_mask <= status_bits_firq_mask_nxt;
|
status_bits_firq_mask_r <= status_bits_firq_mask_nxt;
|
o_imm32 <= imm32_nxt;
|
o_imm32 <= imm32_nxt;
|
o_imm_shift_amount <= imm_shift_amount_nxt;
|
o_imm_shift_amount <= imm_shift_amount_nxt;
|
o_shift_imm_zero <= shift_imm_zero_nxt;
|
o_shift_imm_zero <= shift_imm_zero_nxt;
|
|
|
// when have an interrupt, execute the interrupt operation
|
// when have an interrupt, execute the interrupt operation
|
// unconditionally in the execute stage
|
// unconditionally in the execute stage
|
// ensures that status_bits register gets updated correctly
|
// ensures that status_bits register gets updated correctly
|
// Likewise when in middle of multi-cycle instructions
|
// Likewise when in middle of multi-cycle instructions
|
// execute them unconditionally
|
// execute them unconditionally
|
o_condition <= instruction_valid && !interrupt ? condition_nxt : AL;
|
condition_r <= instruction_valid && !interrupt ? condition_nxt : AL;
|
o_decode_exclusive <= decode_exclusive_nxt;
|
o_decode_exclusive <= decode_exclusive_nxt;
|
o_decode_iaccess <= decode_iaccess_nxt;
|
decode_iaccess_r <= decode_iaccess_nxt;
|
o_decode_daccess <= decode_daccess_nxt;
|
o_decode_daccess <= decode_daccess_nxt;
|
|
|
o_rm_sel <= rm_sel_nxt;
|
o_rm_sel <= rm_sel_nxt;
|
o_rs_sel <= rs_sel_nxt;
|
o_rs_sel <= rs_sel_nxt;
|
o_load_rd <= load_rd_nxt;
|
o_load_rd <= load_rd_nxt;
|
Line 1623... |
Line 1648... |
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_use_carry_in <= use_carry_in_nxt;
|
o_use_carry_in <= use_carry_in_nxt;
|
o_multiply_function <= multiply_function_nxt;
|
o_multiply_function <= multiply_function_nxt;
|
o_interrupt_vector_sel <= next_interrupt;
|
o_interrupt_vector_sel <= next_interrupt;
|
o_iaddress_sel <= iaddress_sel_nxt;
|
iaddress_sel_r <= iaddress_sel_nxt;
|
o_daddress_sel <= daddress_sel_nxt;
|
daddress_sel_r <= daddress_sel_nxt;
|
o_pc_sel <= pc_sel_nxt;
|
pc_sel_r <= pc_sel_nxt;
|
o_byte_enable_sel <= byte_enable_sel_nxt;
|
o_byte_enable_sel <= byte_enable_sel_nxt;
|
o_status_bits_sel <= status_bits_sel_nxt;
|
o_status_bits_sel <= status_bits_sel_nxt;
|
o_reg_write_sel <= reg_write_sel_nxt;
|
o_reg_write_sel <= reg_write_sel_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;
|
pc_wen_r <= pc_wen_nxt;
|
o_reg_bank_wen <= reg_bank_wen_nxt;
|
o_reg_bank_wen <= reg_bank_wen_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;
|
Line 1707... |
Line 1732... |
if ( !i_core_stall )
|
if ( !i_core_stall )
|
begin
|
begin
|
irq <= i_irq;
|
irq <= i_irq;
|
firq <= i_firq;
|
firq <= i_firq;
|
|
|
if ( control_state == INT_WAIT1 && o_status_bits_mode == SVC )
|
if ( control_state == INT_WAIT1 && status_bits_mode_r == SVC )
|
begin
|
begin
|
dabt_reg <= 1'd0;
|
dabt_reg <= 1'd0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
Line 1739... |
Line 1764... |
.i_instruction_execute ( instruction_execute ),
|
.i_instruction_execute ( instruction_execute ),
|
.i_instruction_address ( instruction_address ),
|
.i_instruction_address ( instruction_address ),
|
.i_interrupt ( {3{interrupt}} & next_interrupt ),
|
.i_interrupt ( {3{interrupt}} & next_interrupt ),
|
.i_interrupt_state ( control_state == INT_WAIT2 ),
|
.i_interrupt_state ( control_state == INT_WAIT2 ),
|
.i_instruction_undefined ( und_request ),
|
.i_instruction_undefined ( und_request ),
|
.i_pc_sel ( o_pc_sel ),
|
.i_pc_sel ( pc_sel_r ),
|
.i_pc_wen ( o_pc_wen )
|
.i_pc_wen ( pc_wen_r ));
|
);
|
|
|
|
|
|
wire [(15*8)-1:0] xCONTROL_STATE;
|
wire [(15*8)-1:0] xCONTROL_STATE;
|
wire [(15*8)-1:0] xMODE;
|
wire [(15*8)-1:0] xMODE;
|
wire [( 8*8)-1:0] xTYPE;
|
wire [( 8*8)-1:0] xTYPE;
|
Line 1774... |
Line 1798... |
control_state == SWAP_WAIT1 ? "SWAP_WAIT1" :
|
control_state == SWAP_WAIT1 ? "SWAP_WAIT1" :
|
control_state == SWAP_WAIT2 ? "SWAP_WAIT2" :
|
control_state == SWAP_WAIT2 ? "SWAP_WAIT2" :
|
control_state == COPRO_WAIT ? "COPRO_WAIT" :
|
control_state == COPRO_WAIT ? "COPRO_WAIT" :
|
"UNKNOWN " ;
|
"UNKNOWN " ;
|
|
|
assign xMODE = mode_name ( o_status_bits_mode );
|
assign xMODE = mode_name ( status_bits_mode_r );
|
|
|
assign xTYPE =
|
assign xTYPE =
|
type == REGOP ? "REGOP" :
|
type == REGOP ? "REGOP" :
|
type == MULT ? "MULT" :
|
type == MULT ? "MULT" :
|
type == SWAP ? "SWAP" :
|
type == SWAP ? "SWAP" :
|