[libre-riscv-dev] KCP53000B micro-architecture thoughts

Luke Kenneth Casson Leighton lkcl at lkcl.net
Sun Jun 2 20:26:09 BST 2019

On Monday, June 3, 2019, Samuel Falvo II <sam.falvo at gmail.com> wrote:

> On Sun, Jun 2, 2019 at 5:27 AM Luke Kenneth Casson Leighton
> <lkcl at lkcl.net> wrote:
> >  you do need an "Issue" signal as a way to "capture" the opcode, and i
> In my microarchitecture, that's a function of the FU; the i_inst_xxx
> inputs on the CU will be tapped off the registered instruction fields
> in the FU.

Hmm hmm, as long as it is a clock behind the issue signal (on a sync) and
cancelled on a GOWR (again on a sync) it should be fine.

It sounds like you are merging (moving) the functionality that should be in
the CU into the FU, which should be fine as long as it really is the same.

> > * go_sum (aka go_read) captures operand1 and operand2 (if present)
> go_sum is the clock-delayed version of go_read in my design.  I
> created this timing diagram ( https://tinyurl.com/yyxeem4z ) to help
> illustrate how an ADD or SUB instruction would flow through the unit,
> and includes both the CU and FU signals as I understand them.  I also
> incorporated your recommended name changes.  (Scoreboard signals
> aren't present because I haven't gotten that far yet.)
> I'm wondering about naming consistency though; right now, GO_SUM is a
> stage in the state machine, while GO_READ and GO_WRITE are basically
> acknowledgements.  I'm thinking of renaming GO_SUM to SUM_REQ.

Yes, please, do, if the CU is not a 6600 style CU, as it already caused

> In other words, signals in the form of GO_XXX are always
> acknowledgements from an arbiter, XXX_REQ are always requests from the
> FU, and XXX_ACK are always acknowledgements from the CU (but, only if
> required; in the timing diagram above, I didn't need any since we're
> just producing a sum.  For memory interface, we'd need two ACKs, one
> each for the address and data phase of the interconnect).
> >  with m.If(self.issue_i): # capture opcode on issue with SYNC
> >      sync += [
> >     inst_src2_r.eq(self.i_inst_src2),
> >     inst_imm12_r.eq(self.i_inst_imm12)
> >     inst_cin_r.eq(self.i_inst_cin)
> > ]
> >
> > and likewise capture src1 on go_sum_i:
> > with m.if(self.go_sum_i):
> >      sync += [
> >           trunk_data1_r.eq(self.i_trunk_data1),
> >           trunk_data2_r.eq(self.i_trunk_data2),
> Bingo; I'm building my design so as to not use SRFFs.  It makes things
> somewhat more challenging timing-wise, but it's friendlier to the
> smaller, simpler logic-cells that the iCE40HX family uses.

Once I have some time (and a formal unit test) i will look at pulling the
SR Latches. Not yet though.

> > remember though that you *need* that "busy" signal, which would be done
> as:
> Because BUSY is part of the state machine that drives the whole thing,
> that will also reside in the FU logic.

Ok. Just make absolutely sure BUSY is 1 clock behind ISSUE.

Otherwise you get combinatorial loop hell.


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

More information about the libre-riscv-dev mailing list