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

📄 datapath.v

📁 使用verilog作为CPU设计语言实现单数据通路五级流水线的CPU。具有32个通用寄存器、一个程序计数器PC、一个标志寄存器FLAG
💻 V
字号:

/*`include "reg_pile.v"*/
/*`include "alu.v"*/
//`include "mem_data32.v"
//'include "instruction_32.v"
//`include "control.v"
/*`include "func_lib.v"*/
//`include "func_lib.v"
module datapath(clock,
				reset,clk_mem,x3_out,z4_out,z5_out,ir2_out,z4_post_sel,fpu_out,y3_out,ir3_out,
       			r0,r1,r2,r3,r20,r21,r22,r23);		//该行新加

/*测试输出的值*/
/*其中ir1 指 从指令memory读出的值,
ir2 指令ir 读出的值*/

output [31:0]r0,ir2_out,z4_out,z5_out,x3_out,y3_out,r1,ir3_out,r2,r3,r20,r21,r22,r23;
output z4_post_sel;
assign z4_post_sel=ir3_op[5]&&ir3_op[4]&&~ir3_op[3]&&ir3_op[2]&&~ir3_op[1];
output [31:0]fpu_out;

input clock,reset,clk_mem;

wire [1:0]fpu_op;
wire exception;

assign fpu_op[1]=ir3_op[0];
assign fpu_op[0]=ir3_op[1];

wire [3:0]alu_op;
wire ov_out,cf_out,zero_out,signal_out;					/*标志位寄存器的输出*/
wire ov,cf,zero,signal;													/*alu 输出标志位*/
wire ov2branch,zero2branch,signal2branch;				/*用于决定分不分支待定,bran_a31,bran_b31;*/
wire [5:0]ir2_op;
wire [5:0]ir3_op;
wire [5:0]ir4_op;
wire [5:0]ir5_op;
wire mp0sel;
wire mp1sel;
wire [1:0]mp2sel;
wire [1:0]mp4sel;
wire mp3sel;		  //对应mp3_pre_sel
wire [1:0]mp3_2sel;  //对应mp3sel
wire [31:0] 
mp1_out,mp2_out,mp3_1_out,mp3_2_out,mp4_out;
wire [31:0]z4_out;
wire [31:0]alu_out,dx,dy,ir1_out,ir2_out,ir3_out,ir4_out,ir5_out;
wire [31:0]
lh,lo,im1,im2,lh3_out,lo3_out,lh4_out,lo4_out,md3_out,md4_out;
wire x_highbit,y_highbit;//存储寄存器的值
wire [31:0]address;
wire [7:0]data_in,data_out;
wire     regfile_en,
		 x3_en,y3_en,z4_en,
		 z5_en,ov_en,cf_en,
		 signal_en,zero_en,
		 ir2_en,ir3_en,ir4_en,ir5_en,
		 lh3_en,lo3_en,lh4_en,lo4_en,md3_en,md4_en,
         branch_en,pc_en; 
wire [31:0]x3_out,y3_out,pc_out;

wire [4:0] ir2_x,ir2_y,ir2_z,
		   ir3_z,ir4_z,ir5_z;					/*ry,rz;*/
																		 //wire cond;equal to mp0sel										       //
wire rw;														//
wire [31:0]memdataout_buffer,memdata_in;	/*输出有必要三态门么*/


/*新加*/
wire [31:0]stack_out,z4_in,md3_in,mp3_out,mp3_post_out,z4_in_pre;
wire [1:0]md3_sel,stack_sel;
wire mp4_post_sel,z4_sel;
assign stack_en =1;

reg [31:0]memdata_out;
reg[31:0] counter;


