move pytholite to separate repos

This commit is contained in:
Sebastien Bourdeauducq 2015-03-14 22:48:03 +01:00
parent c824379878
commit beeaefccea
10 changed files with 0 additions and 1105 deletions

View file

@ -1,46 +0,0 @@
from migen.flow.network import *
from migen.flow.transactions import *
from migen.actorlib.sim import *
from migen.pytholite.compiler import Pytholite
from migen.sim.generic import run_simulation
from migen.fhdl import verilog
layout = [("r", 32)]
def number_gen(n):
for i in range(n):
yield Token("result", {"r": i})
class SimNumberGen(SimActor):
def __init__(self):
self.result = Source(layout)
SimActor.__init__(self, number_gen(5))
def run_ng_sim(ng):
g = DataFlowGraph()
d = Dumper(layout)
g.add_connection(ng, d)
c = CompositeActor(g)
run_simulation(c, ncycles=20)
def make_ng_pytholite():
ng_pytholite = Pytholite(number_gen, 5)
ng_pytholite.result = Source(layout)
ng_pytholite.finalize()
return ng_pytholite
def main():
print("Simulating native Python:")
ng_native = SimNumberGen()
run_ng_sim(ng_native)
print("Simulating Pytholite:")
ng_pytholite = make_ng_pytholite()
run_ng_sim(ng_pytholite)
print("Converting Pytholite to Verilog:")
ng_pytholite = make_ng_pytholite()
print(verilog.convert(ng_pytholite))
main()

View file

@ -1,67 +0,0 @@
from migen.flow.network import *
from migen.flow.transactions import *
from migen.actorlib.sim import Dumper
from migen.bus import wishbone
from migen.bus.transactions import *
from migen.genlib.ioo import UnifiedIOSimulation
from migen.pytholite.transel import Register
from migen.pytholite.compiler import Pytholite
from migen.sim.generic import run_simulation
from migen.fhdl.std import *
from migen.fhdl import verilog
layout = [("r", 32)]
def gen():
ds = Register(32)
for i in range(3):
r = TRead(i, busname="mem")
yield r
ds.store = r.data
yield Token("result", {"r": ds})
for i in range(5):
r = TRead(i, busname="wb")
yield r
ds.store = r.data
yield Token("result", {"r": ds})
class SlaveModel(wishbone.TargetModel):
def read(self, address):
return address + 4
class TestBench(Module):
def __init__(self, ng):
g = DataFlowGraph()
d = Dumper(layout)
g.add_connection(ng, d)
self.submodules.slave = wishbone.Target(SlaveModel())
self.submodules.intercon = wishbone.InterconnectPointToPoint(ng.wb, self.slave.bus)
self.submodules.ca = CompositeActor(g)
def run_ng_sim(ng):
run_simulation(TestBench(ng), ncycles=50)
def add_interfaces(obj):
obj.result = Source(layout)
obj.wb = wishbone.Interface()
obj.mem = Memory(32, 3, init=[42, 37, 81])
obj.finalize()
def main():
print("Simulating native Python:")
ng_native = UnifiedIOSimulation(gen())
add_interfaces(ng_native)
run_ng_sim(ng_native)
print("Simulating Pytholite:")
ng_pytholite = Pytholite(gen)
add_interfaces(ng_pytholite)
run_ng_sim(ng_pytholite)
print("Converting Pytholite to Verilog:")
ng_pytholite = Pytholite(gen)
add_interfaces(ng_pytholite)
print(verilog.convert(ng_pytholite))
main()

View file

