视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
中南大学EDA课设基于verilog 的RISC CPU设计源码
2025-10-03 15:16:56 责编:小OO
文档
module RISC16(CLK, Rstn, InstAddr, Inst, DW, DAddr, WData, RData);

input CLK, Rstn;

output [31:0]InstAddr, DAddr;

input [15:0]Inst;

outputDW;

output [31:0]WData;

input [31:0]RData;

// IA stage

reg[31:0]PC_reg;//PC register

wire[31:0]PC_add2, PC_addoffset, PC;//new data for PC

wire[1:0]PC_Sel;//select signal for PC

regPC_W;//write signal for PC register

// DC stage

reg[15:0]IFDC_reg;//pipeline register for IFDC

regIFDC_W;//write signal for IFDC register

wireIFDC_Flush;//clear signal for IFDC register

reg[31:0]RegFile[31:0];//register file

wire[31:0]Reg0, Reg1;//operand 0 and 1

reg[3:0]DC_ALU_OP;//ALU operation code from decoder

regDC_WB, DC_DW, DC_LD;//writeback,store,load sigal from decoder

reg[3:0]DC_BJ;//branch condition from decoder

// EX stage

regDCEX_Flush;//clear signal for DCEX register

reg [3:0]DCEX_ALU_OP;//ALU operation code in DCEX register

regDCEX_DW, DCEX_LD, DCEX_WB;//store,load,writeback signal in DCEX register

reg [31:0]DCEX_Reg0, DCEX_Reg1;//operand 0, 1 in DCEX register

reg [4:0]DCEX_imm, DCEX_RegAddr0, DCEX_RegAddr1; //immediate data, register address 0 and 1 in DCEX register

wire signed [ 32:0]ALU_OP0, ALU_OP1;//operand 0 , 1 for ALU

reg signed [32:0]ALU_Result;// result from ALU

regALU_Z, ALU_N;// flag Z, N from ALU

regALU_Z_reg, ALU_N_reg;// flag registers for Z and N

wire [31:0]EX_WData;// witeback data in EX stage

// WB stage

regEXWB_WB;// writeback signal in EXWB register

reg[4:0]EXWB_WAddr;// writeback address in EXWB register

reg[31:0]EXWB_WData;// writeback data in EXWB register

wire[31:0]EX_STData, EX_OP0, EX_OP1;// store data, operand 0 and 1 in EX stage

wire[1:0]EX_BP_Sel_MA_Addr, EX_BP_Sel_MA_Data, EX_BP_Sel_OP0,EX_BP_Sel_OP1;// bypass select siganls

// XX stage

regWBXX_WB;// writeback signal in WBXX register

reg[4:0]WBXX_WAddr;// writeback address in WBXX register

reg[31:0]WBXX_WData;// writeback data in WBXX regsiter

//

// IA stage

//

assign PC_add2 = PC_reg + 2'b10;

