Introduction to FPGA with Verilog

Roshanmaharana
12 min readApr 8, 2020

--

Field Programmable Gate Array which is abbreviated as FPGA is an Integrated Circuit(IC) that can be programmed even after their manufacture. That means their gate array circuitry is reconfigurable.

Talking in Electronics terms, they can be thought as a giant connection of various Digital Circuits like gates, flip-flops,etc.

Other hard-wired Printed Circuit Boards(PCB), which have fixed hardware resources and i.e, each logical element is fixed(e.g. the apace assigned to AND gate will function only as AND gate and not any other gate).

But FPGAs can literally rewire the entire circuitry based on the requirement and hence can reconfigure the Digital Logic. That means the space assigned to AND gates can be changed to any other gate based on the requirement of the given Digital Logic.

The implementation of the Digital Logic is done via programming.

The programming of FPGAs are done in a specially designed languages called Hardware Description Language.

The conventional programming languages like C or C++ whose modified versions can be used to program the microcontrollers can only send a certain instruction to chip and not change the logic inside the chip.

HDLs have the capability to literally design the circuit as per the requirement and then again change the circuitry by reconfiguring the logical elements via programming.

A single FPGA can replace thousands of discrete components by incorporating millions of logic gates in a single integrated circuit (IC) chip.

Currently there are two key players in the FPGA industry namely Xilinx and Altera by Intel.

Internal Structure of FPGA

Internal Structure of FPGA
Fig 1: Internal Structure of FPGA

FPGA consists of 3 major components

  1. Programmable Logic Blocks(PLB)
  2. Programmable Input/Output(I/O) block
  3. Programmable Interconnects

Programmable Logic Blocks are the components responsible for implementing core logic functions. The Logic Block in Xilinx based FPGAs are called as Configurable Logic Blocks or CLB while the similar structures in Altera based FPGAs are called Logic Array Blocks or LAB. These logic blocks also contribute to the storage functionalities of the FPGA. The basic logic block can be anything like a transistor, a NAND gate, Multiplexers, Look-up Table (LUT) or even processors. Both Xilinx and Altera use Look-up Table (LUT) based logic blocks to implement the logic as well as the storage functionalities.

Fig 2: A simple logic block

Programmable I/O block is used to bring signals onto the chip and send them back off again. These are used to interface the logic blocks and routing architecture to the external components. The I/O pad and the surrounding logic circuit form as an I/O cell. It consists of an input buffer and an output buffer with three-state and open collector output controls.

Fig 3: A simple I/O block

Programmable Interconnects or Routing establishes a connection between logic blocks and Input/Output blocks to complete a user-defined design unit. Routing in FPGAs consists of wire segments of varying lengths which can be interconnected via electrically programmable switches. Density of logic block used in an FPGA depends on length and number of wire segments used for routing. It consists of multiplexers pass transistors and tri-state buffers. Pass transistors and multiplexers are used in a logic cluster to connect the logic elements.

Fig 4: Interconnect network

Combined structure of FPGA

Fig 5: Internal Structure of an FPGA when all the components are put together

Look Up Tables(LUT)

From a superficial point of view, it seems that FPGA consists of combination of AND gates, OR gates and the others.

But actually they aren’t physically present rather the Logic Blocks are programmed to make them behave like those.

This process of making the ConfigurableLogic Blocks to behave like those primitive gates are achieved through Look Up Tables (LUT).

The LUT in an FPGA holds a custom truth table, which is loaded when the chip is powered up.

A Look-Up Table is a discrete block of functionality that can be programmed by the Digital Designer.

You can even think of your custom Lookup Table or LUT as a small piece of RAM that is loaded whenever you power up your FPGA chip. It defines and directs the behavior of the combinatorial logic of your chip based on your VHDL or Verilog code, referring to the predetermined values to produce the desired results.

This means that the inputs you put into the Lookup Table are basically the address lines for a one bit wide RAM cell.

Fig 6: A block diagram of a LUT

So, we can conclude that the Lookup Tables basically serve to act like logic gates in various combinations. Instead of having to connect a number of different NAND and NOR gates, you can simply use a Lookup Table to get all the possible combinations.

Programming the FPGA

Types of Hardware Description Languages

  1. Verilog
  2. VHDL
  3. SystemVerilog
  4. MyHDL

But as per the scope of this article, we will be limiting ourselves to Verilog even though you can carry out the similar circuits in other HDL as well. But out of the above, Verilog and VHDL are widely used.

VHDL vs Verilog

Fig 7: VHDL vs. Verilog Google Searches By Country: July 2013 to July 2014(Courtesy- nandland.com)

Note: Before going for programming the FPGA, you should have a good foundation on Digital Circuit Design. Also familiarity with a programming language like C will be useful as we would be comparing the operations of C with Verilog.