@ -1,79 +0,0 @@
from migen.util.misc import xdir
from migen.fhdl.std import *
from migen.flow.actor import *
from migen.flow.actor import _Endpoint
from migen.flow.transactions import *
from migen.actorlib.sim import TokenExchanger
from migen.bus import wishbone, memory
from migen.bus.transactions import *
class UnifiedIOObject(Module):
def do_finalize(self):
if self.get_dataflow():
self.busy = Signal()
self.specials += set(v for k, v in xdir(self, True) if isinstance(v, Memory))
def get_dataflow(self):
return dict((k, v) for k, v in xdir(self, True) if isinstance(v, _Endpoint))
def get_buses(self):
return dict((k, v) for k, v in xdir(self, True) if isinstance(v, (wishbone.Interface, Memory)))
(_WAIT_COMPLETE, _WAIT_POLL) = range(2)
class UnifiedIOSimulation(UnifiedIOObject):
def __init__(self, generator):
self.generator = generator
def do_finalize(self):
UnifiedIOObject.do_finalize(self)
callers = []
self.busname_to_caller_id = {}
if self.get_dataflow():
callers.append(TokenExchanger(self.dispatch_g(0), self))
for k, v in self.get_buses().items():
caller_id = len(callers)
self.busname_to_caller_id[k] = caller_id
g = self.dispatch_g(caller_id)
if isinstance(v, wishbone.Interface):
caller = wishbone.Initiator(g, v)
elif isinstance(v, Memory):
caller = memory.Initiator(g, v)
callers.append(caller)
self.submodules += callers
self.dispatch_state = _WAIT_COMPLETE
self.dispatch_caller = 0
self.pending_transaction = None
def identify_transaction(self, t):
if isinstance(t, Token):
return 0
elif isinstance(t, TRead) or isinstance(t, TWrite):
if t.busname is None:
if len(self.busname_to_caller_id) != 1:
raise TypeError
else:
return list(self.busname_to_caller_id.values())[0]
else:
return self.busname_to_caller_id[t.busname]
else:
raise TypeError
def dispatch_g(self, caller_id):
while True:
if self.dispatch_state == _WAIT_COMPLETE and self.dispatch_caller == caller_id:
transaction = next(self.generator)
tr_cid = self.identify_transaction(transaction)
self.dispatch_caller = tr_cid
if tr_cid == caller_id:
yield transaction
else:
self.pending_transaction = transaction
self.dispatch_state = _WAIT_POLL
yield None
elif self.dispatch_state == _WAIT_POLL and self.dispatch_caller == caller_id:
self.dispatch_state = _WAIT_COMPLETE
yield self.pending_transaction
else:
yield None

View file

