[Libre-soc-dev] daily kan-ban update 17nov2021
Luke Kenneth Casson Leighton
lkcl at lkcl.net
Wed Nov 17 11:42:46 GMT 2021
On Wed, Nov 17, 2021 at 9:14 AM Cesar Strauss <cestrauss at gmail.com> wrote:
> Studying the Fetch Unit / Memory Bus interface (FetchUnitInterface and
> BareFetchUnit in src/soc/minerva/units/fetch.py)
ah for now that should be pretty much exactly as self.imem is used, in
TestIssuer.
> so I can plan how to write the Fetch pipeline unit.
you can see, actually, the minerva fetch unit is already a pipeline
(just with a different API - different names for ready/valid), other
than that it is reasonable to assume that the actual behaviour
is identical.
forTestIssuer i set it to "single blip" mode. as in: one single request
is sent in a single-cycle pulse. because of using the minerva pipeline
code you should just be able to leave that running, remember of
course to send advance requests for the PC by auto-incrementing
it. the data structure returned should be:
* corestate containing PC MSR (and svstate)
* raw 32-bit instruction
self.imem.busy_o will be the inversion of... pipe.p.ready_o, something
like that.
notice also, get_insn() is absolutely terrible design. one 64-bit request
is made, then one half *thrown away*. the next cycle could request
exactly the same 64-bits then chuck away the other half!
to "fix" that, the slightly bizarre behaviour is needed where the
(pipelined) in-order Issuer is *still a FSM* - or, actually two FSMs:
* one for fetching
* one for sending
the fetching one just keeps on grabbing 64 bit things sequentially
unless otherwise told to stop
the sending one on receipt of 64 bit things will blat corestate+32-bit
into an output data struct with ready/valid.
if you wanted to get fancy, a small FIFO queue could be in between
those two. hilariously - ironically - a small FIFO has, actually, a
pipeline ready/valid signalling!
therefore, in effect, the two (suggested) FSMs for fetch (one fetch,
one deliver) are actually two separate pipeline phases on their own!
you should also assume that cacheing is taken care of (if there is any),
so should not attempt to make any kind of small instruction caches,
beyond what is needed to split 64-bit "fetched" data into 32-bit "delivered"
o_data packets (corestate+raw32bit)
also, you should assume that the MSR does *not change* unless
there is an instruction which does, in fact, change it. this will, sigh,
need some stall detection "is this instruction likely to change the
MSR" and that includes OP_TRAP (sigh).
so, there is MSR read in the TestIssuer Fetch phase:
# initiate read of MSR. arrives one clock later
comb += self.state_r_msr.ren.eq(1 << StateRegs.MSR)
when the 64-bit fetch data is received, that *exact same* MSR read
should be sent, duplicate copy,in *both* the LO 32-bit *and* the HI
32-bit.
how / why?
because by stalling on any change to MSR, we logically know -
assume - that it has not (cannot) change. therefore, sending a
copy is perfectly fine.
l.
More information about the Libre-soc-dev
mailing list