from nmigen import * from nmigen.back import rtlil, verilog class Adder: def __init__(self, width): self.a = Signal(width) self.b = Signal(width) self.o = Signal(width) def get_fragment(self, platform): m = Module() m.d.comb += self.o.eq(self.a + self.b) return m.lower(platform) class Subtractor: def __init__(self, width): self.a = Signal(width) self.b = Signal(width) self.o = Signal(width) def get_fragment(self, platform): m = Module() m.d.comb += self.o.eq(self.a - self.b) return m.lower(platform) class ALU: def __init__(self, width): self.op = Signal() self.a = Signal(width) self.b = Signal(width) self.o = Signal(width) self.add = Adder(width) self.sub = Subtractor(width) def get_fragment(self, platform): m = Module() m.submodules.add = self.add m.submodules.sub = self.sub m.d.comb += [ self.add.a.eq(self.a), self.sub.a.eq(self.a), self.add.b.eq(self.b), self.sub.b.eq(self.b), ] with m.If(self.op): m.d.comb += self.o.eq(self.sub.o) with m.Else(): m.d.comb += self.o.eq(self.add.o) return m.lower(platform) alu = ALU(width=16) frag = alu.get_fragment(platform=None) # print(rtlil.convert(frag, ports=[alu.op, alu.a, alu.b, alu.o])) print(verilog.convert(frag, ports=[alu.op, alu.a, alu.b, alu.o]))