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