fhdl.dsl: comb/sync/sync.pix→d.comb/d.sync/d.pix.
This commit is contained in:
parent
00f0b950f6
commit
0fac1f8d0f
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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}))
|
||||||
|
|
|
@ -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}))
|
||||||
|
|
|
@ -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}))
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue