d = Divider(32)
f = d.GetFragment()
-o = verilog.Convert(f, {d.start_i, d.dividend_i, d.divisor_i}, {d.ready_o, d.quotient_o, d.remainder_o})
+o = verilog.Convert(f, {d.ready_o, d.quotient_o, d.remainder_o}, {d.start_i, d.dividend_i, d.divisor_i})
print(o)
\ No newline at end of file
--- /dev/null
+from migen.fhdl import structure as f
+from migen.fhdl import verilog
+from migen.bank import description, csrgen
+
+ninputs = 4
+noutputs = 4
+
+oreg = description.Register("o")
+ofield = description.Field(oreg, "val", noutputs)
+ireg = description.Register("i")
+ifield = description.Field(ireg, "val", ninputs, description.READ_ONLY, description.WRITE_ONLY)
+
+# input path
+gpio_in = f.Signal(f.BV(ninputs), name="gpio_in")
+gpio_in_s = f.Signal(f.BV(ninputs), name="gpio_in_s") # synchronizer
+incomb = [f.Assign(ifield.dev_we, 1)]
+insync = [f.Assign(gpio_in_s, gpio_in), f.Assign(ifield.dev_w, gpio_in_s)]
+inf = f.Fragment(incomb, insync)
+
+bank = csrgen.Bank([oreg, ireg])
+f = bank.GetFragment() + inf
+i = bank.interface
+ofield.dev_r.name = "gpio_out"
+v = verilog.Convert(f, {i.d_o, ofield.dev_r}, {i.a_i, i.we_i, i.d_i, gpio_in})
+print(v)
\ No newline at end of file
--- /dev/null
+from ..fhdl import structure as f
+from ..bus.csr import *
+from .description import *
+from functools import partial
+
+class Bank:
+ def __init__(self, description, address=0):
+ self.description = description
+ self.address = address
+ self.interface = Slave()
+ d = partial(f.Declare, self)
+ d("_sel")
+
+ def GetFragment(self):
+ a = f.Assign
+ comb = []
+ sync = []
+
+ comb.append(a(self._sel, self.interface.a_i[12:] == f.Constant(self.address, f.BV(4))))
+
+ nregs = len(self.description)
+ nbits = f.BitsFor(nregs-1)
+
+ # Bus writes
+ bwcases = []
+ for i in range(nregs):
+ reg = self.description[i]
+ nfields = len(reg.fields)
+ bwra = []
+ 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))
+ if bwcases:
+ sync.append(f.If(self._sel & self.interface.we_i, [f.Case(self.interface.a_i[:nbits], bwcases)]))
+
+ # Bus reads
+ brcases = []
+ for i in range(nregs):
+ reg = self.description[i]
+ nfields = len(reg.fields)
+ brs = []
+ reg_readable = False
+ for j in range(nfields):
+ field = reg.fields[j]
+ if field.access_bus == READ_ONLY or field.access_bus == READ_WRITE:
+ brs.append(field.storage)
+ reg_readable = True
+ else:
+ brs.append(f.Constant(0, f.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))]))
+ else:
+ brcases.append((f.Constant(i, f.BV(nbits)), [a(self.interface.d_o, 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)]))
+ else:
+ comb.append(a(self.interface.d_o, f.Constant(0, f.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))
+ 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)]))
+
+ return f.Fragment(comb, sync)
\ No newline at end of file
--- /dev/null
+from ..fhdl import structure as f
+
+class Register:
+ def __init__(self, name):
+ self.name = name
+ self.fields = []
+
+ def AddField(self, f):
+ self.fields.append(f)
+
+(READ_ONLY, WRITE_ONLY, READ_WRITE) = range(3)
+
+class Field:
+ def __init__(self, parent, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0):
+ self.parent = parent
+ self.name = name
+ self.size = size
+ self.access_bus = access_bus
+ self.access_dev = access_dev
+ self.reset = reset
+ fullname = parent.name + "_" + name
+ self.storage = f.Signal(f.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")
+ 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.AddField(self)
\ No newline at end of file
return set().union(*l)
elif isinstance(node, If):
return ListSignals(node.cond) | ListSignals(node.t) | ListSignals(node.f)
+ elif isinstance(node, Case):
+ l = list(map(lambda x: ListSignals(x[1]), node.cases))
+ return ListSignals(node.test).union(*l).union(ListSignals(node.default))
elif isinstance(node, Fragment):
return ListSignals(node.comb) | ListSignals(node.sync)
else:
return set().union(*l)
elif isinstance(node, If):
return ListTargets(node.t) | ListTargets(node.f)
+ elif isinstance(node, Case):
+ l = list(map(lambda x: ListTargets(x[1]), node.cases))
+ return ListTargets(node.default).union(*l)
else:
raise TypeError
for t in targets:
if not t.variable:
resetcode.append(Assign(t, t.reset))
- return If(rst == 1, resetcode, sl)
\ No newline at end of file
+ return If(rst, resetcode, sl)
\ No newline at end of file
return r
class Case:
- def __init__(self, test, cases=[]):
+ def __init__(self, test, cases=[], default=StatementList()):
self.test = test
- self.cases = cases
+ self.cases = [(c[0], _sl(c[1])) for c in cases]
+ self.default = _sl(default)
#
self.sync = _sl(sync)
def __str__(self):
- return "Comb:\n" + _indent(str(self.comb)) + "\nSync:\n" + _indent(str(self.sync))
\ No newline at end of file
+ return "Comb:\n" + _indent(str(self.comb)) + "\nSync:\n" + _indent(str(self.sync))
+
+ def __add__(self, other):
+ return Fragment(self.comb.l + other.comb.l, self.sync.l + other.sync.l)
\ No newline at end of file
from .convtools import *
from functools import partial
-def Convert(f, ins, outs, name="top", clkname="sys_clk", rstname="sys_rst"):
+def Convert(f, outs=set(), ins=set(), name="top", clkname="sys_clk", rstname="sys_rst"):
ns = Namespace()
clks = Signal(name=clkname)
elif isinstance(node, StatementList):
return "".join(list(map(partial(printnode, level), node.l)))
elif isinstance(node, If):
- r = "\t"*level + "if " + printnode(level, node.cond) + " begin\n"
+ r = "\t"*level + "if (" + printnode(level, node.cond) + ") begin\n"
r += printnode(level + 1, node.t)
if node.f.l:
r += "\t"*level + "end else begin\n"
r += printnode(level + 1, node.f)
r += "\t"*level + "end\n"
return r
+ elif isinstance(node, Case):
+ r = "\t"*level + "case (" + printnode(level, node.test) + ")\n"
+ for case in node.cases:
+ r += "\t"*(level + 1) + printnode(level, case[0]) + ": begin\n"
+ r += printnode(level + 2, case[1])
+ r += "\t"*(level + 1) + "end\n"
+ r += "\t"*level + "endcase\n"
+ return r
else:
raise TypeError