Beispiel #1
0
def generate_vadp_fragment_for_path(dev,route_block_instances,conn_assign):
  def get_route_input(blk):
    name = blk.inputs.field_names()[0]
    return blk.inputs[name]

  def get_route_output(blk):
    name = blk.outputs.field_names()[0]
    return blk.outputs[name]

  vadp_config_stmts, path = use_route_blocks(dev, \
                                             route_block_instances, \
                                             conn_assign)
  for stmt in vadp_config_stmts:
    yield stmt

  for idx in range(0,len(path)-1):
    src_tuple = path[idx]
    dest_tuple = path[idx+1]
    assert(not devlib.Layout.is_pattern(src_tuple[1]))
    assert(not devlib.Layout.is_pattern(dest_tuple[1]))
    srcblk = dev.get_block(src_tuple[0])
    src = vadplib.PortVar(srcblk, \
                  devlib.Location(src_tuple[1]), \
                  srcblk.outputs[src_tuple[2]] \
                  if len(src_tuple) == 3 else \
                  get_route_output(srcblk)
    )
    destblk = dev.get_block(dest_tuple[0])
    dest = vadplib.PortVar(destblk, \
                  devlib.Location(dest_tuple[1]), \
                  destblk.inputs[dest_tuple[2]] \
                  if len(dest_tuple) == 3 else \
                  get_route_input(destblk)
    )
    yield vadplib.VADPConn(src,dest)
Beispiel #2
0
def use_route_blocks(dev,used_route_blocks,conn_assign):
  path = conn_assign.path
  vadpstmts = []
  if len(path) <= 2:
    return vadpstmts,list(path)

  new_path = list(path)
  for idx,(route_block,route_inst_pattern) in enumerate(path[1:-1]):
    blk = dev.get_block(route_block)
    assert(len(blk.modes) == 1)
    assert(len(blk.state) == 0)
    assert(len(blk.data) == 0)
    # get first compatible instance that has not been used yet
    try:
      inst = next(inst for inst in dev.layout.instances(route_block) \
                  if not devlib.Layout \
                  .intersection(inst,route_inst_pattern) is None and \
                  (route_block,inst) not in used_route_blocks )

      new_path[1+idx]= (route_block,inst)
      used_route_blocks.append((route_block,inst))
      target_port = vadplib.PortVar(blk,devlib.Location(inst))
      stmt = vadplib.VADPConfig(target_port,blk.modes)
      stmt.target.ident = devlib.Location(inst)
      vadpstmts.append(stmt)
    except StopIteration as e:
      raise Exception("no instances for route block <%s>" % route_block)

  return vadpstmts,new_path
Beispiel #3
0
def create_vadp_frag(hierarchy, input_var, parent_vadp, instance_map={}):
    def fresh_ident(block):
        if not block.name in instance_map:
            instance_map[block.name] = 0
        inst = instance_map[block.name]
        instance_map[block.name] += 1
        return inst

    if len(hierarchy) == 0:
        return []

    vadp = []
    n_children = len(hierarchy[1]) if len(hierarchy) > 1 else 0
    stems = []
    for frag in hierarchy[0]:
        inst = fresh_ident(frag['block'])
        targ = vadplib.PortVar(frag['block'], inst)
        vadp.append(vadplib.VADPConfig(targ, frag['modes']))
        inp_port = targ.make_port_var(list(frag['block'].inputs)[0])
        for port, expr in frag['exprs'].items():
            out_port_var = targ.make_port_var(frag['block'].outputs[port])
            vadp.append(vadplib.VADPSource(out_port_var, expr))

        # inject connection
        found_source = False
        for idx, stmt in enumerate(parent_vadp):
            if isinstance(stmt,vadplib.VADPSource)  \
               and stmt.dsexpr.op == oplib.OpType.VAR \
               and stmt.dsexpr.name == input_var:
                vadp.append(vadplib.VADPConn(stmt.target, inp_port))
                parent_vadp.pop(idx)
                found_source = True
                break
        if not found_source:
            vadp.append(vadplib.VADPSink(inp_port, genoplib.Var(input_var)))

    enclosing_vadp = list(vadp) + list(parent_vadp)
    if len(hierarchy) > 1:
        vadp += create_vadp_frag(hierarchy[1:], input_var, enclosing_vadp,
                                 instance_map)

    # at most one sink statement
    sources = list(
        filter(lambda vst: isinstance(vst, vadplib.VADPSource), vadp))
    other_stmts = list(
        filter(lambda vst: not isinstance(vst, vadplib.VADPSource), vadp))
    for st in vadp:
        if isinstance(st, vadplib.VADPConn):
            sources = list(filter(lambda src: st.source != src.target,
                                  sources))

    vadp = sources + other_stmts
    n_sinks = len(
        list(filter(lambda vst: isinstance(vst, vadplib.VADPSink), vadp)))
    assert (n_sinks <= 1)
    return vadp
