计算机组成原理 寄存器堆设计实验(加上与ALU连接)

Posted Ice丨shine

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算机组成原理 寄存器堆设计实验(加上与ALU连接)相关的知识,希望对你有一定的参考价值。

实验内容与原理

设计一个32×32位的寄存器堆(即含有32个寄存器,每个寄存器32位)

在这里插入图片描述

实验实现:
寄存器堆:reg类型信号的数组 reg [31:0] REG_Files[0:31];
读操作:组合逻辑电路 assign R_Data_A = REG_Files[R_Addr_A]; assign R_Data_B = REG_Files[R_Addr_B];
写操作:时序逻辑电路 需要Reset信号:用于初始化寄存器(全部清零) 需要clk信号:用于写入寄存器
代码实现:

module register(
    input [4:0]R_Addr_A,
    input [4:0]R_Addr_B,
    input [4:0]W_Addr,
    input [31:0]W_Data,
    input clk,
    input rst,
    input Write_Reg,
    output [31:0]R_Data_A,
    output [31:0]R_Data_B
    );
	 reg [31:0] REG_Files[0:31];
	 integer i;
	 always @(posedge clk or posedge rst)
	begin
		if(rst) //高电平有效,=1则初始化
		begin
			for(i=0;i<32;i=i+1) REG_Files[i]<=0;
		end
		else
			begin
				if(Write_Reg) 
					REG_Files[W_Addr]<=W_Data;
			end
	end


	 
	 //读数据
	 assign R_Data_A = REG_Files[R_Addr_A];
	 assign R_Data_B = REG_Files[R_Addr_B];



endmodule

测试代码:

module register_test;

	// Inputs
	reg [4:0] R_Addr_A;
	reg [4:0] R_Addr_B;
	reg [4:0] W_Addr;
	reg [31:0] W_Data;
	reg clk;
	reg rst;
	reg Write_Reg;

	// Outputs
	wire [31:0] R_Data_A;
	wire [31:0] R_Data_B;

	// Instantiate the Unit Under Test (UUT)
	register uut (
		.R_Addr_A(R_Addr_A), 
		.R_Addr_B(R_Addr_B), 
		.W_Addr(W_Addr), 
		.W_Data(W_Data), 
		.clk(clk), 
		.rst(rst), 
		.Write_Reg(Write_Reg), 
		.R_Data_A(R_Data_A), 
		.R_Data_B(R_Data_B)
	);
	
	always begin 
		#3 clk=~clk;
	end
	initial begin
		// Initialize Inputs
		R_Addr_A = 0;
		R_Addr_B = 0;
		W_Addr = 0;
		W_Data = 0;
		clk = 0;
		rst = 1;
		Write_Reg = 0;

		// Wait 100 ns for global reset to finish
		#2 rst=0;
		#10 
			R_Addr_A = 5'b00001;
			R_Addr_B = 5'b00110;
			W_Addr = 5'b00001;
			W_Data = 32'h00FE_8888;
			Write_Reg = 1;
		#10 
			R_Addr_A = 5'b00001;
			R_Addr_B = 5'b00110;
			W_Addr = 5'b00110;
			W_Data = 32'h00FE_0EEE;
			Write_Reg = 0;//测试写入信号为0的情况
		#10 Write_Reg = 1;
		#5 
			R_Addr_B = 5'b00111;
			R_Addr_A = 5'b00110;
			W_Addr = 5'b00010;
			W_Data = 32'h00FE_1EEE;
		#10 
			R_Addr_B = 5'b00010;
			R_Addr_A = 5'b00110;
			W_Addr = 5'b00011;
			W_Data = 32'h00FE_2EEE;
		#10 
			R_Addr_B = 5'b00010;
			R_Addr_A = 5'b00011;
			W_Addr = 5'b00100;
			W_Data = 32'h00FE_3EEE;
		#10 
			R_Addr_B = 5'b00100;
			R_Addr_A = 5'b00011;
			W_Addr = 5'b00101;
			W_Data = 32'h00FE_4EEE;
		#10 
			R_Addr_B = 5'b00100;
			R_Addr_A = 5'b00101;
			W_Addr = 5'b00110;
			W_Data = 32'h00FE_5EEE;
		#10 
			R_Addr_B = 5'b00100;
			R_Addr_A = 5'b00110;
			W_Addr = 5'b00111;
			W_Data = 32'h00FE_6EEE;
		#10 
			rst=1;
 

	end
      
endmodule

波形:
在这里插入图片描述

利用ALU模块和本实验的寄存器堆模块,编写一个顶层模块,完成Ri θ Rj → Rk的操作(即2个寄存器数据做某种运算,结果送回第3个寄存器中)运算功能θ由ALU模块中的ALU_OP信号指定。
在这里插入图片描述
实验代码

