Writing Testbenches
Functional Verification of HDL Models
Home  |  Contents  |  Reviews  |  Errata  |  Resources  |  Guild  |  Source
 
 
 

1st edition
errata


Second edition errata

  Isn't it ironic that a book on verification contains errors?

Despite the best efforts of my technical editor and technical reviewers, no book is ever written without any errors. Until the next edition of the book, you will find a list of known errors in the current and past editions of the book.

The first section lists corrections of syntax errors in the code examples, or that could lead to misinterpretation in the text. For complete, syntactly correct code for each example, see the source section. The second section enumerates minor corrections to errors that do not otherwise affect the readability or understandability of the text.

If you find an error not listed here, please send an email to the author describing the error and a suggested solution. Please do not forget to include the edition and page number, as well as any sample or figure number where applicable.


Significant Errors

Chapter 1

Chapter 2

Chapter 3

Chapter 4

Page 144, Sample 4-25

The following method declaration
   sent(mac_frame frame) @tclk is {
should read:
   send(frame: mac_frame) @tclk is {
                        

Page 153, Sample 4-36

The following method declaration
   to_bytes(): list of bytes {
should read:
   to_bytes(): list of byte is {
                        

Page 157, Sample 4-38

The following constraint
   it.lines.size() = 480;
should read:
   it.lines.size() == 480;
                        

Page 159, Sample 4-39

The following statements
   link.previous.next = link;
   link.next          = null;
   link.previous      = me.tail;
should read:
   link.prev = me.tail;
   if (me.tail != NULL) {
      link.prev.next = link;
   } else {
      me.head = link;
   };
   link.next = NULL;

The following declarations

   prev   : dl_list;
   next   : dl_list;
should read:
   !prev  : dl_list_el;
   !next  : dl_list_el;

The following action

   for (link  = a_list.head;
        link != null;
        link  = link.next) {
should read:
   for {link  = a_list.head;
        link != NULL;
        link  = link.next} {

Page 168, Sample 4-46

The pre_generate() methods lacks a terminating semi-colon.

Page 170, Sample 4-48

The following constraint
   keep max_frame_next_id == 0;
should read:
   keep mac_frame_next_id == 0;

Page 175, Sample 4-53

The following declaration
   var brch: BRANCH instruction;
should read:
   var br: BRANCH instruction;

Page 179, Sample 4-56

The following actions
   result.add(%{vpi, clp, pt});
   ...
   result = %{gfc, vci};   
   ...
   result = vci;
should read:
   result.add(%{vci, clp, pt});
   ...
   result = %{gfc, vpi};   
   ...
   result = vpi;

Page 184, Sample 4-58

The following constraints
   keep data_len <= 44;
   ...
   keep data_len == 42;
should read:
   keep data.size() <= 44;
   ...
   keep data.size() == 42;

The PAUSE CONTROL mac_frame is missing the constraint:

   keep pad.size() == 0;

Page 184, Sample 4-59

The following line
   compute_hec(): byte is also {
should read:
   compute_hec(): uint (bits: 8) is also {
to match the declaration of the method in the extended struct.

Page 187, Sample 4-60

The following line
   keep aos == opcode in [ADD, SUB];
should read:
   keep aos == (opcode in [ADD, SUB]);

Page 188, Sample 4-63

The following line
   me.pre_data_parity(db);
should read:
   var db_val: byte = db;
   me.pre_data_parity(db_val);

Chapter 5

Page 240, Sample 5-15

In order to be consistent with the scale of the clock period in Sample 5-16, the following line
   keep period in [18..22];
should read:
   keep period in [80..120];

Page 284, Sample 5-69

The following line
   sync true('(RxEnb)' != 1'b0));
should read:
   sync true('(RxEnb)' != 1'b0);

Page 284, last paragraph

The vhdl driver statement is not physically implemented in the stub file. It is physically implemented in the co-simulation interface between Specman Elite and the VHDL simulator being used.

Page 286, Sample 5-71

The following line
   '(RxEmpty)' = 1'b0;
should read:
   wait cycle @drive;
   '(RxEmpty)' = 1'b0;

Page 287, Sample 5-72

The following line
   event drive is only {rise('(RxClk)'); delay(2)} @sim;

should read:

   event clk is rise('(RxClk)') @sim;
   event drive is only {@clk; delay(2)};

Page 291, Sample 5-76

The following lines
      '(tx)' = data[i];
      ...
      if (n_bits == 7) data[7] = 1'b0;
      case (me.parity) {
         ODD  : '(tx)' = bitwise_xnor(data);
         EVEN : '(tx)' = bitwise_xor(data);
         MARK : '(tx)' = 1'b1;
         SPACE: '(tx)' = 1'b0;
      };
      ...
      wait [me.n_stops] * delay(duration);

should read:

      '(tx)' = data[i:i];
      ...
      if (n_bits == 7) { data[7:7] = 1'b0; };
      case (me.parity) {
         ODD  : { '(tx)' = bitwise_xnor(data); };
         EVEN : { '(tx)' = bitwise_xor(data); };
         MARK : { '(tx)' = 1'b1; };
         SPACE: { '(tx)' = 1'b0; };
      };
      ...
      wait delay(me.n_stops * duration);

Page 298, Sample 5-82

The following lines
      unit rs_232 {
         ...
            return null;

should read:

      unit phy_utopia1 {
         ...
            return NULL;

Page 302, Sample 5-86

The following lines
      unit code_mem is {
         ...
            me.fetch();
            data = me.opcode;
            ...
         }

should read:

      unit code_mem {
         ...
            me.fetched();
            '(data)' = me.opcode;
            ...
         };

Page 312, Sample 5-96

The following lines
      split_read(addr: uint (bits:24);
                 len : uint): split_read_response
      is {
         ...
            return;

should read:

      split_read(addr: uint (bits:24),
                 len : uint): split_read_response @sys.any
      is {
         ...
            return result;

Page 313, Sample 5-97

The following lines
      check_split_response(addr: uint (bits:24);
                           len : uint;
                           resp: split_read_response)
      @sys.any is {
         ...
         if (data.size() != len) {

should read:

      check_split_response(addr: uint (bits:24),
                           len : uint,
                           resp: split_read_response)
      @sys.any is {
         ...
         if (resp.data.size() != len) {

Page 315, Sample 5-99

The following lines
      '(data)'   = symbol.data;
      '(cmd_be)' = symbol.be;

should read:

      '(data)'   = sym.data;

Chapter 6

Page 337, Sample 6-22

The following lines
      type mgmt_if_mode [INTEL, MOTOROLA];

should read:

      type mgmt_if_mode: [INTEL, MOTOROLA];

The following lines are missing:

      mode: mgmt_if_mode;
      keep mode == cfg.mode;
      when INTEL harness {

Page 339, Sample 6-25

The following lines
      type mgmt_if_mode [INTEL, MOTOROLA];

should read:

      type mgmt_if_mode: [INTEL, MOTOROLA];

The following lines are missing:

      mode: mgmt_if_mode;
      keep mode == cfg.mode;
      when INTEL harness {

Page 350, Sample 6-29

To be consistent with later samples, the following lines
      unit self_check {

should read:

      unit self_checking {

Page 351, Sample 6-31

The following lines
      extend utopia_L1 {
         sc: self_checking is instance;

should read:

      extend utopia_L1 {
         sc: self_checking;

Page 352, Sample 6-32

The following lines
      extend utopia_L1 {
         port_num: uint;
         sc: self_checking is instance;
         keep for each in me.atm_port {
            it.port_num == index;
         };
         ...
      };

should read:

      extend utopia_L1 {
         port_num: uint;
         sc: self_checking;
         ...
      };
      extend harness {
         keep for each in me.atm_port {
            it.port_num == index;
         };
      };

Page 353, Sample 6-35

The following lines
         me.th.atm_port[0].send(cell);
         ...
      while (1) {
         ...
         me.th.atm_port[on_port].send(cell);

should read:

         me.th.atm_port[0].tx(cell);
         ...
      while (TRUE) {
         ...
         me.th.atm_port[on_port].tx(cell);

Page 355, Sample 6-37

The following lines
      bfm: utopia_L1 is instance;
      ...
         me.bfm.send(cell);

should read:

      bfm: utopia_L1;
      ...
         me.bfm.tx(cell);

Page 356, Sample 6-39

The following lines
      keep this.id == sys.the_one => cell_count == 1;
      keep this.id != sys.the_one => cell_count == 1;

should read:

      keep me.id == sys.the_one => cell_count == 1;
      keep me.id != sys.the_one => cell_count == 0;

Page 357, Sample 6-40

The following lines
         me.cell_count--;

should read:

         me.cell_count -= 1;

Page 359, Sample 6-44

The following lines
         keep soft me.id == 3 =>
            me.cell.is_bad == select{

should read:

         keep me.id == 3 =>
            soft me.cell.is_bad == select{

Page 359, Sample 6-45

The following lines
      extend harness {

should read:

      extend random_tb {

Page 360, Sample 6-46

The following lines
      gen me.crc keeping {
         it != me.crc;
      };

should read:

      gen me.hec keeping {
         it != me.hec;
      };

Page 365, Sample 6-56

The following lines
      keep vpi == cell_idx % 4;

should read:

      keep cell.vpi == cell_idx % 4;

Page 365, Sample 6-57

The following lines
      keep soft cell.size() == 1;

should read:

      keep soft cells.size() == 1;

Page 370, 1st paragraph

The following text

    The probability that is it 2 is 9% (0.9). The probability that is it 3 is 8.1% (0.1 x 0.9 x 0.9 x 0.1). The probability that is is N is 0.9N/10.

should read:

    The probability that is it 2 is 9% (0.1 x 0.9). The probability that is it 3 is 8.1% (0.1 x 0.9 x 0.9). The probability that is is N is 0.9N-1/10.

Page 373, Sample 6-69

The following lines
      keep stream == 0 && scenario_id >= 10 =>

should read:

      keep stream_id == 0 && scenario_id >= 10 =>

Chapter 7


Minor Errors

Chapter 4

Page 144, Sample 4-25

The method named "sent" should really be named "send".

Chapter 5

Page 285, last paragraph

The following sentence

    As a rule, verilog variable and vhdl driver statements should be added only to the user of a bus-functional model,never its author.

should read:

    As a rule, verilog variable and vhdl driver statements should be added only by the user of a bus-functional model, never its author.