We had some good conversations about MEP-107 [1]. One
of the concepts introduced during the conversations was
the idea of "interfaces" (thanks Jan D.) instead of
"containers". My original MEP was over-reaching trying
to include all high-level structures that could contain
a Signal object. Through the conversations this was narrowed
to interfaces. An interface is an object passed as a
port to a myhdl module that has a Signal as an attribute.
These interfaces are supported in today's released versions
but you have to explicitly reference each signal in the
module but outside the generators, i.e. in the elaboration
phase (thanks to Oscar D. for pointing out the current support).
Example:
def complex_add(x,y,z):
# reference the Signals in the interface
xr,xi = x.real,x.imag
yr,yi = y.real,y.imag
zr,zi = z.real,z.imag
@always_comb
def hdl_add():
zr.next = xr + yr
zi.next = xi + yi
return hdl_add
Although this is a basic (digestible) example, this design
pattern can be very powerful and will convert with today's
releases.
MEP-107 proposes the feature to convert attributes so
designs have the option to write code like the above example
or by directly accessing the attributes in the generator.
The following would be the complex add with MEP-107:
def complex_add(x,y,z):
@always_comb
def hdl_add():
z.real = x.real + y.real
z.imag = x.imag + y.imag
return hdl_add
Although, this example illustrates the power of using the
attributes directly there are larger examples were using
the local references is preferred. I reiterate interfaces
are supported in today's versions if locally referenced.
Another powerful feature of interfaces is *transactors*.
In this context a transactor is a piece of software that
replaces a digital function with a simplified implementation.
This can have huge speed and test implications on systems.
A simple example is an external serial interface, say
something as simple as an SPI bus. The SPI bus is serial
and typically much slower (per bit) than the system.
The SPI bus can take a lot of simulation cycles to complete
a transfer. If the physical SPI bus Signals are encapsulated
in an object it can also have a transactor function.
def digi_sys(clock, reset, spi_bus, control_bus):
# ...
gspi = spi(clock, reset, spi_bus, mem_bus)
# ...
def spi(clock, reset, spi_bus, mem_bus):
#... define spi slave functionality
#...
if spi_bus.use_transactor:
g = spi_bus.Transactor(clock, reset, mem_bus)
else:
g = (hdl_serial_input, hdl_mem_intf) # ...
return g
More is needed for this example to be complete but I hope
it gives a little idea how a *transactor* can be built
directly into the system. Where I think this is beneficial
is you don't need a separate simulation environment to
remove/replace different interfaces, it can be built directly
into one simulation environment. This simulation/verification
environment can easily be configured to test different
levels of functionality.
That was a lot of background to recap and to get to my
question. I want to update the MEP with this solidified
definition. Should MEP-107 be rewritten or should it be
rejected as is and a new MEP created? I would like to
rewrite/create with an updated focus on:
* developing the concept of *interfaces* and clearly
defining
* example what is currently supported
* proposal for direct usage of attributes
* inclusion possible approach to implement attributes
Thanks,
Chris Felton
[1] http://www.myhdl.org/doku.php/meps:mep-107
|