/**************************************************************************** ISA definition file - The MIPS I ISA has a 6 bit opcode in the upper 6 bits. - The opcode can also specify a "class". There are two classes: 1. SPECIAL - look in lowest 6 bits to find operation 2. REGIMM - look in [20:16] to find type of branch ****************************************************************************/ /****** OPCODES - bits 31...26 *******/ `define VAL 31 `define WIDTH 32 `define NUMREGS 32 `define LOG2NUMREGS 5 `define PC_WIDTH 30 `define I_DATAWIDTH 32 `define I_ADDRESSWIDTH 14 `define I_SIZE 16384 `define D_ADDRESSWIDTH 32 `define DM_DATAWIDTH 32 `define DM_BYTEENAWIDTH 4 `define DM_ADDRESSWIDTH 10 `define DM_SIZE 16384 `define OP_SPECIAL 6'b000000 `define OP_REGIMM 6'b000001 `define OP_J 6'b000010 `define OP_JAL 6'b000011 `define OP_BEQ 6'b000100 `define OP_BNE 6'b000101 `define OP_BLEZ 6'b000110 `define OP_BGTZ 6'b000111 `define OP_ADDI 6'b001000 `define OP_ADDIU 6'b001001 `define OP_SLTI 6'b001010 `define OP_SLTIU 6'b001011 `define OP_ANDI 6'b001100 `define OP_ORI 6'b001101 `define OP_XORI 6'b001110 `define OP_LUI 6'b001111 `define OP_LB 6'b100000 `define OP_LH 6'b100001 `define OP_LWL 6'b100010 `define OP_LW 6'b100011 `define OP_LBU 6'b100100 `define OP_LHU 6'b100101 `define OP_LWR 6'b100110 `define OP_SB 6'b101100 `define OP_SH 6'b101101 `define OP_SWL 6'b101010 `define OP_SW 6'b101111 `define OP_SWR 6'b101110 /****** FUNCTION CLASS - bits 5...0 *******/ `define FUNC_SLL 6'b000000 `define FUNC_SRL 6'b000010 `define FUNC_SRA 6'b000011 `define FUNC_SLLV 6'b000100 `define FUNC_SRLV 6'b000110 `define FUNC_SRAV 6'b000111 `define FUNC_JR 6'b001110 `define FUNC_JALR 6'b001111 `define FUNC_MFHI 6'b110100 `define FUNC_MTHI 6'b110101 `define FUNC_MFLO 6'b110110 `define FUNC_MTLO 6'b110111 `define FUNC_MULT 6'b111100 `define FUNC_MULTU 6'b111101 `define FUNC_DIV 6'b111110 `define FUNC_DIVU 6'b111111 `define FUNC_ADD 6'b100000 `define FUNC_ADDU 6'b100001 `define FUNC_SUB 6'b100010 `define FUNC_SUBU 6'b100011 `define FUNC_AND 6'b100100 `define FUNC_OR 6'b100101 `define FUNC_XOR 6'b100110 `define FUNC_NOR 6'b100111 `define FUNC_SLT 6'b101010 `define FUNC_SLTU 6'b101011 /****** REGIMM Class - bits 20...16 *******/ `define FUNC_BLTZ 1'b0 `define FUNC_BGEZ 1'b1 `define OP_COP2 6'b010010 `define COP2_FUNC_CFC2 6'b111000 `define COP2_FUNC_CTC2 6'b111010 `define COP2_FUNC_MTC2 6'b111011 //`define FUNC_BLTZAL 5'b10000 //`define FUNC_BGEZAL 5'b10001 /****** * Original REGIMM class, compressed above to save decode logic `define FUNC_BLTZ 5'b00000 `define FUNC_BGEZ 5'b00001 `define FUNC_BLTZAL 5'b10000 `define FUNC_BGEZAL 5'b10001 */ module system ( clk, resetn, boot_iaddr, boot_idata, boot_iwe, boot_daddr, boot_ddata, boot_dwe, nop7_q ); /************************* IO Declarations *********************/ input clk; input resetn; input [31:0] boot_iaddr; input [31:0] boot_idata; input boot_iwe; input [31:0] boot_daddr; input [31:0] boot_ddata; input boot_dwe; output [31:0] nop7_q; /*********************** Signal Declarations *******************/ wire branch_mispred; wire stall_2nd_delayslot; wire has_delayslot; wire haz_zeroer0_q_pipereg5_q; wire haz_zeroer_q_pipereg5_q; // Datapath signals declarations wire addersub_result_slt; wire [ 31 : 0 ] addersub_result; wire [ 31 : 0 ] reg_file_b_readdataout; wire [ 31 : 0 ] reg_file_a_readdataout; wire [ 31 : 0 ] mul_shift_result; wire [ 31 : 0 ] mul_lo; wire [ 31 : 0 ] mul_hi; wire ctrl_mul_stalled; wire [ 31 : 0 ] ifetch_pc_out; wire [ 31 : 0 ] ifetch_instr; wire [ 5 : 0 ] ifetch_opcode; wire [ 5 : 0 ] ifetch_func; wire [4 : 0 ] ifetch_rs; wire [ 4 : 0 ] ifetch_rt; wire [ 4 : 0 ] ifetch_rd; wire [ 25 : 0 ] ifetch_instr_index; wire [ 15 : 0 ] ifetch_offset; wire [ 4 : 0 ] ifetch_sa; wire [ 31 : 0 ] ifetch_next_pc; wire [ 31 : 0 ] data_mem_d_loadresult; wire ctrl_data_mem_stalled; wire [ 31 : 0 ] logic_unit_result; wire [ 31 : 0 ] pcadder_result; wire [ 31 : 0 ] signext16_out; wire [ 31 : 0 ] merge26lo_out; wire [ 31 : 0 ] hi_reg_q; wire branchresolve_eqz; wire branchresolve_gez; wire branchresolve_gtz; wire branchresolve_lez; wire branchresolve_ltz; wire branchresolve_ne; wire branchresolve_eq; wire [ 31 : 0 ] lo_reg_q; wire [ 31 : 0 ] const8_out; wire [ 31 : 0 ] const9_out; wire [ 31 : 0 ] const_out; wire [ 31 : 0 ] pipereg_q; wire [ 25 : 0 ] pipereg1_q; wire [ 4 : 0 ] pipereg2_q; wire [ 31 : 0 ] pipereg5_q; wire [ 31 : 0 ] pipereg14_q; wire [ 31 : 0 ] pipereg3_q; wire [ 31 : 0 ] nop7_q; wire [ 31 : 0 ] nop_q; wire [ 31 : 0 ] nop10_q; wire [ 31 : 0 ] nop6_q; wire [ 31 : 0 ] zeroer_q; wire [ 31 : 0 ] zeroer0_q; wire [ 31 : 0 ] zeroer4_q; wire [ 31 : 0 ] fakedelay_q; wire [ 31 : 0 ] mux3to1_ifetch_load_data_out; wire [ 31 : 0 ] mux2to1_mul_opA_out; wire mux6to1_ifetch_load_out; wire [ 4 : 0 ] mux3to1_mul_sa_out; wire [ 31 : 0 ] mux2to1_addersub_opA_out; wire [ 31 : 0 ] mux7to1_nop10_d_out; wire [ 31 : 0 ] mux2to1_pipereg_d_out; wire [ 31 : 0 ] mux3to1_nop6_d_out; wire [ 31 : 0 ] mux3to1_zeroer4_d_out; wire [ 5 : 0 ] pipereg11_q; wire [ 31 : 0 ] mux2to1_nop_d_out; wire pipereg16_q; wire pipereg15_q; wire [ 31 : 0 ] mux2to1_nop7_d_out; wire [ 5 : 0 ] pipereg12_q; wire [ 4 : 0 ] pipereg13_q; /***************** Control Signals ***************/ //Decoded Opcode signal declarations reg ctrl_mux2to1_pipereg_d_sel; reg [ 2 : 0 ] ctrl_mux7to1_nop10_d_sel; reg ctrl_mux2to1_addersub_opA_sel; reg [ 2 : 0 ] ctrl_mux6to1_ifetch_load_sel; reg [ 1 : 0 ] ctrl_mux3to1_nop6_d_sel; reg ctrl_mux2to1_mul_opA_sel; reg [ 1 : 0 ] ctrl_mux3to1_mul_sa_sel; reg [ 1 : 0 ] ctrl_mux3to1_ifetch_load_data_sel; reg [ 1 : 0 ] ctrl_mux3to1_zeroer4_d_sel; reg ctrl_zeroer4_en; reg ctrl_zeroer0_en; reg ctrl_zeroer_en; reg [ 3 : 0 ] ctrl_data_mem_op; reg [ 2 : 0 ] ctrl_addersub_op; reg ctrl_ifetch_op; reg [ 2 : 0 ] ctrl_mul_op; reg [ 1 : 0 ] ctrl_logic_unit_op; //Enable signal declarations reg ctrl_hi_reg_en; reg ctrl_lo_reg_en; reg ctrl_branchresolve_en; reg ctrl_reg_file_c_we; reg ctrl_reg_file_b_en; reg ctrl_reg_file_a_en; reg ctrl_data_mem_en; reg ctrl_ifetch_we; reg ctrl_ifetch_en; reg ctrl_mul_start; //Other Signals wire squash_stage2; wire stall_out_stage2; wire squash_stage1; wire stall_out_stage1; wire ctrl_pipereg16_squashn; wire ctrl_pipereg15_squashn; wire ctrl_pipereg14_squashn; wire ctrl_pipereg_squashn; wire ctrl_pipereg5_squashn; wire ctrl_pipereg2_squashn; wire ctrl_pipereg3_squashn; wire ctrl_pipereg1_squashn; wire ctrl_pipereg11_squashn; wire ctrl_pipereg12_squashn; wire ctrl_pipereg13_squashn; wire ctrl_pipereg16_resetn; wire ctrl_pipereg15_resetn; wire ctrl_pipereg14_resetn; wire ctrl_pipereg_resetn; wire ctrl_pipereg5_resetn; wire ctrl_pipereg2_resetn; wire ctrl_pipereg3_resetn; wire ctrl_pipereg1_resetn; wire ctrl_pipereg11_resetn; wire ctrl_pipereg12_resetn; wire ctrl_pipereg13_resetn; wire ctrl_pipereg16_en; wire ctrl_pipereg15_en; wire ctrl_pipereg14_en; wire ctrl_pipereg_en; wire ctrl_pipereg5_en; wire ctrl_pipereg2_en; wire ctrl_pipereg3_en; wire ctrl_pipereg1_en; wire ctrl_pipereg11_en; wire ctrl_pipereg12_en; wire ctrl_pipereg13_en; wire crtl_ifetch_squashn; /****************************** Control **************************/ //Decode Logic for Opcode and Multiplex Select signals always@(posedge clk) begin // Initialize control opcodes to zero case (ifetch_opcode) `OP_ADDI: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_ADDIU: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_ANDI: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_BEQ: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_BGTZ: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_BLEZ: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_BNE: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_JAL: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; end `OP_LB: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_LBU: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_LH: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_LHU: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_LUI: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; end `OP_LW: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_ORI: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_REGIMM: case (ifetch_rt[0]) `FUNC_BGEZ: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_BLTZ: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_zeroer_en <= 1'b1; end endcase `OP_SB: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_SH: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_SLTI: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_SLTIU: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_SPECIAL: case (ifetch_func) `FUNC_ADD: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_ADDU: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_AND: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_JALR: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_JR: ctrl_zeroer_en <= 1'b1; `FUNC_MFHI: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; end `FUNC_MFLO: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; end `FUNC_MULT: begin ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_MULTU: begin ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_NOR: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_OR: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_SLL: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; end `FUNC_SLLV: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_SLT: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_SLTU: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_SRA: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; end `FUNC_SRAV: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_SRL: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; end `FUNC_SRLV: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_SUB: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_SUBU: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `FUNC_XOR: begin ctrl_mux3to1_zeroer4_d_sel <= 2'b01; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end endcase `OP_SW: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_zeroer0_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end `OP_XORI: begin ctrl_mux2to1_pipereg_d_sel <= 1'b1; ctrl_mux3to1_zeroer4_d_sel <= 2'b10; ctrl_zeroer4_en <= 1'b1; ctrl_zeroer_en <= 1'b1; end endcase //Logic for enable signals in Pipe Stage 1 ctrl_reg_file_b_en <= ~stall_out_stage2; ctrl_reg_file_a_en <= ~stall_out_stage2; ctrl_ifetch_en <= ~stall_out_stage2; //Decode Logic for Opcode and Multiplex Select signals // Initialize control opcodes to zero case (pipereg11_q) `OP_ADDI: begin ctrl_mux7to1_nop10_d_sel <= 3'b110; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_addersub_op <= 3'b011; end `OP_ADDIU: begin ctrl_mux7to1_nop10_d_sel <= 3'b110; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_addersub_op <= 3'b001; end `OP_ANDI: begin ctrl_mux7to1_nop10_d_sel <= 3'b100; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_logic_unit_op <= 2'b00; end `OP_BEQ: begin ctrl_mux6to1_ifetch_load_sel <= 3'b101; ctrl_mux3to1_ifetch_load_data_sel<= 2'b10; ctrl_ifetch_op <= 1'b0; end `OP_BGTZ: begin ctrl_mux6to1_ifetch_load_sel <= 3'b000; ctrl_mux3to1_ifetch_load_data_sel<= 2'b10; ctrl_ifetch_op <= 1'b0; end `OP_BLEZ: begin ctrl_mux6to1_ifetch_load_sel <= 3'b011; ctrl_mux3to1_ifetch_load_data_sel<= 2'b10; ctrl_ifetch_op <= 1'b0; end `OP_BNE: begin ctrl_mux6to1_ifetch_load_sel <= 3'b100; ctrl_mux3to1_ifetch_load_data_sel<= 2'b10; ctrl_ifetch_op <= 1'b0; end `OP_J: begin ctrl_mux3to1_ifetch_load_data_sel<= 2'b01; ctrl_ifetch_op <= 1'b1; end `OP_JAL: begin ctrl_mux7to1_nop10_d_sel <= 3'b110; ctrl_mux2to1_addersub_opA_sel <= 1'b1; ctrl_mux3to1_ifetch_load_data_sel<= 2'b01; ctrl_addersub_op <= 3'b001; ctrl_ifetch_op <= 1'b1; end `OP_LB: begin ctrl_mux7to1_nop10_d_sel <= 3'b010; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_data_mem_op <= 4'b0111; ctrl_addersub_op <= 3'b011; end `OP_LBU: begin ctrl_mux7to1_nop10_d_sel <= 3'b010; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_data_mem_op <= 4'b0011; ctrl_addersub_op <= 3'b011; end `OP_LH: begin ctrl_mux7to1_nop10_d_sel <= 3'b010; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_data_mem_op <= 4'b0101; ctrl_addersub_op <= 3'b011; end `OP_LHU: begin ctrl_mux7to1_nop10_d_sel <= 3'b010; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_data_mem_op <= 4'b0001; ctrl_addersub_op <= 3'b011; end `OP_LUI: begin ctrl_mux7to1_nop10_d_sel <= 3'b011; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_mux2to1_mul_opA_sel <= 1'b0; ctrl_mux3to1_mul_sa_sel <= 2'b01; ctrl_mul_op <= 3'b000; end `OP_LW: begin ctrl_mux7to1_nop10_d_sel <= 3'b010; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_data_mem_op <= 4'b0000; ctrl_addersub_op <= 3'b011; end `OP_ORI: begin ctrl_mux7to1_nop10_d_sel <= 3'b100; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_logic_unit_op <= 2'b01; end `OP_REGIMM: case (pipereg13_q[0]) `FUNC_BGEZ: begin ctrl_mux6to1_ifetch_load_sel <= 3'b001; ctrl_mux3to1_ifetch_load_data_sel<= 2'b10; ctrl_ifetch_op <= 1'b0; end `FUNC_BLTZ: begin ctrl_mux6to1_ifetch_load_sel <= 3'b010; ctrl_mux3to1_ifetch_load_data_sel<= 2'b10; ctrl_ifetch_op <= 1'b0; end endcase `OP_SB: begin ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_data_mem_op <= 4'b0011; ctrl_addersub_op <= 3'b011; end `OP_SH: begin ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_data_mem_op <= 4'b1001; ctrl_addersub_op <= 3'b011; end `OP_SLTI: begin ctrl_mux7to1_nop10_d_sel <= 3'b101; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_addersub_op <= 3'b101; end `OP_SLTIU: begin ctrl_mux7to1_nop10_d_sel <= 3'b101; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_addersub_op <= 3'b100; end `OP_SPECIAL: case (pipereg12_q) `FUNC_ADD: begin ctrl_mux7to1_nop10_d_sel <= 3'b110; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_addersub_op <= 3'b011; end `FUNC_ADDU: begin ctrl_mux7to1_nop10_d_sel <= 3'b110; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_addersub_op <= 3'b001; end `FUNC_AND: begin ctrl_mux7to1_nop10_d_sel <= 3'b100; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_logic_unit_op <= 2'b00; end `FUNC_JALR: begin ctrl_mux7to1_nop10_d_sel <= 3'b110; ctrl_mux2to1_addersub_opA_sel <= 1'b1; ctrl_mux3to1_ifetch_load_data_sel<= 2'b00; ctrl_addersub_op <= 3'b001; ctrl_ifetch_op <= 1'b1; end `FUNC_JR: begin ctrl_mux3to1_ifetch_load_data_sel<= 2'b00; ctrl_ifetch_op <= 1'b1; end `FUNC_MFHI: ctrl_mux7to1_nop10_d_sel <= 3'b001; `FUNC_MFLO: ctrl_mux7to1_nop10_d_sel <= 3'b000; `FUNC_MULT: begin ctrl_mux2to1_mul_opA_sel <= 1'b1; ctrl_mul_op <= 3'b110; end `FUNC_MULTU: begin ctrl_mux2to1_mul_opA_sel <= 1'b1; ctrl_mul_op <= 3'b100; end `FUNC_NOR: begin ctrl_mux7to1_nop10_d_sel <= 3'b100; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_logic_unit_op <= 2'b11; end `FUNC_OR: begin ctrl_mux7to1_nop10_d_sel <= 3'b100; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_logic_unit_op <= 2'b01; end `FUNC_SLL: begin ctrl_mux7to1_nop10_d_sel <= 3'b011; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_mux2to1_mul_opA_sel <= 1'b0; ctrl_mux3to1_mul_sa_sel <= 2'b00; ctrl_mul_op <= 3'b000; end `FUNC_SLLV: begin ctrl_mux7to1_nop10_d_sel <= 3'b011; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_mux2to1_mul_opA_sel <= 1'b0; ctrl_mux3to1_mul_sa_sel <= 2'b10; ctrl_mul_op <= 3'b000; end `FUNC_SLT: begin ctrl_mux7to1_nop10_d_sel <= 3'b101; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_addersub_op <= 3'b110; end `FUNC_SLTU: begin ctrl_mux7to1_nop10_d_sel <= 3'b101; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_addersub_op <= 3'b100; end `FUNC_SRA: begin ctrl_mux7to1_nop10_d_sel <= 3'b011; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_mux2to1_mul_opA_sel <= 1'b0; ctrl_mux3to1_mul_sa_sel <= 2'b00; ctrl_mul_op <= 3'b011; end `FUNC_SRAV: begin ctrl_mux7to1_nop10_d_sel <= 3'b011; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_mux2to1_mul_opA_sel <= 1'b0; ctrl_mux3to1_mul_sa_sel <= 2'b10; ctrl_mul_op <= 3'b011; end `FUNC_SRL: begin ctrl_mux7to1_nop10_d_sel <= 3'b011; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_mux2to1_mul_opA_sel <= 1'b0; ctrl_mux3to1_mul_sa_sel <= 2'b00; ctrl_mul_op <= 3'b001; end `FUNC_SRLV: begin ctrl_mux7to1_nop10_d_sel <= 3'b011; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_mux2to1_mul_opA_sel <= 1'b0; ctrl_mux3to1_mul_sa_sel <= 2'b10; ctrl_mul_op <= 3'b001; end `FUNC_SUB: begin ctrl_mux7to1_nop10_d_sel <= 3'b110; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_addersub_op <= 3'b000; end `FUNC_SUBU: begin ctrl_mux7to1_nop10_d_sel <= 3'b110; ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_addersub_op <= 3'b010; end `FUNC_XOR: begin ctrl_mux7to1_nop10_d_sel <= 3'b100; ctrl_mux3to1_nop6_d_sel <= 2'b01; ctrl_logic_unit_op <= 2'b10; end endcase `OP_SW: begin ctrl_mux2to1_addersub_opA_sel <= 1'b0; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_data_mem_op <= 4'b1000; ctrl_addersub_op <= 3'b011; end `OP_XORI: begin ctrl_mux7to1_nop10_d_sel <= 3'b100; ctrl_mux3to1_nop6_d_sel <= 2'b10; ctrl_logic_unit_op <= 2'b10; end endcase //Logic for enable signals in Pipe Stage 2 case (pipereg11_q) `OP_ADDI: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `OP_ADDIU: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `OP_ANDI: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `OP_BEQ: begin ctrl_branchresolve_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; end `OP_BGTZ: begin ctrl_branchresolve_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; end `OP_BLEZ: begin ctrl_branchresolve_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; end `OP_BNE: begin ctrl_branchresolve_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; end `OP_J: ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `OP_JAL: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; end `OP_LB: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_data_mem_en <=1'b1; end `OP_LBU: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_data_mem_en <=1'b1; end `OP_LH: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_data_mem_en <=1'b1; end `OP_LHU: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_data_mem_en <=1'b1; end `OP_LUI: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_mul_start <=1'b1; end `OP_LW: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_data_mem_en <=1'b1; end `OP_ORI: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `OP_REGIMM: case (pipereg13_q[0]) `FUNC_BGEZ: begin ctrl_branchresolve_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; end `FUNC_BLTZ: begin ctrl_branchresolve_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; end endcase `OP_SB: ctrl_data_mem_en <=1'b1; `OP_SH: ctrl_data_mem_en <=1'b1; `OP_SLTI: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `OP_SLTIU: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `OP_SPECIAL: case (pipereg12_q) `FUNC_ADD: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `FUNC_ADDU: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `FUNC_AND: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `FUNC_JALR: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; end `FUNC_JR: ctrl_ifetch_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `FUNC_MFHI: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `FUNC_MFLO: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `FUNC_MULT: begin ctrl_hi_reg_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_lo_reg_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_mul_start <=1'b1; end `FUNC_MULTU: begin ctrl_hi_reg_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_lo_reg_en <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_mul_start <=1'b1; end `FUNC_NOR: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `FUNC_OR: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `FUNC_SLL: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_mul_start <=1'b1; end `FUNC_SLLV: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_mul_start <=1'b1; end `FUNC_SLT: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `FUNC_SLTU: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `FUNC_SRA: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_mul_start <=1'b1; end `FUNC_SRAV: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_mul_start <=1'b1; end `FUNC_SRL: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_mul_start <=1'b1; end `FUNC_SRLV: begin ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; ctrl_mul_start <=1'b1; end `FUNC_SUB: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `FUNC_SUBU: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; `FUNC_XOR: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; endcase `OP_SW: ctrl_data_mem_en <=1'b1; `OP_XORI: ctrl_reg_file_c_we <=~ctrl_data_mem_stalled&~ctrl_mul_stalled; endcase end /********* Stall Network & PipeReg Control ********/ assign stall_out_stage1 = stall_out_stage2; assign ctrl_pipereg13_en = ~stall_out_stage1; assign ctrl_pipereg12_en = ~stall_out_stage1; assign ctrl_pipereg11_en = ~stall_out_stage1; assign ctrl_pipereg1_en = ~stall_out_stage1; assign ctrl_pipereg3_en = ~stall_out_stage1; assign ctrl_pipereg2_en = ~stall_out_stage1; assign ctrl_pipereg5_en = ~stall_out_stage1; assign ctrl_pipereg_en = ~stall_out_stage1; assign ctrl_pipereg14_en = ~stall_out_stage1; assign ctrl_pipereg15_en = ~stall_out_stage1; assign ctrl_pipereg16_en = ~stall_out_stage1; assign stall_out_stage2 = ctrl_data_mem_stalled|ctrl_mul_stalled; assign branch_mispred = (((ctrl_ifetch_op==1) || (ctrl_ifetch_op==0 && mux6to1_ifetch_load_out)) & ctrl_ifetch_we); assign stall_2nd_delayslot = &has_delayslot; assign has_delayslot = 0; assign squash_stage1 = ((stall_out_stage1&~stall_out_stage2))|~resetn; assign ctrl_pipereg13_resetn = ~squash_stage1; assign ctrl_pipereg12_resetn = ~squash_stage1; assign ctrl_pipereg11_resetn = ~squash_stage1; assign ctrl_pipereg1_resetn = ~squash_stage1; assign ctrl_pipereg3_resetn = ~squash_stage1; assign ctrl_pipereg2_resetn = ~squash_stage1; assign ctrl_pipereg5_resetn = ~squash_stage1; assign ctrl_pipereg_resetn = ~squash_stage1; assign ctrl_pipereg14_resetn = ~squash_stage1; assign ctrl_pipereg15_resetn = ~squash_stage1; assign ctrl_pipereg16_resetn = ~squash_stage1; assign ctrl_pipereg16_squashn = 1'b1; assign ctrl_pipereg15_squashn = 1'b1; assign ctrl_pipereg14_squashn = 1'b1; assign ctrl_pipereg_squashn = 1'b1; assign ctrl_pipereg5_squashn = 1'b1; assign ctrl_pipereg2_squashn = 1'b1; assign ctrl_pipereg3_squashn = 1'b1; assign ctrl_pipereg1_squashn = 1'b1; assign ctrl_pipereg11_squashn = 1'b1; assign ctrl_pipereg12_squashn = 1'b1; assign ctrl_pipereg13_squashn = 1'b1; assign ctrl_ifetch_squashn = 1'b1; wire ctrl_ifetch_squashn; assign squash_stage2 = ((stall_out_stage2))|~resetn; /****************************** Datapath **************************/ /******************** Hazard Detection Logic ***********************/ assign haz_zeroer0_q_pipereg5_q = (zeroer0_q==pipereg5_q) && (|zeroer0_q); assign haz_zeroer_q_pipereg5_q = (zeroer_q==pipereg5_q) && (|zeroer_q); assign const8_out = 32'b00000000000000000000000000000000; assign const9_out = 32'b00000000000000000000000000010000; assign const_out = 32'b00000000000000000000000000011111; /*************** DATAPATH COMPONENTS **************/ addersub addersub ( .opB(nop6_q), .opA(mux2to1_addersub_opA_out), .op(ctrl_addersub_op), .result_slt(addersub_result_slt), .result(addersub_result)); // defparam // addersub.WIDTH=32; reg_file reg_file ( .clk(clk), .resetn(resetn), .c_writedatain(nop10_q), .c_reg(pipereg5_q), .b_reg(zeroer0_q), .a_reg(zeroer_q), .c_we(ctrl_reg_file_c_we), .b_en(ctrl_reg_file_b_en), .a_en(ctrl_reg_file_a_en), .b_readdataout(reg_file_b_readdataout), .a_readdataout(reg_file_a_readdataout)); mul mul ( .clk(clk), .resetn(resetn), .sa(mux3to1_mul_sa_out), .dst(pipereg5_q), .opB(nop7_q), .opA(mux2to1_mul_opA_out), .op(ctrl_mul_op), .start(ctrl_mul_start), .stalled(ctrl_mul_stalled), .shift_result(mul_shift_result), .lo(mul_lo), .hi(mul_hi)); // defparam // mul.WIDTH=32; ifetch ifetch ( .clk(clk), .resetn(resetn), .boot_iaddr(boot_iaddr), .boot_idata(boot_idata), .boot_iwe(boot_iwe), .load(mux6to1_ifetch_load_out), .load_data(mux3to1_ifetch_load_data_out), .op(ctrl_ifetch_op), .we(ctrl_ifetch_we), .squashn(ctrl_ifetch_squashn), .en(ctrl_ifetch_en), .pc_out(ifetch_pc_out), .instr(ifetch_instr), .opcode(ifetch_opcode), .func(ifetch_func), .rs(ifetch_rs), .rt(ifetch_rt), .rd(ifetch_rd), .instr_index(ifetch_instr_index), .offset(ifetch_offset), .sa(ifetch_sa), .next_pc(ifetch_next_pc)); data_mem data_mem ( .clk(clk), .resetn(resetn), .stalled(ctrl_data_mem_stalled), .d_writedata(nop7_q), .d_address(addersub_result), .op(ctrl_data_mem_op), .d_loadresult(data_mem_d_loadresult)); logic_unit logic_unit ( .opB(nop6_q), .opA(nop_q), .op(ctrl_logic_unit_op), .result(logic_unit_result)); // defparam // logic_unit.WIDTH=32; pcadder pcadder ( .offset(pipereg_q), .pc(pipereg3_q), .result(pcadder_result)); signext16 signext16 ( .in(ifetch_offset), .out(signext16_out)); merge26lo merge26lo ( .in2(pipereg1_q), .in1(pipereg3_q), .out(merge26lo_out)); hi_reg hi_reg ( .clk(clk), .resetn(resetn), .d(mul_hi), .en(ctrl_hi_reg_en), .q(hi_reg_q)); // defparam // hi_reg.WIDTH=32; branchresolve branchresolve ( .rt(nop7_q), .rs(nop_q), .en(ctrl_branchresolve_en), .eqz(branchresolve_eqz), .gez(branchresolve_gez), .gtz(branchresolve_gtz), .lez(branchresolve_lez), .ltz(branchresolve_ltz), .ne(branchresolve_ne), .eq(branchresolve_eq)); // defparam // branchresolve.WIDTH=32; lo_reg lo_reg ( .clk(clk), .resetn(resetn), .d(mul_lo), .en(ctrl_lo_reg_en), .q(lo_reg_q)); // defparam // lo_reg.WIDTH=32; /* const const8 ( .out(const8_out)); // defparam // const8.WIDTH=32, //const8.VAL=0; const const9 ( .out(const9_out)); // defparam // const9.WIDTH=32, //const9.VAL=16; const const ( .out(const_out)); // defparam // const.WIDTH=32, //const.VAL=31; */ pipereg_w32 pipereg ( .clk(clk), .resetn(ctrl_pipereg_resetn), .d(mux2to1_pipereg_d_out), .squashn(ctrl_pipereg_squashn), .en(ctrl_pipereg_en), .q(pipereg_q)); // defparam // pipereg.WIDTH=32; pipereg_w26 pipereg1 ( .clk(clk), .resetn(ctrl_pipereg1_resetn), .d(ifetch_instr_index), .squashn(ctrl_pipereg1_squashn), .en(ctrl_pipereg1_en), .q(pipereg1_q)); // defparam // pipereg1.WIDTH=26; pipereg_w5 pipereg2 ( .clk(clk), .resetn(ctrl_pipereg2_resetn), .d(ifetch_sa), .squashn(ctrl_pipereg2_squashn), .en(ctrl_pipereg2_en), .q(pipereg2_q)); // defparam // pipereg2.WIDTH=5; pipereg_w5 pipereg5 ( .clk(clk), .resetn(ctrl_pipereg5_resetn), .d(zeroer4_q), .squashn(ctrl_pipereg5_squashn), .en(ctrl_pipereg5_en), .q(pipereg5_q)); //defparam //pipereg5.WIDTH=5; pipereg_w32 pipereg14 ( .clk(clk), .resetn(ctrl_pipereg14_resetn), .d(nop10_q), .squashn(ctrl_pipereg14_squashn), .en(ctrl_pipereg14_en), .q(pipereg14_q)); //defparam // pipereg14.WIDTH=32; pipereg_w32 pipereg3 ( .clk(clk), .resetn(ctrl_pipereg3_resetn), .d(ifetch_pc_out), .squashn(ctrl_pipereg3_squashn), .en(ctrl_pipereg3_en), .q(pipereg3_q)); // defparam // pipereg3.WIDTH=32; nop nop7 ( .d(mux2to1_nop7_d_out), .q(nop7_q)); //defparam // nop7.WIDTH=32; nop nop ( .d(mux2to1_nop_d_out), .q(nop_q)); //defparam // nop.WIDTH=32; nop nop10 ( .d(mux7to1_nop10_d_out), .q(nop10_q)); //defparam // nop10.WIDTH=32; nop nop6 ( .d(mux3to1_nop6_d_out), .q(nop6_q)); //defparam // nop6.WIDTH=32; zeroer zeroer ( .d(ifetch_rs), .en(ctrl_zeroer_en), .q(zeroer_q)); //defparam // zeroer.WIDTH=5; zeroer zeroer0 ( .d(ifetch_rt), .en(ctrl_zeroer0_en), .q(zeroer0_q)); //defparam // zeroer0.WIDTH=5; zeroer zeroer4 ( .d(mux3to1_zeroer4_d_out), .en(ctrl_zeroer4_en), .q(zeroer4_q)); //defparam // zeroer4.WIDTH=5; fakedelay fakedelay ( .clk(clk), .d(ifetch_pc_out), .q(fakedelay_q)); //defparam // fakedelay.WIDTH=32; // Multiplexor mux3to1_ifetch_load_data instantiation assign mux3to1_ifetch_load_data_out = (ctrl_mux3to1_ifetch_load_data_sel==2) ? pcadder_result : (ctrl_mux3to1_ifetch_load_data_sel==1) ? merge26lo_out : nop_q; // Multiplexor mux2to1_mul_opA instantiation assign mux2to1_mul_opA_out = (ctrl_mux2to1_mul_opA_sel==1) ? nop_q : nop6_q; // Multiplexor mux6to1_ifetch_load instantiation assign mux6to1_ifetch_load_out = (ctrl_mux6to1_ifetch_load_sel==3'd5) ? branchresolve_eq : (ctrl_mux6to1_ifetch_load_sel==3'd4) ? branchresolve_ne : (ctrl_mux6to1_ifetch_load_sel==3'd3) ? branchresolve_lez : (ctrl_mux6to1_ifetch_load_sel==3'd2) ? branchresolve_ltz : (ctrl_mux6to1_ifetch_load_sel==3'd1) ? branchresolve_gez : branchresolve_gtz; // Multiplexor mux3to1_mul_sa instantiation assign mux3to1_mul_sa_out = (ctrl_mux3to1_mul_sa_sel==2) ? nop_q : (ctrl_mux3to1_mul_sa_sel==1) ? const9_out : pipereg2_q; // Multiplexor mux2to1_addersub_opA instantiation assign mux2to1_addersub_opA_out = (ctrl_mux2to1_addersub_opA_sel==1) ? fakedelay_q : nop_q; // Multiplexor mux7to1_nop10_d instantiation assign mux7to1_nop10_d_out = (ctrl_mux7to1_nop10_d_sel==3'd6) ? addersub_result : (ctrl_mux7to1_nop10_d_sel==3'd5) ? addersub_result_slt : (ctrl_mux7to1_nop10_d_sel==3'd4) ? logic_unit_result : (ctrl_mux7to1_nop10_d_sel==3'd3) ? mul_shift_result : (ctrl_mux7to1_nop10_d_sel==3'd2) ? data_mem_d_loadresult : (ctrl_mux7to1_nop10_d_sel==3'd1) ? hi_reg_q : lo_reg_q; // Multiplexor mux2to1_pipereg_d instantiation assign mux2to1_pipereg_d_out = (ctrl_mux2to1_pipereg_d_sel==1) ? ifetch_offset : signext16_out; // Multiplexor mux3to1_nop6_d instantiation assign mux3to1_nop6_d_out = (ctrl_mux3to1_nop6_d_sel==2) ? pipereg_q : (ctrl_mux3to1_nop6_d_sel==1) ? nop7_q : const8_out; // Multiplexor mux3to1_zeroer4_d instantiation assign mux3to1_zeroer4_d_out = (ctrl_mux3to1_zeroer4_d_sel==2) ? ifetch_rt : (ctrl_mux3to1_zeroer4_d_sel==1) ? ifetch_rd : const_out; pipereg_w6 pipereg11 ( .clk(clk), .resetn(ctrl_pipereg11_resetn), .d(ifetch_opcode), .squashn(ctrl_pipereg11_squashn), .en(ctrl_pipereg11_en), .q(pipereg11_q)); //defparam // pipereg11.WIDTH=6; // Multiplexor mux2to1_nop_d instantiation assign mux2to1_nop_d_out = (pipereg15_q==1) ? pipereg14_q : reg_file_a_readdataout; pipereg_w1 pipereg16 ( .clk(clk), .resetn(ctrl_pipereg16_resetn), .d(haz_zeroer0_q_pipereg5_q), .squashn(ctrl_pipereg16_squashn), .en(ctrl_pipereg16_en), .q(pipereg16_q)); //defparam // pipereg16.WIDTH=1; pipereg_w1 pipereg15 ( .clk(clk), .resetn(ctrl_pipereg15_resetn), .d(haz_zeroer_q_pipereg5_q), .squashn(ctrl_pipereg15_squashn), .en(ctrl_pipereg15_en), .q(pipereg15_q)); //defparam // pipereg15.WIDTH=1; // Multiplexor mux2to1_nop7_d instantiation assign mux2to1_nop7_d_out = (pipereg16_q==1) ? pipereg14_q : reg_file_b_readdataout; pipereg_w6 pipereg12 ( .clk(clk), .resetn(ctrl_pipereg12_resetn), .d(ifetch_func), .squashn(ctrl_pipereg12_squashn), .en(ctrl_pipereg12_en), .q(pipereg12_q)); //defparam // pipereg12.WIDTH=6; pipereg_w5 pipereg13 ( .clk(clk), .resetn(ctrl_pipereg13_resetn), .d(ifetch_rt), .squashn(ctrl_pipereg13_squashn), .en(ctrl_pipereg13_en), .q(pipereg13_q)); //defparam // pipereg13.WIDTH=5; endmodule /**************************************************************************** AddSub unit - Should perform ADD, ADDU, SUBU, SUB, SLT, SLTU is_slt signext addsub op[2] op[1] op[0] | Operation 0 0 0 0 SUBU 2 0 1 0 SUB 1 0 0 1 ADDU 3 0 1 1 ADD 4 1 0 0 SLTU 6 1 1 0 SLT ****************************************************************************/ module addersub ( opB, opA, op, result_slt, result ); //parameter WIDTH=32; //`DEFINE WIDTH 32 input [31:0] opA; input [31:0] opB; //input carry_in; input [2:0] op; output result_slt; output [31:0] result; wire [32:0] sum; wire addsub; wire useless; assign useless = op[1] & op[2]; assign addsub=op[0]; wire not_addsub; assign not_addsub = ~addsub; assign result=sum[31:0]; assign result_slt=sum[32]; dummy_add_sub adder32bit (opA,opB,not_addsub,sum); // This is an LPM from Altera, replacing with a dummy one for now /* lpm_add_sub adder_inst( .dataa({signext&opA[WIDTH-1],opA}), .datab({signext&opB[WIDTH-1],opB}), .cin(~addsub), .add_sub(addsub), .result(sum) // synopsys translate_off , .cout (), .clken (), .clock (), .overflow (), .aclr () // synopsys translate_on ); //defparam // adder_inst.lpm_width=WIDTH+1, // adder_inst.lpm_representation="SIGNED"; */ endmodule module dummy_add_sub ( dataa, datab, cin, result ); //this is goign to be UUUUGGGGGGLLLYYYYY //probably going to do some serious timing violations // but i'm sure it will be interesting for the packing problem input [31:0] dataa; input [31:0] datab; input cin; output [32:0] result; // wire [31:0] carry_from; wire [31:0] sum; full_adder bit0 (cin,dataa[0],datab[0],sum[0],carry_from [0]); full_adder bit1 (carry_from [0],dataa[1],datab[1],sum[1],carry_from [1]); full_adder bit2 (carry_from [1],dataa[2],datab[2],sum[2],carry_from [2]); full_adder bit3 (carry_from [2],dataa[3],datab[3],sum[3],carry_from [3]); full_adder bit4 (carry_from [3],dataa[4],datab[4],sum[4],carry_from [4]); full_adder bit5 (carry_from [4],dataa[5],datab[5],sum[5],carry_from [5]); full_adder bit6 (carry_from [5],dataa[6],datab[6],sum[6],carry_from [6]); full_adder bit7 (carry_from [6],dataa[7],datab[7],sum[7],carry_from [7]); full_adder bit8 (carry_from [7],dataa[8],datab[8],sum[8],carry_from [8]); full_adder bit9 (carry_from [8],dataa[9],datab[9],sum[9],carry_from [9]); full_adder bit10 (carry_from [9],dataa[10],datab[10],sum[10],carry_from [10]); full_adder bit11 (carry_from [10],dataa[11],datab[11],sum[11],carry_from [11]); full_adder bit12 (carry_from [11],dataa[12],datab[12],sum[12],carry_from [12]); full_adder bit13 (carry_from [12],dataa[13],datab[13],sum[13],carry_from [13]); full_adder bit14 (carry_from [13],dataa[14],datab[14],sum[14],carry_from [14]); full_adder bit15 (carry_from [14],dataa[15],datab[15],sum[15],carry_from [15]); full_adder bit16 (carry_from [15],dataa[16],datab[16],sum[16],carry_from [16]); full_adder bit17 (carry_from [16],dataa[17],datab[17],sum[17],carry_from [17]); full_adder bit18 (carry_from [17],dataa[18],datab[18],sum[18],carry_from [18]); full_adder bit19 (carry_from [18],dataa[19],datab[19],sum[19],carry_from [19]); full_adder bit20 (carry_from [19],dataa[20],datab[20],sum[20],carry_from [20]); full_adder bit21 (carry_from [20],dataa[21],datab[21],sum[21],carry_from [21]); full_adder bit22 (carry_from [21],dataa[22],datab[22],sum[22],carry_from [22]); full_adder bit23 (carry_from [22],dataa[23],datab[23],sum[23],carry_from [23]); full_adder bit24 (carry_from [23],dataa[24],datab[24],sum[24],carry_from [24]); full_adder bit25 (carry_from [24],dataa[25],datab[25],sum[25],carry_from [25]); full_adder bit26 (carry_from [25],dataa[26],datab[26],sum[26],carry_from [26]); full_adder bit27 (carry_from [26],dataa[27],datab[27],sum[27],carry_from [27]); full_adder bit28 (carry_from [27],dataa[28],datab[28],sum[28],carry_from [28]); full_adder bit29 (carry_from [28],dataa[29],datab[29],sum[29],carry_from [29]); full_adder bit30 (carry_from [29],dataa[30],datab[30],sum[30],carry_from [30]); full_adder bit31 (carry_from [30],dataa[31],datab[31],sum[31],carry_from [31]); assign result [31:0] = sum; assign result [32] = carry_from [31]; endmodule module full_adder (cin,x,y,s,cout); input cin; input x; input y; output s; output cout; assign s = x^y^cin; assign cout = (x&y) | (x & cin) | (y&cin); endmodule /**************************************************************************** Register File - Has two read ports (a and b) and one write port (c) - sel chooses the register to be read/written ****************************************************************************/ module reg_file( clk, resetn, c_writedatain, c_reg, b_reg, a_reg, c_we, b_en, a_en, b_readdataout, a_readdataout ); //parameter WIDTH=32; //parameter NUMREGS=32; //parameter LOG2NUMREGS=5; input clk; input resetn; input a_en; input b_en; input [31:0] c_writedatain; input c_we; input [31:0] a_reg; input [31:0] b_reg; input [31:0] c_reg; output [31:0] a_readdataout; output [31:0] b_readdataout; reg [31:0] a_readdataout; reg [31:0] b_readdataout; wire [31:0] a_readdataout_temp; wire [31:0] b_readdataout_temp; assign b_readdataout = b_readdataout_temp; assign a_readdataout = a_readdataout_temp; wire wren1; assign wren1 = (c_we & (|c_reg)); single_port_ram regfile1_replace ( .clk (clk), .we(wren1), .data(c_writedatain), .out(a_readdataout_temp), .addr(c_reg[4:0]) ); //Reg file duplicated to avoid contention //between 2 read and 1 write //MORE MEMORY single_port_ram regfile2_replace( .clk (clk), .we(wren1), .data(c_writedatain), .out(b_readdataout_temp), .addr(c_reg[4:0]) ); //Odin II does not recognize that address //registers are being used to read and //write data, so they are assigned to an //unused wire which is later dropped by the //optimizer. wire useless_inputs; //`a_reg` and `b_reg` were not used correctly in last version //of `spree.v` according to the comment above this module. //Investigate whether the comment or the code is wrong assign useless_inputs = resetn & b_en & a_en & ( | a_reg ) & ( | b_reg ); endmodule /**************************************************************************** MUL/DIV unit Operation table op sign dir 4 1 0 x | MULTU 6 1 1 x | MULT 0 0 0 0 | ShiftLeft 1 0 0 1 | ShiftRightLogic 3 0 1 1 | ShiftRightArith ****************************************************************************/ module mul( clk, resetn, sa, dst, opB, opA, op, start, stalled, shift_result, lo, hi ); input clk; input resetn; input start; output stalled; input [4:0] dst; input [31:0] opA; input [31:0] opB; input [4:0] sa; input [2:0] op; output [31:0] shift_result; output [31:0] hi; output [31:0] lo; /********* Control Signals *********/ wire is_signed; wire dir; wire is_mul; assign is_mul=op[2]; // selects between opB and the computed shift amount assign is_signed=op[1]; assign dir=op[0]; // selects between 2^sa and 2^(32-sa) for right shift /********* Circuit Body *********/ wire dum; wire dum2; wire dum3; wire [32:0] opB_mux_out; wire [4:0] left_sa; // Amount of left shift required for both left/right reg [32:0] decoded_sa; wire [31:0] result; //assign opB_mux_out= (is_mul) ? {is_signed&opB[31],opB} : decoded_sa; assign opB_mux_out = opB; dummy_mult fake_mult_one (opA,opB_mux_out, clk, resetn, result); assign hi = result [15:8]; assign lo = result [7:0]; // Cannot support this now /* lpm_mult lpm_mult_component ( .dataa ({is_signed&opA[31],opA}), .datab (opB_mux_out), .sum(), .clock(clk), .clken(), .aclr(~resetn), .result ({dum2,dum,hi,lo})); defparam lpm_mult_component.lpm_32a = 32+1, lpm_mult_component.lpm_32b = 32+1, lpm_mult_component.lpm_32p = 2*32+2, lpm_mult_component.lpm_32s = 1, lpm_mult_component.lpm_pipeline = 1, lpm_mult_component.lpm_type = "LPM_MULT", lpm_mult_component.lpm_representation = "SIGNED", lpm_mult_component.lpm_hint = "MAXIMIZE_SPEED=6"; */ assign shift_result= (dir & |sa) ? hi : lo; // 1 cycle stall state machine wire or_dst; wire start_and_ismul; wire request; assign or_dst = |dst; assign start_and_ismul = start & is_mul; assign request = (or_dst & start & ~is_mul) | (start_and_ismul); onecyclestall staller(request,clk,resetn,stalled); endmodule module dummy_mult ( opA, opB_mux_out, clk, resetn, result ); input [31:0] opA; input [31:0] opB_mux_out; input clk; input resetn; output[31:0] result; reg [31:0] result; always @ (posedge clk) begin if (resetn) result <= 32'b00000000000000000000000000000000; else //multiplier by star symbol //though this is probably supposed to be signed result <= opA * opB_mux_out; end endmodule /**************************************************************************** Fetch Unit op 0 Conditional PC write 1 UnConditional PC write ****************************************************************************/ module ifetch( clk, resetn, boot_iaddr, boot_idata, boot_iwe, load, load_data, op, we, squashn, en, pc_out, instr, opcode, func, rs, rt, rd, instr_index, offset, sa, next_pc ); //parameter PC_WIDTH=30; //parameter I_DATAWIDTH=32; //parameter I_ADDRESSWIDTH=14; //parameter I_SIZE=16384; input [31:0] boot_iaddr; input [31:0] boot_idata; input boot_iwe; input clk; input resetn; input en; // PC increment enable input we; // PC write enable input squashn;// squash fetch input op; // determines if conditional or unconditional branch input load; input [`I_DATAWIDTH-1:0] load_data; output [`I_DATAWIDTH-1:0] pc_out; // output pc + 1 shifted left 2 bits output [`PC_WIDTH-1:0] next_pc; output [31:26] opcode; output [25:21] rs; output [20:16] rt; output [15:11] rd; output [10:6] sa; output [15:0] offset; output [25:0] instr_index; output [5:0] func; output [`I_DATAWIDTH-1:0] instr; wire [`PC_WIDTH-1:0] pc_plus_1; wire [`PC_WIDTH-1:0] pc; assign pc_plus_1 = pc; wire ctrl_load; wire out_of_sync; assign ctrl_load=(load&~op|op); wire notresetn; assign notresetn = ~resetn; wire count_en; assign count_en = (~ctrl_load)&~out_of_sync; wire counter_en; assign counter_en = en | we; wire [32:2] reg_load_data; assign reg_load_data = load_data [31:2]; wire reg_d; wire reg_en; assign reg_d = (we&(~en)&(squashn)); assign reg_en = en|we; register_1bit sync_pcs_up( reg_d, clk, resetn,reg_en, out_of_sync); wire wren1; assign wren1 = 1'b0; wire [9:0] next_pc_wire; assign next_pc_wire = next_pc [9:0]; wire [31:0]dummyout2; dual_port_ram imem_replace( .clk (clk), .we1(wren1), .we2(boot_iwe), .data1(load_data), .data2(boot_idata), .out1(instr), .out2(dummyout2), .addr1(next_pc_wire), .addr2(boot_iaddr[9:0]) ); wire [31:0] dummyin1; assign dummyin1 = 32'b00000000000000000000000000000000; dummy_counter pc_reg ((reg_load_data),(clk),(counter_en),(count_en),(notresetn),(ctrl_load),(pc)); assign pc_out [31:2] = pc_plus_1; assign pc_out [1:0] = 2'b00; assign next_pc = ctrl_load ? load_data[31:2] : pc_plus_1; assign opcode=instr[31:26]; assign rs=instr[25:21]; assign rt=instr[20:16]; assign rd=instr[15:11]; assign sa=instr[10:6]; assign offset=instr[15:0]; assign instr_index=instr[25:0]; assign func=instr[5:0]; //Odin II does not recognize that boot_iaddr //is being used to write data when system //is given 1'b1 on the boot_iwe wire so is //is assigned to an unused wire which is //later dropped by the optimizer. wire NoUse; assign NoUse = ( |boot_iaddr ); endmodule module dummy_counter ( data, clock, clk_en, cnt_en, aset, sload, q ); input [31:2] data; input clock; input clk_en; input cnt_en; input aset; input sload; output [`PC_WIDTH-1:0] q; reg [`PC_WIDTH-1:0] q; wire [2:0] sload_cnten_aset; assign sload_cnten_aset [0] = sload; assign sload_cnten_aset [1] = cnt_en; assign sload_cnten_aset [2] = aset; always @ (posedge clock) //if (cnt_en == 1) //q <= q+1; begin case (sload_cnten_aset) 3'b000: q <= q; 3'b011: q <= q; 3'b110: q <= q; 3'b111: q <= q; 3'b101: q <= q; 3'b100: q <= data; 3'b010: begin if (clk_en) q <= q+1; else q <= q; end 3'b001: q <= 29'b00000000000000000000000000000; default: q <= q; endcase end endmodule module data_mem( clk, resetn, stalled, d_writedata, d_address, op, d_loadresult ); input clk; input resetn; output stalled; input [`D_ADDRESSWIDTH-1:0] d_address; input [3:0] op; input [31:0] d_writedata; output [`DM_DATAWIDTH-1:0] d_loadresult; wire [`DM_BYTEENAWIDTH-1:0] d_byteena; wire [`DM_DATAWIDTH-1:0] d_readdatain; wire [`DM_DATAWIDTH-1:0] d_writedatamem; wire d_write; wire [1:0] d_address_latched; assign d_write=op[3]; wire [1:0] d_small_adr; assign d_small_adr = d_address[1:0]; wire one; assign one = 1'b1; wire [1:0] d_adr_one_zero; assign d_adr_one_zero = d_address [1:0]; wire [1:0] opsize; assign opsize = op[1:0]; wire opext; assign opext = op[2]; store_data_translator sdtrans_inst( .write_data(d_writedata), .d_address(d_adr_one_zero), .store_size(op[1:0]), .d_byteena(d_byteena), .d_writedataout(d_writedatamem) ); load_data_translator ldtrans_inst( .d_readdatain(d_readdatain), .d_loadresult(d_loadresult) ); wire dnot_address; assign dnot_address = ~d_address[31]; wire will_be_wren1; assign will_be_wren1 = d_write&(dnot_address); wire [9:0] memaddr_wrd; assign memaddr_wrd = d_address[`DM_ADDRESSWIDTH:2]; single_port_ram dmem_replace( .clk (clk), .we(will_be_wren1), .data(d_writedatamem), .out(d_readdatain), .addr(memaddr_wrd) ); // 1 cycle stall state machine wire en_and_not_d_write; assign en_and_not_d_write = ~d_write; onecyclestall staller(en_and_not_d_write,clk,resetn,stalled); wire useless_inputs; assign useless_inputs = |d_address; endmodule //temp in here /**************************************************************************** Store data translator - moves store data to appropriate byte/halfword - interfaces with altera blockrams ****************************************************************************/ module store_data_translator( write_data, // data in least significant position d_address, store_size, d_byteena, d_writedataout // shifted data to coincide with address ); //parameter WIDTH=32; input [31:0] write_data; input [1:0] d_address; input [1:0] store_size; output [3:0] d_byteena; output [31:0] d_writedataout; reg [3:0] d_byteena; reg [31:0] d_writedataout; always @(write_data or d_address or store_size) begin case (store_size) 2'b11: case(d_address[1:0]) 2'b00: begin d_byteena=4'b1000; d_writedataout={write_data[7:0],24'b0}; end 2'b01: begin d_byteena=4'b0100; d_writedataout={8'b0,write_data[7:0],16'b0}; end 2'b10: begin d_byteena=4'b0010; d_writedataout={16'b0,write_data[7:0],8'b0}; end default: begin d_byteena=4'b0001; d_writedataout={24'b0,write_data[7:0]}; end endcase 2'b01: case(d_address[1]) 1'b0: begin d_byteena=4'b1100; d_writedataout={write_data[15:0],16'b0}; end default: begin d_byteena=4'b0011; d_writedataout={16'b0,write_data[15:0]}; end endcase default: begin d_byteena=4'b1111; d_writedataout=write_data; end endcase end endmodule /**************************************************************************** Load data translator - moves read data to appropriate byte/halfword and zero/sign extends ****************************************************************************/ module load_data_translator( d_readdatain, d_loadresult ); //parameter WIDTH=32; input [31:0] d_readdatain; output [31:0] d_loadresult; wire d_adr_one; assign d_adr_one = d_address [1]; reg [31:0] d_loadresult; reg sign; wire [1:0] d_address; assign d_address [1:0] =d_readdatain [25:24]; //assume always full-word-access always @(d_readdatain or d_address ) begin d_loadresult[31:0]=d_readdatain[31:0]; end /* Odin II REFUSES TO ACKNOWLEDGE THAT SIGN EXTENDING IS NOT A COMBINATIONAL LOOP always @(d_readdatain or d_address or load_size or load_sign_ext) begin case (load_size) 2'b11: begin case (d_address) 2'b00: begin d_loadresult[7:0]=d_readdatain[31:24]; sign = d_readdatain[31]; end 2'b01: begin d_loadresult[7:0]=d_readdatain[23:16]; sign = d_readdatain[23]; end 2'b10: begin d_loadresult[7:0]=d_readdatain[15:8]; sign = d_readdatain[15]; end default: begin d_loadresult[7:0]=d_readdatain[7:0]; sign = d_readdatain[7]; end endcase // peter milankov note: do this by hand // odin II does not support multiple concatenation //d_loadresult[31:8]={24{load_sign_ext&d_loadresult[7]}}; d_loadresult[31]= load_sign_ext&sign; d_loadresult[30]= load_sign_ext&sign; d_loadresult[29]= load_sign_ext&sign; d_loadresult[28]= load_sign_ext&sign; d_loadresult[27]= load_sign_ext&sign; d_loadresult[26]= load_sign_ext&sign; d_loadresult[25]= load_sign_ext&sign; d_loadresult[24]= load_sign_ext&sign; d_loadresult[23]= load_sign_ext&sign; d_loadresult[22]= load_sign_ext&sign; d_loadresult[21]= load_sign_ext&sign; d_loadresult[20]= load_sign_ext&sign; d_loadresult[19]= load_sign_ext&sign; d_loadresult[18]= load_sign_ext&sign; d_loadresult[17]= load_sign_ext&sign; d_loadresult[16]= load_sign_ext&sign; d_loadresult[15]= load_sign_ext&sign; d_loadresult[14]= load_sign_ext&sign; d_loadresult[13]= load_sign_ext&sign; d_loadresult[12]= load_sign_ext&sign; d_loadresult[11]= load_sign_ext&sign; d_loadresult[10]= load_sign_ext&sign; d_loadresult[9]= load_sign_ext&sign; d_loadresult[8]= load_sign_ext&sign; end 2'b01: begin case (d_adr_one) 1'b0: begin d_loadresult[15:0]=d_readdatain[31:16]; sign = d_readdatain[31]; end default: begin d_loadresult[15:0]=d_readdatain[15:0]; sign = d_readdatain[15]; end endcase // peter milankov note sign extend is concat, do by hand //d_loadresult[31:16]={16{load_sign_ext&d_loadresult[15]}}; d_loadresult[31]= load_sign_ext&sign; d_loadresult[30]= load_sign_ext&sign; d_loadresult[29]= load_sign_ext&sign; d_loadresult[28]= load_sign_ext&sign; d_loadresult[27]= load_sign_ext&sign; d_loadresult[26]= load_sign_ext&sign; d_loadresult[25]= load_sign_ext&sign; d_loadresult[24]= load_sign_ext&sign; d_loadresult[23]= load_sign_ext&sign; d_loadresult[22]= load_sign_ext&sign; d_loadresult[21]= load_sign_ext&sign; d_loadresult[20]= load_sign_ext&sign; d_loadresult[19]= load_sign_ext&sign; d_loadresult[18]= load_sign_ext&sign; d_loadresult[17]= load_sign_ext&sign; d_loadresult[16]= load_sign_ext&sign; end default: d_loadresult[31:0]=d_readdatain[31:0]; endcase end */ endmodule /**************************************************************************** logic unit - note ALU must be able to increment PC for JAL type instructions Operation Table op 0 AND 1 OR 2 XOR 3 NOR ****************************************************************************/ module logic_unit ( opB, opA, op, result ); //parameter WIDTH=32; input [31:0] opA; input [31:0] opB; input [1:0] op; output [31:0] result; reg [31:0] logic_result; always@(opA or opB or op ) case(op) 2'b00: logic_result=opA&opB; 2'b01: logic_result=opA|opB; 2'b10: logic_result=opA^opB; 2'b11: logic_result=~(opA|opB); endcase assign result=logic_result; endmodule module pcadder( offset, pc, result ); //parameter PC_WIDTH=32; input [31:0] pc; input [31:0] offset; output [31:0] result; wire dum; wire useless_inputs; assign useless_inputs = |offset; assign {dum,result} = pc + {offset[31:0],2'b0}; endmodule module signext16 (in, out); input [15:0] in; output [31:0] out; assign out [30]= in[15]; assign out [31]= in[15]; assign out [29]= in[15]; assign out [28]= in[15]; assign out [27]= in[15]; assign out [26]= in[15]; assign out [25]= in[15]; assign out [24]= in[15]; assign out [23]= in[15]; assign out [22]= in[15]; assign out [21]= in[15]; assign out [20]= in[15]; assign out [19]= in[15]; assign out [18]= in[15]; assign out [17]= in[15]; assign out [16]= in[15]; assign out [15:0] = in [15:0]; endmodule module merge26lo(in2, in1, out); input [31:0] in1; input [25:0] in2; output [31:0] out; //assign out[31:0]={in1[31:28],in2[25:0],2'b0}; assign out [31:28] = in1 [31:28]; assign out [27:2] = in2 [25:0]; assign out [1:0] = 2'b00; wire useless_inputs; assign useless_inputs = |in1 & |in2; endmodule /**************************************************************************** Generic Register ****************************************************************************/ module lo_reg( clk, resetn, d, en, q ); //parameter WIDTH=32; input clk; input resetn; input en; input [31:0] d; output [31:0] q; reg [31:0] q; always @(posedge clk ) begin if (resetn==0) q<=0; else if (en==1) q<=d; end endmodule /**************************************************************************** Generic Register ****************************************************************************/ module hi_reg( clk, resetn, d, en, q ); //parameter WIDTH=32; input clk; input resetn; input en; input [31:0] d; output [31:0] q; reg [31:0] q; always @(posedge clk ) //used to be asynchronous reset begin if (resetn==0) q<=0; else if (en==1) q<=d; end endmodule /**************************************************************************** Generic Register ****************************************************************************/ //`define WIDTH 32 /* module register(d,clk,resetn,en,q); //parameter WIDTH=32; input clk; input resetn; input en; input [31:0] d; output [31:0] q; reg [31:0] q; always @(posedge clk ) begin if (resetn==0) q<=0; else if (en==1) q<=d; end endmodule */ module register_1bit( d, clk, resetn, en, q ); //parameter WIDTH=32; input clk; input resetn; input en; input d; output q; reg q; always @(posedge clk ) begin if (resetn==0) q<=0; else if (en==1) q<=d; end endmodule /**************************************************************************** Generic Register - synchronous reset ****************************************************************************/ /* module register_sync(d,clk,resetn,en,q); //parameter WIDTH=32; input clk; input resetn; input en; input [31:0] d; output [31:0] q; reg [31:0] q; always @(posedge clk) //synchronous reset begin if (resetn==0) q<=0; else if (en==1) q<=d; end endmodule */ /**************************************************************************** Generic Pipelined Register - Special component, components starting with "pipereg" have their enables treated independently of instructrions that use them. - They are enabled whenever the stage is active and not stalled ****************************************************************************/ /* module pipereg(clk,resetn,d,squashn,en,q); //parameter WIDTH=32; //`define WIDTH 32 input clk; input resetn; input en; input squashn; input [31:0] d; output [31:0] q; reg [31:0] q; always @(posedge clk) //synchronous reset begin if (resetn==0 || squashn==0) q<=0; else if (en==1) q<=d; end endmodule */ module pipereg_w32( clk, resetn, d, squashn, en, q ); //parameter WIDTH=32; //`define WIDTH 32 input clk; input resetn; input en; input squashn; input [31:0] d; output [31:0] q; reg [31:0] q; always @(posedge clk) //synchronous reset begin if (resetn==0 || squashn==0) q<=0; else if (en==1) q<=d; end endmodule module pipereg_w26( clk, resetn, d, squashn, en, q ); //parameter WIDTH=32; //`define WIDTH 32 input clk; input resetn; input en; input squashn; input [25:0] d; output [25:0] q; reg [25:0] q; always @(posedge clk) //synchronous reset begin if (resetn==0 || squashn==0) q<=0; else if (en==1) q<=d; end endmodule module pipereg_w6( clk, resetn, d, squashn, en, q ); //parameter WIDTH=32; //`define WIDTH 32 input clk; input resetn; input en; input squashn; input [31:0] d; output [31:0] q; reg [31:0] q; always @(posedge clk) //synchronous reset begin if (resetn==0 || squashn==0) q<=0; else if (en==1) begin q[5:0]<=d; q[31:6] <= 0; end end endmodule module pipereg_w5( clk, resetn, d, squashn, en, q ); //parameter WIDTH=32; //`define WIDTH 32 input clk; input resetn; input en; input squashn; input [31:0] d; output [31:0] q; reg [31:0] q; always @(posedge clk) //synchronous reset begin if (resetn==0 || squashn==0) q<=0; else if (en==1) begin q[4:0]<=d; q[31:5] <= 0; end end endmodule module pipereg_w1( clk, resetn, d, squashn, en, q ); //parameter WIDTH=32; //`define WIDTH 32 input clk; input resetn; input en; input squashn; input d; output q; reg q; always @(posedge clk) //synchronous reset begin if (resetn==0 || squashn==0) q<=0; else if (en==1) q<=d; end endmodule /**************************************************************************** Generic Pipelined Register 2 -OLD: If not enabled, queues squash - This piperegister stalls the reset signal as well */ /* module pipereg_full(d,clk,resetn,squashn,en,q); //parameter WIDTH=32; input clk; input resetn; input en; input squashn; input [31:0] d; output [31:0] q; reg [31:0] q; reg squash_save; always @(posedge clk) //synchronous reset begin if (resetn==0 || (squashn==0 && en==1) || (squash_save&en)) q<=0; else if (en==1) q<=d; end always @(posedge clk) begin if (resetn==1 && squashn==0 && en==0) squash_save<=1; else squash_save<=0; end endmodule */ /****************************************************************************/ /**************************************************************************** One cycle Stall circuit ****************************************************************************/ module onecyclestall( request, clk, resetn, stalled ); input request; input clk; input resetn; output stalled; reg T,Tnext; // State machine for Stalling 1 cycle always@(request or T) begin case(T) 1'b0: Tnext=request; 1'b1: Tnext=0; endcase end always@(posedge clk) if (~resetn) T<=0; else T<=Tnext; assign stalled=(request&~T); endmodule /**************************************************************************** Multi cycle Stall circuit - with wait signal - One FF plus one 2:1 mux to stall 1st cycle on request, then wait - this makes wait don't care for the first cycle ****************************************************************************/ /* module multicyclestall(request, devwait,clk,resetn,stalled); input request; input devwait; input clk; input resetn; output stalled; reg T; always@(posedge clk) if (~resetn) T<=0; else T<=stalled; assign stalled=(T) ? devwait : request; endmodule */ /**************************************************************************** One cycle - Pipeline delay register ****************************************************************************/ /* module pipedelayreg(d,en,clk,resetn,squashn,dst,stalled,q); //`define WIDTH 32 //parameter WIDTH=32; input [31:0] d; input [4:0] dst; input en; input clk; input resetn; input squashn; output stalled; output [31:0] q; reg [31:0] q; reg T,Tnext; // State machine for Stalling 1 cycle always@(en or T or dst) begin case(T) 0: Tnext=en&(|dst); 1: Tnext=0; endcase end always@(posedge clk) if (~resetn) T<=0; else T<=Tnext; always @(posedge clk) //synchronous reset begin if (resetn==0 || squashn==0) q<=0; else if (en==1) q<=d; end assign stalled=(en&~T&(|dst)); endmodule */ /**************************************************************************** Fake Delay ****************************************************************************/ module fakedelay(clk,d,q); //`define WIDTH 32 //parameter WIDTH=32; input [31:0] d; input clk; output [31:0] q; wire unused; assign unused = clk; assign q=d; endmodule /**************************************************************************** Zeroer ****************************************************************************/ module zeroer(d,en,q); //parameter WIDTH=32; //`define WIDTH 32 input en; input [4:0] d; output [31:0] q; assign q[4:0]= (en) ? d : 0; assign q [31:05] = 0; endmodule /**************************************************************************** NOP - used to hack position of multiplexors ****************************************************************************/ module nop(d,q); //parameter WIDTH=32; //`define WIDTH 32 input [31:0] d; output [31:0] q; assign q=d; endmodule /**************************************************************************** Const ****************************************************************************/ /**************************************************************************** Branch detector ****************************************************************************/ /* module branch_detector(opcode, func, is_branch); input [5:0] opcode; input [5:0] func; output is_branch; wire is_special; assign is_special=!(|opcode); assign is_branch=((!(|opcode[5:3])) && !is_special) || ((is_special)&&(func[5:3]==3'b001)); endmodule */ //`define WIDTH 32 module branchresolve ( rt, rs, en, eqz, gez, gtz, lez, ltz, ne, eq ); //parameter WIDTH=32; input en; input [31:0] rs; input [31:0] rt; output eq; output ne; output ltz; output lez; output gtz; output gez; output eqz; assign eq=(en)&(rs==rt); assign ne=(en)&~eq; assign eqz=(en)&~(|rs); assign ltz=(en)&rs[31]; assign lez=(en)&rs[31] | eqz; assign gtz=(en)&(~rs[31]) & ~eqz; assign gez=(en)&(~rs[31]); endmodule