ISE环境,verilog编写:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 15:04:43 07/02/2015
// Design Name:
// Module Name: PC
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module PC(CLK_OUT1,Jump,Branch2,zero_flow,ImemRdAddr,Ext_Im,Ins);
input CLK_OUT1;
input Jump,Branch2,zero_flow;
input [31:0]Ext_Im;
input [31:0]Ins;
output [31:0] ImemRdAddr;
reg [31:0] next_pc;
reg [31:0] ImemRdAddr;
initial
begin
ImemRdAddr=-4;
end
always@(posedge CLK_OUT1)
begin
next_pc=ImemRdAddr+4;
if(Jump) //若是jump指令,取当前PC基址+偏移量
next_pc={next_pc[31:28],(Ins[25:0]<<2)};
else //否则,若是分支指令,段内跳转
if(Branch2&zero_flow)
next_pc=next_pc+(Ext_Im<<2);
ImemRdAddr=next_pc;
end
endmodule`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 09:24:28 07/02/2015
// Design Name:
// Module Name: instr_memory
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module instr_memory(CLK_OUT1,ImemRdAddr,Ins0);
input CLK_OUT1;
input[31:0] ImemRdAddr;
output[31:0] Ins0;
reg[31:0] Ins0;
reg[31:0] InstMem [0:255]; //指令存储器的大小
initial
begin
$readmemh("Instruction.txt",InstMem); //读指令文件
end
always @(ImemRdAddr)
begin
Ins0 <= InstMem[ImemRdAddr/4]; //注意点%4
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 09:17:40 07/05/2015
// Design Name:
// Module Name: IF_ID
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module IF_ID(CLK_OUT1,Ins0,Ins);
input CLK_OUT1;
input [31:0]Ins0;
output[31:0] Ins;
reg[31:0] Ins;
always@(posedge CLK_OUT1)
begin
Ins=Ins0;
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 16:01:04 07/01/2015
// Design Name:
// Module Name: ctrl
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ctrl(CLK_OUT1,rst,Ins,RegDst,Branch,MemRead,MemtoReg,MemWrite,ALUSrc,RegWrite,Jump,ALU_Ctrl);
input CLK_OUT1;
input rst;
input[31:0] Ins;
output Jump; //控制跳转
output Branch; //分支控制
output MemRead; //读数据
output MemtoReg; //读数据到寄存器组
output MemWrite; //写到存储器
output [3:0] ALU_Ctrl; //控制ALU
output ALUSrc; //alu操作数来源
output RegWrite; //写到寄存器组
output RegDst; //
reg[5:0] IR_26_31; //存放指令高六位操作码 针对IR指令
reg[5:0] funct; //存放指令高六位操作码 针对IR指令
reg RegDst=1; // 有效时 写寄存器的目标寄存器号来自rd字段(位15:11)
//无效时 写寄存器的目标寄存器号来自rt字段(位20:16)
reg Branch=0; //是否分支
reg MemRead=0; //是否d在存储器读
reg MemtoReg=0; //
reg [3:0] ALU_Ctrl=4'b0000; //
reg MemWrite=0;
reg ALUSrc=0; //有效时,第二个ALU操作数为指令低16位的符号扩展
//无效时 第二个ALU操作数来自寄存器堆的第二个输出(读数据2)
reg RegWrite=0;
reg Jump=0;
parameter // 常量的设定:对应IR的高六位opcode,判断指令类型
R_type=6'b000000,
LW_type=6'b100011,
SW_type=6'b101011,
BEQ_type=6'b000100,
BGEZ=6'b000001,
BNE=6'b000101,
ADDI=6'b001000,
ANDI=6'b001100,
LUI=6'b001111, //立即数加载至高位
ORI=6'b001101,
XORI=6'b001110,
JAL=6'b000011, //跳转并连接:跳转后,GPR[31] 《-PC + 4,是函数指令,PC 转向被调用函数
JUMP=6'b000010;
//funct编码
parameter
myadd=6'b100000,
mysub=6'b100010,
myand=6'b100100,
myor=6'b100101,
mylessthan=6'b101010,
myxor=6'b100110,
mynor=6'b100111,
mysllv=6'b000100,
mysrlv=6'b000110;
always@(Ins)
begin
IR_26_31=Ins[31:26];
funct=Ins[5:0];
case(IR_26_31)
R_type : begin //寄存器-寄存器指令
RegDst<=1'b1; //目的操作数写到A3
ALUSrc<=1'b0;
MemtoReg<=1'b0; //不需要从存储器读数据到寄存器
RegWrite<=1'b1; //需要往寄存器组写结果 (所有的R指令都写)
MemRead<=1'b0; //不需要读存储器
MemWrite<=1'b0; // xie
Branch<=1'b0;
Jump<=0;
if(funct==myadd)
ALU_Ctrl<=4'b0010;
else if(funct==mysub)
ALU_Ctrl<=4'b0110;
else if(funct==myand)
ALU_Ctrl<=4'b0000;
else if(funct==myor)
ALU_Ctrl<=4'b0001;
else if(funct==mylessthan)
ALU_Ctrl<=4'b0111;
else if(funct==myxor)
ALU_Ctrl<=4'b1000;
else if(funct==mynor)
ALU_Ctrl<=4'b1001;
else if(funct==mysllv)
ALU_Ctrl<=4'b1010;
else if(funct==mysrlv)
ALU_Ctrl<=4'b1011;
end
LW_type: begin
RegDst<=1'b0;
ALUSrc<=1'b1;
MemtoReg<=1'b1;
RegWrite<=1'b1; //往寄存器写结果
MemRead<=1'b1;
MemWrite<=1'b0;
Branch<=1'b0;
Jump<=0;
ALU_Ctrl<=4'b0010;
end
SW_type:begin
RegDst<=1'b1;
ALUSrc<=1'b1;
MemtoReg<=1'bx;
RegWrite<=1'b0;
MemRead<=1'b0;
MemWrite<=1'b1;
Branch<=1'b0;
Jump<=0;
ALU_Ctrl<=4'b0010;
end
BEQ_type:begin
RegDst<=1'bx;
ALUSrc<=1'b0;
MemtoReg<=1'bx;
RegWrite<=1'b0;
MemRead<=1'b0;
MemWrite<=1'b0;
Branch<=1'b1;
Jump<=0;
ALU_Ctrl<=4'b0110;
end
BNE:begin
RegDst<=1'bx;
ALUSrc<=1'b0;
MemtoReg<=1'bx;
RegWrite<=1'b0;
MemRead<=1'b0;
MemWrite<=1'b0;
Branch<=1'b1;
Jump<=0;
ALU_Ctrl<=4'b1110;
end
BGEZ:begin
RegDst<=1'bx;
ALUSrc<=1'b0;
MemtoReg<=1'bx;
RegWrite<=1'b0;
MemRead<=1'b0;
MemWrite<=1'b0;
Branch<=1'b1;
Jump<=0;
ALU_Ctrl<=4'b1101;
end
JUMP: begin
RegDst<=1'b1;
ALUSrc<=1'b0;
MemtoReg<=1'b0;
RegWrite<=1'b0;
MemRead<=1'b0;
MemWrite<=1'b0;
Branch<=1'b0;
Jump<=1;
end
JAL: begin
RegDst<=1'b1;
ALUSrc<=1'b0;
MemtoReg<=1'b0;
RegWrite<=1'b1;
MemRead<=1'b0;
MemWrite<=1'b0;
Branch<=1'b0;
Jump<=1;
end
ADDI:
begin
RegDst<=1'b0;
ALUSrc<=1'b1;
MemtoReg<=1'b0;
RegWrite<=1'b1;
MemRead<=1'b0;
MemWrite<=1'b0;
Branch<=1'b0;
Jump<=0;
ALU_Ctrl<=4'b0010;
end
ANDI:
begin
RegDst<=1'b0;
ALUSrc<=1'b1;
MemtoReg<=1'b0;
RegWrite<=1'b1;
MemRead<=1'b0;
MemWrite<=1'b0;
Branch<=1'b0;
Jump<=0;
ALU_Ctrl<=4'b0000;
end
LUI:
begin
RegDst<=1'b0;
ALUSrc<=1'b1;
MemtoReg<=1'b0;
RegWrite<=1'b1;
MemRead<=1'b0;
MemWrite<=1'b0;
Branch<=1'b0;
Jump<=0;
ALU_Ctrl<=4'b1100;
end
ORI:
begin
RegDst<=1'b0;
ALUSrc<=1'b1;
MemtoReg<=1'b0;
RegWrite<=1'b1;
MemRead<=1'b0;
MemWrite<=1'b0;
Branch<=1'b0;
Jump<=0;
ALU_Ctrl<=4'b0001;
end
XORI:
begin
RegDst<=1'b0;
ALUSrc<=1'b1;
MemtoReg<=1'b0;
RegWrite<=1'b1;
MemRead<=1'b0;
MemWrite<=1'b0;
Branch<=1'b0;
Jump<=0;
ALU_Ctrl<=4'b1000;
end
default : begin
RegDst<=1'b1;
ALUSrc<=1'b0;
MemtoReg<=1'b0;
RegWrite<=1'b0;
MemRead<=1'b0;
MemWrite<=1'b0;
Branch<=1'b0;
Jump<=0;
end
endcase
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 10:56:58 07/02/2015
// Design Name:
// Module Name: reg_file
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module reg_file(Ins,CLK_OUT1,RegWrite3,RegDst,DatatoReg,RD10,RD20,Ext_Im0,Jump,ImemRdAddr,A30,A33,A10,A20);
input [31:0] Ins;
input CLK_OUT1;
input RegWrite3,RegDst; //控制信号
input [31:0] DatatoReg;
input Jump;
input [31:0]ImemRdAddr;
input [4:0]A33;
output [31:0] RD10,RD20;
output [31:0] Ext_Im0;
output [4:0] A30;
output [4:0]A10;
output [4:0]A20;
reg [4:0] A1,A2,A3,A30,A10,A20;
reg [31:0] RD10,RD20;
reg [31:0] Ext_Im0;
reg [31:0] R_f [31:0];
initial
begin
$readmemh("D_F.txt",R_f); //读文件
end
always@( Ins) //Ins posedge CLK_OUT1 or
begin
A1=Ins[25:21];
A2=Ins[20:16];
if(RegDst) //确定数据来源
A3=Ins[15:11];
else
A3=Ins[20:16];
A30=A3;
Ext_Im0={16'h0000,Ins[15:0]};
A10=A1;
A20=A2;
RD10=R_f[A1];
RD20=R_f[A2];
// if((Jump&RegWrite3)==1)
// R_f[31]=ImemRdAddr+4;
end
always@( RegWrite3 or DatatoReg or A33) //只有数据到来,而且是要写寄存器时情况才会被写入寄存器组 posedge CLK_OUT1 or
begin
if(RegWrite3)
R_f[A33]<=DatatoReg;
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 09:32:15 07/05/2015
// Design Name:
// Module Name: ID_EX
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ID_EX(CLK_OUT1,RD10,RD20,RD1,RD2,Ext_Im,Ext_Im0,
Branch,MemRead,MemtoReg,MemWrite,ALUSrc,RegWrite,Jump,ALU_Ctrl
,Branch1,MemRead1,MemtoReg1,MemWrite1,ALUSrc1,RegWrite1,Jump1,ALU_Ctrl1,
A30,A31,A10,A20,A11,A21
);
input CLK_OUT1;
input [31:0] RD10,RD20;
input [31:0] Ext_Im0;
input Jump; //控制跳转
input Branch; //分支控制
input MemRead; //读数据
input MemtoReg; //读数据到寄存器组
input MemWrite; //写到存储器
input [3:0] ALU_Ctrl; //控制ALU
input ALUSrc; //alu操作数来源
input RegWrite; //写到寄存器组
input [4:0] A30;
input [4:0] A10;
input [4:0] A20;
output [4:0] A11;
output [4:0] A21;
output [4:0] A31;
output [31:0] RD1,RD2;
output [31:0] Ext_Im;
output Jump1; //控制跳转
output Branch1; //分支控制
output MemRead1; //读数据
output MemtoReg1; //读数据到寄存器组
output MemWrite1; //写到存储器
output [3:0] ALU_Ctrl1; //控制ALU
output ALUSrc1; //alu操作数来源
output RegWrite1; //写到寄存器组
reg [4:0]A31;
reg [4:0]A11;
reg [4:0]A21;
reg [31:0] RD1,RD2;
reg [31:0] Ext_Im;
reg Jump1; //控制跳转
reg Branch1; //分支控制
reg MemRead1; //读数据
reg MemtoReg1; //读数据到寄存器组
reg MemWrite1; //写到存储器
reg [3:0] ALU_Ctrl1; //控制ALU
reg ALUSrc1; //alu操作数来源
reg RegWrite1; //写到寄存器组
always@(posedge CLK_OUT1)
begin
A11<=A10;
A21<=A20;
A31<=A30;
RD1<=RD10;
RD2<=RD20;
Ext_Im<=Ext_Im0;
Jump1<=Jump; //控制跳转
Branch1<=Branch; //分支控制
MemRead1<=MemRead; //读数据
MemtoReg1<=MemtoReg; //读数据到寄存器组
MemWrite1<=MemWrite; //写到存储器
ALU_Ctrl1<=ALU_Ctrl; //控制ALU
ALUSrc1<=ALUSrc; //alu操作数来源
RegWrite1<=RegWrite; //写到寄存器组
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 14:58:43 07/02/2015
// Design Name:
// Module Name: ALU_src_opB
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ALU_src_opB(ALUSrc1,RD2,Ext_Im,op_B0);
input ALUSrc1;
input [31:0]RD2;
input [31:0]Ext_Im;
output [31:0]op_B0;
reg [31:0]op_B0;
always@(ALUSrc1 or RD2 or Ext_Im)
begin
if(ALUSrc1)
op_B0=Ext_Im; //立即数
else
op_B0=RD2;
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 20:55:14 07/01/2015
// Design Name:
// Module Name: alu
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module alu(CLK_OUT1,ALU_Ctrl1,RD1,op_B0,ans0,zero_flow0,A11,A21,RegWrite2,A32,ans);
input CLK_OUT1;
input [3:0] ALU_Ctrl1;
input RegWrite2;
input [31:0] ans;
input [31:0] RD1;
input [31:0] op_B0;
input [4:0] A11,A21,A32;
output [31:0] ans0;
output zero_flow0;
reg [31:0] ans0;
reg zero_flow0;
parameter
myLW =4'b0010,
mySW =4'b0010,
myBE=4'b0110,
myADD=4'b0010,
mySUB=4'b0110,
myAND=4'b0000,
myOR =4'b0001,
mySTL=4'b0111,
myXOR=4'b1000,
myNOR=4'b1001,
mySLLV=4'b1010,
mySRLV=4'b1011,
myLUI=4'b1100,
myBGEZ=4'b1101,
myBNE=4'b1110;
reg [31:0] op_A,op_B;
always@( ALU_Ctrl1 or RD1 or op_B0 )//posedge CLK_OUT1 or
begin
op_A=RD1;
op_B=op_B0;
if(RegWrite2==1)
begin
if(A11==A32)
op_A=ans;
if(A21==A32)
op_B=ans;
end
case(ALU_Ctrl1)
myLW: ans0=op_A+op_B;
mySW: ans0=op_A+op_B;
myADD: ans0=op_A+op_B;
myBE: zero_flow0=(op_A==op_B?1'b1:1'b0);
mySUB: ans0=op_A-op_B;
myAND: ans0=op_A&op_B;
myOR: ans0=op_A|op_B;
mySTL: ans0=op_A>op_A;
myLUI: ans0=op_B<<16;
myBGEZ: zero_flow0=(op_A>=0?1:0);
myBNE: zero_flow0=(op_A==op_B?1'b0:1'b1);
endcase
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 09:52:01 07/05/2015
// Design Name:
// Module Name: EX_MEM
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module EX_MEM(CLK_OUT1,Branch1,MemRead1,MemtoReg1,MemWrite1,RegWrite1,Jump1,
Branch2,MemRead2,MemtoReg2,MemWrite2,RegWrite2,Jump2,
RD2,ans0,RD21,ans,zero_flow0,zero_flow,
A31,A32
);
input CLK_OUT1;
input Jump1; //控制跳转
input Branch1; //分支控制
input MemRead1; //读数据
input MemtoReg1; //读数据到寄存器组
input MemWrite1; //写到存储器
input RegWrite1; //写到寄存器组
input [31:0] RD2;
input [31:0]ans0;
input zero_flow0;
input [4:0]A31;
output [4:0]A32;
output [31:0] ans;
output [31:0] RD21;
output zero_flow;
output Jump2; //控制跳转
output Branch2; //分支控制
output MemRead2; //读数据
output MemtoReg2; //读数据到寄存器组
output MemWrite2; //写到存储器
output RegWrite2; //写到寄存器组
reg [4:0]A32;
reg [31:0] RD21;
reg [31:0] ans;
reg zero_flow;
reg Jump2; //控制跳转
reg Branch2; //分支控制
reg MemRead2; //读数据
reg MemtoReg2; //读数据到寄存器组
reg MemWrite2; //写到存储器
reg RegWrite2; //写到寄存器组
always@(posedge CLK_OUT1)
begin
RD21<=RD2;
ans<=ans0;
Jump2<=Jump1; //控制跳转
Branch2<=Branch1; //分支控制
MemRead2<=MemRead1; //读数据
MemtoReg2<=MemtoReg1; //读数据到寄存器组
MemWrite2<=MemWrite1; //写到存储
RegWrite2<=RegWrite1; //写到寄存器组
zero_flow<=zero_flow0;
A32<=A31;
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 09:32:21 07/02/2015
// Design Name:
// Module Name: data_memory
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module data_memory(CLK_OUT1,Data_out0,MemWrite2,MemRead2,RD21,ans);
input CLK_OUT1;
input MemWrite2,MemRead2; //读写控制信号
input [31:0] ans ; //ALU输出
input [31:0] RD21; //数据来源
output [31:0] Data_out0; //数据输出
reg [31:0] Data_out0;
reg [31:0] Dmem [0:255]; //数据内存
reg [31:0] ADDR; //地址
initial
begin
$readmemh("DM.txt",Dmem);//读指令文件
end
always@(posedge CLK_OUT1 ) //or ans or MemRead2 or MemWrite2
begin
if(MemRead2)
Data_out0=Dmem[ans]; //读内存
if(MemWrite2)
Dmem[ans]=RD21; //写内存
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 10:14:12 07/05/2015
// Design Name:
// Module Name: MEM_WB
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module MEM_WB(CLK_OUT1,MemtoReg2,RegWrite2,MemtoReg3,RegWrite3,
Data_out0,ans,Data_out,ans1,
A32,A33
);
input CLK_OUT1;
input MemtoReg2; //读数据到寄存器组
input RegWrite2; //写到寄存器组
input [31:0] Data_out0;
input [31:0] ans;
input [4:0]A32;
output [4:0]A33;
output MemtoReg3; //读数据到寄存器组
output RegWrite3; //写到寄存器组
output [31:0] Data_out;
output [31:0] ans1;
reg [4:0]A33;
reg [31:0] ans1;
reg [31:0] Data_out;
reg MemtoReg3; //读数据到寄存器组
reg RegWrite3; //写到寄存器组
always@(posedge CLK_OUT1)
begin
Data_out<=Data_out0;
ans1<=ans;
MemtoReg3<=MemtoReg2; //读数据到寄存器组
RegWrite3<=RegWrite2; //写到寄存器组
A33<=A32;
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 10:58:20 07/05/2015
// Design Name:
// Module Name: WB
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module WB(CLK_OUT1,MemtoReg3,DatatoReg,
ans1,Data_out
);
input CLK_OUT1;
input MemtoReg3; //读数据到寄存器组
input [31:0] Data_out;
input [31:0] ans1;
output [31:0] DatatoReg;
reg [31:0]DatatoReg; // 二路选择器输出到寄存器组
always@(Data_out or ans1 or MemtoReg3)
begin
if(MemtoReg3)
DatatoReg=Data_out;
else
DatatoReg=ans1;
end
endmodule