Last updated 12/11/07
Thank you to everyone who has sent me the mistakes they found in my
book, SystemVerilog for Verification, first edition. Like a hardware
project, the book has "bugs". Both hardware and books should be
verified by someone other than the person who created it. Now if I can
only figure out how to perform constrained random testing of text...
As of September 2006 I have sent out books to all the people who were
the first to find mistakes in each of the chapters. Don't worry, I am
already working on the second edition, giving you more opportunity to
earn a free book.
A revised first edition came out June 2007 that fixed many of the
errata shown below.
The following list shows larger mistakes in the book. Minor typos and poor English are not listed.
Preface
- Added my email, chris@spear.net
Chapter 1 Verification Guidelines
-
Page 5, last line: "Given enough time, you can write all the tests
needed for 100% coverage of the entire verification plan.
-
Page 17, Example 1-1, and page 18, Example 1-3, the first line should be:
module test(PAddr,PWrite,PSel,PWData,PEnable,Rst,clk);
- Page 21, second paragraph. Functional coverage measures the
progress of all tests in fulfilling the requirements in the
verification plan.
Chapter 2 Data Types
-
Page 28, Example 2-1, fifth line should be:
clk = 0; // Procedural assignment
-
Page 29, Example 2-3, should be:
if ($isunknown(iport))
$display("@%0d: 4-state value detected on iport %b",
$time, iport);
-
Page 30, Example 2-6 and Figure 2-1 - the array should be called
b_unpack in both diagrams and the surrounding text.
-
Page 30, Example 2-7, the second line misspelled the variable descend.
-
Page 30, Section 2.3.3 The foreach index variable is automatically declared
for you and is local to the scope of the loop.
-
Page 31, Example 2-9, line seven should be:
md = '{'{9, 8, 7}, '{3{5}}};
-
Page 34, Example 2-14, should be:
bit [3:0] [7:0] barray [3]; // Packed: 3x32-bit
bit [31:0] lw = 32’h0123_4567; // Longword
barray[0] = lw;
-
Page 35, delete the line:
The latter function returns the size but does not work with fixed-size arrays.
-
Page 36, Example 2-17.
Lines 2 and 3 should be
b[$] = ’{3,4},
q[$] = ’{0,2,5}; // {0,2,5} Initial queue
Line 7 should be:
q.insert(3, b); // {0,1,2,3,4,5} Insert b in q
Note that this is not supported by all SystemVerilog simulators. As an
alternative, try:
q = {q[0:2], b, q[3:$]}; // {0,1,2,3,4,5} Insert b in q
-
Page 36, section 2.5, mention that a SystemVerilog Queue is similar to
the C++ Standard Template Library deque data type.
-
Page 39, Example 2-19, line 19 should be:
min_address = switch["min_address"];
-
Page 41, Section 2.8.2 should refer to Example
2-21.
-
Page 41, Example 2-21, added a dynamic array:
int d[] = '{2,4,6,8,10};
tq = d.max; // {10}
-
Page 41, the last lines of Example 2-22 should be:
tq = d.find_index with (item > 3); // {0,2,4,5}
tq = d.find_first with (item > 99); // {} - none found
tq = d.find_first_index with (item==8); // {2} d[2]=8
tq = d.find_last with (item==4); // {4}
tq = d.find_last_index with (item==4); // {5} d[5]=4
-
Page 46, section 2.11. The two references to "typedef" should be
"struct":
A struct just groups data fields together. Without the code
that manipulates the data, you are only creating half of the
solution.
There are several places where a struct is useful: creating simple user-defined types, unions, and enumerated types and virtual interfaces.
-
Page 52, Section 2.15, fourth sentence should be: "Addition B uses
8-bit precision because there is an 8-bit variable on the left
side of the assignment."
Chapter 3 Procedural Statements and Routines
-
Page 59, Example 3-10, the third line should not have a "begin":
for (int i=0; i<a.size; i++)
-
Page 61, Example 3-12 had multiple errors, should be:
function void print_sum (ref int a[],
input int first = 0,
input int last = -1);
int sum = 0;
if (last == -1 || last > a.size)
last = a.size;
for (int i=first; i<last; i++)
sum += a[i];
$display("The sum of the arrays is ", sum);
endfunction
-
Page 61, Example 3-13 should be:
print_sum(a); // Sum a[0:size-1] default
print_sum(a, 2, 5); // Sum a[2:4]
print_sum(a, 1); // Start at 1
print_sum(a,, 3); // Sum a[0:2]
print_sum(); // Compile error: a has no default
Chapter 4 Basic OOP
-
Page 68, section 4.3, the third sentence should be, "The packet
contains an address, a CRC, and an array of data values."
-
Page 69 4.4, "Now you can compile the package separately from the
rest of the system.
-
Page 71, 4.6.2 "For example, the BusTran class has two 32-bit
registers (addr and crc) and an array with eight values (data), for a
total of 10 longwords, or 40
bytes. So when you call new, SystemVerilog allocates 40 bytes of storage."
-
Page 78, Example 4-10, the last line should be:
begin
s = new;
s.initialize(42);
end
-
Page 79, Example 4-11, line 5 should be:
$time, addr, crc);
and line 16 should be:
$time, addr, data);
-
Page 80, Example 4-12 also needs $time for the formatted $display statements.
-
Page 82, Example 4-14, the tenth line should be a function, not a task:
function void print (int limit);
-
Page 84, Example 4-17, the third to last line should be:
@(receive) $display(b.data[i]);
-
Page 88, second paragraph, second sentence should be: "There are two
handles, generator.b and transmit.b, that both
refer to the same object."
Example 4-21 should start with:
task transmit(BusTran b);
CBbus.rx_data <= b.data;
b.timestamp = $time;
-
Page 89, section 4.14.2, third line, "...the argument bt is not..."
-
Page 90, third line should have generate_bad.
-
Page 90, Example 4-24 and 4-25, third to last line should be:
transmit(b); // Send it into the DUT
-
Page 95, Figure 4-7 is missing an arrow between the id=3 block and the
startT=42 block.
-
Page 96, Section 4.18 should refer to Figure 4-8.
Chapter 5 Connecting Testbench and Design
-
Page 107, section 5.3.6, the first sentence should be, "An interface
cannot contain module instances, only interface instances."
-
Page 112: Sampling of design signals is done in the Postpone
region, not the Prepone.
-
Page 115, Example 5-17, the first line should be:
`timescale 1ns/1ns
and the last drive in the arb module should be:
#18 arbif.grant = 3; // @ 30ns.
-
Page 124: Examples 5-28 and 5-29 should start with:
bus.cb.request <= 1;
repeat (2) @bus.cb; // Wait two clock cycles
-
Page 125, Example 5-32 should be:
"test.sv", 7: top.t1.a1: started at 55ns failed at 55ns
Offending '(bus.cb.grant == 2’b1)'
Error: "test.sv", 7: top.t1.a1: at time 55 ns
Grant not asserted
Chapter 6 Randomization
-
Page 140, first line should read, "routine that prints any useful information and then gracefully shuts down the simulation."
-
Page 142, Example 6-3, the first 4 lines should be:
class Stim;
const bit [31:0] CONGEST_ADDR = 42;
typedef enum {READ, WRITE, CONTROL} stim_t;
randc stim_t kind; // Enumerated var
-
Page 143, Example 6-7 should be labeled, "Random set constraint
with repeated values"
-
Page 147, Table 6-1 should have the solutions:
b c d
26 26 27
26 26 28
26 26 29
27 27 28
27 27 29
28 28 29
-
Page 156, Example 6-23, the following line has changed:
Transaction t;
and the following line is removed:
int s;
-
Page 158, add the following sentence to the first paragraph, "Since
the variable is calculated procedurally, not through the random
constraint solver, it does not need the rand modifier."
-
Page 160, Example 6-27, first line of display function should be:
$display("\n%s", msg);
-
Page 164, after example 6-32, the third pair of numbers should be
(-63, 127) as the original text incorrectly had a byte holding
the value 128.
-
Page 165, example 6-34, the constraint should be:
pkt1_len + pkt2_len == 9'h64; // 9-bit sum
-
Page 167, Example 6-37, the middle of the foreach loop should be:
@bus.cb;
bus.cb.strobe <= sp.strobe[i];
// If strobe is enabled, drive out next data word
if (sp.strobe[i])
bus.cb.data <= data[count++];
-
Page 167, Example 6-38, the first $write should be:
$write("len: sum=%4d ", len.sum);
-
Page 169, bottom paragraph, len is a 10-bit variable, not 9.
-
Page 180, Example 6-58, the fifth line should be:
rand uint run_for_n_frames; // # frames in test
-
Page 181, Example 6-59, tenth line should be:
function void gen_cfg;
line 16 should be:
foreach (gen[i])
line 21 should be:
drv[i].set_speed(100);
Chapter 7 Threads and Interprocess Communication
-
Page 185, Example 7-1, 186 7-3, and 187 7-5, the ninth line should be:
#30 $display("@%0d: sequential after #30", $time);
-
Page 187, Example 7-6, line 4 should be:
@10: after join_any
-
Page 189, Example 7-8, the sixth line should be:
wait (bus.cb.addr == tr.addr);
-
Page 193, Figure 7-4, the left block should use fork-join instead of
fork-join_none to match Example 7-14. The disable fork
statement disables thread 1 (the fork..join) and all its
children, 2, 3, and 4.
-
Page 194, Example 7-15, the first 4 lines should be:
initial begin
wait_for_tr(tr0); // Spawn thread 0
fork
begin : threads_1_2
-
Page 198, Example 7-23, the second to last line should be:
wait (done_count==N_GENERATORS); // Wait for triggers
-
Pages 204, Examples 7-27 - its text formatting does not match what is
shown in Example 7-28, though the values and order are the same. The
$display statement on line 12 has an extra format. The
final join_any in 7-27 should be just a join.
-
Page 205, Example 7-28 has one more final line of output:
@3: Consumer: got (3)
-
Page 208, Example 7-33 and Page 209, Example 7-35 both use the
declarations and initial block from Example 7-30.
-
Page 211, Example 7-37, the task run ends with an endfunction, but it
should be endtask.
Chapter 8 Advanced OOP and Guidelines
-
Page 215, first sentence should be, "How would you create a complex
class for a bus transaction that also performs error injection and
variable delays?"
-
Page 217, Example 8-2, the display function should use the following
$write:
$write("BadTr: bad_crc=%b, ", bad_crc);
-
Page 221, fourth sentence should read, "The only way you can change
these would be to edit the Transaction class, which goes against
the verification guidelines presented in this book.
-
Page 224, Example 8-9, the 11th line should be:
env.gen.blueprint = bad; // the "bad" one
-
Page 226, Example 8-11, the second line should be:
tr = bad; // Base handle points to extended obj
-
Page 237, Example 8-25, the inner loop should be:
forever begin
agt2drv.get(tr);
foreach (cbs[i]) cbs[i].pre_tx(tr, drop);
if (!drop) transmit(tr);
foreach (cbs[i]) cbs[i].post_tx(tr);
end
Chapter 9 Functional Coverage
-
Page 259, first paragraph, 3rd sentence, "... the maximum length has a domain of
0:22 (0+0:7+15)."
-
Page 266, Example 9-28, third to last line should be:
port: coverpoint tr.port; // Create cover point port
-
Page 269, Example 9-32, last cross coverage definition should include:
ignore_bins md = binsof(port) intersect {0} &&
binsof(kind) intersect {[9:11]};
-
Page 270, Example 9-33, all the occurances of weight should be
option.weight.
-
Page 271, Example 9-34, second to last line should be:
bins b0 =
binsof(b.b1); }
-
Page 275, Example 9-42, the last 3 lines should be:
cpa = new(port_a, 4); // port_a, lo=0:3, hi=4:7
cpb = new(port_b, 2); // port_b, lo=0:1, hi=2:7
end
Chapter 10 Advanced Interfaces
-
Page 286, second paragraph, the first sentence should start with, "In
Example 10-8, the key line in the testbench ..."
Credits
Thanks to Veerendra Bharg Alluri,
Steve Barrett,
Shalom Bresticker,
John Brooks,
Heath Chambers,
Keith Chan,
Luke Chang,
Haihui Chen,
Gunther Clasen,
Steve Collins,
Hashem Heidaragha,
Louis Hsiao,
Tony Hsu,
Stefan Kruepe,
Jimnan Kuo,
Jim Lewis,
Frank Lin,
Daguang Liu,
Victor Lopez,
Michael Macheski,
Robin van Malenhorst,
Ronald Mehler,
Mike Mintz,
Thinh Ngo,
John Nolan,
Ben Rahardja,
Afroza Rahman,
Chandrasekar Rajanayagam,
Jonathan Schmidt,
Dhaval Shah,
Chandru Sippy,
Dave Snogles,
Mladen Stanic,
Raymond Sylvestre,
Hugh Walsh,
Larry Widigen,
Cuihong Zhao,
and
Chunlin Zhang for their help.