e1b775d42b8c259a7c130d8a9a68e743382b4ffd
1 from nmigen
import Module
, Signal
, Cat
, Array
, Const
2 from nmigen
.lib
.coding
import PriorityEncoder
5 from fpbase
import Trigger
9 def __init__(self
, width
, num_ops
=2):
11 self
.num_ops
= num_ops
14 for i
in range(num_ops
):
15 inops
.append(Signal(width
, reset_less
=True))
16 outops
.append(Signal(width
, reset_less
=True))
19 self
.stb
= Signal(num_ops
)
21 self
.ready
= Signal(reset_less
=True)
22 self
.out_decode
= Signal(reset_less
=True)
24 def elaborate(self
, platform
):
26 m
.d
.comb
+= self
.ready
.eq(self
.stb
== Const(-1, (self
.num_ops
, False)))
27 m
.d
.comb
+= self
.out_decode
.eq(self
.ack
& self
.ready
)
28 with m
.If(self
.out_decode
):
29 for i
in range(self
.num_ops
):
31 self
.out_op
[i
].eq(self
.in_op
[i
]),
36 return self
.in_op
+ self
.out_op
+ [self
.stb
, self
.ack
]
40 def __init__(self
, width
, num_ops
):
41 Trigger
.__init
__(self
)
43 self
.num_ops
= num_ops
46 for i
in range(num_ops
):
47 res
.append(Signal(width
))
52 for i
in range(self
.num_ops
):
60 def __init__(self
, width
, num_ops
=2, num_rows
=4):
62 self
.num_ops
= num_ops
63 self
.num_rows
= num_rows
64 self
.mmax
= int(log(self
.num_rows
) / log(2))
66 self
.mid
= Signal(self
.mmax
, reset_less
=True) # multiplex id
67 for i
in range(num_rows
):
68 self
.rs
.append(FPGetSyncOpsMod(width
, num_ops
))
69 self
.rs
= Array(self
.rs
)
71 self
.out_op
= FPOps(width
, num_ops
)
73 def elaborate(self
, platform
):
76 pe
= PriorityEncoder(self
.num_rows
)
77 m
.submodules
.selector
= pe
78 m
.submodules
.out_op
= self
.out_op
79 m
.submodules
+= self
.rs
81 # connect priority encoder
83 for i
in range(self
.num_rows
):
84 in_ready
.append(self
.rs
[i
].ready
)
85 m
.d
.comb
+= pe
.i
.eq(Cat(*in_ready
))
87 active
= Signal(reset_less
=True)
88 out_en
= Signal(reset_less
=True)
89 m
.d
.comb
+= active
.eq(~pe
.n
) # encoder active
90 m
.d
.comb
+= out_en
.eq(active
& self
.out_op
.trigger
)
92 # encoder active: ack relevant input, record MID, pass output
95 m
.d
.sync
+= self
.mid
.eq(pe
.o
)
96 m
.d
.sync
+= rs
.ack
.eq(0)
97 m
.d
.sync
+= self
.out_op
.stb
.eq(0)
98 for j
in range(self
.num_ops
):
99 m
.d
.sync
+= self
.out_op
.v
[j
].eq(rs
.out_op
[j
])
101 m
.d
.sync
+= self
.out_op
.stb
.eq(1)
102 # acks all default to zero
103 for i
in range(self
.num_rows
):
104 m
.d
.sync
+= self
.rs
[i
].ack
.eq(1)
110 for i
in range(self
.num_rows
):
112 res
+= inop
.in_op
+ [inop
.stb
]
113 return self
.out_op
.ports() + res
+ [self
.mid
]