assign PC_addoffset = PC_reg + {{21{IFDC_reg[9]}},IFDC_reg[9:0],1'b0}; //two different way ?

assign PC = (PC_Sel == 2'b00)? PC_add2 : (PC_Sel == 2'b01) ? PC_addoffset : {21'h000000,IFDC_reg[9:0],1'b0};// normal case; branch; jump

//

// IF stage

//

// PC register

always@(posedge CLK or negedge Rstn)

begin

if (!Rstn)

PC_reg <= 32'h00000000;

else if (PC_W)

PC_reg <= PC;

end

// instruction address for InstRAM

assign InstAddr = PC_reg;

//

// DC stage

//

// IFDC

register

always@(posedge CLK or negedge Rstn)

begin

if (!Rstn)

IFDC_reg <= 16'h0000;

else if (IFDC_Flush)

IFDC_reg <= 16'h0000;

else if (IFDC_W)

IFDC_reg <= Inst;

end

// RegFile

always@(posedge CLK)

begin

if (EXWB_WB) //write signle enable

RegFile[EXWB_WAddr] <= EXWB_WData;

end

// operand 0 and 1 from register file

assign Reg0 = RegFile[IFDC_reg[9:5]];

assign Reg1 = RegFile[IFDC_reg[4:0]];

// decoder

// DC_ALU_OP: operation code of ALU

//0000(ADD), 0001(SUB,CMP),0010(AND),0011(OR),0100(XOR),0101(LSL),0110(LSR),0111(ASR),1000(MOV),1111(others)

// DC_WB: writeback siganl

// DC_DW: ST signal

// DC_LD: LD signal

// DC_BJ: Branch or Jump conditions

//0001(BNZ),0010(BZ),0011(BLE),0100(BLT),0101(BGE),0110(BGT),0111(B),1000(JUMP),0000(others

// PC_W: write enable sigal for PC_reg

// IFDC_W: write enable signal for IFDC pipeline register

// DCEX_Flush: clear sigal for DCEX pipeline register

always@(IFDC_reg[15:10])

begin

case(IFDC_reg[15:10])

6'b010000: begin

DC_ALU_OP= 4'b0000;//ADD

DC_WB = 1'b1;

DC_DW = 1'b0;

DC_LD = 1'b0;

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b0;

end

//**********************************************************************

//Please finish the RTL code here!

//**********************************************************************

//==================pc_W IFdc_w ecex_flush?

6'b010001: begin

DC_ALU_OP= 4'b0001;//SUB

DC_WB = 1'b1; //result save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b0;

end

6'b010010: begin

DC_ALU_OP= 4'b0001;//CMP

DC_WB = 1'b0; //result no save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b0;

end

6'b010100: begin

DC_ALU_OP= 4'b0010;//AND

DC_WB = 1'b1; //result save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b0;

end

6'b010101: begin

DC_ALU_OP= 4'b0011;//0R

DC_WB = 1'b1; //result save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b0;

end

6'b010110: begin

DC_ALU_OP= 4'b0100;//XOR

DC_WB = 1'b1; //result save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b0;

en

d

6'b100000: begin

DC_ALU_OP= 4'b0101;//LSL

DC_WB = 1'b1; //result save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b0;

end

6'b100001: begin

DC_ALU_OP= 4'b0110;//LSR

DC_WB = 1'b1; //result save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b0;

end

6'b100010: begin

DC_ALU_OP= 4'b0111;//ASR

DC_WB = 1'b1; //result save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b0;

end

6'b100111: begin

DC_ALU_OP= 4'b1000;//MOV

DC_WB = 1'b1; //result save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b0;

end

6'b011000: begin

DC_ALU_OP= 4'b1111;//LD

DC_WB = 1'b1; //result save

DC_DW = 1'b0; //no store

DC_LD = 1'b1; //load

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b0;

end

6'b011001: begin

DC_ALU_OP= 4'b1111;//ST

DC_WB = 1'b0; //result no save

DC_DW = 1'b1; //store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b0;

end

6'b110000: begin

DC_ALU_OP= 4'b1111;//BZ

DC_WB = 1'b0; //result no save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0010;//BZ

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b1;

end

6'b110001: begin

DC_ALU_OP= 4'b1111;//BNZ

DC_WB = 1'b0; //result no save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0001;//BNZ

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b1;

end

6'b110010: begin

DC_ALU_OP= 4'b1111;//BLE

DC_WB = 1'b0; //result no save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0011;//BLE

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b1;

end

6'b110011: begin

DC_ALU_OP= 4'b1111;//BLT

DC_WB = 1'b0; //result no save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0100;//BLT

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b1;

end

6'b110100: begin

DC_ALU_OP= 4'b1111;//BGE

DC_WB = 1'b0; //result no save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0101;//BGE

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b1;

end

6'b110101: begin

DC_ALU_OP= 4'b1111;//BGT

DC_WB = 1'b0; //result no save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0110;//BGT

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b1;

end

6'b110110: begin

DC_ALU_OP= 4'b1111;//B

DC_WB = 1'b0; //result no save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0111;// B

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b1;

end

6'b111000: begin

DC_ALU_OP= 4'b1111;//JUMP

DC_WB = 1'b0; //no save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b1000;// JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b1;

end

6'b000000: begin

DC_ALU_OP= 4'b1111;//NOP

DC_WB = 1'b0; //no save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b1;

IFDC_W = 1'b1;

DCEX_Flush = 1'b0; //do no thing

end

6'b000001: begin

DC_ALU_OP= 4'b1111;//WAIT

DC_WB = 1'b0; //no save

DC_DW = 1'b0; //no store

DC_LD = 1'b0; //no load

DC_BJ = 4'b0000;// no Branch, no JUMP

PC_W = 1'b0;

IFDC_W = 1'b0;

DCEX_Flush = 1'b1; //

end

endcase

end

// Branch

// PC select signal decided by branch condition(DC_BJ) and flag registers

//01: Branch

//10: JUMP

//00: no branch and no JUMP;

//**********************************************************************

//Please finish the RTL code here!

//**********************************************************************

assign PC_Sel = (DC_BJ == 4'b0000)?2'b00: //0

(DC_BJ == 4'b0010&&ALU_Z==1)?2'b01: //bz

(DC_BJ == 4'b0001&&ALU_Z==0)?2'b01: //bnz

(DC_BJ == 4'b0011&&(ALU_Z==1||ALU_N==1))?2'b01: //ble

(DC_BJ == 4'b0100&&(ALU_Z==0&&ALU_N==1))?2'b01: //blt

(DC_BJ == 4'b0101&&(ALU_Z==1||ALU_N==0))?2'b01: //bge

(DC_BJ == 4'b0110&&(ALU_Z==0&&ALU_N==0))?2'b01: //bgt

(DC_BJ == 4'b0111)?2'b01: //b

(DC_BJ == 4'b1000)?2'b10:2'b00; //jump

// clear signal for IFDC register

assign IFDC_Flush = (PC_Sel != 2'b00 && DC_BJ != 4'b0000) ? 1'b1 : 1'b0;

//

// EX stage

//

// DCEX registers

always@(posedge CLK or negedge Rstn)

begin

if (!Rstn) begin

DCEX_ALU_OP <= 4'b0000;

DCEX_DW<= 1'b0;

DCEX_LD<= 1'b0;

DCEX_WB<= 1'b0;

DCEX_Reg0 <= 32'h00000000;

DCEX_Reg1<= 32'h00000000;

DCEX_imm<= 5'h00;

DCEX_RegAddr0 <= 5'h00;

DCEX_RegAddr1 <=

5'h00;

end

else if (DCEX_Flush) begin

DCEX_ALU_OP <= 4'b0000;

DCEX_DW<= 1'b0;

DCEX_LD<= 1'b0;

DCEX_WB<= 1'b0;

DCEX_Reg0 <= 32'h00000000;

DCEX_Reg1<= 32'h00000000;

DCEX_imm<= 5'h00;

DCEX_RegAddr0 <= 5'h00;

DCEX_RegAddr1 <= 5'h00;

end

else begin

DCEX_ALU_OP <= DC_ALU_OP;

DCEX_DW<= DC_DW;

DCEX_LD<= DC_LD;

DCEX_WB<= DC_WB;

DCEX_Reg0 <= Reg0;

DCEX_Reg1<= Reg1;

DCEX_imm<= IFDC_reg[4:0];

DCEX_RegAddr0 <= IFDC_reg[9:5];

DCEX_RegAddr1 <= IFDC_reg[4:0];

end

end

// bypass controller

// 01: bypass from EXWB pipeline register

// 10:bypass from WBXX pipeline register

// 00: no bypass

//**********************************************************************

//Please finish the following RTL code!

//**********************************************************************//judge adress

// bypass select signal for address to DataRAM

assign EX_BP_Sel_MA_Addr = ((DCEX_RegAddr1==EXWB_WAddr)&&EXWB_WB)?2'b01:

((DCEX_RegAddr1==WBXX_WAddr)&&WBXX_WB)?2'b10:2'b00;

// bypass select signal for data to DataRAM

assign EX_BP_Sel_MA_Data = ((DCEX_RegAddr0==EXWB_WAddr)&&EXWB_WB)?2'b01:

((DCEX_RegAddr0==WBXX_WAddr)&&WBXX_WB)?2'b10:2'b00;

// bypass select signal for operand 0 to ALU

assign EX_BP_Sel_OP0 = ((DCEX_RegAddr0==EXWB_WAddr)&&EXWB_WB)?2'b01:

((DCEX_RegAddr0==WBXX_WAddr)&&WBXX_WB)?2'b10:2'b00;

// bypass select signal for operand 1 to ALU

assign EX_BP_Sel_OP1 = ((DCEX_RegAddr1==EXWB_WAddr)&&EXWB_WB)?2'b01:

((DCEX_RegAddr1==WBXX_WAddr)&&WBXX_WB)?2'b10:2'b00;

// DataRAM interface

assign DW = DCEX_DW;

assign DAddr = (EX_BP_Sel_MA_Addr == 2'b00) ? DCEX_Reg1 :

(EX_BP_Sel_MA_Addr == 2'b01) ? EXWB_WData :

WBXX_WData;

assign WData = (EX_BP_Sel_MA_Data == 2'b00) ? DCEX_Reg0 :

(EX_BP_Sel_MA_Data == 2'b01) ? EXWB_WData :

WBXX_WData;

// ALU

// operands

assign ALU_OP0 = (EX_BP_Sel_OP0 == 2'b00) ? {DCEX_Reg0[31], DCEX_Reg0} :

(EX_BP_Sel_OP0 == 2'b01) ? {EXWB_WData[31], EXWB_WData}:

{WBXX_WData[31], WBXX_WData};

assign ALU_OP1 = (EX_BP_Sel_OP1 == 2'b00) ? {DCEX_Reg1[31], DCEX_Reg1} :

(EX_BP_Sel_OP1 == 2'b01) ? {EXWB_WData[31], EXWB_WData}:

{WBXX_WData[31], WBXX_WData};

// ALU operations

always@(*)

begin

case(DCEX_ALU_OP)

4'b0000: begin//ADD

ALU_Result = ALU_OP0 + ALU_OP1;

if (ALU_Result == 0)

ALU_Z = 1'b1;

else

ALU_Z = 1'b0;

if (ALU_Result[32:31] == 2'b11)

ALU_N = 1'b1;

else

ALU_N = 1'b0;

end

//**********************************************************************

//Please finish the following RTL code!

//**********************************************************************

4'b0001

: begin//SUB

ALU_Result = ALU_OP0 - ALU_OP1;

if (ALU_Result == 0)

ALU_Z = 1'b1;

else

ALU_Z = 1'b0;

if (ALU_Result[32:31] == 2'b11)

ALU_N = 1'b1;

else

ALU_N = 1'b0;

end

4'b0010: begin//AND

ALU_Result = ALU_OP0&ALU_OP1;

if (ALU_Result == 0)

ALU_Z = 1'b1;

else

ALU_Z = 1'b0;

if (ALU_Result[32:31] == 2'b11)

ALU_N = 1'b1;

else

ALU_N = 1'b0;

end

4'b0011: begin//OR

ALU_Result = ALU_OP0|ALU_OP1;

if (ALU_Result == 0)

ALU_Z = 1'b1;

else

ALU_Z = 1'b0;

if (ALU_Result[32:31] == 2'b11)

ALU_N = 1'b1;

else

ALU_N = 1'b0;

end

4'b0100: begin//XOR

ALU_Result = ALU_OP0 ^ ALU_OP1;

if (ALU_Result == 0)

ALU_Z = 1'b1;

else

ALU_Z = 1'b0;

if (ALU_Result[32:31] == 2'b11)

ALU_N = 1'b1;

else

ALU_N = 1'b0;

end

4'b0101: begin//LSL

ALU_Result = ALU_OP0 << DCEX_imm;

if (ALU_Result == 0)

ALU_Z = 1'b1;

else

ALU_Z = 1'b0;

if (ALU_Result[32:31] == 2'b11)

ALU_N = 1'b1;

else

ALU_N = 1'b0;

end

4'b0110: begin//LSR

ALU_Result = ALU_OP0 >> DCEX_imm;

if (ALU_Result == 0)

ALU_Z = 1'b1;

else

ALU_Z = 1'b0;

if (ALU_Result[32:31] == 2'b11)

ALU_N = 1'b1;

else

ALU_N = 1'b0;

end

4'b0111: begin//ASR

ALU_Result = ALU_OP0 >>> DCEX_imm;

if (ALU_Result == 0)

ALU_Z = 1'b1;

else

ALU_Z = 1'b0;

if (ALU_Result[32:31] == 2'b11)

ALU_N = 1'b1;

else

ALU_N = 1'b0;

end

4'b1000: begin//moV

ALU_Result = DCEX_imm;

ALU_Z<= ALU_Z_reg;

ALU_N <= ALU_N_reg ;

end

4'b1111: begin//other

ALU_Z<= ALU_Z_reg;

ALU_N <= ALU_N_reg ;

end

endcase

end

// flag registers

always@(posedge CLK or negedge Rstn)

begin

if (!Rstn) begin

ALU_Z_reg <= 1'b0;

ALU_N_reg <= 1'b0;

end

else begin

ALU_Z_reg <= ALU_Z;

ALU_N_reg <= ALU_N;

end

end

// writeback data in EX stage

assign EX_WData = (DCEX_LD) ? RData : ALU_Result[31:0];

//

// EXWB

//

// EXWB registers

always@(posedge CLK or negedge Rstn)

begin

if (!Rstn) begin

EXWB_WB <= 1'b0;

EXWB_WAddr <= 5'h00;

EXWB_WData <= 32'h00000000;

end

else begin

EXWB_WB <= DCEX_WB;

EXWB_WAddr <= DCEX_RegAddr0;

EXWB_WData <= EX_WData;

end

end

//

// WBXX

//

// WBXX registers

always@(posedge CLK or negedge Rstn)

begin

if (!Rstn) begin

WBXX_WB <= 1'b0;

WBXX_WAddr <= 5'h00;

WBXX_WData <= 32'h00000000;

end

else begin

WBXX_WB <= EXWB_WB;

WBXX_WAddr <= EXWB_WAddr;

WBXX_WData <= EXWB_WData;

end

end

endmodule下载本文

显示全文
专题