fhdl.dsl: comb/sync/sync.pix→d.comb/d.sync/d.pix.

This commit is contained in:
whitequark 2018-12-12 12:38:24 +00:00
parent 00f0b950f6
commit 0fac1f8d0f
9 changed files with 92 additions and 96 deletions

View file

@ -11,16 +11,16 @@ class ALU:
self.co = Signal() self.co = Signal()
def get_fragment(self, platform): def get_fragment(self, platform):
f = Module() m = Module()
with f.If(self.sel == 0b00): with m.If(self.sel == 0b00):
f.comb += self.o.eq(self.a | self.b) m.d.comb += self.o.eq(self.a | self.b)
with f.Elif(self.sel == 0b01): with m.Elif(self.sel == 0b01):
f.comb += self.o.eq(self.a & self.b) m.d.comb += self.o.eq(self.a & self.b)
with f.Elif(self.sel == 0b10): with m.Elif(self.sel == 0b10):
f.comb += self.o.eq(self.a ^ self.b) m.d.comb += self.o.eq(self.a ^ self.b)
with f.Else(): with m.Else():
f.comb += Cat(self.o, self.co).eq(self.a - self.b) m.d.comb += Cat(self.o, self.co).eq(self.a - self.b)
return f.lower(platform) return m.lower(platform)
alu = ALU(width=16) alu = ALU(width=16)

View file

@ -9,9 +9,9 @@ class Adder:
self.o = Signal(width) self.o = Signal(width)
def get_fragment(self, platform): def get_fragment(self, platform):
f = Module() m = Module()
f.comb += self.o.eq(self.a + self.b) m.d.comb += self.o.eq(self.a + self.b)
return f.lower(platform) return m.lower(platform)
class Subtractor: class Subtractor:
@ -21,9 +21,9 @@ class Subtractor:
self.o = Signal(width) self.o = Signal(width)
def get_fragment(self, platform): def get_fragment(self, platform):
f = Module() m = Module()
f.comb += self.o.eq(self.a - self.b) m.d.comb += self.o.eq(self.a - self.b)
return f.lower(platform) return m.lower(platform)
class ALU: class ALU:
@ -37,20 +37,20 @@ class ALU:
self.sub = Subtractor(width) self.sub = Subtractor(width)
def get_fragment(self, platform): def get_fragment(self, platform):
f = Module() m = Module()
f.submodules.add = self.add m.submodules.add = self.add
f.submodules.sub = self.sub m.submodules.sub = self.sub
f.comb += [ m.d.comb += [
self.add.a.eq(self.a), self.add.a.eq(self.a),
self.sub.a.eq(self.a), self.sub.a.eq(self.a),
self.add.b.eq(self.b), self.add.b.eq(self.b),
self.sub.b.eq(self.b), self.sub.b.eq(self.b),
] ]
with f.If(self.op): with m.If(self.op):
f.comb += self.o.eq(self.sub.o) m.d.comb += self.o.eq(self.sub.o)
with f.Else(): with m.Else():
f.comb += self.o.eq(self.add.o) m.d.comb += self.o.eq(self.add.o)
return f.lower(platform) return m.lower(platform)
alu = ALU(width=16) alu = ALU(width=16)

View file

@ -8,14 +8,14 @@ class ClockDivisor:
self.o = Signal() self.o = Signal()
def get_fragment(self, platform): def get_fragment(self, platform):
f = Module() m = Module()
f.sync += self.v.eq(self.v + 1) m.d.sync += self.v.eq(self.v + 1)
f.comb += self.o.eq(self.v[-1]) m.d.comb += self.o.eq(self.v[-1])
return f.lower(platform) return m.lower(platform)
sys = ClockDomain(async_reset=True) sync = ClockDomain(async_reset=True)
ctr = ClockDivisor(factor=16) ctr = ClockDivisor(factor=16)
frag = ctr.get_fragment(platform=None) frag = ctr.get_fragment(platform=None)
# print(rtlil.convert(frag, ports=[sys.clk, sys.reset, ctr.o], clock_domains={"sys": sys})) # print(rtlil.convert(frag, ports=[sync.clk, sync.reset, ctr.o], clock_domains={"sync": sync}))
print(verilog.convert(frag, ports=[sys.clk, sys.reset, ctr.o], clock_domains={"sys": sys})) print(verilog.convert(frag, ports=[sync.clk, sync.reset, ctr.o], clock_domains={"sync": sync}))

View file

