Re: SystemVerilog and channels


Subject: Re: SystemVerilog and channels
From: Christian Burisch (burisch@co-design.com)
Date: Fri Aug 02 2002 - 06:06:07 PDT


At 12:47 PM 8/1/02 -0700, Kevin Cameron wrote:
  Christian Burisch wrote:


Hi Guys,

.....

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;
There was also "channel <= out" for a non-blocking write.
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.
I'm not sure what you mean by "stuck". There is a difference between
"stuck" as in "blocked" which is probably OK, and "stuck" as in "deadlocked"
which means your design is broken.

"Stuck" as in "caught in a jam" :-)
In your first high level model the architect uses a zero delay write to
transmit data to the channel. When the design is refined to use a real
interface, both the reads and write will take time.

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.
I don't think I asked for that. The suggested syntax adds a protocol type
to the channel which dictates the minimum packet size, it only blocks
if you deliberately overread. The following code would not block:

     channel byte data;
     byte         buff[100];
     integer      i = 0;
     always @(data) begin
             buff[i++] = data;
             if (i == 100) begin // full
              // process it...
              i = 0;
             end
     end

Here is the SystemVerilog Version.
First define a channel with the byte type inside it:

interface channel;
  byte data;
  bit valid=0;

  task transmitbyte(input byte d);
   wait(valid == 0);
   data = d;
   valid = 1;
  endtask

  task receivebyte(output byte d);
    wait(valid == 1);
    d = data;
    valid = 0;
   endtask
endinterface

Then your code becomes:

     channel c;
     byte         buff[99:0];
     integer      i = 0;
     always begin
             c.receivebyte(buff[i++]);
             if (i == 100) begin // full
              // process it...
              i = 0;
             end
     end

But actually, this receives bytes in packets of 100, so a better place
to put the read loop is inside the interface:

First define a packet:

typedef byte[99:0] packet;

Then add this task to the interface channel:

task automatic receivepacket(output packet p);
    for (int i=0; i <= 99; i++)
      receivebyte(p[i]);
endtask

Then your code becomes:

     channel c;
     packet p;
     always begin
             c.receivepacket(p);
            // process it...
            end
     end

But the channel needs to talk to something, typically the packet transmission
would happen in another module, so we need to use the interface channel to
connect the modules:

module kevin(channel c);
     packet p;
     always begin
             c.receivepacket(p);
            // process it...
            end
     end
endmodule
 
You have now separated the communication (interface) and the processing
of the data (module).

- when you refine that the "@(data)" would probably just become an
"@(clock)". It helps to have an asynchronous definition because the
synthesis tools don't see an artificial dependency on a clock and just
see the data flow.
2) Interaction with SystemC
   A SystemVerilog interface is a natural place to make a connection to
   other languages, such as C/C++ or SystemC.
But what mechanism do you plan to use to access the SV Interface from C++?
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.
Occam/CSP is an excellent model for HDL parallel processing, it is semantically
most like what both system level designers and hardware designers do, and
scales well to big systems (beyond SoC). Occam itself was a bit short on high
level language constructs (e.g. struct) and had whacky syntax, but the concept
was good.

I had to learn Occam at University (when Transputers were in vogue).
I agree with you on the whacky syntax!

I hope this made sense and that I explained our reasoning behind making
interfaces as they are.

Regards,
Christian
I think it does, thanks.

Here's how I was thinking of using them -

NSC's latest thin client processor (the GX2) is based on a bus architecture
(called Geodelink) which is designed for high speed communication from
point-to-point. A Geodelink node is basically a 6-port hub where each port
has address decoding and caching and the ports can  talk to other nodes.

http://www.national.com/appinfo/solutions/files/GeodeG2Xv3.pdf
 (node == Geodelink Interface Unit)

If I was going to rewrite the code for the GX2 in SV using interfaces I
could do it a few different ways, two would be:

  a) Write a single interface for an entire node (with 6 modports).

  b) Use 6 instances of a Geodelink-port interface and a module to
      describe the internals of the node.

Not being able to instantiate modules in interfaces makes it difficult to do
(a), so I'm probably going to use (b) and the implementation of the node
internals will depend on the usage - design,client dv or application
software.

Not being able to instance modules is not a limitation, and should not stop you
from doing what you want to do. It has been disallowed because it would be
confusing to place hardware inside a communication protocol.

What you could do is define the node interface with all the signals inside
it:
interface node_intf_i;
  ...
endinterface

Then in the design you can use an array of them:

module hub6 (node_intf_i node_intf[5:0], ...
  ...
endmodule

If you prefer to collect the interfaces together:

interface node_intf_bundleof6;
  node_intf_i node_intf[5:0];
endinterface

If you have a separate model to connect to each interface stream:

module hub6 (node_intf_i node_intf[5:0], ...
  hub1 h0(node_intf[0], ...
  hub1 h1(node_intf[1], ...
  hub1 h2(node_intf[2], ...
  hub1 h3(node_intf[3], ...
  hub1 h4(node_intf[4], ...
  hub1 h5(node_intf[5], ...
endmodule

You can even parameterize it with a generate.

These header fragments above do not imply a specific level of abstraction,
i.e. the modules could be architectural models, RTL or gate level.

This is popular with SystemVerilog/SUPERLOG users because it means that
could can easily mix and match different levels of abstractions in the
same simulation....

For design of the node itself I would expect to be working from RTL down,
for the node and RTL, behavior or C++ for the clients.

.... Here you go :-)


For client design (e.g. memory controller and CPU cache) I would expect to
use the same SV interfaces again but have a behavioral or C++ model for
the node.


From an application software development perspective I'm not really interested
in the internals of the node, and since the data transfer is pipelined rather than
direct memory read/write I'd like to use abstract data channels to and between
the SV interfaces for efficiency (using the same interfaces as above). Target
clients would be RTL and down for design verification, behavioral for software
development. If I can use Unix pipes for the channels I would probably debug
my C/C++ code in a seperate process.

- Is my thinking in line with Co-Design's (or anyone else's)?

Absolutely. This is what interfaces are all about. (We'd probably prefer to keep
the C code in the same process to avoid the slow pipes and sockets.)

Regards,

Christian



This archive was generated by hypermail 2b28 : Fri Aug 02 2002 - 05:05:45 PDT