中南大学EDA课设基于verilog 的RISC CPU设计源码

更新时间:2023-07-02 01:48:45 阅读: 评论:0

module RISC16(CLK, Rstn, InstAddr, Inst, DW, DAddr, WData, RData);
input    CLK, Rstn;
output [31:0] InstAddr, DAddr;
input  [15:0] Inst;
output  DW;
output [31:0] WData;
input  [31:0] RData;
// IA stage
reg [31:0] PC_reg;            //PC register
wire [31:0] PC_add2, PC_addofft, PC;      //new data for PC
wire [1:0]  PC_Sel;            //lect signal for PC
reg    PC_W;              //write signal for PC register
// DC stage
reg [15:0] IFDC_reg;            //pipeline register for IFDC
reg    IFDC_W;            //write signal for IFDC register
wire    IFDC_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
reg    DC_WB, DC_DW, DC_LD;        //writeback,store,load sigal from decoder
reg [3:0]  DC_BJ;            //branch condition from decoder
// EX stage
reg    DCEX_Flush;            //clear signal for DCEX register
reg [3:0]  DCEX_ALU_OP;          //ALU operation code in DCEX register
reg    DCEX_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
reg    ALU_Z, ALU_N;          // flag Z, N from ALU
reg    ALU_Z_reg, ALU_N_reg;        // flag registers for Z and N
wire [31:0]  EX_WData;            // witeback data in EX stage
// WB stage
reg    EXWB_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 lect siganls
// XX stage
reg    WBXX_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_addofft = 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_addofft : {21'h000000,IFDC_reg[9:0],1'b0};  // normal ca; branch; jump
//
// IF stage
//
// PC register
always@(podge CLK or negedge Rstn)
begin
if (!Rstn)
PC_reg <= 32'h00000000;
el if (PC_W)
PC_reg <= PC;
end
// instruction address for InstRAM
assign InstAddr = PC_reg;
//
// DC stage
//
// IFDC
register
always@(podge CLK or negedge Rstn)
begin
if (!Rstn)
IFDC_reg <= 16'h0000;
el if (IFDC_Flush)
IFDC_reg <= 16'h0000;
el if (IFDC_W)
IFDC_reg <= Inst;
end
// RegFile
always@(podge 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
2016年考研国家线ca(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
//**********************************************************************
/
/    Plea 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
qinhuangdao
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
memorial6'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
dumboDC_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
limuDC_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
endapfs
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
endca
end
// Branch
// PC lect signal decided by branch condition(DC_BJ) and flag registers
//  01: Branch
//  10: JUMP
/
/  00: no branch and no JUMP;
//**********************************************************************
//    Plea 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@(podge 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
el 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
el 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
//**********************************************************************
//    Plea finish the following RTL code!
//********************************************************************** //judge adress
// bypass lect 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 lect 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 lect 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 lect 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
ca(DCEX_ALU_OP)
4'b0000: begin  //ADD
ALU_Result = ALU_OP0 + ALU_OP1;
if (ALU_Result == 0)
ALU_Z = 1'b1;
el
ALU_Z = 1'b0;
if (ALU_Result[32:31] == 2'b11)
ALU_N = 1'b1;
el
ALU_N = 1'b0;
end
//**********************************************************************
//    Plea finish the following RTL code!
//**********************************************************************
4'b0001
:
begin  //SUB
ALU_Result = ALU_OP0 - ALU_OP1;
if (ALU_Result == 0)
ALU_Z = 1'b1;
el
ALU_Z = 1'b0;
if (ALU_Result[32:31] == 2'b11)
ALU_N = 1'b1;
el
ALU_N = 1'b0;
end
4'b0010: begin  //AND
ALU_Result = ALU_OP0&ALU_OP1;
if (ALU_Result == 0)
ALU_Z = 1'b1;
el
ALU_Z = 1'b0;
if (ALU_Result[32:31] == 2'b11)
ALU_N = 1'b1;
el
ALU_N = 1'b0;
end
4'b0011: begin  //OR
ALU_Result = ALU_OP0|ALU_OP1;
if (ALU_Result == 0)
ALU_Z = 1'b1;
el
ALU_Z = 1'b0;
if (ALU_Result[32:31] == 2'b11)
ALU_N = 1'b1;
el
ALU_N = 1'b0;
end
4'b0100: begin  //XOR
ALU_Result = ALU_OP0 ^ ALU_OP1;
if (ALU_Result == 0)
ALU_Z = 1'b1;
el
ALU_Z = 1'b0;
if (ALU_Result[32:31] == 2'b11)
ALU_N = 1'b1;
el
ALU_N = 1'b0;
end
4'b0101: begin  //LSL
ALU_Result = ALU_OP0 << DCEX_imm;
if (ALU_Result == 0)
ALU_Z = 1'b1;
el
ALU_Z = 1'b0;
if (ALU_Result[32:31] == 2'b11)
ALU_N = 1'b1;
el
ALU_N = 1'b0;
end
4'b0110: begin  //LSR
ALU_Result = ALU_OP0 >> DCEX_imm;
if (ALU_Result == 0)
ALU_Z = 1'b1;
el
ALU_Z = 1'b0;
if (ALU_Result[32:31] == 2'b11)
ALU_N = 1'b1;
el
ALU_N = 1'b0;
end
4'b0111: begin  //ASR
ALU_Result = ALU_OP0 >>> DCEX_imm;
if (ALU_Result == 0)
ALU_Z = 1'b1;
el
ALU_Z = 1'b0;
if (ALU_Result[32:31] == 2'b11)
ALU_N = 1'b1;
el
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
endca 
end
/
/ flag registers
always@(podge CLK or negedge Rstn)
begin
if (!Rstn) begin
ALU_Z_reg <= 1'b0;
ALU_N_reg <= 1'b0;
end
el 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@(podge CLK or negedge Rstn)
begin
if (!Rstn) begin
EXWB_WB  <= 1'b0;
EXWB_WAddr  <= 5'h00;
美国州名EXWB_WData  <= 32'h00000000;
end
el begin
EXWB_WB  <= DCEX_WB;
EXWB_WAddr  <= DCEX_RegAddr0;
EXWB_WData  <= EX_WData;
end
end
//
// WBXX
/
/
// WBXX registers
always@(podge CLK or negedge Rstn)
begin
if (!Rstn) begin
kickoff
WBXX_WB  <= 1'b0;
WBXX_WAddr  <= 5'h00;
WBXX_WData  <= 32'h00000000;
end
el begin
WBXX_WB  <= EXWB_WB;
WBXX_WAddr  <= EXWB_WAddr;
WBXX_WData  <= EXWB_WData;
end
end
endmodule

本文发布于:2023-07-02 01:48:45,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/164288.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:枪手   考研   枪击案   国家   加州
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图