⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 id.v

📁 用VHDL设计具有简单MIPS功能的源码
💻 V
字号:
//******************************************************************************
//
// id.v
//
// the implementation for ID unit .
//
// verilog written by Pengcheng Li, HNU 2006/07/15
//
//******************************************************************************

module ID(//input
			clk,rst,D_IR,D_NPC,
			E_WriteReg,
			E_RD,
			E_Result,
			M_WriteReg,
			M_RD,
			M_Result,
			W_WriteReg,W_RegWriteAddr,W_RegWriteData,
			//output
			WritePC,Branch,WriteIR,ReadMem,WriteReg,MemToReg,WriteMem,
			ALUcontrol,RegDes,ALUSrcB,FWDB,FWDA,
			BranchAddr,
			ea,eb,ei,ert,erd);
input clk,rst;			
input [31:0] D_IR,D_NPC;
input E_WriteReg,M_WriteReg,W_WriteReg;
input [4:0] E_RD,M_RD,W_RegWriteAddr;
input [31:0] E_Result,M_Result,W_RegWriteData;
output 	WritePC,Branch,WriteIR,ReadMem,WriteReg,MemToReg,WriteMem,RegDes,ALUSrcB;
output [3:0] ALUcontrol;
output [1:0] FWDA,FWDB;
output [31:0] BranchAddr;
output [31:0] ea,eb,ei;
output [4:0] ert,erd;
wire [31:0] RegA,RegB;

//******************************************************************************
// instruction field
//******************************************************************************

	`define	opfield		31:26	// 6-bit operation code
	`define	rs			25:21	// 5-bit source register specifier
	`define	rt			20:16	// 5-bit source/dest register specifier 
	`define	immediate	15:0	// 16-bit immediate, branch or address disp
	`define	rd			15:11	// 5-bit destination register specifier
	`define	funct	5:0		// 6-bit function field
	
	wire [5:0]		op;
	wire [4:0]		RtAddr, RdAddr, RsAddr;
	wire [5:0]		func;
	wire [15:0]		immediate;
   
	assign op			= D_IR[`opfield];
	assign RtAddr		= D_IR[`rt];
	assign RdAddr		= D_IR[`rd];
	assign RsAddr		= D_IR[`rs];
	assign func			= D_IR[`funct];
	assign immediate	= D_IR[`immediate];
	
	assign ert = RtAddr;
	assign erd = RdAddr;
	assign ei = {{16{immediate[15]}},immediate[15:0]};// the sign extent of immidiate number 
	
//******************************************************************************
// branch&jump instructions decode
//******************************************************************************

	`define opcode_beq	6'b000100
	`define opcode_bne	6'b000101
	`define opcode_j	6'b000010

	wire isBEQ, isBNE, isJ;
	
	assign isBEQ     = (op == `opcode_beq);
	assign isBNE     = (op == `opcode_bne);
	assign isJ       = (op == `opcode_j);
	
