SystemVerilog and channels
Subject: SystemVerilog and channels
From: Christian Burisch (burisch@co-design.com)
Date: Thu Aug 01 2002 - 09:52:58 PDT
Hi Guys,
Dave Kelf forwarded the thread proposing channels in SystemVerilog.
Some
comments:
First of all Stuart hit the nail on the head that there is some
nomenclature
confusion, because sometimes the same term is used in
SystemVerilog/SUPERLOG
and SystemC with different meanings.
>From: "Stuart Swan" <stuart@cadence.com>
>SystemC 2.0 SystemVerilog
>----------- -------------
>channel interface
>interface modport
I propose to use the SystemVerilog terminology by default and state
explicitely
if you mean something else, like "SystemC channels" or
"SystemC interfaces".
In SystemVerilog and SUPERLOG a module encapsulates implementation,
while
an interface encapsulates communication.
Different levels of abstractions are possible in both modules and
interfaces.
You can have a module at an architectural level, at RTL or at gate
level,
similarly you can model the communication in an interface with a
cycle
accurate protocol or at higher, more abstract levels.
The easiest thing you can do with an interface is just to use it as a
wire
bundle.
So an interface is to a wire in SystemVerilog like a struct is to
an int in C/C++/SystemVerilog/SUPERLOG, a means of grouping the
data.
You can also include the way the data is sent and received in the
interface,
i.e. its protocol.
In this case an interface is to a wire like a class is to an int in C++
or SUPERLOG,
a means of grouping the data and the protocol.
(I am using the term protocol to include the sequence of data being
exchanged, not
just the data types.)
The tasks and functions inside the interface and class are referred to as
"methods"
in OO parlance.
For the former use you can look at a wire as the simplest built in
interface.
There is no built in interface for the latter usage.
What you are suggesting amounts to defining a "channel" in
SystemVerilog as
the simplest possible built in interface.
Sounds like a good idea and we did consider this a few years ago, but
we
didn't do it for reasons that I'll outline below.
Here is an interface in SystemVerilog with a read and write task which
block.
It is unidirectional, if you need bidirectional, then just use 2 of
them.
The data_type is parameterizable, (this is what you call
"interface" in SystemC.)
interface channel;
parameter type data_type = bit;
data_type data;
bit valid;
task write(input data_type d);
wait(valid == 0);
data = d;
valid = 1;
endtask
task read(output data_type d);
wait(valid == 1);
d = data;
valid = 0;
endtask
endinterface
You can add queuing functionality by including a fixed length
FIFO,
if you want:
interface channel;
parameter type data_type = bit;
parameter int max = 10;
data_type fifo[max:0];
int num=0, high=0, low=0;
task write(input data_type d);
wait(num <= max);
fifo[high++]=d;
if (high > max) high = 0;
num++;
endtask
task read(output data_type d);
wait(num > 0);
d = fifo[low++];
if (low > max) low = 0;
num--;
endtask
endinterface
With SUPERLOG you can also have unbounded queues very
easily:
interface channel;
parameter type data_type = bit;
data_type q[0:$];
task write(input data_type d);
q = {q, d};
endtask
task read(output data_type d);
wait(q.$num > 0);
d = q[0];
q = q[1:$];
endtask
endinterface
Note that this example uses SUPERLOG queues which are
not
included as part of SystemVerilog, as when the initial
SUPERLOG ESS donation was executed, this higher level behavior
was not specified as part of the implementation requirements.
The use of queues within interfaces does allow additional
functionality as requested by Kevin.
The reason we did not include a built in interface (which you may want
to
call "channel") which has this functionality is because we
would have to
define names for the write and read tasks inside, which is quite
clunky.
We did consider allowing interfaces to be used in assigments,
similarly
to Kevin's suggestion. Then we can do away with the read and write task
names
in their calls.
i.e. instead of
channel.write(out);
channel.read(in);
you could write:
channel = out;
in = channel;
But of course this syntax would be terrible, because each line could
be
blocking, so looking at the code fragment you would not be able to see
that.
Verilog assigments are in zero time, so we should not mess with
that.
(and the parser would go schizo too)
We could make both of the methods functions (instead of tasks i.e. no
timing
inside), and use Kevin's method of triggering off the interface to supply
the
timing for one of them:
channel = out;
@(channel) in = channel;
This works, but only if you remain at the abstract level. When you
refine
the interface to something real (PCI, SCSI etc) then suddenly both
read
and write take time and you are stuck.
In your posts you talked about three different uses of interfaces.
They are, in order of importance,
1) System Modelling
Here you define a system at a high level and you must be
able
to refine it down to lower levels of abstraction. For this reason
we
don't want a built-in interface where the read and/or the write
must
be a (zero delay) function.
2) Interaction with SystemC
A SystemVerilog interface is a natural place to make a
connection to
other languages, such as C/C++ or SystemC.
3) Multiprocessing Software
Actually I agree with you that SUPERLOG/SystemVerilog may turn
out
to be interesting for multiprocessing software, but this is a
long
way away in the future, (even though there is a research project
about
this at a university).
In any case I believe that Occam is not a good role model for
that.
I hope this made sense and that I explained our reasoning behind
making
interfaces as they are.
Regards,
Christian
This archive was generated by hypermail 2b28
: Thu Aug 01 2002 - 08:49:46 PDT