ALU和寄存器堆(verilog)

一、ALU

1. 实验目的

(1). 深入了解ALU原理;

(2). 学习使用verilog HDL 进行行为级ALU的设计与仿真

2. 实验内容

(1)原理描述

定义输入输出:8位输入A和B,4位输入ALU_Sel,8位输出ALU_Out和1位输出CarryOut。

定义中间变量ALU_Result,用于存储ALU运算的结果。

定义一个临时变量tmp,用于存储A加B的值。

将ALU_Out输出赋值为ALU_Result。

将tmp赋值为{1'b0,A} + {1'b0,B}。

将CarryOut输出赋值为tmp的第8位。

在always @(*)块中使用case语句,根据ALU_Sel的值执行不同的运算。

对于每种情况,将ALU_Result赋值为对应的运算结果。

如果ALU_Sel的值无法匹配任何情况,则默认执行算术加法。

ALU和寄存器堆(verilog)_第1张图片 

 

(2)Verilog HDL设计源代码描述(要求:注释)

module alu(

input [7:0] A,B, // ALU 8位 输入

input [3:0] ALU_Sel,// ALU 选择

output [7:0] ALU_Out, // ALU 8位输出

output CarryOut // Carry Out Flag

);

reg [7:0] ALU_Result;

wire [8:0] tmp;

assign ALU_Out = ALU_Result; // ALU

assign tmp = {1'b0,A} + {1'b0,B};

assign CarryOut = tmp[8]; // Carryout flag

always @(*)

begin

case(ALU_Sel)

4'b0000: // 算数加法

ALU_Result = A + B ;

4'b0001: // 算数减法

ALU_Result = A - B ;

4'b0010: // 乘法

ALU_Result = A * B;

4'b0011: // 除法

ALU_Result = A/B;

4'b0100: // shift left逻辑左移

ALU_Result = A<<1;

4'b0101: // shift right 逻辑右移

ALU_Result = A>>1;

4'b0110: // Rotate left 循环左移

ALU_Result = {A[6:0],A[7]};

4'b0111: // Rotate right循环右移

ALU_Result = {A[0],A[7:1]};

4'b1000: // and 逻辑与

ALU_Result = A & B;

4'b1001: // or逻辑或

ALU_Result = A | B;

4'b1010: // xor 异或

ALU_Result = A ^ B;

4'b1011: //nor或非

ALU_Result = ~(A | B);

4'b1100: //nand 与非

ALU_Result = ~(A & B);

4'b1101: //xnor 同或

ALU_Result = ~(A ^ B);

4'b1110: // 比较大小

ALU_Result = (A>B)?8'd1:8'd0 ;

4'b1111: // 比较像等

ALU_Result = (A==B)?8'd1:8'd0 ;

default: ALU_Result = A + B ;

endcase

end



endmodule

(3)TestBeach仿真代码及仿真结果

`timescale 1ns / 1ps

module tb_alu;

//Inputs

reg[7:0] A,B;

reg[3:0] ALU_Sel;

//Outputs

wire[7:0] ALU_Out;

wire CarryOut;

// Verilog code for ALU

integer i;

alu test_unit(

A,B, // ALU 8-bit Inputs

ALU_Sel,// ALU Selection

ALU_Out, // ALU 8-bit Output

CarryOut // Carry Out Flag

);

initial begin

// hold reset state for 100 ns.

A = 8'h0A;

B = 4'h02;

ALU_Sel = 4'h0;

for (i=0;i<=15;i=i+1)

begin

ALU_Sel = ALU_Sel + 8'h01;

#10;

end;

A = 8'hF6;

B = 8'h0A;

end

endmodule

ALU和寄存器堆(verilog)_第2张图片


二、寄存器堆

1. 实验目的

(1). 深入了解寄存器原理;

(2). 学习使用verilog HDL 进行行为级寄存器的设计与仿真

2. 实验内容

(1)原理描述

寄存器文件共有32个寄存器,每个寄存器宽度为32位。

该模块有以下输入:

clk:控制模块操作的时钟信号。

wen:写使能信号。当它为高电平(1)时,执行写操作。

raddr1:第一个要读取的寄存器的地址。

raddr2:第二个要读取的寄存器的地址。

waddr:要写入的寄存器的地址。

wdata:要写入寄存器的数据。

模块输出:

rdata1:从第一个寄存器读取的数据。

rdata2:从第二个寄存器读取的数据。

test_data:从由test_addr输入指定的寄存器读取的数据。

模块输入:

test_addr:用于测试的要读取的寄存器的地址。

该模块有一个用于存储数据的寄存器数组REG_Files。initial块用于将所有寄存器初始化为0。具有正边沿触发的clk输入的always块用于在wen为高电平时执行写操作。

ALU和寄存器堆(verilog)_第3张图片

(2)Verilog HDL设计源代码描述(要求:注释)

`timescale 1ns / 1ps

module regfile(

input clk, //时钟控制信号

input wen, //写使能信号,1有效

input [4 :0] raddr1, //第一个读端口的地址

input [4 :0] raddr2, //第二个读端口的地址

input [4 :0] waddr, //一个写端口

input [31:0] wdata, //需要写入的数据

output [31:0] rdata1, //读出的数据1

output [31:0] rdata2, //读出的数据2

input [4 :0] test_addr, //输入的调试地址

output [31:0] test_data //输出调试数据

);

//总共32个寄存器

integer i = 0;

reg [31:0] REG_Files[31:0];

initial//初始化32个寄存器,全为0

for(i = 0;i < 32;i = i + 1)

REG_Files[i]<=0;

always @ (posedge clk)

begin

if(wen)

REG_Files[waddr] <= wdata;

end

assign rdata1 = REG_Files[raddr1] ;

assign rdata2 = REG_Files[raddr2];

assign test_data = REG_Files[test_addr];

endmodule

(3)TestBeach仿真代码及仿真结果

module tb_regfile();

// Inputs

reg clk;

reg wen;

reg [4 :0] raddr1;

reg [4 :0] raddr2;

reg [4 :0] waddr;

reg [31:0] wdata;

reg [4 :0] test_addr;



// Outputs

wire [31:0] rdata1;

wire [31:0] rdata2;

wire [31:0] test_data;



// Instantiate the Unit Under Test (UUT)

regfile rf(

.clk(clk),

.wen(wen),

.raddr1(raddr1),

.raddr2(raddr2),

.waddr(waddr),

.wdata(wdata),

.rdata1(rdata1),

.rdata2(rdata2),

.test_addr(test_addr),

.test_data(test_data)

);



initial begin

// Initialize Inputs

clk = 0;

wen = 0;

raddr1 = 0;

raddr2 = 0;

waddr = 0;

wdata = 0;

test_addr = 0;



// Wait 100 ns for global reset to finish

#100;

waddr = 5'h05;

wdata = 32'h3F;

#400;

wen = 1'b1;

#500;

wen = 1'b0;

#400;

raddr1 = 5'h05;

#500;

raddr2 = 5'h05;

#400;

test_addr = 5'h05;

// Add stimulus here

end



always #5 clk = ~clk;

endmodule

ALU和寄存器堆(verilog)_第4张图片 

 

你可能感兴趣的:(数字逻辑电路课程实验,fpga开发)