Verilog设计一个32位ALU,并进行功能验证

设计一个32位ALU,并进行功能验证

使用Quartus+modelsim完成设计

题目如下,已经给定了端口定义。
在这里插入图片描述

分析

ALU需要实现的功能如下:

  • 算术运算
    • 加、减法运算
    • 协助进行串行乘、除法计算
  • 逻辑运算
    • 按位逻辑技术
    • and / nand / or / nor / xor / xnor / buf / not
    • 输出全0,全1值

题目给出了采用行波进位的32位ALU设计,通过分析,认为主体部分为一个32位串行全加器,全加器的输入由原本的a与b替换为组合逻辑电路。故分别设计32位串行加法器以及输入处的组合逻辑电路。

观察发现,令32位串行加法器的p和g进行定义即可。

对于1位ALU而言可以有以下公式来实现,其中的 S 0 , 1 , 2 , 3 S_{0,1,2,3} S0,1,2,3为控制信号:
S = S 3 ⋅ a ⋅ b + S 2 ⋅ a ⋅ b ˉ + S 1 ⋅ a ˉ ⋅ b + S 0 ⋅ a ˉ ⋅ b ˉ \begin{aligned} S=& S_3 \cdot a \cdot b+ S_2 \cdot a \cdot \bar{b}+ S_1 \cdot \bar{a} \cdot b+ S_0 \cdot \bar{a} \cdot \bar{b} \end{aligned} S=S3ab+S2abˉ+S1aˉb+S0aˉbˉ

那么拓展为32位,只需修改控制信号的位数即可

在这里插入图片描述

对于具体的选择控制信号以及逻辑和功能,见下表

选择控制信号
{S[3],S[2],S[1],S[0],Ci,M}
逻辑功能
0000100置全0
000110!A & !Bnor
001010!A & Bnotand
001110!Anot A
010010A & !Bandnot
010110!Bnot B
011010A&!B | !A&Bxor
011110!A | !Bnand
100010A & Band
100110A&B | !A & !Bxnor
101010B传送B
101110A&B | !A&B | !A&!Bnotor
110010A传送A
110110A&B | a&!B | !A&!Bor not
111010A&B | A&!B | !A&Bor
1111101置全1
100101A^B^C加法
011011(A~^B)^C减法

代码实现

在always过程块里,需要用到阻塞赋值,因为需要所有的output同时改变。

对于C:输出进位,直接去carry的最高位即可

对于V:溢出,这里采用最高位比较的方法,即 { o p A [ 31 ] , o p B [ 31 ] , D O [ 31 ] } = 3 ′ b 001 或者 3 ′ b 110 \{opA[31],opB[31],DO[31]\} = 3'b001 或者 3'b110 {opA[31],opB[31],DO[31]}=3b001或者3b110判定为溢出

对于N:符号位, D O DO DO的最高位

对于Z:用 ! ( D O ) !(DO) !(DO)判断

//32bit arithmetic and logic unit(ALU)
module ALU32#(
	parameter n =32
	)(
	input [n-1:0] opA,	//INPUT operand A	
	input [n-1:0] opB,	//INPUT operand B
	input [3:0]  S  ,	//INPUT Signal that selects working mode
	input wire   M  ,	//INPUT Signal that controls logical operation
	input wire   Cin,	//INPUT signal that carry
	output reg[n-1:0]DO,//OUTPUT DATA
	output wire C ,		//OUTPUT Carry
	output wire V ,		//Overflow
	output wire N ,		//DO's sign bit
	output wire Z		//if DO is 0
);
	reg [n-1:0] p;
	reg [n-1:0] g;
	reg [n:0] carry;
	//main body
	always@(opA,opB,S,M,Cin)
	//need blocking assignment
		begin
			carry[0] = Cin;
			g = {n{S[3]}}&opA&opB | {n{S[2]}}&opA&(~opB) | {n{(~M)}};
			//Expand bits
			//let every bit is S[3]/S[2]/(~M)
			//by {n{}}
			p = ~({n{S[3]}}&opA&opB | {n{S[2]}}&opA&(~opB) | {n{S[1]}}&(~opA)&opB | {n{S[0]}}&(~opA)&(~opB));
			//Expand bits
			//let every bit is S[3]/S[2]/S[1]/S[0]
			//by {n{}}
			carry[n:1] = g|(p&carry[n-1:0]);
			DO = p^carry[n-1:0];
		end
	
	//CVNZ analysis
	assign C = carry[n];//carry is the MSD of carry[n,0]
	assign V = (opA[n-1]&opB[n-1]&~DO[n-1]) | (~opA[n-1]&~opB[n-1]&DO[n-1]);//1:overflow;0:not
	assign N = DO[n-1];//sign bit is the MSD
	assign Z = (!(DO))?1:0;//if all bits are 0,then Z=1,else Z=0;

