OpenCores
URL https://opencores.org/ocsvn/amber/amber/trunk

Subversion Repositories amber

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /amber
    from Rev 89 to Rev 88
    Reverse comparison

Rev 89 → Rev 88

/trunk/hw/vlog/amber23/a23_decode.v
52,7 → 52,7
input i_iabt, // instruction pre-fetch abort flag
input i_adex, // Address Exception
input [31:0] i_execute_address, // Registered address output by execute stage
// 2 LSBs of read address used for calculating
// 2 LSBs of read address used for calculating
// shift in LDRB ops
input [7:0] i_abt_status, // Abort status
input [31:0] i_execute_status_bits, // current status bits values in execute stage
68,13 → 68,13
output reg [31:0] o_imm32 = 'd0,
output reg [4:0] o_imm_shift_amount = 'd0,
output reg o_shift_imm_zero = 'd0,
output wire [3:0] o_condition,
output reg [3:0] o_condition = 4'he, // 4'he = al
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
output wire [1:0] o_status_bits_mode,
output wire o_status_bits_irq_mask,
output wire o_status_bits_firq_mask,
output reg [1:0] o_status_bits_mode = 2'b11, // SVC
output reg o_status_bits_irq_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_rds_sel = 'd0,
89,8 → 89,8
output reg o_use_carry_in = 'd0,
output reg [1:0] o_multiply_function = 'd0,
output reg [2:0] o_interrupt_vector_sel = 'd0,
output wire [3:0] o_address_sel,
output wire [1:0] o_pc_sel,
output reg [3:0] o_address_sel = 4'd2,
output reg [1:0] o_pc_sel = 2'd2,
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_reg_write_sel,
101,7 → 101,7
output reg o_write_data_wen = 'd0,
output reg o_base_address_wen = 'd0, // save LDM base address register
// in case of data abort
output wire o_pc_wen,
output reg o_pc_wen = 1'd1,
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,
114,10 → 114,10
// --------------------------------------------------
output reg [2:0] o_copro_opcode1 = 'd0,
output reg [2:0] o_copro_opcode2 = 'd0,
output reg [3:0] o_copro_crn = 'd0,
output reg [3:0] o_copro_crn = 'd0,
output reg [3:0] o_copro_crm = 'd0,
output reg [3:0] o_copro_num = 'd0,
output reg [1:0] o_copro_operation = 'd0, // 0 = no operation,
output reg [1:0] o_copro_operation = 'd0, // 0 = no operation,
// 1 = Move to Amber Core Register from Coprocessor
// 2 = Move to Coprocessor from Amber Core Register
output reg o_copro_write_data_wen = 'd0,
126,7 → 126,7
output [7:0] o_iabt_status,
output o_dabt_trigger,
output [31:0] o_dabt_address,
output [7:0] o_dabt_status
output [7:0] o_dabt_status
 
 
);
161,8 → 161,8
SWAP_WAIT1 = 5'd23,
SWAP_WAIT2 = 5'd24,
COPRO_WAIT = 5'd25;
 
 
// ========================================================
// Internal signals
// ========================================================
169,7 → 169,7
wire [31:0] instruction;
wire instruction_iabt; // abort 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
wire [7:0] instruction_iabt_status; // abort status, follows the instruction
wire [1:0] instruction_sel;
292,31 → 292,10
 
 
// ========================================================
// 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
// ========================================================
 
assign o_iabt_trigger = instruction_iabt && status_bits_mode_r == SVC && control_state == INT_WAIT1;
assign o_iabt_trigger = instruction_iabt && o_status_bits_mode == SVC && control_state == INT_WAIT1;
assign o_iabt_address = instruction_address;
assign o_iabt_status = instruction_iabt_status;
 