@ -1,318 +0,0 @@
import inspect
import ast
from collections import OrderedDict
from migen.util.misc import xdir
from migen.fhdl.structure import *
from migen.fhdl.visit import TransformModule
from migen.fhdl.specials import Memory
from migen.genlib.ioo import UnifiedIOObject
from migen.pytholite.reg import *
from migen.pytholite.expr import *
from migen.pytholite import transel
from migen.pytholite.io import gen_io
from migen.pytholite.util import *
def _is_name_used(node, name):
for n in ast.walk(node):
if isinstance(n, ast.Name) and n.id == name:
return True
return False
def _make_function_args_dict(undefined, symdict, args, defaults):
d = OrderedDict()
for argument in args:
d[argument.arg] = undefined
for default, argname in zip(defaults, reversed(list(d.keys()))):
default_val = eval_ast(default, symdict)
d[argname] = default_val
return d
def _process_function_args(symdict, function_def, args, kwargs):
defargs = function_def.args
undefined = object()
ad_positional = _make_function_args_dict(undefined, symdict, defargs.args, defargs.defaults)
vararg_name = defargs.vararg
kwarg_name = defargs.kwarg
ad_kwonly = _make_function_args_dict(undefined, symdict, defargs.kwonlyargs, defargs.kw_defaults)
# grab argument values
current_argvalue = iter(args)
try:
for argname in ad_positional.keys():
ad_positional[argname] = next(current_argvalue)
except StopIteration:
pass
vararg = tuple(current_argvalue)
kwarg = dict()
for k, v in kwargs.items():
if k in ad_positional:
ad_positional[k] = v
elif k in ad_kwonly:
ad_kwonly[k] = v
else:
kwarg[k] = v
# check
undefined_pos = [k for k, v in ad_positional.items() if v is undefined]
if undefined_pos:
formatted = " and ".join("'" + k + "'" for k in undefined_pos)
raise TypeError("Missing required positional arguments: " + formatted)
if vararg and vararg_name is None:
raise TypeError("Function takes {} positional arguments but {} were given".format(len(ad_positional),
len(ad_positional) + len(vararg)))
ad_kwonly = [k for k, v in ad_positional.items() if v is undefined]
if undefined_pos:
formatted = " and ".join("'" + k + "'" for k in undefined_pos)
raise TypeError("Missing required keyword-only arguments: " + formatted)
if kwarg and kwarg_name is None:
formatted = " and ".join("'" + k + "'" for k in kwarg.keys())
raise TypeError("Got unexpected keyword arguments: " + formatted)
# update symdict
symdict.update(ad_positional)
if vararg_name is not None:
symdict[vararg_name] = vararg
symdict.update(ad_kwonly)
if kwarg_name is not None:
symdict[kwarg_name] = kwarg
class _Compiler:
def __init__(self, ioo, symdict, registers):
self.ioo = ioo
self.symdict = symdict
self.registers = registers
self.ec = ExprCompiler(self.symdict)
def visit_top(self, node, args, kwargs):
if isinstance(node, ast.Module) \
and len(node.body) == 1 \
and isinstance(node.body[0], ast.FunctionDef):
function_def = node.body[0]
_process_function_args(self.symdict, function_def, args, kwargs)
states, exit_states = self.visit_block(function_def.body)
return states
else:
raise NotImplementedError
# blocks and statements
def visit_block(self, statements):
sa = StateAssembler()
statements = iter(statements)
statement = None
while True:
if statement is None:
try:
statement = next(statements)
except StopIteration:
return sa.ret()
if isinstance(statement, ast.Assign):
# visit_assign can recognize a I/O pattern, consume several
# statements from the iterator and return the first statement
# that is not part of the I/O pattern anymore.
statement = self.visit_assign(sa, statement, statements)
else:
if isinstance(statement, ast.If):
self.visit_if(sa, statement)
elif isinstance(statement, ast.While):
self.visit_while(sa, statement)
elif isinstance(statement, ast.For):
self.visit_for(sa, statement)
elif isinstance(statement, ast.Expr):
self.visit_expr_statement(sa, statement)
else:
raise NotImplementedError
statement = None
def visit_assign(self, sa, node, statements):
if isinstance(node.value, ast.Call):
is_special = False
try:
value = self.ec.visit_expr_call(node.value)
except NotImplementedError:
is_special = True
if is_special:
return self.visit_assign_special(sa, node, statements)
else:
value = self.ec.visit_expr(node.value)
if isinstance(value, (int, bool, Value)):
r = []
for target in node.targets:
if isinstance(target, ast.Attribute) and target.attr == "store":
treg = target.value
if isinstance(treg, ast.Name):
r.append(self.symdict[treg.id].load(value))
else:
raise NotImplementedError
else:
raise NotImplementedError
sa.assemble([r], [r])
else:
raise NotImplementedError
def visit_assign_special(self, sa, node, statements):
value = node.value
assert(isinstance(value, ast.Call))
if isinstance(value.func, ast.Name):
callee = self.symdict[value.func.id]
else:
raise NotImplementedError
if callee == transel.Register:
if len(value.args) != 1:
raise TypeError("Register() takes exactly 1 argument")
bits_sign = eval_ast(value.args[0], self.symdict)
if isinstance(node.targets[0], ast.Name):
targetname = node.targets[0].id
else:
targetname = "unk"
reg = ImplRegister(targetname, bits_sign)
self.registers.append(reg)
for target in node.targets:
if isinstance(target, ast.Name):
self.symdict[target.id] = reg
else:
raise NotImplementedError
else:
return self.visit_io_pattern(sa, node.targets, callee, value.args, value.keywords, statements)
def visit_io_pattern(self, sa, targets, model, args, keywords, statements):
# first statement is <modelname> = <model>(<args>)
if len(targets) != 1 or not isinstance(targets[0], ast.Name):
raise NotImplementedError("Unrecognized I/O pattern")
modelname = targets[0].id
if modelname in self.symdict:
raise NotImplementedError("I/O model name is not free")
# second statement must be yield <modelname>
try:
ystatement = next(statements)
except StopIteration:
raise NotImplementedError("Incomplete or fragmented I/O pattern")
if not isinstance(ystatement, ast.Expr) \
or not isinstance(ystatement.value, ast.Yield) \
or not isinstance(ystatement.value.value, ast.Name) \
or ystatement.value.value.id != modelname:
print(ast.dump(ystatement))
raise NotImplementedError("Unrecognized I/O pattern")
# following optional statements are assignments to registers
# with <modelname> used in expressions.
from_model = []
while True:
try:
fstatement = next(statements)
except StopIteration:
fstatement = None
if not isinstance(fstatement, ast.Assign) \
or not _is_name_used(fstatement.value, modelname):
break
tregs = []
for target in fstatement.targets:
if isinstance(target, ast.Attribute) and target.attr == "store":
if isinstance(target.value, ast.Name):
tregs.append(self.symdict[target.value.id])
else:
raise NotImplementedError
else:
raise NotImplementedError
from_model.append((tregs, fstatement.value))
states, exit_states = gen_io(self, modelname, model, args, keywords, from_model)
sa.assemble(states, exit_states)
return fstatement
def visit_if(self, sa, node):
test = self.ec.visit_expr(node.test)
states_t, exit_states_t = self.visit_block(node.body)
states_f, exit_states_f = self.visit_block(node.orelse)
exit_states = exit_states_t + exit_states_f
test_state_stmt = If(test, id_next_state(states_t[0]))
test_state = [test_state_stmt]
if states_f:
test_state_stmt.Else(id_next_state(states_f[0]))
else:
exit_states.append(test_state)
sa.assemble([test_state] + states_t + states_f,
exit_states)
def visit_while(self, sa, node):
test = self.ec.visit_expr(node.test)
states_b, exit_states_b = self.visit_block(node.body)
test_state = [If(test, id_next_state(states_b[0]))]
for exit_state in exit_states_b:
exit_state.insert(0, id_next_state(test_state))
sa.assemble([test_state] + states_b, [test_state])
def visit_for(self, sa, node):
if not isinstance(node.target, ast.Name):
raise NotImplementedError
target = node.target.id
if target in self.symdict:
raise NotImplementedError("For loop target must use an available name")
it = self.visit_iterator(node.iter)
states = []
last_exit_states = []
for iteration in it:
self.symdict[target] = iteration
states_b, exit_states_b = self.visit_block(node.body)
for exit_state in last_exit_states:
exit_state.insert(0, id_next_state(states_b[0]))
last_exit_states = exit_states_b
states += states_b
del self.symdict[target]
sa.assemble(states, last_exit_states)
def visit_iterator(self, node):
return eval_ast(node, self.symdict)
def visit_expr_statement(self, sa, node):
if isinstance(node.value, ast.Yield):
yvalue = node.value.value
if not isinstance(yvalue, ast.Call) or not isinstance(yvalue.func, ast.Name):
raise NotImplementedError("Unrecognized I/O pattern")
callee = self.symdict[yvalue.func.id]
states, exit_states = gen_io(self, None, callee, yvalue.args, yvalue.keywords, [])
sa.assemble(states, exit_states)
else:
raise NotImplementedError
class Pytholite(UnifiedIOObject):
def __init__(self, func, *args, **kwargs):
self.func = func
self.args = args
self.kwargs = kwargs
def do_finalize(self):
UnifiedIOObject.do_finalize(self)
if self.get_dataflow():
self.busy.reset = 1
self.memory_ports = dict()
for key in xdir(self):
mem = getattr(self, key)
if isinstance(mem, Memory):
port = mem.get_port(write_capable=True, we_granularity=8)
self.specials += port
self.memory_ports[mem] = port
self._compile()
def _compile(self):
tree = ast.parse(inspect.getsource(self.func))
symdict = self.func.__globals__.copy()
registers = []
states = _Compiler(self, symdict, registers).visit_top(tree, self.args, self.kwargs)
for register in registers:
if register.source_encoding:
register.finalize()
self.submodules += register
fsm = implement_fsm(states)
self.submodules += TransformModule(LowerAbstractLoad().visit, fsm)

