X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fadd%2Fsinglepipe.py;h=68b62e432d4fc6022b99361c3358d01638414fce;hb=6bff1a997f3846872cf489c24b5c01426c4dc97c;hp=3675ea90d75f8e854c7e6d657196605e98ccb39a;hpb=cc748d2869ae9670c8d8662f3ebd99255232acc1;p=ieee754fpu.git diff --git a/src/add/singlepipe.py b/src/add/singlepipe.py index 3675ea90..68b62e43 100644 --- a/src/add/singlepipe.py +++ b/src/add/singlepipe.py @@ -198,13 +198,12 @@ class ControlBase(StageHelper, Elaboratable): # set up the input and output data if stage is not None: - self._new_data(self, self, "data") + self._new_data("data") - def _new_data(self, p, n, name): + def _new_data(self, name): """ allocates new data_i and data_o """ - self.p.data_i = _spec(p.stage.ispec, "%s_i" % name) - self.n.data_o = _spec(n.stage.ospec, "%s_o" % name) + self.p.data_i, self.n.data_o = self.new_specs(name) @property def data_r(self): @@ -280,9 +279,10 @@ class ControlBase(StageHelper, Elaboratable): # connect front and back of chain to ourselves front = pipechain[0] # first in chain end = pipechain[-1] # last in chain - self._new_data(front, end, "chain") # NOTE: REPLACES existing data + self.set_specs(front, end) # sets up ispec/ospec functions + self._new_data("chain") # NOTE: REPLACES existing data eqs += front._connect_in(self) # front p to our p - eqs += end._connect_out(self) # end n to out n + eqs += end._connect_out(self) # end n to our n return eqs @@ -735,14 +735,20 @@ class FIFOControl(ControlBase): fwft=True, pipe=False): """ FIFO Control - * :depth: number of entries in the FIFO - * :stage: data processing block - * :fwft: first word fall-thru mode (non-fwft introduces delay) - * :buffered: use buffered FIFO (introduces extra cycle delay) + * :depth: number of entries in the FIFO + * :stage: data processing block + * :fwft: first word fall-thru mode (non-fwft introduces delay) + * :pipe: specifies pipe mode. - NOTE 1: FPGAs may have trouble with the defaults for SyncFIFO - (fwft=True, buffered=False). XXX TODO: fix this by - using Queue in all cases instead. + when fwft = True it indicates that transfers may occur + combinatorially through stage processing in the same clock cycle. + This requires that the Stage be a Moore FSM: + https://en.wikipedia.org/wiki/Moore_machine + + when fwft = False it indicates that all output signals are + produced only from internal registers or memory, i.e. that the + Stage is a Mealy FSM: + https://en.wikipedia.org/wiki/Mealy_machine data is processed (and located) as follows: @@ -766,27 +772,29 @@ class FIFOControl(ControlBase): fifo = Queue(fwidth, self.fdepth, fwft=self.fwft, pipe=self.pipe) m.submodules.fifo = fifo - # store result of processing in combinatorial temporary - result = _spec(self.stage.ospec, "r_temp") - m.d.comb += nmoperator.eq(result, self.data_r) + def processfn(data_i): + # store result of processing in combinatorial temporary + result = _spec(self.stage.ospec, "r_temp") + m.d.comb += nmoperator.eq(result, self.process(data_i)) + return nmoperator.cat(result) + + ## prev: make the FIFO (Queue object) "look" like a PrevControl... + m.submodules.fp = fp = PrevControl() + fp.valid_i, fp._ready_o, fp.data_i = fifo.we, fifo.writable, fifo.din + m.d.comb += fp._connect_in(self.p, fn=processfn) + + # next: make the FIFO (Queue object) "look" like a NextControl... + m.submodules.fn = fn = NextControl() + fn.valid_o, fn.ready_i, fn.data_o = fifo.readable, fifo.re, fifo.dout + connections = fn._connect_out(self.n, fn=nmoperator.cat) - # connect previous rdy/valid/data - do cat on data_i - # NOTE: cannot do the PrevControl-looking trick because - # of need to process the data. shaaaame.... - m.d.comb += [fifo.we.eq(self.p.valid_i_test), - self.p.ready_o.eq(fifo.writable), - nmoperator.eq(fifo.din, nmoperator.cat(result)), - ] - - # connect next rdy/valid/data - do cat on data_o (further below) - connections = [self.n.valid_o.eq(fifo.readable), - fifo.re.eq(self.n.ready_i_test), - ] + # ok ok so we can't just do the ready/valid eqs straight: + # first 2 from connections are the ready/valid, 3rd is data. if self.fwft: - m.d.comb += connections # combinatorial on next ready/valid + m.d.comb += connections[:2] # combinatorial on next ready/valid else: - m.d.sync += connections # unbuffered fwft mode needs sync - data_o = nmoperator.cat(self.n.data_o).eq(fifo.dout) + m.d.sync += connections[:2] # non-fwft mode needs sync + data_o = connections[2] # get the data data_o = self._postprocess(data_o) # XXX TBD, does nothing right now m.d.comb += data_o