How does a company create a programmable device using an ASIC process?
The basis of any ASIC technology is the transistor, with the largest devices holding up to a billion. There are multiple ASIC processes that have been developed over the years, and they all rely on 0s and 1s, in other words, on or off transistors. These on or off transistors can be thought of as Booleans, true or false values.
The basis of Boolean algebra was developed by George Bool in 1847. The fundamentals of Boolean algebra make up the basis of the logic gates upon which all digital logic is formed. The code that we will be writing will be at a fairly high level, but it is important to understand the basics and it will give us a good springboard for a first project.
Fundamental logic gates
There are four basic logic gates. We typically write the truth tables for the gates to understand their functionality. A truth table shows us what the output is for every set of inputs to a circuit. Refer to the following example involving a NOT
gate.
Important note
In this section, we are primarily discussing only the logical functions. There are equivalent bitwise functions that will be introduced. Logical functions are typically used in if
statements, bitwise functions in logic operations.
Assign statement
In SystemVerilog
, we can use an assign
statement to take whatever value is on the right-hand side of the equal sign to the left-hand side. Its usage is as follows:
assign out = in;
in
can be another signal, function, or operation on multiple signals. out
can be any valid signal declared prior to the assign
statement.
Comments
SystemVerilog
provides two ways of commenting. The first is using a double slash, //
. This type of comment runs until the end of the line it's located on. The second type of comment is a block comment. Both are shown here:
// Everything here is a comment./* I can span Multiple Lines */
if statement
SystemVerilog
provides a way of testing conditions via the if
statement. The basic syntax is as follows:
if (condition) event
We will discuss if
statements in more detail in Chapter 2, Combinational Logic.
Logical NOT (!)
The output of the NOT
gate produces the inverse of the signal going in. The function in SystemVerilog
can be written as follows:
assign out = !in; // logical or boolean operator
The associated truth table is as follows:
The NOT
gate is one of the most common operators we will be using:
if (!empty) ...
Often, we need to test a signal before performing an operation. For example, if we are using a First in First Out (FIFO) storage to smooth out sporadic data or for crossing clock domains, we'll need to test whether there is data available before popping it out for use. FIFOs have flags used for flow control, the two most common being full and empty. We can do this by testing the empty flag, as shown previously.
We will go into greater depth in later chapters on how to design a FIFO as well as use one.
Logical AND (&&), bitwise AND (&)
Often, we will want to test whether one or more conditions are active at the same time. To do this, we will be using the AND
gate.
The function in SystemVerilog
can be written as follows:
assign out = in1 && in0; // logical or boolean operator
The associated truth table is as follows:
Continuing our FIFO example, you might be popping from one FIFO and pushing into another:
if (!src_fifo_empty && !dst_fifo_full) ...
In this case, you want to make sure that both the source FIFO has data (is not empty) and that the destination is not full. We can accomplish this by testing it via the if
statement.
Logical OR (||), bitwise OR (|)
Another common occurrence is to check whether any one signal out of a group is set to perform an operation.
The function in SystemVerilog
can be written as follows:
assign out = in1 || and in0; // logical or boolean operator
The associated truth table is as follows:
Next, we will look at the exclusive OR
function.
XOR (^)
The exclusive OR
function checks whether either one of two inputs is set, but not both. The function in SystemVerilog
can be written as follows:
assign out = in1 ^ and in0; // logical or boolean operator
The associated truth table is as follows:
This function is used in building adders, parity, and error correcting and checking codes. In the next section, we'll look at how an adder is built using the preceding gates.
More complex operations
We've looked at the basic components in the previous sections that make up every digital design. Here we'll look at an example of how we can put together multiple logic gates to perform work. For this we will introduce the concept of a full adder. A full adder takes three inputs, A, B, and carry in, and produces two outputs, sum and carry out. Let's look at the truth table:
The SystemVerilog
code for the full adder written as Boolean logic would be as follows:
assign Sum = A ^ B ^ Cin; assign Cout = A & B | (A^B) & Cin;
You'll notice that we are using the bitwise operators for AND (&) and OR (|) since we are operating on bits. From this straightforward, yet important example, you can see that real-world functionality can be built from these basic building blocks. In fact, all the circuits in an ASIC or FPGA are built this way, but luckily you don't need to dive into this level of detail unless you really want to thanks to the proliferation of High-Level Design Languages (HDLs), such as SystemVerilog
.