@ -8,14 +8,14 @@ class ClockDivisor:
self.o = Signal() self.o = Signal()
def get_fragment(self, platform): def get_fragment(self, platform):
f = Module() m = Module()
f.sync += self.v.eq(self.v + 1) m.d.sync += self.v.eq(self.v + 1)
f.comb += self.o.eq(self.v[-1]) m.d.comb += self.o.eq(self.v[-1])
return f.lower(platform) return m.lower(platform)
sys = ClockDomain() sync = ClockDomain()
ctr = ClockDivisor(factor=16) ctr = ClockDivisor(factor=16)
frag = ctr.get_fragment(platform=None) frag = ctr.get_fragment(platform=None)
# print(rtlil.convert(frag, ports=[sys.clk, ctr.o], clock_domains={"sys": sys})) # print(rtlil.convert(frag, ports=[sync.clk, ctr.o], clock_domains={"sync": sync}))
print(verilog.convert(frag, ports=[sys.clk, ctr.o], clock_domains={"sys": sys})) print(verilog.convert(frag, ports=[sync.clk, ctr.o], clock_domains={"sync": sync}))

View file

@ -9,14 +9,14 @@ class ClockDivisor:
self.ce = Signal() self.ce = Signal()
def get_fragment(self, platform): def get_fragment(self, platform):
f = Module() m = Module()
f.sync += self.v.eq(self.v + 1) m.d.sync += self.v.eq(self.v + 1)
f.comb += self.o.eq(self.v[-1]) m.d.comb += self.o.eq(self.v[-1])
return CEInserter(self.ce)(f.lower()) return CEInserter(self.ce)(m.lower(platform))
sys = ClockDomain() sync = ClockDomain()
ctr = ClockDivisor(factor=16) ctr = ClockDivisor(factor=16)
frag = ctr.get_fragment(platform=None) frag = ctr.get_fragment(platform=None)
# print(rtlil.convert(frag, ports=[sys.clk, ctr.o, ctr.ce], clock_domains={"sys": sys})) # print(rtlil.convert(frag, ports=[sync.clk, ctr.o, ctr.ce], clock_domains={"sync": sync}))
print(verilog.convert(frag, ports=[sys.clk, ctr.o, ctr.ce], clock_domains={"sys": sys})) print(verilog.convert(frag, ports=[sync.clk, ctr.o, ctr.ce], clock_domains={"sync": sync}))

View file

@ -11,16 +11,16 @@ class ParMux:
self.o = Signal(width) self.o = Signal(width)
def get_fragment(self, platform): def get_fragment(self, platform):
f = Module() m = Module()
with f.Case(self.s, "--1"): with m.Case(self.s, "--1"):
f.comb += self.o.eq(self.a) m.d.comb += self.o.eq(self.a)
with f.Case(self.s, "-1-"): with m.Case(self.s, "-1-"):
f.comb += self.o.eq(self.b) m.d.comb += self.o.eq(self.b)
with f.Case(self.s, "1--"): with m.Case(self.s, "1--"):
f.comb += self.o.eq(self.c) m.d.comb += self.o.eq(self.c)
with f.Case(self.s): with m.Case(self.s):
f.comb += self.o.eq(0) m.d.comb += self.o.eq(0)
return f.lower(platform) return m.lower(platform)
pmux = ParMux(width=16) pmux = ParMux(width=16)

View file

@ -449,11 +449,13 @@ def convert_fragment(builder, fragment, name, clock_domains):
triggers = [] triggers = []
if cd_name is None: if cd_name is None:
triggers.append(("always",)) triggers.append(("always",))
else: elif cd_name in clock_domains:
cd = clock_domains[cd_name] cd = clock_domains[cd_name]
triggers.append(("posedge", xformer(cd.clk))) triggers.append(("posedge", xformer(cd.clk)))
if cd.async_reset: if cd.async_reset:
triggers.append(("posedge", xformer(cd.reset))) triggers.append(("posedge", xformer(cd.reset)))
else:
raise ValueError("Clock domain {} not found in design".format(cd_name))
for trigger in triggers: for trigger in triggers:
with process.sync(*trigger) as sync: with process.sync(*trigger) as sync:

View file

