基于verilog的处理器设计之寄存器堆

该寄存器堆是CPU中多个寄存器组成的阵列,由32个32位的寄存器构成,两个读数据口(Ra->BusA Rb->BusB),一个写数据口(Rw ->BusW),写数据受使能信号Wen控制,在时钟的下降沿有效
第一种实现方法,代码如下

module D_FF(
     input clk,
	 input [4:0]Ra,
	 input [4:0]Rb, 
	 input [4:0]Rw,
	 input Wen,
	 output [31:0]BusA,
	 output [31:0]BusB,
	 input [31:0]BusW
 );
 
 reg [31:0]DataReg[31:0];

 always@(negedge clk)
  begin 
   if(Wen & Rw!=5'd0)
    DataReg[Rw] <= BusW;
  end  
 
 assign BusA = (Ra==5'd0)?32'd0:DataReg[Ra];
 assign BusB = (Ra==5'd0)?32'd0:DataReg[Rb];
 
endmodule

第二种实现方法,代码如下

module D_FF(
                 input          clk,
				 input          rst_n,
				 input  [4:0]  	Ra,
				 input  [4:0]   Rb,
				 input  [4:0]   Rw,
				 input          Wen,
				 output [31:0]  BusA,
				 output [31:0]  BusB,
				 input  [31:0]  BusW);
				 
				 reg    [31:0]DataReg[31:0];
				 wire   DataWen[31:0];
				 
		assign   DataWen[0] = 1'b0;
		
		genvar   i;
		generate for(i=1;i<32;i=i+1)
		begin
		     assign DataWen[i] = (Wen & (Rw == 1));
		end
		endgenerate
		
		genvar   j;
		generate for(j=0;j<32;j=j+1)
		begin
		     always @(posedge clk or negedge rst_n)begin
			     if(~rst_n)
				    DataReg[j] <= 31'd0;
				 else if(DataWen[j])
				    DataReg[j] <= BusW;
			 end
		end
		endgenerate
		
		assign BusA = DataReg[Ra];
		assign BusB = DataReg[Rb];


endmodule

第三种实现方法,代码如下

module D_FF(
              input         clk,
				 input        rst_n,
				 input  [4:0]  	Ra,
				 input  [4:0]   Rb,
				 input  [4:0]   Rw,
				 input          Wen,
				 output [31:0]  BusA,
				 output [31:0]  BusB,
				 input  [31:0]  BusW);
				 
				 reg    [31:0]DataReg[31:0];
				 reg   DataWen[31:0];
				 
		integer   i;
		always@(negedge clk)
		begin
		for(i = 1;i<32;i = i + 1)begin
		 DataWen[i] <= (Wen & (Rw == 1));
		 end
      end
		
		integer   j;		
      always @(negedge clk or negedge rst_n)
		if(!rst_n)		   
			for(j=0;j<32;j = j + 1)begin
			  DataWen[0] <= 1'b0;
			  DataReg[j] <= 31'd0;
			end
		else begin
			for(j = 1; j < 32;j = j + 1)begin
			 if(DataWen[j])
				DataReg[j] <= BusW;
			end
		end	 

		assign BusA = DataReg[Ra];
		assign BusB = DataReg[Rb];

endmodule

电路仿真代码及相应仿真结果

`timescale 1ns/1ns 
`define clk_period  20
module D_FF_tb;

reg  clk;
reg  rst_n;
reg  [4:0] Ra;
reg  [4:0] Rb;
reg  [4:0] Rw;
reg        Wen;
reg  [31:0] BusW;
wire [31:0] BusA;
wire [31:0] BusB;


D_FF D_FF(
	 .clk(clk),
	 .rst_n(rst_n),
	 .Ra(Ra),
	 .Rb(Rb),
	 .Rw(Rw),
	 .Wen(Wen),
	 .BusW(BusW),
	 .BusA(BusA),
	 .BusB(BusB)
);
integer i,j,k;

initial clk = 1'b0;
always #(`clk_period/2)clk = ~clk;
	
initial begin
    rst_n = 1'b0;
	 Ra = 5'b0;
	 Rb = 5'b0;
	 Rw = 5'b0;
	 Wen = 1'b0;
	 #5;
	 rst_n = 1'b1;
    Wen = 1'b1;
	 for (j = 1 ; j < 32; j = j + 1) begin
		        Rw = j;
				BusW = j; 
				#50;

	 end
	Wen = 1'b0;
	
	#5;
	for (i = 1 ; i < 32; i = i + 1) begin
		      Ra = i;
			  #5;
			  
	end
	
	#5;
	for (k = 1 ; k < 32; k = k + 1) begin
		      Rb = k;
			  #5;
			  
	end
	
	#5;
	$stop;
	
end

endmodule

先依次向编号为1~31的寄存器中依次写入1 ~ 31
基于verilog的处理器设计之寄存器堆_第1张图片
给Ra信号依次赋值1 ~ 31,观察BusA端口的值依次是1~31
基于verilog的处理器设计之寄存器堆_第2张图片
给Rb信号依次赋值1 ~ 31,观察BusB端口的值依次是1~31
基于verilog的处理器设计之寄存器堆_第3张图片

你可能感兴趣的:(基于verilog的处理器设计之寄存器堆)