1 """Simple example of a FSM-based ALU
3 This demonstrates a design that follows the valid/ready protocol of the
4 ALU, but with a FSM implementation, instead of a pipeline. It is also
5 intended to comply with both the CompALU API and the nmutil Pipeline API
6 (Liskov Substitution Principle)
10 1) p.ready_o is asserted on the initial ("Idle") state, otherwise it keeps low.
11 2) n.valid_o is asserted on the final ("Done") state, otherwise it keeps low.
12 3) The FSM stays in the Idle state while p.valid_i is low, otherwise
13 it accepts the input data and moves on.
14 4) The FSM stays in the Done state while n.ready_i is low, otherwise
15 it releases the output data and goes back to the Idle state.
19 from nmigen
import Elaboratable
, Signal
, Module
20 from nmigen
.back
.pysim
import Simulator
21 from soc
.fu
.cr
.cr_input_record
import CompCROpSubset
28 class Shifter(Elaboratable
):
29 """Simple sequential shifter
32 * p.data_i.data: Value to be shifted
33 * p.data_i.shift: Shift amount
34 * p.data_i.dir: Shift direction
37 * n.data_o: Shifted value
40 def __init__(self
, width
):
41 self
.data
= Signal(width
, name
="p_data_i")
42 self
.shift
= Signal(width
, name
="p_shift_i")
43 self
.dir = Signal(name
="p_dir_i")
44 self
.ctx
= Dummy() # comply with CompALU API
47 return [self
.data
, self
.shift
]
50 def __init__(self
, width
):
51 self
.data
= Signal(width
, name
="n_data_o")
57 def __init__(self
, width
):
58 self
.data_i
= Shifter
.PrevData(width
)
59 self
.valid_i
= Signal(name
="p_valid_i")
60 self
.ready_o
= Signal(name
="p_ready_o")
63 def __init__(self
, width
):
64 self
.data_o
= Shifter
.NextData(width
)
65 self
.valid_o
= Signal(name
="n_valid_o")
66 self
.ready_i
= Signal(name
="n_ready_i")
68 def __init__(self
, width
):
70 self
.p
= self
.PrevPort(width
)
71 self
.n
= self
.NextPort(width
)
73 # more pieces to make this example class comply with the CompALU API
74 self
.op
= CompCROpSubset()
75 self
.p
.data_i
.ctx
.op
= self
.op
76 self
.i
= self
.p
.data_i
._get
_data
()
77 self
.out
= self
.n
.data_o
._get
_data
()
79 def elaborate(self
, platform
):
81 # TODO: Implement Module
85 yield self
.p
.data_i
.data
86 yield self
.p
.data_i
.shift
87 yield self
.p
.data_i
.dir
92 yield self
.n
.data_o
.data
100 m
.submodules
.shf
= dut
= Shifter(8)
101 print("Shifter port names:")
103 print("-", port
.name
)
105 # Todo: Implement Simulation
108 if __name__
== "__main__":