[2021-07-18]Verilog HDL syntax summary

Posted by DeepakJ on Sun, 16 Jan 2022 00:15:48 +0100

1. Introduction

The content of this article is my summary of the process of learning Verilog HDL grammar. My expectation is to write the content in detail, but as a beginner, it is inevitable to make mistakes or logical problems, so I will revise, adjust and supplement the content for a long time.

First, what is Verilog? Is a Hardware Description Language (HDL).

What does it describe? Describes a model of a digital circuit or digital system.

Personal understanding is to transform the model of digital circuit (or system) into the form of programming language and describe it.

What we compile is not just a program, but can be visualized. After the circuits are constructed one by one, they can be connected to realize the required functions together. (what we write may also be our dream)

In this, the model is also divided into many levels:

Model type corresponding to Verilog language
Description levelintroduce
1. System levelFollow up supplement
2. Algorithm levelFollow up supplement

3.RTL level (register transfer level)

Describes how to control and process the flow of various types of data between registers.

4. Gate level

Describe the connections between logic gates
5. Switch levelDescribe the connection between the triode and the storage node

The above 1 ~ 3 belong to behavior description. In 1 ~ 3, only RTL has a clear corresponding relationship with logic circuit.

Now it is clear that Verilog can describe the whole circuit system, using an inappropriate metaphor, just as we know that we can build a house with brick, cement, steel bar and concrete; The house is built one by one, layer by layer. The complex circuit system is based on modules, which cooperate to realize the functions one by one, and each module can be composed of a sub module.

Therefore, the module is briefly introduced in the next section.

2. block

My personal understanding: module is the basic unit to realize specific functions; I admit that this sentence looks like nonsense or an inappropriate metaphor. It's like building a house and building a new home for yourself with bricks and cement for life. At least your house needs to have kitchen, bedroom, living room, bathroom and so on.

How is the module defined in Verilog?

//Module definition module name
module <module name>(
        CLK,
        RSTB,
        ......
        DOUT);

input wire CLK;        //Clock
input wire RSTB;       //Reset falling edge valid

......

output wire DOUT;      //output signal


//parameter
parameter WIDTH=8;

//Module content
..................
..................

//Instantiation naming
example example_inst(
       .CLK(CLK),
       .RSTB(RSTB),
       .DOUT(DOUT)//

);

endmodule

I am currently in contact with modules such as adder, selector, trigger, decoder, FIFO, latch (this is used with caution), etc.

The following takes a selector as an example. Implementation functions:

The module has three inputs, in_1,in_2,sel

One output out

Input sel is 1 module out = in_1. Input value;

Input sel is 0, module out = in_2.

RTL file:

//Module start module name
module mux2_1
(   //Input / output list (note that each line is followed by a comma except at the end of the list)

    //Type data type [bit width] variable name,
	input wire [0:0] in_1, 	//input signal 1
	input wire 		 in_2,	//input signal 2
	input wire       sel ,	//select signal
	
	output reg       out	//output
    //Here, out ends directly with semicolon without comma
);
/*Define module method 2
module mux2_1(
        in_1,
        in_2,
        
        out
);
input wire [0:0] in_1; 	//input signal 1
input wire 		 in_2;	//input signal 2
input wire       sel;	//select signal

output reg       out;
*/

