[libre-riscv-dev] 53000 as ME for libre-riscv - bus interfaces?

Luke Kenneth Casson Leighton lkcl at lkcl.net
Sun May 5 21:38:24 BST 2019


---
crowd-funded eco-conscious hardware: https://www.crowdsupply.com/eoma68

On Sun, May 5, 2019 at 6:09 AM Samuel Falvo II <sam.falvo at gmail.com> wrote:
>
> On Sat, May 4, 2019 at 8:32 PM Luke Kenneth Casson Leighton
> <lkcl at lkcl.net> wrote:
> >  ok, so that would mean not being able to work within the nmigen
> > simulation environment: it would be necessary to compile nmigen to
> > verilog, and use e.g. cocotb or other testing framework.
>
> When building the Kestrel, I simulate individual cores.  But when it
> comes to integrating multiple cores together, I test on the FPGA
> itself, building small test harnesses if required.  The Kestrel's
> design is simple enough that I can afford this as a reasonable
> alternative to simulating the entire computer.
>
> I came to adopt this approach back when I was building the first
> Kestrel-2 (with my 16-bit stack CPU, the S16X4).  I was using the
> Xilinx tools at the time, and simulated the whole computer (minus
> video for practical reasons).  Everything looked to be working OK, but
> when synthesized and uploaded to the Spartan 3, the design just
> wouldn't work.  I was forced to debug it with my oscilloscope probing
> various and manually exposed interior signals.  I've never changed my
> approach since those days.
>
> >  so, if you set TileLink as the sole exclusive bus, what are they
>
> I wasn't planning on making TileLink the exclusive bus.  By providing
> IFU, LD, and ST classes as parameters at the time you instantiate the
> CPU, you should be able to make a tailored processor that fits your
> interface requirements.  I envisioned something like this:
>
> from cpu.lib.somewhere import wishbone, tilelink, axi4, axi3
>
> INTERFACE=wishbone   # or tilelink, or axi4, etc.
>
> m.submodules.cpu = KCP53000B(
>     ifu=INTERFACE.IFU, ld=INTERFACE.LD, st=INTERFACE.ST,
>     reset_pc=0xABCDABCC, ..etc..
> )
>
> where "iface" would be a Python module of your choice imported earlier
> (e.g., wishbone, tilelink, axi4, whatever).

 yes.  just passing in the class (usually done as kls) is one way: let
the module that uses it instantiate an instance.  or, create a base
class where the *deriver* is required to add the missing ifu

https://git.libre-riscv.org/?p=ieee754fpu.git;a=blob;f=src/nmutil/concurrentunit.py;h=5f02d7cd9ade7e11364c75aab2079bedd1fac57c;hb=HEAD#l43

or, pass the instance in as a parameter.  Global Variables Bad.  This
Is Not Verilog.  It is pyyythoooon.

:)


> > if however it is written in nmigen, and uses AXI4, there is this:
> > https://github.com/peteut/migen-axi
>
> I am under the understanding that migen and nmigen are not source
> compatible with each other.  Am I mistaken?

 nmigen has a compatibility layer for migen (not the other way round)

> That said, when looking at that repository, I have to admit that my
> relatively inexperienced eyes do not see anything which I could
> possibly reuse in my design.  If I wanted to support axi4, I'd have to
> start from scratch (perhaps using migen-axi as a template to work
> from).  I've /never/ found a prepackaged bus interface repository
> which I could just drop-in and use as-is.

 that's interesting.  it says that they're just not properly designed
as libraries.

> The closest I've been able to find to that ideal for re-use is this:
> https://git.m-labs.hk/M-Labs/HeavyX/src/branch/master/heavycomps/heavycomps
> , but even this would require customization for my specific project.
>
> (I'm glad to have googled that, because it shows me how to use
> Records, which I've been baffled over for some time.

 :)

 we have Had The Discussion on the addition of __setattr__ and
__iter__.  whitequark is pathologically intransigent on the obvious,
logical and natural addition of __setattr__ and __iter__

https://git.libre-riscv.org/?p=ieee754fpu.git;a=blob;f=src/nmutil/iocontrol.py;h=0e2810b5e9a58abd97bfaea1929bcae5baa67283;hb=HEAD#l135

the addition of __setattr__ is pretty obvious: it allows this:

x = Record()
x.src1 = Signal()
x.src2 = Signal()
x.nested = Record()
x.nested.y = Signal()

etc. etc.

the benefit for that should be absolutely clear when it comes to
making classes that derive from Record:

class Interface(Record):
    def __init__(self, width):
        Record.__init__(self)
        self.addr = Signal(width)
        self.data = Signal(width)

where you would have to make some sort of god-awful non-OO-based mess
to dynamically create the record structure otherwise:

class Interface(Record):
    def __init__(self, width):
        structure = (('addr', width), # utterly hopeless
                           ('data', width)) # non-OO mess
        Record.__init__(self, structure)


__iter__ is less obvious, and comes down to Record treating itself as
an ordered sequence of *items* NOT an ordered sequence of *BITS*.

whitequark absolutely and pathologically insists that Record is an
ordered sequence of *BITS* and categorically and pathologically will
not accept that everyone that i have spoken to about Record treats it
as an ordered sequence of *items*.

the difference comes when running "Cat(some_record).eq(some_signal)".

under whitequark's insistence that it be viewed as "bits", the lack of
an __iter__ results in python being forced to use __len__ to work out
the "length", and to perform numerical iteration.

this in turn results in a MASSIVE unreadable digraph of BIT level assignments.

by contrast, the addition of __iter__ returns only a few items, and
nmigen's code is intelligent enough to perform LHS and RHS slicing to
give extremely compact assignments, with very simple and readable
digraphs in ilang.

l.



More information about the libre-riscv-dev mailing list