/*
|
/*
|
* Simply RISC M1 Central Processing Unit
|
* Simply RISC M1 Central Processing Unit
|
*/
|
*/
|
|
|
`include "m1_defs.vh"
|
`include "m1_defs.vh"
|
|
|
module m1_cpu (
|
module m1_cpu (
|
|
|
// System
|
// System
|
input sys_clock_i, // System Clock
|
input sys_clock_i, // System Clock
|
input sys_reset_i, // System Reset
|
input sys_reset_i, // System Reset
|
input sys_irq_i, // Interrupt Request
|
input sys_irq_i, // Interrupt Request
|
|
|
// ALU
|
// ALU
|
output[31:0] alu_a_o, // ALU Operand A
|
output[31:0] alu_a_o, // ALU Operand A
|
output[31:0] alu_b_o, // ALU Operand B
|
output[31:0] alu_b_o, // ALU Operand B
|
output[4:0] alu_func_o, // ALU Function
|
output[4:0] alu_func_o, // ALU Function
|
output alu_signed_o, // ALU operation is Signed
|
output alu_signed_o, // ALU operation is Signed
|
input[32:0] alu_result_i, // ALU Result with Carry
|
input[32:0] alu_result_i, // ALU Result with Carry
|
|
|
// Multiplier
|
// Multiplier
|
output reg mul_req_o, // Multiplier Request
|
output reg mul_req_o, // Multiplier Request
|
output[31:0] mul_a_o, // Multiplier Operand A
|
output[31:0] mul_a_o, // Multiplier Operand A
|
output[31:0] mul_b_o, // Multiplier Operand B
|
output[31:0] mul_b_o, // Multiplier Operand B
|
output mul_signed_o, // Multiplication is Signed
|
output mul_signed_o, // Multiplication is Signed
|
input mul_ack_i, // Multiplier Ack
|
input mul_ack_i, // Multiplier Ack
|
input[63:0] mul_product_i, // Multiplier Product
|
input[63:0] mul_product_i, // Multiplier Product
|
|
|
// Divider
|
// Divider
|
output reg div_req_o, // Divider Request
|
output reg div_req_o, // Divider Request
|
output[31:0] div_a_o, // Divider Operand A
|
output[31:0] div_a_o, // Divider Operand A
|
output[31:0] div_b_o, // Divider Operand B
|
output[31:0] div_b_o, // Divider Operand B
|
output div_signed_o, // Division is Signed
|
output div_signed_o, // Division is Signed
|
input div_ack_i, // Divider Ack
|
input div_ack_i, // Divider Ack
|
input[31:0] div_quotient_i, // Divider Quotient
|
input[31:0] div_quotient_i, // Divider Quotient
|
input[31:0] div_remainder_i, // Divider Remainder
|
input[31:0] div_remainder_i, // Divider Remainder
|
|
|
// Instruction Memory
|
// Instruction Memory
|
output imem_read_o, // I$ Read
|
output imem_read_o, // I$ Read
|
output[31:0] imem_addr_o, // I$ Address
|
output[31:0] imem_addr_o, // I$ Address
|
input imem_done_i, // I$ Done
|
input imem_done_i, // I$ Done
|
input[31:0] imem_data_i, // I$ Data
|
input[31:0] imem_data_i, // I$ Data
|
|
|
// Data Memory
|
// Data Memory
|
output dmem_read_o, // D$ Read
|
output dmem_read_o, // D$ Read
|
output dmem_write_o, // D$ Write
|
output dmem_write_o, // D$ Write
|
output[3:0] dmem_sel_o, // D$ Byte selector
|
output[3:0] dmem_sel_o, // D$ Byte selector
|
output[31:0] dmem_addr_o, // D$ Address
|
output[31:0] dmem_addr_o, // D$ Address
|
output[31:0] dmem_data_o, // D$ Write Data
|
output[31:0] dmem_data_o, // D$ Write Data
|
input dmem_done_i, // D$ Done
|
input dmem_done_i, // D$ Done
|
input[31:0] dmem_data_i // D$ Read Data
|
input[31:0] dmem_data_i // D$ Read Data
|
|
|
);
|
);
|
|
|
/*
|
/*
|
* Registers
|
* Registers
|
*/
|
*/
|
|
|
// Register file
|
// Register file
|
reg[31:0] GPR[31:0]; // General Purpose Registers
|
reg[31:0] GPR[31:0]; // General Purpose Registers
|
reg[31:0] PC; // Program Counter
|
reg[31:0] PC; // Program Counter
|
reg[31:0] HI, LO; // HI and LO registers (for multiplication/division)
|
reg[31:0] HI, LO; // HI and LO registers (for multiplication/division)
|
reg[31:0] SysCon[0:31]; // System Control registers
|
reg[31:0] SysCon[0:31]; // System Control registers
|
|
|
/*
|
/*
|
* Pipeline latches
|
* Pipeline latches
|
*/
|
*/
|
|
|
// Latch 1: IF/ID
|
// Latch 1: IF/ID
|
reg[31:0] if_id_opcode; // Instruction Register
|
reg[31:0] if_id_opcode; // Instruction Register
|
reg[31:0] if_id_addr, if_id_addrnext; // Addresses of the fetched opcode and of the next one
|
reg[31:0] if_id_addr, if_id_addrnext; // Addresses of the fetched opcode and of the next one
|
|
|
// Latch 2: ID/EX
|
// Latch 2: ID/EX
|
reg[31:0] id_ex_opcode;
|
reg[31:0] id_ex_opcode;
|
reg[31:0] id_ex_addr, id_ex_addrnext;
|
reg[31:0] id_ex_addr, id_ex_addrnext;
|
reg[31:0] id_ex_addrbranch, id_ex_addrjump, id_ex_addrjr; // Evaluated jump addresses
|
reg[31:0] id_ex_addrbranch, id_ex_addrjump, id_ex_addrjr; // Evaluated jump addresses
|
reg[31:0] id_ex_alu_a, id_ex_alu_b; // ALU operands
|
reg[31:0] id_ex_alu_a, id_ex_alu_b; // ALU operands
|
reg[4:0] id_ex_alu_func; // ALU operation code
|
reg[4:0] id_ex_alu_func; // ALU operation code
|
reg id_ex_alu_signed; // ALU operation is signed
|
reg id_ex_alu_signed; // ALU operation is signed
|
reg id_ex_branch, id_ex_jump, id_ex_jr, id_ex_linked; // Instruction is a jump
|
reg id_ex_branch, id_ex_jump, id_ex_jr, id_ex_linked; // Instruction is a jump
|
reg id_ex_mult, id_ex_div; // Instruction is a multiplication/division
|
reg id_ex_mult, id_ex_div; // Instruction is a multiplication/division
|
reg id_ex_load, id_ex_store; // Instruction is a load/store
|
reg id_ex_load, id_ex_store; // Instruction is a load/store
|
reg[2:0] id_ex_size; // Load/store size (see defs.h)
|
reg[2:0] id_ex_size; // Load/store size (see defs.h)
|
reg[31:0] id_ex_store_value; // Store value
|
reg[31:0] id_ex_store_value; // Store value
|
reg[4:0] id_ex_destreg; // Destination register (GPR number)
|
reg[4:0] id_ex_destreg; // Destination register (GPR number)
|
reg id_ex_desthi, id_ex_destlo; // Destination register (HI/LO)
|
reg id_ex_desthi, id_ex_destlo; // Destination register (HI/LO)
|
reg[4:0] id_ex_destsyscon; // Destination register (System Control)
|
reg[4:0] id_ex_destsyscon; // Destination register (System Control)
|
|
|
// Latch 3: EX/MEM
|
// Latch 3: EX/MEM
|
reg[31:0] ex_mem_opcode;
|
reg[31:0] ex_mem_opcode;
|
reg[31:0] ex_mem_addr, ex_mem_addrnext;
|
reg[31:0] ex_mem_addr, ex_mem_addrnext;
|
reg[31:0] ex_mem_addrbranch, ex_mem_addrjump, ex_mem_addrjr;
|
reg[31:0] ex_mem_addrbranch, ex_mem_addrjump, ex_mem_addrjr;
|
reg[63:0] ex_mem_aluout; // ALU result
|
reg[63:0] ex_mem_aluout; // ALU result
|
reg ex_mem_carry; // ALU carry
|
reg ex_mem_carry; // ALU carry
|
reg ex_mem_branch, ex_mem_jump, ex_mem_jr, ex_mem_linked;
|
reg ex_mem_branch, ex_mem_jump, ex_mem_jr, ex_mem_linked;
|
reg ex_mem_mult, ex_mem_div;
|
reg ex_mem_mult, ex_mem_div;
|
reg ex_mem_load, ex_mem_store;
|
reg ex_mem_load, ex_mem_store;
|
reg[2:0] ex_mem_size;
|
reg[2:0] ex_mem_size;
|
reg[31:0] ex_mem_store_value;
|
reg[31:0] ex_mem_store_value;
|
reg[3:0] ex_mem_store_sel; // Byte Selector on Stores
|
reg[3:0] ex_mem_store_sel; // Byte Selector on Stores
|
reg[31:0] ex_mem_destold; // Old value for partial rewrite
|
reg[31:0] ex_mem_destold; // Old value for partial rewrite
|
reg[4:0] ex_mem_destreg;
|
reg[4:0] ex_mem_destreg;
|
reg ex_mem_desthi, ex_mem_destlo;
|
reg ex_mem_desthi, ex_mem_destlo;
|
reg[4:0] ex_mem_destsyscon;
|
reg[4:0] ex_mem_destsyscon;
|
|
|
// Latch 4: MEM/WB
|
// Latch 4: MEM/WB
|
reg[31:0] mem_wb_opcode;
|
reg[31:0] mem_wb_opcode;
|
reg[31:0] mem_wb_addr, mem_wb_addrnext;
|
reg[31:0] mem_wb_addr, mem_wb_addrnext;
|
reg[63:0] mem_wb_value; // Write-back value
|
reg[63:0] mem_wb_value; // Write-back value
|
reg[4:0] mem_wb_destreg;
|
reg[4:0] mem_wb_destreg;
|
reg mem_wb_desthi, mem_wb_destlo;
|
reg mem_wb_desthi, mem_wb_destlo;
|
reg [4:0] mem_wb_destsyscon;
|
reg [4:0] mem_wb_destsyscon;
|
|
|
/*
|
/*
|
* Combinational logic
|
* Combinational logic
|
*/
|
*/
|
|
|
// ALU
|
// ALU
|
assign alu_a_o = id_ex_alu_a;
|
assign alu_a_o = id_ex_alu_a;
|
assign alu_b_o = id_ex_alu_b;
|
assign alu_b_o = id_ex_alu_b;
|
assign alu_func_o = id_ex_alu_func;
|
assign alu_func_o = id_ex_alu_func;
|
assign alu_signed_o = id_ex_alu_signed;
|
assign alu_signed_o = id_ex_alu_signed;
|
|
|
// Multiplier
|
// Multiplier
|
assign mul_a_o = id_ex_alu_a;
|
assign mul_a_o = id_ex_alu_a;
|
assign mul_b_o = id_ex_alu_b;
|
assign mul_b_o = id_ex_alu_b;
|
assign mul_signed_o = id_ex_alu_signed;
|
assign mul_signed_o = id_ex_alu_signed;
|
wire mul_ready = (mul_req_o==mul_ack_i); // Convert ABP ack to true/false format
|
wire mul_ready = (mul_req_o==mul_ack_i); // Convert ABP ack to true/false format
|
wire mul_busy = !mul_ready;
|
wire mul_busy = !mul_ready;
|
|
|
// Divider
|
// Divider
|
assign div_a_o = id_ex_alu_a;
|
assign div_a_o = id_ex_alu_a;
|
assign div_b_o = id_ex_alu_b;
|
assign div_b_o = id_ex_alu_b;
|
assign div_signed_o = id_ex_alu_signed;
|
assign div_signed_o = id_ex_alu_signed;
|
wire div_ready = (div_req_o==div_ack_i); // Convert ABP ack to true/false format
|
wire div_ready = (div_req_o==div_ack_i); // Convert ABP ack to true/false format
|
wire div_busy = !div_ready;
|
wire div_busy = !div_ready;
|
|
|
// Incremented Program Counter
|
// Incremented Program Counter
|
wire[31:0] PCnext = PC + 4;
|
wire[31:0] PCnext = PC + 4;
|
|
|
// Instruction Memory
|
// Instruction Memory
|
assign imem_read_o = 1;
|
assign imem_read_o = 1;
|
assign imem_addr_o = PC;
|
assign imem_addr_o = PC;
|
|
|
// Data Memory
|
// Data Memory
|
assign dmem_addr_o = ex_mem_aluout;
|
assign dmem_addr_o = ex_mem_aluout;
|
assign dmem_read_o = ex_mem_load;
|
assign dmem_read_o = ex_mem_load;
|
assign dmem_write_o = ex_mem_store;
|
assign dmem_write_o = ex_mem_store;
|
assign dmem_data_o = ex_mem_store_value;
|
assign dmem_data_o = ex_mem_store_value;
|
assign dmem_sel_o = ex_mem_store_sel;
|
assign dmem_sel_o = ex_mem_store_sel;
|
|
|
// Decode fields from the Instruction Register
|
// Decode fields from the Instruction Register
|
wire[5:0] if_id_op = if_id_opcode[31:26]; // Operation code
|
wire[5:0] if_id_op = if_id_opcode[31:26]; // Operation code
|
wire[4:0] if_id_rs = if_id_opcode[25:21]; // Source register
|
wire[4:0] if_id_rs = if_id_opcode[25:21]; // Source register
|
wire[4:0] if_id_rt = if_id_opcode[20:16]; // Target register
|
wire[4:0] if_id_rt = if_id_opcode[20:16]; // Target register
|
wire[4:0] if_id_rd = if_id_opcode[15:11]; // Destination register
|
wire[4:0] if_id_rd = if_id_opcode[15:11]; // Destination register
|
wire[31:0] if_id_imm_signext = {{16{if_id_opcode[15]}}, if_id_opcode[15:0]}; // Immediate field with sign-extension
|
wire[31:0] if_id_imm_signext = {{16{if_id_opcode[15]}}, if_id_opcode[15:0]}; // Immediate field with sign-extension
|
wire[31:0] if_id_imm_zeroext = {16'b0, if_id_opcode[15:0]}; // Immediate field with zero-extension
|
wire[31:0] if_id_imm_zeroext = {16'b0, if_id_opcode[15:0]}; // Immediate field with zero-extension
|
wire[25:0] if_id_index = if_id_opcode[25:0]; // Index field
|
wire[25:0] if_id_index = if_id_opcode[25:0]; // Index field
|
wire[4:0] if_id_shamt = if_id_opcode[10:6]; // Shift amount
|
wire[4:0] if_id_shamt = if_id_opcode[10:6]; // Shift amount
|
wire[5:0] if_id_func = if_id_opcode[5:0]; // Function
|
wire[5:0] if_id_func = if_id_opcode[5:0]; // Function
|
|
|
// True for still undecoded operations that read GPR[rs]
|
// True for still undecoded operations that read GPR[rs]
|
wire if_id_reads_rs = (
|
wire if_id_reads_rs = (
|
if_id_op==`OPCODE_BEQ || if_id_op==`OPCODE_BNE || if_id_op==`OPCODE_BLEZ || if_id_op==`OPCODE_BGTZ ||
|
if_id_op==`OPCODE_BEQ || if_id_op==`OPCODE_BNE || if_id_op==`OPCODE_BLEZ || if_id_op==`OPCODE_BGTZ ||
|
if_id_op==`OPCODE_ADDI || if_id_op==`OPCODE_ADDIU || if_id_op==`OPCODE_SLTI || if_id_op==`OPCODE_SLTIU ||
|
if_id_op==`OPCODE_ADDI || if_id_op==`OPCODE_ADDIU || if_id_op==`OPCODE_SLTI || if_id_op==`OPCODE_SLTIU ||
|
if_id_op==`OPCODE_ANDI || if_id_op==`OPCODE_ORI || if_id_op==`OPCODE_XORI || if_id_op==`OPCODE_LB ||
|
if_id_op==`OPCODE_ANDI || if_id_op==`OPCODE_ORI || if_id_op==`OPCODE_XORI || if_id_op==`OPCODE_LB ||
|
if_id_op==`OPCODE_LH || if_id_op==`OPCODE_LWL || if_id_op==`OPCODE_LW || if_id_op==`OPCODE_LBU ||
|
if_id_op==`OPCODE_LH || if_id_op==`OPCODE_LWL || if_id_op==`OPCODE_LW || if_id_op==`OPCODE_LBU ||
|
if_id_op==`OPCODE_LHU || if_id_op==`OPCODE_LWR || if_id_op==`OPCODE_SB || if_id_op==`OPCODE_SH ||
|
if_id_op==`OPCODE_LHU || if_id_op==`OPCODE_LWR || if_id_op==`OPCODE_SB || if_id_op==`OPCODE_SH ||
|
if_id_op==`OPCODE_SWL || if_id_op==`OPCODE_SW || if_id_op==`OPCODE_SWR || (
|
if_id_op==`OPCODE_SWL || if_id_op==`OPCODE_SW || if_id_op==`OPCODE_SWR || (
|
if_id_op==`OPCODE_SPECIAL && (
|
if_id_op==`OPCODE_SPECIAL && (
|
if_id_func==`FUNCTION_SLLV || if_id_func==`FUNCTION_SRLV || if_id_func==`FUNCTION_SRAV ||
|
if_id_func==`FUNCTION_SLLV || if_id_func==`FUNCTION_SRLV || if_id_func==`FUNCTION_SRAV ||
|
if_id_func==`FUNCTION_JR || if_id_func==`FUNCTION_JALR || if_id_func==`FUNCTION_MTHI ||
|
if_id_func==`FUNCTION_JR || if_id_func==`FUNCTION_JALR || if_id_func==`FUNCTION_MTHI ||
|
if_id_func==`FUNCTION_MTLO || if_id_func==`FUNCTION_MULT || if_id_func==`FUNCTION_MULTU ||
|
if_id_func==`FUNCTION_MTLO || if_id_func==`FUNCTION_MULT || if_id_func==`FUNCTION_MULTU ||
|
if_id_func==`FUNCTION_DIV || if_id_func==`FUNCTION_DIVU || if_id_func==`FUNCTION_ADD ||
|
if_id_func==`FUNCTION_DIV || if_id_func==`FUNCTION_DIVU || if_id_func==`FUNCTION_ADD ||
|
if_id_func==`FUNCTION_ADDU || if_id_func==`FUNCTION_SUB || if_id_func==`FUNCTION_SUBU ||
|
if_id_func==`FUNCTION_ADDU || if_id_func==`FUNCTION_SUB || if_id_func==`FUNCTION_SUBU ||
|
if_id_func==`FUNCTION_AND || if_id_func==`FUNCTION_OR || if_id_func==`FUNCTION_XOR ||
|
if_id_func==`FUNCTION_AND || if_id_func==`FUNCTION_OR || if_id_func==`FUNCTION_XOR ||
|
if_id_func==`FUNCTION_NOR || if_id_func==`FUNCTION_SLT || if_id_func==`FUNCTION_SLTU
|
if_id_func==`FUNCTION_NOR || if_id_func==`FUNCTION_SLT || if_id_func==`FUNCTION_SLTU
|
)
|
)
|
) || (
|
) || (
|
if_id_op==`OPCODE_BCOND && (
|
if_id_op==`OPCODE_BCOND && (
|
if_id_rt==`BCOND_BLTZ || if_id_rt==`BCOND_BGEZ || if_id_rt==`BCOND_BLTZAL || if_id_rt==`BCOND_BGEZAL
|
if_id_rt==`BCOND_BLTZ || if_id_rt==`BCOND_BGEZ || if_id_rt==`BCOND_BLTZAL || if_id_rt==`BCOND_BGEZAL
|
)
|
)
|
)
|
)
|
);
|
);
|
|
|
// True for still undecoded operations that read GPR[rt]
|
// True for still undecoded operations that read GPR[rt]
|
wire if_id_reads_rt = (
|
wire if_id_reads_rt = (
|
if_id_op==`OPCODE_BEQ || if_id_op==`OPCODE_BNE || if_id_op==`OPCODE_SB || if_id_op==`OPCODE_SH ||
|
if_id_op==`OPCODE_BEQ || if_id_op==`OPCODE_BNE || if_id_op==`OPCODE_SB || if_id_op==`OPCODE_SH ||
|
if_id_op==`OPCODE_SWL || if_id_op==`OPCODE_SW || if_id_op==`OPCODE_SWR || (
|
if_id_op==`OPCODE_SWL || if_id_op==`OPCODE_SW || if_id_op==`OPCODE_SWR || (
|
if_id_op==`OPCODE_SPECIAL && (
|
if_id_op==`OPCODE_SPECIAL && (
|
if_id_func==`FUNCTION_SLL || if_id_func==`FUNCTION_SRL || if_id_func==`FUNCTION_SRA ||
|
if_id_func==`FUNCTION_SLL || if_id_func==`FUNCTION_SRL || if_id_func==`FUNCTION_SRA ||
|
if_id_func==`FUNCTION_SLLV || if_id_func==`FUNCTION_SRLV || if_id_func==`FUNCTION_SRAV ||
|
if_id_func==`FUNCTION_SLLV || if_id_func==`FUNCTION_SRLV || if_id_func==`FUNCTION_SRAV ||
|
if_id_func==`FUNCTION_MULT || if_id_func==`FUNCTION_MULTU || if_id_func==`FUNCTION_DIV ||
|
if_id_func==`FUNCTION_MULT || if_id_func==`FUNCTION_MULTU || if_id_func==`FUNCTION_DIV ||
|
if_id_func==`FUNCTION_DIVU || if_id_func==`FUNCTION_ADD || if_id_func==`FUNCTION_ADDU ||
|
if_id_func==`FUNCTION_DIVU || if_id_func==`FUNCTION_ADD || if_id_func==`FUNCTION_ADDU ||
|
if_id_func==`FUNCTION_SUB || if_id_func==`FUNCTION_SUBU || if_id_func==`FUNCTION_AND ||
|
if_id_func==`FUNCTION_SUB || if_id_func==`FUNCTION_SUBU || if_id_func==`FUNCTION_AND ||
|
if_id_func==`FUNCTION_OR || if_id_func==`FUNCTION_XOR || if_id_func==`FUNCTION_NOR ||
|
if_id_func==`FUNCTION_OR || if_id_func==`FUNCTION_XOR || if_id_func==`FUNCTION_NOR ||
|
if_id_func==`FUNCTION_SLT || if_id_func==`FUNCTION_SLTU
|
if_id_func==`FUNCTION_SLT || if_id_func==`FUNCTION_SLTU
|
)
|
)
|
)
|
)
|
);
|
);
|
|
|
// True for still undecoded operations that read the HI register
|
// True for still undecoded operations that read the HI register
|
wire if_id_reads_hi = (if_id_op==`OPCODE_SPECIAL && if_id_func==`FUNCTION_MFHI);
|
wire if_id_reads_hi = (if_id_op==`OPCODE_SPECIAL && if_id_func==`FUNCTION_MFHI);
|
|
|
// True for still undecoded operations that read the LO register
|
// True for still undecoded operations that read the LO register
|
wire if_id_reads_lo = (if_id_op==`OPCODE_SPECIAL && if_id_func==`FUNCTION_MFLO);
|
wire if_id_reads_lo = (if_id_op==`OPCODE_SPECIAL && if_id_func==`FUNCTION_MFLO);
|
|
|
// Finally detect a RAW hazard
|
// Finally detect a RAW hazard
|
wire raw_detected = (
|
wire raw_detected = (
|
(if_id_reads_rs && if_id_rs!=0 &&
|
(if_id_reads_rs && if_id_rs!=0 &&
|
(if_id_rs==id_ex_destreg || if_id_rs==ex_mem_destreg || if_id_rs==mem_wb_destreg)) ||
|
(if_id_rs==id_ex_destreg || if_id_rs==ex_mem_destreg || if_id_rs==mem_wb_destreg)) ||
|
(if_id_reads_rt && if_id_rt!=0 &&
|
(if_id_reads_rt && if_id_rt!=0 &&
|
(if_id_rt==id_ex_destreg || if_id_rt==ex_mem_destreg || if_id_rt==mem_wb_destreg)) ||
|
(if_id_rt==id_ex_destreg || if_id_rt==ex_mem_destreg || if_id_rt==mem_wb_destreg)) ||
|
(if_id_reads_hi && (id_ex_desthi || ex_mem_desthi || mem_wb_desthi)) ||
|
(if_id_reads_hi && (id_ex_desthi || ex_mem_desthi || mem_wb_desthi)) ||
|
(if_id_reads_lo && (id_ex_destlo || ex_mem_destlo || mem_wb_destlo))
|
(if_id_reads_lo && (id_ex_destlo || ex_mem_destlo || mem_wb_destlo))
|
);
|
);
|
|
|
// Stall signals for all the stages
|
// Stall signals for all the stages
|
wire if_stall, id_stall, ex_stall, mem_stall, wb_stall;
|
wire if_stall, id_stall, ex_stall, mem_stall, wb_stall;
|
assign if_stall = id_stall || !imem_done_i;
|
assign if_stall = id_stall || !imem_done_i;
|
assign id_stall = ex_stall || raw_detected;
|
assign id_stall = ex_stall || raw_detected;
|
assign ex_stall = mem_stall || mul_busy || div_busy;
|
assign ex_stall = mem_stall || mul_busy || div_busy;
|
assign mem_stall = wb_stall || ( (dmem_read_o||dmem_write_o) && !dmem_done_i);
|
assign mem_stall = wb_stall || ( (dmem_read_o||dmem_write_o) && !dmem_done_i);
|
assign wb_stall = 0;
|
assign wb_stall = 0;
|
|
|
|
// Branch taken
|
|
wire branch_taken;
|
|
assign branch_taken = ( ex_mem_branch==1 && (ex_mem_aluout==32'h00000001) );
|
|
|
// Name the System Configuration registers
|
// Name the System Configuration registers
|
wire[31:0] BadVAddr = SysCon[`SYSCON_BADVADDR];
|
wire[31:0] BadVAddr = SysCon[`SYSCON_BADVADDR];
|
wire[31:0] Status = SysCon[`SYSCON_STATUS];
|
wire[31:0] Status = SysCon[`SYSCON_STATUS];
|
wire[31:0] Cause = SysCon[`SYSCON_CAUSE];
|
wire[31:0] Cause = SysCon[`SYSCON_CAUSE];
|
wire[31:0] EPC = SysCon[`SYSCON_EPC];
|
wire[31:0] EPC = SysCon[`SYSCON_EPC];
|
wire[31:0] PrID = SysCon[`SYSCON_PRID];
|
wire[31:0] PrID = SysCon[`SYSCON_PRID];
|
|
|
// Index for GPR initialization
|
// Index for GPR initialization
|
integer i;
|
integer i;
|
|
|
/*
|
/*
|
* Sequential logic
|
* Sequential logic
|
*/
|
*/
|
|
|
always @ (posedge sys_clock_i) begin
|
always @ (posedge sys_clock_i) begin
|
|
|
// Initialize all the registers
|
// Initialize all the registers
|
if (sys_reset_i==1) begin
|
if (sys_reset_i==1) begin
|
|
|
// GPRs initialization
|
// GPRs initialization
|
for(i=0; i<=31; i=i+1) GPR[i] <= 32'h00000000;
|
for(i=0; i<=31; i=i+1) GPR[i] <= 32'h00000000;
|
|
|
// System registers
|
// System registers
|
PC <= `BOOT_ADDRESS;
|
PC <= `BOOT_ADDRESS;
|
HI <= 0;
|
HI <= 0;
|
LO <= 0;
|
LO <= 0;
|
|
|
// Initialize system configuration registers
|
// Initialize system configuration registers
|
for(i=0; i<=31; i=i+1) SysCon[i] <= 32'h00000000;
|
for(i=0; i<=31; i=i+1) SysCon[i] <= 32'h00000000;
|
|
|
// Initialize ABP requests to instantiated modules
|
// Initialize ABP requests to instantiated modules
|
mul_req_o <= 0;
|
mul_req_o <= 0;
|
div_req_o <= 0;
|
div_req_o <= 0;
|
|
|
// Latch 1: IF/ID
|
// Latch 1: IF/ID
|
if_id_opcode <= `NOP;
|
if_id_opcode <= `NOP;
|
if_id_addr <= `BOOT_ADDRESS;
|
if_id_addr <= `BOOT_ADDRESS;
|
if_id_addrnext <= 0;
|
if_id_addrnext <= 0;
|
|
|
// Latch 2: ID/EX
|
// Latch 2: ID/EX
|
id_ex_opcode <= 0;
|
id_ex_opcode <= 0;
|
id_ex_addr <= 0;
|
id_ex_addr <= 0;
|
id_ex_addrnext <= 0;
|
id_ex_addrnext <= 0;
|
id_ex_addrjump <= 0;
|
id_ex_addrjump <= 0;
|
id_ex_addrbranch <= 0;
|
id_ex_addrbranch <= 0;
|
id_ex_alu_a <= 0;
|
id_ex_alu_a <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <=0;
|
id_ex_jr <=0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
|
|
ex_mem_opcode <= 0;
|
ex_mem_opcode <= 0;
|
ex_mem_addr <= 0;
|
ex_mem_addr <= 0;
|
ex_mem_addrnext <= 0;
|
ex_mem_addrnext <= 0;
|
ex_mem_addrjump <= 0;
|
ex_mem_addrjump <= 0;
|
ex_mem_addrbranch <= 0;
|
ex_mem_addrbranch <= 0;
|
ex_mem_aluout <= 0;
|
ex_mem_aluout <= 0;
|
ex_mem_carry <= 0;
|
ex_mem_carry <= 0;
|
ex_mem_branch <= 0;
|
ex_mem_branch <= 0;
|
ex_mem_jump <= 0;
|
ex_mem_jump <= 0;
|
ex_mem_jr <= 0;
|
ex_mem_jr <= 0;
|
ex_mem_linked <= 0;
|
ex_mem_linked <= 0;
|
ex_mem_mult <= 0;
|
ex_mem_mult <= 0;
|
ex_mem_div <= 0;
|
ex_mem_div <= 0;
|
ex_mem_load <= 0;
|
ex_mem_load <= 0;
|
ex_mem_store <= 0;
|
ex_mem_store <= 0;
|
ex_mem_store_value <= 0;
|
ex_mem_store_value <= 0;
|
ex_mem_store_sel <= 0;
|
ex_mem_store_sel <= 0;
|
ex_mem_destreg <= 0;
|
ex_mem_destreg <= 0;
|
ex_mem_desthi <= 0;
|
ex_mem_desthi <= 0;
|
ex_mem_destlo <= 0;
|
ex_mem_destlo <= 0;
|
|
|
// Latch 4: MEM/WB
|
// Latch 4: MEM/WB
|
mem_wb_opcode <= 0;
|
mem_wb_opcode <= 0;
|
mem_wb_addr <= 0;
|
mem_wb_addr <= 0;
|
mem_wb_addrnext <= 0;
|
mem_wb_addrnext <= 0;
|
mem_wb_value <= 0;
|
mem_wb_value <= 0;
|
mem_wb_destreg <= 0;
|
mem_wb_destreg <= 0;
|
mem_wb_desthi <= 0;
|
mem_wb_desthi <= 0;
|
mem_wb_destlo <= 0;
|
mem_wb_destlo <= 0;
|
|
|
end else begin
|
end else begin
|
|
|
$display("================> Time %t <================", $time);
|
$display("================> Time %t <================", $time);
|
|
|
/*
|
/*
|
* Pipeline Stage 1: Instruction Fetch (IF)
|
* Pipeline Stage 1: Instruction Fetch (IF)
|
*
|
*
|
* READ/WRITE:
|
* READ/WRITE:
|
* - read memory
|
* - read memory
|
* - write the IF/ID latch
|
* - write the IF/ID latch
|
* - write the PC register
|
* - write the PC register
|
*
|
*
|
* DESCRIPTION:
|
* DESCRIPTION:
|
* This stage usually reads the next instruction from the PC address in memory and
|
* This stage usually reads the next instruction from the PC address in memory and
|
* then updates the PC value by incrementing it by 4.
|
* then updates the PC value by incrementing it by 4.
|
* When a hazard is detected this stage is idle.
|
|
*/
|
*/
|
|
|
// A RAW hazard will stall the CPU
|
// Handle hazards (if_stall = id_stall || !imem_done_i)
|
if(if_stall) begin
|
if(if_stall) begin
|
|
|
|
// IF stall backward propagated from ID
|
if(id_stall) begin
|
if(id_stall) begin
|
$display("INFO: CPU(%m)-IF: Fetching stalled and latch kept for following stalled pipeline stage");
|
$display("INFO: CPU(%m)-IF: Fetching stalled like ID, latch keeps old value");
|
|
// IMEM is not ready
|
end else begin
|
end else begin
|
$display("INFO: CPU(%m)-IF: Fetching stalled and bubble inserted for following running pipeline stage");
|
$display("INFO: CPU(%m)-IF: Fetching stalled due to IMEM, latch filled with bubble");
|
if_id_opcode <= `BUBBLE;
|
if_id_opcode <= `BUBBLE;
|
end
|
end
|
|
|
end else begin
|
end else begin
|
|
|
// If branch taken update the Program Counter
|
// If branch taken update the Program Counter (branch_taken = ex_mem_branch==1 && ex_mem_aluout==32'h00000001)
|
if(ex_mem_branch==1 && ex_mem_aluout==32'h00000001) begin
|
if(branch_taken) begin
|
|
|
$display("INFO: CPU(%m)-IF: Bubble inserted due branch taken in EX/MEM instruction @ADDR=%X w/OPCODE=%X having ALUout=%X", ex_mem_addr, ex_mem_opcode, ex_mem_aluout);
|
$display("INFO: CPU(%m)-IF: Bubble inserted due branch taken in EX/MEM instruction @ADDR=%X w/OPCODE=%X having ALUout=%X", ex_mem_addr, ex_mem_opcode, ex_mem_aluout);
|
if_id_opcode <= `BUBBLE;
|
if_id_opcode <= `BUBBLE;
|
PC <= ex_mem_addrbranch;
|
PC <= ex_mem_addrbranch;
|
|
|
// Jump to the required immediate address
|
// Jump to the required immediate address
|
end else if(id_ex_jump==1) begin
|
end else if(id_ex_jump==1) begin
|
|
|
$display("INFO: CPU(%m)-IF: Bubble inserted due to jump in ID/EX instruction @ADDR=%X w/OPCODE=%X", id_ex_addr, id_ex_opcode);
|
$display("INFO: CPU(%m)-IF: Bubble inserted due to jump in ID/EX instruction @ADDR=%X w/OPCODE=%X", id_ex_addr, id_ex_opcode);
|
if_id_opcode <= `BUBBLE;
|
if_id_opcode <= `BUBBLE;
|
PC <= id_ex_addrjump;
|
PC <= id_ex_addrjump;
|
|
|
// Jump to the required address stored in GPR
|
// Jump to the required address stored in GPR
|
end else if(id_ex_jr==1) begin
|
end else if(id_ex_jr==1) begin
|
|
|
$display("INFO: CPU(%m)-IF: Bubble inserted due to jump register in ID/EX instruction @ADDR=%X w/OPCODE=%X", id_ex_addr, id_ex_opcode);
|
$display("INFO: CPU(%m)-IF: Bubble inserted due to jump register in ID/EX instruction @ADDR=%X w/OPCODE=%X", id_ex_addr, id_ex_opcode);
|
if_id_opcode <= `BUBBLE;
|
if_id_opcode <= `BUBBLE;
|
PC <= id_ex_addrjr;
|
PC <= id_ex_addrjr;
|
|
|
// Normal execution
|
// Normal execution
|
end else begin
|
end else begin
|
|
|
$display("INFO: CPU(%m)-IF: Fetched from Program Counter @ADDR=%h getting OPCODE=%X", PC, imem_data_i);
|
$display("INFO: CPU(%m)-IF: Fetched from Program Counter @ADDR=%h getting OPCODE=%X", PC, imem_data_i);
|
if_id_opcode <= imem_data_i;
|
if_id_opcode <= imem_data_i;
|
if_id_addr <= PC;
|
if_id_addr <= PC;
|
if_id_addrnext <= PCnext;
|
if_id_addrnext <= PCnext;
|
PC <= PCnext;
|
PC <= PCnext;
|
|
|
end
|
end
|
end
|
end
|
|
|
/*
|
/*
|
* Pipeline Stage 2: Instruction Decode (ID)
|
* Pipeline Stage 2: Instruction Decode (ID)
|
*
|
*
|
* READ/WRITE:
|
* READ/WRITE:
|
* - read the IF/ID latch
|
* - read the IF/ID latch
|
* - read the register file
|
* - read the register file
|
* - write the ID/EX latch
|
* - write the ID/EX latch
|
*
|
*
|
* DESCRIPTION:
|
* DESCRIPTION:
|
* This stage decodes the instruction and puts the values for the ALU inputs
|
* This stage decodes the instruction and puts the values for the ALU inputs
|
*/
|
*/
|
|
|
if(id_stall) begin
|
if(branch_taken) begin
|
|
$display("INFO: CPU(%m)-ID: Branch taken and bubble inserted");
|
|
id_ex_opcode <=`BUBBLE;
|
|
id_ex_alu_a <= 0;
|
|
id_ex_alu_b <= 0;
|
|
id_ex_alu_func <= `ALU_OP_ADD;
|
|
id_ex_alu_signed <= 0;
|
|
id_ex_addr <= if_id_addr;
|
|
id_ex_addrnext <= 0;
|
|
id_ex_addrjump <= 0;
|
|
id_ex_addrbranch <= 0;
|
|
id_ex_branch <= 0;
|
|
id_ex_jump <= 0;
|
|
id_ex_jr <= 0;
|
|
id_ex_linked <= 0;
|
|
id_ex_mult <= 0;
|
|
id_ex_div <= 0;
|
|
id_ex_load <= 0;
|
|
id_ex_store <= 0;
|
|
id_ex_destreg <= 0;
|
|
id_ex_desthi <= 0;
|
|
id_ex_destlo <= 0;
|
|
end else if(id_stall) begin
|
|
|
if(ex_stall) begin
|
if(ex_stall) begin
|
$display("INFO: CPU(%m)-ID: Decoding stalled and latch kept for following stalled pipeline stage");
|
$display("INFO: CPU(%m)-ID: Decoding stalled and latch kept");
|
end else begin
|
end else begin
|
$display("INFO: CPU(%m)-ID: Decoding stalled and bubble inserted for following running pipeline stage");
|
$display("INFO: CPU(%m)-ID: Decoding stalled and bubble inserted");
|
id_ex_opcode <=`BUBBLE;
|
id_ex_opcode <=`BUBBLE;
|
id_ex_alu_a <= 0;
|
id_ex_alu_a <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_addr <= if_id_addr;
|
id_ex_addr <= if_id_addr;
|
id_ex_addrnext <= 0;
|
id_ex_addrnext <= 0;
|
id_ex_addrjump <= 0;
|
id_ex_addrjump <= 0;
|
id_ex_addrbranch <= 0;
|
id_ex_addrbranch <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
end else begin
|
end else begin
|
id_ex_opcode <= if_id_opcode;
|
id_ex_opcode <= if_id_opcode;
|
id_ex_addr <= if_id_addr;
|
id_ex_addr <= if_id_addr;
|
id_ex_addrnext <= if_id_addrnext;
|
id_ex_addrnext <= if_id_addrnext;
|
id_ex_addrbranch <= if_id_addrnext + {if_id_imm_signext[29:0], 2'b00};
|
id_ex_addrbranch <= if_id_addrnext + {if_id_imm_signext[29:0], 2'b00};
|
id_ex_addrjump <= {if_id_addr[31:28], if_id_index, 2'b00};
|
id_ex_addrjump <= {if_id_addr[31:28], if_id_index, 2'b00};
|
id_ex_addrjr <= GPR[if_id_rs];
|
id_ex_addrjr <= GPR[if_id_rs];
|
|
|
if(if_id_opcode==`BUBBLE) begin
|
if(if_id_opcode==`BUBBLE) begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BUBBLE", if_id_addr, if_id_opcode);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BUBBLE", if_id_addr, if_id_opcode);
|
id_ex_alu_a <= 0;
|
id_ex_alu_a <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end else case(if_id_op)
|
end else case(if_id_op)
|
`OPCODE_J:
|
`OPCODE_J:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as J %h", if_id_addr, if_id_opcode, if_id_index);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as J %h", if_id_addr, if_id_opcode, if_id_index);
|
id_ex_alu_a <= 0;
|
id_ex_alu_a <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 1;
|
id_ex_jump <= 1;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_JAL:
|
`OPCODE_JAL:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as JAL %h", if_id_addr, if_id_opcode, if_id_index);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as JAL %h", if_id_addr, if_id_opcode, if_id_index);
|
id_ex_alu_a <= if_id_addrnext;
|
id_ex_alu_a <= if_id_addrnext;
|
id_ex_alu_b <= 4;
|
id_ex_alu_b <= 4;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 1;
|
id_ex_jump <= 1;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 1;
|
id_ex_linked <= 1;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 31;
|
id_ex_destreg <= 31;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_BEQ:
|
`OPCODE_BEQ:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BEQ r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_rt, if_id_imm_signext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BEQ r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_rt, if_id_imm_signext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_SEQ;
|
id_ex_alu_func <= `ALU_OP_SEQ;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 1;
|
id_ex_branch <= 1;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_BNE:
|
`OPCODE_BNE:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BNE r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_rt, if_id_imm_signext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BNE r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_rt, if_id_imm_signext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_SNE;
|
id_ex_alu_func <= `ALU_OP_SNE;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 1;
|
id_ex_branch <= 1;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_BLEZ:
|
`OPCODE_BLEZ:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BLEZ r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_imm_signext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BLEZ r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_imm_signext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_SLE;
|
id_ex_alu_func <= `ALU_OP_SLE;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 1;
|
id_ex_branch <= 1;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_BGTZ:
|
`OPCODE_BGTZ:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BGTZ r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_imm_signext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BGTZ r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_imm_signext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_SGT;
|
id_ex_alu_func <= `ALU_OP_SGT;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 1;
|
id_ex_branch <= 1;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_ADDI:
|
`OPCODE_ADDI:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as ADDI r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_signext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as ADDI r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_signext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_ADDIU:
|
`OPCODE_ADDIU:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as ADDIU r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_signext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as ADDIU r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_signext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_SLTI:
|
`OPCODE_SLTI:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SLTI r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_signext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SLTI r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_signext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_SLT;
|
id_ex_alu_func <= `ALU_OP_SLT;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_SLTIU:
|
`OPCODE_SLTIU:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SLTIU r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_signext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SLTIU r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_signext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_SLT;
|
id_ex_alu_func <= `ALU_OP_SLT;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_ANDI:
|
`OPCODE_ANDI:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as ANDI r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_zeroext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as ANDI r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_zeroext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_zeroext;
|
id_ex_alu_b <= if_id_imm_zeroext;
|
id_ex_alu_func <= `ALU_OP_AND;
|
id_ex_alu_func <= `ALU_OP_AND;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_ORI:
|
`OPCODE_ORI:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as ORI r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_zeroext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as ORI r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_zeroext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_zeroext;
|
id_ex_alu_b <= if_id_imm_zeroext;
|
id_ex_alu_func <= `ALU_OP_OR;
|
id_ex_alu_func <= `ALU_OP_OR;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_XORI:
|
`OPCODE_XORI:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as XORI r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_zeroext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as XORI r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_rs, if_id_imm_zeroext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_zeroext;
|
id_ex_alu_b <= if_id_imm_zeroext;
|
id_ex_alu_func <= `ALU_OP_XOR;
|
id_ex_alu_func <= `ALU_OP_XOR;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_LUI:
|
`OPCODE_LUI:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LUI r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_zeroext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LUI r%d, %h", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_zeroext);
|
id_ex_alu_a <= if_id_imm_zeroext;
|
id_ex_alu_a <= if_id_imm_zeroext;
|
id_ex_alu_b <= 16;
|
id_ex_alu_b <= 16;
|
id_ex_alu_func <= `ALU_OP_SLL;
|
id_ex_alu_func <= `ALU_OP_SLL;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_COP0:
|
`OPCODE_COP0:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as COP0", if_id_addr, if_id_opcode);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as COP0", if_id_addr, if_id_opcode);
|
end
|
end
|
`OPCODE_COP1:
|
`OPCODE_COP1:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as COP1", if_id_addr, if_id_opcode);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as COP1", if_id_addr, if_id_opcode);
|
end
|
end
|
`OPCODE_COP2:
|
`OPCODE_COP2:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as COP2", if_id_addr, if_id_opcode);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as COP2", if_id_addr, if_id_opcode);
|
end
|
end
|
`OPCODE_COP3:
|
`OPCODE_COP3:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as COP3", if_id_addr, if_id_opcode);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as COP3", if_id_addr, if_id_opcode);
|
end
|
end
|
`OPCODE_LB:
|
`OPCODE_LB:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LB r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LB r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 1;
|
id_ex_load <= 1;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= `SIZE_BYTE;
|
id_ex_size <= `SIZE_BYTE;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_LH:
|
`OPCODE_LH:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LH r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LH r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 1;
|
id_ex_load <= 1;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= `SIZE_HALF;
|
id_ex_size <= `SIZE_HALF;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_LWL:
|
`OPCODE_LWL:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LWL r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LWL r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 1;
|
id_ex_load <= 1;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= `SIZE_LEFT;
|
id_ex_size <= `SIZE_LEFT;
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_LW:
|
`OPCODE_LW:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LW r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LW r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 1;
|
id_ex_load <= 1;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= `SIZE_WORD;
|
id_ex_size <= `SIZE_WORD;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_LBU:
|
`OPCODE_LBU:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LBU r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LBU r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 1;
|
id_ex_load <= 1;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= `SIZE_BYTE;
|
id_ex_size <= `SIZE_BYTE;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_LHU:
|
`OPCODE_LHU:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LHU r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LHU r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 1;
|
id_ex_load <= 1;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= `SIZE_HALF;
|
id_ex_size <= `SIZE_HALF;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_LWR:
|
`OPCODE_LWR:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LWR r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LWR r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 1;
|
id_ex_load <= 1;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= `SIZE_RIGHT;
|
id_ex_size <= `SIZE_RIGHT;
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_destreg <= if_id_rt;
|
id_ex_destreg <= if_id_rt;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_SB:
|
`OPCODE_SB:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SB r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SB r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 1;
|
id_ex_store <= 1;
|
id_ex_size <= `SIZE_BYTE;
|
id_ex_size <= `SIZE_BYTE;
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_SH:
|
`OPCODE_SH:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SH r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SH r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 1;
|
id_ex_store <= 1;
|
id_ex_size <= `SIZE_HALF;
|
id_ex_size <= `SIZE_HALF;
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_SWL:
|
`OPCODE_SWL:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SWL r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SWL r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 1;
|
id_ex_store <= 1;
|
id_ex_size <= `SIZE_LEFT;
|
id_ex_size <= `SIZE_LEFT;
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_SW:
|
`OPCODE_SW:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SW r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SW r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 1;
|
id_ex_store <= 1;
|
id_ex_size <= `SIZE_WORD;
|
id_ex_size <= `SIZE_WORD;
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_SWR:
|
`OPCODE_SWR:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SWR r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SWR r%d, %d(r%d)", if_id_addr, if_id_opcode, if_id_rt, if_id_imm_signext, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_b <= if_id_imm_signext;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 1;
|
id_ex_store <= 1;
|
id_ex_size <= `SIZE_RIGHT;
|
id_ex_size <= `SIZE_RIGHT;
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_store_value <= GPR[if_id_rt];
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`OPCODE_LWC1:
|
`OPCODE_LWC1:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LWC1", if_id_addr, if_id_opcode);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LWC1", if_id_addr, if_id_opcode);
|
end
|
end
|
`OPCODE_LWC2:
|
`OPCODE_LWC2:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LWC2", if_id_addr, if_id_opcode);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LWC2", if_id_addr, if_id_opcode);
|
end
|
end
|
`OPCODE_LWC3:
|
`OPCODE_LWC3:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LWC3", if_id_addr, if_id_opcode);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as LWC3", if_id_addr, if_id_opcode);
|
end
|
end
|
`OPCODE_SWC1:
|
`OPCODE_SWC1:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SWC1", if_id_addr, if_id_opcode);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SWC1", if_id_addr, if_id_opcode);
|
end
|
end
|
`OPCODE_SWC2:
|
`OPCODE_SWC2:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SWC2", if_id_addr, if_id_opcode);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SWC2", if_id_addr, if_id_opcode);
|
end
|
end
|
`OPCODE_SWC3:
|
`OPCODE_SWC3:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SWC3", if_id_addr, if_id_opcode);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SWC3", if_id_addr, if_id_opcode);
|
end
|
end
|
`OPCODE_SPECIAL:
|
`OPCODE_SPECIAL:
|
case(if_id_func)
|
case(if_id_func)
|
`FUNCTION_SLL:
|
`FUNCTION_SLL:
|
begin
|
begin
|
if(if_id_opcode==`NOP) $display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as NOP", if_id_addr, if_id_opcode);
|
if(if_id_opcode==`NOP) $display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as NOP", if_id_addr, if_id_opcode);
|
else $display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SLL r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rd, if_id_rt, if_id_shamt);
|
else $display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SLL r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rd, if_id_rt, if_id_shamt);
|
id_ex_alu_a <= GPR[if_id_rt];
|
id_ex_alu_a <= GPR[if_id_rt];
|
id_ex_alu_b <= if_id_shamt;
|
id_ex_alu_b <= if_id_shamt;
|
id_ex_alu_func <= `ALU_OP_SLL;
|
id_ex_alu_func <= `ALU_OP_SLL;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_SRL:
|
`FUNCTION_SRL:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SRL r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rd, if_id_rt, if_id_shamt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SRL r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rd, if_id_rt, if_id_shamt);
|
id_ex_alu_a <= GPR[if_id_rt];
|
id_ex_alu_a <= GPR[if_id_rt];
|
id_ex_alu_b <= if_id_shamt;
|
id_ex_alu_b <= if_id_shamt;
|
id_ex_alu_func <= `ALU_OP_SRL;
|
id_ex_alu_func <= `ALU_OP_SRL;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_SRA:
|
`FUNCTION_SRA:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SRA r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rd, if_id_rt, if_id_shamt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SRA r%d, r%d, %h", if_id_addr, if_id_opcode, if_id_rd, if_id_rt, if_id_shamt);
|
id_ex_alu_a <= GPR[if_id_rt];
|
id_ex_alu_a <= GPR[if_id_rt];
|
id_ex_alu_b <= if_id_shamt;
|
id_ex_alu_b <= if_id_shamt;
|
id_ex_alu_func <= `ALU_OP_SRA;
|
id_ex_alu_func <= `ALU_OP_SRA;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_SLLV:
|
`FUNCTION_SLLV:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SLLV r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rt, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SLLV r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rt, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rt];
|
id_ex_alu_a <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rs];
|
id_ex_alu_func <= `ALU_OP_SLL;
|
id_ex_alu_func <= `ALU_OP_SLL;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_SRLV:
|
`FUNCTION_SRLV:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SRLV r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rt, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SRLV r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rt, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rt];
|
id_ex_alu_a <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rs];
|
id_ex_alu_func <= `ALU_OP_SRL;
|
id_ex_alu_func <= `ALU_OP_SRL;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_SRAV:
|
`FUNCTION_SRAV:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SRAV r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rt, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SRAV r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rt, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rt];
|
id_ex_alu_a <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rs];
|
id_ex_alu_func <= `ALU_OP_SRA;
|
id_ex_alu_func <= `ALU_OP_SRA;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_JR:
|
`FUNCTION_JR:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as JR r%d", if_id_addr, if_id_opcode, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as JR r%d", if_id_addr, if_id_opcode, if_id_rs);
|
id_ex_alu_a <= 0;
|
id_ex_alu_a <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 1;
|
id_ex_jr <= 1;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_JALR:
|
`FUNCTION_JALR:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as JALR [r%d,] r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as JALR [r%d,] r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs);
|
id_ex_alu_a <= if_id_addrnext;
|
id_ex_alu_a <= if_id_addrnext;
|
id_ex_alu_b <= 4;
|
id_ex_alu_b <= 4;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 1;
|
id_ex_jr <= 1;
|
id_ex_linked <= 1;
|
id_ex_linked <= 1;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_SYSCALL:
|
`FUNCTION_SYSCALL:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SYSCALL", if_id_addr, if_id_opcode);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SYSCALL", if_id_addr, if_id_opcode);
|
// id_ex_alu_a <= 0;
|
// id_ex_alu_a <= 0;
|
// id_ex_alu_b <= 0;
|
// id_ex_alu_b <= 0;
|
// id_ex_alu_func <= `ALU_OP_ADD;
|
// id_ex_alu_func <= `ALU_OP_ADD;
|
// id_ex_alu_signed <= 0;
|
// id_ex_alu_signed <= 0;
|
// id_ex_branch <= 0;
|
// id_ex_branch <= 0;
|
// id_ex_jump <= 0;
|
// id_ex_jump <= 0;
|
// id_ex_jr <= 0;
|
// id_ex_jr <= 0;
|
// id_ex_linked <= 0;
|
// id_ex_linked <= 0;
|
// id_ex_mult <= 0;
|
// id_ex_mult <= 0;
|
// id_ex_div <= 0;
|
// id_ex_div <= 0;
|
// id_ex_load <= 0;
|
// id_ex_load <= 0;
|
// id_ex_store <= 0;
|
// id_ex_store <= 0;
|
// id_ex_size <= 0;
|
// id_ex_size <= 0;
|
// id_ex_store_value <= 0;
|
// id_ex_store_value <= 0;
|
// id_ex_destreg <= 0;
|
// id_ex_destreg <= 0;
|
// id_ex_desthi <= 0;
|
// id_ex_desthi <= 0;
|
// id_ex_destlo <= 0;
|
// id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_BREAK:
|
`FUNCTION_BREAK:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BREAK", if_id_addr, if_id_opcode);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BREAK", if_id_addr, if_id_opcode);
|
// id_ex_alu_a <= 0;
|
// id_ex_alu_a <= 0;
|
// id_ex_alu_b <= 0;
|
// id_ex_alu_b <= 0;
|
// id_ex_alu_func <= `ALU_OP_ADD;
|
// id_ex_alu_func <= `ALU_OP_ADD;
|
// id_ex_alu_signed <= 0;
|
// id_ex_alu_signed <= 0;
|
// id_ex_branch <= 0;
|
// id_ex_branch <= 0;
|
// id_ex_jump <= 0;
|
// id_ex_jump <= 0;
|
// id_ex_jr <= 0;
|
// id_ex_jr <= 0;
|
// id_ex_linked <= 0;
|
// id_ex_linked <= 0;
|
// id_ex_mult <= 0;
|
// id_ex_mult <= 0;
|
// id_ex_div <= 0;
|
// id_ex_div <= 0;
|
// id_ex_load <= 0;
|
// id_ex_load <= 0;
|
// id_ex_store <= 0;
|
// id_ex_store <= 0;
|
// id_ex_size <= 0;
|
// id_ex_size <= 0;
|
// id_ex_store_value <= 0;
|
// id_ex_store_value <= 0;
|
// id_ex_destreg <= 0;
|
// id_ex_destreg <= 0;
|
// id_ex_desthi <= 0;
|
// id_ex_desthi <= 0;
|
// id_ex_destlo <= 0;
|
// id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_MFHI:
|
`FUNCTION_MFHI:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as MFHI r%d", if_id_addr, if_id_opcode, if_id_rd);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as MFHI r%d", if_id_addr, if_id_opcode, if_id_rd);
|
id_ex_alu_a <= HI;
|
id_ex_alu_a <= HI;
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_MTHI:
|
`FUNCTION_MTHI:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as MTHI r%d", if_id_addr, if_id_opcode, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as MTHI r%d", if_id_addr, if_id_opcode, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 1;
|
id_ex_desthi <= 1;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_MFLO:
|
`FUNCTION_MFLO:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as MFLO r%d", if_id_addr, if_id_opcode, if_id_rd);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as MFLO r%d", if_id_addr, if_id_opcode, if_id_rd);
|
id_ex_alu_a <= LO;
|
id_ex_alu_a <= LO;
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_MTLO:
|
`FUNCTION_MTLO:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as MTLO r%d", if_id_addr, if_id_opcode, if_id_rs);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as MTLO r%d", if_id_addr, if_id_opcode, if_id_rs);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 1;
|
id_ex_destlo <= 1;
|
end
|
end
|
`FUNCTION_MULT:
|
`FUNCTION_MULT:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as MULT r%d, r%d", if_id_addr, if_id_opcode, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as MULT r%d, r%d", if_id_addr, if_id_opcode, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_MULT;
|
id_ex_alu_func <= `ALU_OP_MULT;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 1;
|
id_ex_mult <= 1;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 1;
|
id_ex_desthi <= 1;
|
id_ex_destlo <= 1;
|
id_ex_destlo <= 1;
|
mul_req_o <= !mul_req_o; // Toggle the ABP request
|
mul_req_o <= !mul_req_o; // Toggle the ABP request
|
end
|
end
|
`FUNCTION_MULTU:
|
`FUNCTION_MULTU:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as MULTU r%d, r%d", if_id_addr, if_id_opcode, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as MULTU r%d, r%d", if_id_addr, if_id_opcode, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_MULT;
|
id_ex_alu_func <= `ALU_OP_MULT;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 1;
|
id_ex_mult <= 1;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 1;
|
id_ex_desthi <= 1;
|
id_ex_destlo <= 1;
|
id_ex_destlo <= 1;
|
mul_req_o <= !mul_req_o; // Toggle the ABP request
|
mul_req_o <= !mul_req_o; // Toggle the ABP request
|
end
|
end
|
`FUNCTION_DIV:
|
`FUNCTION_DIV:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as DIV r%d, r%d", if_id_addr, if_id_opcode, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as DIV r%d, r%d", if_id_addr, if_id_opcode, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_DIV;
|
id_ex_alu_func <= `ALU_OP_DIV;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 1;
|
id_ex_div <= 1;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 1;
|
id_ex_desthi <= 1;
|
id_ex_destlo <= 1;
|
id_ex_destlo <= 1;
|
div_req_o <= !div_req_o; // Toggle the ABP request
|
div_req_o <= !div_req_o; // Toggle the ABP request
|
end
|
end
|
`FUNCTION_DIVU:
|
`FUNCTION_DIVU:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as DIVU r%d, r%d", if_id_addr, if_id_opcode, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as DIVU r%d, r%d", if_id_addr, if_id_opcode, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_DIV;
|
id_ex_alu_func <= `ALU_OP_DIV;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 1;
|
id_ex_div <= 1;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 0;
|
id_ex_destreg <= 0;
|
id_ex_desthi <= 1;
|
id_ex_desthi <= 1;
|
id_ex_destlo <= 1;
|
id_ex_destlo <= 1;
|
div_req_o <= !div_req_o; // Toggle the ABP request
|
div_req_o <= !div_req_o; // Toggle the ABP request
|
end
|
end
|
`FUNCTION_ADD:
|
`FUNCTION_ADD:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as ADD r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as ADD r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_ADDU:
|
`FUNCTION_ADDU:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as ADDU r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as ADDU r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_func <= `ALU_OP_ADD;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_SUB:
|
`FUNCTION_SUB:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SUB r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SUB r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_SUB;
|
id_ex_alu_func <= `ALU_OP_SUB;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_SUBU:
|
`FUNCTION_SUBU:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SUBU r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SUBU r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_SUB;
|
id_ex_alu_func <= `ALU_OP_SUB;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_AND:
|
`FUNCTION_AND:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as AND r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as AND r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_AND;
|
id_ex_alu_func <= `ALU_OP_AND;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_OR:
|
`FUNCTION_OR:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as OR r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as OR r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_OR;
|
id_ex_alu_func <= `ALU_OP_OR;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_XOR:
|
`FUNCTION_XOR:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as XOR r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as XOR r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_XOR;
|
id_ex_alu_func <= `ALU_OP_XOR;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_NOR:
|
`FUNCTION_NOR:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as NOR r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as NOR r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_NOR;
|
id_ex_alu_func <= `ALU_OP_NOR;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_SLT:
|
`FUNCTION_SLT:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SLT r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SLT r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_SLT;
|
id_ex_alu_func <= `ALU_OP_SLT;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`FUNCTION_SLTU:
|
`FUNCTION_SLTU:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SLTU r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as SLTU r%d, r%d, r%d", if_id_addr, if_id_opcode, if_id_rd, if_id_rs, if_id_rt);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_b <= GPR[if_id_rt];
|
id_ex_alu_func <= `ALU_OP_SLT;
|
id_ex_alu_func <= `ALU_OP_SLT;
|
id_ex_alu_signed <= 0;
|
id_ex_alu_signed <= 0;
|
id_ex_branch <= 0;
|
id_ex_branch <= 0;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
endcase
|
endcase
|
`OPCODE_BCOND:
|
`OPCODE_BCOND:
|
case(if_id_rt)
|
case(if_id_rt)
|
`BCOND_BLTZ:
|
`BCOND_BLTZ:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BLTZ r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_imm_signext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BLTZ r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_imm_signext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_SLT;
|
id_ex_alu_func <= `ALU_OP_SLT;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 1;
|
id_ex_branch <= 1;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`BCOND_BGEZ:
|
`BCOND_BGEZ:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BGEZ r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_imm_signext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BGEZ r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_imm_signext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_SGE;
|
id_ex_alu_func <= `ALU_OP_SGE;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 1;
|
id_ex_branch <= 1;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 0;
|
id_ex_linked <= 0;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= if_id_rd;
|
id_ex_destreg <= if_id_rd;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`BCOND_BLTZAL:
|
`BCOND_BLTZAL:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BLTZAL r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_imm_signext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BLTZAL r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_imm_signext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <= `ALU_OP_SLT;
|
id_ex_alu_func <= `ALU_OP_SLT;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 1;
|
id_ex_branch <= 1;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 1;
|
id_ex_linked <= 1;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 31;
|
id_ex_destreg <= 31;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
`BCOND_BGEZAL:
|
`BCOND_BGEZAL:
|
begin
|
begin
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BGEZAL r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_imm_signext);
|
$display("INFO: CPU(%m)-ID: Decoded instruction @ADDR=%X w/OPCODE=%X as BGEZAL r%d, %h", if_id_addr, if_id_opcode, if_id_rs, if_id_imm_signext);
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_a <= GPR[if_id_rs];
|
id_ex_alu_b <= 0;
|
id_ex_alu_b <= 0;
|
id_ex_alu_func <=`ALU_OP_SGE;
|
id_ex_alu_func <=`ALU_OP_SGE;
|
id_ex_alu_signed <= 1;
|
id_ex_alu_signed <= 1;
|
id_ex_branch <= 1;
|
id_ex_branch <= 1;
|
id_ex_jump <= 0;
|
id_ex_jump <= 0;
|
id_ex_jr <= 0;
|
id_ex_jr <= 0;
|
id_ex_linked <= 1;
|
id_ex_linked <= 1;
|
id_ex_mult <= 0;
|
id_ex_mult <= 0;
|
id_ex_div <= 0;
|
id_ex_div <= 0;
|
id_ex_load <= 0;
|
id_ex_load <= 0;
|
id_ex_store <= 0;
|
id_ex_store <= 0;
|
id_ex_size <= 0;
|
id_ex_size <= 0;
|
id_ex_store_value <= 0;
|
id_ex_store_value <= 0;
|
id_ex_destreg <= 31;
|
id_ex_destreg <= 31;
|
id_ex_desthi <= 0;
|
id_ex_desthi <= 0;
|
id_ex_destlo <= 0;
|
id_ex_destlo <= 0;
|
end
|
end
|
endcase
|
endcase
|
|
|
endcase
|
endcase
|
|
|
end
|
end
|
|
|
/*
|
/*
|
* Pipeline Stage 3: Execute (EX)
|
* Pipeline Stage 3: Execute (EX)
|
*
|
*
|
* READ/WRITE:
|
* READ/WRITE:
|
* - read the ID/EX latch
|
* - read the ID/EX latch
|
* - write the EX/MEM latch
|
* - write the EX/MEM latch
|
*
|
*
|
* DESCRIPTION:
|
* DESCRIPTION:
|
* This stage takes the result from the ALU and put it in the proper latch.
|
* This stage takes the result from the ALU and put it in the proper latch.
|
* Please note that assignments to ALU inputs are done outside since they're wires.
|
* Please note that assignments to ALU inputs are done outside since they're wires.
|
*/
|
*/
|
|
|
if(ex_stall) begin
|
if(ex_stall) begin
|
|
|
if(mem_stall) begin
|
if(mem_stall) begin
|
$display("INFO: CPU(%m)-EX: Execution stalled and latch kept for following stalled pipeline stage");
|
$display("INFO: CPU(%m)-EX: Execution stalled and latch kept");
|
end else begin
|
end else begin
|
$display("INFO: CPU(%m)-EX: Execution stalled and bubble inserted for following running pipeline stage");
|
$display("INFO: CPU(%m)-EX: Execution stalled and bubble inserted");
|
ex_mem_opcode <= `BUBBLE;
|
ex_mem_opcode <= `BUBBLE;
|
ex_mem_addr <= id_ex_addr;
|
ex_mem_addr <= id_ex_addr;
|
ex_mem_addrnext <= 0;
|
ex_mem_addrnext <= 0;
|
ex_mem_destreg <= 0;
|
ex_mem_destreg <= 0;
|
ex_mem_desthi <= 0;
|
ex_mem_desthi <= 0;
|
ex_mem_destlo <= 0;
|
ex_mem_destlo <= 0;
|
end
|
end
|
|
|
end else begin
|
end else begin
|
|
|
// If not stalled propagate values to next latches
|
// If not stalled propagate values to next latches
|
ex_mem_opcode <= id_ex_opcode;
|
ex_mem_opcode <= id_ex_opcode;
|
ex_mem_addr <= id_ex_addr;
|
ex_mem_addr <= id_ex_addr;
|
ex_mem_addrnext <= id_ex_addrnext;
|
ex_mem_addrnext <= id_ex_addrnext;
|
ex_mem_addrjump <= id_ex_addrjump;
|
ex_mem_addrjump <= id_ex_addrjump;
|
ex_mem_addrbranch <= id_ex_addrbranch;
|
ex_mem_addrbranch <= id_ex_addrbranch;
|
ex_mem_branch <= id_ex_branch;
|
ex_mem_branch <= id_ex_branch;
|
ex_mem_jump <= id_ex_jump;
|
ex_mem_jump <= id_ex_jump;
|
ex_mem_jr <= id_ex_jr;
|
ex_mem_jr <= id_ex_jr;
|
ex_mem_linked <= id_ex_linked;
|
ex_mem_linked <= id_ex_linked;
|
ex_mem_mult <= id_ex_mult;
|
ex_mem_mult <= id_ex_mult;
|
ex_mem_div <= id_ex_div;
|
ex_mem_div <= id_ex_div;
|
ex_mem_load <= id_ex_load;
|
ex_mem_load <= id_ex_load;
|
ex_mem_store <= id_ex_store;
|
ex_mem_store <= id_ex_store;
|
ex_mem_size <= id_ex_size;
|
ex_mem_size <= id_ex_size;
|
ex_mem_destold <= id_ex_store_value;
|
ex_mem_destold <= id_ex_store_value;
|
ex_mem_destreg <= id_ex_destreg;
|
ex_mem_destreg <= id_ex_destreg;
|
ex_mem_desthi <= id_ex_desthi;
|
ex_mem_desthi <= id_ex_desthi;
|
ex_mem_destlo <= id_ex_destlo;
|
ex_mem_destlo <= id_ex_destlo;
|
|
|
// Choose the output from ALU, Multiplier or Divider
|
// Choose the output from ALU, Multiplier or Divider
|
if(id_ex_mult) begin
|
if(id_ex_mult) begin
|
ex_mem_aluout <= mul_product_i;
|
ex_mem_aluout <= mul_product_i;
|
ex_mem_carry <= 1'b0;
|
ex_mem_carry <= 1'b0;
|
end else if(id_ex_div) begin
|
end else if(id_ex_div) begin
|
ex_mem_aluout <= { div_remainder_i, div_quotient_i };
|
ex_mem_aluout <= { div_remainder_i, div_quotient_i };
|
ex_mem_carry <= 1'b0;
|
ex_mem_carry <= 1'b0;
|
end else begin
|
end else begin
|
ex_mem_aluout <= {32'b0, alu_result_i[31:0]};
|
ex_mem_aluout <= {32'b0, alu_result_i[31:0]};
|
ex_mem_carry <= alu_result_i[32];
|
ex_mem_carry <= alu_result_i[32];
|
end
|
end
|
|
|
// Handle all supported store sizes
|
// Handle all supported store sizes
|
if(id_ex_store) begin
|
if(id_ex_store) begin
|
$display("INFO: CPU(%m)-EX: Execution of Store instruction @ADDR=%X w/OPCODE=%X started to STORE_ADDR=%X w/STORE_DATA=%X", id_ex_addr, id_ex_opcode, alu_result_i, id_ex_store_value);
|
$display("INFO: CPU(%m)-EX: Execution of Store instruction @ADDR=%X w/OPCODE=%X started to STORE_ADDR=%X w/STORE_DATA=%X", id_ex_addr, id_ex_opcode, alu_result_i, id_ex_store_value);
|
case(id_ex_size)
|
case(id_ex_size)
|
`SIZE_WORD: begin
|
`SIZE_WORD: begin
|
ex_mem_store_value <= id_ex_store_value;
|
ex_mem_store_value <= id_ex_store_value;
|
ex_mem_store_sel <= 4'b1111;
|
ex_mem_store_sel <= 4'b1111;
|
end
|
end
|
`SIZE_HALF: begin
|
`SIZE_HALF: begin
|
if(alu_result_i[1]==0) begin
|
if(alu_result_i[1]==0) begin
|
ex_mem_store_value <= {{16'b0}, id_ex_store_value[15:0]};
|
ex_mem_store_value <= {{16'b0}, id_ex_store_value[15:0]};
|
ex_mem_store_sel <= 4'b0011;
|
ex_mem_store_sel <= 4'b0011;
|
end else begin
|
end else begin
|
ex_mem_store_value <= {id_ex_store_value[15:0], {16'b0}};
|
ex_mem_store_value <= {id_ex_store_value[15:0], {16'b0}};
|
ex_mem_store_sel <= 4'b1100;
|
ex_mem_store_sel <= 4'b1100;
|
end
|
end
|
end
|
end
|
`SIZE_BYTE: begin
|
`SIZE_BYTE: begin
|
case(alu_result_i[1:0])
|
case(alu_result_i[1:0])
|
2'b00: begin
|
2'b00: begin
|
ex_mem_store_value <= {{24'b0}, id_ex_store_value[7:0]};
|
ex_mem_store_value <= {{24'b0}, id_ex_store_value[7:0]};
|
ex_mem_store_sel <= 4'b0001;
|
ex_mem_store_sel <= 4'b0001;
|
end
|
end
|
2'b01: begin
|
2'b01: begin
|
ex_mem_store_value <= {{16'b0}, id_ex_store_value[7:0],{8'b0}};
|
ex_mem_store_value <= {{16'b0}, id_ex_store_value[7:0],{8'b0}};
|
ex_mem_store_sel <= 4'b0010;
|
ex_mem_store_sel <= 4'b0010;
|
end
|
end
|
2'b10: begin
|
2'b10: begin
|
ex_mem_store_value <= {{8'b0}, id_ex_store_value[7:0],{16'b0}};
|
ex_mem_store_value <= {{8'b0}, id_ex_store_value[7:0],{16'b0}};
|
ex_mem_store_sel <= 4'b0100;
|
ex_mem_store_sel <= 4'b0100;
|
end
|
end
|
2'b11: begin
|
2'b11: begin
|
ex_mem_store_value <= {id_ex_store_value[7:0], {24'b0}};
|
ex_mem_store_value <= {id_ex_store_value[7:0], {24'b0}};
|
ex_mem_store_sel <= 4'b1000;
|
ex_mem_store_sel <= 4'b1000;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
`SIZE_LEFT: begin
|
`SIZE_LEFT: begin
|
case(alu_result_i[1:0])
|
case(alu_result_i[1:0])
|
2'b00: begin
|
2'b00: begin
|
ex_mem_store_value <= {24'b0, id_ex_store_value[31:24]};
|
ex_mem_store_value <= {24'b0, id_ex_store_value[31:24]};
|
ex_mem_store_sel <= 4'b0001;
|
ex_mem_store_sel <= 4'b0001;
|
end
|
end
|
2'b01: begin
|
2'b01: begin
|
ex_mem_store_value <= {16'b0, id_ex_store_value[31:16]};
|
ex_mem_store_value <= {16'b0, id_ex_store_value[31:16]};
|
ex_mem_store_sel <= 4'b0011;
|
ex_mem_store_sel <= 4'b0011;
|
end
|
end
|
2'b10: begin
|
2'b10: begin
|
ex_mem_store_value <= {8'b0, id_ex_store_value[31:8]};
|
ex_mem_store_value <= {8'b0, id_ex_store_value[31:8]};
|
ex_mem_store_sel <= 4'b0111;
|
ex_mem_store_sel <= 4'b0111;
|
end
|
end
|
2'b11: begin
|
2'b11: begin
|
ex_mem_store_value <= id_ex_store_value;
|
ex_mem_store_value <= id_ex_store_value;
|
ex_mem_store_sel <= 4'b1111;
|
ex_mem_store_sel <= 4'b1111;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
`SIZE_RIGHT: begin
|
`SIZE_RIGHT: begin
|
case(alu_result_i[1:0])
|
case(alu_result_i[1:0])
|
2'b00: begin
|
2'b00: begin
|
ex_mem_store_value <= id_ex_store_value;
|
ex_mem_store_value <= id_ex_store_value;
|
ex_mem_store_sel <= 4'b1111;
|
ex_mem_store_sel <= 4'b1111;
|
end
|
end
|
2'b01: begin
|
2'b01: begin
|
ex_mem_store_value <= {id_ex_store_value[23:0], 8'b0};
|
ex_mem_store_value <= {id_ex_store_value[23:0], 8'b0};
|
ex_mem_store_sel <= 4'b1110;
|
ex_mem_store_sel <= 4'b1110;
|
end
|
end
|
2'b10: begin
|
2'b10: begin
|
ex_mem_store_value <= {id_ex_store_value[15:0], 16'b0};
|
ex_mem_store_value <= {id_ex_store_value[15:0], 16'b0};
|
ex_mem_store_sel <= 4'b1100;
|
ex_mem_store_sel <= 4'b1100;
|
end
|
end
|
2'b11: begin
|
2'b11: begin
|
ex_mem_store_value <= {id_ex_store_value[7:0], 24'b0};
|
ex_mem_store_value <= {id_ex_store_value[7:0], 24'b0};
|
ex_mem_store_sel <= 4'b1000;
|
ex_mem_store_sel <= 4'b1000;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
endcase
|
endcase
|
|
|
// Not a store
|
// Not a store
|
end else begin
|
end else begin
|
$display("INFO: CPU(%m)-EX: Execution of instruction @ADDR=%X w/OPCODE=%X gave ALU result %X", id_ex_addr, id_ex_opcode, alu_result_i);
|
$display("INFO: CPU(%m)-EX: Execution of instruction @ADDR=%X w/OPCODE=%X gave ALU result %X", id_ex_addr, id_ex_opcode, alu_result_i);
|
end
|
end
|
|
|
end
|
end
|
|
|
/*
|
/*
|
* Pipeline Stage 4: Memory access (MEM)
|
* Pipeline Stage 4: Memory access (MEM)
|
*
|
*
|
* READ/WRITE:
|
* READ/WRITE:
|
* - read the EX/MEM latch
|
* - read the EX/MEM latch
|
* - read or write memory
|
* - read or write memory
|
* - write the MEM/WB latch
|
* - write the MEM/WB latch
|
*
|
*
|
* DESCRIPTION:
|
* DESCRIPTION:
|
* This stage perform accesses to memory to read/write the data during
|
* This stage perform accesses to memory to read/write the data during
|
* the load/store operations.
|
* the load/store operations.
|
*/
|
*/
|
|
|
if(mem_stall) begin
|
if(mem_stall) begin
|
|
|
$display("INFO: CPU(%m)-MEM: Memory stalled");
|
$display("INFO: CPU(%m)-MEM: Memory stalled");
|
|
|
end else begin
|
end else begin
|
|
|
mem_wb_opcode <= ex_mem_opcode;
|
mem_wb_opcode <= ex_mem_opcode;
|
mem_wb_addr <= ex_mem_addr;
|
mem_wb_addr <= ex_mem_addr;
|
mem_wb_addrnext <= ex_mem_addrnext;
|
mem_wb_addrnext <= ex_mem_addrnext;
|
mem_wb_destreg <= ex_mem_destreg;
|
mem_wb_destreg <= ex_mem_destreg;
|
mem_wb_desthi <= ex_mem_desthi;
|
mem_wb_desthi <= ex_mem_desthi;
|
mem_wb_destlo <= ex_mem_destlo;
|
mem_wb_destlo <= ex_mem_destlo;
|
|
|
// Handle all supported load sizes
|
// Handle all supported load sizes
|
if(ex_mem_load) begin
|
if(ex_mem_load) begin
|
|
|
$display("INFO: CPU(%m)-MEM: Loading value %X", dmem_data_i);
|
$display("INFO: CPU(%m)-MEM: Loading value %X", dmem_data_i);
|
mem_wb_value[63:32] <= 32'b0;
|
mem_wb_value[63:32] <= 32'b0;
|
case(ex_mem_size)
|
case(ex_mem_size)
|
`SIZE_WORD: begin
|
`SIZE_WORD: begin
|
mem_wb_value[31:0] <= dmem_data_i;
|
mem_wb_value[31:0] <= dmem_data_i;
|
end
|
end
|
`SIZE_HALF: begin
|
`SIZE_HALF: begin
|
if(ex_mem_aluout[1]==0) mem_wb_value[31:0] <= {{16{dmem_data_i[15]}}, dmem_data_i[15:0]};
|
if(ex_mem_aluout[1]==0) mem_wb_value[31:0] <= {{16{dmem_data_i[15]}}, dmem_data_i[15:0]};
|
else mem_wb_value[31:0] <= {{16{dmem_data_i[31]}}, dmem_data_i[31:16]};
|
else mem_wb_value[31:0] <= {{16{dmem_data_i[31]}}, dmem_data_i[31:16]};
|
end
|
end
|
`SIZE_BYTE: begin
|
`SIZE_BYTE: begin
|
case(ex_mem_aluout[1:0])
|
case(ex_mem_aluout[1:0])
|
2'b00: mem_wb_value[31:0] <= {{24{dmem_data_i[7]}}, dmem_data_i[7:0]};
|
2'b00: mem_wb_value[31:0] <= {{24{dmem_data_i[7]}}, dmem_data_i[7:0]};
|
2'b01: mem_wb_value[31:0] <= {{24{dmem_data_i[15]}}, dmem_data_i[15:8]};
|
2'b01: mem_wb_value[31:0] <= {{24{dmem_data_i[15]}}, dmem_data_i[15:8]};
|
2'b10: mem_wb_value[31:0] <= {{24{dmem_data_i[23]}}, dmem_data_i[23:16]};
|
2'b10: mem_wb_value[31:0] <= {{24{dmem_data_i[23]}}, dmem_data_i[23:16]};
|
2'b11: mem_wb_value[31:0] <= {{24{dmem_data_i[31]}}, dmem_data_i[31:24]};
|
2'b11: mem_wb_value[31:0] <= {{24{dmem_data_i[31]}}, dmem_data_i[31:24]};
|
endcase
|
endcase
|
end
|
end
|
`SIZE_LEFT: begin
|
`SIZE_LEFT: begin
|
case(ex_mem_aluout[1:0])
|
case(ex_mem_aluout[1:0])
|
2'b00: mem_wb_value[31:0] <= {dmem_data_i[7:0], ex_mem_destold[23:0]};
|
2'b00: mem_wb_value[31:0] <= {dmem_data_i[7:0], ex_mem_destold[23:0]};
|
2'b01: mem_wb_value[31:0] <= {dmem_data_i[15:0], ex_mem_destold[15:0]};
|
2'b01: mem_wb_value[31:0] <= {dmem_data_i[15:0], ex_mem_destold[15:0]};
|
2'b10: mem_wb_value[31:0] <= {dmem_data_i[23:0], ex_mem_destold[7:0]};
|
2'b10: mem_wb_value[31:0] <= {dmem_data_i[23:0], ex_mem_destold[7:0]};
|
2'b11: mem_wb_value[31:0] <= dmem_data_i;
|
2'b11: mem_wb_value[31:0] <= dmem_data_i;
|
endcase
|
endcase
|
end
|
end
|
`SIZE_RIGHT: begin
|
`SIZE_RIGHT: begin
|
case(ex_mem_aluout[1:0])
|
case(ex_mem_aluout[1:0])
|
2'b00: mem_wb_value[31:0] <= dmem_data_i;
|
2'b00: mem_wb_value[31:0] <= dmem_data_i;
|
2'b01: mem_wb_value[31:0] <= {ex_mem_destold[31:24], dmem_data_i[31:8]};
|
2'b01: mem_wb_value[31:0] <= {ex_mem_destold[31:24], dmem_data_i[31:8]};
|
2'b10: mem_wb_value[31:0] <= {ex_mem_destold[31:16], dmem_data_i[31:16]};
|
2'b10: mem_wb_value[31:0] <= {ex_mem_destold[31:16], dmem_data_i[31:16]};
|
2'b11: mem_wb_value[31:0] <= {ex_mem_destold[31:8], dmem_data_i[31:24]};
|
2'b11: mem_wb_value[31:0] <= {ex_mem_destold[31:8], dmem_data_i[31:24]};
|
endcase
|
endcase
|
end
|
end
|
endcase
|
endcase
|
|
|
// For multiplications and divisions the result is 64-bit wide
|
// For multiplications and divisions the result is 64-bit wide
|
end else if (ex_mem_desthi && ex_mem_destlo) begin
|
end else if (ex_mem_desthi && ex_mem_destlo) begin
|
|
|
$display("INFO: CPU(%m)-MEM: Propagating value %X", ex_mem_aluout);
|
$display("INFO: CPU(%m)-MEM: Propagating value %X", ex_mem_aluout);
|
mem_wb_value[63:32] <= ex_mem_aluout[63:32];
|
mem_wb_value[63:32] <= ex_mem_aluout[63:32];
|
mem_wb_value[31:0] <= ex_mem_aluout[31:0];
|
mem_wb_value[31:0] <= ex_mem_aluout[31:0];
|
|
|
// For MTHI instruction we must move the value to the correct side of the bus
|
// For MTHI instruction we must move the value to the correct side of the bus
|
end else if (ex_mem_desthi) begin
|
end else if (ex_mem_desthi) begin
|
|
|
$display("INFO: CPU(%m)-MEM: Propagating value %X", ex_mem_aluout);
|
$display("INFO: CPU(%m)-MEM: Propagating value %X", ex_mem_aluout);
|
mem_wb_value[63:32] <= ex_mem_aluout[31:0];
|
mem_wb_value[63:32] <= ex_mem_aluout[31:0];
|
mem_wb_value[31:0] <= 32'b0;
|
mem_wb_value[31:0] <= 32'b0;
|
|
|
// The default is working with 32-bit values
|
// The default is working with 32-bit values
|
end else begin
|
end else begin
|
|
|
$display("INFO: CPU(%m)-MEM: Propagating value %X", ex_mem_aluout);
|
$display("INFO: CPU(%m)-MEM: Propagating value %X", ex_mem_aluout);
|
mem_wb_value[63:32] <= 32'b0;
|
mem_wb_value[63:32] <= 32'b0;
|
mem_wb_value[31:0] <= ex_mem_aluout[31:0];
|
mem_wb_value[31:0] <= ex_mem_aluout[31:0];
|
|
|
end
|
end
|
|
|
end
|
end
|
|
|
/*
|
/*
|
* Pipeline Stage 5: Write Back (WB)
|
* Pipeline Stage 5: Write Back (WB)
|
*
|
*
|
* READ/WRITE:
|
* READ/WRITE:
|
* - read the MEM/WB latch
|
* - read the MEM/WB latch
|
* - write the register file
|
* - write the register file
|
*
|
*
|
* DESCRIPTION:
|
* DESCRIPTION:
|
* This stage writes back the result into the proper register (GPR, HI, LO).
|
* This stage writes back the result into the proper register (GPR, HI, LO).
|
*/
|
*/
|
|
|
if(wb_stall) begin
|
if(wb_stall) begin
|
|
|
$display("INFO: CPU(%m)-WB: Write-Back stalled");
|
$display("INFO: CPU(%m)-WB: Write-Back stalled");
|
|
|
end else begin
|
end else begin
|
|
|
// GPRs
|
// GPRs
|
if(mem_wb_destreg!=0) begin
|
if(mem_wb_destreg!=0) begin
|
$display("INFO: CPU(%m)-WB: Writing Back GPR[%d]=%X", mem_wb_destreg, mem_wb_value[31:0]);
|
$display("INFO: CPU(%m)-WB: Writing Back GPR[%d]=%X", mem_wb_destreg, mem_wb_value[31:0]);
|
GPR[mem_wb_destreg] <= mem_wb_value[31:0];
|
GPR[mem_wb_destreg] <= mem_wb_value[31:0];
|
end
|
end
|
|
|
// HI
|
// HI
|
if(mem_wb_desthi) begin
|
if(mem_wb_desthi) begin
|
$display("INFO: CPU(%m)-WB: Writing Back HI=%X", mem_wb_value[63:32]);
|
$display("INFO: CPU(%m)-WB: Writing Back HI=%X", mem_wb_value[63:32]);
|
HI <= mem_wb_value[63:32];
|
HI <= mem_wb_value[63:32];
|
end
|
end
|
|
|
// LO
|
// LO
|
if(mem_wb_destlo) begin
|
if(mem_wb_destlo) begin
|
$display("INFO: CPU(%m)-WB: Writing Back LO=%X", mem_wb_value[31:0]);
|
$display("INFO: CPU(%m)-WB: Writing Back LO=%X", mem_wb_value[31:0]);
|
LO <= mem_wb_value[31:0];
|
LO <= mem_wb_value[31:0];
|
end
|
end
|
|
|
// SysCon
|
// SysCon
|
if(mem_wb_destsyscon!=0) begin
|
if(mem_wb_destsyscon!=0) begin
|
$display("INFO: CPU(%m)-WB: Writing Back SysCon[%d]=%X", mem_wb_destsyscon, mem_wb_value[31:0]);
|
$display("INFO: CPU(%m)-WB: Writing Back SysCon[%d]=%X", mem_wb_destsyscon, mem_wb_value[31:0]);
|
SysCon[mem_wb_destsyscon] <= mem_wb_value[31:0];
|
SysCon[mem_wb_destsyscon] <= mem_wb_value[31:0];
|
end
|
end
|
|
|
// Idle
|
// Idle
|
if(mem_wb_destreg==0 & mem_wb_desthi==0 & mem_wb_destlo==0)
|
if(mem_wb_destreg==0 & mem_wb_desthi==0 & mem_wb_destlo==0)
|
$display("INFO: CPU(%m)-WB: Write-Back has nothing to do");
|
$display("INFO: CPU(%m)-WB: Write-Back has nothing to do");
|
|
|
end
|
end
|
|
|
// Display register file at each raising edge
|
// Display register file at each raising edge
|
$display("INFO: CPU(%m)-Regs: R00=%X R01=%X R02=%X R03=%X R04=%X R05=%X R06=%X R07=%X",
|
$display("INFO: CPU(%m)-Regs: R00=%X R01=%X R02=%X R03=%X R04=%X R05=%X R06=%X R07=%X",
|
GPR[0], GPR[1], GPR[2], GPR[3], GPR[4], GPR[5], GPR[6], GPR[7]);
|
GPR[0], GPR[1], GPR[2], GPR[3], GPR[4], GPR[5], GPR[6], GPR[7]);
|
$display("INFO: CPU(%m)-Regs: R08=%X R09=%X R10=%X R11=%X R12=%X R13=%X R14=%X R15=%X",
|
$display("INFO: CPU(%m)-Regs: R08=%X R09=%X R10=%X R11=%X R12=%X R13=%X R14=%X R15=%X",
|
GPR[8], GPR[9], GPR[10], GPR[11], GPR[12], GPR[13], GPR[14], GPR[15]);
|
GPR[8], GPR[9], GPR[10], GPR[11], GPR[12], GPR[13], GPR[14], GPR[15]);
|
$display("INFO: CPU(%m)-Regs: R16=%X R17=%X R18=%X R19=%X R20=%X R21=%X R22=%X R23=%X",
|
$display("INFO: CPU(%m)-Regs: R16=%X R17=%X R18=%X R19=%X R20=%X R21=%X R22=%X R23=%X",
|
GPR[16], GPR[17], GPR[18], GPR[19], GPR[20], GPR[21], GPR[22], GPR[23]);
|
GPR[16], GPR[17], GPR[18], GPR[19], GPR[20], GPR[21], GPR[22], GPR[23]);
|
$display("INFO: CPU(%m)-Regs: R24=%X R25=%X R26=%X R27=%X R28=%X R29=%X R30=%X R31=%X",
|
$display("INFO: CPU(%m)-Regs: R24=%X R25=%X R26=%X R27=%X R28=%X R29=%X R30=%X R31=%X",
|
GPR[24], GPR[25], GPR[26], GPR[27], GPR[28], GPR[29], GPR[30], GPR[31]);
|
GPR[24], GPR[25], GPR[26], GPR[27], GPR[28], GPR[29], GPR[30], GPR[31]);
|
$display("INFO: CPU(%m)-Regs: PC=%X HI=%X LO=%X",
|
$display("INFO: CPU(%m)-Regs: PC=%X HI=%X LO=%X",
|
PC, HI, LO);
|
PC, HI, LO);
|
|
|
end
|
end
|
end
|
end
|
|
|
endmodule
|
endmodule
|
|
|
|
|