Beispiel #4
0
def derive_tableau_from_port_rel(tableau, goal, rel, unif):
    new_tableau = tableau.copy()
    new_tableau.remove_goal(goal)

    out_port = PortVar(rel.block, rel.ident, rel.port)
    if isinstance(goal.variable, DSVar):
        assert (rel.block.outputs.has(rel.port.name))
        new_tableau.add_stmt(VADPSource(out_port, \
                                        genoplib.Var(goal.variable.var)))
    elif isinstance(goal.variable, PortVar):
        in_port = PortVar(goal.variable.block, \
                          goal.variable.ident, \
                          goal.variable.port)
        new_tableau.add_stmt(VADPConn(out_port, in_port))
    elif isinstance(goal.variable, LawVar):
        in_port = LawVar(goal.variable.law, \
                         goal.variable.ident, \
                         goal.variable.var)
        new_tableau.add_stmt(VADPConn(out_port, in_port))

    else:
        raise Exception("TODO: vadp should find/replace laws.")

    block_var = vadplib.PortVar(rel.block, rel.ident)
    vadp_cfg = VADPConfig(block_var, rel.modes)
    for stmt in tableau.vadp:
        if isinstance(stmt,VADPConfig) and \
           stmt.same_target(vadp_cfg):
            stmt.merge(vadp_cfg)
            vadp_cfg = stmt

    data_vars = []
    for vop, e in unif.assignments:
        if rel.block.data.has(vop.name):
            dat = rel.block.data[vop.name]
            data_vars += [vop.name] + dat.inputs
            if dat.type == blocklib.BlockDataType.EXPR:
                repl = {}
                for block_var, ds_var in map(lambda inp: unif.get_by_name(inp), \
                                             dat.inputs):
                    assert (ds_var.op == genoplib.OpType.VAR)
                    repl[ds_var.name] = block_var

                assert (set(e.vars()) == set(repl.keys()))
                expr = e.substitute(repl)
                vadp_cfg.bind(vop.name, expr)
            else:
                vadp_cfg.bind(vop.name, e)

    # translate assignments to goals
    for vop,e in filter(lambda asgn: not asgn[0].name in data_vars, \
                        unif.assignments):
        v = vop.name
        # binding input port assignment
        if rel.block.inputs.has(v):
            sig_type = rel.block.inputs[v].type
            new_tableau.add_goal(Goal(PortVar(rel.block, \
                                              rel.ident, \
                                              rel.block.inputs[v]), \
                                      sig_type,e))

        elif v in rel.cstrs and \
             rel.cstrs[v] == unifylib.UnifyConstraint.SAMEVAR:
            pass
        else:
            print(rel)
            print(rel.cstrs)
            print(rel.modes)
            raise Exception("unknown: %s=%s" % (v, e))

    new_tableau.add_stmt(vadp_cfg)

    # if we used a freshly generated block, make sure to replace it
    replenish_block = (rel.ident == max(map(lambda r: r.ident \
                                            if isinstance(r,PortRelation) \
                                            and r.same_block(rel) else 0, \
                                            tableau.relations)))

    # update existing relations in tableau to respect unification
    new_tableau.relations = []
    for curr_rel in tableau.relations:
        # find port relations using the same block
        if isinstance(curr_rel,PortRelation) and \
           curr_rel.same_block(rel)  \
           and curr_rel.ident == rel.ident:

            new_rel = curr_rel.copy()
            # do not add relation to new tableau
            if curr_rel.equals(rel):
                continue

            # could not concretize relation
            if not apply_vadp_config_to_relation(new_rel.block, \
                                                 vadp_cfg, \
                                                 unif, \
                                                 new_rel):
                continue

            new_tableau.add_relation(new_rel)

        else:
            new_tableau.add_relation(curr_rel.copy())

    # add fresh block of same type if necessary
    if replenish_block:
        for output in rel.block.outputs:
            for expr, modes in output.relation.get_by_property():
                new_rel = PortRelation(rel.block, rel.ident + 1, modes, output,
                                       expr)
                new_tableau.add_relation(new_rel)

    return new_tableau
