Games / Log forensics / Synthesis

Synthesis

Each case shows the tail of a real run, ending where the tool stopped or warned. Say what caused it, or what to do about it. A case you miss returns later in the round and starts its schedule over; one you get right returns after 1, 3, 7, then 21 days. Keys 1 to 4 choose an option, h shows a hint, and Enter moves on. Progress is stored in this browser.

SourceEach case is the tail of a real run of the gcd design on Nangate45 in the openroad/orfs container, with one thing wrong. The same failures happen on commercial tools in different words: what carries across is the reasoning from the last few lines back to the cause. Reference: the OpenROAD documentation (OpenROAD-flow-scripts on GitHub).
All 3 cases in this stage, with answers
  • What is the cause, and where do you look for it?
    1_1_yosys_canonicalize log
    6.12. Analyzing design hierarchy..
    ERROR: Module `\missing_helper' referenced in module `\Subtractor_0x422b1f52edd46a85' in cell `\u_helper' is not part of the design.
    Elapsed time: 0:00.09[h:]min:sec. CPU time: user 0.07 sys 0.02 (99%). Peak memory: 38144KB.
    make[1]: *** [Makefile:271: do-yosys-canonicalize] Error 1
    make: *** [Makefile:274: results/nangate45/gcd/undef_module/1_1_yosys_canonicalize.rtlil] Error 2
    A module is instantiated that no source file defines.

    Hint: The message names three things. Ask which of them is the one that does not exist.

    The hierarchy check walks from the top down and stops at the first instance whose module it cannot find. It names the missing module, the module that instantiates it, and the instance, which is everything needed to find the line. The usual causes are a file left out of the file list, a typo, and a cell that should have been declared a black box.

    # add the file that defines it, or declare it a black box
    (* blackbox *) module missing_helper (input clk); endmodule
  • The run completed after this. What has it silently built?
    1_1_yosys_canonicalize log
    6.5. Executing AST frontend in derive mode using pre-parsed AST for module `\RegRst_0x9f365fdf6c8998a'.
    6.6. Executing AST frontend in derive mode using pre-parsed AST for module `\RegEn_0x68db79c4ec1d6e5b'.
    6.7. Executing AST frontend in derive mode using pre-parsed AST for module `\Subtractor_0x422b1f52edd46a85'.
    /tmp/rtl/gcd_latch.v:760: Warning: Identifier `\req_val' is implicitly declared.
    /tmp/rtl/gcd_latch.v:760: Warning: Identifier `\req_msg' is implicitly declared.
    /tmp/rtl/gcd_latch.v:760: Warning: Range select [15:0] out of bounds on signal `\req_msg': Setting all 16 result bits to undef.
    6.8. Executing AST frontend in derive mode using pre-parsed AST for module `\Mux_0xdd6473406d1a99a'.
    A one-bit wire where a sixteen-bit one was meant.

    Hint: Ask what width a signal gets when nothing declares it.

    Verilog lets an undeclared identifier become an implicit one-bit wire, so a misspelled name never stops the run. The third line is the consequence: the range select cannot fit, so the bits become undefined. This is the kind of warning that is worth failing a build on, because everything downstream is built on it and none of it complains again.

    // declare what you use, and fail the build on implicit declarations
    wire [15:0] req_msg;
  • The error is at the end. Which line above it is the cause?
    1_2_yosys log
    14. Executing INSBUF pass (insert buffer cells for connected wires).
    15. Executing CHECK pass (checking for obvious problems).
    Warning: multiple conflicting drivers for gcd.\resp_rdy:
        port Z[0] of cell $auto$insbuf.cc:97:execute$2712 (BUF_X1)
        module input resp_rdy[0]
    16. Printing statistics.
    17. Executing CHECK pass (checking for obvious problems).
    ERROR: Found 1 problems in 'check -assert'.
    The warning, which says one signal has two drivers.

    Hint: The error says a check failed. The check printed what it found one step earlier.

    A net with two drivers has no defined value, so the check refuses to pass the netlist on. The error line itself says only that a check failed; the detail is in the warning above, which names the signal and both of the things driving it. One of them here is a module input, which usually means an output was assigned a name that already belongs to a port.

    // drive each net from exactly one place
    assign clash = req_val;