My First ASIC

For the first time in the past few years, I’m really having a lot of fun, and I owe it to my ASIC design course.  For a previous homework assignment, I had to modify and customize a simple counter device.  I then had to simulate and find the optimal clock period with Synopsys.  In the next homework assignment, I had generate the back-annotated delays, and then re-simulate, re-synthesize, and finally analyze for power consumption.  Using the Cadence Encounter tool that is available on campus, the result of my efforts is shown below.

My First ASIC - a simple counter

 

Now I just have to learn how to read what Encounter is showing me (Fence, Guide, Obstruct, etc.) …

The Power of Synthesis

When I was an undergraduate a lot of my classmates hated HDLs (we were learning VHDL).  They often claimed they were electronic engineers and not programmers, they hated writing programs and wanted to work with circuits and electronics.  It probably did not help that the professors loved to give academic problems rather than real-world issues.  I think more would have enjoyed learning HDLs and RTL if they had been interfacing FPGAs with other components or designing digital filters rather than implementing LZH compression algorithms in hardware and software.  However, I also think they failed to see the true power of HDLs and hardware synthesis.

What my fellow classmates did not realize is that even though they were writing RTL in a programming language-like syntax, they were actually designing circuits.  I suspect the compilers and the for-loops may have thrown them off, but they were really modeling hardware.  One doesn’t just begin writing RTL (without years of experience at least), one has a high -level circuit in mind that should be modeled with the RTL.  Take the following Verilog RTL, for example, with a for-loop:

module bitmask(
  input clock,
  input [7:0] in_data,
  input [3:0] index,
  output [7:0] sum
);

reg [7:0] buffer;
reg [7:0] mask;

assign sum = buffer;

always @(posedge clock)
  buffer <= mask & in_data;

integer i;

always @(*)
  for(i=7; i>=0; i=i-1)
    mask[i] = (i>= index) ? 1'b0 : 1'b1;

endmodule

For those that don’t read Verilog or just refuse to try, this module applies an adjustable mask to an input and stores the result in a register.  The mask is created by specify from where the mask should begin.  The result of a simulation is shown below.  Note that in the output below, ptr maps to index and data maps to in_data

GtkWave display of the value-change dump (generated by GNU Icarus Verilog)

The incoming data is 0x55h, and the mask ptr is set to 4.  In terms of big endianness, this means that the lower byte of the mask should be all ones and the upper byte should be all zeros.  The result when the register clocks the masked data on the clock’s positive edge is 0x05h.  We then change the input data to 0xDEh, and the mask ptr is set to 5.  Now the mask consists of the top three bits being zeros, and the lower five bits being ones.  On the positive clock edge, the result in the register is 0x1Eh.

This is a very primitive example, but I wanted to show how some simple RTL modeling can be so powerful.  I synthesized this module using Synopsys Design Compiler one of my university’s lab machines.  The synthesized circuit is shown below.   I was synthesizing with an ASIC standard cell library, so if you did this for an FPGA you might get somewhat different output.

Unfortunately, Synopsys did not print the port names when the schematic was exported to postscript, but I think you can get the idea.  The squares on the right are the flip-flops that correspong to register buffer.  The ports of the left represent the inputs, and the logic gates between the inputs and flip-flops are the combination logic required to produce the mask.

The true power of synthesis is that it allows designers to increase their productivity in great strides.  While it may take only a few minutes to model a circuit with RTL and do a quick simulation for verification, imagine having to do karnaugh-map optimizations and truth-tables to come up with the optimized circuit that Synopsys produced?

GNU Verilog

I started my graduate studies in electrical engineering on this past Monday.  I am taking a course in ASIC design which I have always wanted to learn more about.  In the course we will be using the Verilog HDL language, and we will be using expensive industry standard tools, including  ModelSim for simulation and Synopsis for synthesis.  I do not always have access to ModelSim and I was looking for a simple way to test some verilog without having to use the university’s machines.  I stumbled upon the GNU Icaraus Verilog compiler and GtkWave.  Like all GNU tools, they are available free of charge and are of rather good quality in my opinion.  I created a basic tutorial for getting started with these tools using a simple D flip-flop.

Before getting started, one must install the ‘verilog’ and ‘gtkwave’ packages, corresponding to Icarus Verilog and GtkWave.  I found the packages available for OpenSuSE, and I am sure they are also available for other distributions too.  The brave can alawys build from the source if no package exists.

Lets get started.  Below is the verilog model for a simple D flip-flop with a synchronous reset.

// dff.v
module dff(d,q,clock,reset);
input wire clock;
input wire reset;
input wire d;
output reg q;

always @(posedge clock)
begin
if (clock) begin
if (reset) begin
q <= 1’b0;
end
else begin
q <= d;
end
end
end

Below is a basic test bench with a 20 ns clock period that toggles the flip-flop input a few times.

// dff_tb.v
`timescale 1ns/1ps
module dff_tb;
parameter CLK_PERIOD = 20;
reg clock, reset, d;
wire q;

dff d0(
.d(d),
.q(q),
.reset(reset),
.clock(clock)
);

initial begin
$dumpfile(“dff_tb.vcd”);
$dumpvars(1, dff_tb);
$monitor(“clock=%b, d=%b, q=%b”, clock, d, q);
clock = 1’b1;
reset = 1’b1;
d = 1’b0;
#(CLK_PERIOD*5)
reset = 1’b0;
#CLK_PERIOD
d = 1’b1;
#CLK_PERIOD
d = 1’b0;
#CLK_PERIOD
d = 1’b1;
#CLK_PERIOD
d = 1’b0;
#CLK_PERIOD
$finish;
end

always #(CLK_PERIOD/2) clock = ~clock;

endmodule

The test bench is written such that the changes in the signals are dumped to a Value Change Dump (VCD) file, using the $dumpfile and $dumpvars system commands.  The state of the variables is also printed to the terminal using the $monitor system command. Now that the D flip-flop module and a test bench are ready, we need to compile the verilog and run the simulator.

iverilog -o dff dff.v dff_tb.v  # compiles the modules into a “dff” project
vvp dff                                           # runs the simulation on the project
gtkwave -f dff_tb.vcd              # graphically view the simulation output

Selecting the dff_tb in the upper lefthand box, add each of the four signals using the “insert” button.  The time scale will probably set set in the picoseconds, so zoom out until you are at a suitable scale to view the waveforms.  This can all probably be done on the command line, but I have not looked into it yet.

As you can see, with two very simple packages it is easy to get started modeling with Verilog–with no cost at all.  Synthesis, on the other hand…