//******************************************************************************
// ALU instructions decode / control signal for ALU datapath
//******************************************************************************
	//operation code and function code
	//R-Type
	`define opcode_rtype	6'b000000
	`define funcode_add	6'b100000
	`define funcode_sub	6'b100010
	`define funcode_and	6'b100100
	`define funcode_or	6'b100101
	`define funcode_slt	6'b101010
	//I-Type
	`define opcode_lw	6'b100011
	`define opcode_sw	6'b101011
	`define opcode_addi	6'b001000
	`define opcode_andi	6'b001100
	`define opcode_ori	6'b001101

	`define aluop_add	4'b0001
	`define aluop_sub	4'b0010
	`define aluop_and	4'b0011
	`define aluop_or	4'b0100
	`define aluop_slt	4'b0101
	`define aluop_lw	4'b0110
	`define aluop_sw	4'b0111
	`define aluop_addi	4'b1000
	`define aluop_andi	4'b1001
	`define aluop_ori	4'b1010
	wire isADD,isSUB,isAND,isOR,isSLT,isLW,isSW,isADDI,isANDI,isORI;
	assign isADD = (op == `opcode_rtype) && (func == `funcode_add);
	assign isSUB = (op == `opcode_rtype) && (func == `funcode_sub);
	assign isAND = (op == `opcode_rtype) && (func == `funcode_and);
	assign isOR  = (op == `opcode_rtype) && (func == `funcode_or);
	assign isSLT = (op == `opcode_rtype) && (func == `funcode_slt);
	assign isLW = (op == `opcode_lw);
	assign isSW = (op == `opcode_sw);
	assign isADDI = (op == `opcode_addi);
	assign isANDI = (op == `opcode_andi);
	assign isORI = (op == `opcode_ori);
	
	assign ALUcontrol[0] = isADD | isAND | isSLT | isSW | isANDI;
	assign ALUcontrol[1] = isSUB | isAND | isLW | isSW | isORI;
	assign ALUcontrol[2] = isOR | isSLT | isLW | isSW;
	assign ALUcontrol[3] = isADDI | isANDI | isORI;
	
	assign WritePC = 1;
	assign WriteIR = 1;
	assign ReadMem = 0;
	assign WriteReg = isADD | isSUB | isAND | isOR | isSLT | isLW | isADDI | isANDI | isORI;
	assign MemToReg = isLW;		// use memory data for writing to register
	assign WriteMem = isSW;		// write to memory
	assign RegDes = (op == `opcode_rtype);
	assign ALUSrcB = ~(isADDI|isANDI|isORI|isLW|isSW);
	//Register file
	RegFile RegFile(.RsData(RegA), .RtData(RegB), .clk(clk), .RegWriteData(W_RegWriteData), .RegWriteAddr(W_RegWriteAddr), .RegWriteEn(W_WriteReg), .RsAddr(RsAddr), .RtAddr(RtAddr));
	
	//Internal data forward
	assign FWDA[0] = rst?0:((E_WriteReg && (E_RD != 0) && (E_RD ==RsAddr)) || (W_WriteReg && (W_RegWriteAddr != 0) && (E_RD !=RsAddr) && (M_RD !=RsAddr) && (W_RegWriteAddr == RsAddr)));
	assign FWDA[1] = rst?0:((M_WriteReg && (M_RD!=0) && (E_RD !=RsAddr) && (M_RD==RsAddr)) || (W_WriteReg && (W_RegWriteAddr != 0) && (E_RD !=RsAddr) && (M_RD !=RsAddr) && (W_RegWriteAddr == RsAddr)));
	assign ea = FWDA[0]?(FWDA[1]?W_RegWriteData:E_Result):(FWDA[1]?M_Result:RegA);
	
	assign FWDB[0] = rst?0:(E_WriteReg && (E_RD != 0) && (E_RD ==RtAddr)) || (W_WriteReg && (W_RegWriteAddr != 0) && (E_RD !=RtAddr) && (M_RD !=RtAddr) && (W_RegWriteAddr == RtAddr));
	assign FWDB[1] = rst?0:(M_WriteReg && (M_RD!=0) && (E_RD !=RtAddr) && (M_RD==RtAddr)) || (W_WriteReg && (W_RegWriteAddr != 0) && (E_RD !=RtAddr) && (M_RD !=RtAddr) && (W_RegWriteAddr == RtAddr));
	assign eb = FWDB[0]?(FWDB[1]?W_RegWriteData:E_Result):(FWDB[1]?M_Result:RegB);
	
	// get the Branch signal and Branch Address
	assign ALUZero = (ea == eb);
	assign Branch = rst?0:(isBEQ & ALUZero) |(isBNE & ~ALUZero)|isJ;
	assign BranchAddr = Branch?(isJ?{D_NPC[31:28],D_IR[25:0],2'b00}:D_NPC + {{14{D_IR[15]}} , D_IR[15:0],2'b00}):32'b0;

endmodule


			

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -