Verilog设计一个32位ALU,并进行功能验证
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=S3⋅a⋅b+S2⋅a⋅bˉ+S1⋅aˉ⋅b+S0⋅aˉ⋅bˉ
那么拓展为32位,只需修改控制信号的位数即可
对于具体的选择控制信号以及逻辑和功能,见下表
选择控制信号 {S[3],S[2],S[1],S[0],Ci,M} |
逻辑 | 功能 |
---|---|---|
000010 | 0 | 置全0 |
000110 | !A & !B | nor |
001010 | !A & B | notand |
001110 | !A | not A |
010010 | A & !B | andnot |
010110 | !B | not B |
011010 | A&!B | !A&B | xor |
011110 | !A | !B | nand |
100010 | A & B | and |
100110 | A&B | !A & !B | xnor |
101010 | B | 传送B |
101110 | A&B | !A&B | !A&!B | notor |
110010 | A | 传送A |
110110 | A&B | a&!B | !A&!B | or not |
111010 | A&B | A&!B | !A&B | or |
111110 | 1 | 置全1 |
100101 | A^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]}=3′b001或者3′b110判定为溢出
对于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的设计。
更多推荐
所有评论(0)