from nmigen import Signal, Cat, Const, Mux, Module
from nmigen.cli import verilog, rtlil
+from nmigen.hdl.rec import Record, Layout
+
from collections.abc import Sequence
"""
def __init__(self):
- self.i_valid = Signal(name="p_i_valid") # >>in
- self.o_ready = Signal(name="p_o_ready") # <<out
+ self.i_valid = Signal(name="p_i_valid") # prev >>in self
+ self.o_ready = Signal(name="p_o_ready") # prev <<out self
def connect_in(self, prev):
""" helper function to connect stage to an input source. do not
* o_data : an output - added by the user of this class
"""
def __init__(self):
- self.o_valid = Signal(name="n_o_valid") # out>>
- self.i_ready = Signal(name="n_i_ready") # <<in
+ self.o_valid = Signal(name="n_o_valid") # self out>> next
+ self.i_ready = Signal(name="n_i_ready") # self <<in next
def connect_to_next(self, nxt):
""" helper function to connect to the next stage data/valid/ready.
""" makes signals equal: a helper routine which identifies if it is being
passsed a list (or tuple) of objects, and calls the objects' eq
function.
+
+ complex objects (classes) can be used: they must follow the
+ convention of having an eq member function, which takes the
+ responsibility of further calling eq and returning a list of
+ eq assignments
+
+ Record is a special (unusual, recursive) case, where the input
+ is specified as a dictionary (which may contain further dictionaries,
+ recursively), where the field names of the dictionary must match
+ the Record's field spec.
"""
if not isinstance(o, Sequence):
o, i = [o], [i]
res = []
for (ao, ai) in zip(o, i):
- res.append(ao.eq(ai))
+ #print ("eq", ao, ai)
+ if isinstance(ao, Record):
+ for idx, (field_name, field_shape, _) in enumerate(ao.layout):
+ if isinstance(field_shape, Layout):
+ rres = eq(ao.fields[field_name], ai.fields[field_name])
+ else:
+ rres = eq(ao.fields[field_name], ai[field_name])
+ res += rres
+ else:
+ res.append(ao.eq(ai))
return res
"""
def __init__(self, stage):
""" pass in a "stage" which may be either a static class or a class
- instance, which has three functions:
+ instance, which has four functions (one optional):
* ispec: returns input signals according to the input specification
* ispec: returns output signals to the output specification
* process: takes an input instance and returns processed data
+ * setup: performs any module linkage if the stage uses one.
User must also:
* add i_data member to PrevControl and
def ports(self):
return [self.p.i_valid, self.n.i_ready,
self.n.o_valid, self.p.o_ready,
- self.p.i_data, self.n.o_data
+ self.p.i_data, self.n.o_data # XXX need flattening!
]
"""A simple pipeline stage containing combinational logic that can execute
completely in one clock cycle.
- Parameters:
- -----------
- input_shape : int or tuple or None
- the shape of ``input.data`` and ``comb_input``
- output_shape : int or tuple or None
- the shape of ``output.data`` and ``comb_output``
- name : str
- the name
-
Attributes:
-----------
input : StageInput
The pipeline input
output : StageOutput
The pipeline output
- comb_input : Signal, input_shape
- The input to the combinatorial logic
- comb_output: Signal, output_shape
+ r_data : Signal, input_shape
+ A temporary (buffered) copy of a prior (valid) input
+ result: Signal, output_shape
The output of the combinatorial logic
"""