Verilog HDL

Verilog, standardized as IEEE 1364, is a hardware description language (HDL) used to model electronic systems.

It was created by Prabhu Goel, Phil Moorby and Chi-Lai Huang and Douglas Warmke between late 1983 and early 1984.

Verilog is a portmanteau of the words “verification” and “logic”.

Before jumping to actual programming, we need to familiarize ourself with certain types of modelling in the Digital System Design and we will be going through each modelling with the respective Verilog code.

The types of modelling are as follows:

  1. Dataflow Modelling
  2. Hierarchical Modelling
  3. Structural level Modelling
  4. Switch level Modelling (Special/Auxiliary type)

Before going towards the basic codes of the above kinds of modelling, let us understand the syntax and the programming structure of Verilog HDL

Below is the structure in which Verilog is written

Fig 8: module declaration in Verilog

A module is a block of Verilog code that implements a certain functionality.

Here is place where you can write the code to design your desired circuit by programming the logic blocks.

Modules can be compared with main class in Java within which your entire program is written.

But unlike Java and other Object Oriented Programming Languages, when we talk of Verilog then we cannot define a module inside another module. In short, nested modules are not allowed in Verilog.

We can use conditional blocks like if-else, switch and ternary conditional operators. Even loop constructs are supported.

But we can call one module inside another. In this case the module inside which another module is declared then that forms the higher module and the other forms the lower module.

Inside the code if we come across a case where the output of one logic element forms the input of another then we call that element as a wire.

For storing any random values that are to be used for testing, then we make use of the element called reg.

Verilog is case-sensitive.

As we got a gist of the programming in Verilog let us understand the different types of modelling.

Dataflow Modelling

Dataflow Modelling is the kind of modelling where we design the circuit by using the Boolean expression.

This kind of modelling is carried out with the help of operators in Verilog.

Consider two inputs ‘a’ and ‘b’ and their respective output as ‘y’ then

y=a&b carries out Logical AND operation

y=a|b carries out Logical OR operation

y=!a carries out Logical NOT operation

y=a^b carries out Logical XOR operation

y=!(a&b) carries out Logical NAND operation

y=!(a|b) carries out Logical NOR operation

y=!(a^b) carries out Logical XNOR operation

All the above operations are done bitwise!

COMMENT LINES

// is used for single line comments

/*Multi line

Comments*/

Note: “/*” and “*/” comes in pairs and they also can’t be nested.

CODING

Now in case we need to implement a simple operation of an AND gate, let us see how we do it in Verilog.

Consider the Boolean Expression: y=a.b

module and_gate(input a,b,output y);

y=a&b;

endmodule

Simple. Isn’t it?

Let’s jump over to hierarchical modelling

Hierarchical Modelling

Hierarchical Modelling is the kind of modelling where we design the circuit by using the truth-table of the given logic.

This type of modelling is achieved by using conditional statements.

Conditional statements are of 3 types:-

  1. if-else statement
  2. case statement
  3. Ternary operator

Before writing the conditional statements, it is very much essential to include an always@ block.

The always@ blocks are used to describe events that should happen under certain conditions. always@ blocks are always followed by a set of parentheses, a begin, some code, and an end.

The always@( * ) blocks are used to describe Combinational Logic, or Logic Gates.

Only = (blocking) assignments should be used in an always@( * ) block.

Only use always@( * ) block when you want to infer an element(s) that changes its value as soon as one or more of its inputs change.

Let us see the skeleton of each of these conditional operators

if-else

The if-else condition in Verilog is similar to what we use in C when we speak of execution but there is a slight change in syntax(given below)

if(<condition>)

begin

N-lines of code(logic)

end

else

begin

N-lines of code(logic)

end

Isn’t the if-else construct similar to what we have done in C?

Just like in C, in Verilog also we can do nested if operation.

Similar to if-else in C

case

The case in Verilog also works in similar way like C except it doesn’t have a break statement for termination of the block execution.

Similar to the switch operations in C, in Verilog as well the case is used for checking equality conditions except in Verilog after checking the equality condition and executing the code inside that particular case, it breaks automatically and no usage of a break statement is required.

Similar to C, case statement also uses default keyword so that if cases other than the mentioned ones are false then default will be executed.

The syntax is shown below:

case(<variable>)

begin

<case 1>: begin <lines of code> end

<case 2>: begin <lines of code> end

default: begin<lines of code> end

end

endcase

Ternary operator

The ternary operator is an operator that takes three arguments.

The first argument is a comparison argument, the second is the result upon a true comparison, and the third is the result upon a false comparison.

The execution of the ternary operator in Verilog is similar to that in C with its syntax given below:-

