Line 43... |
Line 43... |
|
|
|
|
module a25_execute (
|
module a25_execute (
|
|
|
input i_clk,
|
input i_clk,
|
input i_access_stall, // stall all stages of the cpu at the same time
|
input i_core_stall, // stall all stages of the Amber core at the same time
|
input i_mem_stall, // data memory access stalls
|
input i_mem_stall, // data memory access stalls
|
|
output o_exec_stall, // stall the core pipeline
|
|
|
input [31:0] i_wb_read_data, // data reads
|
input [31:0] i_wb_read_data, // data reads
|
input i_wb_read_data_valid, // read data is valid
|
input i_wb_read_data_valid, // read data is valid
|
input [9:0] i_wb_load_rd, // Rd for data reads
|
input [10:0] i_wb_load_rd, // Rd for data reads
|
|
|
input [31:0] i_copro_read_data, // From Co-Processor, to either Register
|
input [31:0] i_copro_read_data, // From Co-Processor, to either Register
|
// or Memory
|
// or Memory
|
input i_decode_iaccess, // Indicates an instruction access
|
input i_decode_iaccess, // Indicates an instruction access
|
input i_decode_daccess, // Indicates a data access
|
input i_decode_daccess, // Indicates a data access
|
Line 71... |
Line 72... |
output reg o_adex = 'd0, // Address Exception
|
output reg o_adex = 'd0, // Address Exception
|
output reg o_priviledged = 'd0, // Priviledged access
|
output reg o_priviledged = 'd0, // Priviledged access
|
output reg o_exclusive = 'd0, // swap access
|
output reg o_exclusive = 'd0, // swap access
|
output reg o_write_enable = 'd0,
|
output reg o_write_enable = 'd0,
|
output reg [3:0] o_byte_enable = 'd0,
|
output reg [3:0] o_byte_enable = 'd0,
|
output reg [7:0] o_exec_load_rd = 'd0, // The destination register for a load instruction
|
output reg [8:0] o_exec_load_rd = 'd0, // The destination register for a load instruction
|
output [31:0] o_status_bits, // Full PC will all status bits, but PC part zero'ed out
|
output [31:0] o_status_bits, // Full PC will all status bits, but PC part zero'ed out
|
output o_multiply_done,
|
output o_multiply_done,
|
|
|
|
|
// --------------------------------------------------
|
// --------------------------------------------------
|
Line 154... |
Line 155... |
wire [31:0] interrupt_vector;
|
wire [31:0] interrupt_vector;
|
wire [7:0] shift_amount;
|
wire [7:0] shift_amount;
|
wire [31:0] barrel_shift_in;
|
wire [31:0] barrel_shift_in;
|
wire [31:0] barrel_shift_out;
|
wire [31:0] barrel_shift_out;
|
wire barrel_shift_carry;
|
wire barrel_shift_carry;
|
|
wire barrel_shift_stall;
|
|
|
wire [3:0] status_bits_flags_nxt;
|
wire [3:0] status_bits_flags_nxt;
|
reg [3:0] status_bits_flags = 'd0;
|
reg [3:0] status_bits_flags = 'd0;
|
wire [1:0] status_bits_mode_nxt;
|
wire [1:0] status_bits_mode_nxt;
|
reg [1:0] status_bits_mode = SVC;
|
reg [1:0] status_bits_mode = SVC;
|
Line 167... |
Line 169... |
wire status_bits_mode_rds_oh_update;
|
wire status_bits_mode_rds_oh_update;
|
wire status_bits_irq_mask_nxt;
|
wire status_bits_irq_mask_nxt;
|
reg status_bits_irq_mask = 1'd1;
|
reg status_bits_irq_mask = 1'd1;
|
wire status_bits_firq_mask_nxt;
|
wire status_bits_firq_mask_nxt;
|
reg status_bits_firq_mask = 1'd1;
|
reg status_bits_firq_mask = 1'd1;
|
|
wire [8:0] exec_load_rd_nxt;
|
|
|
wire execute; // high when condition execution is true
|
wire execute; // high when condition execution is true
|
wire [31:0] reg_write_nxt;
|
wire [31:0] reg_write_nxt;
|
wire pc_wen;
|
wire pc_wen;
|
wire [14:0] reg_bank_wen;
|
wire [14:0] reg_bank_wen;
|
Line 222... |
Line 225... |
|
|
|
|
// ========================================================
|
// ========================================================
|
// Status Bits Select
|
// Status Bits Select
|
// ========================================================
|
// ========================================================
|
assign ldm_flags = i_wb_read_data_valid & ~i_mem_stall & i_wb_load_rd[7];
|
assign ldm_flags = i_wb_read_data_valid & ~i_mem_stall & i_wb_load_rd[8];
|
assign ldm_status_bits = i_wb_read_data_valid & ~i_mem_stall & i_wb_load_rd[6];
|
assign ldm_status_bits = i_wb_read_data_valid & ~i_mem_stall & i_wb_load_rd[7];
|
|
|
|
|
assign status_bits_flags_nxt = ldm_flags ? read_data_filtered[31:28] :
|
assign status_bits_flags_nxt = ldm_flags ? read_data_filtered[31:28] :
|
i_status_bits_sel == 3'd0 ? alu_flags :
|
i_status_bits_sel == 3'd0 ? alu_flags :
|
i_status_bits_sel == 3'd1 ? alu_out [31:28] :
|
i_status_bits_sel == 3'd1 ? alu_out [31:28] :
|
Line 346... |
Line 349... |
|
|
|
|
// ========================================================
|
// ========================================================
|
// Filter Read Data
|
// Filter Read Data
|
// ========================================================
|
// ========================================================
|
// mem_load_rd[9:8] -> shift ROR bytes
|
// mem_load_rd[10:9]-> shift ROR bytes
|
// mem_load_rd[7] -> load flags with PC
|
// mem_load_rd[8] -> load flags with PC
|
// mem_load_rd[6] -> load status bits with PC
|
// mem_load_rd[7] -> load status bits with PC
|
// mem_load_rd[5] -> Write into User Mode register
|
// mem_load_rd[6:5] -> Write into this Mode registers
|
// mem_load_rd[4] -> zero_extend byte
|
// mem_load_rd[4] -> zero_extend byte
|
// mem_load_rd[3:0] -> Destination Register
|
// mem_load_rd[3:0] -> Destination Register
|
assign read_data_filtered1 = i_wb_load_rd[9:8] === 2'd0 ? i_wb_read_data :
|
assign read_data_filtered1 = i_wb_load_rd[10:9] === 2'd0 ? i_wb_read_data :
|
i_wb_load_rd[9:8] === 2'd1 ? {i_wb_read_data[7:0], i_wb_read_data[31:8]} :
|
i_wb_load_rd[10:9] === 2'd1 ? {i_wb_read_data[7:0], i_wb_read_data[31:8]} :
|
i_wb_load_rd[9:8] === 2'd2 ? {i_wb_read_data[15:0], i_wb_read_data[31:16]} :
|
i_wb_load_rd[10:9] === 2'd2 ? {i_wb_read_data[15:0], i_wb_read_data[31:16]} :
|
{i_wb_read_data[23:0], i_wb_read_data[31:24]} ;
|
{i_wb_read_data[23:0], i_wb_read_data[31:24]} ;
|
|
|
assign read_data_filtered = i_wb_load_rd[4] ? {24'd0, read_data_filtered1[7:0]} : read_data_filtered1 ;
|
assign read_data_filtered = i_wb_load_rd[4] ? {24'd0, read_data_filtered1[7:0]} : read_data_filtered1 ;
|
|
|
|
|
Line 454... |
Line 457... |
|
|
|
|
// ========================================================
|
// ========================================================
|
// Address Valid
|
// Address Valid
|
// ========================================================
|
// ========================================================
|
assign daddress_valid_nxt = execute && i_decode_daccess && !i_access_stall;
|
assign daddress_valid_nxt = execute && i_decode_daccess && !i_core_stall;
|
|
|
// For some multi-cycle instructions, the stream of instrution
|
// For some multi-cycle instructions, the stream of instrution
|
// reads can be paused. However if the instruction does not execute
|
// reads can be paused. However if the instruction does not execute
|
// then the read stream must not be interrupted.
|
// then the read stream must not be interrupted.
|
assign iaddress_valid_nxt = i_decode_iaccess || !execute;
|
assign iaddress_valid_nxt = i_decode_iaccess || !execute;
|
Line 483... |
Line 486... |
assign read_data_filtered_c = i_wb_read_data_valid ? read_data_filtered : read_data_filtered_r;
|
assign read_data_filtered_c = i_wb_read_data_valid ? read_data_filtered : read_data_filtered_r;
|
assign load_rd_c = i_wb_read_data_valid ? i_wb_load_rd[3:0] : load_rd_r;
|
assign load_rd_c = i_wb_read_data_valid ? i_wb_load_rd[3:0] : load_rd_r;
|
|
|
|
|
// ========================================================
|
// ========================================================
|
|
// Set mode for the destination registers of a mem read
|
|
// ========================================================
|
|
// The mode is either user mode, or the current mode
|
|
assign exec_load_rd_nxt = { i_decode_load_rd[7:6],
|
|
i_decode_load_rd[5] ? USR : status_bits_mode, // 1 bit -> 2 bits
|
|
i_decode_load_rd[4:0] };
|
|
|
|
|
|
// ========================================================
|
// Register Update
|
// Register Update
|
// ========================================================
|
// ========================================================
|
|
assign o_exec_stall = barrel_shift_stall;
|
|
|
assign daddress_update = !i_access_stall;
|
assign daddress_update = !i_core_stall;
|
assign exec_load_rd_update = !i_access_stall && execute;
|
assign exec_load_rd_update = !i_core_stall && execute;
|
assign priviledged_update = !i_access_stall;
|
assign priviledged_update = !i_core_stall;
|
assign exclusive_update = !i_access_stall && execute;
|
assign exclusive_update = !i_core_stall && execute;
|
assign write_enable_update = !i_access_stall;
|
assign write_enable_update = !i_core_stall;
|
assign write_data_update = !i_access_stall && execute && i_write_data_wen;
|
assign write_data_update = !i_core_stall && execute && i_write_data_wen;
|
assign byte_enable_update = !i_access_stall && execute && i_write_data_wen;
|
assign byte_enable_update = !i_core_stall && execute && i_write_data_wen;
|
|
|
assign iaddress_update = pc_dmem_wen || (!i_access_stall && !i_conflict);
|
assign iaddress_update = pc_dmem_wen || (!i_core_stall && !i_conflict);
|
assign copro_write_data_update = !i_access_stall && execute && i_copro_write_data_wen;
|
assign copro_write_data_update = !i_core_stall && execute && i_copro_write_data_wen;
|
|
|
assign base_address_update = !i_access_stall && execute && i_base_address_wen;
|
assign base_address_update = !i_core_stall && execute && i_base_address_wen;
|
// assign dcache_read_data_update = !i_mem_stall;
|
assign status_bits_flags_update = ldm_flags || (!i_core_stall && execute && i_status_bits_flags_wen);
|
assign status_bits_flags_update = ldm_flags || (!i_access_stall && execute && i_status_bits_flags_wen);
|
assign status_bits_mode_update = ldm_status_bits || (!i_core_stall && execute && i_status_bits_mode_wen);
|
assign status_bits_mode_update = ldm_status_bits || (!i_access_stall && execute && i_status_bits_mode_wen);
|
assign status_bits_mode_rds_oh_update = !i_core_stall;
|
assign status_bits_mode_rds_oh_update = !i_access_stall;
|
assign status_bits_irq_mask_update = ldm_status_bits || (!i_core_stall && execute && i_status_bits_irq_mask_wen);
|
assign status_bits_irq_mask_update = ldm_status_bits || (!i_access_stall && execute && i_status_bits_irq_mask_wen);
|
assign status_bits_firq_mask_update = ldm_status_bits || (!i_core_stall && execute && i_status_bits_firq_mask_wen);
|
assign status_bits_firq_mask_update = ldm_status_bits || (!i_access_stall && execute && i_status_bits_firq_mask_wen);
|
|
|
|
|
|
always @( posedge i_clk )
|
always @( posedge i_clk )
|
begin
|
begin
|
o_daddress <= daddress_update ? o_daddress_nxt : o_daddress;
|
o_daddress <= daddress_update ? o_daddress_nxt : o_daddress;
|
o_daddress_valid <= daddress_update ? daddress_valid_nxt : o_daddress_valid;
|
o_daddress_valid <= daddress_update ? daddress_valid_nxt : o_daddress_valid;
|
o_exec_load_rd <= exec_load_rd_update ? i_decode_load_rd : o_exec_load_rd;
|
o_exec_load_rd <= exec_load_rd_update ? exec_load_rd_nxt : o_exec_load_rd;
|
o_priviledged <= priviledged_update ? priviledged_nxt : o_priviledged;
|
o_priviledged <= priviledged_update ? priviledged_nxt : o_priviledged;
|
o_exclusive <= exclusive_update ? i_decode_exclusive : o_exclusive;
|
o_exclusive <= exclusive_update ? i_decode_exclusive : o_exclusive;
|
o_write_enable <= write_enable_update ? write_enable_nxt : o_write_enable;
|
o_write_enable <= write_enable_update ? write_enable_nxt : o_write_enable;
|
o_write_data <= write_data_update ? write_data_nxt : o_write_data;
|
o_write_data <= write_data_update ? write_data_nxt : o_write_data;
|
o_byte_enable <= byte_enable_update ? byte_enable_nxt : o_byte_enable;
|
o_byte_enable <= byte_enable_update ? byte_enable_nxt : o_byte_enable;
|
Line 535... |
Line 547... |
|
|
// ========================================================
|
// ========================================================
|
// Instantiate Barrel Shift
|
// Instantiate Barrel Shift
|
// ========================================================
|
// ========================================================
|
a25_barrel_shift u_barrel_shift (
|
a25_barrel_shift u_barrel_shift (
|
|
.i_clk ( i_clk ),
|
.i_in ( barrel_shift_in ),
|
.i_in ( barrel_shift_in ),
|
.i_carry_in ( status_bits_flags[1] ),
|
.i_carry_in ( status_bits_flags[1] ),
|
.i_shift_amount ( shift_amount ),
|
.i_shift_amount ( shift_amount ),
|
.i_shift_imm_zero ( i_shift_imm_zero ),
|
.i_shift_imm_zero ( i_shift_imm_zero ),
|
.i_function ( i_barrel_shift_function ),
|
.i_function ( i_barrel_shift_function ),
|
|
|
.o_out ( barrel_shift_out ),
|
.o_out ( barrel_shift_out ),
|
.o_carry_out ( barrel_shift_carry )
|
.o_carry_out ( barrel_shift_carry ),
|
|
.o_stall ( barrel_shift_stall )
|
);
|
);
|
|
|
|
|
// ========================================================
|
// ========================================================
|
// Instantiate ALU
|
// Instantiate ALU
|
Line 566... |
Line 580... |
// ========================================================
|
// ========================================================
|
// Instantiate Booth 64-bit Multiplier-Accumulator
|
// Instantiate Booth 64-bit Multiplier-Accumulator
|
// ========================================================
|
// ========================================================
|
a25_multiply u_multiply (
|
a25_multiply u_multiply (
|
.i_clk ( i_clk ),
|
.i_clk ( i_clk ),
|
.i_access_stall ( i_access_stall ),
|
.i_core_stall ( i_core_stall ),
|
.i_a_in ( rs ),
|
.i_a_in ( rs ),
|
.i_b_in ( rm ),
|
.i_b_in ( rm ),
|
.i_function ( i_multiply_function ),
|
.i_function ( i_multiply_function ),
|
.i_execute ( execute ),
|
.i_execute ( execute ),
|
.o_out ( multiply_out ),
|
.o_out ( multiply_out ),
|
Line 582... |
Line 596... |
// ========================================================
|
// ========================================================
|
// Instantiate Register Bank
|
// Instantiate Register Bank
|
// ========================================================
|
// ========================================================
|
a25_register_bank u_register_bank(
|
a25_register_bank u_register_bank(
|
.i_clk ( i_clk ),
|
.i_clk ( i_clk ),
|
.i_access_stall ( i_access_stall ),
|
.i_core_stall ( i_core_stall ),
|
.i_mem_stall ( i_mem_stall ),
|
.i_mem_stall ( i_mem_stall ),
|
.i_rm_sel ( i_rm_sel ),
|
.i_rm_sel ( i_rm_sel ),
|
.i_rs_sel ( i_rs_sel ),
|
.i_rs_sel ( i_rs_sel ),
|
.i_rn_sel ( i_rn_sel ),
|
.i_rn_sel ( i_rn_sel ),
|
.i_pc_wen ( pc_wen ),
|
.i_pc_wen ( pc_wen ),
|
Line 597... |
Line 611... |
.i_mode_exec ( status_bits_mode ),
|
.i_mode_exec ( status_bits_mode ),
|
|
|
.i_wb_read_data ( read_data_filtered ),
|
.i_wb_read_data ( read_data_filtered ),
|
.i_wb_read_data_valid ( i_wb_read_data_valid ),
|
.i_wb_read_data_valid ( i_wb_read_data_valid ),
|
.i_wb_read_data_rd ( i_wb_load_rd[3:0] ),
|
.i_wb_read_data_rd ( i_wb_load_rd[3:0] ),
|
.i_wb_user_mode ( i_wb_load_rd[5] ),
|
.i_wb_mode ( i_wb_load_rd[6:5] ),
|
|
|
.i_status_bits_flags ( status_bits_flags ),
|
.i_status_bits_flags ( status_bits_flags ),
|
.i_status_bits_irq_mask ( status_bits_irq_mask ),
|
.i_status_bits_irq_mask ( status_bits_irq_mask ),
|
.i_status_bits_firq_mask ( status_bits_firq_mask ),
|
.i_status_bits_firq_mask ( status_bits_firq_mask ),
|
|
|