endmodule

Testbench

testbench撰写的时候讲分析中的表格中的所有情况进行了罗列,除了直接波形观察,为了更好的查看数据,使用$monitor,来得到所需数据。

`timescale 1 ns/ 1 ns
module ALU32_vlg_tst();
reg [3:0] S;
reg Cin;
reg M;

reg [31:0] opA;
reg [31:0] opB;
// wires      
wire [31:0]  DO;                                         
wire C;
wire V;
wire N;
wire Z;

// assign statements (if any)                          
ALU32 i1 (
// port map - connection between master ports and signals/registers   
	.C(C),
	.Cin(Cin),
	.DO (DO),
	.M(M),
	.N(N),
	.S(S),
	.V(V),
	.Z(Z),
	.opA(opA),
	.opB(opB)
);

//18 kinds of situation
initial                                                
begin    
	{S,Cin,M} = 6'b0000_1_0;opA = 32'h0000_ffff;opB = 32'hff00_ff00;//all bits are 0
#10	{S,Cin,M} = 6'b0001_1_0;//nor
#10	{S,Cin,M} = 6'b0010_1_0;//notand
#10	{S,Cin,M} = 6'b0011_1_0;//notA
#10	{S,Cin,M} = 6'b0100_1_0;//andnot
#10	{S,Cin,M} = 6'b0101_1_0;//notB
#10	{S,Cin,M} = 6'b0110_1_0;//xor
#10	{S,Cin,M} = 6'b0111_1_0;//nand
#10	{S,Cin,M} = 6'b1000_1_0;//and
#10	{S,Cin,M} = 6'b1001_1_0;//xnor
#10	{S,Cin,M} = 6'b1010_1_0;//B
#10	{S,Cin,M} = 6'b1011_1_0;//notor
#10	{S,Cin,M} = 6'b1100_1_0;//A
#10	{S,Cin,M} = 6'b1101_1_0;//or not
#10	{S,Cin,M} = 6'b1110_1_0;//or
#10	{S,Cin,M} = 6'b1111_1_0;//all bits are 1

#10	{S,Cin,M} = 6'b1001_0_1;opA = 32'hffff_ffff;opB = 32'habcd_4321;//add
#10	{S,Cin,M} = 6'b0110_1_1;opA = 32'hffff_ffff;opB = 32'h0000_ffff;//sub

end                                                    
        
initial 
	$monitor($time," -- INPUT: {S,Cin,M}=%b%b%b;opA=%h,opB=%h,\t OUTPUT: DO=%h,C=%b,V=%b,N=%b,Z=%b",S,Cin,M,opA,opB,DO,C,V,N,Z);
endmodule

结果

RTL Viewer,电路综合得到的电路如下图所示:

在这里插入图片描述

Wave结果如下图所示:

在这里插入图片描述

Transcript中得到的monitor结果如下,其中测试顺序均按照分析中的表格进行。逐项分析验证,该电路正确无误,实现了32位ALU的设计。

在这里插入图片描述

  • 5
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值