y= a ? b : c

Explanation

If condition a is True then y=b else y=c.

As we have had a basic understanding on all the conditional operators, let us see an example in a code by the illustration of AND gate. In this process, we would learn how to write a code of an AND gate in Hierarchical Modelling eventhough we know how to write it in Dataflow Modelling.

So in order to write a code of an AND gate in Hierarchical Modelling, we need to know the truth table before we proceed to write its code.

The truth table for an AND gate is given below:-

Fig 9: TRUTH TABLE for a 2-input AND gate

module and_gate(input a,b,output y);

always@(*)

begin

if(a==1'b1 && b==1'b1)

y=1'b1;

else

y=1'b0;

end

endmodule

In the above code in a==1'b1 implies that if the value of a is 1 or not where b stands for bit and the number preeceeding b stands for the number of bits(n) and the number following b is the value of that n-bit binary number.

In general it is denoted as:

y = n’b<…n bit binary number….>

E.g. y=3'b111; //this means y is a 3 bit number with value 7 in binary.

So the above code for the AND gate is very simple to understand if we understand the truth table. The output(y) is 1 when both inputs(a & b) are 1 else the output(y) is 0.

Now let’s understand structural modelling.

Structural Modelling

Structural Modelling is the kind of modelling where we design the circuit by using the Logic Diagram of a given logic.

As we will be using gates to implement this kind of modelling in our code, it is also called Gate-Level Modelling.

Before going to the programming, let us see the various types of gates.

There are primarily 2 types of gates

  1. Primitive Gates
  2. Non-primitive Gates

Primitive Gates

Primitive Gates are the fundamental gates that are provided by Verilog or are in-built in the Verilog platform.

The Primitive Gates in Verilog are AND, OR, NAND, NOR, XOR, XNOR, NOT, BUFFER.

Fig 10: Syntax of writing primitive gates

Note that the type of gate should be in lowercase while the name of the gate can be in uppercase and in general can be given as:

<gate type> gate_name(<output variable>,<input variable>);

Non-primitive Gates

The non-primitive gates are the type of gates that are made by the designer using the primitive gates.

Fig 11

The above diagram explains the concept of non-primitive gates very clearly. The 4 bit Ripple Carry Adder consists of 4 one-bit Full Adders which are connected with each other to give the desired results.

The Full Adders(FA) arethe non primitive gate which consists of the primitive gates.

Fig 12: 1- BIT FULL ADDER

If we see the internal structure of the full adder, it consists of AND,OR and XOR gates which are the primitive gates.

The syntax for writing the non-primitive gates is a little bit different.

Consider the example of the 4-bit ripple Carry Adder in Fig 11. For example we have to write the code for Full Adder A where A0, B0 and C0 are inputs and S0 and C0 are outputs, then we can write by the following way:

full_adder A(A0,B0,C0,S0,C0);

One important point to note is that the full_adder module should be declared and the logic should have been written else the code won’t execute.

Another important point to note is that the variables you are declaring in the order in your lower module, should have the same order in the higher module else the code won’t work properly.

As we are done with the type of gates let us see an illustration via code.

Let us take the same example of the AND gate that we have done for both Dataflow and Hierarchical Modelling.

In order to carry out Structural Modelling, we need to have the logic diagram.

Fig 13: AND gate

The code for the above AND gate can written in the following way:

module and_gate(input A,B,output Y);

and a1(Y,A,B);

endmodule

Simple. Isn’t it?

Switch-Level Modelling

This kind of modelling uses CMOS circuits for the design of the circuit.

In order to understand this circuit, it is very much essential to have a base in CMOS VLSI Design. But as per the scope of this article, sticking to the introduction to Verilog, this type of Modelling is not necessary as this itself would take a lot of articles to explain. So as of now this part is skipped. In future, articles on this topic might be published.

After going through all kinds of modelling, one might raise the question on where to use what kind of modelling.

Practically we can use all kinds of modelling for writing the code.

But which kind of modelling will be suitable for the given design is upto the designer’s choice. For example, if a given problem has a complex boolean expression but a simple truth table, then hierarchical modelling is employed.

As we are done with the basics, let us apply our knowledge by implementing simple adder circuits.

HALF ADDER

Fig 14: Half Adder

module half_adder(input A,B,output S,C);

xor X1(S,A,B);

and A1(C,A,B);

endmodule

FULL ADDER

Fig 15: Full Adder

module full_adder(input A,B.Cin,output S,Cout);

wire W1,W2,W3;

xor X1(W1,A,B);

xor X2(S,W1,Cin);

and A1(W2,W1,Cin);

and A2(W3,A,B);

or O1(Cout,W2,W3);

endmodule

Hope you enjoyed it. Have a nice day!

--

--