📄 r2000_cpu_pipe.v
字号:
.id_rt_i (ID_rt_index) , .ex_rt_i (EX_rt_index) , .ex_mem_read_i (EX_ctl_mem_read), .ex_multdiv_rdy_i (EX_multdiv_ready) , .id_ctl_exe_op_i (ID_ctl_execution_op) , /* Output */ .IF_stall (IF_stall) , .IFID_stall (IFID_stall), .IDEX_stall (IDEX_stall), .EXMEM_stall (EXMEM_stall), .MEMWB_stall (MEMWB_stall), .EX_freeze (EX_freeze) , .MEM_freeze (MEM_freeze), .WB_freeze (WB_freeze) , .IFID_flush (IFID_flush), .IDEX_flush (IDEX_flush), .EXMEM_flush(EXMEM_flush), .MEMWB_flush (MEMWB_flush) ); /*======================================================================================================================================================*/ /* IF:Instruction Fetch STAGE */ /*======================================================================================================================================================*/ /* *********** */ /* THE PC UNIT */ /* *********** */ r2000_pc unit_pc ( /* Input */ .clk_i (clk_i) , .rst_i (rst_i) , .mux_pc_i (ID_mux_pc_out) , .stall_i (IF_stall) , /* Output */ .PC_o (wPC) , .PC4_o (IF_PCplus4) );`ifdef BREAK_PT always@(`CLOCK_EDGE clk_i) if (wPC == 'h9d0) $stop;`endif //BREAK_PT // Code Memory address assign mem_code_addr_o = wPC; /* ************** */ /* IF/ID PIPELINE */ /* ************** */ /* CONTROL */ /* DATAPATH */ r2000_pipe #(`dw) IFID_pc_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IFID_stall) , .flush_i(IFID_flush) , .D_i(IF_PCplus4) , .Q_o(ID_PCplus4) ); r2000_pipe #(`dw) IFID_inst_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IFID_stall) , .flush_i(IFID_flush) , .D_i(mem_code_inst_i) , .Q_o(ID_inst) );`ifdef CP0 assign IF_EPC = wPC; r2000_pipe #(`dw) IFID_epc_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IFID_stall) , .flush_i(IFID_flush) , .D_i(IF_EPC) , .Q_o(ID_EPC) );`endif //CP0 /*======================================================================================================================================================*/ /* ID:Instruction Decode STAGE */ /*======================================================================================================================================================*/ /* ****************** */ /* INSTRUCTION decode */ /* ****************** */ assign ID_rs_index = ID_inst[25:21]; // -- rs register index assign ID_rt_index = ID_inst[20:16]; // -- rt register index assign ID_rd_index = ID_inst[15:11]; // -- rd register index assign ID_im = ID_inst[15:0]; // -- Immediat assign ID_imup = { ID_im, {16{1'b0}}}; // -- Immediat Up assign ID_signextend = {{16{ID_im[15]}}, ID_im}; // -- Sign extended assign ID_zeroextend = { {16{1'b0}}, ID_im}; // -- Zero extended /* THE DECODER UNIT OF THE CPU */ r2000_decoder unit_decoder ( /* Input */ .Instruction_i (ID_inst) , // the instruction /* Output */ /* INSTRUCTION DECODE STAGE */ .RegDrt_o (ID_ctl_reg_rt) , .BranchSel_o (ID_ctl_branch_type) , // branch/jump control .ConditionSel_o (ID_ctl_branch_cond) , /* EXECUTION STAGE */ .AluOp_o (ID_ctl_alu_op) , // alu controls .AluSrcB_o (ID_ctl_alu_src_b) , .AluStatus_o (ID_ctl_alu_status) , .ShiftVar_o (ID_ctl_shift_var) , // shifter control .ShiftLr_o (ID_ctl_shift_lr) , .ShiftLa_o (ID_ctl_shift_la) , .MultDivSign_o (ID_ctl_multdiv_sign) , // multiplication/division control .MultDivOp_o (ID_ctl_multdiv_op) , .MultDivStart_o (ID_ctl_multdiv_start) , .MultDivHiW_o (ID_ctl_multdiv_hiw) , .MultDivLoW_o (ID_ctl_multdiv_low) , .ExOp_o (ID_ctl_execution_op) , // choice the operation result /* MEMORY STAGE */ .MemRead_o (ID_ctl_mem_read) , // memory interface bus control .MemWrite_o (ID_ctl_mem_write) , .MemOe_o (ID_ctl_mem_oe) , .MemLength_o (ID_ctl_mem_tail) , .MemSign_o (ID_ctl_mem_sign) , /* WRITE BACK STAGE */ .RegWrite_o (ID_ctl_reg_write) , // register file controls .RegDst_o (ID_ctl_reg_dst) , .RegSrc_o (ID_clt_reg_src) , /* CO-PROCESSOR 0 */ .CoSys_o (ID_sig_clt_sys) , // syscall instruction cp0 .CoBreak_o (ID_sig_clt_brk) , // break instruction cp0 .CoRfe_o (ID_clt_rfe) , // rfe cp0 .CoMf_o (ID_clt_CoMf) , // CP0 Move From .CoMt_o (ID_clt_CoMt) // CP0 Move To ); /* FORWARD UNIT */ r2000_forward unit_forward ( /* input */ .id_rs_i (ID_rs_index) , .id_rt_i (ID_rt_index) , .ex_rd_i (EX_rd_index) , .ex_reg_write_i (EX_ctl_reg_write), .mem_rd_i (MEM_rd_index) , .mem_reg_write_i (MEM_ctl_reg_write), .wb_rd_i (WB_rd_index) , .wb_reg_write_i (WB_ctl_reg_write), /* Output */ .sel_a_o (rs_sel) , .sel_b_o (rt_sel) ); /* FORWARD MUX */ assign ID_reg_rs_forward = (rs_sel == 1) ? EX_result_operation : (rs_sel == 2) ? MEM_RegDatain : (rs_sel == 3) ? WB_RegDatain :`ifdef CP0 (ID_clt_CoMt || ID_clt_CoMf) ? `ZERO : //Suppress the influence of rs field wich is MT=00100`endif //CP0 ID_reg_rs ; assign ID_reg_rt_forward = (rt_sel == 1) ? EX_result_operation : (rt_sel == 2) ? MEM_RegDatain : (rt_sel == 3) ? WB_RegDatain :`ifdef CP0 (ID_clt_CoMf) ? MEM_cp0_dout : `endif //CP0 ID_reg_rt ; /* *********************** */ /* THE NEW PC VALUE CHOICE */ /* *********************** */ assign wAdresse16 = ID_inst[15:0]; // -- Immediat 16 bits assign wAdresse26 = ID_inst[25:0]; // -- Immediat 26 bits assign wTargetBranch = { {14{wAdresse16[15]}}, wAdresse16, 2'b0 }; // -- Branch value assign wTargetJump = { ID_PCplus4[31:28] , wAdresse26, 2'b0 }; // -- Jump value `ifdef CP0 r2000_mux5 #(`aw) mux_pc ( /* Input */ .in0_i (IF_PCplus4), // from the pc + 4... .in1_i (ID_reg_rs_forward) , // or from rs indexed register file... .in2_i (ID_PCplus4 + wTargetBranch), // or from the branch value... .in3_i (wTargetJump) , // or from the jump value .in4_i (wEPC_Vector) , // or from the CP0 EPC .sel_i (ID_mux_branch_sel) , // /* Output */ .out_o (ID_mux_pc_out) // the new pc value choice );`else r2000_mux4 #(`aw) mux_pc ( /* Input */ .in0_i (IF_PCplus4), // from the pc + 4... .in1_i (ID_reg_rs_forward) , // or from rs indexed register file... .in2_i (ID_PCplus4 + wTargetBranch), // or from the branch value... .in3_i (wTargetJump) , // or from the jump value .sel_i (ID_mux_branch_sel) , // /* Output */ .out_o (ID_mux_pc_out) // the new pc value choice );`endif //CP0 assign ID_PCplus8 = ID_PCplus4 + 4; // the pc + 4 was executed in the delay slot so store the pc + 8 /* THE COMPARE UNIT */ r2000_cmp unit_comparator ( /* Input */ .A_i (ID_reg_rs_forward), // Operand A .B_i (ID_reg_rt_forward), // Operand B /* Output */ .Status_o (ID_cmp_status) // Status Flags ); /* THE BRANCH DECODER UNIT */ r2000_branchdecoder unit_branchdecoder ( /* Input */ .BranchType_i (ID_ctl_branch_type), // branch type .CondSel_i (ID_ctl_branch_cond), // branch condition .Status_i (ID_cmp_status) , // status flags from the alu`ifdef CP0 .Exception_i (wException) , // Exception has occured`endif //CP0 /* Output */ .BranchSel_o (ID_mux_branch_sel) // the branch type of the pc ); /* THE rt index SOURCE */ r2000_mux2 #(`iw) mux_rt_index ( /* Input */ .in0_i (ID_rt_index) , // from the instruction rt field... .in1_i (`zer0) , // or zero .sel_i (ID_ctl_reg_rt) , /* Output */ .out_o (ID_mux_rt_index_out) // rt index choice ); /* THE rd index SOURCE */ r2000_mux3 #(`iw) mux_rd_index ( /* Input */ .in0_i (ID_rd_index) , // from the instruction rd field... .in1_i (ID_rt_index) , // or from the instruction rt field... .in2_i (`ra) , // or from the ra register pointer .sel_i (ID_ctl_reg_dst) , /* Output */ .out_o (ID_mux_rd_index_out) // rd index choice ); /* REGISTER FILE UNIT */ r2000_regfile unit_regfile ( .en_i (WB_freeze) , .clk_i (~clk_i) , // may put REGISTER FILE ON NEGEDGE CLK .rst_i (rst_i) , /* Read from the register file */ .RdIndex1_i (ID_rs_index) , .Data1_o (ID_reg_rs) , .RdIndex2_i (ID_mux_rt_index_out) , .Data2_o (ID_reg_rt) , /* Write to register file */ .WrIndex_i (WB_rd_index) , .Data_i (WB_RegDatain) , .Wr_i (WB_ctl_reg_write) ); /* ************** */ /* ID/EX PIPELINE */ /* ************** */ /* CONTROL */ // EX r2000_pipe #( 3) IDEX_ctl_alu_op_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_alu_op) , .Q_o(EX_ctl_alu_op) ); r2000_pipe #( 2) IDEX_ctl_alu_src_b_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_alu_src_b) , .Q_o(EX_ctl_alu_src_b) ); r2000_pipe #( 1) IDEX_ctl_alu_status_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_alu_status) , .Q_o(EX_ctl_alu_status) ); r2000_pipe #( 1) IDEX_ctl_shift_var_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_shift_var) , .Q_o(EX_ctl_shift_var) ); r2000_pipe #( 1) IDEX_ctl_shift_lr_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_shift_lr) , .Q_o(EX_ctl_shift_lr) ); r2000_pipe #( 1) IDEX_ctl_shift_la_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_shift_la) , .Q_o(EX_ctl_shift_la) ); r2000_pipe #( 1) IDEX_ctl_multdiv_sign_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_multdiv_sign) , .Q_o(EX_ctl_multdiv_sign) ); r2000_pipe #( 1) IDEX_ctl_multdiv_op_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_multdiv_op) , .Q_o(EX_ctl_multdiv_op) ); r2000_pipe #( 1) IDEX_ctl_multdiv_start_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_multdiv_start) , .Q_o(EX_ctl_multdiv_start) ); r2000_pipe #( 1) IDEX_ctl_multdiv_hiw_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_multdiv_hiw) , .Q_o(EX_ctl_multdiv_hiw) ); r2000_pipe #( 1) IDEX_ctl_multdiv_low_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_multdiv_low) , .Q_o(EX_ctl_multdiv_low) ); r2000_pipe #( 3) IDEX_ctl_execution_op_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_execution_op) , .Q_o(EX_ctl_execution_op) ); // MEM r2000_pipe #( 1) IDEX_ctl_mem_read_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_mem_read) , .Q_o(EX_ctl_mem_read) ); r2000_pipe #( 1) IDEX_ctl_mem_write_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_mem_write) , .Q_o(EX_ctl_mem_write) ); r2000_pipe #( 1) IDEX_ctl_mem_oe_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_mem_oe) , .Q_o(EX_ctl_mem_oe) ); r2000_pipe #( 2) IDEX_ctl_mem_tail_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_mem_tail) , .Q_o(EX_ctl_mem_tail) ); r2000_pipe #( 1) IDEX_ctl_mem_sign_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_mem_sign) , .Q_o(EX_ctl_mem_sign) ); // WB r2000_pipe #( 1) IDEX_ctl_reg_write_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_ctl_reg_write) , .Q_o(EX_ctl_reg_write) ); r2000_pipe #( 1) IDEX_ctl_reg_src_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_clt_reg_src) , .Q_o(EX_clt_reg_src) ); /* DATAPATH */ r2000_pipe #(`dw) IDEX_pc_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(`CLEAR) , .D_i(ID_PCplus8) , .Q_o(EX_PCplus8) ); r2000_pipe #(`dw) IDEX_inst_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(IDEX_flush) , .D_i(ID_inst) , .Q_o(EX_inst) ); r2000_pipe #(`dw) IDEX_rs_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(`CLEAR) , .D_i(ID_reg_rs_forward) , .Q_o(EX_reg_rs) ); r2000_pipe #(`dw) IDEX_rt_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(`CLEAR) , .D_i(ID_reg_rt_forward) , .Q_o(EX_reg_rt) ); r2000_pipe #(`dw) IDEX_se_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(`CLEAR) , .D_i(ID_signextend) , .Q_o(EX_signextend) ); r2000_pipe #(`dw) IDEX_ze_pipe (.clk_i(clk_i) , .rst_i(rst_i) , .stall_i(IDEX_stall) , .flush_i(`CLEAR) , .D_i(ID_zeroextend) , .Q_o(EX_zeroextend) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -