[logo] 
 
Home
News
Activity
About/Contact
Major Tools
  Dinotrace
  Verilator
  Verilog-mode
  Verilog-Perl
Other Tools
  BugVise
  CovVise
  Force-Gate-Sim
  Gspice
  IPC::Locker
  Rsvn
  SVN::S4
  SystemPerl
  Voneline
  WFH
General Info
  Papers

Issue #542

import package is broken under multiply instantiated cells

Added by Alex Solomatnikov 10 months ago. Updated 9 months ago.

Status:Closed Start date:08/07/2012
Priority:Normal Due date:
Assignee:Wilson Snyder % Done:

0%

Category:TranslationError
Target version:-

Description

This used to work 3 months ago:

package driver_definitions;

// Returns the maximum of two numbers
function automatic integer max;
    input integer a;
    input integer b;
    begin
        max = (a > b) ? a : b;
    end
endfunction

// Calculate the ceiling of log_2 of the input value
function automatic integer ceil_log2;
    input integer value;
    begin
        value = value - 1;
        for (ceil_log2 = 0; value > 0; ceil_log2 = ceil_log2 + 1)
            value = value >> 1;
    end
endfunction

endpackage

module rand_num_gen(
  ...
);

import driver_definitions::*;

...

localparam LFSR_DATA_WIDTH    = ceil_log2(LFSR_DATA_RANGE);
localparam LFSR_WIDTH        = max(4, ceil_log2(LFSR_DATA_RANGE + 1));

Now I get errors:

%Error: rand_num_gen.sv:46: Can't find definition of task/function: ceil_log2
%Error: rand_num_gen.sv:47: Can't find definition of task/function: max

History

Updated by Wilson Snyder 10 months ago

  • Status changed from New to AskedReporter

Sorry this works for me, please give a failing example in verilator test_regress format.

Updated by Alex Solomatnikov 10 months ago

It looks like the reason for this issue is that verilator does not try to find/open a file with the name driver_definitions.sv, as it used to do (or as VCS does). So, I get an error when I try to compile just this module:

verilato -sv --cc rand_num_gen.sv --top-module rand_num_gen -Wno-fatal -I.
%Error: rand_num_gen.sv:30: syntax error, unexpected IDENTIFIER, expecting PACKAGE-IDENTIFIER or STRING
%Error: Exiting due to 1 error(s)

If I add:

`include "driver_definitions.sv" 

then it works.

Similarly, test_regress/t/t_package_abs.v has package definition in the same file, not in a separate file as it is usually done.

Updated by Wilson Snyder 10 months ago

No, verilator has never implemented automatic package resolution, and it fails on both revisions the same.

Also neither does VCS. At present VCS requires all packages to be listed on the command line, or equivalently in a file included off from the command line. Even `including a package from a module that is found by automatic library lookup is NOT sufficient. About 3 months ago I had a long debate with them on getting them to fix this mess but they stonewalled. Yes, it should be obvious that this is useful....

Anyhow if you can isolate the test case that passes on the old rev and fails now I'll fix it; there is a lot changed there and I have little doubt that something was broken.

Updated by Alex Solomatnikov 10 months ago

You are right - it is not an include issue.

Here is reduced test case:

package defs;

function automatic integer max;
        input integer a;
        input integer b;
        begin
                max = (a > b) ? a : b;
        end
endfunction

function automatic integer log2;
        input integer value;
        begin
                value = value >> 1;
                for (log2 = 0; value > 0; log2 = log2 + 1)
                        value = value >> 1;
        end
endfunction

function automatic integer ceil_log2;
        input integer value;
        begin
                value = value - 1;
                for (ceil_log2 = 0; value > 0; ceil_log2 = ceil_log2 + 1)
                        value = value >> 1;
        end
endfunction

endpackage

module gen(
        clk,
        reset_n,
        enable,
        ready,
        rand_num,
        is_less_than
);

import defs::*;

parameter RAND_NUM_WIDTH        = "";
parameter RAND_NUM_MIN          = "";
parameter RAND_NUM_MAX          = "";

localparam DATA_RANGE           = RAND_NUM_MAX - RAND_NUM_MIN + 1;
localparam DATA_WIDTH           = ceil_log2(DATA_RANGE);
localparam WIDTH                = max(4, ceil_log2(DATA_RANGE + 1));