module ALU_register(
    input [2:0]ALU_OP,
    input [4:0]R_Addr_A,
    input [4:0]R_Addr_B,
    input [4:0]W_Addr,
    input Write_Reg,
    input clk,
    input rst,
    output ZF,
    output OF,
    output [31:0]R_Data_A,
    output [31:0]R_Data_B,
    output [31:0]F
    );
	 
	 register r1(
		.R_Addr_A(R_Addr_A), 
		.R_Addr_B(R_Addr_B), 
		.W_Addr(W_Addr), 
		.Write_Reg(Write_Reg),
		.W_Data(F), 
		.clk(clk), 
		.rst(rst), 
		.R_Data_A(R_Data_A), 
		.R_Data_B(R_Data_B)
	 );
	 ALU a(
		.A(R_Data_A), 
		.B(R_Data_B), 
		.F(F), 
		.ZF(ZF), 
		.OF(OF), 
		.ALU_OP(ALU_OP)
	 );


endmodule

ALU代码见: 数字电路 多功能ALU设计实验.

测试代码(仅供参考)

module ALU_REG_test;

	// Inputs
	reg [2:0] ALU_OP;
	reg [4:0] R_Addr_A;
	reg [4:0] R_Addr_B;
	reg [4:0] W_Addr;
	reg Write_Reg;
	reg clk;
	reg rst;

	// Outputs
	wire ZF;
	wire OF;
	wire [31:0] R_Data_A;
	wire [31:0] R_Data_B;
	wire [31:0] F;

	// Instantiate the Unit Under Test (UUT)
	ALU_register uut (
		.ALU_OP(ALU_OP), 
		.R_Addr_A(R_Addr_A), 
		.R_Addr_B(R_Addr_B), 
		.W_Addr(W_Addr), 
		.Write_Reg(Write_Reg), 
		.clk(clk), 
		.rst(rst), 
		.ZF(ZF), 
		.OF(OF), 
		.R_Data_A(R_Data_A), 
		.R_Data_B(R_Data_B), 
		.F(F)
	);
	always begin 
		#3 clk=~clk;
	end
	initial begin
		// Initialize Inputs
		ALU_OP = 0;
		R_Addr_A = 0;
		R_Addr_B = 0;
		W_Addr = 0;
		Write_Reg = 0;
		clk = 0;
		rst = 1;
		#10
		rst=0;
		Write_Reg = 1;
		R_Addr_A = 32'h0000_0000;
		R_Addr_B = 32'h0000_0001;
		W_Addr = 32'd0;
		ALU_OP = 3'b011;
		#10
		Write_Reg = 1;
		R_Addr_A = 32'h0000_0000;
		R_Addr_B = 32'h0000_0001;
		W_Addr = 32'd1;
		ALU_OP = 3'b011;
		#10
		
		Write_Reg = 1;
		R_Addr_A = 32'h0000_0000;
		R_Addr_B = 32'h0000_0001;
		W_Addr = 32'd10;
		ALU_OP = 3'b000;
		#3 R_Addr_A = 32'd10;//在每次写入之后都观察写入地址的数据,并且在时钟周期内所以不会写入
		#10
		
		Write_Reg = 1;
		R_Addr_A = 32'h0000_0000;
		R_Addr_B = 32'h0000_0001;
		W_Addr = 32'd11;
		ALU_OP = 3'b001;
		#3 R_Addr_A = 32'd11;
		#10
		
		Write_Reg = 1;
		R_Addr_A = 32'h0000_0000;
		R_Addr_B = 32'h0000_0001;
		W_Addr = 32'd12;
		ALU_OP = 3'b010;
		#3 R_Addr_A = 32'd12;
		#10 
		
		Write_Reg = 1;
		R_Addr_A = 32'h0000_0000;
		R_Addr_B = 32'h0000_0001;
		W_Addr = 32'd13;
		ALU_OP = 3'b011;
		#3 R_Addr_A = 32'd13;
		#10  
		
		Write_Reg = 1;
		R_Addr_A = 32'h0000_0000;
		R_Addr_B = 32'h0000_0001;
		W_Addr = 32'd14;
		ALU_OP = 3'b100;
		#3 R_Addr_A = 32'd14;
		#10
		
		Write_Reg = 1;
		R_Addr_A = 32'h0000_0000;
		R_Addr_B = 32'h0000_0001;
		W_Addr = 32'd15;
		ALU_OP = 3'b101;
		#3 R_Addr_A = 32'd15;
		#10
		
		Write_Reg = 1;
		R_Addr_A = 32'h0000_0000;
		R_Addr_B = 32'h0000_0001;
		W_Addr = 32'd16;
		ALU_OP = 3'b110;
		#3 R_Addr_A = 32'd16;
		#10
		
		Write_Reg = 1;
		R_Addr_A = 32'h0000_0000;
		R_Addr_B = 32'h0000_0001;
		W_Addr = 32'd17;
		ALU_OP = 3'b111;
		#31 R_Addr_A = 32'd17;
		#10
		
		rst=1;

	end
      
endmodule

波形图:
在这里插入图片描述

以上是关于计算机组成原理 寄存器堆设计实验(加上与ALU连接)的主要内容,如果未能解决你的问题,请参考以下文章

计算机组成原理 存储器设计实验(并加上ALU和寄存器)

计算机组成原理 存储器设计实验(并加上ALU和寄存器)

计算机组成原理 存储器设计实验(并加上ALU和寄存器)

计算机组成原理运算器组成实验

计算机组成原理 王道考研2021 第二章:数据的表示和运算 -- 算术逻辑单元(ALU)电路基础知识加法器的实现

(计算机组成原理)第五章中央处理器-第三节1:CPU内部单总线数据通路中数据的流动