mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
fhdl: simpler syntax
This commit is contained in:
parent
39b7190334
commit
c7b9dfc203
13 changed files with 187 additions and 161 deletions
|
@ -1,4 +1,4 @@
|
||||||
from migen.fhdl import structure as f
|
from migen.fhdl.structure import *
|
||||||
from migen.bus.csr import *
|
from migen.bus.csr import *
|
||||||
from migen.bank.description import *
|
from migen.bank.description import *
|
||||||
|
|
||||||
|
@ -7,32 +7,31 @@ class Bank:
|
||||||
self.description = description
|
self.description = description
|
||||||
self.address = address
|
self.address = address
|
||||||
self.interface = Slave()
|
self.interface = Slave()
|
||||||
f.declare_signal(self, "_sel")
|
declare_signal(self, "_sel")
|
||||||
|
|
||||||
def get_fragment(self):
|
def get_fragment(self):
|
||||||
a = f.Assign
|
|
||||||
comb = []
|
comb = []
|
||||||
sync = []
|
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)
|
nregs = len(self.description)
|
||||||
nbits = f.bits_for(nregs-1)
|
nbits = bits_for(nregs-1)
|
||||||
|
|
||||||
# Bus writes
|
# Bus writes
|
||||||
bwcases = []
|
bwcases = []
|
||||||
for i in range(nregs):
|
for i in range(nregs):
|
||||||
reg = self.description[i]
|
reg = self.description[i]
|
||||||
nfields = len(reg.fields)
|
nfields = len(reg.fields)
|
||||||
bwra = []
|
bwra = [Constant(i, BV(nbits))]
|
||||||
for j in range(nfields):
|
for j in range(nfields):
|
||||||
field = reg.fields[j]
|
field = reg.fields[j]
|
||||||
if field.access_bus == WRITE_ONLY or field.access_bus == READ_WRITE:
|
if field.access_bus == WRITE_ONLY or field.access_bus == READ_WRITE:
|
||||||
bwra.append(a(field.storage, self.interface.d_i[j]))
|
bwra.append(field.storage.eq(self.interface.d_i[j]))
|
||||||
if bwra:
|
if len(bwra) > 1:
|
||||||
bwcases.append((f.Constant(i, f.BV(nbits)), bwra))
|
bwcases.append(bwra)
|
||||||
if bwcases:
|
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
|
# Bus reads
|
||||||
brcases = []
|
brcases = []
|
||||||
|
@ -47,24 +46,24 @@ class Bank:
|
||||||
brs.append(field.storage)
|
brs.append(field.storage)
|
||||||
reg_readable = True
|
reg_readable = True
|
||||||
else:
|
else:
|
||||||
brs.append(f.Constant(0, f.bv(field.size)))
|
brs.append(Constant(0, BV(field.size)))
|
||||||
if reg_readable:
|
if reg_readable:
|
||||||
if len(brs) > 1:
|
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:
|
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:
|
if brcases:
|
||||||
sync.append(a(self.interface.d_o, f.Constant(0, f.BV(32))))
|
sync.append(self.interface.d_o.eq(Constant(0, BV(32))))
|
||||||
sync.append(f.If(self._sel, [f.Case(self.interface.a_i[:nbits], brcases)]))
|
sync.append(If(self._sel, Case(self.interface.a_i[:nbits], *brcases)))
|
||||||
else:
|
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
|
# Device access
|
||||||
for reg in self.description:
|
for reg in self.description:
|
||||||
for field in reg.fields:
|
for field in reg.fields:
|
||||||
if field.access_dev == READ_ONLY or field.access_dev == READ_WRITE:
|
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:
|
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)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from migen.fhdl import structure as f
|
from migen.fhdl.structure import *
|
||||||
|
|
||||||
class Register:
|
class Register:
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
|
@ -19,10 +19,10 @@ class Field:
|
||||||
self.access_dev = access_dev
|
self.access_dev = access_dev
|
||||||
self.reset = reset
|
self.reset = reset
|
||||||
fullname = parent.name + "_" + name
|
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:
|
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:
|
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_w = Signal(BV(self.size), fullname + "_w")
|
||||||
self.dev_we = f.Signal(name=fullname + "_we")
|
self.dev_we = Signal(name=fullname + "_we")
|
||||||
self.parent.add_field(self)
|
self.parent.add_field(self)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from migen.fhdl import structure as f
|
from migen.fhdl.structure import *
|
||||||
from migen.bus.simple import Simple
|
from migen.bus.simple import Simple
|
||||||
|
|
||||||
_desc = [
|
_desc = [
|
||||||
|
@ -22,13 +22,12 @@ class Interconnect:
|
||||||
self.slaves = slaves
|
self.slaves = slaves
|
||||||
|
|
||||||
def get_fragment(self):
|
def get_fragment(self):
|
||||||
a = f.Assign
|
|
||||||
comb = []
|
comb = []
|
||||||
rb = f.Constant(0, f.BV(32))
|
rb = Constant(0, BV(32))
|
||||||
for slave in self.slaves:
|
for slave in self.slaves:
|
||||||
comb.append(a(slave.a_i, self.master.a_o))
|
comb.append(slave.a_i.eq(self.master.a_o))
|
||||||
comb.append(a(slave.we_i, self.master.we_o))
|
comb.append(slave.we_i.eq(self.master.we_o))
|
||||||
comb.append(a(slave.d_i, self.master.d_o))
|
comb.append(slave.d_i.eq(self.master.d_o))
|
||||||
rb = rb | slave.d_o
|
rb = rb | slave.d_o
|
||||||
comb.append(a(self.master.d_i, rb))
|
comb.append(self.master.d_i.eq(rb))
|
||||||
return f.Fragment(comb)
|
return Fragment(comb)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from migen.fhdl import structure as f
|
from migen.fhdl.structure import *
|
||||||
|
|
||||||
def get_sig_name(signal, slave):
|
def get_sig_name(signal, slave):
|
||||||
if signal[0] ^ slave:
|
if signal[0] ^ slave:
|
||||||
|
@ -19,4 +19,4 @@ class Simple():
|
||||||
if name:
|
if name:
|
||||||
busname += "_" + name
|
busname += "_" + name
|
||||||
signame = get_sig_name(signal, slave)
|
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))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from migen.fhdl import structure as f
|
from migen.fhdl.structure import *
|
||||||
from migen.corelogic import roundrobin, multimux
|
from migen.corelogic import roundrobin, multimux
|
||||||
from migen.bus.simple import Simple, get_sig_name
|
from migen.bus.simple import Simple, get_sig_name
|
||||||
|
|
||||||
|
@ -49,16 +49,16 @@ class Arbiter:
|
||||||
for m in self.masters:
|
for m in self.masters:
|
||||||
dest = getattr(m, name)
|
dest = getattr(m, name)
|
||||||
if name == "ack_i" or name == "err_i":
|
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:
|
else:
|
||||||
comb.append(f.Assign(dest, source))
|
comb.append(dest.eq(source))
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
# connect bus requests to round-robin selector
|
# connect bus requests to round-robin selector
|
||||||
reqs = [m.cyc_o for m in self.masters]
|
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:
|
class Decoder:
|
||||||
# slaves is a list of pairs:
|
# slaves is a list of pairs:
|
||||||
|
@ -76,18 +76,18 @@ class Decoder:
|
||||||
self.register = register
|
self.register = register
|
||||||
|
|
||||||
addresses = [slave[0] for slave in self.slaves]
|
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):
|
def mkconst(x):
|
||||||
if isinstance(x, int):
|
if isinstance(x, int):
|
||||||
return f.Constant(x, f.BV(maxbits))
|
return Constant(x, BV(maxbits))
|
||||||
else:
|
else:
|
||||||
return x
|
return x
|
||||||
self.addresses = list(map(mkconst, addresses))
|
self.addresses = list(map(mkconst, addresses))
|
||||||
|
|
||||||
ns = len(self.slaves)
|
ns = len(self.slaves)
|
||||||
d = partial(f.declare_signal, self)
|
d = partial(declare_signal, self)
|
||||||
d("_slave_sel", f.BV(ns))
|
d("_slave_sel", BV(ns))
|
||||||
d("_slave_sel_r", f.BV(ns))
|
d("_slave_sel_r", BV(ns))
|
||||||
|
|
||||||
def get_fragment(self):
|
def get_fragment(self):
|
||||||
comb = []
|
comb = []
|
||||||
|
@ -97,44 +97,44 @@ class Decoder:
|
||||||
i = 0
|
i = 0
|
||||||
hi = self.master.adr_o.bv.width - self.offset
|
hi = self.master.adr_o.bv.width - self.offset
|
||||||
for addr in self.addresses:
|
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))
|
self.master.adr_o[hi-addr.bv.width:hi] == addr))
|
||||||
i += 1
|
i += 1
|
||||||
if self.register:
|
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:
|
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
|
# connect master->slaves signals except cyc
|
||||||
m2s_names = [(get_sig_name(x, False), get_sig_name(x, True))
|
m2s_names = [(get_sig_name(x, False), get_sig_name(x, True))
|
||||||
for x in _desc if x[0] and x[1] != "cyc"]
|
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]
|
for name in m2s_names for slave in self.slaves]
|
||||||
|
|
||||||
# combine cyc with slave selection signals
|
# combine cyc with slave selection signals
|
||||||
i = 0
|
i = 0
|
||||||
for slave in self.slaves:
|
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
|
i += 1
|
||||||
|
|
||||||
# generate master ack (resp. err) by ORing all slave acks (resp. errs)
|
# generate master ack (resp. err) by ORing all slave acks (resp. errs)
|
||||||
ackv = f.Constant(0)
|
ackv = Constant(0)
|
||||||
errv = f.Constant(0)
|
errv = Constant(0)
|
||||||
for slave in self.slaves:
|
for slave in self.slaves:
|
||||||
ackv = ackv | slave[1].ack_o
|
ackv = ackv | slave[1].ack_o
|
||||||
errv = errv | slave[1].err_o
|
errv = errv | slave[1].err_o
|
||||||
comb.append(f.Assign(self.master.ack_i, ackv))
|
comb.append(self.master.ack_i.eq(ackv))
|
||||||
comb.append(f.Assign(self.master.err_i, errv))
|
comb.append(self.master.err_i.eq(errv))
|
||||||
|
|
||||||
# mux (1-hot) slave data return
|
# mux (1-hot) slave data return
|
||||||
i = 0
|
i = 0
|
||||||
datav = f.Constant(0, self.master.dat_i.bv)
|
datav = Constant(0, self.master.dat_i.bv)
|
||||||
for slave in self.slaves:
|
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
|
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:
|
class InterconnectShared:
|
||||||
def __init__(self, masters, slaves, offset=0, register=False):
|
def __init__(self, masters, slaves, offset=0, register=False):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from migen.bus import wishbone
|
from migen.bus import wishbone
|
||||||
from migen.bus import csr
|
from migen.bus import csr
|
||||||
from migen.fhdl import structure as f
|
from migen.fhdl.structure import *
|
||||||
from migen.corelogic import timeline
|
from migen.corelogic import timeline
|
||||||
|
|
||||||
class Inst():
|
class Inst():
|
||||||
|
@ -8,15 +8,15 @@ class Inst():
|
||||||
self.wishbone = wishbone.Slave("to_csr")
|
self.wishbone = wishbone.Slave("to_csr")
|
||||||
self.csr = csr.Master("from_wishbone")
|
self.csr = csr.Master("from_wishbone")
|
||||||
self.timeline = timeline.Inst(self.wishbone.cyc_i & self.wishbone.stb_i,
|
self.timeline = timeline.Inst(self.wishbone.cyc_i & self.wishbone.stb_i,
|
||||||
[(1, [f.Assign(self.csr.we_o, self.wishbone.we_i)]),
|
[(1, [self.csr.we_o.eq(self.wishbone.we_i)]),
|
||||||
(2, [f.Assign(self.wishbone.ack_o, 1)]),
|
(2, [self.wishbone.ack_o.eq(1)]),
|
||||||
(3, [f.Assign(self.wishbone.ack_o, 0)])])
|
(3, [self.wishbone.ack_o.eq(0)])])
|
||||||
|
|
||||||
def get_fragment(self):
|
def get_fragment(self):
|
||||||
sync = [
|
sync = [
|
||||||
f.Assign(self.csr.we_o, 0),
|
self.csr.we_o.eq(0),
|
||||||
f.Assign(self.csr.d_o, self.wishbone.dat_i),
|
self.csr.d_o.eq(self.wishbone.dat_i),
|
||||||
f.Assign(self.csr.a_o, self.wishbone.adr_i[2:16]),
|
self.csr.a_o.eq(self.wishbone.adr_i[2:16]),
|
||||||
f.Assign(self.wishbone.dat_o, self.csr.d_i)
|
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()
|
||||||
|
|
|
@ -1,45 +1,44 @@
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from migen.fhdl import structure as f
|
from migen.fhdl.structure import *
|
||||||
|
|
||||||
class Inst:
|
class Inst:
|
||||||
def __init__(self, w):
|
def __init__(self, w):
|
||||||
self.w = w
|
self.w = w
|
||||||
|
|
||||||
d = partial(f.declare_signal, self)
|
d = partial(declare_signal, self)
|
||||||
|
|
||||||
d("start_i")
|
d("start_i")
|
||||||
d("dividend_i", f.BV(w))
|
d("dividend_i", BV(w))
|
||||||
d("divisor_i", f.BV(w))
|
d("divisor_i", BV(w))
|
||||||
d("ready_o")
|
d("ready_o")
|
||||||
d("quotient_o", f.BV(w))
|
d("quotient_o", BV(w))
|
||||||
d("remainder_o", f.BV(w))
|
d("remainder_o", BV(w))
|
||||||
|
|
||||||
d("_qr", f.BV(2*w))
|
d("_qr", BV(2*w))
|
||||||
d("_counter", f.BV(f.bits_for(w)))
|
d("_counter", BV(bits_for(w)))
|
||||||
d("_divisor_r", f.BV(w))
|
d("_divisor_r", BV(w))
|
||||||
d("_diff", f.BV(w+1))
|
d("_diff", BV(w+1))
|
||||||
|
|
||||||
def get_fragment(self):
|
def get_fragment(self):
|
||||||
a = f.Assign
|
|
||||||
comb = [
|
comb = [
|
||||||
a(self.quotient_o, self._qr[:self.w]),
|
self.quotient_o.eq(self._qr[:self.w]),
|
||||||
a(self.remainder_o, self._qr[self.w:]),
|
self.remainder_o.eq(self._qr[self.w:]),
|
||||||
a(self.ready_o, self._counter == f.Constant(0, self._counter.bv)),
|
self.ready_o.eq(self._counter == Constant(0, self._counter.bv)),
|
||||||
a(self._diff, self.remainder_o - self._divisor_r)
|
self._diff.eq(self.remainder_o - self._divisor_r)
|
||||||
]
|
]
|
||||||
sync = [
|
sync = [
|
||||||
f.If(self.start_i == 1, [
|
If(self.start_i,
|
||||||
a(self._counter, self.w),
|
self._counter.eq(self.w),
|
||||||
a(self._qr, self.dividend_i),
|
self._qr.eq(self.dividend_i),
|
||||||
a(self._divisor_r, self.divisor_i)
|
self._divisor_r.eq(self.divisor_i)
|
||||||
], [
|
).Elif(~self.ready_o,
|
||||||
f.If(self.ready_o == 0, [
|
If(self._diff[self.w],
|
||||||
f.If(self._diff[self.w] == 1,
|
self._qr.eq(Cat(0, self._qr[:2*self.w-1]))
|
||||||
[a(self._qr, f.Cat(0, self._qr[:2*self.w-1]))],
|
).Else(
|
||||||
[a(self._qr, f.Cat(1, self._qr[:self.w-1], self._diff[:self.w]))]),
|
self._qr.eq(Cat(1, self._qr[:self.w-1], self._diff[:self.w]))
|
||||||
a(self._counter, self._counter - f.Constant(1, self._counter.bv)),
|
),
|
||||||
])
|
self._counter.eq(self._counter - Constant(1, self._counter.bv))
|
||||||
])
|
)
|
||||||
]
|
]
|
||||||
return f.Fragment(comb, sync)
|
return Fragment(comb, sync)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from migen.fhdl import structure as f
|
from migen.fhdl.structure import *
|
||||||
|
|
||||||
def multimux(sel, inputs, output):
|
def multimux(sel, inputs, output):
|
||||||
n = len(inputs)
|
n = len(inputs)
|
||||||
|
@ -6,8 +6,8 @@ def multimux(sel, inputs, output):
|
||||||
comb = []
|
comb = []
|
||||||
for osig in output:
|
for osig in output:
|
||||||
choices = [x[i] for x in inputs]
|
choices = [x[i] for x in inputs]
|
||||||
cases = [(f.Constant(j, sel.bv), [f.Assign(osig, choices[j])]) for j in range(n)]
|
cases = [[Constant(j, sel.bv), osig.eq(choices[j])] for j in range(n)]
|
||||||
default = cases.pop()[1]
|
cases[n-1][0] = Default()
|
||||||
comb.append(f.Case(sel, cases, default))
|
comb.append(Case(sel, *cases))
|
||||||
i += 1
|
i += 1
|
||||||
return comb
|
return comb
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
from migen.fhdl import structure as f
|
from migen.fhdl.structure import *
|
||||||
|
|
||||||
class Inst:
|
class Inst:
|
||||||
def __init__(self, n):
|
def __init__(self, n):
|
||||||
self.n = n
|
self.n = n
|
||||||
self.bn = f.bits_for(self.n-1)
|
self.bn = bits_for(self.n-1)
|
||||||
f.declare_signal(self, "request", f.BV(self.n))
|
declare_signal(self, "request", BV(self.n))
|
||||||
f.declare_signal(self, "grant", f.BV(self.bn))
|
declare_signal(self, "grant", BV(self.bn))
|
||||||
|
|
||||||
def get_fragment(self):
|
def get_fragment(self):
|
||||||
cases = []
|
cases = []
|
||||||
|
@ -13,10 +13,14 @@ class Inst:
|
||||||
switch = []
|
switch = []
|
||||||
for j in reversed(range(i+1,i+self.n)):
|
for j in reversed(range(i+1,i+self.n)):
|
||||||
t = j % self.n
|
t = j % self.n
|
||||||
switch = [f.If(self.request[t],
|
switch = [
|
||||||
[f.Assign(self.grant, f.Constant(t, f.BV(self.bn)))],
|
If(self.request[t],
|
||||||
switch)]
|
self.grant.eq(Constant(t, BV(self.bn)))
|
||||||
case = f.If(~self.request[i], switch)
|
).Else(
|
||||||
cases.append((f.Constant(i, f.BV(self.bn)), case))
|
*switch
|
||||||
statement = f.Case(self.grant, cases)
|
)
|
||||||
return f.Fragment(sync=[statement])
|
]
|
||||||
|
case = If(~self.request[i], *switch)
|
||||||
|
cases.append([Constant(i, BV(self.bn)), case])
|
||||||
|
statement = Case(self.grant, *cases)
|
||||||
|
return Fragment(sync=[statement])
|
||||||
|
|
|
@ -1,27 +1,31 @@
|
||||||
from migen.fhdl import structure as f
|
from migen.fhdl.structure import *
|
||||||
|
|
||||||
class Inst:
|
class Inst:
|
||||||
def __init__(self, trigger, events):
|
def __init__(self, trigger, events):
|
||||||
self.trigger = trigger
|
self.trigger = trigger
|
||||||
self.events = events
|
self.events = events
|
||||||
self.lastevent = max([e[0] for e in 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):
|
def get_fragment(self):
|
||||||
counterlogic = f.If(self._counter != f.Constant(0, self._counter.bv),
|
counterlogic = If(self._counter != Constant(0, self._counter.bv),
|
||||||
[f.Assign(self._counter, self._counter + f.Constant(1, self._counter.bv))],
|
self._counter.eq(self._counter + Constant(1, self._counter.bv))
|
||||||
[f.If(self.trigger, [f.Assign(self._counter, f.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
|
# insert counter reset if it doesn't automatically overflow
|
||||||
# (test if self.lastevent+1 is a power of 2)
|
# (test if self.lastevent+1 is a power of 2)
|
||||||
if (self.lastevent & (self.lastevent + 1)) != 0:
|
if (self.lastevent & (self.lastevent + 1)) != 0:
|
||||||
counterlogic = f.If(self._counter == self.lastevent,
|
counterlogic = If(self._counter == self.lastevent,
|
||||||
[f.Assign(self._counter, f.Constant(0, self._counter.bv))],
|
self._counter.eq(Constant(0, self._counter.bv))
|
||||||
[counterlogic])
|
).Else(
|
||||||
|
counterlogic
|
||||||
|
)
|
||||||
def get_cond(e):
|
def get_cond(e):
|
||||||
if e[0] == 0:
|
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:
|
else:
|
||||||
return self._counter == f.Constant(e[0], self._counter.bv)
|
return self._counter == Constant(e[0], self._counter.bv)
|
||||||
sync = [f.If(get_cond(e), e[1]) for e in self.events]
|
sync = [If(get_cond(e), *e[1]) for e in self.events]
|
||||||
sync.append(counterlogic)
|
sync.append(counterlogic)
|
||||||
return f.Fragment(sync=sync)
|
return Fragment(sync=sync)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from .structure import *
|
from migen.fhdl.structure import *
|
||||||
|
from migen.fhdl.structure import _Operator
|
||||||
|
|
||||||
class Namespace:
|
class Namespace:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -29,7 +30,7 @@ def list_signals(node):
|
||||||
return set()
|
return set()
|
||||||
elif isinstance(node, Signal):
|
elif isinstance(node, Signal):
|
||||||
return {node}
|
return {node}
|
||||||
elif isinstance(node, Operator):
|
elif isinstance(node, _Operator):
|
||||||
l = list(map(list_signals, node.operands))
|
l = list(map(list_signals, node.operands))
|
||||||
return set().union(*l)
|
return set().union(*l)
|
||||||
elif isinstance(node, Slice):
|
elif isinstance(node, Slice):
|
||||||
|
@ -105,7 +106,5 @@ def is_variable(node):
|
||||||
|
|
||||||
def insert_reset(rst, sl):
|
def insert_reset(rst, sl):
|
||||||
targets = list_targets(sl)
|
targets = list_targets(sl)
|
||||||
resetcode = []
|
resetcode = [t.eq(t.reset) for t in targets]
|
||||||
for t in targets:
|
return If(rst, *resetcode).Else(*sl.l)
|
||||||
resetcode.append(Assign(t, t.reset))
|
|
||||||
return If(rst, resetcode, sl)
|
|
||||||
|
|
|
@ -23,53 +23,53 @@ class BV:
|
||||||
|
|
||||||
class Value:
|
class Value:
|
||||||
def __invert__(self):
|
def __invert__(self):
|
||||||
return Operator("~", [self])
|
return _Operator("~", [self])
|
||||||
|
|
||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
return Operator("+", [self, other])
|
return _Operator("+", [self, other])
|
||||||
def __radd__(self, other):
|
def __radd__(self, other):
|
||||||
return Operator("+", [other, self])
|
return _Operator("+", [other, self])
|
||||||
def __sub__(self, other):
|
def __sub__(self, other):
|
||||||
return Operator("-", [self, other])
|
return _Operator("-", [self, other])
|
||||||
def __rsub__(self, other):
|
def __rsub__(self, other):
|
||||||
return Operator("-", [other, self])
|
return _Operator("-", [other, self])
|
||||||
def __mul__(self, other):
|
def __mul__(self, other):
|
||||||
return Operator("*", [self, other])
|
return _Operator("*", [self, other])
|
||||||
def __rmul__(self, other):
|
def __rmul__(self, other):
|
||||||
return Operator("*", [other, self])
|
return _Operator("*", [other, self])
|
||||||
def __lshift__(self, other):
|
def __lshift__(self, other):
|
||||||
return Operator("<<", [self, other])
|
return _Operator("<<", [self, other])
|
||||||
def __rlshift__(self, other):
|
def __rlshift__(self, other):
|
||||||
return Operator("<<", [other, self])
|
return _Operator("<<", [other, self])
|
||||||
def __rshift__(self, other):
|
def __rshift__(self, other):
|
||||||
return Operator(">>", [self, other])
|
return _Operator(">>", [self, other])
|
||||||
def __rrshift__(self, other):
|
def __rrshift__(self, other):
|
||||||
return Operator(">>", [other, self])
|
return _Operator(">>", [other, self])
|
||||||
def __and__(self, other):
|
def __and__(self, other):
|
||||||
return Operator("&", [self, other])
|
return _Operator("&", [self, other])
|
||||||
def __rand__(self, other):
|
def __rand__(self, other):
|
||||||
return Operator("&", [other, self])
|
return _Operator("&", [other, self])
|
||||||
def __xor__(self, other):
|
def __xor__(self, other):
|
||||||
return Operator("^", [self, other])
|
return _Operator("^", [self, other])
|
||||||
def __rxor__(self, other):
|
def __rxor__(self, other):
|
||||||
return Operator("^", [other, self])
|
return _Operator("^", [other, self])
|
||||||
def __or__(self, other):
|
def __or__(self, other):
|
||||||
return Operator("|", [self, other])
|
return _Operator("|", [self, other])
|
||||||
def __ror__(self, other):
|
def __ror__(self, other):
|
||||||
return Operator("|", [other, self])
|
return _Operator("|", [other, self])
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
return Operator("<", [self, other])
|
return _Operator("<", [self, other])
|
||||||
def __le__(self, other):
|
def __le__(self, other):
|
||||||
return Operator("<=", [self, other])
|
return _Operator("<=", [self, other])
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return Operator("==", [self, other])
|
return _Operator("==", [self, other])
|
||||||
def __ne__(self, other):
|
def __ne__(self, other):
|
||||||
return Operator("!=", [self, other])
|
return _Operator("!=", [self, other])
|
||||||
def __gt__(self, other):
|
def __gt__(self, other):
|
||||||
return Operator(">", [self, other])
|
return _Operator(">", [self, other])
|
||||||
def __ge__(self, other):
|
def __ge__(self, other):
|
||||||
return Operator(">=", [self, other])
|
return _Operator(">=", [self, other])
|
||||||
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
|
@ -85,8 +85,11 @@ class Value:
|
||||||
return Slice(self, start, stop)
|
return Slice(self, start, stop)
|
||||||
else:
|
else:
|
||||||
raise KeyError
|
raise KeyError
|
||||||
|
|
||||||
|
def eq(self, r):
|
||||||
|
return Assign(self, r)
|
||||||
|
|
||||||
class Operator(Value):
|
class _Operator(Value):
|
||||||
def __init__(self, op, operands):
|
def __init__(self, op, operands):
|
||||||
self.op = op
|
self.op = op
|
||||||
self.operands = list(map(_cst, operands))
|
self.operands = list(map(_cst, operands))
|
||||||
|
@ -151,23 +154,41 @@ class StatementList:
|
||||||
if l is None: l = []
|
if l is None: l = []
|
||||||
self.l = 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):
|
def _sl(x):
|
||||||
if isinstance(x, list):
|
if isinstance(x, list):
|
||||||
return StatementList(x)
|
return StatementList(x)
|
||||||
else:
|
else:
|
||||||
return x
|
return x
|
||||||
|
|
||||||
class If:
|
class Default:
|
||||||
def __init__(self, cond, t, f=StatementList()):
|
pass
|
||||||
self.cond = cond
|
|
||||||
self.t = _sl(t)
|
|
||||||
self.f = _sl(f)
|
|
||||||
|
|
||||||
class Case:
|
class Case:
|
||||||
def __init__(self, test, cases=[], default=StatementList()):
|
def __init__(self, test, *cases):
|
||||||
self.test = test
|
self.test = test
|
||||||
self.cases = [(c[0], _sl(c[1])) for c in cases]
|
self.cases = [(c[0], StatementList(c[1:])) for c in cases if not isinstance(c[0], Default)]
|
||||||
self.default = _sl(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()
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from migen.fhdl.structure import *
|
from migen.fhdl.structure import *
|
||||||
|
from migen.fhdl.structure import _Operator
|
||||||
from migen.fhdl.convtools import *
|
from migen.fhdl.convtools import *
|
||||||
|
|
||||||
def _printsig(ns, s):
|
def _printsig(ns, s):
|
||||||
|
@ -21,7 +22,7 @@ def _printexpr(ns, node):
|
||||||
return "-" + str(node.bv) + str(-self.n)
|
return "-" + str(node.bv) + str(-self.n)
|
||||||
elif isinstance(node, Signal):
|
elif isinstance(node, Signal):
|
||||||
return ns.get_name(node)
|
return ns.get_name(node)
|
||||||
elif isinstance(node, Operator):
|
elif isinstance(node, _Operator):
|
||||||
arity = len(node.operands)
|
arity = len(node.operands)
|
||||||
if arity == 1:
|
if arity == 1:
|
||||||
r = node.op + _printexpr(ns, node.operands[0])
|
r = node.op + _printexpr(ns, node.operands[0])
|
||||||
|
|
Loading…
Reference in a new issue