Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fhdl: simpler syntax
  • Loading branch information
Sebastien Bourdeauducq committed Dec 16, 2011
1 parent 39b7190 commit c7b9dfc
Show file tree
Hide file tree
Showing 13 changed files with 187 additions and 161 deletions.
37 changes: 18 additions & 19 deletions 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 *

Expand All @@ -7,32 +7,31 @@ def __init__(self, description, address=0):
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 = []
Expand All @@ -47,24 +46,24 @@ def get_fragment(self):
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)
return Fragment(comb, sync)
12 changes: 6 additions & 6 deletions 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):
Expand All @@ -19,10 +19,10 @@ def __init__(self, parent, name, size=1, access_bus=READ_WRITE, access_dev=READ_
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)
self.dev_w = Signal(BV(self.size), fullname + "_w")
self.dev_we = Signal(name=fullname + "_we")
self.parent.add_field(self)
15 changes: 7 additions & 8 deletions 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 = [
Expand All @@ -22,13 +22,12 @@ def __init__(self, master, slaves):
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)
4 changes: 2 additions & 2 deletions 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:
Expand All @@ -19,4 +19,4 @@ def __init__(self, desc, slave, name):
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))
46 changes: 23 additions & 23 deletions 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

Expand Down Expand Up @@ -49,16 +49,16 @@ def get_fragment(self):
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:
Expand All @@ -76,18 +76,18 @@ def __init__(self, master, slaves, offset=0, register=False):
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 = []
Expand All @@ -97,44 +97,44 @@ def get_fragment(self):
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):
Expand Down
18 changes: 9 additions & 9 deletions migen/bus/wishbone2csr.py
@@ -1,22 +1,22 @@
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():
def __init__(self):
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()
55 changes: 27 additions & 28 deletions 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)
8 changes: 4 additions & 4 deletions migen/corelogic/multimux.py
@@ -1,13 +1,13 @@
from migen.fhdl import structure as f
from migen.fhdl.structure import *

def multimux(sel, inputs, output):
n = len(inputs)
i = 0
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

0 comments on commit c7b9dfc

Please sign in to comment.