View file

@ -1,122 +0,0 @@
import ast
from migen.fhdl.structure import *
from migen.fhdl.structure import _Slice
from migen.pytholite import transel
from migen.pytholite.reg import *
from migen.pytholite.util import eval_ast
class ExprCompiler:
def __init__(self, symdict):
self.symdict = symdict
def visit_expr(self, node):
# Attempt compile-time evaluation first
try:
result = eval_ast(node, self.symdict)
except:
result = None
if isinstance(result, int):
return result
if isinstance(node, ast.Call):
return self.visit_expr_call(node)
elif isinstance(node, ast.BinOp):
return self.visit_expr_binop(node)
elif isinstance(node, ast.Compare):
return self.visit_expr_compare(node)
elif isinstance(node, ast.Name):
return self.visit_expr_name(node)
elif isinstance(node, ast.Num):
return self.visit_expr_num(node)
elif isinstance(node, ast.Attribute):
return self.visit_expr_attribute(node)
elif isinstance(node, ast.Subscript):
return self.visit_expr_subscript(node)
else:
raise NotImplementedError
def visit_expr_call(self, node):
if isinstance(node.func, ast.Name):
callee = self.symdict[node.func.id]
else:
raise NotImplementedError
if callee == transel.bitslice:
if len(node.args) != 2 and len(node.args) != 3:
raise TypeError("bitslice() takes 2 or 3 arguments")
val = self.visit_expr(node.args[0])
low = eval_ast(node.args[1], self.symdict)
if len(node.args) == 3:
up = eval_ast(node.args[2], self.symdict)
else:
up = low + 1
return _Slice(val, low, up)
else:
raise NotImplementedError
def visit_expr_binop(self, node):
left = self.visit_expr(node.left)
right = self.visit_expr(node.right)
if isinstance(node.op, ast.Add):
return left + right
elif isinstance(node.op, ast.Sub):
return left - right
elif isinstance(node.op, ast.Mult):
return left * right
elif isinstance(node.op, ast.LShift):
return left << right
elif isinstance(node.op, ast.RShift):
return left >> right
elif isinstance(node.op, ast.BitOr):
return left | right
elif isinstance(node.op, ast.BitXor):
return left ^ right
elif isinstance(node.op, ast.BitAnd):
return left & right
else:
raise NotImplementedError
def visit_expr_compare(self, node):
test = self.visit_expr(node.left)
r = None
for op, rcomparator in zip(node.ops, node.comparators):
comparator = self.visit_expr(rcomparator)
if isinstance(op, ast.Eq):
comparison = test == comparator
elif isinstance(op, ast.NotEq):
comparison = test != comparator
elif isinstance(op, ast.Lt):
comparison = test < comparator
elif isinstance(op, ast.LtE):
comparison = test <= comparator
elif isinstance(op, ast.Gt):
comparison = test > comparator
elif isinstance(op, ast.GtE):
comparison = test >= comparator
else:
raise NotImplementedError
if r is None:
r = comparison
else:
r = r & comparison
test = comparator
return r
def visit_expr_name(self, node):
if node.id == "True":
return 1
if node.id == "False":
return 0
r = self.symdict[node.id]
if isinstance(r, ImplRegister):
r = r.storage
return r
def visit_expr_num(self, node):
return node.n
def visit_expr_attribute(self, node):
raise NotImplementedError
def visit_expr_subscript(self, node):
raise NotImplementedError

