Verilog设计技巧实例及实现

Verilog设计技巧实例及实现

1 引言

最近在刷HDLBits的过程中学习了一些Verilog的设计技巧,在这里予以整理。部分操作可能降低代码的可读性和Debug的难度,请大家根据实际情况进行使用。

2 目录

2.1 casez

例:创建八位输入信号的优先编码器。给定一个8位向量,输出向量中第一个为1的位。如果输入向量没有高位,则报告0。例如,输入8'b10010000应该输出3'd4。

这里我们若用case语句来实现,共有256个case,可以用脚本生成,但在这里我们介绍一种基于casez的解决方案,可以将256个case降低为9个item。在casez中,值为z的位将被忽视比较。因此一些输入(例如4'b1111)将匹配多个case item,选择第一个匹配项。同时,也可以用?代表忽视比较的项,意义与z相同。代码如下:

module top_module (
    input [7:0] in,
    output reg [2:0] pos  );
    
    always@(*)begin
        casez(in)
            8'bzzzzzzz1:begin//z不予比较
                pos = 3'd0;
            end
            8'bzzzzzz10:begin
                pos = 3'd1;
            end
            8'bzzzzz100:begin
                pos = 3'd2;
            end
            8'bzzzz1000:begin
                pos = 3'd3;
            end
            8'bzzz10000:begin
                pos = 3'd4;
            end
            8'bzz100000:begin
                pos = 3'd5;
            end
            8'bz1000000:begin
                pos = 3'd6;
            end
            8'b10000000:begin
                pos = 3'd7;
            end
            default:begin
                pos = 3'd0;
            end
        endcase
    end
endmodule

Verilog设计技巧实例及实现

图1 结果时序图

2.2 generate for实例化重复模块

例:已有名为bcd_fadd的一位BCD全加器模块,它将两个BCD数字a[3:0],b[3:0]加起来并产生和sum[3:0]及进位cout。现需实例化100个bcd_fadd以创建100位BCD全加器,实现将两个100位BCD数字a[99:0],b[99:0]以及进位信号cin相加,产生一个100位的和sum[99:0]及进位cout。

在这里我们可以分割为一个以cin为进位的全加器以及99个重复的以cout_inter为进位的全加器模块,因此可以用generatefor生成重复模块。代码如下:

module top_module( 
    input [399:0] a, b,
    input cin,
    output cout,
    output [399:0] sum );
    
    wire [99:0] cout_inter;//中间进位值cout
        
    generate
        genvar i;
        for(i = 0; i <= 99; i++)begin:adder//adder指的是自定义的模块名
            if(i==0)begin
                bcd_fadd u_bcd_fadd(
                    .a		(a[3:0]),
                    .b		(b[3:0]),
                    .cin	(cin),
                    .cout	(cout_inter[0]),
                    .sum 	(sum[3:0])
                );
            end
            else begin
                 bcd_fadd ui_bcd_fadd(
                     .a		(a[4*i+3:4*i]),
                     .b		(b[4*i+3:4*i]),
                     .cin	(cout_inter[i-1]),
                     .cout	(cout_inter[i]),
                     .sum 	(sum[4*i+3:4*i])
                );
            end
        end
    endgenerate
        
    assign cout = cout_inter[99];
    
endmodule

2.3 &、|及^的使用

例:建立一个四输入(in[3:0])的组合电路,有3个输出:4位输入信号的与out_and、4位输入信号的或out_or及4位输入信号的异或out_xor

这里我们可以规约运算符简单实现,代码如下:

module top_module( 
    input [3:0] in,
    output out_and,
    output out_or,
    output out_xor
);
    assign out_and = &in;
    assign out_or = |in;
    assign out_xor = ^in;
endmodule

Verilog设计技巧实例及实现

图2 结果时序图

3 结果显示

---

参考资料:HDLBits

上一篇:Verilog HDL-IP核开发(一)


下一篇:Verilog 多位与一位 进行异或