340,7 → 319,7
( control_state == MEM_WAIT1 ||
control_state == MEM_WAIT2 ||
control_state == MTRANS_EXEC1 ||
control_state == MTRANS_EXEC2 ||
control_state == MTRANS_EXEC2 ||
control_state == MTRANS_EXEC3 ||
control_state == MTRANS_EXEC3B ||
control_state == MTRANS_EXEC4 ||
359,9 → 338,9
assign use_pre_fetch_instruction = control_state == PRE_FETCH_EXEC;
 
 
assign instruction_sel = use_saved_current_instruction ? 2'd1 : // saved_current_instruction
use_pre_fetch_instruction ? 2'd2 : // pre_fetch_instruction
2'd0 ; // o_read_data
assign instruction_sel = use_saved_current_instruction ? 2'd1 : // saved_current_instruction
use_pre_fetch_instruction ? 2'd2 : // pre_fetch_instruction
2'd0 ; // o_read_data
 
assign instruction = instruction_sel == 2'd0 ? o_read_data :
instruction_sel == 2'd1 ? saved_current_instruction :
371,7 → 350,7
assign instruction_iabt = instruction_sel == 2'd0 ? iabt_reg :
instruction_sel == 2'd1 ? saved_current_instruction_iabt :
pre_fetch_instruction_iabt ;
 
assign instruction_address = instruction_sel == 2'd0 ? abt_address_reg :
instruction_sel == 2'd1 ? saved_current_instruction_address :
pre_fetch_instruction_address ;
391,25 → 370,25
12'b00010?001001 : itype = SWAP;
12'b000000??1001 : itype = MULT;
12'b00?????????? : itype = REGOP;
12'b01?????????? : itype = TRANS;
12'b100????????? : itype = MTRANS;
12'b101????????? : itype = BRANCH;
12'b01?????????? : itype = TRANS;
12'b100????????? : itype = MTRANS;
12'b101????????? : itype = BRANCH;
12'b110????????? : itype = CODTRANS;
12'b1110???????0 : itype = COREGOP;
12'b1110???????1 : itype = CORTRANS;
12'b1110???????0 : itype = COREGOP;
12'b1110???????1 : itype = CORTRANS;
default: itype = SWI;
endcase
 
 
// ========================================================
// Fixed fields within the instruction
// ========================================================
 
assign opcode = instruction[24:21];
assign condition_nxt = instruction[31:28];
 
assign o_rm_sel_nxt = instruction[3:0];
 
assign o_rn_sel_nxt = branch ? 4'd15 : // Use PC to calculate branch destination
instruction[19:16] ;
 
416,10 → 395,10
assign o_rds_sel_nxt = control_state == SWAP_WRITE ? instruction[3:0] : // Rm gets written out to memory
itype == MTRANS ? mtrans_reg :
branch ? 4'd15 : // Update the PC
rds_use_rs ? instruction[11:8] :
rds_use_rs ? instruction[11:8] :
instruction[15:12] ;
 
 
assign shift_imm = instruction[11:7];
 
// this is used for RRX
431,23 → 410,23
 
assign immediate_shifter_operand = instruction[25];
assign rds_use_rs = (itype == REGOP && !instruction[25] && instruction[4]) ||
(itype == MULT &&
(control_state == MULT_PROC1 ||
(itype == MULT &&
(control_state == MULT_PROC1 ||
control_state == MULT_PROC2 ||
instruction_valid && !interrupt )) ;
assign branch = itype == BRANCH;
assign opcode_compare =
opcode == CMP ||
opcode == CMN ||
opcode == TEQ ||
opcode == CMP ||
opcode == CMN ||
opcode == TEQ ||
opcode == TST ;
 
 
assign mem_op = itype == TRANS;
assign load_op = mem_op && instruction[20];
assign store_op = mem_op && !instruction[20];
assign write_pc = pc_wen_nxt && pc_sel_nxt != 2'd0;
assign regop_set_flags = itype == REGOP && instruction[20];
assign regop_set_flags = itype == REGOP && instruction[20];
 
assign mem_op_pre_indexed = instruction[24] && instruction[21];
assign mem_op_post_indexed = !instruction[24];
454,7 → 433,7
 
assign imm32_nxt = // add 0 to Rm
itype == MULT ? { 32'd0 } :
 
// 4 x number of registers
itype == MTRANS ? { mtrans_base_reg_change } :
itype == BRANCH ? { offset24 } :
479,25 → 458,25
 
assign imm_shift_amount_nxt = shift_imm ;
 
// This signal is encoded in the decode stage because
// This signal is encoded in the decode stage because
// it is on the critical path in the execute stage
assign shift_imm_zero_nxt = imm_shift_amount_nxt == 5'd0 && // immediate amount = 0
barrel_shift_amount_sel_nxt == 2'd2; // shift immediate amount
 
assign alu_function_nxt = { alu_swap_sel_nxt,
alu_not_sel_nxt,
assign alu_function_nxt = { alu_swap_sel_nxt,
alu_not_sel_nxt,
alu_cin_sel_nxt,
alu_cout_sel_nxt,
alu_cout_sel_nxt,
alu_out_sel_nxt };
 
 
// ========================================================
// MTRANS Operations
// ========================================================
 
// Bit 15 = r15
// Bit 0 = R0
// In LDM and STM instructions R0 is loaded or stored first
// In LDM and STM instructions R0 is loaded or stored first
always @*
casez (instruction[15:0])
16'b???????????????1 : mtrans_reg = 4'h0 ;
522,28 → 501,28
always @*
casez (instruction[15:0])
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?????????????100 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 3], 3'd0};
16'b????????????1000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 4], 4'd0};
16'b???????????10000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 5], 5'd0};
16'b??????????100000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 6], 6'd0};
16'b?????????1000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 7], 7'd0};
16'b????????10000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 8], 8'd0};
16'b???????100000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 9], 9'd0};
16'b??????1000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:10], 10'd0};
16'b?????10000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:11], 11'd0};
16'b????100000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:12], 12'd0};
16'b???1000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:13], 13'd0};
16'b??10000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:14], 14'd0};
16'b?100000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15 ], 15'd0};
default : mtrans_instruction_nxt = {instruction[31:16], 16'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????????????1000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 4], 4'd0};
16'b???????????10000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 5], 5'd0};
16'b??????????100000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 6], 6'd0};
16'b?????????1000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 7], 7'd0};
16'b????????10000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 8], 8'd0};
16'b???????100000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 9], 9'd0};
16'b??????1000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:10], 10'd0};
16'b?????10000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:11], 11'd0};
16'b????100000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:12], 12'd0};
16'b???1000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:13], 13'd0};
16'b??10000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:14], 14'd0};
16'b?100000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15 ], 15'd0};
default : mtrans_instruction_nxt = {instruction[31:16], 16'd0};
endcase
 
 
// number of registers to be stored
assign mtrans_num_registers = {4'd0, instruction[15]} +
{4'd0, instruction[14]} +
{4'd0, instruction[13]} +
assign mtrans_num_registers = {4'd0, instruction[15]} +
{4'd0, instruction[14]} +
{4'd0, instruction[13]} +
{4'd0, instruction[12]} +
{4'd0, instruction[11]} +
{4'd0, instruction[10]} +
557,7 → 536,7
{4'd0, instruction[ 2]} +
{4'd0, instruction[ 1]} +
{4'd0, instruction[ 0]} ;
 
// 4 x number of registers to be stored
assign mtrans_base_reg_change = {25'd0, mtrans_num_registers, 2'd0};
 
571,15 → 550,15
assign dabt_request = dabt_reg;
 
// 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
assign und_request = itype == CODTRANS ||
itype == COREGOP ||
assign und_request = itype == CODTRANS ||
itype == COREGOP ||
( itype == CORTRANS && instruction[11:8] != 4'd15 );
 
 
// in order of priority !!
// Highest
// in order of priority !!
// Highest
// 1 Reset
// 2 Data Abort (including data TLB miss)
// 3 FIRQ
586,21 → 565,21
// 4 IRQ
// 5 Prefetch Abort (including prefetch TLB miss)
// 6 Undefined instruction, SWI
// Lowest
// Lowest
assign next_interrupt = dabt_request ? 3'd1 : // Data Abort
firq_request ? 3'd2 : // FIRQ
irq_request ? 3'd3 : // IRQ
instruction_adex ? 3'd4 : // Address Exception
instruction_iabt ? 3'd5 : // PreFetch Abort, only triggered
instruction_adex ? 3'd4 : // Address Exception
instruction_iabt ? 3'd5 : // PreFetch Abort, only triggered
// if the instruction is used
und_request ? 3'd6 : // Undefined Instruction
swi_request ? 3'd7 : // SWI
3'd0 ; // none
3'd0 ; // none
 
// SWI and undefined instructions do not cause an interrupt in the decode
// stage. They only trigger interrupts if they arfe executed, so the
// interrupt is triggered if the execute condition is met in the execute stage
assign interrupt = next_interrupt != 3'd0 &&
assign interrupt = next_interrupt != 3'd0 &&
next_interrupt != 3'd7 && // SWI
next_interrupt != 3'd6 ; // undefined interrupt
 
625,18 → 604,18
// default mode
status_bits_mode_nxt = i_execute_status_bits[1:0]; // change to mode in execute stage get reflected
// back to this stage automatically
status_bits_irq_mask_nxt = status_bits_irq_mask_r;
status_bits_firq_mask_nxt = status_bits_firq_mask_r;
status_bits_irq_mask_nxt = o_status_bits_irq_mask;
status_bits_firq_mask_nxt = o_status_bits_firq_mask;
exclusive_exec_nxt = 1'd0;
data_access_exec_nxt = 1'd0;
copro_operation_nxt = 'd0;
 
// Save an instruction to use later
saved_current_instruction_wen = 1'd0;
pre_fetch_instruction_wen = 1'd0;
mtrans_r15_nxt = mtrans_r15;
restore_base_address_nxt = restore_base_address;
 
// default Mux Select values
barrel_shift_amount_sel_nxt = 'd0; // don't shift the input
barrel_shift_data_sel_nxt = 'd0; // immediate value
643,21 → 622,21
barrel_shift_function_nxt = 'd0;
use_carry_in_nxt = 'd0;
multiply_function_nxt = 'd0;
address_sel_nxt = 'd0;
pc_sel_nxt = 'd0;
byte_enable_sel_nxt = 'd0;
status_bits_sel_nxt = 'd0;
reg_write_sel_nxt = 'd0;
address_sel_nxt = 'd0;
pc_sel_nxt = 'd0;
byte_enable_sel_nxt = 'd0;
status_bits_sel_nxt = 'd0;
reg_write_sel_nxt = 'd0;
user_mode_regs_load_nxt = 'd0;
o_user_mode_regs_store_nxt = 'd0;
 
o_user_mode_regs_store_nxt = 'd0;
// ALU Muxes
alu_swap_sel_nxt = 'd0;
alu_not_sel_nxt = 'd0;
alu_cin_sel_nxt = 'd0;
alu_cout_sel_nxt = 'd0;
alu_out_sel_nxt = 'd0;
 
alu_swap_sel_nxt = 'd0;
alu_not_sel_nxt = 'd0;
alu_cin_sel_nxt = 'd0;
alu_cout_sel_nxt = 'd0;
alu_out_sel_nxt = 'd0;
// default Flop Write Enable values
write_data_wen_nxt = 'd0;
copro_write_data_wen_nxt = 'd0;
668,7 → 647,7
status_bits_mode_wen_nxt = 'd0;
status_bits_irq_mask_wen_nxt = 'd0;
status_bits_firq_mask_wen_nxt = 'd0;
 
if ( instruction_valid && !interrupt )
begin
if ( itype == REGOP )
681,24 → 660,24
pc_sel_nxt = 2'd1; // alu_out
address_sel_nxt = 4'd1; // alu_out
end
else
else
reg_bank_wsel_nxt = instruction[15:12];
end
 
if ( !immediate_shifter_operand )
barrel_shift_function_nxt = instruction[6:5];
 
if ( !immediate_shifter_operand )
barrel_shift_data_sel_nxt = 2'd2; // Shift value from Rm register
 
if ( !immediate_shifter_operand && instruction[4] )
barrel_shift_amount_sel_nxt = 2'd1; // Shift amount from Rs registter
 
if ( !immediate_shifter_operand && !instruction[4] )
barrel_shift_amount_sel_nxt = 2'd2; // Shift immediate amount
 
if ( !immediate_shifter_operand && !instruction[4] )
barrel_shift_amount_sel_nxt = 2'd2; // Shift immediate amount
// regops that do not change the overflow flag
if ( opcode == AND || opcode == EOR || opcode == TST || opcode == TEQ ||
if ( opcode == AND || opcode == EOR || opcode == TST || opcode == TEQ ||
opcode == ORR || opcode == MOV || opcode == BIC || opcode == MVN )
status_bits_sel_nxt = 3'd5;
 
707,7 → 686,7
alu_out_sel_nxt = 4'd1; // Add
use_carry_in_nxt = shift_extend;
end
 
if ( opcode == ADC ) // Add with Carry
begin
alu_out_sel_nxt = 4'd1; // Add
714,7 → 693,7
alu_cin_sel_nxt = 2'd2; // carry in from status_bits
use_carry_in_nxt = shift_extend;
end
 
if ( opcode == SUB || opcode == CMP ) // Subtract
begin
alu_out_sel_nxt = 4'd1; // Add
721,8 → 700,8
alu_cin_sel_nxt = 2'd1; // cin = 1
alu_not_sel_nxt = 1'd1; // invert B
end
 
// SBC (Subtract with Carry) subtracts the value of its
// SBC (Subtract with Carry) subtracts the value of its
// second operand and the value of NOT(Carry flag) from
// the value of its first operand.
// Rd = Rn - shifter_operand - NOT(C Flag)
733,7 → 712,7
alu_not_sel_nxt = 1'd1; // invert B
use_carry_in_nxt = 1'd1;
end
 
if ( opcode == RSB ) // Reverse Subtract
begin
alu_out_sel_nxt = 4'd1; // Add
741,7 → 720,7
alu_not_sel_nxt = 1'd1; // invert B
alu_swap_sel_nxt = 1'd1; // swap A and B
end
 
if ( opcode == RSC ) // Reverse Subtract with carry
begin
alu_out_sel_nxt = 4'd1; // Add
750,13 → 729,13
alu_swap_sel_nxt = 1'd1; // swap A and B
use_carry_in_nxt = 1'd1;
end
 
if ( opcode == AND || opcode == TST ) // Logical AND, Test (using AND operator)
begin
alu_out_sel_nxt = 4'd8; // AND
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
end
 
if ( opcode == EOR || opcode == TEQ ) // Logical Exclusive OR, Test Equivalence (using EOR operator)
begin
alu_out_sel_nxt = 4'd6; // XOR
770,7 → 749,7
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
use_carry_in_nxt = 1'd1;
end
 
if ( opcode == BIC ) // Bit Clear (using AND & NOT operators)
begin
alu_out_sel_nxt = 4'd8; // AND
778,13 → 757,13
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
use_carry_in_nxt = 1'd1;
end
 
if ( opcode == MOV ) // Move
begin
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
use_carry_in_nxt = 1'd1;
end
 
if ( opcode == MVN ) // Move NOT
begin
alu_not_sel_nxt = 1'd1; // invert B
792,22 → 771,22
use_carry_in_nxt = 1'd1;
end
end
 
// Load & Store instructions
if ( mem_op )
begin
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
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
alu_out_sel_nxt = 4'd1; // Add
 
if ( !instruction[23] ) // U: Subtract offset
begin
alu_cin_sel_nxt = 2'd1; // cin = 1
alu_not_sel_nxt = 1'd1; // invert B
end
 
if ( store_op )
begin
write_data_wen_nxt = 1'd1;
814,7 → 793,7
if ( itype == TRANS && instruction[22] )
byte_enable_sel_nxt = 2'd1; // Save byte
end
 
// need to update the register holding the address ?
// This is Rn bits [19:16]
if ( mem_op_pre_indexed || mem_op_post_indexed )
821,33 → 800,33
begin
// Check is the load destination is the PC
if ( o_rn_sel_nxt == 4'd15 )
pc_sel_nxt = 2'd1;
else
pc_sel_nxt = 2'd1;
else
reg_bank_wsel_nxt = o_rn_sel_nxt;
end
 
// if post-indexed, then use Rn rather than ALU output, as address
if ( mem_op_post_indexed )
address_sel_nxt = 4'd4; // Rn
else
else
address_sel_nxt = 4'd1; // alu out
 
if ( instruction[25] && itype == TRANS )
barrel_shift_data_sel_nxt = 2'd2; // Shift value from Rm register
 
if ( itype == TRANS && instruction[25] && shift_imm != 5'd0 )
begin
if ( itype == TRANS && instruction[25] && shift_imm != 5'd0 )
begin
barrel_shift_function_nxt = instruction[6:5];
barrel_shift_amount_sel_nxt = 2'd2; // imm_shift_amount
end
end
 
if ( itype == BRANCH )
begin
pc_sel_nxt = 2'd1; // alu_out
address_sel_nxt = 4'd1; // alu_out
alu_out_sel_nxt = 4'd1; // Add
 
if ( instruction[24] ) // Link
begin
reg_bank_wsel_nxt = 4'd14; // Save PC to LR
854,23 → 833,23
reg_write_sel_nxt = 3'd1; // pc - 32'd4
end
end
 
if ( itype == MTRANS )
begin
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
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
alu_out_sel_nxt = 4'd1; // Add
mtrans_r15_nxt = instruction[15]; // load or save r15 ?
base_address_wen_nxt = 1'd1; // Save the value of the register used for the base address,
// in case of a data abort, and need to restore the value
// in case of a data abort, and need to restore the value
 
// The spec says -
// If the instruction would have overwritten the base with data
// If the instruction would have overwritten the base with data
// (that is, it has the base in the transfer list), the overwriting is prevented.
// This is true even when the abort occurs after the base word gets loaded
restore_base_address_nxt = instruction[20] &&
restore_base_address_nxt = instruction[20] &&
(instruction[15:0] & (1'd1 << instruction[19:16]));
 
// Increment or Decrement
878,7 → 857,7
begin
if ( instruction[24] ) // increment before
address_sel_nxt = 4'd7; // Rn + 4
else
else
address_sel_nxt = 4'd4; // Rn
end
else // decrement
890,47 → 869,47
else
address_sel_nxt = 4'd1; // alu out
end
 
// Load or store ?
if ( !instruction[20] ) // Store
write_data_wen_nxt = 1'd1;
 
// LDM: load into user mode registers, when in priviledged mode
// Don't use mtrans_r15 here because its not loaded yet
write_data_wen_nxt = 1'd1;
// LDM: load into user mode registers, when in priviledged mode
// Don't use mtrans_r15 here because its not loaded yet
//if ( {instruction[22],instruction[20],instruction[15]} == 3'b110 )
if ( {instruction[22:20],instruction[15]} == 4'b1010 )
if ( {instruction[22:20],instruction[15]} == 4'b1010 )
user_mode_regs_load_nxt = 1'd1;
 
// SDM: store the user mode registers, when in priviledged mode
//if ( {instruction[22],instruction[20]} == 3'b10 )
// SDM: store the user mode registers, when in priviledged mode
//if ( {instruction[22],instruction[20]} == 3'b10 )
if ( {instruction[22:20]} == 3'b100 )
o_user_mode_regs_store_nxt = 1'd1;
 
// update the base register ?
if ( instruction[21] ) // the W bit
reg_bank_wsel_nxt = o_rn_sel_nxt;
end
 
 
if ( itype == MULT )
begin
multiply_function_nxt[0] = 1'd1; // set enable
// 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
pc_wen_nxt = 1'd0; // hold current PC value
 
if ( instruction[21] )
multiply_function_nxt[1] = 1'd1; // accumulate
end
 
 
// swp - do read part first
if ( itype == SWAP )
begin
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
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
barrel_shift_data_sel_nxt = 2'd2; // Shift value from Rm register
address_sel_nxt = 4'd4; // Rn
944,7 → 923,7
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
address_sel_nxt = 4'd3; // pc (not pc + 4)
 
if ( instruction[20] ) // MRC
copro_operation_nxt = 2'd1; // Register transfer from Co-Processor
else // MCR
956,35 → 935,35
end
end
 
 
if ( itype == SWI || und_request )
begin
// save address of next instruction to Supervisor Mode LR
reg_write_sel_nxt = 3'd1; // pc -4
reg_bank_wsel_nxt = 4'd14; // LR
 
address_sel_nxt = 4'd2; // interrupt_vector
pc_sel_nxt = 2'd2; // interrupt_vector
 
status_bits_mode_nxt = interrupt_mode; // e.g. Supervisor mode
status_bits_mode_wen_nxt = 1'd1;
 
// disable normal interrupts
status_bits_irq_mask_nxt = 1'd1;
status_bits_irq_mask_wen_nxt = 1'd1;
end
 
 
if ( regop_set_flags )
begin
status_bits_flags_wen_nxt = 1'd1;
 
// If <Rd> is r15, the ALU output is copied to the Status Bits.
// Not allowed to use r15 for mul or lma instructions
// If <Rd> is r15, the ALU output is copied to the Status Bits.
// Not allowed to use r15 for mul or lma instructions
if ( instruction[15:12] == 4'd15 )
begin
status_bits_sel_nxt = 3'd1; // alu out
 
// Priviledged mode? Then also update the other status bits
if ( i_execute_status_bits[1:0] != USR )
begin
994,9 → 973,9
end
end
end
end
 
end
 
// Handle asynchronous interrupts.
// interrupts are processed only during execution states
// multicycle instructions must complete before the interrupt starts
1008,8 → 987,8
// Save the interrupt causing instruction to refer back to later
// This also saves the instruction abort vma and status, in the case of an
// instruction abort interrupt
saved_current_instruction_wen = 1'd1;
 
saved_current_instruction_wen = 1'd1;
// save address of next instruction to Supervisor Mode LR
// Address Exception ?
if ( next_interrupt == 3'd4 )
1016,15 → 995,15
reg_write_sel_nxt = 3'd7; // pc
else
reg_write_sel_nxt = 3'd1; // pc -4
 
reg_bank_wsel_nxt = 4'd14; // LR
 
address_sel_nxt = 4'd2; // interrupt_vector
pc_sel_nxt = 2'd2; // interrupt_vector
 
status_bits_mode_nxt = interrupt_mode; // e.g. Supervisor mode
status_bits_mode_wen_nxt = 1'd1;
 
// disable normal interrupts
status_bits_irq_mask_nxt = 1'd1;
status_bits_irq_mask_wen_nxt = 1'd1;
1036,16 → 1015,16
status_bits_firq_mask_wen_nxt = 1'd1;
end
end
 
 
// previous instruction was either ldr or sdr
// if it is currently executing in the execute stage do the following
// if it is currently executing in the execute stage do the following
if ( control_state == MEM_WAIT1 )
begin
// Save the next instruction to execute later
// Do this even if this instruction does not execute because of Condition
pre_fetch_instruction_wen = 1'd1;
 
if ( instruction_execute ) // conditional execution state
begin
address_sel_nxt = 4'd3; // pc (not pc + 4)
1052,24 → 1031,24
pc_wen_nxt = 1'd0; // hold current PC value
end
end
 
 
// completion of load operation
// completion of load operation
if ( control_state == MEM_WAIT2 && load_op )
begin
barrel_shift_data_sel_nxt = 2'd1; // load word from memory
barrel_shift_amount_sel_nxt = 2'd3; // shift by address[1:0] x 8
 
// shift needed
if ( i_execute_address[1:0] != 2'd0 )
barrel_shift_function_nxt = ROR;
 
// load a byte
// load a byte
if ( itype == TRANS && instruction[22] )
alu_out_sel_nxt = 4'd3; // zero_extend8
 
if ( !dabt ) // dont load data there is an abort on the data read
begin
begin
// Check if the load destination is the PC
if (instruction[15:12] == 4'd15)
begin
1076,12 → 1055,12
pc_sel_nxt = 2'd1; // alu_out
address_sel_nxt = 4'd1; // alu_out
end
else
else
reg_bank_wsel_nxt = instruction[15:12];
end
end
 
 
// second cycle of multiple load or store
if ( control_state == MTRANS_EXEC1 )
begin
1088,39 → 1067,39
// Save the next instruction to execute later
// Do this even if this instruction does not execute because of Condition
pre_fetch_instruction_wen = 1'd1;
 
if ( instruction_execute ) // conditional execution state
begin
address_sel_nxt = 4'd5; // o_address
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
 
if ( !instruction[20] ) // Store
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:20],mtrans_r15} == 4'b1010 )
user_mode_regs_load_nxt = 1'd1;
 
// SDM: store the user mode registers, when in priviledged mode
//if ( {instruction[22],instruction[20]} == 2'b10 )
// SDM: store the user mode registers, when in priviledged mode
//if ( {instruction[22],instruction[20]} == 2'b10 )
if ( {instruction[22:20]} == 3'b100 )
o_user_mode_regs_store_nxt = 1'd1;
end
end
 
 
end
end
// third cycle of multiple load or store
if ( control_state == MTRANS_EXEC2 )
begin
address_sel_nxt = 4'd5; // o_address
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
barrel_shift_data_sel_nxt = 2'd1; // load word from memory
 
// Load or Store
if ( instruction[20] ) // Load
begin
1131,17 → 1110,17
end
else // Store
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 )
user_mode_regs_load_nxt = 1'd1;
 
// SDM: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 2'b10 )
// SDM: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 2'b10 )
o_user_mode_regs_store_nxt = 1'd1;
end
 
 
// second or fourth cycle of multiple load or store
if ( control_state == MTRANS_EXEC3 && instruction_execute )
begin
1148,19 → 1127,19
address_sel_nxt = 4'd3; // pc (not pc + 4)
pc_wen_nxt = 1'd0; // hold current PC value
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
// the last register in the set to be loaded
if ( instruction[20] && !dabt ) // Load
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],instruction[20],mtrans_r15} == 3'b110 )
user_mode_regs_load_nxt = 1'd1;
 
// SDM: store the user mode registers, when in priviledged mode
//if ( {instruction[22:20]} == 3'b100 )
if ( {instruction[22],instruction[20]} == 2'b10 )
// SDM: store the user mode registers, when in priviledged mode
//if ( {instruction[22:20]} == 3'b100 )
if ( {instruction[22],instruction[20]} == 2'b10 )
o_user_mode_regs_store_nxt = 1'd1;
end
 
1170,23 → 1149,23
// Save the next instruction to execute later
// Do this even if this instruction does not execute because of Condition
pre_fetch_instruction_wen = 1'd1;
 
address_sel_nxt = 4'd3; // pc (not pc + 4)
pc_wen_nxt = 1'd0; // hold current PC value
 
// 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 )
user_mode_regs_load_nxt = 1'd1;
 
// SDM: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 2'b10 )
// SDM: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 2'b10 )
o_user_mode_regs_store_nxt = 1'd1;
end
 
if ( control_state == MTRANS_EXEC4 )
begin
barrel_shift_data_sel_nxt = 2'd1; // load word from memory
 
if ( instruction[20] ) // Load
begin
if (!dabt) // dont overwrite registers or status if theres a data abort
1196,18 → 1175,18
address_sel_nxt = 4'd1; // alu_out - read instructions using new PC value
pc_sel_nxt = 2'd1; // alu_out
pc_wen_nxt = 1'd1; // write PC
 
// ldm with S bit and pc: the Status bits are updated
// Node this must be done only at the end
// so the register set is the set in the mode before it
// gets changed.
if ( instruction[22] )
// gets changed.
if ( instruction[22] )
begin
status_bits_sel_nxt = 3'd1; // alu out
status_bits_flags_wen_nxt = 1'd1;
 
// Can't change the mode or mask bits in User mode
if ( i_execute_status_bits[1:0] != USR )
if ( i_execute_status_bits[1:0] != USR )
begin
status_bits_mode_wen_nxt = 1'd1;
status_bits_irq_mask_wen_nxt = 1'd1;
1221,23 → 1200,23
end
end
end
 
// we have a data abort interrupt
if ( dabt )
begin
begin
pc_wen_nxt = 1'd0; // hold current PC value
end
 
// 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 )
user_mode_regs_load_nxt = 1'd1;
 
// SDM: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 2'b10 )
// SDM: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 2'b10 )
o_user_mode_regs_store_nxt = 1'd1;
end
 
 
// state is for when a data abort interrupt is triggered during an LDM
if ( control_state == MTRANS5_ABORT )
begin
1249,8 → 1228,8
reg_bank_wsel_nxt = instruction[19:16]; // to Rn
end
end
 
 
// Multiply or Multiply-Accumulate
if ( control_state == MULT_PROC1 && instruction_execute )
begin
1261,7 → 1240,7
multiply_function_nxt = o_multiply_function;
end
 
 
// Multiply or Multiply-Accumulate
// Do multiplication
// Wait for done or accumulate signal
1274,7 → 1253,7
multiply_function_nxt = o_multiply_function;
end
 
 
// Save RdLo
// always last cycle of all multiply or multiply accumulate operations
if ( control_state == MULT_STORE )
1281,19 → 1260,19
begin
reg_write_sel_nxt = 3'd2; // multiply_out
multiply_function_nxt = o_multiply_function;
 
if ( itype == MULT ) // 32-bit
reg_bank_wsel_nxt = instruction[19:16]; // Rd
else // 64-bit / Long
reg_bank_wsel_nxt = instruction[15:12]; // RdLo
 
if ( instruction[20] ) // the 'S' bit
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;
end
end
 
// Add lower 32 bits to multiplication product
if ( control_state == MULT_ACCUMU )
begin
1301,7 → 1280,7
pc_wen_nxt = 1'd0; // hold current PC value
address_sel_nxt = 4'd3; // pc (not pc + 4)
end
 
// swp - do write request in 2nd cycle
if ( control_state == SWAP_WRITE && instruction_execute )
begin
1308,44 → 1287,44
barrel_shift_data_sel_nxt = 2'd2; // Shift value from Rm register
address_sel_nxt = 4'd4; // Rn
write_data_wen_nxt = 1'd1;
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
 
if ( instruction[22] )
byte_enable_sel_nxt = 2'd1; // Save byte
 
if ( instruction_execute ) // conditional execution state
pc_wen_nxt = 1'd0; // hold current PC value
 
// Save the next instruction to execute later
// Do this even if this instruction does not execute because of Condition
pre_fetch_instruction_wen = 1'd1;
 
end
 
 
// swp - receive read response in 3rd cycle
if ( control_state == SWAP_WAIT1 )
if ( control_state == SWAP_WAIT1 )
begin
barrel_shift_data_sel_nxt = 2'd1; // load word from memory
barrel_shift_amount_sel_nxt = 2'd3; // shift by address[1:0] x 8
 
// shift needed
if ( i_execute_address[1:0] != 2'd0 )
barrel_shift_function_nxt = ROR;
 
if ( instruction_execute ) // conditional execution state
begin
address_sel_nxt = 4'd3; // pc (not pc + 4)
pc_wen_nxt = 1'd0; // hold current PC value
end
 
// load a byte
// load a byte
if ( instruction[22] )
alu_out_sel_nxt = 4'd3; // zero_extend8
 
if ( !dabt )
begin
begin
// Check is the load destination is the PC
if ( instruction[15:12] == 4'd15 )
begin
1352,26 → 1331,26
pc_sel_nxt = 2'd1; // alu_out
address_sel_nxt = 4'd1; // alu_out
end
else
else
reg_bank_wsel_nxt = instruction[15:12];
end
end
 
// 1 cycle delay for Co-Processor Register access
if ( control_state == COPRO_WAIT && instruction_execute )
begin
pre_fetch_instruction_wen = 1'd1;
 
if ( instruction[20] ) // mrc instruction
begin
// Check is the load destination is the PC
if ( instruction[15:12] == 4'd15 )
begin
// If r15 is specified for <Rd>, the condition code flags are
// If r15 is specified for <Rd>, the condition code flags are
// updated instead of a general-purpose register.
status_bits_sel_nxt = 3'd3; // i_copro_data
status_bits_flags_wen_nxt = 1'd1;
 
// Can't change these in USR mode
if ( i_execute_status_bits[1:0] != USR )
begin
1380,25 → 1359,25
status_bits_firq_mask_wen_nxt = 1'd1;
end
end
else
else
reg_bank_wsel_nxt = instruction[15:12];
 
reg_write_sel_nxt = 3'd5; // i_copro_data
end
else // mcr instruction
begin
copro_operation_nxt = 2'd2; // Register transfer to Co-Processor
end
copro_operation_nxt = 2'd2; // Register transfer to Co-Processor
end
end
 
 
// Have just changed the status_bits mode but this
// creates a 1 cycle gap with the old mode
// coming back from execute into instruction_decode
// So squash that old mode value during this
// cycle of the interrupt transition
if ( control_state == INT_WAIT1 )
status_bits_mode_nxt = status_bits_mode_r; // Supervisor mode
// cycle of the interrupt transition
if ( control_state == INT_WAIT1 )
status_bits_mode_nxt = o_status_bits_mode; // Supervisor mode
 
end
 
1413,12 → 1392,12
// ========================================================
 
// this replicates the current value of the execute signal in the execute stage
assign instruction_execute = conditional_execute ( condition_r, i_execute_status_bits[31:28] );
assign instruction_execute = conditional_execute ( o_condition, i_execute_status_bits[31:28] );
 
assign instruction_valid = (control_state == EXECUTE || control_state == PRE_FETCH_EXEC) ||
// when last instruction was multi-cycle instruction but did not execute
// 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 ||
control_state == MEM_WAIT1 ||
control_state == COPRO_WAIT ||
control_state == SWAP_WRITE ||
1432,7 → 1411,7
begin
// default is to hold the current state
control_state_nxt = control_state;
 
// Note: The order is important here
if ( control_state == RST_WAIT1 ) control_state_nxt = RST_WAIT2;
if ( control_state == RST_WAIT2 ) control_state_nxt = EXECUTE;
1440,39 → 1419,39
if ( control_state == INT_WAIT2 ) control_state_nxt = EXECUTE;
if ( control_state == COPRO_WAIT ) control_state_nxt = PRE_FETCH_EXEC;
if ( control_state == PC_STALL1 ) control_state_nxt = PC_STALL2;
if ( control_state == PC_STALL2 ) control_state_nxt = EXECUTE;
if ( control_state == SWAP_WRITE ) control_state_nxt = SWAP_WAIT1;
if ( control_state == SWAP_WAIT1 ) control_state_nxt = SWAP_WAIT2;
if ( control_state == MULT_STORE ) control_state_nxt = PRE_FETCH_EXEC;
if ( control_state == PC_STALL2 ) control_state_nxt = EXECUTE;
if ( control_state == SWAP_WRITE ) control_state_nxt = SWAP_WAIT1;
if ( control_state == SWAP_WAIT1 ) control_state_nxt = SWAP_WAIT2;
if ( control_state == MULT_STORE ) control_state_nxt = PRE_FETCH_EXEC;
if ( control_state == MTRANS5_ABORT ) control_state_nxt = PRE_FETCH_EXEC;
 
if ( control_state == MEM_WAIT1 )
control_state_nxt = MEM_WAIT2;
 
if ( control_state == MEM_WAIT2 ||
if ( control_state == MEM_WAIT2 ||
control_state == SWAP_WAIT2 )
begin
if ( write_pc ) // writing to the PC!!
if ( write_pc ) // writing to the PC!!
control_state_nxt = PC_STALL1;
else
control_state_nxt = PRE_FETCH_EXEC;
end
 
if ( control_state == MTRANS_EXEC1 )
begin
if ( control_state == MTRANS_EXEC1 )
begin
if (mtrans_instruction_nxt[15:0] != 16'd0)
control_state_nxt = MTRANS_EXEC2;
else // if the register list holds a single register
else // if the register list holds a single register
control_state_nxt = MTRANS_EXEC3;
end
 
// Stay in State MTRANS_EXEC2 until the full list of registers to
// load or store has been processed
if ( control_state == MTRANS_EXEC2 && mtrans_num_registers == 5'd1 )
control_state_nxt = MTRANS_EXEC3;
 
if ( control_state == MTRANS_EXEC3 ) control_state_nxt = MTRANS_EXEC4;
 
if ( control_state == MTRANS_EXEC3 ) control_state_nxt = MTRANS_EXEC4;
if ( control_state == MTRANS_EXEC3B ) control_state_nxt = MTRANS_EXEC4;
 
if ( control_state == MTRANS_EXEC4 )
1479,12 → 1458,12
begin
if ( dabt ) // data abort
control_state_nxt = MTRANS5_ABORT;
else if (write_pc) // writing to the PC!!
else if (write_pc) // writing to the PC!!
control_state_nxt = PC_STALL1;
else
control_state_nxt = PRE_FETCH_EXEC;
end
 
if ( control_state == MULT_PROC1 )
begin
if (!instruction_execute)
1492,23 → 1471,23
else
control_state_nxt = MULT_PROC2;
end
 
if ( control_state == MULT_PROC2 )
begin
if ( i_multiply_done )
if ( o_multiply_function[1] ) // Accumulate ?
control_state_nxt = MULT_ACCUMU;
else
else
control_state_nxt = MULT_STORE;
end
 
 
if ( control_state == MULT_ACCUMU )
begin
control_state_nxt = MULT_STORE;
end
 
 
// This should come at the end, so that conditional execution works
// correctly
if ( instruction_valid )
1516,10 → 1495,10
// default is to stay in execute state, or to move into this
// state from a conditional execute state
control_state_nxt = EXECUTE;
 
if ( mem_op ) // load or store word or byte
control_state_nxt = MEM_WAIT1;
if ( write_pc )
if ( write_pc )
control_state_nxt = PC_STALL1;
if ( itype == MTRANS )
begin
1531,7 → 1510,7
else
control_state_nxt = MTRANS_EXEC1;
end
else
else
control_state_nxt = MTRANS_EXEC3;
end
 
1538,14 → 1517,14
if ( itype == MULT )
control_state_nxt = MULT_PROC1;
 
if ( itype == SWAP )
if ( itype == SWAP )
control_state_nxt = SWAP_WRITE;
 
if ( itype == CORTRANS && !und_request )
if ( itype == CORTRANS && !und_request )
control_state_nxt = COPRO_WAIT;
 
// interrupt overrides everything else so its last
if ( interrupt )
// interrupt overrides everything else so its last
if ( interrupt )
control_state_nxt = INT_WAIT1;
end
end
1555,30 → 1534,30
// Register Update
// ========================================================
always @ ( posedge i_clk )
if (!i_fetch_stall)
begin
if (!i_fetch_stall)
begin
o_read_data <= i_read_data;
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;
iabt_reg <= i_iabt;
adex_reg <= i_adex;
abt_status_reg <= i_abt_status;
status_bits_mode_r <= status_bits_mode_nxt;
status_bits_irq_mask_r <= status_bits_irq_mask_nxt;
status_bits_firq_mask_r <= status_bits_firq_mask_nxt;
o_status_bits_mode <= status_bits_mode_nxt;
o_status_bits_irq_mask <= status_bits_irq_mask_nxt;
o_status_bits_firq_mask <= status_bits_firq_mask_nxt;
o_imm32 <= imm32_nxt;
o_imm_shift_amount <= imm_shift_amount_nxt;
o_shift_imm_zero <= shift_imm_zero_nxt;
 
// when have an interrupt, execute the interrupt operation
// unconditionally in the execute stage
// ensures that status_bits register gets updated correctly
// Likewise when in middle of multi-cycle instructions
// execute them unconditionally
condition_r <= instruction_valid && !interrupt ? condition_nxt : AL;
o_condition <= instruction_valid && !interrupt ? condition_nxt : AL;
o_exclusive_exec <= exclusive_exec_nxt;
o_data_access_exec <= data_access_exec_nxt;
 
o_rm_sel <= o_rm_sel_nxt;
o_rds_sel <= o_rds_sel_nxt;
o_rn_sel <= o_rn_sel_nxt;
1589,8 → 1568,8
o_use_carry_in <= use_carry_in_nxt;
o_multiply_function <= multiply_function_nxt;
o_interrupt_vector_sel <= next_interrupt;
address_sel_r <= address_sel_nxt;
pc_sel_r <= pc_sel_nxt;
o_address_sel <= address_sel_nxt;
o_pc_sel <= pc_sel_nxt;
o_byte_enable_sel <= byte_enable_sel_nxt;
o_status_bits_sel <= status_bits_sel_nxt;
o_reg_write_sel <= reg_write_sel_nxt;
1598,7 → 1577,7
o_firq_not_user_mode <= firq_not_user_mode_nxt;
o_write_data_wen <= write_data_wen_nxt;
o_base_address_wen <= base_address_wen_nxt;
pc_wen_r <= pc_wen_nxt;
o_pc_wen <= pc_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;
1605,7 → 1584,7
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_firq_mask_wen <= status_bits_firq_mask_wen_nxt;
 
o_copro_opcode1 <= instruction[23:21];
o_copro_opcode2 <= instruction[7:5];
o_copro_crn <= instruction[19:16];
1631,7 → 1610,7
// then when its decoded, a copy is saved to the saved_current_instruction
// register
if (itype == MTRANS)
begin
begin
saved_current_instruction <= mtrans_instruction_nxt;
saved_current_instruction_iabt <= instruction_iabt;
saved_current_instruction_adex <= instruction_adex;
1638,8 → 1617,8
saved_current_instruction_address <= instruction_address;
saved_current_instruction_iabt_status <= instruction_iabt_status;
end
else if (saved_current_instruction_wen)
begin
else if (saved_current_instruction_wen)
begin
saved_current_instruction <= instruction;
saved_current_instruction_iabt <= instruction_iabt;
saved_current_instruction_adex <= instruction_adex;
1647,36 → 1626,36
saved_current_instruction_iabt_status <= instruction_iabt_status;
end
 
if (pre_fetch_instruction_wen)
if (pre_fetch_instruction_wen)
begin
pre_fetch_instruction <= o_read_data;
pre_fetch_instruction_iabt <= iabt_reg;
pre_fetch_instruction_adex <= adex_reg;
pre_fetch_instruction_address <= abt_address_reg;
pre_fetch_instruction_iabt_status <= abt_status_reg;
end
pre_fetch_instruction <= o_read_data;
pre_fetch_instruction_iabt <= iabt_reg;
pre_fetch_instruction_adex <= adex_reg;
pre_fetch_instruction_address <= abt_address_reg;
pre_fetch_instruction_iabt_status <= abt_status_reg;
end
end
 
 
 
always @ ( posedge i_clk )
if ( !i_fetch_stall )
begin
irq <= i_irq;
firq <= i_firq;
 
if ( control_state == INT_WAIT1 && status_bits_mode_r == SVC )
irq <= i_irq;
firq <= i_firq;
if ( control_state == INT_WAIT1 && o_status_bits_mode == SVC )
begin
dabt_reg <= 1'd0;
end
else
begin
dabt_reg <= dabt_reg || i_dabt;
dabt_reg <= dabt_reg || i_dabt;
end
dabt_reg_d1 <= dabt_reg;
end
 
dabt_reg_d1 <= dabt_reg;
end
 
assign dabt = dabt_reg || i_dabt;
 
 
1697,15 → 1676,15
.i_interrupt ( {3{interrupt}} & next_interrupt ),
.i_interrupt_state ( control_state == INT_WAIT2 ),
.i_instruction_undefined ( und_request ),
.i_pc_sel ( pc_sel_r ),
.i_pc_wen ( pc_wen_r ));
.i_pc_sel ( o_pc_sel ),
.i_pc_wen ( o_pc_wen )
);
 
 
 
wire [(15*8)-1:0] xCONTROL_STATE;
wire [(15*8)-1:0] xMODE;
 
assign xCONTROL_STATE =
assign xCONTROL_STATE =
control_state == RST_WAIT1 ? "RST_WAIT1" :
control_state == RST_WAIT2 ? "RST_WAIT2" :
 
1734,7 → 1713,7
control_state == COPRO_WAIT ? "COPRO_WAIT" :
"UNKNOWN " ;
 
assign xMODE = mode_name ( status_bits_mode_r );
assign xMODE = mode_name ( o_status_bits_mode );
 
always @( posedge i_clk )
if (control_state == EXECUTE && ((instruction[0] === 1'bx) || (instruction[31] === 1'bx)))
/trunk/hw/vlog/amber23/a23_execute.v
57,7 → 57,7
 
output reg [31:0] o_copro_write_data = 'd0,
output reg [31:0] o_write_data = 'd0,
output wire [31:0] o_address,
output reg [31:0] o_address = 32'hdead_dead,
output reg o_adex = 'd0, // Address Exception
output reg o_address_valid = 'd0, // Prevents the reset address value being a
// wishbone access
200,9 → 200,7
 
wire carry_in;
 
reg [31:0] address_r = 32'hdead_dead;
 
 
// ========================================================
// Status Bits in PC register
// ========================================================
266,11 → 264,10
// ========================================================
assign pc_plus4 = pc + 32'd4;
assign pc_minus4 = pc - 32'd4;
assign address_plus4 = address_r + 32'd4;
assign address_plus4 = o_address + 32'd4;
assign alu_plus4 = alu_out + 32'd4;
assign rn_plus4 = rn + 32'd4;
 
 
// ========================================================
// Barrel Shift Amount Select
// ========================================================
459,7 → 456,7
o_data_access <= data_access_update ? i_data_access_exec : o_data_access;
o_write_enable <= write_enable_update ? write_enable_nxt : o_write_enable;
o_write_data <= write_data_update ? write_data_nxt : o_write_data;
address_r <= address_update ? o_address_nxt : address_r;
o_address <= address_update ? o_address_nxt : o_address;
o_adex <= address_update ? adex_nxt : o_adex;
o_address_valid <= address_update ? 1'd1 : o_address_valid;
o_byte_enable <= byte_enable_update ? byte_enable_nxt : o_byte_enable;
475,9 → 472,7
status_bits_firq_mask <= status_bits_firq_mask_update ? status_bits_firq_mask_nxt : status_bits_firq_mask;
end
 
assign o_address = address_r;
 
 
// ========================================================
// Instantiate Barrel Shift
// ========================================================
/trunk/hw/vlog/amber25/a25_decode.v
64,13 → 64,13
output reg [31:0] o_imm32 = 'd0,
output reg [4:0] o_imm_shift_amount = 'd0,
output reg o_shift_imm_zero = 'd0,
output wire [3:0] o_condition,
output reg [3:0] o_condition = 4'he, // 4'he = al
output reg o_decode_exclusive = 'd0, // exclusive access request ( swap instruction )
output wire o_decode_iaccess, // Indicates an instruction access
output reg o_decode_iaccess = 1'd1, // Indicates an instruction access
output reg o_decode_daccess = 'd0, // Indicates a data access
output wire [1:0] o_status_bits_mode,
output wire o_status_bits_irq_mask,
output wire o_status_bits_firq_mask,
output reg [1:0] o_status_bits_mode = 2'b11, // SVC
output reg o_status_bits_irq_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_rs_sel = 'd0,
86,9 → 86,9
output reg [8:0] o_alu_function = 'd0,
output reg [1:0] o_multiply_function = 'd0,
output reg [2:0] o_interrupt_vector_sel = 'd0,
output wire [3:0] o_iaddress_sel,
output wire [3:0] o_daddress_sel,
output wire [2:0] o_pc_sel,
output reg [3:0] o_iaddress_sel = 4'd2,
output reg [3:0] o_daddress_sel = 4'd2,
output reg [2:0] o_pc_sel = 3'd2,
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_reg_write_sel,
99,7 → 99,7
output reg o_write_data_wen = 'd0,
output reg o_base_address_wen = 'd0, // save ldm base address register
// in case of data abort
output wire o_pc_wen,
output reg o_pc_wen = 1'd1,
output reg [14:0] o_reg_bank_wen = 'd0,
output reg o_status_bits_flags_wen = 'd0,
output reg o_status_bits_mode_wen = 'd0,
111,10 → 111,10
// --------------------------------------------------
output reg [2:0] o_copro_opcode1 = 'd0,
output reg [2:0] o_copro_opcode2 = 'd0,
output reg [3:0] o_copro_crn = 'd0,
output reg [3:0] o_copro_crn = 'd0,
output reg [3:0] o_copro_crm = 'd0,
output reg [3:0] o_copro_num = 'd0,
output reg [1:0] o_copro_operation = 'd0, // 0 = no operation,
output reg [1:0] o_copro_operation = 'd0, // 0 = no operation,
// 1 = Move to Amber Core Register from Coprocessor
// 2 = Move to Coprocessor from Amber Core Register
output reg o_copro_write_data_wen = 'd0,
159,8 → 159,8
SWAP_WAIT1 = 5'd18,
SWAP_WAIT2 = 5'd19,
COPRO_WAIT = 5'd20;
 
 
// ========================================================
// Internal signals
// ========================================================
168,7 → 168,7
wire [3:0] type; // regop, mem access etc.
wire instruction_iabt; // abort 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
wire [7:0] instruction_iabt_status; // abort status, follows the instruction
wire [1:0] instruction_sel;
310,8 → 310,8
wire [7:0] load_rd_nxt;
wire load_rd_byte;
wire ldm_user_mode;
wire ldm_status_bits;
wire ldm_flags;
wire ldm_status_bits;
wire ldm_flags;
wire [6:0] load_rd_d1_nxt;
reg [6:0] load_rd_d1 = 'd0; // MSB is the valid bit
 
341,37 → 341,12
reg rs_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
// ========================================================
 
assign o_iabt_trigger = instruction_iabt && status_bits_mode_r == SVC && control_state == INT_WAIT1;
assign o_iabt_trigger = instruction_iabt && o_status_bits_mode == SVC && control_state == INT_WAIT1;
assign o_iabt_address = instruction_address;
assign o_iabt_status = instruction_iabt_status;
 
395,7 → 370,7
( control_state == MEM_WAIT1 ||
control_state == MEM_WAIT2 ||
control_state == MTRANS_EXEC1 ||
control_state == MTRANS_EXEC2 ||
control_state == MTRANS_EXEC2 ||
control_state == MTRANS_ABORT ||
control_state == MULT_PROC1 ||
control_state == MULT_PROC2 ||
414,19 → 389,19
 
 
assign instruction_sel = use_hold_instruction ? 2'd3 : // hold_instruction
use_saved_current_instruction ? 2'd1 : // saved_current_instruction
use_pre_fetch_instruction ? 2'd2 : // pre_fetch_instruction
2'd0 ; // fetch_instruction_r
use_saved_current_instruction ? 2'd1 : // saved_current_instruction
use_pre_fetch_instruction ? 2'd2 : // pre_fetch_instruction
2'd0 ; // fetch_instruction_r
 
assign instruction = instruction_sel == 2'd0 ? fetch_instruction_r :
instruction_sel == 2'd1 ? saved_current_instruction :
instruction_sel == 2'd3 ? hold_instruction :
pre_fetch_instruction ;
 
assign type = instruction_sel == 2'd0 ? fetch_instruction_type_r :
instruction_sel == 2'd1 ? saved_current_instruction_type :
instruction_sel == 2'd3 ? hold_instruction_type :
pre_fetch_instruction_type ;
pre_fetch_instruction_type ;
 
// abort flag
assign instruction_iabt = instruction_sel == 2'd0 ? iabt_reg :
433,7 → 408,7
instruction_sel == 2'd1 ? saved_current_instruction_iabt :
instruction_sel == 2'd3 ? hold_instruction_iabt :
pre_fetch_instruction_iabt ;
 
assign instruction_address = instruction_sel == 2'd0 ? fetch_address_r :
instruction_sel == 2'd1 ? saved_current_instruction_address :
instruction_sel == 2'd3 ? hold_instruction_address :
450,11 → 425,11
instruction_sel == 2'd3 ? hold_instruction_adex :
pre_fetch_instruction_adex ;
 
 
// ========================================================
// Fixed fields within the instruction
// ========================================================
 
assign opcode = instruction[24:21];
assign condition_nxt = instruction[31:28];
 
463,7 → 438,7
assign rs_sel_nxt = control_state == SWAP_WRITE ? instruction[3:0] : // Rm gets written out to memory
type == MTRANS ? mtrans_reg1 :
branch ? 4'd15 : // Update the PC
rds_use_rs ? instruction[11:8] :
rds_use_rs ? instruction[11:8] :
instruction[15:12] ;
 
// Load from memory into registers
485,8 → 460,8
 
assign immediate_shift_op = instruction[25];
assign rds_use_rs = (type == REGOP && !instruction[25] && instruction[4]) ||
(type == MULT &&
(control_state == MULT_PROC1 ||
(type == MULT &&
(control_state == MULT_PROC1 ||
control_state == MULT_PROC2 ||
// instruction_valid && !interrupt )) ;
// remove the '!conflict' term from the interrupt logic used here
501,7 → 476,7
assign store_op = mem_op && !instruction[20];
assign write_pc = (pc_wen_nxt && pc_sel_nxt != 3'd0) || load_pc_r || load_pc_nxt;
assign current_write_pc = (pc_wen_nxt && pc_sel_nxt != 3'd0) || load_pc_nxt;
assign regop_set_flags = type == REGOP && instruction[20];
assign regop_set_flags = type == REGOP && instruction[20];
 
assign mem_op_pre_indexed = instruction[24] && instruction[21];
assign mem_op_post_indexed = !instruction[24];
508,7 → 483,7
 
assign imm32_nxt = // add 0 to Rm
type == MULT ? { 32'd0 } :
 
// 4 x number of registers
type == MTRANS ? { mtrans_base_reg_change } :
type == BRANCH ? { offset24 } :
533,17 → 508,17
 
assign imm_shift_amount_nxt = shift_imm ;
 
// This signal is encoded in the decode stage because
// This signal is encoded in the decode stage because
// it is on the critical path in the execute stage
assign shift_imm_zero_nxt = imm_shift_amount_nxt == 5'd0 && // immediate amount = 0
barrel_shift_amount_sel_nxt == 2'd2; // shift immediate amount
 
assign alu_function_nxt = { alu_swap_sel_nxt,
alu_not_sel_nxt,
assign alu_function_nxt = { alu_swap_sel_nxt,
alu_not_sel_nxt,
alu_cin_sel_nxt,
alu_cout_sel_nxt,
alu_cout_sel_nxt,
alu_out_sel_nxt };
 
// ========================================================
// Register Conflict Detection
// ========================================================
563,13 → 538,13
assign rd_conflict1 = instruction_execute && rd_valid && ( load_rd_d1_nxt[4] && instruction[15:12] == load_rd_d1_nxt[3:0] );
assign rd_conflict2 = instruction_execute_r && rd_valid && ( load_rd_d1 [4] && instruction[15:12] == load_rd_d1 [3:0] );
 
assign stm_conflict1a = instruction_execute && stm_valid && ( load_rd_d1_nxt[4] && mtrans_reg1 == load_rd_d1_nxt[3:0] );
assign stm_conflict1b = instruction_execute && stm_valid && ( load_rd_d1_nxt[4] && mtrans_reg2 == load_rd_d1_nxt[3:0] );
assign stm_conflict1a = instruction_execute && stm_valid && ( load_rd_d1_nxt[4] && mtrans_reg1 == load_rd_d1_nxt[3:0] );
assign stm_conflict1b = instruction_execute && stm_valid && ( load_rd_d1_nxt[4] && mtrans_reg2 == load_rd_d1_nxt[3:0] );
assign stm_conflict2a = instruction_execute_r && stm_valid && ( load_rd_d1 [4] && mtrans_reg1 == load_rd_d1 [3:0] );
assign stm_conflict2b = instruction_execute_r && stm_valid && ( load_rd_d1 [4] && mtrans_reg2 == load_rd_d1 [3:0] );
 
assign conflict1 = instruction_valid &&
(rn_conflict1 || rm_conflict1 || rs_conflict1 || rd_conflict1 ||
(rn_conflict1 || rm_conflict1 || rs_conflict1 || rd_conflict1 ||
stm_conflict1a || stm_conflict1b);
 
assign conflict2 = instruction_valid && (stm_conflict2a || stm_conflict2b);
598,10 → 573,10
// ========================================================
// MTRANS Operations
// ========================================================
 
// Bit 15 = r15
// Bit 0 = r0
// In ldm and stm instructions r0 is loaded or stored first
// In ldm and stm instructions r0 is loaded or stored first
always @*
casez ( instruction[15:0] )
16'b???????????????1 : mtrans_reg1 = 4'h0 ;
648,28 → 623,28
always @*
casez (instruction[15:0])
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?????????????100 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 3], 3'd0};
16'b????????????1000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 4], 4'd0};
16'b???????????10000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 5], 5'd0};
16'b??????????100000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 6], 6'd0};
16'b?????????1000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 7], 7'd0};
16'b????????10000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 8], 8'd0};
16'b???????100000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 9], 9'd0};
16'b??????1000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:10], 10'd0};
16'b?????10000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:11], 11'd0};
16'b????100000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:12], 12'd0};
16'b???1000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:13], 13'd0};
16'b??10000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:14], 14'd0};
16'b?100000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15 ], 15'd0};
default : mtrans_instruction_nxt = {instruction[31:16], 16'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????????????1000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 4], 4'd0};
16'b???????????10000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 5], 5'd0};
16'b??????????100000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 6], 6'd0};
16'b?????????1000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 7], 7'd0};
16'b????????10000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 8], 8'd0};
16'b???????100000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 9], 9'd0};
16'b??????1000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:10], 10'd0};
16'b?????10000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:11], 11'd0};
16'b????100000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:12], 12'd0};
16'b???1000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:13], 13'd0};
16'b??10000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:14], 14'd0};
16'b?100000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15 ], 15'd0};
default : mtrans_instruction_nxt = {instruction[31:16], 16'd0};
endcase
 
 
// number of registers to be stored
assign mtrans_num_registers = {4'd0, instruction[15]} +
{4'd0, instruction[14]} +
{4'd0, instruction[13]} +
assign mtrans_num_registers = {4'd0, instruction[15]} +
{4'd0, instruction[14]} +
{4'd0, instruction[13]} +
{4'd0, instruction[12]} +
{4'd0, instruction[11]} +
{4'd0, instruction[10]} +
683,7 → 658,7
{4'd0, instruction[ 2]} +
{4'd0, instruction[ 1]} +
{4'd0, instruction[ 0]} ;
 
// 4 x number of registers to be stored
assign mtrans_base_reg_change = {25'd0, mtrans_num_registers, 2'd0};
 
697,15 → 672,15
assign dabt_request = dabt_reg;
 
// 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
assign und_request = type == CODTRANS ||
type == COREGOP ||
assign und_request = type == CODTRANS ||
type == COREGOP ||
( type == CORTRANS && instruction[11:8] != 4'd15 );
 
 
// in order of priority !!
// Highest
// in order of priority !!
// Highest
// 1 Reset
// 2 Data Abort (including data TLB miss)
// 3 FIRQ
712,22 → 687,22
// 4 IRQ
// 5 Prefetch Abort (including prefetch TLB miss)
// 6 Undefined instruction, SWI
// Lowest
// Lowest
assign next_interrupt = dabt_request ? 3'd1 : // Data Abort
firq_request ? 3'd2 : // FIRQ
irq_request ? 3'd3 : // IRQ
instruction_adex ? 3'd4 : // Address Exception
instruction_iabt ? 3'd5 : // PreFetch Abort, only triggered
instruction_adex ? 3'd4 : // Address Exception
instruction_iabt ? 3'd5 : // PreFetch Abort, only triggered
// if the instruction is used
und_request ? 3'd6 : // Undefined Instruction
swi_request ? 3'd7 : // SWI
3'd0 ; // none
3'd0 ; // none
 
 
// SWI and undefined instructions do not cause an interrupt in the decode
// stage. They only trigger interrupts if they arfe executed, so the
// interrupt is triggered if the execute condition is met in the execute stage
assign interrupt = next_interrupt != 3'd0 &&
assign interrupt = next_interrupt != 3'd0 &&
next_interrupt != 3'd7 && // SWI
next_interrupt != 3'd6 && // undefined interrupt
!conflict ; // Wait for conflicts to resolve before
736,8 → 711,8
 
// Added to use in rds_use_rs logic to break a combinational loop invloving
// the conflict signal
assign interrupt_or_conflict
= next_interrupt != 3'd0 &&
assign interrupt_or_conflict
= next_interrupt != 3'd0 &&
next_interrupt != 3'd7 && // SWI
next_interrupt != 3'd6 ; // undefined interrupt
 
759,40 → 734,40
// default mode
status_bits_mode_nxt = i_execute_status_bits[1:0]; // change to mode in execute stage get reflected
// back to this stage automatically
status_bits_irq_mask_nxt = status_bits_irq_mask_r;
status_bits_firq_mask_nxt = status_bits_firq_mask_r;
status_bits_irq_mask_nxt = o_status_bits_irq_mask;
status_bits_firq_mask_nxt = o_status_bits_firq_mask;
decode_exclusive_nxt = 1'd0;
decode_daccess_nxt = 1'd0;
decode_iaccess_nxt = 1'd1;
copro_operation_nxt = 'd0;
 
// Save an instruction to use later
saved_current_instruction_wen = 1'd0;
pre_fetch_instruction_wen = 1'd0;
restore_base_address_nxt = restore_base_address;
 
// default Mux Select values
barrel_shift_amount_sel_nxt = 'd0; // don't shift the input
barrel_shift_data_sel_nxt = 'd0; // immediate value
barrel_shift_function_nxt = 'd0;
barrel_shift_function_nxt = 'd0;
use_carry_in_nxt = 'd0;
multiply_function_nxt = 'd0;
iaddress_sel_nxt = 'd0;
daddress_sel_nxt = 'd0;
pc_sel_nxt = 'd0;
load_pc_nxt = 'd0;
byte_enable_sel_nxt = 'd0;
status_bits_sel_nxt = 'd0;
reg_write_sel_nxt = 'd0;
o_user_mode_regs_store_nxt = 'd0;
 
iaddress_sel_nxt = 'd0;
daddress_sel_nxt = 'd0;
pc_sel_nxt = 'd0;
load_pc_nxt = 'd0;
byte_enable_sel_nxt = 'd0;
status_bits_sel_nxt = 'd0;
reg_write_sel_nxt = 'd0;
o_user_mode_regs_store_nxt = 'd0;
// ALU Muxes
alu_swap_sel_nxt = 'd0;
alu_not_sel_nxt = 'd0;
alu_cin_sel_nxt = 'd0;
alu_cout_sel_nxt = 'd0;
alu_out_sel_nxt = 'd0;
 
alu_swap_sel_nxt = 'd0;
alu_not_sel_nxt = 'd0;
alu_cin_sel_nxt = 'd0;
alu_cout_sel_nxt = 'd0;
alu_out_sel_nxt = 'd0;
// default Flop Write Enable values
write_data_wen_nxt = 'd0;
copro_write_data_wen_nxt = 'd0;
799,7 → 774,7
base_address_wen_nxt = 'd0;
pc_wen_nxt = 'd1;
reg_bank_wen_nxt = 'd0; // Don't select any
 
status_bits_flags_wen_nxt = 'd0;
status_bits_mode_wen_nxt = 'd0;
status_bits_irq_mask_wen_nxt = 'd0;
817,35 → 792,35
pc_sel_nxt = 3'd1; // alu_out
iaddress_sel_nxt = 4'd1; // alu_out
end
else
else
reg_bank_wen_nxt = decode (instruction[15:12]);
end
 
if ( !immediate_shift_op )
begin
barrel_shift_function_nxt = instruction[6:5];
end
 
if ( !immediate_shift_op )
barrel_shift_data_sel_nxt = 2'd2; // Shift value from Rm register
 
if ( !immediate_shift_op && instruction[4] )
barrel_shift_amount_sel_nxt = 2'd1; // Shift amount from Rs registter
if ( !immediate_shift_op && !instruction[4] )
barrel_shift_amount_sel_nxt = 2'd2; // Shift immediate amount
 
if ( !immediate_shift_op && !instruction[4] )
barrel_shift_amount_sel_nxt = 2'd2; // Shift immediate amount
 
// regops that do not change the overflow flag
if ( opcode == AND || opcode == EOR || opcode == TST || opcode == TEQ ||
if ( opcode == AND || opcode == EOR || opcode == TST || opcode == TEQ ||
opcode == ORR || opcode == MOV || opcode == BIC || opcode == MVN )
status_bits_sel_nxt = 3'd5;
 
if ( opcode == ADD || opcode == CMN ) // CMN is just like an ADD
begin
alu_out_sel_nxt = 4'd1; // Add
use_carry_in_nxt = shift_extend;
end
 
if ( opcode == ADC ) // Add with Carry
begin
alu_out_sel_nxt = 4'd1; // Add
852,7 → 827,7
alu_cin_sel_nxt = 2'd2; // carry in from status_bits
use_carry_in_nxt = shift_extend;
end
 
if ( opcode == SUB || opcode == CMP ) // Subtract
begin
alu_out_sel_nxt = 4'd1; // Add
859,8 → 834,8
alu_cin_sel_nxt = 2'd1; // cin = 1
alu_not_sel_nxt = 1'd1; // invert B
end
 
// SBC (Subtract with Carry) subtracts the value of its
// SBC (Subtract with Carry) subtracts the value of its
// second operand and the value of NOT(Carry flag) from
// the value of its first operand.
// Rd = Rn - shifter_operand - NOT(C Flag)
871,7 → 846,7
alu_not_sel_nxt = 1'd1; // invert B
use_carry_in_nxt = 1'd1;
end
 
if ( opcode == RSB ) // Reverse Subtract
begin
alu_out_sel_nxt = 4'd1; // Add
880,7 → 855,7
alu_swap_sel_nxt = 1'd1; // swap A and B
use_carry_in_nxt = 1'd1;
end
 
if ( opcode == RSC ) // Reverse Subtract with carry
begin
alu_out_sel_nxt = 4'd1; // Add
889,13 → 864,13
alu_swap_sel_nxt = 1'd1; // swap A and B
use_carry_in_nxt = 1'd1;
end
 
if ( opcode == AND || opcode == TST ) // Logical AND, Test (using AND operator)
begin
alu_out_sel_nxt = 4'd8; // AND
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
end
 
if ( opcode == EOR || opcode == TEQ ) // Logical Exclusive OR, Test Equivalence (using EOR operator)
begin
alu_out_sel_nxt = 4'd6; // XOR
909,7 → 884,7
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
use_carry_in_nxt = 1'd1;
end
 
if ( opcode == BIC ) // Bit Clear (using AND & NOT operators)
begin
alu_out_sel_nxt = 4'd8; // AND
917,13 → 892,13
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
use_carry_in_nxt = 1'd1;
end
 
if ( opcode == MOV ) // Move
begin
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
use_carry_in_nxt = 1'd1;
end
 
if ( opcode == MVN ) // Move NOT
begin
alu_not_sel_nxt = 1'd1; // invert B
931,7 → 906,7
use_carry_in_nxt = 1'd1;
end
end
 
// Load & Store instructions
if ( mem_op )
begin
944,13 → 919,13
 
decode_daccess_nxt = 1'd1; // indicate a valid data access
alu_out_sel_nxt = 4'd1; // Add
 
if ( !instruction[23] ) // U: Subtract offset
begin
alu_cin_sel_nxt = 2'd1; // cin = 1
alu_not_sel_nxt = 1'd1; // invert B
end
 
if ( store_op )
begin
write_data_wen_nxt = 1'd1;
957,7 → 932,7
if ( type == TRANS && instruction[22] )
byte_enable_sel_nxt = 2'd1; // Save byte
end
 
// need to update the register holding the address ?
// This is Rn bits [19:16]
if ( mem_op_pre_indexed || mem_op_post_indexed )
964,34 → 939,34
begin
// Check is the load destination is the PC
if ( rn_sel_nxt == 4'd15 )
pc_sel_nxt = 3'd1;
else
pc_sel_nxt = 3'd1;
else
reg_bank_wen_nxt = decode ( rn_sel_nxt );
end
 
// if post-indexed, then use Rn rather than ALU output, as address
if ( mem_op_post_indexed )
daddress_sel_nxt = 4'd4; // Rn
else
else
daddress_sel_nxt = 4'd1; // alu out
 
if ( instruction[25] && type == TRANS )
barrel_shift_data_sel_nxt = 2'd2; // Shift value from Rm register
 
if ( type == TRANS && instruction[25] && shift_imm != 5'd0 )
begin
if ( type == TRANS && instruction[25] && shift_imm != 5'd0 )
begin
barrel_shift_function_nxt = instruction[6:5];
barrel_shift_amount_sel_nxt = 2'd2; // imm_shift_amount
end
end
 
 
if ( type == BRANCH )
begin
pc_sel_nxt = 3'd1; // alu_out
iaddress_sel_nxt = 4'd1; // alu_out
alu_out_sel_nxt = 4'd1; // Add
 
if ( instruction[24] ) // Link
begin
reg_bank_wen_nxt = decode (4'd14); // Save PC to LR
999,7 → 974,7
end
end
 
 
if ( type == MTRANS )
begin
saved_current_instruction_wen = 1'd1; // Save the memory access instruction to refer back to later
1006,7 → 981,7
decode_daccess_nxt = 1'd1; // valid data access
alu_out_sel_nxt = 4'd1; // Add
base_address_wen_nxt = 1'd1; // Save the value of the register used for the base address,
// in case of a data abort, and need to restore the value
// in case of a data abort, and need to restore the value
 
if ( mtrans_num_registers > 4'd1 )
begin
1016,10 → 991,10
 
 
// The spec says -
// If the instruction would have overwritten the base with data
// If the instruction would have overwritten the base with data
// (that is, it has the base in the transfer list), the overwriting is prevented.
// This is true even when the abort occurs after the base word gets loaded
restore_base_address_nxt = instruction[20] &&
restore_base_address_nxt = instruction[20] &&
(instruction[15:0] & (1'd1 << instruction[19:16]));
 
// Increment
1027,10 → 1002,10
begin
if ( instruction[24] ) // increment before
daddress_sel_nxt = 4'd7; // Rn + 4
else
else
daddress_sel_nxt = 4'd4; // Rn
end
else
else
// Decrement
begin
alu_cin_sel_nxt = 2'd1; // cin = 1
1040,15 → 1015,15
else
daddress_sel_nxt = 4'd1; // alu out
end
 
// Load or store ?
if ( !instruction[20] ) // Store
write_data_wen_nxt = 1'd1;
 
// stm: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 2'b10 )
write_data_wen_nxt = 1'd1;
// stm: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 2'b10 )
o_user_mode_regs_store_nxt = 1'd1;
 
// update the base register ?
if ( instruction[21] ) // the W bit
reg_bank_wen_nxt = decode (rn_sel_nxt);
1061,21 → 1036,21
load_pc_nxt = 1'd1;
end
end
 
 
if ( type == MULT )
begin
multiply_function_nxt[0] = 1'd1; // set enable
// 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
pc_wen_nxt = 1'd0; // hold current PC value
 
if ( instruction[21] )
multiply_function_nxt[1] = 1'd1; // accumulate
end
 
 
// swp - do read part first
if ( type == SWAP )
begin
1095,7 → 1070,7
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
iaddress_sel_nxt = 4'd3; // pc (not pc + 4)
 
if ( instruction[20] ) // MRC
copro_operation_nxt = 2'd1; // Register transfer from Co-Processor
else // MCR
1107,35 → 1082,35
end
end
 
 
if ( type == SWI || und_request )
begin
// save address of next instruction to Supervisor Mode LR
reg_write_sel_nxt = 3'd1; // pc -4
reg_bank_wen_nxt = decode (4'd14); // LR
 
iaddress_sel_nxt = 4'd2; // interrupt_vector
pc_sel_nxt = 3'd2; // interrupt_vector
 
status_bits_mode_nxt = interrupt_mode; // e.g. Supervisor mode
status_bits_mode_wen_nxt = 1'd1;
 
// disable normal interrupts
status_bits_irq_mask_nxt = 1'd1;
status_bits_irq_mask_wen_nxt = 1'd1;
end
 
 
if ( regop_set_flags )
begin
status_bits_flags_wen_nxt = 1'd1;
 
// If <Rd> is r15, the ALU output is copied to the Status Bits.
// Not allowed to use r15 for mul or lma instructions
// If <Rd> is r15, the ALU output is copied to the Status Bits.
// Not allowed to use r15 for mul or lma instructions
if ( instruction[15:12] == 4'd15 )
begin
status_bits_sel_nxt = 3'd1; // alu out
 
// Priviledged mode? Then also update the other status bits
if ( i_execute_status_bits[1:0] != USR )
begin
1145,9 → 1120,9
end
end
end
end
 
end
 
// Handle asynchronous interrupts.
// interrupts are processed only during execution states
// multicycle instructions must complete before the interrupt starts
1159,8 → 1134,8
// Save the interrupt causing instruction to refer back to later
// This also saves the instruction abort vma and status, in the case of an
// instruction abort interrupt
saved_current_instruction_wen = 1'd1;
 
saved_current_instruction_wen = 1'd1;
// save address of next instruction to Supervisor Mode LR
// Address Exception ?
if ( next_interrupt == 3'd4 )
1167,15 → 1142,15
reg_write_sel_nxt = 3'd7; // pc
else
reg_write_sel_nxt = 3'd1; // pc -4
 
reg_bank_wen_nxt = decode (4'd14); // LR
 
iaddress_sel_nxt = 4'd2; // interrupt_vector
pc_sel_nxt = 3'd2; // interrupt_vector
 
status_bits_mode_nxt = interrupt_mode; // e.g. Supervisor mode
status_bits_mode_wen_nxt = 1'd1;
 
// disable normal interrupts
status_bits_irq_mask_nxt = 1'd1;
status_bits_irq_mask_wen_nxt = 1'd1;
1187,16 → 1162,16
status_bits_firq_mask_wen_nxt = 1'd1;
end
end
 
 
// previous instruction was ldr
// if it is currently executing in the execute stage do the following
// if it is currently executing in the execute stage do the following
if ( control_state == MEM_WAIT1 && !conflict )
begin
// Save the next instruction to execute later
// Do this even if the ldr instruction does not execute because of Condition
pre_fetch_instruction_wen = 1'd1;
 
if ( instruction_execute ) // conditional execution state
begin
iaddress_sel_nxt = 4'd3; // pc (not pc + 4)
1204,17 → 1179,17
load_pc_nxt = load_pc_r;
end
end
 
 
// completion of ldr instruction
if ( control_state == MEM_WAIT2 )
begin
if ( !dabt ) // dont load data there is an abort on the data read
begin
begin
pc_wen_nxt = 1'd0; // hold current PC value
 
// Check if the load destination is the PC
if (( type == TRANS && instruction[15:12] == 4'd15 ) ||
if (( type == TRANS && instruction[15:12] == 4'd15 ) ||
( type == MTRANS && instruction[20] && mtrans_reg1 == 4'd15 ))
begin
pc_sel_nxt = 3'd3; // read_data_filtered
1223,19 → 1198,19
end
end
end
 
 
// second cycle of multiple load or store
if ( control_state == MTRANS_EXEC1 && !conflict )
begin
// Save the next instruction to execute later
pre_fetch_instruction_wen = 1'd1;
 
if ( instruction_execute ) // conditional execution state
begin
daddress_sel_nxt = 4'd5; // o_address
decode_daccess_nxt = 1'd1; // data access
 
if ( mtrans_num_registers > 4'd2 )
decode_iaccess_nxt = 1'd0; // skip the instruction fetch
 
1246,14 → 1221,14
iaddress_sel_nxt = 4'd3; // pc (not pc + 4)
end
 
 
if ( !instruction[20] ) // Store
write_data_wen_nxt = 1'd1;
 
// stm: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 2'b10 )
// stm: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 2'b10 )
o_user_mode_regs_store_nxt = 1'd1;
 
// write to the pc ?
if ( instruction[20] && mtrans_reg1 == 4'd15 ) // Write to PC
begin
1261,10 → 1236,10
pc_wen_nxt = 1'd0; // hold current PC value rather than an instruction fetch
load_pc_nxt = 1'd1;
end
end
end
 
 
end
end
// third cycle of multiple load or store
if ( control_state == MTRANS_EXEC2 )
begin
1281,13 → 1256,13
pc_wen_nxt = 1'd0; // hold current PC value
iaddress_sel_nxt = 4'd3; // pc (not pc + 4)
end
 
// Store
if ( !instruction[20] )
write_data_wen_nxt = 1'd1;
 
// stm: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 2'b10 )
// stm: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 2'b10 )
o_user_mode_regs_store_nxt = 1'd1;
 
// write to the pc ?
1298,8 → 1273,8
load_pc_nxt = 1'd1;
end
end
 
 
// state is for when a data abort interrupt is triggered during an ldm
if ( control_state == MTRANS_ABORT )
begin
1311,8 → 1286,8
reg_bank_wen_nxt = decode ( instruction[19:16] ); // to Rn
end
end
 
 
// Multiply or Multiply-Accumulate
if ( control_state == MULT_PROC1 && instruction_execute && !conflict )
begin
1323,7 → 1298,7
multiply_function_nxt = o_multiply_function;
end
 
 
// Multiply or Multiply-Accumulate
// Do multiplication
// Wait for done or accumulate signal
1336,7 → 1311,7
multiply_function_nxt = o_multiply_function;
end
 
 
// Save RdLo
// always last cycle of all multiply or multiply accumulate operations
if ( control_state == MULT_STORE )
1343,20 → 1318,20
begin
reg_write_sel_nxt = 3'd2; // multiply_out
multiply_function_nxt = o_multiply_function;
 
if ( type == MULT ) // 32-bit
reg_bank_wen_nxt = decode (instruction[19:16]); // Rd
else // 64-bit / Long
reg_bank_wen_nxt = decode (instruction[15:12]); // RdLo
 
if ( instruction[20] ) // the 'S' bit
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;
end
end
 
 
// Add lower 32 bits to multiplication product
if ( control_state == MULT_ACCUMU )
begin
1364,8 → 1339,8
pc_wen_nxt = 1'd0; // hold current PC value
iaddress_sel_nxt = 4'd3; // pc (not pc + 4)
end
 
 
// swp - do write request in 2nd cycle
if ( control_state == SWAP_WRITE && instruction_execute && !conflict )
begin
1374,23 → 1349,23
write_data_wen_nxt = 1'd1;
decode_iaccess_nxt = 1'd0; // skip the instruction fetch
decode_daccess_nxt = 1'd1; // data access
 
if ( instruction[22] )
byte_enable_sel_nxt = 2'd1; // Save byte
 
if ( instruction_execute ) // conditional execution state
pc_wen_nxt = 1'd0; // hold current PC value
 
// Save the next instruction to execute later
// Do this even if this instruction does not execute because of Condition
pre_fetch_instruction_wen = 1'd1;
 
load_pc_nxt = load_pc_r;
end
 
 
// swp - receive read response in 3rd cycle
if ( control_state == SWAP_WAIT1 )
if ( control_state == SWAP_WAIT1 )
begin
 
if ( instruction_execute ) // conditional execution state
1398,9 → 1373,9
iaddress_sel_nxt = 4'd3; // pc (not pc + 4)
pc_wen_nxt = 1'd0; // hold current PC value
end
 
if ( !dabt )
begin
begin
// Check is the load destination is the PC
if ( instruction[15:12] == 4'd15 )
begin
1410,23 → 1385,23
end
end
end
 
 
// 1 cycle delay for Co-Processor Register access
if ( control_state == COPRO_WAIT && instruction_execute && !conflict )
begin
pre_fetch_instruction_wen = 1'd1;
 
if ( instruction[20] ) // mrc instruction
begin
// Check is the load destination is the PC
if ( instruction[15:12] == 4'd15 )
begin
// If r15 is specified for <Rd>, the condition code flags are
// If r15 is specified for <Rd>, the condition code flags are
// updated instead of a general-purpose register.
status_bits_sel_nxt = 3'd3; // i_copro_data
status_bits_flags_wen_nxt = 1'd1;
 
// Can't change these in USR mode
if ( i_execute_status_bits[1:0] != USR )
begin
1435,25 → 1410,25
status_bits_firq_mask_wen_nxt = 1'd1;
end
end
else
else
reg_bank_wen_nxt = decode (instruction[15:12]);
 
reg_write_sel_nxt = 3'd5; // i_copro_data
end
else // mcr instruction
begin
copro_operation_nxt = 2'd2; // Register transfer to Co-Processor
end
copro_operation_nxt = 2'd2; // Register transfer to Co-Processor
end
end
 
 
// Have just changed the status_bits mode but this
// creates a 1 cycle gap with the old mode
// coming back from execute into instruction_decode
// So squash that old mode value during this
// cycle of the interrupt transition
if ( control_state == INT_WAIT1 )
status_bits_mode_nxt = status_bits_mode_r; // Supervisor mode
// cycle of the interrupt transition
if ( control_state == INT_WAIT1 )
status_bits_mode_nxt = o_status_bits_mode; // Supervisor mode
 
end
 
1468,7 → 1443,7
// ========================================================
 
// this replicates the current value of the execute signal in the execute stage
assign instruction_execute = conditional_execute ( condition_r, i_execute_status_bits[31:28] );
assign instruction_execute = conditional_execute ( o_condition, i_execute_status_bits[31:28] );
 
 
// First state of executing a new instruction
1476,7 → 1451,7
assign instruction_valid = ((control_state == EXECUTE || control_state == PRE_FETCH_EXEC) ||
// when last instruction was multi-cycle instruction but did not execute
// 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 ||
control_state == MEM_WAIT1 ||
control_state == COPRO_WAIT ||
control_state == SWAP_WRITE ||
1488,7 → 1463,7
begin
// default is to hold the current state
control_state_nxt = control_state;
 
// Note: The order is important here
if ( control_state == RST_WAIT1 ) control_state_nxt = RST_WAIT2;
if ( control_state == RST_WAIT2 ) control_state_nxt = EXECUTE;
1496,39 → 1471,39
if ( control_state == INT_WAIT2 ) control_state_nxt = EXECUTE;
if ( control_state == COPRO_WAIT ) control_state_nxt = PRE_FETCH_EXEC;
if ( control_state == PC_STALL1 ) control_state_nxt = PC_STALL2;
if ( control_state == PC_STALL2 ) control_state_nxt = EXECUTE;
if ( control_state == SWAP_WRITE ) control_state_nxt = SWAP_WAIT1;
if ( control_state == SWAP_WAIT1 ) control_state_nxt = SWAP_WAIT2;
if ( control_state == MULT_STORE ) control_state_nxt = PRE_FETCH_EXEC;
if ( control_state == PC_STALL2 ) control_state_nxt = EXECUTE;
if ( control_state == SWAP_WRITE ) control_state_nxt = SWAP_WAIT1;
if ( control_state == SWAP_WAIT1 ) control_state_nxt = SWAP_WAIT2;
if ( control_state == MULT_STORE ) control_state_nxt = PRE_FETCH_EXEC;
if ( control_state == MTRANS_ABORT ) control_state_nxt = PRE_FETCH_EXEC;
 
if ( control_state == MEM_WAIT1 )
control_state_nxt = MEM_WAIT2;
 
if ( control_state == MEM_WAIT2 ||
if ( control_state == MEM_WAIT2 ||
control_state == SWAP_WAIT2 )
begin
if ( write_pc ) // writing to the PC!!
if ( write_pc ) // writing to the PC!!
control_state_nxt = PC_STALL1;
else
control_state_nxt = PRE_FETCH_EXEC;
end
 
if ( control_state == MTRANS_EXEC1 )
begin
if ( control_state == MTRANS_EXEC1 )
begin
if ( mtrans_instruction_nxt[15:0] != 16'd0 )
control_state_nxt = MTRANS_EXEC2;
else // if the register list holds a single register
else // if the register list holds a single register
begin
if ( dabt ) // data abort
control_state_nxt = MTRANS_ABORT;
else if ( write_pc ) // writing to the PC!!
else if ( write_pc ) // writing to the PC!!
control_state_nxt = MEM_WAIT1;
else
control_state_nxt = PRE_FETCH_EXEC;
end
end
 
// Stay in State MTRANS_EXEC2 until the full list of registers to
// load or store has been processed
if ( control_state == MTRANS_EXEC2 && mtrans_num_registers == 5'd1 )
1535,13 → 1510,13
begin
if ( dabt ) // data abort
control_state_nxt = MTRANS_ABORT;
else if ( write_pc ) // writing to the PC!!
else if ( write_pc ) // writing to the PC!!
control_state_nxt = MEM_WAIT1;
else
control_state_nxt = PRE_FETCH_EXEC;
end
 
 
if ( control_state == MULT_PROC1 )
begin
if (!instruction_execute)
1549,23 → 1524,23
else
control_state_nxt = MULT_PROC2;
end
 
if ( control_state == MULT_PROC2 )
begin
if ( i_multiply_done )
if ( o_multiply_function[1] ) // Accumulate ?
control_state_nxt = MULT_ACCUMU;
else
else
control_state_nxt = MULT_STORE;
end
 
 
if ( control_state == MULT_ACCUMU )
begin
control_state_nxt = MULT_STORE;
end
 
 
// This should come at the end, so that conditional execution works
// correctly
if ( instruction_valid )
1573,8 → 1548,8
// default is to stay in execute state, or to move into this
// state from a conditional execute state
control_state_nxt = EXECUTE;
 
if ( current_write_pc )
if ( current_write_pc )
control_state_nxt = PC_STALL1;
 
if ( load_op && instruction[15:12] == 4'd15 ) // load new PC value
1590,17 → 1565,17
if ( type == MULT && !conflict )
control_state_nxt = MULT_PROC1;
 
if ( type == SWAP && !conflict )
if ( type == SWAP && !conflict )
control_state_nxt = SWAP_WRITE;
 
if ( type == CORTRANS && !und_request && !conflict )
if ( type == CORTRANS && !und_request && !conflict )
control_state_nxt = COPRO_WAIT;
 
// interrupt overrides everything else so its last
if ( interrupt && !conflict )
// interrupt overrides everything else so its last
if ( interrupt && !conflict )
control_state_nxt = INT_WAIT1;
end
 
end
 
 
1608,10 → 1583,10
// Register Update
// ========================================================
always @ ( posedge i_clk )
if ( !i_core_stall )
begin
if ( !i_core_stall )
begin
if (!conflict)
begin
begin
fetch_instruction_r <= i_fetch_instruction;
fetch_instruction_type_r <= instruction_type(i_fetch_instruction);
fetch_address_r <= i_execute_iaddress;
1620,27 → 1595,27
abt_status_reg <= i_abt_status;
end
 
status_bits_mode_r <= status_bits_mode_nxt;
status_bits_irq_mask_r <= status_bits_irq_mask_nxt;
status_bits_firq_mask_r <= status_bits_firq_mask_nxt;
o_status_bits_mode <= status_bits_mode_nxt;
o_status_bits_irq_mask <= status_bits_irq_mask_nxt;
o_status_bits_firq_mask <= status_bits_firq_mask_nxt;
o_imm32 <= imm32_nxt;
o_imm_shift_amount <= imm_shift_amount_nxt;
o_shift_imm_zero <= shift_imm_zero_nxt;
 
// when have an interrupt, execute the interrupt operation
// unconditionally in the execute stage
// ensures that status_bits register gets updated correctly
// Likewise when in middle of multi-cycle instructions
// execute them unconditionally
condition_r <= instruction_valid && !interrupt ? condition_nxt : AL;
o_condition <= instruction_valid && !interrupt ? condition_nxt : AL;
o_decode_exclusive <= decode_exclusive_nxt;
decode_iaccess_r <= decode_iaccess_nxt;
o_decode_iaccess <= decode_iaccess_nxt;
o_decode_daccess <= decode_daccess_nxt;
 
o_rm_sel <= rm_sel_nxt;
o_rs_sel <= rs_sel_nxt;
o_load_rd <= load_rd_nxt;
load_rd_d1 <= load_rd_d1_nxt;
load_rd_d1 <= load_rd_d1_nxt;
load_pc_r <= load_pc_nxt;
o_rn_sel <= rn_sel_nxt;
o_barrel_shift_amount_sel <= barrel_shift_amount_sel_nxt;
1650,9 → 1625,9
o_use_carry_in <= use_carry_in_nxt;
o_multiply_function <= multiply_function_nxt;
o_interrupt_vector_sel <= next_interrupt;
iaddress_sel_r <= iaddress_sel_nxt;
daddress_sel_r <= daddress_sel_nxt;
pc_sel_r <= pc_sel_nxt;
o_iaddress_sel <= iaddress_sel_nxt;
o_daddress_sel <= daddress_sel_nxt;
o_pc_sel <= pc_sel_nxt;
o_byte_enable_sel <= byte_enable_sel_nxt;
o_status_bits_sel <= status_bits_sel_nxt;
o_reg_write_sel <= reg_write_sel_nxt;
1659,13 → 1634,13
o_firq_not_user_mode <= firq_not_user_mode_nxt;
o_write_data_wen <= write_data_wen_nxt;
o_base_address_wen <= base_address_wen_nxt;
pc_wen_r <= pc_wen_nxt;
o_pc_wen <= pc_wen_nxt;
o_reg_bank_wen <= reg_bank_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_irq_mask_wen <= status_bits_irq_mask_wen_nxt;
o_status_bits_firq_mask_wen <= status_bits_firq_mask_wen_nxt;
 
o_copro_opcode1 <= instruction[23:21];
o_copro_opcode2 <= instruction[7:5];
o_copro_crn <= instruction[19:16];
1688,7 → 1663,7
// then when its decoded, a copy is saved to the saved_current_instruction
// register
if ( type == MTRANS )
begin
begin
saved_current_instruction <= mtrans_instruction_nxt;
saved_current_instruction_type <= type;
saved_current_instruction_iabt <= instruction_iabt;
1696,8 → 1671,8
saved_current_instruction_address <= instruction_address;
saved_current_instruction_iabt_status <= instruction_iabt_status;
end
else if ( saved_current_instruction_wen )
begin
else if ( saved_current_instruction_wen )
begin
saved_current_instruction <= instruction;
saved_current_instruction_type <= type;
saved_current_instruction_iabt <= instruction_iabt;
1706,18 → 1681,18
saved_current_instruction_iabt_status <= instruction_iabt_status;
end
 
if ( pre_fetch_instruction_wen )
if ( pre_fetch_instruction_wen )
begin
pre_fetch_instruction <= fetch_instruction_r;
pre_fetch_instruction_type <= fetch_instruction_type_r;
pre_fetch_instruction_iabt <= iabt_reg;
pre_fetch_instruction_adex <= adex_reg;
pre_fetch_instruction_address <= fetch_address_r;
pre_fetch_instruction_iabt_status <= abt_status_reg;
pre_fetch_instruction <= fetch_instruction_r;
pre_fetch_instruction_type <= fetch_instruction_type_r;
pre_fetch_instruction_iabt <= iabt_reg;
pre_fetch_instruction_adex <= adex_reg;
pre_fetch_instruction_address <= fetch_address_r;
pre_fetch_instruction_iabt_status <= abt_status_reg;
end
 
 
// TODO possible to use saved_current_instruction instead and save some regs?
// TODO possible to use saved_current_instruction instead and save some regs?
hold_instruction <= instruction;
hold_instruction_type <= type;
hold_instruction_iabt <= instruction_iabt;
1727,25 → 1702,25
end
 
 
 
always @ ( posedge i_clk )
if ( !i_core_stall )
begin
irq <= i_irq;
firq <= i_firq;
 
if ( control_state == INT_WAIT1 && status_bits_mode_r == SVC )
irq <= i_irq;
firq <= i_firq;
if ( control_state == INT_WAIT1 && o_status_bits_mode == SVC )
begin
dabt_reg <= 1'd0;
end
else
begin
dabt_reg <= dabt_reg || i_dabt;
dabt_reg <= dabt_reg || i_dabt;
end
dabt_reg_d1 <= dabt_reg;
end
 
dabt_reg_d1 <= dabt_reg;
end
 
assign dabt = dabt_reg || i_dabt;
 
 
1766,8 → 1741,9
.i_interrupt ( {3{interrupt}} & next_interrupt ),
.i_interrupt_state ( control_state == INT_WAIT2 ),
.i_instruction_undefined ( und_request ),
.i_pc_sel ( pc_sel_r ),
.i_pc_wen ( pc_wen_r ));
.i_pc_sel ( o_pc_sel ),
.i_pc_wen ( o_pc_wen )
);
 
 
wire [(15*8)-1:0] xCONTROL_STATE;
1774,7 → 1750,7
wire [(15*8)-1:0] xMODE;
wire [( 8*8)-1:0] xTYPE;
 
assign xCONTROL_STATE =
assign xCONTROL_STATE =
control_state == RST_WAIT1 ? "RST_WAIT1" :
control_state == RST_WAIT2 ? "RST_WAIT2" :
 
1800,9 → 1776,9
control_state == COPRO_WAIT ? "COPRO_WAIT" :
"UNKNOWN " ;
 
assign xMODE = mode_name ( status_bits_mode_r );
assign xMODE = mode_name ( o_status_bits_mode );
 
assign xTYPE =
assign xTYPE =
type == REGOP ? "REGOP" :
type == MULT ? "MULT" :
type == SWAP ? "SWAP" :
/trunk/hw/vlog/amber25/a25_execute.v
53,7 → 53,7
input i_wb_read_data_valid, // read data is valid
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
input i_decode_iaccess, // Indicates an instruction access
input i_decode_daccess, // Indicates a data access
61,12 → 61,12
 
output reg [31:0] o_copro_write_data = 'd0,
output reg [31:0] o_write_data = 'd0,
output wire [31:0] o_iaddress,
output [31:0] o_iaddress_nxt, // un-registered version of address to the
output reg [31:0] o_iaddress = 32'hdead_dead,
output [31:0] o_iaddress_nxt, // un-registered version of address to the
// cache rams address ports
output reg o_iaddress_valid = 'd0, // High when instruction address is valid
output reg [31:0] o_daddress = 32'h0, // Address to data cache
output [31:0] o_daddress_nxt, // un-registered version of address to the
output [31:0] o_daddress_nxt, // un-registered version of address to the
// cache rams address ports
output reg o_daddress_valid = 'd0, // High when data address is valid
output reg o_adex = 'd0, // Address Exception
111,7 → 111,7
input i_use_carry_in, // e.g. add with carry instruction
 
input i_write_data_wen,
input i_base_address_wen, // save LDM base address register,
input i_base_address_wen, // save LDM base address register,
// in case of data abort
input i_pc_wen,
input [14:0] i_reg_bank_wen,
180,7 → 180,7
wire [14:0] reg_bank_wen;
wire [31:0] multiply_out;
wire [1:0] multiply_flags;
reg [31:0] base_address = 'd0; // Saves base address during LDM instruction in
reg [31:0] base_address = 'd0; // Saves base address during LDM instruction in
// case of data abort
wire [31:0] read_data_filtered1;
wire [31:0] read_data_filtered;
192,7 → 192,7
wire write_enable_nxt;
wire daddress_valid_nxt;
wire iaddress_valid_nxt;
wire priviledged_nxt;
wire priviledged_nxt;
wire priviledged_update;
wire iaddress_update;
wire daddress_update;
217,14 → 217,12
 
wire carry_in;
 
reg [31:0] iaddress_r = 32'hdead_dead;
 
 
// ========================================================
// Status Bits in PC register
// ========================================================
wire [1:0] status_bits_mode_out;
assign status_bits_mode_out = (i_status_bits_mode_wen && i_status_bits_sel == 3'd1 && !ldm_status_bits) ?
assign status_bits_mode_out = (i_status_bits_mode_wen && i_status_bits_sel == 3'd1 && !ldm_status_bits) ?
alu_out[1:0] : status_bits_mode ;
 
assign o_status_bits = { status_bits_flags, // 31:28
248,7 → 246,7
// 4 = update flags after a multiply operation
i_status_bits_sel == 3'd4 ? { multiply_flags, status_bits_flags[1:0] } :
// regops that do not change the overflow flag
i_status_bits_sel == 3'd5 ? { alu_flags[3:1], status_bits_flags[0] } :
i_status_bits_sel == 3'd5 ? { alu_flags[3:1], status_bits_flags[0] } :
4'b1111 ;
 
assign status_bits_mode_nxt = ldm_status_bits ? read_data_filtered [1:0] :
268,14 → 266,14
assign status_bits_mode_rds_oh_nxt = i_user_mode_regs_store_nxt ? 1'd1 << OH_USR :
status_bits_mode_update ? oh_status_bits_mode(status_bits_mode_nxt) :
oh_status_bits_mode(status_bits_mode) ;
 
 
assign status_bits_irq_mask_nxt = ldm_status_bits ? read_data_filtered [27] :
i_status_bits_sel == 3'd0 ? i_status_bits_irq_mask :
i_status_bits_sel == 3'd5 ? i_status_bits_irq_mask :
i_status_bits_sel == 3'd1 ? alu_out [27] :
i_copro_read_data [27] ;
 
assign status_bits_firq_mask_nxt = ldm_status_bits ? read_data_filtered [26] :
i_status_bits_sel == 3'd0 ? i_status_bits_firq_mask :
i_status_bits_sel == 3'd5 ? i_status_bits_firq_mask :
313,10 → 311,10
// ========================================================
 
assign interrupt_vector = // Reset vector
(i_interrupt_vector_sel == 3'd0) ? 32'h00000000 :
// Data abort interrupt vector
(i_interrupt_vector_sel == 3'd0) ? 32'h00000000 :
// Data abort interrupt vector
(i_interrupt_vector_sel == 3'd1) ? 32'h00000010 :
// Fast interrupt vector
// Fast interrupt vector
(i_interrupt_vector_sel == 3'd2) ? 32'h0000001c :
// Regular interrupt vector
(i_interrupt_vector_sel == 3'd3) ? 32'h00000018 :
342,7 → 340,7
// if current instruction does not execute because it does not meet the condition
// then address advances to next instruction
assign o_iaddress_nxt = (pc_dmem_wen) ? pcf(read_data_filtered) :
(!execute) ? pc_plus4 :
(!execute) ? pc_plus4 :
(i_iaddress_sel == 4'd0) ? pc_plus4 :
(i_iaddress_sel == 4'd1) ? alu_out_pc_filtered :
(i_iaddress_sel == 4'd2) ? interrupt_vector :
372,13 → 370,13
// mem_load_rd[7] -> load status bits with PC
// mem_load_rd[6:5] -> Write into this Mode registers
// 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[10:9] == 2'd0 ? i_wb_read_data :
i_wb_load_rd[10:9] == 2'd1 ? {i_wb_read_data[7:0], i_wb_read_data[31:8]} :
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]} ;
 
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 ;
 
 
// ========================================================
398,22 → 396,22
// Register Write Select
// ========================================================
 
assign save_int_pc = { status_bits_flags,
status_bits_irq_mask,
status_bits_firq_mask,
pc[25:2],
assign save_int_pc = { status_bits_flags,
status_bits_irq_mask,
status_bits_firq_mask,
pc[25:2],
status_bits_mode };
 
 
assign save_int_pc_m4 = { status_bits_flags,
status_bits_irq_mask,
status_bits_firq_mask,
pc_minus4[25:2],
assign save_int_pc_m4 = { status_bits_flags,
status_bits_irq_mask,
status_bits_firq_mask,
pc_minus4[25:2],
status_bits_mode };
 
 
assign reg_write_nxt = i_reg_write_sel == 3'd0 ? alu_out :
// save pc to lr on an interrupt
// save pc to lr on an interrupt
i_reg_write_sel == 3'd1 ? save_int_pc_m4 :
// to update Rd at the end of Multiplication
i_reg_write_sel == 3'd2 ? multiply_out :
420,7 → 418,7
i_reg_write_sel == 3'd3 ? o_status_bits :
i_reg_write_sel == 3'd5 ? i_copro_read_data : // mrc
i_reg_write_sel == 3'd6 ? base_address :
save_int_pc ;
save_int_pc ;
 
 
// ========================================================
428,9 → 426,9
// ========================================================
assign byte_enable_nxt = i_byte_enable_sel == 2'd0 ? 4'b1111 : // word write
i_byte_enable_sel == 2'd2 ? // halfword write
( o_daddress_nxt[1] == 1'd0 ? 4'b0011 :
( o_daddress_nxt[1] == 1'd0 ? 4'b0011 :
4'b1100 ) :
 
o_daddress_nxt[1:0] == 2'd0 ? 4'b0001 : // byte write
o_daddress_nxt[1:0] == 2'd1 ? 4'b0010 :
o_daddress_nxt[1:0] == 2'd2 ? 4'b0100 :
448,7 → 446,7
// Conditional Execution
// ========================================================
assign execute = conditional_execute ( i_condition, status_bits_flags );
 
// allow the PC to increment to the next instruction when current
// instruction does not execute
assign pc_wen = (i_pc_wen || !execute) && !i_conflict;
509,11 → 507,11
// 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],
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
// ========================================================
521,7 → 519,7
 
assign daddress_update = !i_core_stall;
assign exec_load_rd_update = !i_core_stall && execute;
assign priviledged_update = !i_core_stall;
assign priviledged_update = !i_core_stall;
assign exclusive_update = !i_core_stall && execute;
assign write_enable_update = !i_core_stall;
assign write_data_update = !i_core_stall && execute && i_write_data_wen;
530,7 → 528,7
assign iaddress_update = pc_dmem_wen || (!i_core_stall && !i_conflict);
assign copro_write_data_update = !i_core_stall && execute && i_copro_write_data_wen;
 
assign base_address_update = !i_core_stall && execute && i_base_address_wen;
assign base_address_update = !i_core_stall && execute && i_base_address_wen;
assign status_bits_flags_update = ldm_flags || (!i_core_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_rds_oh_update = !i_core_stall;
539,21 → 537,21
 
 
always @( posedge i_clk )
begin
o_daddress <= daddress_update ? o_daddress_nxt : o_daddress;
begin
o_daddress <= daddress_update ? o_daddress_nxt : o_daddress;
o_daddress_valid <= daddress_update ? daddress_valid_nxt : o_daddress_valid;
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_exclusive <= exclusive_update ? i_decode_exclusive : o_exclusive;
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;
iaddress_r <= iaddress_update ? o_iaddress_nxt : iaddress_r;
o_iaddress <= iaddress_update ? o_iaddress_nxt : o_iaddress;
o_iaddress_valid <= iaddress_update ? iaddress_valid_nxt : o_iaddress_valid;
o_adex <= iaddress_update ? adex_nxt : o_adex;
o_copro_write_data <= copro_write_data_update ? write_data_nxt : o_copro_write_data;
o_adex <= iaddress_update ? adex_nxt : o_adex;
o_copro_write_data <= copro_write_data_update ? write_data_nxt : o_copro_write_data;
 
base_address <= base_address_update ? rn : base_address;
base_address <= base_address_update ? rn : base_address;
 
status_bits_flags <= status_bits_flags_update ? status_bits_flags_nxt : status_bits_flags;
status_bits_mode <= status_bits_mode_update ? status_bits_mode_nxt : status_bits_mode;
562,9 → 560,7
status_bits_firq_mask <= status_bits_firq_mask_update ? status_bits_firq_mask_nxt : status_bits_firq_mask;
end
 
assign o_iaddress = iaddress_r;
 
 
// ========================================================
// Instantiate Barrel Shift
// ========================================================
586,10 → 582,10
// ========================================================
// Instantiate ALU
// ========================================================
assign barrel_shift_carry_alu = i_barrel_shift_data_sel == 2'd0 ?
(i_imm_shift_amount[4:1] == 0 ? status_bits_flags[1] : i_imm32[31]) :
assign barrel_shift_carry_alu = i_barrel_shift_data_sel == 2'd0 ?
(i_imm_shift_amount[4:1] == 0 ? status_bits_flags[1] : i_imm32[31]) :
barrel_shift_carry;
 
a25_alu u_alu (
.i_a_in ( rn ),
.i_b_in ( barrel_shift_out ),
614,7 → 610,7
.i_execute ( execute ),
.o_out ( multiply_out ),
.o_flags ( multiply_flags ), // [1] = N, [0] = Z
.o_done ( o_multiply_done )
.o_done ( o_multiply_done )
);
 
 
646,10 → 642,10
 
// pre-encoded in decode stage to speed up long path
.i_firq_not_user_mode ( i_firq_not_user_mode ),
 
// use one-hot version for speed, combine with i_user_mode_regs_store
.i_mode_rds_exec ( status_bits_mode_rds_oh ),
 
.i_mode_rds_exec ( status_bits_mode_rds_oh ),
.o_rm ( reg_bank_rm ),
.o_rs ( reg_bank_rs ),
.o_rd ( reg_bank_rd ),
689,8 → 685,8
status_bits_mode == FIRQ ? "FIRQ" :
status_bits_mode == USR ? "USR" :
"XXX" ;
 
 
//synopsys translate_on
 
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.