@ -14,36 +14,30 @@ class _ModuleBuilderProxy:
object.__setattr__(self, "_depth", depth) object.__setattr__(self, "_depth", depth)
class _ModuleBuilderComb(_ModuleBuilderProxy): class _ModuleBuilderDomain(_ModuleBuilderProxy):
def __iadd__(self, assigns): def __init__(self, builder, depth, cd_name):
self._builder._add_statement(assigns, cd=None, depth=self._depth)
return self
class _ModuleBuilderSyncCD(_ModuleBuilderProxy):
def __init__(self, builder, depth, cd):
super().__init__(builder, depth) super().__init__(builder, depth)
self._cd = cd self._cd_name = cd_name
def __iadd__(self, assigns): def __iadd__(self, assigns):
self._builder._add_statement(assigns, cd=self._cd, depth=self._depth) self._builder._add_statement(assigns, cd_name=self._cd_name, depth=self._depth)
return self return self
class _ModuleBuilderSync(_ModuleBuilderProxy): class _ModuleBuilderDomains(_ModuleBuilderProxy):
def __iadd__(self, assigns):
self._builder._add_statement(assigns, cd="sys", depth=self._depth)
return self
def __getattr__(self, name): def __getattr__(self, name):
return _ModuleBuilderSyncCD(self._builder, self._depth, name) if name == "comb":
cd_name = None
else:
cd_name = name
return _ModuleBuilderDomain(self._builder, self._depth, cd_name)
def __getitem__(self, name): def __getitem__(self, name):
return self.__getattr__(name) return self.__getattr__(name)
def __setattr__(self, name, value): def __setattr__(self, name, value):
if not isinstance(value, _ModuleBuilderSyncCD): if not isinstance(value, _ModuleBuilderDomain):
raise AttributeError("Cannot assign sync.{} attribute - use += instead" raise AttributeError("Cannot assign d.{} attribute - use += instead"
.format(name)) .format(name))
def __setitem__(self, name, value): def __setitem__(self, name, value):
@ -53,15 +47,12 @@ class _ModuleBuilderSync(_ModuleBuilderProxy):
class _ModuleBuilderRoot: class _ModuleBuilderRoot:
def __init__(self, builder, depth): def __init__(self, builder, depth):
self._builder = builder self._builder = builder
self.comb = _ModuleBuilderComb(builder, depth) self.domain = self.d = _ModuleBuilderDomains(builder, depth)
self.sync = _ModuleBuilderSync(builder, depth)
def __setattr__(self, name, value): def __getattr__(self, name):
if name == "comb" and not isinstance(value, _ModuleBuilderComb): if name in ("comb", "sync"):
raise AttributeError("Cannot assign comb attribute - use += instead") raise AttributeError("'{}' object has no attribute '{}'; did you mean 'd.{}'?"
if name == "sync" and not isinstance(value, _ModuleBuilderSync): .format(type(self).__name__, name, name))
raise AttributeError("Cannot assign sync attribute - use += instead")
super().__setattr__(name, value)
class _ModuleBuilderIf(_ModuleBuilderRoot): class _ModuleBuilderIf(_ModuleBuilderRoot):
@ -201,12 +192,12 @@ class Module(_ModuleBuilderRoot):
self._stmt_switch_test = None self._stmt_switch_test = None
self._stmt_switch_cases = OrderedDict() self._stmt_switch_cases = OrderedDict()
def _add_statement(self, assigns, cd, depth): def _add_statement(self, assigns, cd_name, depth):
def cd_name(cd): def cd_human_name(cd_name):
if cd is None: if cd_name is None:
return "comb" return "comb"
else: else:
return "sync.{}".format(cd) return cd_name
if depth < self._stmt_depth: if depth < self._stmt_depth:
self._flush() self._flush()
@ -218,12 +209,12 @@ class Module(_ModuleBuilderRoot):
for signal in assign.lhs._lhs_signals(): for signal in assign.lhs._lhs_signals():
if signal not in self._driving: if signal not in self._driving:
self._driving[signal] = cd self._driving[signal] = cd_name
elif self._driving[signal] != cd: elif self._driving[signal] != cd_name:
cd_curr = self._driving[signal] cd_curr = self._driving[signal]
raise ValueError("Driver-driver conflict: trying to drive {!r} from {}, but " raise ValueError("Driver-driver conflict: trying to drive {!r} from d.{}, but "
"it is already driven from {}" "it is already driven from d.{}"
.format(signal, self.cd_name(cd), self.cd_name(cd_curr))) .format(signal, cd_human_name(cd), cd_human_name(cd_curr)))
self._statements.append(assign) self._statements.append(assign)

View file

@ -15,8 +15,11 @@ class MultiReg:
for i in range(n)] for i in range(n)]
def get_fragment(self, platform): def get_fragment(self, platform):
f = Module() if hasattr(platform, "get_multi_reg"):
return platform.get_multi_reg(self)
m = Module()
for i, o in zip((self.i, *self._regs), self._regs): for i, o in zip((self.i, *self._regs), self._regs):
f.sync[self.odomain] += o.eq(i) m.d[self.odomain] += o.eq(i)
f.comb += self.o.eq(self._regs[-1]) m.d.comb += self.o.eq(self._regs[-1])
return f.lower(platform) return m.lower(platform)