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了 !!!!
很想认识一下你,交流交流