Beispiel #5
0
def simplify_fuse_lut(dev,vadp,rule):
  target_stmt = None

  for stmt in vadp:
    print(">>>> %s" % stmt)

    if isinstance(stmt, tablib.VADPConfig) and \
       isinstance(stmt.target, tablib.LawVar) and \
       stmt.target.law == rule.law:
      target_stmt = stmt
      break

  print("FOUND: %s" % target_stmt)
  if target_stmt is None:
    return False,vadp

  new_vadp = []
  identifier = target_stmt.target.ident
  mode = target_stmt.mode
  lut = vadplib.PortVar(dev.get_block('lut'),identifier)
  lut_cfg = vadplib.VADPConfig(lut,"*")
  lut_cfg.bind('e', target_stmt.assigns['e'])
  new_vadp.append(lut_cfg)

  adc = vadplib.PortVar(dev.get_block('adc'),identifier)
  adc_mode = adc.block.modes[["m"] if mode[1] == "m" else ["h"]]
  adc_cfg = vadplib.VADPConfig(adc,adc_mode)
  new_vadp.append(adc_cfg)

  dac = vadplib.PortVar(dev.get_block('dac'),identifier)
  dac_mode = dac.block.modes[["dyn","m"] if mode[1] == "m" else ["dyn","h"]]
  dac_cfg = vadplib.VADPConfig(dac,dac_mode)
  new_vadp.append(dac_cfg)

  new_vadp.append(vadplib.VADPConn(adc.make_port_var('z'), \
                           lut.make_port_var('x')))

 
  new_vadp.append(vadplib.VADPConn(lut.make_port_var('z'), \
                           dac.make_port_var('x')))

  for stmt in vadp:
    if isinstance(stmt, tablib.VADPConn) and \
       isinstance(stmt.source, tablib.LawVar) and \
       rule.same_usage(stmt.source):
      new_vadp.append(vadplib.VADPConn(dac.make_port_var('z'), \
                               stmt.sink))
    elif isinstance(stmt, tablib.VADPConn) and \
       isinstance(stmt.sink, tablib.LawVar) and \
       rule.same_usage(stmt.sink):
      new_vadp.append(vadplib.VADPConn(stmt.source, \
                                       adc.make_port_var('x')))

    elif isinstance(stmt,tablib.VADPSource) and \
         isinstance(stmt.port, tablib.LawVar) and \
         rule.same_usage(stmt.port):
      new_vadp.append(vadplib.VAPSource(PortVar(dac,identifier,z), \
                                        stmt.source))
    else:
      print("unaffected: %s" % stmt)
      new_vadp.append(stmt)

    return True,new_vadp