From c7b9dfc203218a200601ff83acb68f719432a125 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 16 Dec 2011 21:30:14 +0100 Subject: [PATCH] fhdl: simpler syntax --- migen/bank/csrgen.py | 37 ++++++++------- migen/bank/description.py | 12 ++--- migen/bus/csr.py | 15 +++---- migen/bus/simple.py | 4 +- migen/bus/wishbone.py | 46 +++++++++---------- migen/bus/wishbone2csr.py | 18 ++++---- migen/corelogic/divider.py | 55 +++++++++++------------ migen/corelogic/multimux.py | 8 ++-- migen/corelogic/roundrobin.py | 26 ++++++----- migen/corelogic/timeline.py | 28 +++++++----- migen/fhdl/convtools.py | 11 +++-- migen/fhdl/structure.py | 85 ++++++++++++++++++++++------------- migen/fhdl/verilog.py | 3 +- 13 files changed, 187 insertions(+), 161 deletions(-) diff --git a/migen/bank/csrgen.py b/migen/bank/csrgen.py index 2a538a072..43fa14e5c 100644 --- a/migen/bank/csrgen.py +++ b/migen/bank/csrgen.py @@ -1,4 +1,4 @@ -from migen.fhdl import structure as f +from migen.fhdl.structure import * from migen.bus.csr import * from migen.bank.description import * @@ -7,32 +7,31 @@ class Bank: self.description = description self.address = address self.interface = Slave() - f.declare_signal(self, "_sel") + declare_signal(self, "_sel") def get_fragment(self): - a = f.Assign comb = [] sync = [] - comb.append(a(self._sel, self.interface.a_i[10:] == f.Constant(self.address, f.BV(4)))) + comb.append(self._sel.eq(self.interface.a_i[10:] == Constant(self.address, BV(4)))) nregs = len(self.description) - nbits = f.bits_for(nregs-1) + nbits = bits_for(nregs-1) # Bus writes bwcases = [] for i in range(nregs): reg = self.description[i] nfields = len(reg.fields) - bwra = [] + bwra = [Constant(i, BV(nbits))] for j in range(nfields): field = reg.fields[j] if field.access_bus == WRITE_ONLY or field.access_bus == READ_WRITE: - bwra.append(a(field.storage, self.interface.d_i[j])) - if bwra: - bwcases.append((f.Constant(i, f.BV(nbits)), bwra)) + bwra.append(field.storage.eq(self.interface.d_i[j])) + if len(bwra) > 1: + bwcases.append(bwra) if bwcases: - sync.append(f.If(self._sel & self.interface.we_i, [f.Case(self.interface.a_i[:nbits], bwcases)])) + sync.append(If(self._sel & self.interface.we_i, Case(self.interface.a_i[:nbits], *bwcases))) # Bus reads brcases = [] @@ -47,24 +46,24 @@ class Bank: brs.append(field.storage) reg_readable = True else: - brs.append(f.Constant(0, f.bv(field.size))) + brs.append(Constant(0, BV(field.size))) if reg_readable: if len(brs) > 1: - brcases.append((f.Constant(i, f.BV(nbits)), [a(self.interface.d_o, f.Cat(*brs))])) + brcases.append([Constant(i, BV(nbits)), self.interface.d_o.eq(f.Cat(*brs))]) else: - brcases.append((f.Constant(i, f.BV(nbits)), [a(self.interface.d_o, brs[0])])) + brcases.append([Constant(i, BV(nbits)), self.interface.d_o.eq(brs[0])]) if brcases: - sync.append(a(self.interface.d_o, f.Constant(0, f.BV(32)))) - sync.append(f.If(self._sel, [f.Case(self.interface.a_i[:nbits], brcases)])) + sync.append(self.interface.d_o.eq(Constant(0, BV(32)))) + sync.append(If(self._sel, Case(self.interface.a_i[:nbits], *brcases))) else: - comb.append(a(self.interface.d_o, f.Constant(0, f.BV(32)))) + comb.append(self.interface.d_o.eq(Constant(0, BV(32)))) # Device access for reg in self.description: for field in reg.fields: if field.access_dev == READ_ONLY or field.access_dev == READ_WRITE: - comb.append(a(field.dev_r, field.storage)) + comb.append(field.dev_r.eq(field.storage)) if field.access_dev == WRITE_ONLY or field.access_dev == READ_WRITE: - sync.append(f.If(field.dev_we, [a(field.storage, field.dev_w)])) + sync.append(If(field.dev_we, field.storage.eq(field.dev_w))) - return f.Fragment(comb, sync) \ No newline at end of file + return Fragment(comb, sync) diff --git a/migen/bank/description.py b/migen/bank/description.py index ec405d23b..d0115f7fb 100644 --- a/migen/bank/description.py +++ b/migen/bank/description.py @@ -1,4 +1,4 @@ -from migen.fhdl import structure as f +from migen.fhdl.structure import * class Register: def __init__(self, name): @@ -19,10 +19,10 @@ class Field: self.access_dev = access_dev self.reset = reset fullname = parent.name + "_" + name - self.storage = f.Signal(f.BV(self.size), fullname) + self.storage = Signal(BV(self.size), fullname) if self.access_dev == READ_ONLY or self.access_dev == READ_WRITE: - self.dev_r = f.Signal(f.BV(self.size), fullname + "_r") + self.dev_r = Signal(BV(self.size), fullname + "_r") if self.access_dev == WRITE_ONLY or self.access_dev == READ_WRITE: - self.dev_w = f.Signal(f.BV(self.size), fullname + "_w") - self.dev_we = f.Signal(name=fullname + "_we") - self.parent.add_field(self) \ No newline at end of file + self.dev_w = Signal(BV(self.size), fullname + "_w") + self.dev_we = Signal(name=fullname + "_we") + self.parent.add_field(self) diff --git a/migen/bus/csr.py b/migen/bus/csr.py index 74fc42735..b5f40a614 100644 --- a/migen/bus/csr.py +++ b/migen/bus/csr.py @@ -1,4 +1,4 @@ -from migen.fhdl import structure as f +from migen.fhdl.structure import * from migen.bus.simple import Simple _desc = [ @@ -22,13 +22,12 @@ class Interconnect: self.slaves = slaves def get_fragment(self): - a = f.Assign comb = [] - rb = f.Constant(0, f.BV(32)) + rb = Constant(0, BV(32)) for slave in self.slaves: - comb.append(a(slave.a_i, self.master.a_o)) - comb.append(a(slave.we_i, self.master.we_o)) - comb.append(a(slave.d_i, self.master.d_o)) + comb.append(slave.a_i.eq(self.master.a_o)) + comb.append(slave.we_i.eq(self.master.we_o)) + comb.append(slave.d_i.eq(self.master.d_o)) rb = rb | slave.d_o - comb.append(a(self.master.d_i, rb)) - return f.Fragment(comb) + comb.append(self.master.d_i.eq(rb)) + return Fragment(comb) diff --git a/migen/bus/simple.py b/migen/bus/simple.py index 83fee1d1c..07214679c 100644 --- a/migen/bus/simple.py +++ b/migen/bus/simple.py @@ -1,4 +1,4 @@ -from migen.fhdl import structure as f +from migen.fhdl.structure import * def get_sig_name(signal, slave): if signal[0] ^ slave: @@ -19,4 +19,4 @@ class Simple(): if name: busname += "_" + name signame = get_sig_name(signal, slave) - setattr(self, signame, f.Signal(f.BV(signal[2]), busname + "_" + signame)) + setattr(self, signame, Signal(BV(signal[2]), busname + "_" + signame)) diff --git a/migen/bus/wishbone.py b/migen/bus/wishbone.py index 140f1ba72..8fc48004d 100644 --- a/migen/bus/wishbone.py +++ b/migen/bus/wishbone.py @@ -1,6 +1,6 @@ from functools import partial -from migen.fhdl import structure as f +from migen.fhdl.structure import * from migen.corelogic import roundrobin, multimux from migen.bus.simple import Simple, get_sig_name @@ -49,16 +49,16 @@ class Arbiter: for m in self.masters: dest = getattr(m, name) if name == "ack_i" or name == "err_i": - comb.append(f.Assign(dest, source & (self.rr.grant == f.Constant(i, self.rr.grant.bv)))) + comb.append(dest.eq(source & (self.rr.grant == Constant(i, self.rr.grant.bv)))) else: - comb.append(f.Assign(dest, source)) + comb.append(dest.eq(source)) i += 1 # connect bus requests to round-robin selector reqs = [m.cyc_o for m in self.masters] - comb.append(f.Assign(self.rr.request, f.Cat(*reqs))) + comb.append(self.rr.request.eq(Cat(*reqs))) - return f.Fragment(comb) + self.rr.get_fragment() + return Fragment(comb) + self.rr.get_fragment() class Decoder: # slaves is a list of pairs: @@ -76,18 +76,18 @@ class Decoder: self.register = register addresses = [slave[0] for slave in self.slaves] - maxbits = max([f.bits_for(addr) for addr in addresses]) + maxbits = max([bits_for(addr) for addr in addresses]) def mkconst(x): if isinstance(x, int): - return f.Constant(x, f.BV(maxbits)) + return Constant(x, BV(maxbits)) else: return x self.addresses = list(map(mkconst, addresses)) ns = len(self.slaves) - d = partial(f.declare_signal, self) - d("_slave_sel", f.BV(ns)) - d("_slave_sel_r", f.BV(ns)) + d = partial(declare_signal, self) + d("_slave_sel", BV(ns)) + d("_slave_sel_r", BV(ns)) def get_fragment(self): comb = [] @@ -97,44 +97,44 @@ class Decoder: i = 0 hi = self.master.adr_o.bv.width - self.offset for addr in self.addresses: - comb.append(f.Assign(self._slave_sel[i], + comb.append(self._slave_sel[i].eq( self.master.adr_o[hi-addr.bv.width:hi] == addr)) i += 1 if self.register: - sync.append(f.Assign(self._slave_sel_r, self._slave_sel)) + sync.append(self._slave_sel_r.eq(self._slave_sel)) else: - comb.append(f.Assign(self._slave_sel_r, self._slave_sel)) + comb.append(self._slave_sel_r.eq(self._slave_sel)) # connect master->slaves signals except cyc m2s_names = [(get_sig_name(x, False), get_sig_name(x, True)) for x in _desc if x[0] and x[1] != "cyc"] - comb += [f.Assign(getattr(slave[1], name[1]), getattr(self.master, name[0])) + comb += [getattr(slave[1], name[1]).eq(getattr(self.master, name[0])) for name in m2s_names for slave in self.slaves] # combine cyc with slave selection signals i = 0 for slave in self.slaves: - comb.append(f.Assign(slave[1].cyc_i, self.master.cyc_o & self._slave_sel[i])) + comb.append(slave[1].cyc_i.eq(self.master.cyc_o & self._slave_sel[i])) i += 1 # generate master ack (resp. err) by ORing all slave acks (resp. errs) - ackv = f.Constant(0) - errv = f.Constant(0) + ackv = Constant(0) + errv = Constant(0) for slave in self.slaves: ackv = ackv | slave[1].ack_o errv = errv | slave[1].err_o - comb.append(f.Assign(self.master.ack_i, ackv)) - comb.append(f.Assign(self.master.err_i, errv)) + comb.append(self.master.ack_i.eq(ackv)) + comb.append(self.master.err_i.eq(errv)) # mux (1-hot) slave data return i = 0 - datav = f.Constant(0, self.master.dat_i.bv) + datav = Constant(0, self.master.dat_i.bv) for slave in self.slaves: - datav = datav | (f.Replicate(self._slave_sel_r[i], self.master.dat_i.bv.width) & slave[1].dat_o) + datav = datav | (Replicate(self._slave_sel_r[i], self.master.dat_i.bv.width) & slave[1].dat_o) i += 1 - comb.append(f.Assign(self.master.dat_i, datav)) + comb.append(self.master.dat_i.eq(datav)) - return f.Fragment(comb, sync) + return Fragment(comb, sync) class InterconnectShared: def __init__(self, masters, slaves, offset=0, register=False): diff --git a/migen/bus/wishbone2csr.py b/migen/bus/wishbone2csr.py index c7ea78fab..7cfc7a0ab 100644 --- a/migen/bus/wishbone2csr.py +++ b/migen/bus/wishbone2csr.py @@ -1,6 +1,6 @@ from migen.bus import wishbone from migen.bus import csr -from migen.fhdl import structure as f +from migen.fhdl.structure import * from migen.corelogic import timeline class Inst(): @@ -8,15 +8,15 @@ class Inst(): self.wishbone = wishbone.Slave("to_csr") self.csr = csr.Master("from_wishbone") self.timeline = timeline.Inst(self.wishbone.cyc_i & self.wishbone.stb_i, - [(1, [f.Assign(self.csr.we_o, self.wishbone.we_i)]), - (2, [f.Assign(self.wishbone.ack_o, 1)]), - (3, [f.Assign(self.wishbone.ack_o, 0)])]) + [(1, [self.csr.we_o.eq(self.wishbone.we_i)]), + (2, [self.wishbone.ack_o.eq(1)]), + (3, [self.wishbone.ack_o.eq(0)])]) def get_fragment(self): sync = [ - f.Assign(self.csr.we_o, 0), - f.Assign(self.csr.d_o, self.wishbone.dat_i), - f.Assign(self.csr.a_o, self.wishbone.adr_i[2:16]), - f.Assign(self.wishbone.dat_o, self.csr.d_i) + self.csr.we_o.eq(0), + self.csr.d_o.eq(self.wishbone.dat_i), + self.csr.a_o.eq(self.wishbone.adr_i[2:16]), + self.wishbone.dat_o.eq(self.csr.d_i) ] - return f.Fragment(sync=sync) + self.timeline.get_fragment() + return Fragment(sync=sync) + self.timeline.get_fragment() diff --git a/migen/corelogic/divider.py b/migen/corelogic/divider.py index 9c82ad6cf..880074af0 100644 --- a/migen/corelogic/divider.py +++ b/migen/corelogic/divider.py @@ -1,45 +1,44 @@ from functools import partial -from migen.fhdl import structure as f +from migen.fhdl.structure import * class Inst: def __init__(self, w): self.w = w - d = partial(f.declare_signal, self) + d = partial(declare_signal, self) d("start_i") - d("dividend_i", f.BV(w)) - d("divisor_i", f.BV(w)) + d("dividend_i", BV(w)) + d("divisor_i", BV(w)) d("ready_o") - d("quotient_o", f.BV(w)) - d("remainder_o", f.BV(w)) + d("quotient_o", BV(w)) + d("remainder_o", BV(w)) - d("_qr", f.BV(2*w)) - d("_counter", f.BV(f.bits_for(w))) - d("_divisor_r", f.BV(w)) - d("_diff", f.BV(w+1)) + d("_qr", BV(2*w)) + d("_counter", BV(bits_for(w))) + d("_divisor_r", BV(w)) + d("_diff", BV(w+1)) def get_fragment(self): - a = f.Assign comb = [ - a(self.quotient_o, self._qr[:self.w]), - a(self.remainder_o, self._qr[self.w:]), - a(self.ready_o, self._counter == f.Constant(0, self._counter.bv)), - a(self._diff, self.remainder_o - self._divisor_r) + self.quotient_o.eq(self._qr[:self.w]), + self.remainder_o.eq(self._qr[self.w:]), + self.ready_o.eq(self._counter == Constant(0, self._counter.bv)), + self._diff.eq(self.remainder_o - self._divisor_r) ] sync = [ - f.If(self.start_i == 1, [ - a(self._counter, self.w), - a(self._qr, self.dividend_i), - a(self._divisor_r, self.divisor_i) - ], [ - f.If(self.ready_o == 0, [ - f.If(self._diff[self.w] == 1, - [a(self._qr, f.Cat(0, self._qr[:2*self.w-1]))], - [a(self._qr, f.Cat(1, self._qr[:self.w-1], self._diff[:self.w]))]), - a(self._counter, self._counter - f.Constant(1, self._counter.bv)), - ]) - ]) + If(self.start_i, + self._counter.eq(self.w), + self._qr.eq(self.dividend_i), + self._divisor_r.eq(self.divisor_i) + ).Elif(~self.ready_o, + If(self._diff[self.w], + self._qr.eq(Cat(0, self._qr[:2*self.w-1])) + ).Else( + self._qr.eq(Cat(1, self._qr[:self.w-1], self._diff[:self.w])) + ), + self._counter.eq(self._counter - Constant(1, self._counter.bv)) + ) ] - return f.Fragment(comb, sync) + return Fragment(comb, sync) diff --git a/migen/corelogic/multimux.py b/migen/corelogic/multimux.py index db8e24b5f..fde064ee7 100644 --- a/migen/corelogic/multimux.py +++ b/migen/corelogic/multimux.py @@ -1,4 +1,4 @@ -from migen.fhdl import structure as f +from migen.fhdl.structure import * def multimux(sel, inputs, output): n = len(inputs) @@ -6,8 +6,8 @@ def multimux(sel, inputs, output): comb = [] for osig in output: choices = [x[i] for x in inputs] - cases = [(f.Constant(j, sel.bv), [f.Assign(osig, choices[j])]) for j in range(n)] - default = cases.pop()[1] - comb.append(f.Case(sel, cases, default)) + cases = [[Constant(j, sel.bv), osig.eq(choices[j])] for j in range(n)] + cases[n-1][0] = Default() + comb.append(Case(sel, *cases)) i += 1 return comb diff --git a/migen/corelogic/roundrobin.py b/migen/corelogic/roundrobin.py index e079b0047..8926e9873 100644 --- a/migen/corelogic/roundrobin.py +++ b/migen/corelogic/roundrobin.py @@ -1,11 +1,11 @@ -from migen.fhdl import structure as f +from migen.fhdl.structure import * class Inst: def __init__(self, n): self.n = n - self.bn = f.bits_for(self.n-1) - f.declare_signal(self, "request", f.BV(self.n)) - f.declare_signal(self, "grant", f.BV(self.bn)) + self.bn = bits_for(self.n-1) + declare_signal(self, "request", BV(self.n)) + declare_signal(self, "grant", BV(self.bn)) def get_fragment(self): cases = [] @@ -13,10 +13,14 @@ class Inst: switch = [] for j in reversed(range(i+1,i+self.n)): t = j % self.n - switch = [f.If(self.request[t], - [f.Assign(self.grant, f.Constant(t, f.BV(self.bn)))], - switch)] - case = f.If(~self.request[i], switch) - cases.append((f.Constant(i, f.BV(self.bn)), case)) - statement = f.Case(self.grant, cases) - return f.Fragment(sync=[statement]) + switch = [ + If(self.request[t], + self.grant.eq(Constant(t, BV(self.bn))) + ).Else( + *switch + ) + ] + case = If(~self.request[i], *switch) + cases.append([Constant(i, BV(self.bn)), case]) + statement = Case(self.grant, *cases) + return Fragment(sync=[statement]) diff --git a/migen/corelogic/timeline.py b/migen/corelogic/timeline.py index aed5727a6..efe09a189 100644 --- a/migen/corelogic/timeline.py +++ b/migen/corelogic/timeline.py @@ -1,27 +1,31 @@ -from migen.fhdl import structure as f +from migen.fhdl.structure import * class Inst: def __init__(self, trigger, events): self.trigger = trigger self.events = events self.lastevent = max([e[0] for e in events]) - f.declare_signal(self, "_counter", f.BV(f.bits_for(self.lastevent))) + declare_signal(self, "_counter", BV(bits_for(self.lastevent))) def get_fragment(self): - counterlogic = f.If(self._counter != f.Constant(0, self._counter.bv), - [f.Assign(self._counter, self._counter + f.Constant(1, self._counter.bv))], - [f.If(self.trigger, [f.Assign(self._counter, f.Constant(1, self._counter.bv))])]) + counterlogic = If(self._counter != Constant(0, self._counter.bv), + self._counter.eq(self._counter + Constant(1, self._counter.bv)) + ).Elif(self.trigger, + self._counter.eq(Constant(1, self._counter.bv)) + ) # insert counter reset if it doesn't automatically overflow # (test if self.lastevent+1 is a power of 2) if (self.lastevent & (self.lastevent + 1)) != 0: - counterlogic = f.If(self._counter == self.lastevent, - [f.Assign(self._counter, f.Constant(0, self._counter.bv))], - [counterlogic]) + counterlogic = If(self._counter == self.lastevent, + self._counter.eq(Constant(0, self._counter.bv)) + ).Else( + counterlogic + ) def get_cond(e): if e[0] == 0: - return self.trigger & (self._counter == f.Constant(0, self._counter.bv)) + return self.trigger & (self._counter == Constant(0, self._counter.bv)) else: - return self._counter == f.Constant(e[0], self._counter.bv) - sync = [f.If(get_cond(e), e[1]) for e in self.events] + return self._counter == Constant(e[0], self._counter.bv) + sync = [If(get_cond(e), *e[1]) for e in self.events] sync.append(counterlogic) - return f.Fragment(sync=sync) + return Fragment(sync=sync) diff --git a/migen/fhdl/convtools.py b/migen/fhdl/convtools.py index b236ff1b5..12edaec90 100644 --- a/migen/fhdl/convtools.py +++ b/migen/fhdl/convtools.py @@ -1,4 +1,5 @@ -from .structure import * +from migen.fhdl.structure import * +from migen.fhdl.structure import _Operator class Namespace: def __init__(self): @@ -29,7 +30,7 @@ def list_signals(node): return set() elif isinstance(node, Signal): return {node} - elif isinstance(node, Operator): + elif isinstance(node, _Operator): l = list(map(list_signals, node.operands)) return set().union(*l) elif isinstance(node, Slice): @@ -105,7 +106,5 @@ def is_variable(node): def insert_reset(rst, sl): targets = list_targets(sl) - resetcode = [] - for t in targets: - resetcode.append(Assign(t, t.reset)) - return If(rst, resetcode, sl) + resetcode = [t.eq(t.reset) for t in targets] + return If(rst, *resetcode).Else(*sl.l) diff --git a/migen/fhdl/structure.py b/migen/fhdl/structure.py index 009930e6e..9a03b5991 100644 --- a/migen/fhdl/structure.py +++ b/migen/fhdl/structure.py @@ -23,53 +23,53 @@ class BV: class Value: def __invert__(self): - return Operator("~", [self]) + return _Operator("~", [self]) def __add__(self, other): - return Operator("+", [self, other]) + return _Operator("+", [self, other]) def __radd__(self, other): - return Operator("+", [other, self]) + return _Operator("+", [other, self]) def __sub__(self, other): - return Operator("-", [self, other]) + return _Operator("-", [self, other]) def __rsub__(self, other): - return Operator("-", [other, self]) + return _Operator("-", [other, self]) def __mul__(self, other): - return Operator("*", [self, other]) + return _Operator("*", [self, other]) def __rmul__(self, other): - return Operator("*", [other, self]) + return _Operator("*", [other, self]) def __lshift__(self, other): - return Operator("<<", [self, other]) + return _Operator("<<", [self, other]) def __rlshift__(self, other): - return Operator("<<", [other, self]) + return _Operator("<<", [other, self]) def __rshift__(self, other): - return Operator(">>", [self, other]) + return _Operator(">>", [self, other]) def __rrshift__(self, other): - return Operator(">>", [other, self]) + return _Operator(">>", [other, self]) def __and__(self, other): - return Operator("&", [self, other]) + return _Operator("&", [self, other]) def __rand__(self, other): - return Operator("&", [other, self]) + return _Operator("&", [other, self]) def __xor__(self, other): - return Operator("^", [self, other]) + return _Operator("^", [self, other]) def __rxor__(self, other): - return Operator("^", [other, self]) + return _Operator("^", [other, self]) def __or__(self, other): - return Operator("|", [self, other]) + return _Operator("|", [self, other]) def __ror__(self, other): - return Operator("|", [other, self]) + return _Operator("|", [other, self]) def __lt__(self, other): - return Operator("<", [self, other]) + return _Operator("<", [self, other]) def __le__(self, other): - return Operator("<=", [self, other]) + return _Operator("<=", [self, other]) def __eq__(self, other): - return Operator("==", [self, other]) + return _Operator("==", [self, other]) def __ne__(self, other): - return Operator("!=", [self, other]) + return _Operator("!=", [self, other]) def __gt__(self, other): - return Operator(">", [self, other]) + return _Operator(">", [self, other]) def __ge__(self, other): - return Operator(">=", [self, other]) + return _Operator(">=", [self, other]) def __getitem__(self, key): @@ -85,8 +85,11 @@ class Value: return Slice(self, start, stop) else: raise KeyError + + def eq(self, r): + return Assign(self, r) -class Operator(Value): +class _Operator(Value): def __init__(self, op, operands): self.op = op self.operands = list(map(_cst, operands)) @@ -151,23 +154,41 @@ class StatementList: if l is None: l = [] self.l = l +class If: + def __init__(self, cond, *t): + self.cond = cond + self.t = StatementList(t) + self.f = StatementList() + + def Else(self, *f): + self.f = StatementList(f) + return self + + def Elif(self, cond, *t): + self.f = StatementList([If(cond, *t)]) + return self + def _sl(x): if isinstance(x, list): return StatementList(x) else: return x -class If: - def __init__(self, cond, t, f=StatementList()): - self.cond = cond - self.t = _sl(t) - self.f = _sl(f) +class Default: + pass class Case: - def __init__(self, test, cases=[], default=StatementList()): + def __init__(self, test, *cases): self.test = test - self.cases = [(c[0], _sl(c[1])) for c in cases] - self.default = _sl(default) + self.cases = [(c[0], StatementList(c[1:])) for c in cases if not isinstance(c[0], Default)] + self.default = None + for c in cases: + if isinstance(c[0], Default): + if self.default is not None: + raise ValueError + self.default = StatementList(c[1:]) + if self.default is None: + self.default = StatementList() # diff --git a/migen/fhdl/verilog.py b/migen/fhdl/verilog.py index 4ec02eb4f..75bba734e 100644 --- a/migen/fhdl/verilog.py +++ b/migen/fhdl/verilog.py @@ -1,6 +1,7 @@ from functools import partial from migen.fhdl.structure import * +from migen.fhdl.structure import _Operator from migen.fhdl.convtools import * def _printsig(ns, s): @@ -21,7 +22,7 @@ def _printexpr(ns, node): return "-" + str(node.bv) + str(-self.n) elif isinstance(node, Signal): return ns.get_name(node) - elif isinstance(node, Operator): + elif isinstance(node, _Operator): arity = len(node.operands) if arity == 1: r = node.op + _printexpr(ns, node.operands[0])