Wednesday, July 1, 2009

Topic #1 (Part 2): HDL - Verilog

When someone is introduced to HDL the common question of "which variant should I choose?" comes up. Verilog and VHDL have a lot of similarities and differences, these differences may make this question simple to answer. Verilog is a variant of HDL that was designed to cater towards people with a background in C, the syntax and keywords are very familiar with only slight differences. If a person was tasked with creating a D register (flip flop) in Verilog, this would be the corresponding code:

module dff(clk,d,q,qn);
input clk, d;
output q, qn;

reg q=0;
reg qn=1;

always @(posedge clk)
begin
q<=d; qn<=~d; end endmodule
The resulting simulation:

When analyzing this code line by line we first see the "module" statement. A module is similar to a function in C where once the function has been properly defined it can later be using in other projects to perform a specific task. After the name of the module (dff was used as the name since this is a D flip flop module) we list the inputs and outputs. These I/Os can be listed in any order. Notice also that statements, just like in C, are terminated with semicolons.

The following two statements, define whether each port is an input port, an output port, or an inout port ("inout" is rarely used).

The next two statements define q and qn (the data output and the inverted data output port) as registers. There are two primary variable types that can be used, reg and wire. A variable of type register, can be updated at specific events. A register can also be defined as an array of values. For instance:

reg [7:0] counter;

This statement would define a register called counter with an 8-bit depth thus giving it 256 unique values. Uses of arrays will be discussed later. A "wire" by definition can only be a single bit as it attempts to replicate the function of a physical wire (meaning at any point in time a wire can only contain one physical value). Unlike the reg the wire does not make use of the assignment operator "<=", a wire uses the keyword "assign" and the "=" operator. The difference between these two are very important when considering timing. HDL has two methods of statement execution: sequential and concurrency. Sequential statements just as the name describes executes statement sequential in the order they appear in the code. Although you can write a lot of code sequentially, it is actually not synthesize-able. Concurrent statements are statements that occur at the end of a clock cycle. The interesting and painful part of concurrency is that you don't necessarily know which register was updated first. Because of this, it is impossible to physically realize a module that updates a register more than once at any point in time. This may sound obvious to most, but from the standpoint of someone with C programming, where sequential statements are the only option. Looking back at the snippet of code, the next statement shows one possible way to control when a register is updated. The "always" keyword says to always perform the following statement(s) "at" (denoted as @) some event.
The "begin" and "end" keywords are Verilog's way to encapsulate multiple statements that are to follow the event rule.

Well, this is it for now. I will give an identical example using VHDL

No comments:

Post a Comment