We touched on this subject previously: if you have a driver and receiver
in the same module, then the driver is typed locally but the receiver is
looking at the resolved net which maybe a different type. This is
simplified in Verilog-AMS because there are only two types (logic and
analog) that can be mixed and analog usage is identified by different
syntax. In the case of user defined discrete types it may be necessary
to explicitly identify some or all driver and receiver types.
A simple receiver example -
module dff(wire clock...
always @ (posedge clock) ...
here "clock" is going to default to type "logic" (which has the method
"posedge"), but the resolved net could be any type that can be converted
to logic (or supports posedge).
If you want to add (say) a capacitance driver to the model then
(standalone) you could do something like:
module dff(clock...
reg capacitance clock;
// capacitance is a user defined type
initial clock = 1e-12;
....
But these two descriptions don't mix well since "posedge" is not likely
to be a method of the capacitance type.
To disambiguate the usage you can do separate driver and receiver
declarations (with names other than clock), e.g.:
module dff(wire clock...
// create driver "cap" for wire "clock"
driver capacitance cap(clock);
initial cap = 1e-12;
// create receiver "lclock" for wire "clock"
receiver logic lclock(clock);
always @ (posedge lclock) ...
Explicit driver/receiver declaration can have advantages if you want to
pass a reference to a driver to a routine (for assignment, maybe through
DPI) or you want to have multiple drivers or receivers for a particular
signal within the same module (it's also somewhat like Ken Bakalar's
ADMS_Signals proposal).
You can circumvent the problem by pushing the drivers and receivers into
separate modules (as children) so you don't have drivers and receivers
of different types in the same context, but that makes analyzing code
harder (for man and machine). It might make sense to do that for the
case above (since capacitance would normally be a separate component),
but other cases don't partion easily, e.g. if you have a current drive
with voltage sensing you probably want to define all the behavior
together, e.g.-
module foo(wire out...
driver current iout(out);
receiver pwl vout(out); // voltage & slope
...
You might also want to add additional receiver declarations so you can
make assertions about how they relate, e.g.:
receiver pwl vout(out);
receiver logic lout(out);
...
// check logic levels and voltages correlate
if (lout == 1) assert(pwl.voltage > vdd/2);
if (lout == 0) assert(pwl.voltage < vdd/2);
You could do something similar with type casting instead, but I couldn't
come up with a good example.
Just more food for thought ;-)
Kev.
-- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.Received on Fri Aug 20 01:30:31 2010
This archive was generated by hypermail 2.1.8 : Fri Aug 20 2010 - 01:30:41 PDT