View file

@ -1,201 +0,0 @@
import ast
from itertools import zip_longest
from migen.fhdl.std import *
from migen.flow.actor import Source, Sink
from migen.flow.transactions import *
from migen.bus import wishbone
from migen.bus.transactions import *
from migen.pytholite.util import *
from migen.pytholite.expr import ExprCompiler
class _TokenPullExprCompiler(ExprCompiler):
def __init__(self, symdict, modelname, ep):
ExprCompiler.__init__(self, symdict)
self.modelname = modelname
self.ep = ep
def visit_expr_subscript(self, node):
# check that we are subscripting <modelname>.value
if not isinstance(node.value, ast.Attribute) \
or node.value.attr != "value" \
or not isinstance(node.value.value, ast.Name) \
or node.value.value.id != self.modelname:
raise NotImplementedError
if not isinstance(node.slice, ast.Index):
raise NotImplementedError
field = eval_ast(node.slice.value, self.symdict)
signal = getattr(self.ep.payload, field)
return signal
def _gen_df_io(compiler, modelname, to_model, from_model):
epname = eval_ast(to_model["endpoint"], compiler.symdict)
values = to_model["value"]
idle_wait = eval_ast(to_model["idle_wait"], compiler.symdict)
ep = getattr(compiler.ioo, epname)
if idle_wait:
state = [compiler.ioo.busy.eq(0)]
else:
state = []
if isinstance(values, ast.Name) and values.id == "None":
# token pull from sink
if not isinstance(ep, Sink):
raise TypeError("Attempted to pull from source")
ec = _TokenPullExprCompiler(compiler.symdict, modelname, ep)
for target_regs, expr in from_model:
cexpr = ec.visit_expr(expr)
state += [reg.load(cexpr) for reg in target_regs]
state += [
ep.ack.eq(1),
If(~ep.stb, id_next_state(state))
]
return [state], [state]
else:
# token push to source
if not isinstance(ep, Source):
raise TypeError("Attempted to push to sink")
if from_model:
raise TypeError("Attempted to read from pushed token")
if not isinstance(values, ast.Dict):
raise NotImplementedError
for akey, value in zip(values.keys, values.values):
key = eval_ast(akey, compiler.symdict)
signal = getattr(ep.payload, key)
state.append(signal.eq(compiler.ec.visit_expr(value)))
state += [
ep.stb.eq(1),
If(~ep.ack, id_next_state(state))
]
return [state], [state]
class _BusReadExprCompiler(ExprCompiler):
def __init__(self, symdict, modelname, data_signal):
ExprCompiler.__init__(self, symdict)
self.modelname = modelname
self.data_signal = data_signal
def visit_expr_attribute(self, node):
# recognize <modelname>.data as the bus read signal, raise exception otherwise
if not isinstance(node.value, ast.Name) \
or node.value.id != self.modelname \
or node.attr != "data":
raise NotImplementedError
return self.data_signal
def _gen_wishbone_io(compiler, modelname, model, to_model, from_model, bus):
state = [
bus.cyc.eq(1),
bus.stb.eq(1),
bus.adr.eq(compiler.ec.visit_expr(to_model["address"])),
]
if model == TWrite:
if from_model:
raise TypeError("Attempted to read from write transaction")
state += [
bus.we.eq(1),
bus.dat_w.eq(compiler.ec.visit_expr(to_model["data"]))
]
sel = to_model["sel"]
if isinstance(sel, ast.Name) and sel.id == "None":
nbytes = (flen(bus.dat_w) + 7)//8
state.append(bus.sel.eq(2**nbytes-1))
else:
state.append(bus.sel.eq(compiler.ec.visit_expr(sel)))
else:
ec = _BusReadExprCompiler(compiler.symdict, modelname, bus.dat_r)
for target_regs, expr in from_model:
cexpr = ec.visit_expr(expr)
state += [reg.load(cexpr) for reg in target_regs]
state.append(If(~bus.ack, id_next_state(state)))
return [state], [state]
def _gen_memory_io(compiler, modelname, model, to_model, from_model, port):
s1 = [port.adr.eq(compiler.ec.visit_expr(to_model["address"]))]
if model == TWrite:
if from_model:
raise TypeError("Attempted to read from write transaction")
s1.append(port.dat_w.eq(compiler.ec.visit_expr(to_model["data"])))
sel = to_model["sel"]
if isinstance(sel, ast.Name) and sel.id == "None":
nbytes = (flen(port.dat_w) + 7)//8
s1.append(port.we.eq(2**nbytes-1))
else:
s1.append(port.we.eq(compiler.ec.visit_expr(sel)))
return [s1], [s1]
else:
s2 = []
s1.append(id_next_state(s2))
ec = _BusReadExprCompiler(compiler.symdict, modelname, port.dat_r)
for target_regs, expr in from_model:
cexpr = ec.visit_expr(expr)
s2 += [reg.load(cexpr) for reg in target_regs]
return [s1, s2], [s2]
def _gen_bus_io(compiler, modelname, model, to_model, from_model):
busname = eval_ast(to_model["busname"], compiler.symdict)
if busname is None:
buses = compiler.ioo.get_buses()
if len(buses) != 1:
raise TypeError("Bus name not specified")
bus = list(buses.values())[0]
else:
bus = getattr(compiler.ioo, busname)
if isinstance(bus, wishbone.Interface):
return _gen_wishbone_io(compiler, modelname, model, to_model, from_model, bus)
elif isinstance(bus, Memory):
port = compiler.ioo.memory_ports[bus]
return _gen_memory_io(compiler, modelname, model, to_model, from_model, port)
else:
raise NotImplementedError("Unsupported bus")
def _decode_args(desc, args, args_kw):
d = {}
argnames = set()
for param, value in zip_longest(desc, args):
if param is None:
raise TypeError("Too many arguments")
if isinstance(param, tuple):
name, default = param
else:
name, default = param, None
# build the set of argument names at the same time
argnames.add(name)
if value is None:
if default is None:
raise TypeError("No default value for parameter " + name)
else:
d[name] = default
else:
d[name] = value
for akw in args_kw:
if akw.arg not in argnames:
raise TypeError("Parameter " + akw.arg + " does not exist")
d[akw.arg] = akw.value
return d
def gen_io(compiler, modelname, model, to_model, to_model_kw, from_model):
if model == Token:
desc = [
"endpoint",
("value", ast.Name("None", ast.Load(), lineno=0, col_offset=0)),
("idle_wait", ast.Name("False", ast.Load(), lineno=0, col_offset=0))
]
args = _decode_args(desc, to_model, to_model_kw)
return _gen_df_io(compiler, modelname, args, from_model)
elif model == TRead or model == TWrite:
desc = [
"address",
("data", ast.Num(0)),
("sel", ast.Name("None", ast.Load(), lineno=0, col_offset=0)),
("busname", ast.Name("None", ast.Load(), lineno=0, col_offset=0))
]
args = _decode_args(desc, to_model, to_model_kw)
return _gen_bus_io(compiler, modelname, model, args, from_model)
else:
raise NotImplementedError

