📄 r2000_cpu_pipe.v
字号:
r2000_pipe #(`dw) IDEX_up_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(`CLEAR) , .D_i(ID_imup) , .Q_o(EX_imup) ); r2000_pipe #(`iw) IDEX_rd_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(`CLEAR) , .D_i(ID_mux_rd_index_out) , .Q_o(EX_rd_index) ); `ifdef CP0 r2000_pipe #( 1) IDEX_sig_brk_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(`CLEAR) , .flush_i(`CLEAR) , .D_i(ID_sig_clt_brk) , .Q_o(EX_sig_clt_brk) ); r2000_pipe #( 1) IDEX_sig_sys_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(`CLEAR) , .flush_i(`CLEAR) , .D_i(ID_sig_clt_sys) , .Q_o(EX_sig_clt_sys) ); r2000_pipe #( 1) IDEX_rfe_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(`CLEAR) , .D_i(ID_clt_rfe) , .Q_o(EX_clt_rfe) ); r2000_pipe #( 1) IDEX_comt_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(`CLEAR) , .D_i(ID_clt_CoMt) , .Q_o(EX_clt_CoMt) ); r2000_pipe #(`dw) IDEX_epc_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(`CLEAR) , .D_i(ID_EPC) , .Q_o(EX_EPC) ); r2000_pipe #(`SELWIDTH) IDEX_brc_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(`CLEAR) , .D_i(ID_mux_branch_sel) , .Q_o(EX_mux_branch_sel) );`endif //CP0 /*======================================================================================================================================================*/ /* EX:Execution STAGE */ /*======================================================================================================================================================*/ /* ************************* */ /* ARITHMETIC and LOGIC UNIT */ /* ************************* */ assign EX_funct = EX_inst[5:0] ; // -- function (R-format) assign EX_shamt = EX_inst[10:6] ; // -- Shift amount// assign EX_rs_index = EX_inst[25:21] ; // -- rs register index assign EX_rt_index = EX_inst[20:16] ; // -- rt register index /* ALU CONTROL */ r2000_aluctrl unit_alucontrol ( /* Input */ .AluOp_i (EX_ctl_alu_op) , .FuncCode_i (EX_funct) , /* Output */ .AluCtl_o (EX_alu_cmd) // alu command type ); /* OPERAND B SOURCE */ r2000_mux3 mux_alu_operandb ( .in0_i (EX_reg_rt) , // rt index register file... .in1_i (EX_signextend) , // or sign extended immediat... .in2_i (EX_zeroextend) , // or zero extended immediat... .sel_i (EX_ctl_alu_src_b) , // .out_o (EX_mux_src_b_out) // operand b choice ); /* THE ALU UNIT */ r2000_alu unit_alu ( /* Input */ .AluCtl_i (EX_alu_cmd) , // alu command .A_i (EX_reg_rs) , // operand a .B_i (EX_mux_src_b_out) , // operand b .StateValid_i (EX_ctl_alu_status) , // Valid Status /* Output */ .AluOut_o (EX_alu_out) , // alu result .Status_o (EX_AluStatus) // status flags );`ifdef CP0 assign {EX_Carry, EX_Zero, EX_Neg, EX_ovf} = EX_AluStatus; // Alu Status assign EX_sig_ovf = EX_ovf;`endif //CP0 /* SHIFTER AMOUNT SOURCE */ r2000_mux2 #(5) mux_shift_variable ( .in0_i (EX_shamt) , // from the shamt field of the instruction... .in1_i (EX_reg_rs[4:0]) , // or rs index register file .sel_i (EX_ctl_shift_var) , .out_o (EX_shifter_amount) // the shift amount choice ); /* THE SHIFTER UNIT */ r2000_shifter unit_shifter ( /* Input */ .A_i (EX_reg_rt) , // operand .SH_i (EX_shifter_amount) , // Shift amount .LR_i (EX_ctl_shift_lr) , // Left/Right .LA_i (EX_ctl_shift_la) , // Logic/Arithmetic /* Output */ .G_o (EX_shifter_out) // shifter result ); /* THE MULTIPLICATION/DIVISION UNIT */ r2000_multdiv unit_multdiv ( .en_i (EX_freeze) , /* Input */ .clk_i (~clk_i) , .rst_i (rst_i) , .operand1_i (EX_reg_rs) , // first operand .operand2_i (EX_reg_rt) , // second operand .datain_i (EX_reg_rs) , // data input .sign_i (EX_ctl_multdiv_sign) , // un/signed .mult_div_i (EX_ctl_multdiv_op) , // type of operation .start_i (EX_ctl_multdiv_start) , // start the operation .hiw_i (EX_ctl_multdiv_hiw) , // hi write .low_i (EX_ctl_multdiv_low) , // lo write /* Output */ .hi_o (EX_hi) , // hi result .lo_o (EX_lo) , // lo result .ready_o (EX_multdiv_ready) // end of operation ); r2000_mux7 mux_reg_w ( /* Input */ .in0_i (EX_alu_out) , // from the alu result... .in1_i (`ZERO) , // or from null (not used) .in2_i (EX_shifter_out) , // or from the shifter result .in3_i (EX_PCplus8) , // or from the pc unit .in4_i (EX_hi) , // or from the hi register .in5_i (EX_lo) , // or from the lo register .in6_i (EX_imup) , // or from the immediat up .sel_i (EX_ctl_execution_op) , /* Output */ .out_o (EX_result_operation) // write register choice ); /* *************** */ /* EX/MEM PIPELINE */ /* *************** */ /* CONTROL */ // MEM r2000_pipe #( 1) EXMEM_ctl_mem_read_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_ctl_mem_read) , .Q_o(MEM_ctl_mem_read) ); r2000_pipe #( 1) EXMEM_ctl_mem_write_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_ctl_mem_write) , .Q_o(MEM_ctl_mem_write) ); r2000_pipe #( 1) EXMEM_ctl_mem_oe_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_ctl_mem_oe) , .Q_o(MEM_ctl_mem_oe) ); r2000_pipe #( 2) EXMEM_ctl_mem_tail_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_ctl_mem_tail) , .Q_o(MEM_ctl_mem_tail) ); r2000_pipe #( 1) EXMEM_ctl_mem_sign_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_ctl_mem_sign) , .Q_o(MEM_ctl_mem_sign) ); // WB r2000_pipe #( 1) EXMEM_ctl_reg_write_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_ctl_reg_write) , .Q_o(MEM_ctl_reg_write) ); r2000_pipe #( 1) EXMEM_ctl_reg_src_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_clt_reg_src) , .Q_o(MEM_clt_reg_src) ); /* DATAPATH */`ifdef DEBUG r2000_pipe #(`dw) EXMEM_inst_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_inst) , .Q_o(MEM_inst) );`endif//DEBUG r2000_pipe #(`dw) EXMEM_result_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_result_operation) , .Q_o(MEM_result_operation) ); r2000_pipe #(`dw) EXMEM_address_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_alu_out) , .Q_o(MEM_alu_out) ); r2000_pipe #(`iw) EXMEM_rd_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_rd_index) , .Q_o(MEM_rd_index) ); r2000_pipe #(`dw) EXMEM_rt_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_reg_rt) , .Q_o(MEM_reg_rt) ); `ifdef CP0 r2000_pipe #( 1) EXMEM_sig_brk_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(`CLEAR) , .flush_i(`CLEAR) , .D_i(EX_sig_clt_brk) , .Q_o(MEM_sig_clt_brk) ); r2000_pipe #( 1) EXMEM_sig_sys_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(`CLEAR) , .flush_i(`CLEAR) , .D_i(EX_sig_clt_sys) , .Q_o(MEM_sig_clt_sys) ); r2000_pipe #( 6) EXMEM_sig_int_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(`CLEAR) , .flush_i(`CLEAR) , .D_i(sig_int_i) , .Q_o(MEM_sig_int) ); r2000_pipe #( 2) EXMEM_sig_si_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(`CLEAR) , .flush_i(`CLEAR) , .D_i(sig_si_i) , .Q_o(MEM_sig_si) ); r2000_pipe #( 1) EXMEM_sig_ovf_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(`CLEAR) , .flush_i(`CLEAR) , .D_i(EX_sig_ovf) , .Q_o(MEM_sig_ovf) ); r2000_pipe #( 1) EXMEM_comt_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_clt_CoMt) , .Q_o(MEM_clt_CoMt) ); r2000_pipe #( 1) EXMEM_rfe_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_clt_rfe) , .Q_o(MEM_clt_rfe) ); r2000_pipe #(`dw) EXMEM_epc_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_EPC) , .Q_o(MEM_EPC) ); r2000_pipe #(`SELWIDTH) EXMEM_brc_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(EXMEM_stall) , .flush_i(EXMEM_flush) , .D_i(EX_mux_branch_sel) , .Q_o(MEM_mux_branch_sel) );`endif //CP0 /*======================================================================================================================================================*/ /* MEM:Memory STAGE */ /*======================================================================================================================================================*/ /* ************************* */ /* MEMORY DATA BUS interface */ /* ************************* */`ifdef DCACHE`else// DCACHE r2000_reg2mem unit_reg_to_mem ( .RegData_i (MEM_reg_rt) , // Register Side .Length_i (MEM_ctl_mem_tail) , // WORD, HALF, BYTE .Ad_i (MemDataAddrInt[1:0]) , // the two least significant bits effective address .Oe_i (MEM_ctl_mem_oe) , // Memory Write .MemData_o (MemDataInterDout) , // Memory Side .low1_o (MEM_MemDataBlew1) , .high1_o (MEM_MemDataBhew1) , .low2_o (MEM_MemDataBlew2) , .high2_o (MEM_MemDataBhew2) );`endif// DCACHE r2000_mem2reg unit_mem_to_reg ( .MemData_i (mem_data_data_i) , // Memory Side (MemDataDin), // Memory Side .Length_i (MEM_ctl_mem_tail) , // WORD, HALF, BYTE .Sign_i (MEM_ctl_mem_sign) , // Sign extension type .Ad_i (MemDataAddrInt[1:0]) , // the two least significant bits effective address .Rd_i (MEM_ctl_mem_read) , // Memory Read .RegData_o (MemDataInterDin) , // Register Side .low1_o (MEM_MemDataBler1) , .high1_o (MEM_MemDataBher1) , .low2_o (MEM_MemDataBler2) , .high2_o (MEM_MemDataBher2) ); /* ********************************************************************* */ /* OUTPUTS SIGNALS FROM CPU TO MEMORY */ /* ********************************** */ // Enable assign mem_data_en_o = MEM_freeze; // Read write assign mem_data_wr_o = MEM_ctl_mem_write; assign mem_data_rd_o = MEM_ctl_mem_read; // Adress assign MemDataAddrInt = MEM_alu_out; assign mem_data_addr_o = MemDataAddrInt;`ifdef DCACHE // Data assign mem_data_data_o = MEM_reg_rt; // remove "r2000_reg2mem" // Bit select assign mem_data_width_o = MEM_ctl_mem_tail;`else// DCACHE // Data assign mem_data_data_o = MemDataInterDout; // On reset bi-directional ports in input state // Bit select assign mem_data_blel_o = ~(~MEM_MemDataBlew1 | ~MEM_MemDataBler1); assign mem_data_bhel_o = ~(~MEM_MemDataBhew1 | ~MEM_MemDataBher1); assign mem_data_bleh_o = ~(~MEM_MemDataBlew2 | ~MEM_MemDataBler2); assign mem_data_bheh_o = ~(~MEM_MemDataBhew2 | ~MEM_MemDataBher2);`endif// DCACHE /* REGISTER DATA WRITE SOURCE */ r2000_mux2 mux_reg_datain ( .in0_i (MEM_result_operation) , // from the Result of execution operation (ALU, SHIFTER, MULT/DIVDER...) .in1_i (MemDataInterDin) , // or from the data memory .sel_i (MEM_clt_reg_src) , .out_o (MEM_RegDatain) // the result write back to the registerfile );`ifdef CP0 always@(`CLOCK_EDGE clk_i, `RESET_EDGE rst_i) begin if (rst_i == `RESET_ON) MEM_branch_Slot = `CLEAR; else // Branch Slot instruction in MEM stage (see mux_pc) MEM_branch_Slot = ((MEM_mux_branch_sel == 1) || (MEM_mux_branch_sel == 2) || (MEM_mux_branch_sel == 3)); end /*==================================================*/ /* CP0 :Co-Processor0 Unit */ /*==================================================*/ r2000_cp0 unit_cp0 ( // Register transfert .rw_i (MEM_clt_CoMt) , // Read/Write Signal .addr_i (MEM_rd_index) , // Adress of the register Write .data_i (MEM_RegDatain) , // Data in the register .addr_o (ID_rd_index) , // Adress of the register Read .data_o (MEM_cp0_dout) , // Data out of the register .brch_i (MEM_branch_Slot) , // Detect exception in Branch Slot // Exception signals .OVF_i (MEM_sig_ovf) , // Overflow exception .SYS_i (MEM_sig_clt_sys) , // System exception .INT_i (MEM_sig_int) , // Interrupt interrupt .SI_i (MEM_sig_si) , // .EPC_i (MEM_EPC) , // PC to EPC .Exception_o (wException) , // Exception occured .PC_vec_o (wEPC_Vector) , // Exception Vector .rfe_i (MEM_clt_rfe) , // Signal of the rfe instruction // System .rst_i (rst_i) , .clk_i (~clk_i) );`endif //CP0 /* *************** */ /* MEM/WB PIPELINE */ /* *************** */ /* CONTROL */ // WB r2000_pipe #( 1) MEMWB_ctl_reg_write_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(MEMWB_stall) , .flush_i(MEMWB_flush) , .D_i(MEM_ctl_reg_write) , .Q_o(WB_ctl_reg_write) ); /* DATAPATH */`ifdef DEBUG r2000_pipe #(`dw) MEMWB_inst_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(MEMWB_stall) , .flush_i(MEMWB_flush) , .D_i(MEM_inst) , .Q_o(WB_inst) );`endif//DEBUG r2000_pipe #(`dw) MEMWB_regdatain_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(MEMWB_stall) , .flush_i(MEMWB_flush) , .D_i(MEM_RegDatain) , .Q_o(WB_RegDatain) ); r2000_pipe #(`iw) MEMWB_rd_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(MEMWB_stall) , .flush_i(MEMWB_flush) , .D_i(MEM_rd_index) , .Q_o(WB_rd_index) ); /*======================================================================================================================================================*/ /* WB:Write Back STAGE */ /*======================================================================================================================================================*/endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -