Let’s start with a quick introduction to writing Verilog code. Admittedly, we already did take a quick look at Verilog in this earlier post, but I didn’t go into any detail. Verilog files at the top-most level consist of module declarations. So the simplest introduction to Verilog that I can create would look like something that just declares an empty module. Take a look at the following code for an example.
// declare our 'empty' device
module empty();
endmodule
This Verilog code declares a new module named empty. It specifies no input ports, no logic, no state, and no output ports. Not a very interesting design at all. So let’s take a look at a slightly more interesting example.
// declare a pass-through buffer
module buffer(input wire clk, output wire d);
assign d = clk;
endmodule
This Verilog module adds a few more elements. First, we declare some input and output ports named clk and d. The keyword wire tells Verilog that these are simple connections, like a physical wire. We will talk about more interesting types of inputs and outputs another time. Inside our module declaration there is also an assignment of clk to d which we prefix with the assign keyword.
In Verilog, assignments via the assign keyword are called continuous assignments. This declaration tells Verilog that the input port clk should be directly connected to the output port d. For continuous assignments that connection takes the form of an implied wire. In Verilog terms, we say that Verilog will infer a wire in order to make this connection. So in this module all we are doing is routing the input port directly to the output. This is about as simple a Verilog circuit design as we can create. If the clk input were an oscillating digital waveform, we will see that same waveform at the output d.
In Verilog, assignments via the assign keyword are called continuous assignments.
But does it work?
I ran our circuit using the Vivado Behavioral Simulator and displayed the input and output waveforms. In the image below, you can see that the output port d exactly matches the input port clk. Excellent, our very first circuit design works!
Source code
I will post the source code for this design in the github repository that accompanies this blog. For the simple circuit we designed above you can find the code here.
Syntax highlighting anyone?
My apologies for the lack of proper syntax highlighting. As our code gets longer this may become increasingly inconvenient. And I have yet to find a good syntax highlighter plugin for Verilog. If you know of a good one please leave me a comment!