Define ports for a simple sequential Shifter
[soc.git] / src / soc / experiment / alu_fsm.py
1 """Simple example of a FSM-based ALU
2
3 This demonstrates a design that follows the valid/ready protocol of the
4 ALU, but with a FSM implementation, instead of a pipeline.
5
6 The basic rules are:
7
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.
14 """
15
16 from nmigen import Elaboratable, Signal, Module
17 from nmigen.back.pysim import Simulator
18
19
20 class Shifter(Elaboratable):
21 """Simple sequential shifter
22
23 Prev port data:
24 * p.data_i.data: Value to be shifted
25 * p.data_i.shift: Shift amount
26 * p.data_i.dir: Shift direction
27
28 Next port data:
29 * n.data_o: Shifted value
30 """
31 class PrevData:
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")
36
37 class PrevPort:
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")
42
43 class NextPort:
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")
48
49 def __init__(self, width):
50 self.width = width
51 self.p = self.PrevPort(width)
52 self.n = self.NextPort(width)
53
54 def elaborate(self, platform):
55 m = Module()
56 # TODO: Implement Module
57 return m
58
59 def __iter__(self):
60 yield self.p.data_i.data
61 yield self.p.data_i.shift
62 yield self.p.data_i.dir
63 yield self.p.valid_i
64 yield self.p.ready_o
65 yield self.n.ready_i
66 yield self.n.valid_o
67 yield self.n.data_o
68
69 def ports(self):
70 return list(self)
71
72
73 def test_shifter():
74 m = Module()
75 m.submodules.shf = dut = Shifter(8)
76 print("Shifter port names:")
77 for port in dut:
78 print("-", port.name)
79 sim = Simulator(m)
80 # Todo: Implement Simulation
81
82
83 if __name__ == "__main__":
84 test_shifter()