Subject: [sv-ec] More on clocking domains and related stuff...
From: Stefen Boyd (stefen@boyd.com)
Date: Tue Jan 28 2003 - 14:17:32 PST
Given some more thoughts (i.e. nightmares) about clocking
domains all the related stuff (cruft?)...
After my comments, I've got some proposals that fix
the problems with clocking domains, remove the need for the
separate verification phase, and remove the need for a
program block.
I see that we need to go one of two directions with
the clocking domains:
* Get rid of them because they aren't needed and
they aren't necessary to access the design.
* Fix them so they really provide an extensible way
to access the design.
1) It's too verbose
Taking the example from 13.2:
clocking bus @(posedge clock1);
default input #10ns output #2ns
input data, ready, enable = top.mem1.enable;
output negedge ack;
input #1step addr;
endclocking
If I want to use one of these signals in verification code,
I have to write bus.xxx everywhere...
As an alternative (Verilog 2001 code):
`define negclk @(negedge clock1)
`define posclk @(posedge clock1)
wire #10ns data, ready, enable = top.mem1.enable;
wire #1step addr;
initial begin
...
`posclk
... // do something intellegent ;}
ack <= `negclk newvala;
addr <= #1step newvalb;
...
end
Note:
* I don't need hierarchical references to names as they
stay in my scope.
* Input side is easy to do much more compactly than clocking
domain, although outputs are a bit more work, it's about
as much extra typing as having to put the hierarchical
reference to the clocking domain.
The bottom line is that I don't get a big benefit in code
reduction from adding this clocking domain construct.
2) It forces the addition of the design phase
I may not understand this correctly, but it looks
like the equivalent Verilog code looks something like:
always @(posedge clk) begin: equiv_if
reg data;
data = design.data;
end
Since data get's the updated value in the active events, we
have to wait to start using it until sometime after the
posedge clk... I suppose we could wait until nba time so
long as the clock edge happens as an active event and not
an nba.
But now that we're using these sampled values instead
of directly using the value, we're stuck waiting 'till
later to run our verification code that uses this signal.
So not only does it not make a significant reduction in
typing, but when I have no delays, it forces my verification
code to have to run later... So long as my design uses
nbas for flops, I could have run my code in the active
events... but now I'm stuck waiting. Granted if you don't
use nbas for flops, you have other problems that won't
be fixed by design & verification phases.
3) It isn't extensible
If I have a 24 port GEth DUT I'm testing, I could use an
instance array of interfaces to pass to verification tasks
that would access each port. But if I wanted to use a
clock domain to do the same kind of work, I'd have to have
24 clock domains defined and either pass all the variables
to the same task, or write 24 almost identical tasks to
access each port.
4) What I'd like to see
* Shorthand notation for interfaces
The only value of clocking domains is to allow easy
*non-zero* setup samples and driving holds.
Making this a shorthand notation that cuts down on
typing is attractive, but the current syntax doesn't
achieve this goal.
Since interfaces *are* extensible, I would add the shorthand
to interfaces... I would try putting it on modports:
interface simple_bus; // Define the interface
logic req, gnt;
logic [7:0] addr, data;
logic [1:0] mode;
logic start, rdy;
modport dut (input req, addr, mode, start, clk,
output gnt, rdy,
inout data);
modport tb @(posedge clk) (input #1step gnt, rdy, clk,
output #2 req, addr, mode, start,
inout data);
endinterface: simple_bus
Rules:
> Looks like from the bnf that we can't put skew on inout
in clocking domain, so it wouldn't be allowed here either...
> Basically, the syntax I'm proposing is very similar to
the proposed clocking syntax, so we should be able to have
the default, etc.
> The signals sampled or driven would
> The clock isn't required. If you already dealt with your
timing control happening on clock edges, this would simply
get you old values of inputs and would delay writes to
outputs.
> Writes to outputs (even when no clock is specified) would still
happen in the queue associated with that type of assignment.
Blocking assignments would go into active events (e.g. #2 time
units later) and non-blocking events would go into the nba
queue.
* implicit interface modport connections
The previous unification of clocking with interfaces makes
clocking domains extensible, but doesn't solve the verbosity
problem. You still have to write clocking_domain.signal Although
using really short clocking domains helps reduce the typing, the
names become useless. What I would like to see is the ability
to use an interface in a way that exposes the signals of
that interface's modport so they can be accessed without the
hierarchical reference.
Proposal:
Instances may use an interface with a modport and make
all the signals of the modport available in the same
scope.
Example:
module chip_test(simple_bus.tb(.*));
...
endmodule
Rules
> If the modport names clash with other
identifiers at the module scope (including
other implicit modports), an error will be
generated.
* ##0
The problem with the program block is that it solves
a general problem in a very restricted and limited way.
The biggest reason for it's existence is that it provides
a special place to execute code in the verification phase.
The problem of needing to wait for a "stable" point
in the simulation is a general one. Dennis B. and Jay have
mentioned that this is a general request they often receive.
I submit that what we need is to simply define a new part
of the event queue, just before rosync. In the HDL you
could reach this by using ##0. Presumably, the PLI will
be enhanced to support waiting until this time. Assertions
could be defined to wait until this time to evaluate.
Regards,
Stefen
--------------------
Stefen Boyd Boyd Technology, Inc.
stefen@BoydTechInc.com (408)739-BOYD
www.BoydTechInc.com (408)739-1402 (fax)
This archive was generated by hypermail 2b28 : Tue Jan 28 2003 - 14:17:45 PST