[libre-riscv-dev] [Bug 64] data handling / io control / data routing API needed
bugzilla-daemon at libre-riscv.org
bugzilla-daemon at libre-riscv.org
Sun Apr 28 12:25:32 BST 2019
http://bugs.libre-riscv.org/show_bug.cgi?id=64
--- Comment #26 from Luke Kenneth Casson Leighton <lkcl at lkcl.net> ---
(In reply to Jacob Lifshay from comment #8)
> > * the use of the function create_data *on* an object - rather than being
> > a function itself - forces a requirement on chaining of segments to
> > provide an *intermediary* data object from which *both* the input
> > object *and* the output object are forced to inherit.
> No, it doesn't actually. all it requires is that the output shape of the
> previous CombSeg == the input shape of the current CombSeg, which is a
> structural comparison, not identity.
you may have misunderstood as i didn't give an example. let me try
to write one. the issue is:
* that there is only one name for the function that creates data.
* that in creating a Chain of Blocks, each Block can no longer
tell the chaining function which data is its input and which its output
so a Stage (Block) is declared... except to be honest i cannot for the
life of me see how to even start to do one Stage, let alone chain two
together!
which brings me on to something very important - a flaw in the proposed
setup of EntryPort and ExitPort - that i missed before.
i have encountered situations - usually involving modules - where it is
NOT POSSIBLE to determine, at constructor time, what data is supposed to
go into the Stage.
the only way to know is during elaboration.
yet, the elaborate function is clearly inappropriate for overloading as
a constructor.
in addition, i also encountered situations - again, involving modules -
where constructing the data ***FAILS*** because the nmigen Modules on
which it critically depends have not yet been set up. only if those
modules are correctly initialised during *elaboration* (and the data
constructed at that time as well) will it work.
*this is one of the many reasons i separated Data out from the I/O control*.
def EntryPort
def __init__(self, name: str):
---> self.data_in = None # CAN ONLY BE SAFELY SET UP LATER <----
self.ready_out = Signal(1, name=name + "_ready_out")
self.valid_in = Signal(1, reset=0, name=name + "_valid_in")
so the subdivision of "labour" so to speak is:
* A "convention" for Data [a generator with eventual yield of something
that derives from Value. yes that includes Consts!]
* PrevControl for IO signalling to previous stage (no data involved)
* NextControl for IO signalling to next stage (no data involved)
* Stage API with ispec, ospec and process function for combinatorial block
and specifying both the input data format and output data format
NO IO SIGNALLING IS INVOLVED. clean separation of data from IO
* StageChain conforming to the same DATA-HANDLING-ONLY Stage API to
chain (potentially hierarchically) Stages together
NO IO SIGNALLING IS INVOLVED. clean separation of data from IO
* ControlBase which brings Stage (data) together with Prev and Next
IO Control
*THIS* is where IO signalling meets Data... yet they are still separate
* ControlBase.connect for connecting chains of ControlBase instances together
(creating actual multi-stage pipelines in the process)
* Derivatives of ControlBase actually manage the prev/next sync, and
pass data around, taking care of when it is "processed", according to
the design of that *derivative*... *NOT* when the *STAGE* decides data
you are proposing:
* Data for mandatory control of data formats (module or class)
* Shape for mandatory restriction of data allocation through one and only
one specifically-named member function of Data (create_data).
* EntryPort for IO signalling to previous stage *AND* allocation of DATA
(which will fail under certain circumstances)
* ExitPort for IO signalling to next stage *AND* allocation of DATA
(which will fail under certain circumstances)
* CombSeg for bringing previous and next data together (despite the
fact that Block *ALSO* brings data together).
NO PROCESSING IS INVOLVED OR POSSIBLE (that's CombSegFn)
* CombSegFn for providing a means of (combinatorially) linking input data
to processing to output.
This is basically functionally directly equivalent to the Stage API
(except that it is mandatory that it be a nmigen module, where the
Stage API permits non-module scenarios, hence the difference between
Stage.process and Stage.setup)
* Block for bringing EntryPort and ExitPort together (despite CombSeg
already *having* Data)
* CombBlock as a really unclear (and unnecessary) workaround for CombSeg
already having in/out Data...
the proposed API goes awry in several places:
* certain Blocks may wish to pre-process or post-process, depending on
design. CombSegFn prevents and prohibits that decision-making process
by *BLOCKS THEMSELVES* - by *design*
* Entry/ExitPort creating data in the constructor runs into difficulties
with nmigen module elaboration
* several design restrictions which limit the scope of possibilities.
* a workaround (Block.wrap) for double-allocation (by design) of data,
where only one class is strictly necessary to take responsibility for
data emplacement.
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the libre-riscv-dev
mailing list