fhdl: simpler syntax
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 16 Dec 2011 20:30:14 +0000 (21:30 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 16 Dec 2011 20:30:14 +0000 (21:30 +0100)
13 files changed:
migen/bank/csrgen.py
migen/bank/description.py
migen/bus/csr.py
migen/bus/simple.py
migen/bus/wishbone.py
migen/bus/wishbone2csr.py
migen/corelogic/divider.py
migen/corelogic/multimux.py
migen/corelogic/roundrobin.py
migen/corelogic/timeline.py
migen/fhdl/convtools.py
migen/fhdl/structure.py
migen/fhdl/verilog.py

index 2a538a072fc5c4c6bdf5ef275e748e4a65498426..43fa14e5c295e8db885f149765c3cdf530352115 100644 (file)
@@ -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)
index ec405d23b1f618dbb6873b4f1cf48c09524dcd3c..d0115f7fbac5ba51fb0ce809589b12f0ec5c73d7 100644 (file)
@@ -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)
index 74fc42735fc95b4f1eaf157bbf4aea5f86f279e3..b5f40a614af76b2d15b4cb334cce70afa1622a2e 100644 (file)
@@ -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)
index 83fee1d1cfc8dc50ffcedfa4e2ec1fa1e4254ab7..07214679c3731f84041262a99de8760fa73a9bc5 100644 (file)
@@ -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))
index 140f1ba72cc6d799f4821b250c12cf1e317dbbea..8fc48004d3b74965dfad795636f7ed490e09d158 100644 (file)
@@ -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):
index c7ea78fab682a7e73d627278477959cf0a0728f4..7cfc7a0aba53921a219868c4532b46f10cc2cf63 100644 (file)
@@ -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()
index 9c82ad6cfa738cbb60a3fa5fee1e6e88fe99ff17..880074af0e395e9679377f6adb03f789617071b7 100644 (file)
@@ -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)
index db8e24b5f4df614e45e9c0650ddba9cbff281046..fde064ee7749ad52ae9f5dbd0a1b338b836d2aa8 100644 (file)
@@ -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
index e079b00477f1fbf3872579b22a2ad7f88991832a..8926e98739e68e3aed856db300b7ecb7d154184b 100644 (file)
@@ -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])
index aed5727a6666eaf412ebe3b7e20fe9e6b782c1a7..efe09a189b824f7f4e38837fbfa759eb79069adc 100644 (file)
@@ -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)
index b236ff1b5c83cba50e01395cc6f2777b025d408d..12edaec9015897b1d8ab914cbc096a4fde95d2de 100644 (file)
@@ -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)
index 009930e6eb03fcc4a4b6c5093fc57430a586e715..9a03b5991f87acdb65c21e4e5f0f1b083d00a731 100644 (file)
@@ -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()
 
 #
 
index 4ec02eb4fb7f255abc806d582885f0a72d617f85..75bba734e4f3cd818dd3997392e5ec91480ef1aa 100644 (file)
@@ -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])