Verilog-HDLBits1

位运算符

~   按位取反
&   按位与
|   按位或
^   按位异或
^~  按位同或(异或非)

除了对变量的具体位做运算,也可对整个变量进行操作,相当于将变量的每一位加到相同的与或异或同或门上

例:HDLBits 39 Gates100 要求对100位的输入建立与、或、异或门,此时可通过位运算符对整个变量作用来实现功能。

/*
Build a combinational circuit with 100 inputs, in[99:0].
There are 3 outputs:
out_and: output of a 100-input AND gate.
out_or: output of a 100-input OR gate.
out_xor: output of a 100-input XOR gate.
*/

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

位拼接运算符

{}
{}={}

在进行向量拼接并进行赋值时,只需保证两边的位长相等即可,括号中的变量不需要一一对应

例:HDLBits 17 vectorr 要求对8位输入翻转输出,则左侧括号需要写出全部从0~7位(逆序),右侧(正序)则直接放上变量即可

/*
Given an 8-bit input vector [7:0], reverse its bit ordering.
*/

module top_module( 
    input [7:0] in,
    output [7:0] out
);
    // this is fine, but the one below is better
    // assign {out[7],out[6],out[5],out[4],out[3],out[2],out[1],out[0]}=
    // {in[0],in[1],in[2],in[3],in[4],in[5],in[6],in[7]};
    assign {out[7],out[6],out[5],out[4],out[3],out[2],out[1],out[0]}=in;
endmodule

此外,在进行复制操作时,每个部分都需要用额外的括号包裹,如把三个in的最高位和三个in连接:

{  {3{in}},3{in[7]}  }

或非和异或

{}
{}={}

或非是NOR,或后取反,只有全0才为1

或非门

异或是XOR,相同为0,不同为1

异或门也可以实为一个特殊的数据选择器——在控制信号为1时对原数据取反

异或门

 阻塞与非阻塞复制

在Bits30 alwaysblock2的中:

There are three types of assignments in Verilog:

  • Continuous assignments (assign x = y;). Can only be used when not inside a procedure ("always block").
  • Procedural blocking assignment: (x = y;). Can only be used inside a procedure.
  • Procedural non-blocking assignment: (x <= y;). Can only be used inside a procedure.

In a combinational always block, use blocking assignments. In a clocked always block, use non-blocking assignments. A full understanding of why is not particularly useful for hardware design and requires a good understanding of how Verilog simulators keep track of events. Not following this rule results in extremely hard to find errors that are both non-

deterministic and differ between simulation and synthesized hardware.

  • 不可在always块中用assign赋值
  • always中,组合逻辑用阻塞赋值(大概是always的条件是*?);在时序逻辑(大概是always由clk驱动?)用非阻塞赋值

用generate实例化模块

5.2 Verilog 模块例化 | 菜鸟教程 (runoob.com)

当例化多个相同的模块时,一个一个的手动例化会比较繁琐。用 generate 语句进行多个模块的重复例化,可大大简化程序的编写过程。

重复例化 4 个 1bit 全加器组成一个 4bit 全加器的代码如下:

module full_adder4(
    input [3:0]   a ,   //adder1
    input [3:0]   b ,   //adder2
    input         c ,   //input carry bit
 
    output [3:0]  so ,  //adding result
    output        co    //output carry bit
    );
 
    wire [3:0]    co_temp ;
    //第一个例化模块一般格式有所差异,需要单独例化
    full_adder1  u_adder0(
        .Ai     (a[0]),
        .Bi     (b[0]),
        .Ci     (c==1'b1 ? 1'b1 : 1'b0),
        .So     (so[0]),
        .Co     (co_temp[0]));
 
    genvar        i ;
    generate
        for(i=1; i<=3; i=i+1) begin: adder_gen
        full_adder1  u_adder(
            .Ai     (a[i]),
            .Bi     (b[i]),
            .Ci     (co_temp[i-1]), //上一个全加器的溢位是下一个的进位
            .So     (so[i]),
            .Co     (co_temp[i]));
        end
    endgenerate
 
    assign co    = co_temp[3] ;
 
endmodule

在HDLBits43  Bcdadd100中,需要实例化100个模块

You are provided with a BCD one-digit adder named bcd_fadd that adds two BCD digits and carry-in, and produces a sum and carry-out.

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

Instantiate 100 copies of bcd_fadd to create a 100-digit BCD ripple-carry adder. Your adder should add two 100-digit BCD numbers (packed into 400-bit vectors) and a carry-in to produce a 100-digit sum and carry out.

module top_module( 
    input [399:0] a, b,
    input cin,
    output cout,
    output [399:0] sum );
    
    generate
        genvar i;
        wire[99:0] cout0;
        for (i = 0;i < 100;i++ ) begin:bcd_fadd
            if(i == 0)begin
                bcd_fadd b_f1(.a(a[3:0]),.b(b[3:0]),.cin(cin),.cout(cout0[0]),.sum(sum[3:0]));
            end
            else begin
                bcd_fadd b_f2(.a(a[4*i+3:4*i]),.b(b[4*i+3:4*i]),.cin(cout0[i-1]),.cout(cout0[i]),.sum(sum[4*i+3:4*i]));
            end
        
        end
        assign cout = cout0[99];
    endgenerate
  
        
endmodule
/*这里因为是相当于100个4位加法器进行相加,因而中间进位产生了一个100位的进位情况;这里面是采用generate块的使用。这个方法要学会使用*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值