//Module content
//always indicates the block. The contents in the block are running all the time, followed by (*) indicates the trigger condition, that is, as long as the variables sel and out in the block are changed,
//The block statement is run
always@(*)
	if(sel == 1'b1)//Here is a simple judgment statement
		out = in_1;
	else 	
		out = in_2;
//The happy time is so short that the module is over
endmodule

Test_ The bench file implements the following functions:

The in in RTL file is given every 10us_ 1,in_ 2. SEL, assign a binary random number 0 or 1;

You can observe whether the out output strictly realizes the function through the joint simulation of quartus and modelsim

//Time scale unit time interval / time accuracy
`timescale 1us/1us
//Module start I / O list is empty
module tb_mux2_1();
//Define register type variables
reg		in_1;
reg 	in_2;
reg		sel;
//Define linetype variables
wire 	out;
//Initialization block. Note that this initial initialization stage can only be used for Test_bench is used for running simulation. It must not be written in rtl
initial
	begin
	in_1 <= 1'b0;
	in_2 <= 1'b0;
	sel  <= 1'b0;
	end
//The always block has no trigger condition, which means that it has been executed #10, indicating the delay of 10 * unit time interval 
// %2 means the remainder of dividing by 2 {$random}%2 means generating a random number and dividing by 2 for the remainder 
//                                Limit the generated random number < 2, i.e. 0 and 1
always  #10 in_1 <=	{$random} % 2;
always  #10 in_2 <=	{$random} % 2;
always  #10 sel  <=	{$random} % 2;
//
initial
	begin
	//            1e-9s	==  ns
		$timeformat(-6,0,"us",6);
    //$monitor (parameter list) is used to monitor and output the values of parameters
    //The writing method is similar to printf in C language.
		$monitor("@time %t:in_1 = %b sel=%b out=%b",$time,in_1,in_2,sel,out);
	end

//Instantiate the rtl file and test_ Connect variables between bench files,
//After connecting, you can pass test_bench file assigns value to the input in rtl file to test whether the module function can be realized
mux2_1	mux2_1_inst
(
	.in_1(in_1),	//input signal 1
	.in_2(in_2),	//input signal 2
	.sel(sel),		//select signal
	.out(out)	//output
);
//Module end
endmodule

The above code is learned from brother Bili bilishang wildfire FPGA. His video is very detailed. I attach the website at the end. If the above code or other content infringes, please contact me and I will delete it.

By the way, Mr. Lu Xun said: it's best to write only one module and one function in each file.

3. Constant, data type, operator

(1) Constant

1) digital

Representation

Binary integer: B or B

Octal integer: O or o

Decimal integer: D or D

Hexadecimal integer: H or H

Direct examples:

Bit width'Base system+number
//for example
8'b0001_0010;//The 8-bit binary number underline is for convenience and does not affect the actual value. It is equivalent to 8'b000010010
//Note that the underline can only be placed in the middle of the number part, such as 16'b0001_0000_0010_0100
//It cannot be placed between hexadecimal and digit, which is wrong, such as 8'b_00010000
8'h80;//8-bit hexadecimal number converted to binary 1000_ 0000;

2)x and z values

In digital circuits, x represents the indefinite value and z represents the high resistance state value.

I haven't used this yet, so I don't want to introduce it. I'll put it here first. If I get in touch with it later, I'll add it.

(2) Data type

As far as I've learned, the commonly used types are wire, reg and parameter. (if what I learned later involves other things, I will add)

1)wire type

Format:

wire [Bit width range] Variable 1,Variable 2;
//for example
wire [3:0] a,b;//Define two wire type variables A and b with a bit width of 4.
wire [0:0] c;//Define a wire type variable c with a bit width of 1.
wire       d;//Define a wire type variable d with bit width of 1.

 
  • wire data is mostly used to represent the assigned signal specified with the assign keyword;
  • In the module, if the input and output signals are not specially defined, the default is wire type;
  • wire type signal can be used as input of any equation, or as output of assign statement or instantiated component;
  • If the bit width is not specified, it defaults to 1.

2) reg type

Format 1:

reg [Bit width range] Variable 1, variable 2;
//for example
reg [4:1] a,b;//Define two reg variables A and b with a bit width of 4.
reg [0:0] c;//Defines a reg type variable c with a bit width of 1.
reg       d;//Defines a reg type variable d with a bit width of 1.

 
  • The initial value of reg data is x by default, i.e. an indefinite value.
  • reg data is mostly used to represent the assigned signal in the always block, often representing a trigger;
  • In the always block, each signal assigned must be of type reg;
  • If the bit width is not specified, it defaults to 1.

Format 2: used to define variables of memory type

reg [Bit width-1:0]  memory name  [depth-1:0];
For example:
parameter FIFO_WIDTH = 8;
parameter FIFO_DEPTH = 8;

reg [FIFO_WIDTH-1 : 0] FIFO [FIFO_DEPTH-1:0]; 

3) parameter type

parameter Parameter name=Parameter value;
//for example
parameter FIFO_DEPTH = 8;//Define FIFO_DEPTH is 8
parameter FIFO_WIDTH = 8;
  • parameter data is often used to define bit width, FIFO depth, and delay time

(3) Operator

1) arithmetic operator

Arithmetic operator (parameter a=8, parameter b=2)
SymbolUse exampleResult (decimal)describe
+a+b10Add
-a-b6subtract
*a*b16Multiply
/a/b4be divided by
%8%20Divide and remainder

2) assignment operator

Assignment operator (reg [3:0] a;wire [3:0] b;)
SymbolUse exampledescribe
=b = ablocking assignment
<=a <= b;nonblocking assignment

Blocking assignment:

  • After the assignment statement is executed, the block ends;
  • The value of b in the above table changes immediately after the assignment statement is executed;

For example:

wire a;
wire b;
//continuous assignment 
assign a = b;

Non blocking assignment:

  • In the statement block, the statement a < = B in the table; The value of a will not be changed immediately after assignment, which is used for subsequent statements in the block;
  • After the end of the block, the value of a will complete the copy operation, and the value of a will change;
  • This is the most commonly used assignment method when writing integrable sequential logic modules.

For example:

reg  [3:0] a;
reg  [3:0] b;
reg  [3:0] c;

always 
    begin
    a <= b;
    c <= a;
    end
/*
Make a chestnut:
Initial value
a = 4'b0001;
b = 4'b0010;
c = 4'b0100;

After executing the always statement block above
a = 4'b0010;
b = 4'b0010;
c = 4'b0001;
During execution, the value of a does not immediately change to the value of b, but continues with C < = a 
Assign the initial value 4'b0001 of a to c. similarly, the value of c will not change immediately at this time,
Instead, at the end of end, both a and c complete the assignment.
*/

3) relational operators

Relational operator
SymbolUse exampleResult (decimal)describe
>4>31greater than
<4<30less than
>=4>=31Greater than or equal to
<=4<=30Less than or equal to

Note that the less than or equal to the length here is the same as that in the non blocking assignment (< =), but the actual meaning is completely different.

In the use of relational operators, if the relationship is established, such as 4 > 3, it returns 1; if the relationship is not established, such as 4 < = 3, it returns 0;

It is often used in for loops. if judged, I haven't used it yet. if I have used it later, I will add it. For example:

integer   i;
reg       a;
reg [7:0] b;
for(i=0;i<8;i=i+1) a=b[i];

4) logical operators

Logical operator
SymbolUse exampleResult (decimal)describe
&&1&&11Logic and
||0||00Logical or
!!10Logical non

Truth table:

Logical operation truth table
aba&&ba||b!a!b
reallyreallyreallyreallyfalsefalse
reallyfalsefalsereallyfalsereally
falsereallyfalsereallyreallyfalse
falsefalsefalsefalsereallyreally

Note: as long as a is any integer that is not 0, it is true.

5) Bitwise operator

Bitwise Operators
SymbolUse exampleResult (decimal)describe
~~4'b01104'b1001Bitwise inversion
^4'b0010^4'b01004'b0110Bitwise XOR
^~4'b0010^~4'b01004'b1001Bitwise homor (XOR non)
&4'b1100&4'b01014'b0100Bitwise AND
|4'0010||4'b10104'b1010Bitwise OR

Truth table of inverse operator

~result
01
10
xx

Bitwise XOR truth table

^01x
001x
110x
xxxx
Bitwise identical or truth table
^~01x
010x
101x
xxxx
Bitwise and truth table
&01x
0000
101x
x0xx
Bitwise or truth table
|01x
001x
1111
xx1x

5) conditional operator

Judge true and false? Value 1: value 2 (judge true or false, return value 1, return value 2).

Take an example

//Here, if b is greater than c, a = 1, if b is less than or equal to c, a=0 
a = (b>c)? 1:0; 

6) equality operator

Equality operators
SymbolUse exampleResult (decimal)describe
==1==00be equal to
!=1!=01Not equal to
===1===11be equal to
!==1!==10Not equal to

The main difference between = = and = = = is in the judgment of uncertain value x and high resistance value z, as shown in the table below

==01xz
010xx
101xx
xxxxx
zxxxx
===01xz
01000
10100
x0010
z0001

7) shift operator

Let's give an example directly:

4'b0010 >> 1 = 4'b0001;
4'b0100 << 1 = 4'b1000;
4'b0101 << 2 = 5'b10100;
4'b0101 >> 4 = 4'b0000; 
1<<3 =32'b1000;//The default bit width is 32 bits.

8) splicing operator

Example above:

{a[0],b[2],a[2],b[1]}
//It is combined into a 4-bit wide number. The highest bit is the value of a[0], the second highest bit is the value of b[2], the second lowest bit is the value of a[2], and the lowest bit is the value of b[1]
{1'b0,1'b1,a[1],a[3]}
//Combine into a 4-bit wide number, the highest bit is 0, the second highest bit is 1, the second lowest bit is the value of a[1], and the lowest bit is the value of a[3] 
{5{1'b1}}
//Combine into a 5-bit wide number 5'b11111
{4{a[1]}}
//Combine into a 4-bit wide number. All 4 bits are the value of a[1]

9) index

For example:

2**2 //The second power of 2
2**3 //the cube of 2

10) reduction operator

//The reduction operator symbol is the same as the bit operator symbol
&1001 // Equivalent to ((1 & 0) & 0 & 1) = 0
|1001 // Equivalent to ((1|0) |0) |1 = 1
^0111 //Equivalent to ((0 ^ 1) ^ 1) ^ 1 = 1

11) operator prioritization

Generally speaking, the priority is sorted by monocular operator > binocular operator > ternary operator.

What are monocular, binocular and tricular? A singleton is an operand of 1, such as ~a,! a. ^ A, similarly, if the operand is 2, it is binary. For example, a & & B, there should be only?:.

For priority segmentation, from top to bottom, the highest to the lowest:

!    ~
/   *   %
+    -
<<    >>
>=    >    <    <=
==    !=    ===    !==
&
^    ^~
|
&&
||
?:

4. Common keyword block statement generation block (to be continued)

(1)always

(2)initial

(3)assign

(4) Input / output, rising edge, falling edge

(5) Block statement

(6) Generating block

reference resources:

Verilog digital system design tutorial (3rd Edition) compiled by Xia Yuwen

[wildfire] FPGA series teaching video, real hand-in-hand teaching,

Topics: Verilog