Verilog组合设计:ALU算术逻辑单元
本文使用Verilog实现一个简单的16位算术逻辑单元ALU的组合设计,并完成相应的测试工作。组合设计属于Verilog行为设计的范畴,是将结构化功能进行抽象表示后完成的逻辑设计。
ALU功能需求定义如下:

输入:16位X和Y作为计算操作数,2位M作为控制信号
输出:16位Q
控制信号功能模式:
| M | 操作 |
|---|---|
| 00 | Y |
| 01 | X+Y |
| 10 | X+1 |
| 11 | X-Y |
Verilog实现ALU模块:
// MU0 ALU design
`timescale 1ns/100ps
// for simulation purposes
`default_nettype none
// module header
module mu0_alu(input wire [15:0] X,
input wire [15:0] Y,
input wire [1:0] M,
output reg [15:0] Q);
// behavioural description
always @ (*)
begin
case (M)
2'b00: Q = Y;
2'b01: Q = X + Y;
2'b10: Q = X + 1;
2'b11: Q = X - Y;
default: Q = 16'hxxxx;
endcase
end
endmodule
// for simulation purposes
`default_nettype wire
输入参数使用wire类型,表示物理连线,输入内容始终直接由外部给定,无条件相等;输出参数使用reg类型,表示其值需要一定信号触发该变量才会被赋值,即通过触发才能使输出信号反映输入信号的状态,否则其值未定义。
使用always block和阻塞赋值语句对输出Q赋值(reg类型变量仅能在always块中被赋值)。整个区块对任意输入变量敏感,X、Y或M的变化都会触发ALU重新计算输出Q。区块中使用switch语句判断控制信号M,并根据功能需求完成相应的运算。default表示M未定义时输出Q未定义。
下面编写测试脚本(testbench)。
// MU0 ALU testbench
// #1 = 1ns
`timescale 1ns/100ps
module mu0_alu_tb();
// Internal connections
reg [15:0] X;
reg [15:0] Y;
reg [1:0] M;
wire [15:0] Q;
// Instantiate mu0_alu as dut (device under test)
mu0_alu dut(X, Y, M, Q);
// Test vectors
initial
begin
// connectivity test, test if all inputs and output are normally connected, use Q=X+Y
#100 X=16'h0000; Y=16'h0000; M=2'b01;
// sensitivity test
// test if the output will response to the change of X
#100 X=16'h0001;
// test if the output will response to the change of Y
#100 Y=16'h0001;
// test different control signals M and corresponding functions, use identifiable X and Y
// test M=b00, Q=Y
#100 X=16'h3333; Y=16'h2222; M=2'b00;
// test M=b01, Q=X+Y
#100 M=2'b01;
// test M=b10, Q=X+1
#100 M=2'b10;
// test M=b11, Q=X-Y
#100 M=2'b11;
// test undefined control signal M
#100 M=2'bxx;
#100 $finish; // end the simulation
end
// Save results as VCD file
initial
begin
$dumpfile("mu0_alu_tb_results.vcd"); // Save simulation waveforms in this file
$dumpvars; // Capture all simulation waveforms
end
endmodule
测试传入变量的类型恰好相反,输入变量为reg,输出变量为wire。因为输入变量会在测试过程中被主动更新,而输出直接获取模块的原始输出,无附加组合逻辑操作。
测试需要涵盖连接性测试,检测所有位的输入输出是否正常连通;感知列表测试,测试模块是否对各个输入变量的变化敏感,正常输出;控制逻辑测试,测试每一种控制信号M是否使程序正确完成相应算术操作。
在控制逻辑测试中,需要使用可辨识的X和Y,使X和Y的各类算术操作结果具有独特性,从而判断程序是否正确运作。控制逻辑测试包括控制信号M未定义的情况。
使用以下命令编译代码、执行并使用gtkwave可视化结果。(操作系统:Linux Mint)
iverilog -y. -o mu0_alu_output mu0_alu_tb.v vvp mu0_alu_output gtkwave mu0_alu_tb_results.vcd

一条评论
copper
学长你好,我是曼大大一cs的新生,在查资料的时候发现了你的网址,太nb了 !!!!
很想认识一下你,交流交流