FPGA学习——HDLBits网站刷题笔记整理(5)

Verilog的更多功能

三元条件运算符

对于条件表达式b ? x : y,先计算条件b,然后进行判断。如果b的值为true,计算x的值,运算结果为x的值;否则,计算y的值,运算结果为y的值。一个条件表达式绝不会既计算x,又计算y。
Verilog中有一个三元条件运算符很像C语言,这可以用于在一行中根据条件选择两个值中的一个,而不用在组合always块中使用if-then。
题目:给定四个无符号数,求最小值。无符号数可以与标准比较运算符(a <b)进行比较。
答案:

module top_module (a, b, c, d,min);
    input [7:0] a, b, c, d;
    output [7:0] min;
    wire [7:0] min1;
    wire [7:0] min2;
    assign min1 = (a<b)? a:b;
    assign min2 = (c<min1)?c:min1;
    assign min = (d<min2)?d:min2;

endmodule

缩位(归约)运算符

归约运算符是一元操作数,相当于C语言中的单目运算符。它是对一个操作数进行位操作,最后得到一个一位的数。
归约运算的过程是第一步先用操作数的第一位和第二位进行位操作,然后再用第一步的结果和操作的数的下一位。
进行位操作,如此重复直到最后一位。
Verilog中的归约运算符包含归约与(&),归约与非(~&)、归约或(|)、归约或非(~|)、归约异或(^)、归约同或(~^

我们已经熟悉了两个值之间的位运算,例如a&b或a^b。有时,需要创建一个对一个向量的所有位进行操作的宽门,如(a[0]&a[1]&a[2]&a[3]…),如果向量很长的话会很乏味。
归约运算符可以对向量的位进行AND、OR和XOR运算,产生一位输出:

& a[3:0]     // AND: a[3]&a[2]&a[1]&a[0]. Equivalent to (a[3:0] == 4'hf)
| b[3:0]     // OR:  b[3]|b[2]|b[1]|b[0]. Equivalent to (b[3:0] != 4'h0)
^ c[2:0]     // XOR: c[2]^c[1]^c[0]

这些是只有一个操作数的一元运算符(类似于NOT运算符!)。您还可以反转这些门的输出来创建NAND、NOR和XNOR门,例如(~&amp;d[7:0]

归约运算符与位运算符的异同:
相同点:
1)这些运算符与位运算符使用的符号相同。
2)逻辑运算结果遵从相同的运算规则。
3)基本运算符只有三个&、|、^,其他在这三个的基础上取反组成,如~&
区别:
1)位运算为二元操作符,而归约运算符为一元操作符。
2)位运算符运算结果可以为一位位宽,也可以为多位位宽(向量运算),而归约运算符只有位宽为一位的运算结果。

组合for循环:向量翻转

题目:给定一个100位的输入向量,翻转它的位顺序。
答案:

module top_module(in, out);
    input [99:0] in;
    output [99:0] out;
    integer i;
    always @(*) 
        begin
        for(i=0;i<100;i++) begin
            out[i]=in[99-i];
        end
    end
endmodule

组合for循环:255bit计数

题目:“计数”电路对输入向量中的1进行计数。为一个255位输入向量建立一个“计数”电路。
答案:

module top_module(in, out);
    input [254:0] in;
    output [7:0] out;
    integer i;
    integer temp;
    always @(*)
        begin
        out = 8'd0;
        for(i=0;i<255;i++) begin
            out = out + in[i];
        end
    end
endmodule

生成循环语句

Verilog中的generate语句常用于编写可配置的、可综合的RTL的设计结构。它可用于创建模块的多个实例化,或者有条件的实例化代码块。
1)generate循环结构
generate循环的语法与for循环语句的语法很相似。但是在使用时必须先在genvar声明中声明循环中使用的索引变量名,然后才能使用它。genvar声明的索引变量被用作整数用来判断generate循环。genvar声明可以是generate结构的内部或外部区域,并且相同的循环索引变量可以在多个generate循环中,只要这些环不嵌套。genvar只有在建模的时候才会出现,在仿真时就已经消失了。
2)条件if-generate构造
条件语句从很多的备选块中选择最多一个generate块,请注意,在这我说的是最多,因为有可能是一个也不选择的。在建模中,条件必须为常量表达式。
条件if-generate不关心是否命名,并且可以不具有begin / end。当然,上述两个条件只能包含一项。它也会创建单独的范围和层次结构级别,这个和generate循环是一样的。由于最多选择一个代码块,因此在单个的if-generate中以相同的名称命名所有的备用代码块是合法的,而且这有助于保持对代码的分层引用。但是,不同的generate构造中必须具有不同的名称。
3)条件case-generate构造
与if-generate类似,case-generate也可用于从几个块中有条件地选择一个代码块。它的用法类似于基本case语句,并且if-generate中的所有规则也适用于case-generate块。

题目1:通过实例化100个全加器来创建一个100位二进制行波进位加法器。加法器将两个100位数字和一个进位相加,产生100位和并执行。
答案:

module top_module(a, b, cin, cout, sum);
    input [99:0] a, b;
    input cin;
    output [99:0] cout;
    output [99:0] sum;
	genvar i;
    generate
        for(i=0;i<100;i++) 
        begin:adder
            if(i==0)
                assign{cout[0],sum[0]}=a[0]+b[0]+cin;
            else
                assign{cout[i],sum[i]}=a[i]+b[i]+cout[i-1];
        end           
    endgenerate
endmodule

题目2:我们为您提供了一个名为BCD_fadd的BCD一位加法器,它将两个BCD数字相加并执行进位,然后生成一个求和并执行进位。

module bcd_fadd {
    input [3:0] a,
    input [3:0] b,
    input     cin,
    output   cout,
    output [3:0] sum );

实例化bcd_fadd的100个副本,以创建一个100位的BCD行波进位加法器。
答案:

module top_module(a, b, cin, cout, sum);
    input [399:0] a, b;
    input cin;
    output cout;
    output [399:0] sum;
    wire [99:0] cout_temp;
	genvar i;
    generate
        for(i=0;i<100;i++) 
        begin:bcd_fadd
            if(i == 0)
                bcd_fadd bcd_inst(a[3:0],b[3:0],cin,cout_temp[0],sum[3:0]);
            else
                bcd_fadd bcd_inst(a[4*i+3:4*i],b[4*i+3:4*i],cout_temp[i-1],cout_temp[i],sum[4*i+3:4*i]);
        end
        assign cout=cout_temp[99];
    endgenerate
endmodule

以上是HDLBits Verilog语言刷题网站中的More Verilog Features部分,后续部分会继续更新。对一些基础性知识点进行归纳总结,有错误请指正。仅供学习参考,谢谢!!!

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TC_zyq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值