FPGA learning - HDLBits website brushing notes sorting

More features of Verilog

Ternary conditional operator

For conditional expression b? x: y, calculate condition b first, and then judge. If the value of b is true, calculate the value of x, and the operation result is the value of x; Otherwise, the value of Y is calculated and the operation result is the value of Y. A conditional expression never evaluates both x and y.
There is a ternary conditional operator in Verilog, much like C language, which can be used to select one of the two values according to the condition in one line instead of using if then in the combined always block.
Title: given four unsigned numbers, find the minimum. Unsigned numbers can be compared with standard comparison operators (a < b).
answer:

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

Reduction operator

The unary operator is equivalent to the unary operator in C. It performs a bit operation on an operand and finally gets a one bit number.
The process of reduction operation is that in the first step, the first and second bits of the operand are used for bit operation, and then the result of the first step and the next bit of the operand are used.
Carry out bit operation, and repeat until the last bit.
The reduction operators in Verilog include reduction and (&), reduction and non (~ &), reduction or (|), reduction or non (~ |), reduction XOR (^), reduction same or (~ ^)

We are already familiar with bit operations between two values, such as a & B or a^b. Sometimes, you need to create a wide gate that operates on all bits of a vector, such as (a [0] & A [1] & A [2] & A [3]...), which will be boring if the vector is very long.
The reduction operator can perform AND, OR AND XOR operations on the bits of the vector to produce a bit 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 with only one operand (similar to the NOT operator!). You can also reverse the output of these gates to create NAND, NOR, and XNOR gates, for example (~ & amp; d [7:0])

Similarities and differences between reduction operator and bit operator:
Similarities:
1) These operators use the same symbols as bitwise operators.
2) The logical operation results follow the same operation rules.
3) There are only three basic operators &, |, ^, and the others are composed of negations based on these three operators, such as~&
difference:
1) Bit operations are binary operators and reduction operators are unary operators.
2) The operation result of bit operator can be one bit wide or multiple bit wide (vector operation), while the reduction operator only has the operation result of one bit wide.

Combining for loops: vector flipping

Title: given a 100 bit input vector, flip its bit order.
answer:

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

Combined for loop: 255bit count

Title: "counting" circuit counts 1 in the input vector. Establish a "count" circuit for a 255 bit input vector.
answer:

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

Generate loop statement

The generate statement in Verilog is often used to write the design structure of configurable and comprehensive RTL. It can be used to create multiple instantiations of modules or conditionally instantiated code blocks.
1)generate loop structure
The syntax of the generate loop is very similar to that of the for loop statement. However, the index variable name used in the loop must be declared in the genvar declaration before it can be used. The index variable declared by genvar is used as an integer to judge the generate loop. The genvar declaration can be an internal or external region of the generate structure, and the same loop index variable can be in multiple generate loops as long as these loops are not nested. Genvar only appears when modeling, and has disappeared when simulating.
2) Conditional if generate construct
The conditional statement selects at most one generate block from many alternative blocks. Please note that I am talking at most here, because there may be none. In modeling, the condition must be a constant expression.
The conditional if generate does not care whether it is named or not, and may not have begin / end. Of course, only one of the above two conditions can be included. It also creates separate scope and hierarchy levels, which is the same as the generate loop. Since at most one code block is selected, it is legal to name all alternate code blocks with the same name in a single if generate, and this helps to maintain hierarchical references to the code. However, different generate constructs must have different names.
3) Conditional case generate construction
Similar to if generate, case generate can also be used to conditionally select a code block from several blocks. Its usage is similar to the basic case statement, and all the rules in if generate also apply to the case generate block.

Topic 1: create a 100 bit binary traveling wave carry adder by instantiating 100 full adders. The adder adds two 100 bit numbers and a carry to produce a 100 bit sum and executes it.
answer:

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

Topic 2: we provide you with a BCD_fadd's BCD one bit adder adds two BCD numbers and performs carry, and then generates a sum and performs carry.

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

Instantiate BCD_ 100 copies of FADD to create a 100 bit BCD traveling wave carry adder.
answer:

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

The above is the More Verilog Features section of HDLBits Verilog language question brushing website, and the subsequent sections will continue to be updated. Summarize some basic knowledge points. Please correct any mistakes. For learning reference only, thank you!!!

Added by bugsuperstar37 on Thu, 20 Jan 2022 11:26:57 +0200