HDLBits 系列(3)——Verilog Language(More Verilog Features)

目录

2.5 More Verilog Features

1.Conditional ternary operator

2.Reduction operators

3.Reduction: Even wider gates

4.Combinational for-loop: Vector reversal 2

5.Combinational for-loop: 255-bit population count

6.Generate for-loop: 100-bit binary adder 2

7.Generate for-loop: 100-digit BCD adder


2.5 More Verilog Features

1.Conditional ternary operator

Verilog has a ternary conditional operator ( ? : ) much like C:

(condition ? if_true : if_false)

This can be used to choose one of two values based on condition (a mux!) on one line, without using an if-then inside a combinational always block.

Examples:

(0 ? 3 : 5)     // This is 5 because the condition is false.
(sel ? b : a)   // A 2-to-1 multiplexer between a and b selected by sel.

always @(posedge clk)         // A T-flip-flop.
  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 Bit of Practice

Given four unsigned numbers, find the minimum. Unsigned numbers can be compared with standard comparison operators (a < b). Use the conditional operator to make two-way min circuits, then compose a few of them to create a 4-way min circuit. You'll probably want some wire vectors for the intermediate results.

module top_module (
    input [7:0] a, b, c, d,
    output [7:0] min);//

    // assign intermediate_result1 = compare? true: false;
    assign min=a<b?(a<c?(a<d?a:d):(c<d?c:d)):(b<c?(b<d?b:d):(c<d?c:d));

endmodule

2.Reduction operators

You're already familiar with bitwise operations between two values, e.g., a & b or a ^ b. Sometimes, you want to create a wide gate that operates on all of the bits of one vector, like (a[0] & a[1] & a[2] & a[3] ... ), which gets tedious if the vector is long.

The reduction operators can do AND, OR, and XOR of the bits of a vector, producing one bit of output:

& 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]

These are unary operators that have only one operand (similar to the NOT operators ! and ~). You can also invert the outputs of these to create NAND, NOR, and XNOR gates, e.g., (~& d[7:0]).

A Bit of Practice

Parity checking is often used as a simple method of detecting errors when transmitting data through an imperfect channel. Create a circuit that will compute a parity bit for a 8-bit byte (which will add a 9th bit to the byte). We will use "even" parity, where the parity bit is just the XOR of all 8 data bits.

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

3.Reduction: Even wider gates

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=&in;
         assign out_or=|in;
         assign out_xor=^in;
        
    endmodule

4.Combinational for-loop: Vector reversal 2

Given a 100-bit input vector [99:0], reverse its bit ordering.

module top_module( 
    input [99:0] in,
    output [99:0] out
);
    
generate
    genvar i;
    for (i=0;i<100;i=i+1)begin:reverse
        assign out[99-i]=in[i];
    end
endgenerate
    
endmodule

5.Combinational for-loop: 255-bit population count

A "population count" circuit counts the number of '1's in an input vector. Build a population count circuit for a 255-bit input vector.

module top_module( 
    input [254:0] in,
    output [7:0] out );
	integer i;
    reg [7:0]count;
    always@(*)begin
        count = 1'b0;
        for(i=0;i<255;i=i+1)begin
            if (in[i])
                count=count+1'b1;
            else 
               count=count; 
        end
    end
    assign out=count;
    
endmodule

6.Generate for-loop: 100-bit binary adder 2

Create a 100-bit binary ripple-carry adder by instantiating 100 full adders. The adder adds two 100-bit numbers and a carry-in to produce a 100-bit sum and carry out. To encourage you to actually instantiate full adders, also output the carry-out from each full adder in the ripple-carry adder. cout[99] is the final carry-out from the last full adder, and is the carry-out you usually see.

module top_module( 
    input [99:0] a, b,
    input cin,
    output [99:0] cout,
    output [99:0] sum );
    
   integer i;
    always@(*)begin
        
        for (i=0;i<100;i=i+1)begin
            if (i==0)begin
                 sum[0]=cin^a[0]^b[0];
                 cout[0]=(cin&a[0] )| (cin&b[0]) | (a[0]&b[0]);
            end
            else begin
                sum[i]=cout[i-1]^a[i]^b[i];
                cout[i]=(cout[i-1]&a[i] )| (cout[i-1]&b[i]) | (a[i]&b[i]);
            end
        end 
    end
      
endmodule

7.Generate for-loop: 100-digit BCD adder

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 );
    
    wire [99:0]count1;
    
generate 
    genvar i;
    for (i=0;i<100;i=i+1)begin:add
        if (i==0)begin
            bcd_fadd bcd_fadd_1(
                .a(a[3:0]),
                .b(b[3:0]),
                .cin(cin),
                .cout(count1[0]),
                .sum(sum[3:0])
                );
        end
        else begin
             bcd_fadd bcd_fadd_2(
                 .a(a[4*i+3:4*i]),
                 .b(b[4*i+3:4*i]),
                 .cin(count1[i-1]),
                 .cout(count1[i]),
                 .sum(sum[4*i+3:4*i])
                );
        end
    end
    assign cout=count1[99];
    
endgenerate

         
endmodule

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Bronceyang131

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

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

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

打赏作者

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

抵扣说明:

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

余额充值