| /**************************************************************************** |
| 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 |
| |
| |