//assign pc_en=1;
assign lh3_en=1;
assign lo3_en=1;
assign lh4_en=1;
assign lo4_en=1;
assign md3_en=1;
assign md4_en=1;
//assign ir3_en=1;
assign ir4_en=1;
assign ir5_en=1;
assign z5_en=1;
assign ov_en=(ir3_op[5]==0&&ir3_op[3]==0&&ir3_op[2]==0&&ir3_op[1]==0);
assign cf_en=(ir3_op[5]==0&&ir3_op[3]==0&&ir3_op[2]==0&&ir3_op[1]==0);
assign zero_en=(ir3_op[5]==0); 
assign signal_en=(ir3_op[5]==0);
assign branch_en=((ir3_op[5]==0&&ir3_op[3]==0&&ir3_op[2]==0&&ir3_op[1]==0&&ir3_op[0]==1)||(ir3_op==6'b101010));
//只有加法和减法能影响进位和溢出标志位
//凡是运算指令都能影响零标志位和符号标志位
//只有减法和条件转移指令能影响分支判断标志位

assign ir2_op[5:0]=ir2_out[31:26];/**/   
assign ir3_op[5:0]=ir3_out[31:26];
assign ir4_op[5:0]=ir4_out[31:26];
assign ir5_op[5:0]=ir5_out[31:26];

assign ir3_z[4:0]=ir3_out[25:21];/**/
assign ir4_z[4:0]=ir4_out[25:21];
assign ir5_z[4:0]=ir5_out[25:21];	/**/

assign ir2_x[4:0]=ir2_out[20:16];
assign ir2_y[4:0]=ir2_out[15:11];
assign ir2_z[4:0]=ir2_out[25:21];		

assign lh  [31:16]=ir2_out[15:0];
assign lh   [15:0] =16'b0;
assign lo   [31:16]=16'b0;
assign lo   [15:0] =ir2_out[15:0];

assign im2  [31:25]={7{ir2_out[25]}};
assign im2  [24:0] =ir2_out[24:0];	/*pc+1 指令memory 数据宽度定为32*/

assign im1  [31:15]={17{ir2_out[15]}};
assign im1  [14:0] =ir2_out[14:0];       /*16????????????*/
assign address=z4_out+counter;

d_flp  regov(ov_out,ov,clock,ov_en,reset);
d_flp  regcf(cf_out,cf,clock,cf_en,reset);
d_flp  regzero(zero_out,zero,clock,zero_en,reset);
d_flp  regsignal(signal_out,signal,clock,signal_en,reset);


Reg    ir3(ir3_out,ir2_out,clock,ir3_en,reset);//ir2_out from instruction memory ir2_en
Reg    ir4(ir4_out,ir3_out,clock,ir4_en,reset);
Reg    ir5(ir5_out,ir4_out,clock,ir5_en,reset);

Reg    lh3(lh3_out,lh,clock,lh3_en,reset);
Reg    lh4(lh4_out,lh3_out,clock,lh4_en,reset);

Reg    lo3(lo3_out,lo,clock,lo3_en,reset);
Reg    lo4(lo4_out,lo3_out,clock,lo4_en,reset);


Reg    md3(md3_out,md3_in,clock,md3_en,reset);//新改
Reg    md4(md4_out,md3_out,clock,md4_en,reset);

Reg 	x3(x3_out,mp2_out,clock,x3_en,reset);					
Reg 	y3(y3_out,mp3_2_out,clock,y3_en,reset);				
Reg 	z4(z4_out,z4_in,clock,z4_en,reset);//新改
Reg 	z5(z5_out,mp4_out,clock,z5_en,reset);

/*-------------------------------------------------------------------------------*/
mux5x2_1  mp1(mp1_out,ir2_y,ir2_z,mp1sel);																//mp1_out 五位复选
mux32x4_1 mp2(mp2_out,dx,alu_out,z4_out,stack_out,mp2sel[1],mp2sel[0]);					//第一级复选 01 alu_out 00 dx 10 z4_out//新增一个stackout是11
mux32x2_1 mp3(mp3_1_out,dy,im1,mp3sel);					//mp3_1_out, 0 dy 1 im1
mux32x4_1 mp3_2(mp3_2_out,mp3_1_out,alu_out,z4_out,lo,mp3_2sel[1],mp3_2sel[0]);//im1,dy,lo,alu_out
				//mp3_2sel  00 mp3_1_out   01 alu_out  10 z4_out 11 lo

always@(posedge clk_mem)
begin
   if(counter==3)
      counter=0;
   else counter=counter+1;
end			
assign data_in[7:0]=({8{counter==0}}&memdata_in[7:0])|({8{counter==1}}&memdata_in[15:8])|({8{counter==2}}&memdata_in[23:16])|({8{counter==3}}&memdata_in[31:24]);
d_8_1  data_memory(address[7:0],~clk_mem,data_in,rw,data_out);
always@(negedge clk_mem)
begin
   if(counter==2)
 memdata_out[7:0]=data_out[7:0];
 else if(counter==3)
 memdata_out[15:8]=data_out[7:0];
else if(counter==0)
 memdata_out[23:16]=data_out[7:0];
else if(counter==1)
  memdata_out[31:24]=data_out[7:0];
end
				
mux32x4_1 mp4(mp4_out,memdataout_buffer,lh4_out,lo4_out,z4_out,
							mp4sel[1],mp4sel[0]);		              		//11->memdataout_buffer
/*新加起*/
mux32x2_1 mp3_post(mp3_post_out,mp3_out,4,mp3_post_sel);			//push时为1,选出数字4而不是mp3_out	
mux32x2_1 z4_select(z4_in_pre,alu_out,stack_out,z4_sel);
mux32x2_1 z4_post_select(z4_in,z4_in_pre,fpu_out,z4_post_sel);					//0选alu输出结果,1选pop,选直接的stack值的输出。
mux32x4_1 md3_select(md3_in,dy,alu_out,z4_out,1,md3_sel[1],md3_sel[0]);		//00选dy 01-aluout 10- z4out,11-无实际意义
stack st(stack_out,z5_out,stack_sel,clk,stack_en,reset);
//module stack (stack_out,z5_out,stack_sel,clk,stack_en,clear);					
/*新加止*/
			//

alu a(x3_out,y3_out,alu_op,alu_out,ov,cf,zero,signal);
fpu_arch(fpu_op,x3_out,y3_out,fpu_out,exception);

pc  b(im2,reset,pc_en,clock,mp0sel,pc_out);
/*module pc(Im,clear_0,PC_Regin,CLK,MP0,OUT);*/

/*---------------------------------------------------------------------------------*/
regfile r(r3,r2,r1,r0,dx,dy,ir2_x,ir2_y,ir5_z,z5_out,regfile_en,reset,clock);//
//module regfile(Q3,Q2,Q1,Q0,Dx,Dy,Rx,Ry,Rz,Dz,IN,clear_0,clk);
//branch_en 表示flag 是否应保留,在我的数据通路中实现

SignalReg filterflag
(ov2branch,zero2branch,signal2branch,x_highbit,y_highbit,
 ov,zero,signal,x3_out[31],y3_out[31],					//,bran_a31,bran_b31,,x3_out[31],y3_out[31],
 clock,branch_en,reset);									//x3_out[31],y3_out[31]??????????
																			
condcontrol con(mp0sel,ir2_op,ir3_op,ov,signal,zero,x3_out[31],y3_out[31],
ov2branch,zero2branch,signal2branch,x_highbit,y_highbit);  // 严治的分支信号 输出mp0sel

/*module condcontrol(mp0sel,ir2_op,ir3_op,ov,signal,zero,x3_out31,y3_out31,
ov2branch,zero2branch,signal2branch,a312branch,b312branch);*/									
//这一块有问题																								//branch logic  需要这么多输入决定么
	
//昊天的控制逻辑	
/*原接口,下为新接口	
control ctrl(ir2_op,ir3_op,ir4_op,ir5_op,ir3_z,ir4_z,
ir2_x,ir2_y,pc_en,ir2_en,mp1sel,mp2sel,mp3sel,mp3_2sel,alu_op,
ir3_en,x3_en,y3_en,rw,z4_en,mp4sel,regfile_en);
*/

control ctrl(ir2_op,ir3_op,ir4_op,ir5_op,ir3_z,ir4_z,
ir2_x,ir2_y,pc_en,ir2_en,mp1sel,mp2sel,mp3sel,mp3_2sel,alu_op,
ir3_en,x3_en,y3_en,rw,z4_en,mp4sel,regfile_en,
ir2_z,mp3_post_sel,z4_sel,md3_sel,stack_sel,clock);

/*---------------------------------------------------------------------------------*/
bufif0 buf1[31:0](memdataout_buffer,memdata_out,rw); //rw 0低电平 读出
bufif1 buf2[31:0](memdata_in,md4_out,rw);	      		//rw   1电平   读入
/*d_32  data_memory(z4_out[7:0],clock,memdata_in,rw,memdata_out);//z4_out 决定写入的地址*/
instruction_32_1 instruction_memory(pc_out[7:0],clock,32'b0,0,ir2_out);			//
endmodule

⌨️ 快捷键说明

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