Structural Descriptions with Generics and Synopsys

The Synopsys implementation of VHDL is a professional-grade thing. Far more than we need in CMPT 250. The downside of this is that it's fantastically overpowered, which somes along with a rather difficult interface to deal with. The upside should be that it does everything we'd ever think of attempting.

One aspect of the Synopsys simulator that has bothered me several times is its behaviour when given a structural implementation using generics. Basically, it ranges between quirky and broken.

What follows is a description (and rant) about this. Is it possible that it's all wrong because I'm missing some small detail of VHDL or Synopsys? Yes.

Partial Port Mapping

In VHDL, it's possible to connect parts of a port when instantiating an entity. For example:

port map (
  A(0) => A0,
  A(1) => A1);

... is perfectly legitimate (assuming the port A is a std_logic_vector(1 downto 0) or similar).

It's also legal VHDL to do this with a signal using a generic parameter:

generic map (
  n => 4)
port map (
  A(3 downto 1) => input(2 downto 0),
  A(0) => input(3));

(Here, assuming that the port A is a std_logic_vector(n-1 downto 0).)

This will compile fine with Synopsys, but when simulated, I get an error like the following:

***Internal system error. Cannot recover.

FAULT CONTEXT
  Program          : 'vhdlsim'
  Release          : '2001.09'
  Architecture     : 'sparcOS5'
  Phase            : <null>
  Last UI Command  : <null>
  Simulation Time  : 0 NS

FAULT ID:
'3128548 3223260 -13506308 1073440 1075916 1090616 1085564 452484 420964'

The main problem (at least in a instrutional context) is that this error message does nothing useful to help someone track down its source. The best one can do is to do some kind of binary search until they track down the offending lines and guess at the cause. [I say this from experience.]

If you don't believe me (or want to try it on your own system), you can try the VHDL file with partial port maps that produced the above error.

This is easy enough to work around. You just have to create an internal signal with everything concatenated the way it should be and map to the whole port:

temp <= input(2 downto 0) & input(3);

...

generic map (
  n => 4)
port map (
  A => temp);

You can see this in the previous file with the port mapped in one go. This works with my Synopsys installation, so does the same thing with no generic.

Generics within Generics

This problem occurs when using a generic value to specify a generic, like this:

generic map (
  n => n)
...

I am less confident about the nature of the bug here. Sometimes, things work, but sometimes not. I first noticed it when playing around and trying to create a structural implementation of a circuit that multiplies by 10, by doing some shifts and an addition (using an previous implementation of the adder). In Synopsys, this circuit (either the mul10 or the testbench) produces this error:

**Internal Error: vhdlsim:
    Please report (uniqueness error).
FAULT CONTEXT
  Program          : 'vhdlsim'
  Release          : '2001.09'
  Architecture     : 'sparcOS5'
  Phase            : Mark resolved signals
  Last UI Command  : <null>
  Simulation Time  : 0 NS

FAULT ID:
'3125628 3127184 1380252 1565288 1447344 1447388 1447436 1447436 1447436 1447636 900308 1091124 1085572 452484 420964'

Without the generic in the mul10 (it can be left in the adder), this bug disappears and everything works as expected.

Also, it seems that with only one generic-specified port (the adder has two), things also work, but I haven't bothered to play with it enough to say for sure.

This bug is much harder to work around than the previous one (as far as I can tell). You basically have to get rid of the generic.

So?

Well, both of these work just fine with VHDL Simili (the only other VHDL implementation I had handy). They are also valid VHDL code, according to Ashenden (couldn't find the IEEE spec as I was writing this).

I don't think I'm the only one to have thought of creating structural implementations with generics—that's what they're for after all.

Even so, it's perfectly reasonable for Synopsys to not implement the entire VHDL specification. I don't think there is a to-the-letter implementation of the C++ standard, but that doesn't stop people from using it. The problem is with the horrible error messages that Synopsys generates in these cases. They tell the user essentially nothing about the cause of the error; students are often left with the impression that it's impossible to fix.


Copyright © Greg Baker, last modified 2004-01-28.