1

The goal is to create a mechanism to automatically catch unqiue case violations and have them reported to the test-bench for error counting during simulation. The log files can be huge making post processing less practical. Manually creating assertions is error prone (especially when then one-hot condition is not a continuous bus like the code below) and and a never ending assignment while the design is in development.

always_comb begin
  unique case(1'b1)
    a[3]  : b = 4'h3;
    a[2]  : b = 4'h2;
    c[10] : b = 4'hE;
    c[8]  : b = 4'h4;
  endcase
end

I can enable/disable the reporting for unique case violations with $assertcontrol, therefore I believe it is possible to use VPI callback, but I'm having trouble using vpi_iterate() to find the unique case, currently I'm slowly traversing the design trying to figure out when to pass what kind of object my vpiHandle is pointing to. I tried vpi_iterate(vpiCallback, NULL), but my simulator returns a a massage stating vpiCallback has not been implemented yet.

The simulator is reporting unique case violations to the log file. So how can I get my test-bench to detect it?

Greg
  • 18,111
  • 5
  • 46
  • 68
  • Do you just want to promote the warning to an error? For incisive you can do that with `-ncerror` – nguthrie Apr 21 '16 at 19:04
  • @nguthrie , I'd like it to trigger something in my test-bench, such as issue a `` `uvm_error() `` – Greg Apr 21 '16 at 19:47
  • I can't help you with the VPI, but how about defining some macro that included your error checking/assertion as well as the `unique case`? – Matthew Taylor Apr 21 '16 at 19:59
  • @MatthewTaylor , I cannot touch the RTL. I been considering making a per-processing script to parse the RTL files, some how detect extract the signals used in `unique case` plus figure out the clock-domain(s), then generate file of `bind` statements. Creating a parameterized checker module with the `$onehot` assertion would be the easy part. Creating the script to parse and extract is hard. Plus I'm not sure if the script strategy would be prone to flagging false violation from zero-time glitches. – Greg Apr 21 '16 at 20:42

1 Answers1

0

I don't have the full answer yet, but here's something to get you started. I added your always_comb block to a module:

module some_module();
  logic [3:0] a;
  logic [3:0] b;
  logic [8:0] c;

  always_comb begin : always_comb_proc
    unique case(1'b1)
      a[3]  : b = 4'h3;
      a[2]  : b = 4'h2;
      c[10] : b = 4'hE;
      c[8]  : b = 4'h4;
    endcase
  end

  initial begin
    $add_cbs();
  end
endmodule

I created a VPI system task that can find the handle to the unique case. It's just a matter of traversing the hierarchy:

void add_cbs_calltf() {
  // getting the module could be more elegant
  vpiHandle mod = vpi_handle_by_name("some_module", NULL);

  // there's only one process - the 'always_comb'
  vpiHandle proc_it = vpi_iterate(vpiProcess, mod);
  vpiHandle proc = vpi_scan(proc_it);

  // each 'always' process has an event control
  // - for 'always_comb', this is implicit
  vpiHandle ev_ctrl = vpi_handle(vpiStmt, proc);

  // the event control contains the 'begin/end' statement
  vpiHandle named_begin = vpi_handle(vpiStmt, ev_ctrl);

  // finally, a 'begin/end' statement can contain other statements
  // - the one and only in this case is the 'unique case'
  vpiHandle stmt_it = vpi_iterate(vpiStmt, named_begin);
  vpiHandle stmt = vpi_scan(stmt_it);
  vpi_printf("stmt type = %s\n", vpi_get_str(vpiType, stmt));
  vpi_printf("stmt case type = %d\n", vpi_get(vpiCaseType, stmt));
  vpi_printf("stmt case qualifier = %d\n", vpi_get(vpiQualifier, stmt));
}

I still don't know how to add a callback when the "assertion" triggers, but this should be a step in the right direction. I'll probably look into it and update the answer.

Tudor Timi
  • 7,453
  • 1
  • 24
  • 53