【此后无良辰】实验二 CPU部件实现之ALU和寄存器堆

一、 实验目的

理解和掌握CPU中的算术逻辑运算部件(ALU)和寄存器堆(Register File)的工作原理,并使用Verilog和ModelSim进行设计和仿真。

二、 实验内容

  1. 使用Verilog完成ALU的设计,并编写测试仿真文件验证其正确性。要求:
    ALU支持16位的加、减、与、或以及移位运算。
  2. 使用Verilog完成通用寄存器堆的设计,并编写测试仿真文件验证其正确性。要求
    寄存器堆包含8个16位的寄存器;
    寄存器堆有两个读端口和一个写端口。

三、 实验原理

ALU和寄存器堆的原理图在这里插入图片描述

ALU :通常支持许多基本算术和按位逻辑函数,实现指令所指定的各种算术和逻辑运算操作

寄存器堆:是CPU中多个寄存器组成的阵列,通常由快速的静态随机读写存储器(SRAM)实现。这种RAM具有专门的读端口与写端口,可以多路并发访问不同的寄存器。

四、实验步骤

  1. Verilog关键代码描述

ALU
代码如下:

module alu(
  input wire [15:0] in1, in2,
  input wire [2:0] alu_op,
  output reg [15:0] Z
);
  always@* begin
    case(alu_op)
      3'b000: Z = in1+in2;
      3'b001: Z = in1-in2;
      3'b010: Z = in1&&in2;
      3'b011: Z = in1||in2;
      3'b100: Z = in1<<in2;
      3'b101: Z = in1>>in2;
    endcase
  end
endmodule

代码截图如下:
在这里插入图片描述

Verilog关键代码解释:
Alu等于设置一个一个多路选择器,根据alu_op的值不同,对输入的两个数a,b进行不同方式的计算
在这里插入图片描述

寄存器堆
代码如下:

module reg_stack(
  input wire Wen, clk,
  input wire [2:0] Ra, Rb, Rw,
  input wire [15:0] Busw,
  output wire [15:0] Busa, Busb
);
  reg [15:0] regfile[7:0];
  assign Busa = regfile[Ra];
  assign Busb = regfile[Rb];
  always@(posedge clk) begin
      if(Wen == 1)
        regfile[Rw] <= Busw;
  end
endmodule

代码截图如下:
在这里插入图片描述

Verilog关键代码解释:
设置一个 reg [15:0] regfile[7:0]; 即8个16位的寄存器
在每一个上升沿的时候判断Wen是否为1
为1则代表寄存器要写入

  1. 测试文件描述

ALU
测试文件代码:

`timescale 1ns / 1ps

module reg_simulation(
output [15:0] Busa,
output  [15:0] Busb
);
reg [15:0] Busw;
reg [2:0] Ra,Rb,Rw;
reg clk;
reg Wen;
always #5 clk=~clk;

integer i,reg_n = 0;

initial
begin
    Wen=1;
    clk=0;
    
    for(i = 0;i<8;i = i+ 1) begin
        Busw = i;
        Rw = i;
        reg_n = reg_n + 1;
        #10;
        end
    Wen = 0;
    #10
    for (i  = 0;i<8/2;i=i+1) begin
         Rb=reg_n-1;
         Ra=reg_n-2;
         reg_n = reg_n - 2;
         #10;
    end
    Ra = 0;
    Rb = 1;
    #10 $stop;
end
reg_stack try(
    .Wen(Wen),
    .Busw(Busw),
    .Rw(Rw),
    .Ra(Ra),
    .Rb(Rb),
    .clk(clk),
    .Busa(Busa),
    .Busb(Busb) 
);
endmodule

测试文件关键代码截图:
在这里插入图片描述

测试文件代码解释:
每隔10ns,输入一个a,b和operator,即使用alu计算一次a和b,最后运行10ns后停止程序。

寄存器堆
测试文件代:

`timescale 1ns / 1ps

module reg_simulation(
output [15:0] Busa,
output  [15:0] Busb
);
reg [15:0] Busw;
reg [2:0] Ra,Rb,Rw;
reg clk;
reg Wen;
always #5 clk=~clk;
integer i,reg_n = 0;
initial
begin
    Wen=1;
    clk=0;
    
    for(i = 0;i<8;i = i+ 1) begin
        Busw = i;
        Rw = i;
        reg_n = reg_n + 1;
        #10;
        end
    Wen = 0;
    #10
    
    for (i  = 0;i<8/2;i=i+1) begin
         Rb=reg_n-1;
         Ra=reg_n-2;
         reg_n = reg_n - 2;
         #10;
    end
    Ra = 0;
    Rb = 1;
    #10 $stop;
end
reg_stack try(
    .Wen(Wen),
    .Busw(Busw),
    .Rw(Rw),
    .Ra(Ra),
    .Rb(Rb),
    .clk(clk),
    .Busa(Busa),
    .Busb(Busb) 
);
Endmodule

测试文件关键代码截图:

在这里插入图片描述
在这里插入图片描述

测试文件代码解释:
我们在开始时,通过时钟控制,写入0-7共八个数字
再通过每次取出两个数,完成对寄存器堆的验证。

  1. ModelSim仿真及分析

ALU
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通过我们的测试文件和verilog代码可知:
第一次输入a=1,b=2,应该进行加操作 得3
第一次输入a=4,b=2,应该进行减操作 得2
第一次输入a=2,b=4,应该进行并操作 得1
第一次输入a=2,b=4,应该进行或操作 得1
第一次输入a=32,b=2,应该进行左移操作 得128
第一次输入a=8,b=1,应该进行右移操作 得4

结合仿真文件可知,实验结果正确

寄存器堆
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通过我们的测试文件和verilog代码可知:
在前90ns,我们往寄存器堆中填充了8个数
分别是0,1,2,3,4,5,6,7,
在后面的50ns中,我们从寄存器堆中取出数字
从取出的数字顺序可知:

填充顺序:0 1 2 3 4 5 6 7
取出顺序:7 6 5 4 3 2 1 0

可知寄存器堆的运用成功

五、总结

ALU
利用verilog语言设计了一个ALU支持16位的加、减、与、或以及移位运算,并在相应的测试文件中在不同的时钟设置不同的数和操作数,
在这里插入图片描述

结合ModelSim仿真,成功验证了ALU。
在这里插入图片描述

寄存器堆
利用Verilog完成通用寄存器堆的设计。
寄存器堆包含8个16位的寄存器,寄存器堆有两个读端口和一个写端口,寄存器在每一个上升沿进行判断,如果Wen为1,则往寄存器堆写入数。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

结合ModelSim仿真,数字顺序可知:
填充顺序:0 1 2 3 4 5 6 7
取出顺序:7 6 5 4 3 2 1 0

可知寄存器堆的运用成功

望能对诸君有所帮助,切忌直接抄袭(觉得有用记得点赞呀~)

  • 28
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值