View file

@ -1,41 +0,0 @@
from operator import itemgetter
from migen.fhdl.std import *
from migen.fhdl import visit as fhdl
class AbstractLoad:
def __init__(self, target, source):
self.target = target
self.source = source
def lower(self):
if not self.target.finalized:
raise FinalizeError
return self.target.sel.eq(self.target.source_encoding[id(self.source)])
class LowerAbstractLoad(fhdl.NodeTransformer):
def visit_unknown(self, node):
if isinstance(node, AbstractLoad):
return node.lower()
else:
return node
class ImplRegister(Module):
def __init__(self, name, bits_sign):
self.name = name
self.storage = Signal(bits_sign, name=self.name)
self.source_encoding = {}
self.id_to_source = {}
def load(self, source):
if id(source) not in self.source_encoding:
self.source_encoding[id(source)] = len(self.source_encoding) + 1
self.id_to_source[id(source)] = source
return AbstractLoad(self, source)
def do_finalize(self):
self.sel = Signal(max=len(self.source_encoding)+1, name="pl_regsel_"+self.name)
# do nothing when sel == 0
items = sorted(self.source_encoding.items(), key=itemgetter(1))
cases = dict((v, self.storage.eq(self.id_to_source[k])) for k, v in items)
self.sync += Case(self.sel, cases)

