从零开始设计riscv cpu记录之二

📅 2026/6/30 10:20:27
从零开始设计riscv cpu记录之二
目前写的代码是最简单的基本的思路后期再慢慢添加控制逻辑逐步完善。八、pc_reg.v代码includedefines.vmodulepc_reg(input wire clk,input wire rst,input wire jump_i,input wire[AW-1:0]jump_addr_i,input wire stall_i,output reg[AW-1:0]pc_o);always(posedge clk)beginif(rstRstEnable)begin pc_oRstAddr;endelseif(jump_iJumpEnable)begin pc_ojump_addr_i;endelseif(stall_iStallEnable)begin pc_opc_o;endelsebegin pc_opc_o32d4;end end endmodule九、ifetch.v代码includedefines.vmoduleifetch(//from pc_reg.vinput[AW-1:0]pc_i,// romoutput[AW-1:0]rom_raddr_o,input[DW-1:0]rom_rdata_i,// to if_id.voutput[DW-1:0]inst_o,output[AW-1:0]inst_addr_o);assign rom_raddr_opc_i;assign inst_orom_rdata_i;assign inst_addr_opc_i;endmodule十、if_id.v代码includedefines.vmoduleif_id(input wire clk,input wire rst,input wire hold_i,input wire flush_i,input wire[DW-1:0]inst_i,input wire[AW-1:0]inst_addr_i,output reg[DW-1:0]inst_o,output reg[AW-1:0]inst_addr_o);always(posedge clk)beginif(rstRstEnable)begin inst_oINST_NOP;inst_addr_oZeroWord;endelseif(flush_iFlushEnable)begin inst_oINST_NOP;inst_addr_oZeroWord;endelseif(hold_iHoldEnable)begin inst_oinst_o;inst_addr_oinst_addr_o;endelsebegin inst_oinst_i;inst_addr_oinst_addr_i;end end endmodule十一、id.v代码timescale1ns/1ps includedefines.vmoduleid(// from if_id.vinput wire[DW-1:0]inst_i,input wire[AW-1:0]inst_addr_i,//regs.voutput reg[4:0]reg1_raddr_o,output reg[4:0]reg2_raddr_o,input wire[DW-1:0]reg1_rdata_i,input wire[DW-1:0]reg2_rdata_i,//to id_ex.voutput reg reg_we_o,output reg[4:0]reg_waddr_o,output reg[DW-1:0]inst_o,output reg[AW-1:0]inst_addr_O,output reg[DW-1:0]op1_o,output reg[DW-1:0]op2_o,output reg[DW-1:0]op1_jump_o,output reg[DW-1:0]op2_jump_o);// inst slicewire[6:0]opcodeinst_i[6:0];wire[4:0]rdinst_i[11:7];wire[2:0]func3inst_i[14:12];wire[4:0]rs1inst_i[19:15];wire[4:0]rs2inst_i[24:20];wire[6:0]func7inst_i[31:25];always(*)begin reg_we_oWriteDisable;reg_waddr_oZeroReg;inst_oinst_i;inst_addr_Oinst_addr_i;op1_oZeroWord;op2_oZeroWord;op1_jump_oZeroWord;op2_jump_oZeroWord;reg1_raddr_oZeroReg;reg2_raddr_oZeroReg;case(opcode)INST_TYPE_LUI:begin reg_we_oWriteEnable;reg_waddr_ord;op1_o{inst_i[31:12],12h0};op2_oZeroWord;end INST_TYPE_AUIPC:begin reg_we_oWriteEnable;reg_waddr_ord;op1_oinst_addr_i;op2_o{inst_i[31:12],12h0};end INST_TYPE_JAL:begin reg_we_oWriteEnable;reg_waddr_ord;op1_oinst_addr_i;op2_o32h4;op1_jump_oinst_addr_i;op2_jump_o{{12{inst_i[31]}},inst_i[19:12],inst_i[20],inst_i[30:21],1b0};end INST_TYPE_JALR:begin reg_we_oWriteEnable;reg_waddr_ord;reg1_raddr_ors1;op1_oinst_addr_i;op2_o32h4;op1_jump_oreg1_rdata_i;op2_jump_o{{20{inst_i[31]}},inst_i[31:20]};end INST_TYPE_B:begincase(func3)INST_BEQ,INST_BNE,INST_BLT,INST_BGE,INST_BLTU,INST_BGEU:begin reg1_raddr_ors1;reg2_raddr_ors2;op1_oreg1_rdata_i;op2_oreg2_rdata_i;op1_jump_oinst_addr_i;op2_jump_o{{20{inst_i[31]}},inst_i[7],inst_i[30:25],inst_i[11:8],1b0};enddefault:begin end endcase end INST_TYPE_LOAD:begincase(func3)INST_LB,INST_LH,INST_LW,INST_LBU,INST_LHU:begin reg_we_oWriteEnable;reg_waddr_ord;reg1_raddr_ors1;reg2_raddr_oZeroReg;op1_oreg1_rdata_i;op2_o{{20{inst_i[31]}},inst_i[31:20]};enddefault:begin end endcase end INST_TYPE_STORE:begincase(func3)INST_SB,INST_SH,INST_SW:begin reg1_raddr_ors1;reg2_raddr_ors2;op1_oreg1_rdata_i;op2_o{{20{inst_i[31]}},inst_i[31:25],inst_i[11:7]};enddefault:begin end endcase end INST_TYPE_I:begincase(func3)INST_ADDI,INST_SLTI,INST_SLTIU,INST_XORI,INST_ORI,INST_ANDI,INST_SLLI,INST_SRI:begin reg1_raddr_ors1;reg_we_oWriteEnable;reg_waddr_ord;op1_oreg1_rdata_i;op2_o{{20{inst_i[31]}},inst_i[31:20]};enddefault:begin end endcase end INST_TYPE_R_M:beginif(func7func7_R||func7func7_sub_sra)begincase(func3)INST_ADD_SUB,INST_SLL,INST_SLT,INST_SLTU,INST_XOR,INST_SR,INST_OR,INST_AND:begin reg1_raddr_ors1;reg2_raddr_ors2;reg_we_oWriteEnable;reg_waddr_ord;op1_oreg1_rdata_i;op2_oreg2_rdata_i;enddefault:begin end endcase endelseif(func7func7_M)begincase(func3)INST_MUL,INST_MULH,INST_MULHSU,INST_MULHU:begin reg1_raddr_ors1;reg2_raddr_ors2;reg_we_oWriteEnable;reg_waddr_ord;op1_oreg1_rdata_i;op2_oreg2_rdata_i;end INST_DIV,INST_DIVU,INST_REM,INST_REMU:begin reg1_raddr_ors1;reg2_raddr_ors2;op1_oreg1_rdata_i;op2_oreg2_rdata_i;reg_waddr_ord;op1_jump_oinst_addr_i;op2_jump_o32h4;enddefault:begin end endcase endelsebegin end end INST_TYPE_FENCE:begin op1_jump_oinst_addr_i;op2_jump_o32h4;enddefault:begin end endcase end endmodule十二、id_ex.v代码includedefines.vmoduleid_ex(input wire clk,input wire rst,input wire flush_i,input wire stall_i,input wire[DW-1:0]inst_i,input wire[AW-1:0]inst_addr_i,input wire reg_we_i,input wire[4:0]reg_waddr_i,input wire[DW-1:0]op1_i,input wire[DW-1:0]op2_i,input wire[DW-1:0]op1_jump_i,input wire[DW-1:0]op2_jump_i,output reg[DW-1:0]inst_o,output reg[AW-1:0]inst_addr_o,output reg reg_we_o,output reg[4:0]reg_waddr_o,output reg[DW-1:0]op1_o,output reg[DW-1:0]op2_o,output reg[DW-1:0]op1_jump_o,output reg[DW-1:0]op2_jump_o);always(posedge clk)beginif(rst||flush_i)begin inst_oINST_NOP;inst_addr_oZeroWord;reg_we_oWriteDisable;reg_waddr_oZeroReg;op1_oZeroWord;op2_oZeroWord;op1_jump_oZeroWord;op2_jump_oZeroWord;endelseif(stall_iStallEnable)begin inst_oinst_o;inst_addr_oinst_addr_o;reg_we_oreg_we_o;reg_waddr_oreg_waddr_o;op1_oop1_o;op2_oop2_o;op1_jump_oop1_jump_o;op2_jump_oop2_jump_o;endelsebegin inst_oinst_i;inst_addr_oinst_addr_i;reg_we_oreg_we_i;reg_waddr_oreg_waddr_i;op1_oop1_i;op2_oop2_i;op1_jump_oop1_jump_i;op2_jump_oop2_jump_i;end end endmodule