From a31b58253ed42a980007b25d4f521ba3a26d909c Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Thu, 28 Mar 2019 14:36:42 +0000 Subject: [PATCH] move inputgroup to separate module --- src/add/inputgroup.py | 115 +++++++++++++++++++++++++++++++ src/add/nmigen_add_experiment.py | 108 ----------------------------- src/add/test_inputgroup.py | 2 +- 3 files changed, 116 insertions(+), 109 deletions(-) create mode 100644 src/add/inputgroup.py diff --git a/src/add/inputgroup.py b/src/add/inputgroup.py new file mode 100644 index 00000000..e1b775d4 --- /dev/null +++ b/src/add/inputgroup.py @@ -0,0 +1,115 @@ +from nmigen import Module, Signal, Cat, Array, Const +from nmigen.lib.coding import PriorityEncoder +from math import log + +from fpbase import Trigger + + +class FPGetSyncOpsMod: + def __init__(self, width, num_ops=2): + self.width = width + self.num_ops = num_ops + inops = [] + outops = [] + for i in range(num_ops): + inops.append(Signal(width, reset_less=True)) + outops.append(Signal(width, reset_less=True)) + self.in_op = inops + self.out_op = outops + self.stb = Signal(num_ops) + self.ack = Signal() + self.ready = Signal(reset_less=True) + self.out_decode = Signal(reset_less=True) + + def elaborate(self, platform): + m = Module() + m.d.comb += self.ready.eq(self.stb == Const(-1, (self.num_ops, False))) + m.d.comb += self.out_decode.eq(self.ack & self.ready) + with m.If(self.out_decode): + for i in range(self.num_ops): + m.d.comb += [ + self.out_op[i].eq(self.in_op[i]), + ] + return m + + def ports(self): + return self.in_op + self.out_op + [self.stb, self.ack] + + +class FPOps(Trigger): + def __init__(self, width, num_ops): + Trigger.__init__(self) + self.width = width + self.num_ops = num_ops + + res = [] + for i in range(num_ops): + res.append(Signal(width)) + self.v = Array(res) + + def ports(self): + res = [] + for i in range(self.num_ops): + res.append(self.v[i]) + res.append(self.ack) + res.append(self.stb) + return res + + +class InputGroup: + def __init__(self, width, num_ops=2, num_rows=4): + self.width = width + self.num_ops = num_ops + self.num_rows = num_rows + self.mmax = int(log(self.num_rows) / log(2)) + self.rs = [] + self.mid = Signal(self.mmax, reset_less=True) # multiplex id + for i in range(num_rows): + self.rs.append(FPGetSyncOpsMod(width, num_ops)) + self.rs = Array(self.rs) + + self.out_op = FPOps(width, num_ops) + + def elaborate(self, platform): + m = Module() + + pe = PriorityEncoder(self.num_rows) + m.submodules.selector = pe + m.submodules.out_op = self.out_op + m.submodules += self.rs + + # connect priority encoder + in_ready = [] + for i in range(self.num_rows): + in_ready.append(self.rs[i].ready) + m.d.comb += pe.i.eq(Cat(*in_ready)) + + active = Signal(reset_less=True) + out_en = Signal(reset_less=True) + m.d.comb += active.eq(~pe.n) # encoder active + m.d.comb += out_en.eq(active & self.out_op.trigger) + + # encoder active: ack relevant input, record MID, pass output + with m.If(out_en): + rs = self.rs[pe.o] + m.d.sync += self.mid.eq(pe.o) + m.d.sync += rs.ack.eq(0) + m.d.sync += self.out_op.stb.eq(0) + for j in range(self.num_ops): + m.d.sync += self.out_op.v[j].eq(rs.out_op[j]) + with m.Else(): + m.d.sync += self.out_op.stb.eq(1) + # acks all default to zero + for i in range(self.num_rows): + m.d.sync += self.rs[i].ack.eq(1) + + return m + + def ports(self): + res = [] + for i in range(self.num_rows): + inop = self.rs[i] + res += inop.in_op + [inop.stb] + return self.out_op.ports() + res + [self.mid] + + diff --git a/src/add/nmigen_add_experiment.py b/src/add/nmigen_add_experiment.py index bc310555..c09ab681 100644 --- a/src/add/nmigen_add_experiment.py +++ b/src/add/nmigen_add_experiment.py @@ -32,114 +32,6 @@ class FPState(FPBase): setattr(self, k, v) -class FPGetSyncOpsMod: - def __init__(self, width, num_ops=2): - self.width = width - self.num_ops = num_ops - inops = [] - outops = [] - for i in range(num_ops): - inops.append(Signal(width, reset_less=True)) - outops.append(Signal(width, reset_less=True)) - self.in_op = inops - self.out_op = outops - self.stb = Signal(num_ops) - self.ack = Signal() - self.ready = Signal(reset_less=True) - self.out_decode = Signal(reset_less=True) - - def elaborate(self, platform): - m = Module() - m.d.comb += self.ready.eq(self.stb == Const(-1, (self.num_ops, False))) - m.d.comb += self.out_decode.eq(self.ack & self.ready) - with m.If(self.out_decode): - for i in range(self.num_ops): - m.d.comb += [ - self.out_op[i].eq(self.in_op[i]), - ] - return m - - def ports(self): - return self.in_op + self.out_op + [self.stb, self.ack] - - -class FPOps(Trigger): - def __init__(self, width, num_ops): - Trigger.__init__(self) - self.width = width - self.num_ops = num_ops - - res = [] - for i in range(num_ops): - res.append(Signal(width)) - self.v = Array(res) - - def ports(self): - res = [] - for i in range(self.num_ops): - res.append(self.v[i]) - res.append(self.ack) - res.append(self.stb) - return res - - -class InputGroup: - def __init__(self, width, num_ops=2, num_rows=4): - self.width = width - self.num_ops = num_ops - self.num_rows = num_rows - self.mmax = int(log(self.num_rows) / log(2)) - self.rs = [] - self.mid = Signal(self.mmax, reset_less=True) # multiplex id - for i in range(num_rows): - self.rs.append(FPGetSyncOpsMod(width, num_ops)) - self.rs = Array(self.rs) - - self.out_op = FPOps(width, num_ops) - - def elaborate(self, platform): - m = Module() - - pe = PriorityEncoder(self.num_rows) - m.submodules.selector = pe - m.submodules.out_op = self.out_op - m.submodules += self.rs - - # connect priority encoder - in_ready = [] - for i in range(self.num_rows): - in_ready.append(self.rs[i].ready) - m.d.comb += pe.i.eq(Cat(*in_ready)) - - active = Signal(reset_less=True) - out_en = Signal(reset_less=True) - m.d.comb += active.eq(~pe.n) # encoder active - m.d.comb += out_en.eq(active & self.out_op.trigger) - - # encoder active: ack relevant input, record MID, pass output - with m.If(out_en): - rs = self.rs[pe.o] - m.d.sync += self.mid.eq(pe.o) - m.d.sync += rs.ack.eq(0) - m.d.sync += self.out_op.stb.eq(0) - for j in range(self.num_ops): - m.d.sync += self.out_op.v[j].eq(rs.out_op[j]) - with m.Else(): - m.d.sync += self.out_op.stb.eq(1) - # acks all default to zero - for i in range(self.num_rows): - m.d.sync += self.rs[i].ack.eq(1) - - return m - - def ports(self): - res = [] - for i in range(self.num_rows): - inop = self.rs[i] - res += inop.in_op + [inop.stb] - return self.out_op.ports() + res + [self.mid] - - class FPGetOpMod: def __init__(self, width): self.in_op = FPOp(width) diff --git a/src/add/test_inputgroup.py b/src/add/test_inputgroup.py index e78090ea..09a72e17 100644 --- a/src/add/test_inputgroup.py +++ b/src/add/test_inputgroup.py @@ -3,7 +3,7 @@ from nmigen import Module, Signal from nmigen.compat.sim import run_simulation from nmigen.cli import verilog, rtlil -from nmigen_add_experiment import InputGroup +from inputgroup import InputGroup def testbench(dut): -- 2.30.2