View file

@ -1,198 +0,0 @@
import operator
def bitslice(val, low, up=None):
if up is None:
up = low + 1
nbits = up - low
mask = (2**nbits - 1) << low
return (val & mask) >> low
class Register:
def __init__(self, bits_sign):
if isinstance(bits_sign, tuple):
self._nbits, self._signed = bits_sign
else:
self._nbits, self._signed = bits_sign, False
self._val = 0
def _set_store(self, val):
if self._signed:
sbw = 2**(self._nbits - 1)
self._val = val & (sbw - 1)
if val & sbw:
self._val -= sbw
else:
self._val = val & (2**self._nbits - 1)
store = property(None, _set_store)
def __nonzero__(self):
if self._val:
return 1
else:
return 0
def __len__(self):
return self._nbits
def __add__(self, other):
if isinstance(other, Register):
return self._val + other._val
else:
return self._val + other
def __radd__(self, other):
return other + self._val
def __sub__(self, other):
if isinstance(other, Register):
return self._val - other._val
else:
return self._val - other
def __rsub__(self, other):
return other - self._val
def __mul__(self, other):
if isinstance(other, Register):
return self._val * other._val
else:
return self._val * other
def __rmul__(self, other):
return other * self._val
def __div__(self, other):
if isinstance(other, Register):
return self._val / other._val
else:
return self._val / other
def __rdiv__(self, other):
return other / self._val
def __truediv__(self, other):
if isinstance(other, Register):
return operator.truediv(self._val, other._val)
else:
return operator.truediv(self._val, other)
def __rtruediv__(self, other):
return operator.truediv(other, self._val)
def __floordiv__(self, other):
if isinstance(other, Register):
return self._val // other._val
else:
return self._val // other
def __rfloordiv__(self, other):
return other // self._val
def __mod__(self, other):
if isinstance(other, Register):
return self._val % other._val
else:
return self._val % other
def __rmod__(self, other):
return other % self._val
def __pow__(self, other):
if isinstance(other, Register):
return self._val ** other._val
else:
return self._val ** other
def __rpow__(self, other):
return other ** self._val
def __lshift__(self, other):
if isinstance(other, Register):
return self._val << other._val
else:
return self._val << other
def __rlshift__(self, other):
return other << self._val
def __rshift__(self, other):
if isinstance(other, Register):
return self._val >> other._val
else:
return self._val >> other
def __rrshift__(self, other):
return other >> self._val
def __and__(self, other):
if isinstance(other, Register):
return self._val & other._val
else:
return self._val & other
def __rand__(self, other):
return other & self._val
def __or__(self, other):
if isinstance(other, Register):
return self._val | other._val
else:
return self._val | other
def __ror__(self, other):
return other | self._val
def __xor__(self, other):
if isinstance(other, Register):
return self._val ^ other._val
else:
return self._val ^ other
def __rxor__(self, other):
return other ^ self._val
def __neg__(self):
return -self._val
def __pos__(self):
return +self._val
def __abs__(self):
return abs(self._val)
def __invert__(self):
return ~self._val
def __int__(self):
return int(self._val)
def __float__(self):
return float(self._val)
def __oct__(self):
return oct(self._val)
def __hex__(self):
return hex(self._val)
def __index__(self):
return int(self._val)
def __lt__(self, other):
return self._val < other
def __le__(self, other):
return self._val <= other
def __eq__(self, other):
return self._val == other
def __ge__(self, other):
return self._val >= other
def __gt__(self, other):
return self._val > other
def __ne__(self, other):
return self._val != other
def __str__(self):
return str(self._val)
def __repr__(self):
return "Register(" + repr(self._val) + ")"
def _augm(self, other):
raise TypeError("Register objects do not support augmented assignment")
__iadd__ = __isub__ = __idiv__ = __imul__ = __ipow__ = __imod__ = _augm
__ior__ = __iand__ = __ixor__ = __irshift__ = __ilshift__ = _augm
def __setitem__(self, key, val):
raise TypeError("Register objects do not support item/slice assignment")

View file

@ -1,33 +0,0 @@
import ast
from migen.genlib.fsm import FSM, NextState
def id_next_state(l):
return NextState(id(l))
# entry state is first state returned
class StateAssembler:
def __init__(self):
self.states = []
self.exit_states = []
def assemble(self, n_states, n_exit_states):
self.states += n_states
for exit_state in self.exit_states:
exit_state.insert(0, id_next_state(n_states[0]))
self.exit_states = n_exit_states
def ret(self):
return self.states, self.exit_states
def implement_fsm(states):
fsm = FSM()
for state in states:
fsm.act(id(state), state)
return fsm
def eval_ast(expr, symdict):
if not isinstance(expr, ast.Expression):
expr = ast.Expression(expr)
code = compile(expr, "<ast>", "eval")
return eval(code, symdict)