Line 66... |
Line 66... |
output reg [4:0] o_read_data_alignment = 1'd0, // 2 LSBs of read address used for calculating shift in LDRB ops
|
output reg [4:0] o_read_data_alignment = 1'd0, // 2 LSBs of read address used for calculating shift in LDRB ops
|
|
|
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_exclusive_exec = 'd0, // exclusive access request ( swap instruction )
|
output reg o_exclusive_exec = 'd0, // exclusive access request ( swap instruction )
|
output reg o_data_access_exec = 'd0, // high means the memory access is a read
|
output reg o_data_access_exec = 'd0, // high means the memory access is a read
|
// read or write, low for instruction
|
// read or write, low for instruction
|
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_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_rm_sel_nxt,
|
Line 87... |
Line 87... |
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 o_use_carry_in = 'd0,
|
output reg o_use_carry_in = '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_address_sel = 4'd2,
|
output wire [3:0] o_address_sel,
|
output reg [1:0] o_pc_sel = 2'd2,
|
output wire [1: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_load,
|
output reg o_user_mode_regs_load,
|
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_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 [3:0] o_reg_bank_wsel = '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,
|
Line 290... |
Line 290... |
|
|
wire regop_set_flags;
|
wire regop_set_flags;
|
|
|
|
|
// ========================================================
|
// ========================================================
|
|
// registers for output ports with non-zero initial values
|
|
// ========================================================
|
|
reg [3:0] condition_r = 4'he; // 4'he = al
|
|
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] address_sel_r = 4'd2;
|
|
reg [1:0] pc_sel_r = 2'd2;
|
|
reg pc_wen_r = 1'd1;
|
|
|
|
assign o_condition = condition_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_address_sel = address_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 = abt_address_reg;
|
assign o_dabt_address = abt_address_reg;
|
Line 602... |
Line 623... |
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;
|
exclusive_exec_nxt = 1'd0;
|
exclusive_exec_nxt = 1'd0;
|
data_access_exec_nxt = 1'd0;
|
data_access_exec_nxt = 1'd0;
|
copro_operation_nxt = 'd0;
|
copro_operation_nxt = 'd0;
|
|
|
// Save an instruction to use later
|
// Save an instruction to use later
|
Line 1375... |
Line 1396... |
// 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/o_read_data to u_register_bank/r8_firq
|
// Speed up the long path from u_decode/o_read_data to u_register_bank/r8_firq
|
Line 1390... |
Line 1411... |
// ========================================================
|
// ========================================================
|
// 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] );
|
|
|
assign instruction_valid = (control_state == EXECUTE || control_state == PRE_FETCH_EXEC) ||
|
assign instruction_valid = (control_state == EXECUTE || control_state == PRE_FETCH_EXEC) ||
|
// when last instruction was multi-cycle instruction but did not execute
|
// when last instruction was multi-cycle instruction but did not execute
|
// because condition was false then act like you're in the execute state
|
// because condition was false then act like you're in the execute state
|
(!instruction_execute && (control_state == PC_STALL1 ||
|
(!instruction_execute && (control_state == PC_STALL1 ||
|
Line 1540... |
Line 1561... |
o_read_data_alignment <= {i_execute_address[1:0], 3'd0};
|
o_read_data_alignment <= {i_execute_address[1:0], 3'd0};
|
abt_address_reg <= i_execute_address;
|
abt_address_reg <= i_execute_address;
|
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;
|
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_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 <= o_rm_sel_nxt;
|
o_rm_sel <= o_rm_sel_nxt;
|
o_rds_sel <= o_rds_sel_nxt;
|
o_rds_sel <= o_rds_sel_nxt;
|
Line 1566... |
Line 1587... |
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_address_sel <= address_sel_nxt;
|
address_sel_r <= address_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_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;
|
pc_wen_r <= pc_wen_nxt;
|
o_reg_bank_wsel <= reg_bank_wsel_nxt;
|
o_reg_bank_wsel <= reg_bank_wsel_nxt;
|
o_reg_bank_wen <= decode ( 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;
|
Line 1642... |
Line 1663... |
if ( !i_fetch_stall )
|
if ( !i_fetch_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 1674... |
Line 1695... |
.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;
|
|
|
Line 1711... |
Line 1732... |
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 );
|
|
|
always @( posedge i_clk )
|
always @( posedge i_clk )
|
if (control_state == EXECUTE && ((instruction[0] === 1'bx) || (instruction[31] === 1'bx)))
|
if (control_state == EXECUTE && ((instruction[0] === 1'bx) || (instruction[31] === 1'bx)))
|
begin
|
begin
|
`TB_ERROR_MESSAGE
|
`TB_ERROR_MESSAGE
|