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.
8 1) p.ready_o is asserted on the initial ("Idle") state, otherwise it keeps low.
9 2) n.valid_o is asserted on the final ("Done") state, otherwise it keeps low.
10 3) The FSM stays in the Idle state while p.valid_i is low, otherwise
11 it accepts the input data and moves on.
12 4) The FSM stays in the Done state while n.ready_i is low, otherwise
13 it releases the output data and goes back to the Idle state.
16 from nmigen
import Elaboratable
, Signal
, Module
17 from nmigen
.back
.pysim
import Simulator
20 class Shifter(Elaboratable
):
21 """Simple sequential shifter
24 * p.data_i.data: Value to be shifted
25 * p.data_i.shift: Shift amount
26 * p.data_i.dir: Shift direction
29 * n.data_o: Shifted value
32 def __init__(self
, width
):
33 self
.data
= Signal(width
, name
="p_data_i")
34 self
.shift
= Signal(width
, name
="p_shift_i")
35 self
.dir = Signal(name
="p_dir_i")
38 def __init__(self
, width
):
39 self
.data_i
= Shifter
.PrevData(width
)
40 self
.valid_i
= Signal(name
="p_valid_i")
41 self
.ready_o
= Signal(name
="p_ready_o")
44 def __init__(self
, width
):
45 self
.data_o
= Signal(width
, name
="n_data_o")
46 self
.valid_o
= Signal(name
="n_valid_o")
47 self
.ready_i
= Signal(name
="n_ready_i")
49 def __init__(self
, width
):
51 self
.p
= self
.PrevPort(width
)
52 self
.n
= self
.NextPort(width
)
54 def elaborate(self
, platform
):
56 # TODO: Implement Module
60 yield self
.p
.data_i
.data
61 yield self
.p
.data_i
.shift
62 yield self
.p
.data_i
.dir
75 m
.submodules
.shf
= dut
= Shifter(8)
76 print("Shifter port names:")
80 # Todo: Implement Simulation
83 if __name__
== "__main__":