input                           clk;
input                           reset_n;
input                           enable;
output                          ready;
output  [RAND_NUM_WIDTH-1:0]    rand_num;
output                          is_less_than;

endmodule

module test(
        clk,
        reset_n,
        enable,
        ready,
        count
);

import defs::*;

parameter COUNT_WIDTH           = "";

parameter POWER_OF_TWO          = "";

parameter MIN_COUNT             = "";
parameter MAX_COUNT             = "";

localparam MIN_EXPONENT         = ceil_log2(MIN_COUNT);
localparam MAX_EXPONENT         = log2(MAX_COUNT);
localparam EXPONENT_WIDTH       = ceil_log2(MAX_EXPONENT + 1);

input                           clk;
input                           reset_n;
input                           enable;
output                          ready;
output  [COUNT_WIDTH-1:0]  count;

generate
if (POWER_OF_TWO == 1)
begin : power_of_two_true
        wire    [EXPONENT_WIDTH-1:0]    rand_exponent_out;

        gen rand_exponent (
                .clk            (clk),
                .reset_n        (reset_n),
                .enable         (enable),
                .ready          (ready),
                .rand_num       (rand_exponent_out));
        defparam rand_exponent.RAND_NUM_WIDTH   = EXPONENT_WIDTH;
        defparam rand_exponent.RAND_NUM_MIN             = MIN_EXPONENT;
        defparam rand_exponent.RAND_NUM_MAX             = MAX_EXPONENT;

        assign count = 1 << rand_exponent_out;
end
else
begin : power_of_two_false
        gen rand_count (
                .clk            (clk),
                .reset_n        (reset_n),
                .enable         (enable),
                .ready          (ready),
                .rand_num       (count));
        defparam rand_count.RAND_NUM_WIDTH = COUNT_WIDTH;
        defparam rand_count.RAND_NUM_MIN   = MIN_COUNT;
        defparam rand_count.RAND_NUM_MAX   = MAX_COUNT;
end
endgenerate

endmodule

Latest verilator version:

~/verilator/verilator_bin -sv --cc -Wno-fatal --error-limit 1000 test.v --top-module test
%Warning-PINMISSING: test.v:91: Cell has missing pin: is_less_than
%Warning-PINMISSING: Use "/* verilator lint_off PINMISSING */" and lint_on around source to disable this message.
%Warning-PINMISSING: test.v:105: Cell has missing pin: is_less_than
%Error: test.v:47: Can't find definition of task/function: ceil_log2
%Error: test.v:48: Can't find definition of task/function: max
%Error: Exiting due to 2 error(s)

Older version:

/tools/verilator/verilator-3.833/bin/verilator_bin -sv --cc -Wno-fatal --error-limit 1000 test.v --top-module test
%Warning-PINMISSING: test.v:91: Cell has missing pin: is_less_than
%Warning-PINMISSING: Use "/* verilator lint_off PINMISSING */" and lint_on around source to disable this message.
%Warning-PINMISSING: test.v:105: Cell has missing pin: is_less_than
%Warning-WIDTH: test.v:76: Operator FUNCREF 'ceil_log2' expects 32 bits on the Function Argument, but Function Argument's VARREF 'MIN_COUNT' generates 1 bits.
%Warning-WIDTH: test.v:77: Operator FUNCREF 'log2' expects 32 bits on the Function Argument, but Function Argument's VARREF 'MAX_COUNT' generates 1 bits.
%Warning-LITENDIAN: test.v:54: Little bit endian vector: MSB < LSB of bit range: -1:0
%Warning-LITENDIAN: test.v:84: Little bit endian vector: MSB < LSB of bit range: -1:0

Note that 3.833 includes tri-state fixes.

Updated by Wilson Snyder 10 months ago

  • Subject changed from import package is broken to import package is broken under multiply instantiated cells
  • Category set to TranslationError
  • Status changed from AskedReporter to Resolved
  • Assignee set to Wilson Snyder

Fixed in git towards 3.841.

Updated by Wilson Snyder 9 months ago

  • Status changed from Resolved to Closed

In 3.841.

Also available in: Atom