HDLBits(五)学习笔记—— More Verilog Features

三目运算符

(条件 ? if_true : if_false)
可通过三目运算符在一行中,选择两个值之一,无需在always块中使用if-then,给出如下例子:

(sel ? b : a)   // 通过sel进行二选一

always @(posedge clk)         // T触发器
  q <= toggle ? ~q : q;

always @(*)                   // State transition logic for a one-input FSM
  case (state)
    A: next = w ? B : A;
    B: next = w ? A : B;
  endcase

assign out = ena ? q : 1'bz;  // A tri-state buffer

((sel[1:0] == 2'h0) ? a :     // A 3-to-1 mux
 (sel[1:0] == 2'h1) ? b :
                      c )

练习

给定四个无符号数字,找到最小值。无符号数字可以与标准比较运算符(a < b)进行比较。使用条件运算符来得到,同时两两比较时,可创建新的变量来暂存中间结果。

module top_module (
    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

缩位运算符

若想创建一个多位宽的逻辑门操作,就要对一个向量的所有位进行操作,比如(a[0] & a[1] & a[2] & a[3] … ),如果向量很长,这种计算方式很麻烦。而缩位运算符即可对一个向量的各个位进行操作,产生一位的输出,例如:

在这里插入图片描述

练习 1

奇偶校验可在数据传输时进行错误的检测。
创建一个电路,该电路将计算 8 位字节的奇偶校验位(这将向字节添加第 9 位)。我们将使用“偶数”奇偶校验,其中奇偶校验位只是所有8个数据位的异或。

module top_module (
    input [7:0] in,
    output parity); 
    
assign parity = ^in[7:0];
//assign parity = ^in;

endmodule

练习 2

构建具有 100 个输入的组合电路,采用[99:0]。有 3 个输出:
out_and:100 输入 对应的AND 门的输出。
out_or:100 输入对应的 OR 门的输出。
out_xor:100输入对应的异或门的输出。

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

endmodule

组合for循环,向量反转

给定一个 100 位输入向量 [99:0],反转其位顺序。

module top_module( 
    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循环,255位计数

module top_module( 
    input [254:0] in,
    output [7:0] out );

    integer i;

    always @(*) begin
        out = 8'd0;
        for(i=0;i<255;i++) begin
            out = out + in[i];
        end
    end   
endmodule

循环生成语句

关于生成块:
Verilog中的generate生成语句可动态地生成Verilog代码,常用于编写可配置的、可综合的RTL的设计结构。它可用于参数化模块的生成,可创建模块的多个实例化,或者有条件的实例化代码块。——生成块的本质是用循环内的一条语句来代替多条重复的Verilog语句。

在使用generate循环生成语句时,必须说明生成的实例范围。

生成的实例具有唯一的标识名,因此可用层次命名规则引用,生成的声明和实例,能在设计中被有条件的调用。

genvar用于声明生成变量,并且只能在生成块中用(生成变量的值只能由循环生成语句改变),其被用作整数用来判断generate循环。

循环生成语句可嵌套,但是使用同一个生成变量作为索引的循环生成语句不可相互嵌套。

练习1

用循环生成语句 设计100位二进制加法器

module top_module( 
    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 //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

100位BCD加法器

module top_module( 
    input [399:0] a, b,
    input cin,
    output cout,
    output [399:0] sum
);    
   genvar i;
    wire [99:0] cout_tmp;
   generate
       for(i=0;i<100;i++)begin:bcd_fadd
           if(i == 0)
               bcd_fadd u_bcd(a[3:0],b[3:0],cin,cout_tmp[0],sum[3:0]);
           else
               bcd_fadd u_bcd(a[4*i+3:4*i],b[4*i+3:4*i],cout_tmp[i-1],cout_tmp[i],sum[4*i+3:4*i]);       
       end       
   endgenerate        
endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Fighting_FPGA

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

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

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

打赏作者

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

抵扣说明:

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

余额充值