def test():
    params = vast.Paramlist([])
    clk = vast.Ioport(vast.Input('CLK'))
    rst = vast.Ioport(vast.Input('RST'))
    width = vast.Width(vast.IntConst('7'), vast.IntConst('0'))
    led = vast.Ioport(vast.Output('led', width=width),
                      vast.Reg('led', width=width))
    ports = vast.Portlist((clk, rst, led))
    items = [
        vast.EmbeddedCode("""
// Embedded code
reg [31:0] count;
always @(posedge CLK) begin
  if(RST) begin
    count <= 0;
    led <= 0;
  end else begin
    if(count == 1024 - 1) begin
      count <= 0;
      led <= led + 1;
    end else begin
      count <= count + 1;
    end 
  end
end
""")
    ]
    ast = vast.ModuleDef("top", params, ports, items)

    codegen = ASTCodeGenerator()
    rslt = codegen.visit(ast)

    print(rslt)
    assert (expected == rslt)
Example #2
0
    def getFIFOInstOfNewTemplate(self, e_name: str, e_width: int, e_depth: int,
                                 pipeline_level: int):
        e_inst_list = self.e_name_to_ast_node[e_name]

        # use our FIFO template
        e_inst_list.module = 'fifo_almost_full'

        param_width = ast.ParamArg('DATA_WIDTH',
                                   ast.Rvalue(ast.IntConst(str(e_width))))
        param_depth = ast.ParamArg('DEPTH',
                                   ast.Rvalue(ast.IntConst(str(e_depth))))

        addr_bitwidth = int(math.log2(e_width) + 1)
        param_addr_width = ast.ParamArg(
            'ADDR_WIDTH', ast.Rvalue(ast.IntConst(str(addr_bitwidth))))

        # pipeline_level equals the required grace period
        param_grace_period = ast.ParamArg(
            'GRACE_PERIOD', ast.Rvalue(ast.IntConst(str(pipeline_level))))

        params = [
            param_width, param_depth, param_addr_width, param_grace_period
        ]
        e_inst_list.parameterlist = params

        for c in e_inst_list.instances:  # should only has 1 instance
            c.module = e_inst_list.module
            c.parameterlist = params

        return self.codegen.visit(e_inst_list)
 def add_decls(self, names, node_type, width=None):
     '''Adds new signal declarations'''
     if not issubclass(node_type, ast.Variable):
         print(
             'ERROR: invalid argument for node_type in VerilogMutator.add_decls()'
         )
     # preprocessing inputs if they don't match the expected type
     if isinstance(names, str):
         names = [names]
     if isinstance(width, int):
         if width == 1:
             width = None
         else:
             width = ast.Width(ast.IntConst(width - 1),
                               ast.IntConst(0))  # msb, lsb
     # collect all the declared signals
     new_decls = []
     for name in names:
         new_decls.append(node_type(name, width))
     # wrap them in a Decl node
     decl = ast.Decl(new_decls)
     # find index to insert at
     insert_index = 0
     for i in range(len(self.module.items)):
         if isinstance(self.module.items[i], ast.Decl):
             insert_index = i + 1
     # insert the new Decl node
     self.module.items = self.module.items[:insert_index] + (
         decl, ) + self.module.items[insert_index:]
Example #4
0
    def make_width(self, node):
        if node.raw_width is not None:
            msb = self.bind_visitor.visit(node.raw_width[0])
            lsb = self.bind_visitor.visit(node.raw_width[1])
            return vast.Width(msb, lsb)

        if node.width is not None:
            msb = vast.Minus(self.bind_visitor.visit(node.width),
                             vast.IntConst('1'))
            lsb = vast.IntConst('0')
            return vast.Width(msb, lsb)

        return None
Example #5
0
def test():
    params = vast.Paramlist(())
    clk = vast.Ioport(vast.Input('CLK'))
    rst = vast.Ioport(vast.Input('RST'))
    width = vast.Width(vast.IntConst('7'), vast.IntConst('0'))
    led = vast.Ioport(vast.Output('led', width=width))
    ports = vast.Portlist((clk, rst, led))
    items = (vast.Assign(vast.Identifier('led'), vast.IntConst('8')), )
    ast = vast.ModuleDef("top", params, ports, items)

    codegen = ASTCodeGenerator()
    rslt = codegen.visit(ast)

    print(rslt)
    assert (expected == rslt)
def print_item(c, defs, type_prefix):
    zero = vast.IntConst('0')
    if c.width.msb == zero and c.width.lsb == zero:
        defs.append((type_prefix, c.name))
    else:
        defs.append((type_prefix, '[%d:%d] %s' %
                     (int(c.width.msb.value), int(c.width.lsb.value), c.name)))
Example #7
0
def main():
    datawid = vast.Parameter('DATAWID', vast.Rvalue(vast.IntConst('32')))
    params = vast.Paramlist([datawid])
    clk = vast.Ioport(vast.Input('CLK'))
    rst = vast.Ioport(vast.Input('RST'))
    width = vast.Width(vast.IntConst('7'), vast.IntConst('0'))
    led = vast.Ioport(vast.Output('led', width=width))
    ports = vast.Portlist([clk, rst, led])

    width = vast.Width(
        vast.Minus(vast.Identifier('DATAWID'), vast.IntConst('1')),
        vast.IntConst('0'))
    count = vast.Reg('count', width=width)

    assign = vast.Assign(
        vast.Lvalue(vast.Identifier('led')),
        vast.Rvalue(
            vast.Partselect(
                vast.Identifier('count'),  # count
                vast.Minus(vast.Identifier('DATAWID'),
                           vast.IntConst('1')),  # [DATAWID-1:
                vast.Minus(vast.Identifier('DATAWID'),
                           vast.IntConst('8')))))  # :DATAWID-8]

    sens = vast.Sens(vast.Identifier('CLK'), type='posedge')
    senslist = vast.SensList([sens])

    assign_count_true = vast.NonblockingSubstitution(
        vast.Lvalue(vast.Identifier('count')), vast.Rvalue(vast.IntConst('0')))
    if0_true = vast.Block([assign_count_true])

    # count + 1
    count_plus_1 = vast.Plus(vast.Identifier('count'), vast.IntConst('1'))
    assign_count_false = vast.NonblockingSubstitution(
        vast.Lvalue(vast.Identifier('count')), vast.Rvalue(count_plus_1))
    if0_false = vast.Block([assign_count_false])

    if0 = vast.IfStatement(vast.Identifier('RST'), if0_true, if0_false)
    statement = vast.Block([if0])

    always = vast.Always(senslist, statement)

    items = []
    items.append(count)
    items.append(assign)
    items.append(always)

    ast = vast.ModuleDef("top", params, ports, items)

    codegen = ASTCodeGenerator()
    rslt = codegen.visit(ast)
    print(rslt)
Example #8
0
def lower_next(done_stage: vast.IntConst, ns: NextState):
    """
        done_stage is the index of the final stage which just
        holds the all the values in the register.
    """
    # The computation is finished; transition to the done stage.
    if isinstance(ns, Done):
        return vast.Rvalue(done_stage)
    elif isinstance(ns, DirectNext):
        return vast.Rvalue(vast.IntConst(ns.state))
    elif isinstance(ns, CondNext):
        return vast.Cond(
            vast.Rvalue(vast.Identifier(ns.cond.name)),
            vast.IntConst(ns.on_true),
            vast.IntConst(ns.on_false),
        )
    else:
        raise ValueError("Malformed AST, expected next: %s" % ns.pretty())
Example #9
0
def _convert_hls_fifo_to_relay_station(node, e: Edge) -> None:
    node.module = 'relay_station'  # pipeline the FIFO

    width = ast.ParamArg('DATA_WIDTH', ast.Rvalue(ast.IntConst(str(e.width))))
    depth = ast.ParamArg(
        'DEPTH',
        ast.Rvalue(ast.IntConst(str(e.depth + e.added_depth_for_rebalance))))
    addr_width = ast.ParamArg('ADDR_WIDTH',
                              ast.Rvalue(ast.IntConst(str(e.addr_width))))
    level = ast.ParamArg('LEVEL',
                         ast.Rvalue(ast.IntConst(str(e.pipeline_level))))

    params = [width, depth, addr_width, level]
    node.parameterlist = params

    for c in node.instances:
        c.module = 'relay_station'
        c.parameterlist = params
Example #10
0
    def make_dims(self, node):
        if node.raw_dims is not None:
            lengths = []
            for raw_dim in node.raw_dims:
                l = self.bind_visitor.visit(raw_dim[0])
                r = self.bind_visitor.visit(raw_dim[1])
                lengths.append(vast.Length(l, r))
            return vast.Dimensions(lengths)

        if node.dims is not None:
            lengths = []
            for dim in node.dims:
                l = vast.IntConst('0')
                r = vast.Minus(self.bind_visitor.visit(dim),
                               vast.IntConst('1'))
                lengths.append(vast.Length(l, r))
            return vast.Dimensions(lengths)

        return None
Example #11
0
def _convert_hls_fifo_to_autobridge_fifo_template(node, e: Edge) -> None:
    # TODO: remove the extra grace period from the FIFO template

    node.module = 'fifo_almost_full'  # pipeline the FIFO

    width = ast.ParamArg('DATA_WIDTH', ast.Rvalue(ast.IntConst(str(e.width))))
    depth = ast.ParamArg(
        'DEPTH',
        ast.Rvalue(ast.IntConst(str(e.depth + e.added_depth_for_rebalance))))
    addr_width = ast.ParamArg('ADDR_WIDTH',
                              ast.Rvalue(ast.IntConst(str(e.addr_width))))
    grace_period = ast.ParamArg('GRACE_PERIOD',
                                ast.Rvalue(ast.IntConst(str("0"))))

    params = [width, depth, addr_width, grace_period]
    node.parameterlist = params

    for c in node.instances:
        c.module = 'fifo_almost_full'
        c.parameterlist = params
Example #12
0
def lower_expr(expr: SynthExpr):
    if isinstance(expr, RegRef):
        return vast.Identifier(expr.name)
    elif isinstance(expr, Num):
        return vast.IntConst(expr.val)
    elif isinstance(expr, Binop):
        return BINOP_MAP[expr.op](
            lower_expr(expr.left),
            lower_expr(expr.right),
        )
    else:
        raise ValueError("Malformed AST, expected expr: %s" % expr.pretty())
Example #13
0
def addRelayStation(formator, node, edges_dict):
    # only considers fifo/rs instances
    if (not formator.isFIFOInstanceList(node)):
        return

    edge_name = formator.getFIFONameFromInstanceList(node)
    e = edges_dict[edge_name]

    if (e.mark):
        node.module = 'relay_station'

        width = ast.ParamArg('DATA_WIDTH',
                             ast.Rvalue(ast.IntConst(str(e.width))))
        depth = ast.ParamArg('DEPTH', ast.Rvalue(ast.IntConst(str(e.depth))))
        addr_width = ast.ParamArg('ADDR_WIDTH',
                                  ast.Rvalue(ast.IntConst(str(e.addr_width))))
        level = ast.ParamArg('LEVEL', ast.Rvalue(ast.IntConst(str(e.latency))))
        params = [width, depth, addr_width, level]

        node.parameterlist = params

        for c in node.instances:
            c.module = 'relay_station'
            c.parameterlist = params

        # print(f'[codegen] update rs to {edge_name} -> {node.module}')

    # replace the ad-hoc fifos by hls
    # add the depth used for balancing reconvergent paths
    else:
        node.module = 'fifo'
        new_depth = int(e.depth + e.additional_depth)
        new_addr_width = int(math.log2(new_depth) + 1)

        width = ast.ParamArg('DATA_WIDTH',
                             ast.Rvalue(ast.IntConst(str(e.width))))
        depth = ast.ParamArg('DEPTH', ast.Rvalue(ast.IntConst(str(new_depth))))
        addr_width = ast.ParamArg(
            'ADDR_WIDTH', ast.Rvalue(ast.IntConst(str(new_addr_width))))
        params = [width, depth, addr_width]

        node.parameterlist = params

        for c in node.instances:
            c.module = 'fifo'
            c.parameterlist = params
Example #14
0
    def __init__(self, orcl_cir, obf_cir, enable_async, key_constraints):
        self.dip_gen = None
        self.dis_gen = None
        self.dip_chk = None
        self.uc = None
        self.ce = None
        self.umc = None
        self.state_size_msb = 0
        self.main = None
        self.enable_async = enable_async
        self.key_constraints = key_constraints
        self.orcl_cir = orcl_cir

        # create common components module
        if obf_cir:
            self.key_size_msb = obf_cir.n_keys - 1
        self.input_size_msb = orcl_cir.n_inputs - 2
        self.output_size_msb = orcl_cir.n_outputs - 1
        self.key_width = vast.Width(vast.IntConst(self.key_size_msb),
                                    vast.IntConst('0'))
        self.inp_width = vast.Width(vast.IntConst(str(self.input_size_msb)),
                                    vast.IntConst('0'))
        self.out_width = vast.Width(vast.IntConst(str(self.output_size_msb)),
                                    vast.IntConst('0'))

        # create instances for org0 and obf1 and obf2
        ports = create_ports('iv', 'ov0', orcl_cir)
        inst = vast.Instance(orcl_cir.name, "org0", ports, "")
        self.org0 = vast.InstanceList(orcl_cir.name, "", [inst])

        ports = create_ports('iv', 'ov1', orcl_cir)
        key_ports = [vast.PortArg("", vast.Identifier('k1'))]
        inst = vast.Instance(orcl_cir.name + '_obf', "obf1", ports + key_ports,
                             "")
        self.obf1 = vast.InstanceList(orcl_cir.name + '_obf', "", [inst])

        ports = create_ports('iv', 'ov2', orcl_cir)
        key_ports = [vast.PortArg("", vast.Identifier('k2'))]
        inst = vast.Instance(orcl_cir.name + '_obf', "obf2", ports + key_ports,
                             "")
        self.obf2 = vast.InstanceList(orcl_cir.name + '_obf', "", [inst])
Example #15
0
    def expose_internal_scheduling_signals(self,
                                           num_rules_per_module=None,
                                           scheduling_order=None,
                                           add_force_fire=False):
        # if schedule isn't provided, assume rules first then modules
        if scheduling_order is None:
            scheduling_order = [
                'RL_' + x for x in self.get_rules_in_scheduling_order()
            ] + ['MODULE_' + x for x, y in self.get_submodules()]
        instance_to_module = {x: y for x, y in self.get_submodules()}
        can_fires = []
        will_fires = []
        # compute total number of bits
        total_num_bits = 0
        for name in scheduling_order:
            if name.startswith('RL_'):
                total_num_bits += 1
            elif name.startswith('MODULE_'):
                instance_name = name[len('MODULE_'):]
                module_name = instance_to_module[instance_name]
                if num_rules_per_module is None:
                    continue
                if module_name not in num_rules_per_module:
                    continue
                num_submodule_rules = num_rules_per_module[module_name]
                if num_submodule_rules == 0:
                    continue
                total_num_bits += num_submodule_rules
        # now add the signals
        curr_bit_index = 0
        for name in scheduling_order:
            if name.startswith('RL_'):
                self.add_decls('BLOCK_FIRE_' + name, ast.Wire)
                if add_force_fire:
                    self.add_decls('FORCE_FIRE_' + name, ast.Wire)
                # definition of BLOCK_FIRE and FORCE_FILE
                assign = self.get_assign('WILL_FIRE_' + name)
                if add_force_fire:
                    new_rhs = ast.Or(
                        ast.Identifier('FORCE_FIRE_' + name),
                        ast.And(ast.Unot(ast.Identifier('BLOCK_FIRE_' + name)),
                                assign.right.var))
                else:
                    new_rhs = ast.And(
                        ast.Unot(ast.Identifier('BLOCK_FIRE_' + name)),
                        assign.right.var)
                assign.right.var = new_rhs
                # definition of BLOCK_FIRE_* and FORCE_FIRE_* signals from top-level BLOCK_FIRE and FORCE_FIRE
                if total_num_bits == 1:
                    self.add_assign('BLOCK_FIRE_' + name,
                                    ast.Identifier('BLOCK_FIRE'))
                    if add_force_fire:
                        self.add_assign('FORCE_FIRE_' + name,
                                        ast.Identifier('FORCE_FIRE'))
                else:
                    self.add_assign(
                        'BLOCK_FIRE_' + name,
                        ast.Partselect(ast.Identifier('BLOCK_FIRE'),
                                       ast.IntConst(curr_bit_index),
                                       ast.IntConst(curr_bit_index)))
                    if add_force_fire:
                        self.add_assign(
                            'FORCE_FIRE_' + name,
                            ast.Partselect(ast.Identifier('FORCE_FIRE'),
                                           ast.IntConst(curr_bit_index),
                                           ast.IntConst(curr_bit_index)))
                curr_bit_index += 1
                can_fires.append(ast.Identifier('CAN_FIRE_' + name))
                will_fires.append(ast.Identifier('WILL_FIRE_' + name))
            elif name.startswith('MODULE_'):
                instance_name = name[len('MODULE_'):]
                module_name = instance_to_module[instance_name]
                if num_rules_per_module is None:
                    continue
                if module_name not in num_rules_per_module:
                    continue
                num_submodule_rules = num_rules_per_module[module_name]
                if num_submodule_rules == 0:
                    continue
                instance = self.get_instance(instance_name)
                for signal_type in [
                        'CAN_FIRE', 'WILL_FIRE', 'BLOCK_FIRE', 'FORCE_FIRE'
                ]:
                    if signal_type == 'FORCE_FIRE' and not add_force_fire:
                        continue
                    # declarations of all FIRE signals for the submodule
                    self.add_decls(signal_type + '_' + name,
                                   ast.Wire,
                                   width=num_submodule_rules)
                    # connection of all FIRE signals to the submodule
                    # this assumes the submodule has ports named CAN_FIRE, WILL_FIRE, BLOCK_FIRE, and if add_force_fire is true, FORCE_FIRE
                    instance.portlist += (ast.PortArg(
                        signal_type,
                        ast.Identifier(signal_type + '_' + name)), )
                # assignments of BLOCK_FIRE_* and FORCE_FIRE_* signals from top-level BLOCK_FIRE and FORCE_FIRE
                lsb = curr_bit_index
                msb = curr_bit_index + num_submodule_rules - 1
                curr_bit_index += num_submodule_rules
                if total_num_bits == 1:
                    self.add_assign('BLOCK_FIRE_' + name,
                                    ast.Identifier('BLOCK_FIRE'))
                    if add_force_fire:
                        self.add_assign('FORCE_FIRE_' + name,
                                        ast.Identifier('FORCE_FIRE'))
                else:
                    self.add_assign(
                        'BLOCK_FIRE_' + name,
                        ast.Partselect(ast.Identifier('BLOCK_FIRE'),
                                       ast.IntConst(msb), ast.IntConst(lsb)))
                    if add_force_fire:
                        self.add_assign(
                            'FORCE_FIRE_' + name,
                            ast.Partselect(ast.Identifier('FORCE_FIRE'),
                                           ast.IntConst(msb),
                                           ast.IntConst(lsb)))
                can_fires.append(ast.Identifier('CAN_FIRE_' + name))
                will_fires.append(ast.Identifier('WILL_FIRE_' + name))
            elif name.startswith('METH_'):
                raise ValueError(
                    '"METH_" scheduling signals are not supported yet')
            else:
                raise ValueError('unexpected entry "%s" in scheduling_order' %
                                 name)

        if total_num_bits != 0:
            # new ports
            self.add_ports(['CAN_FIRE', 'WILL_FIRE', 'BLOCK_FIRE'])
            if add_force_fire:
                self.add_ports(['FORCE_FIRE'])
            self.add_decls('CAN_FIRE', ast.Output, width=total_num_bits)
            self.add_decls('WILL_FIRE', ast.Output, width=total_num_bits)
            self.add_decls('BLOCK_FIRE', ast.Input, width=total_num_bits)
            if add_force_fire:
                self.add_decls('FORCE_FIRE', ast.Input, width=total_num_bits)
            self.add_decls('CAN_FIRE', ast.Wire, width=total_num_bits)
            self.add_decls('WILL_FIRE', ast.Wire, width=total_num_bits)
            # connect CAN_FIRE and WILL_FIRE
            can_fires.reverse()
            will_fires.reverse()
            self.add_assign('CAN_FIRE', ast.Concat(can_fires))
            self.add_assign('WILL_FIRE', ast.Concat(will_fires))

        return total_num_bits
Example #16
0
def lower_fsm(fsm: FSM):
    assert fsm.start_state == 0, "Starting state is not 0"
    zero = vast.IntConst(0)
    all_registers = [
        Register("a", 8),
        Register("b", 8),
        Register("tmp", 8),
        Register("_cond", 1),
    ]
    register_defs = [
        vast.Reg(
            reg.name,
            vast.Width(vast.IntConst(reg.width -
                                     1), zero) if reg.width - 1 != 0 else None)
        for reg in all_registers
    ]

    ports = vast.Portlist([
        vast.Ioport(vast.Input('clk')),
        # XXX(rachit): AST can't represent `output reg done`
        # so assign to a local register and use a wire.
        vast.Ioport(vast.Output('done')),
    ])
    done_state = max(fsm.actions.keys()) + 1
    done_reg = vast.Reg('done_out')
    hook_up_done = vast.Assign(
        vast.Lvalue(vast.Identifier('done')),
        vast.Rvalue(vast.Identifier('done_out')),
    )

    # Register to store the FSM state.
    fsm_reg_size = int(math.ceil(math.log2(done_state))) + 1
    fsm_reg = vast.Reg(name="fsm_reg",
                       width=vast.Width(vast.IntConst(fsm_reg_size - 1), zero))

    # Define all the registers.
    reg_decl = register_defs + [fsm_reg]

    # Define the initial process
    inits = vast.Initial(
        vast.Block([
            vast.BlockingSubstitution(
                vast.Lvalue(vast.Identifier(reg.name)),
                vast.Rvalue(vast.IntConst(0)),
            ) for reg in reg_decl
        ]))

    # Default case, assigns to the done register.
    done = vast.IntConst(done_state)
    default_case = vast.Case(cond=None,
                             statement=vast.Block([
                                 vast.NonblockingSubstitution(
                                     vast.Lvalue(vast.Identifier(reg.name)),
                                     vast.Rvalue(vast.Identifier(reg.name)),
                                 ) for reg in reg_decl
                             ] + [
                                 vast.NonblockingSubstitution(
                                     vast.Lvalue(vast.Identifier('done_out')),
                                     vast.Rvalue(vast.IntConst(1)))
                             ]))

    # Generate Case conditions for each transition.
    cases = [
        vast.Case([vast.IntConst(cond_val)],
                  lower_action(fsm_reg, done, action))
        for (cond_val, action) in fsm.actions.items()
    ]
    case_statement = vast.CaseStatement(comp=vast.Identifier(fsm_reg.name),
                                        caselist=cases + [default_case])
    always_ff = vast.Always(
        vast.SensList([vast.Sens(vast.Identifier('clk'), 'posedge')]),
        vast.Block([case_statement]))

    return vast.ModuleDef(name="main",
                          paramlist=vast.Paramlist([]),
                          portlist=ports,
                          items=reg_decl +
                          [done_reg, hook_up_done, inits, always_ff])
Example #17
0
    def visit_Int(self, node):
        value_list = []
        value = node.value

        if isinstance(node.value, str) and node.value.find('-') >= 0:
            pos = node.value.find('-') + 1
            value = node.value[pos:]
            value_list.append('-')

        if isinstance(node.value, int) and node.value < 0:
            value = abs(node.value)
            value_list.append('-')

        if node.width:
            value_list.append(str(node.width))

        if node.base is None:
            if node.signed:
                value_list.append("'sd")
            elif node.width:
                value_list.append("'d")
            if isinstance(value, str):
                value_list.append(value)
            else:
                value_list.append(str(value))
        elif node.base == 2:
            if node.signed:
                value_list.append("'sb")
            else:
                value_list.append("'b")
            if isinstance(value, str):
                value_list.append(value)
            else:
                value_list.append(bin(value).replace('0b', ''))
        elif node.base == 8:
            if node.signed:
                value_list.append("'so")
            else:
                value_list.append("'o")
            if isinstance(value, str):
                value_list.append(value)
            else:
                value_list.append(oct(value).replace('0o', ''))
        elif node.base == 10:
            if node.signed:
                value_list.append("'sd")
            else:
                value_list.append("'d")
            if isinstance(value, str):
                value_list.append(value)
            else:
                value_list.append(str(value))
        elif node.base == 16:
            if node.signed:
                value_list.append("'sh")
            else:
                value_list.append("'h")
            if isinstance(value, str):
                value_list.append(value)
            else:
                value_list.append(hex(value).replace('0x', ''))
        else:
            raise ValueError("Int.base must be 2, 8, 10, or 16")

        return vast.IntConst(''.join(value_list))
Example #18
0
 def make_length(self, node):
     msb = vast.IntConst('0')
     lsb = vast.Minus(self.bind_visitor.visit(node), vast.IntConst('1'))
     return vast.Length(msb, lsb)
Example #19
0
 def visit_int(self, node):
     return vast.IntConst(str(node))
Example #20
0
 def visit_bool(self, node):
     if node: return vast.IntConst('1')
     return vast.IntConst('0')
def createFaultyOutputFile(preparedModules, faultModuleFile):
    # This file creates the faulty output file
    # If this code is used as reference for pyverilog, be very cautious about
    # the exact use of it and a good debugger is very useful
    # Todo I still have struggle with the fault module injection, so if vectors
    # appear or similar things it could become diffcult -> it fails
    print("Start creating faulty verilog file!")

    # Contains all the verilog components of this module
    portMembers = []
    itemMembersPortInput = []
    itemMembersPortInputVector = []
    itemMembersPortOutput = []
    itemMembersPortOutputVector = []
    itemMembersWire = []
    itemMembersWireVector = []
    itemMembersFaultModule = []
    itemMembersGate = []
    itemMembers = []
    emptyList = []

    # The following code create transforms all the modifies parts into
    # pyverilog understandable code
    for element in range(0, preparedModules.getModuleListLength()):

        if 'topmodule' in preparedModules.moduleList[element].type[1]:
            if verbose:
                print("Found Topmodule!")
            outputName = preparedModules.moduleList[element].type[0]

            # Handling the Ports
            for port in range(0, preparedModules.moduleList[element].ports.__len__()):
                if "Input" in preparedModules.moduleList[element].ports[port][0]:
                    # print("Input")
                    if 'singular' in preparedModules.moduleList[element].ports[port][3]:
                        itemMembersPortInput.append(vast.Input(name=preparedModules.moduleList[element].ports[port][2], width=None, signed=False))
                        portMembers.append(vast.Port(name=preparedModules.moduleList[element].ports[port][2], type=None, width=None))
                    elif 'vector' in preparedModules.moduleList[element].ports[port][3]:
                        # For initialization
                        prepVector = getPreparedVector(preparedModules.moduleList[element].ports[port][2])
                        width = vast.Width(msb=vast.IntConst(prepVector[1]), lsb=vast.IntConst(prepVector[2]))
                        itemMembersPortInputVector.append(vast.Decl([vast.Input(name=prepVector[0], width=width)]))
                        # For port definition
                        portMembers.append(vast.Port(name=prepVector[0], type=None, width=None))
                    else:
                        print("createFaultyOutputFile - topmodule - ports: Unknown port type found!")

                elif "Output" in preparedModules.moduleList[element].ports[port][0]:
                    # print("Output")
                    if 'singular' in preparedModules.moduleList[element].ports[port][3]:
                        portMembers.append(vast.Port(name=preparedModules.moduleList[element].ports[port][2], type=None, width=None))
                        itemMembersPortOutput.append(vast.Output(name=preparedModules.moduleList[element].ports[port][2], width=None, signed=False))

                    elif 'vector' in preparedModules.moduleList[element].ports[port][3]:
                        # For initialization
                        prepVector = getPreparedVector(preparedModules.moduleList[element].ports[port][2])
                        width = vast.Width(msb=vast.IntConst(prepVector[1]), lsb=vast.IntConst(prepVector[2]))
                        itemMembersPortOutputVector.append(vast.Decl([vast.Output(name=prepVector[0], width=width)]))
                        # For port definition
                        portMembers.append(vast.Port(name=prepVector[0], type=None, width=None))

                    else:
                        print("createFaultyOutputFile - topmodule - ports: Unknown port type found!")
                else:
                    print("createFaultyOutputFile - topmodule - ports: Unknown port found!")
                    sys.exit(8)

            # Handling the wires
            for wire in range(0, preparedModules.moduleList[element].wires.__len__()):
                if 'singular' in preparedModules.moduleList[element].wires[wire][1]:
                    wire = vast.Wire(name=preparedModules.moduleList[element].wires[wire][0])
                    itemMembersWire.append(wire)

                # TODO this is kind of dangerous, because it seems that there is pointer, wirearray, wire and the use is always similar
                elif 'vector' in preparedModules.moduleList[element].wires[wire][1]:
                    prepVector = getPreparedVector(preparedModules.moduleList[element].wires[wire][0])
                    # length = vast.Length(msb=vast.IntConst(prepVector[1]), lsb=vast.IntConst(prepVector[2]))
                    # wireArray = vast.WireArray(name=prepVector[0], length=length, width=None)  # WireArray can also consume width but this seems distinct from the IO ports not to be used for the vector width
                    width = vast.Width(msb=vast.IntConst(prepVector[1]), lsb=vast.IntConst(prepVector[2]))
                    wire = vast.Wire(name=prepVector[0], width=width)
                    itemMembersWireVector.append(vast.Decl(list=[wire]))
                else:
                    print("createFaultyOutputFile - topmodule - wires: Unknown wire found!")
                    sys.exit(8)


        # Relevant for the Gates
        elif 'gate' in preparedModules.moduleList[element].type[1]:
            moduleName = preparedModules.moduleList[element].name
            moduleType = preparedModules.moduleList[element].type[0]
            modulePortList = []

            # Port Handling
            for port in range(0, preparedModules.moduleList[element].ports.__len__()):
                if 'singular' in preparedModules.moduleList[element].ports[port][3]:
                    argName = vast.Identifier(name=preparedModules.moduleList[element].ports[port][2])
                    portArg = vast.PortArg(argname=argName, portname=preparedModules.moduleList[element].ports[port][1])
                    modulePortList.append(portArg)
                elif 'pointer' in preparedModules.moduleList[element].ports[port][3]:
                    prepPointer = getPreparedPointer(preparedModules.moduleList[element].ports[port][2])
                    argName = vast.Pointer(var=vast.Identifier(prepPointer[0]), ptr=vast.IntConst(prepPointer[1]))
                    portArg = vast.PortArg(argname=argName, portname=preparedModules.moduleList[element].ports[port][1])
                    modulePortList.append(portArg)
                else:
                    print("createFaultyOutputFile - gates - ports: Unknown port type found!")
                    sys.exit(9)

            # Instance Handling
            moduleInstance = vast.Instance(module=moduleType, name=moduleName, portlist=modulePortList,
                                           parameterlist=emptyList, array=None)

            moduleInstanceList = vast.InstanceList(module=moduleType, instances=[moduleInstance],
                                                   parameterlist=emptyList)

            itemMembersGate.append(moduleInstanceList)

        else:
            print("createFaultyOutputFile: Error unknown module-type appeared")
            sys.exit(7)

    # Adding the fault modules
    # Getting the name from the faultModule File, which is an argument of this script
    print(
        "Attention, only the name of the faultModule-file is used, anything else is hardcoded in the script (amount of IOs and so on)")
    print(
        "We expect, that you use Questa/Modelsim for simulation, so it makes no difference, if the fault module is a Verilog or Systemverilog file")

    print(
        "The inputs of the topmodule won't be connected to fault modules, the necessity of the function needs to be evaluated")

    faultModuleName = (((faultModuleFile.split('/'))[-1]).split('.'))[0]
    print('Faultmodule name: %s' % faultModuleName)

    global MAKE_PORTS_FAULTY
    if MAKE_PORTS_FAULTY:
        print("The function to involve the ports of the top module has to be evaluated and if necessary implemented!")

    # Implementing Fault Modules - this is hardcoded, must be modified if a different kind of fault modules is used
    # TODO a code block which handles the inport outport so that there is a clean cut between the ports and the wires

    # Additional values for the module parameters
    moduleID = ("MODULEID", "")
    faultParametersByScript = False
    prob_c2f = ("PROB_C2F", "32'd42949672")
    prob_f2c = ("PROB_F2C", "32'd3865470565")
    seed = ("SEED", "32'd1234")
    random.seed(a=None, version=2)
    randomSeed = True

    for i in range(0, preparedModules.moduleList[0].wires.__len__()):


        # Wire Preperation
        if 'singular' in preparedModules.moduleList[0].wires[i][1]:


            wireName = preparedModules.moduleList[0].wires[i][0]
            if "_a" == wireName[(len(wireName) - 2):]:
                faultPortList = []
                # Module
                wirePair = (
                    preparedModules.moduleList[0].wires[i][0],
                    preparedModules.moduleList[0].wires[i + 1][0])
                moduleName = wirePair[0][:(len(wirePair[0]) - 2)] + '_faulty'
                # Clock
                argName = vast.Identifier(name='faultClock')
                portArg = vast.PortArg(argname=argName, portname='CLK')
                faultPortList.append(portArg)
                # Inport
                argName = vast.Identifier(name=wirePair[0])
                portArg = vast.PortArg(argname=argName, portname='in')
                faultPortList.append(portArg)
                # Outport
                argName = vast.Identifier(name=wirePair[1])
                portArg = vast.PortArg(argname=argName, portname='out')
                faultPortList.append(portArg)

                # Parameter Handling - If we want to add certain parameters to the file, these lines need to be modified
                parameterList = []
                moduleID = (moduleID[0], wirePair[0][:(len(wirePair[0]) - 2)])
                parameterList.append(vast.ParamArg(argname=vast.StringConst(moduleID[1]), paramname=moduleID[0]))

                # Condition query if the testbench shall set the parameters (so no global defines are used
                if faultParametersByScript:
                    parameterList.append(vast.ParamArg(argname=vast.IntConst(prob_c2f[1]), paramname=prob_c2f[0]))
                    parameterList.append(vast.ParamArg(argname=vast.IntConst(prob_f2c[1]), paramname=prob_f2c[0]))

                # Randomizing seed
                if randomSeed:
                    seed = ("SEED", "32'd" + str(random.randint(a=1, b=10000)))
                parameterList.append(vast.ParamArg(argname=vast.IntConst(seed[1]), paramname=seed[0]))

                # Instance Handling
                moduleInstance = vast.Instance(module=faultModuleName, name=moduleName, portlist=faultPortList,
                                               parameterlist=emptyList, array=None)

                moduleInstanceList = vast.InstanceList(module=faultModuleName, instances=[moduleInstance],
                                                       parameterlist=parameterList)

                itemMembersFaultModule.append(moduleInstanceList)  # FaultModule initialization


        elif 'vector' in preparedModules.moduleList[0].wires[i][1]:
            # Preparing the vector
            prepVector = getPreparedVector(preparedModules.moduleList[0].wires[i][0])
            wireName_a =  prepVector[0]
            vectorMSB = prepVector[1]
            vectorLSB = prepVector[2]
            # print(preparedModules.moduleList[0].wires[i][0])

            if "_a" == wireName_a[(len(wireName_a) - 2):]:
                # Must be after if else it would possible take a wrong wire
                wireName_b = getPreparedVector(preparedModules.moduleList[0].wires[i + 1][0])[0]

                for j in range(int(vectorLSB), int(vectorMSB) + 1):         # +1 that the last bit is also included

                    faultPortList = []
                    # Module
                    wirePair = (wireName_a , wireName_b)
                    moduleName = wirePair[0][:(len(wireName_a[0]) - 2)] + str(j) + 'b_faulty'
                    # Clock
                    argName = vast.Identifier(name='faultClock')
                    portArg = vast.PortArg(argname=argName, portname='CLK')
                    faultPortList.append(portArg)
                    # Inport
                    argName = vast.Pointer(var=vast.Identifier(wireName_a), ptr=vast.IntConst(j))
                    portArg = vast.PortArg(argname=argName, portname='in')
                    faultPortList.append(portArg)
                    # Outport
                    argName = vast.Pointer(var=vast.Identifier(wireName_b), ptr=vast.IntConst(j))
                    portArg = vast.PortArg(argname=argName, portname='out')
                    faultPortList.append(portArg)

                    # Parameter Handling - If we want to add certain parameters to the file, these lines need to be modified
                    parameterList = []
                    moduleID =  (moduleID[0], wirePair[0][:(len(wirePair[0]) - 2)] + '_' + str(j))
                    parameterList.append(vast.ParamArg(argname=vast.StringConst(moduleID[1]), paramname=moduleID[0]))

                    # Condition query if the testbench shall set the parameters (so no global defines are used)
                    if faultParametersByScript:
                        parameterList.append(vast.ParamArg(argname=vast.IntConst(prob_c2f[1]), paramname=prob_c2f[0]))
                        parameterList.append(vast.ParamArg(argname=vast.IntConst(prob_f2c[1]), paramname=prob_f2c[0]))

                    # Randomizing seed
                    if randomSeed:
                        seed = ("SEED", "32'd" + str(random.randint(a=1, b=10000)))

                    parameterList.append(vast.ParamArg(argname=vast.IntConst(seed[1]), paramname=seed[0]))

                    # Instance Handling
                    moduleInstance = vast.Instance(module=faultModuleName, name=moduleName, portlist=faultPortList,
                                                   parameterlist=emptyList, array=None)

                    moduleInstanceList = vast.InstanceList(module=faultModuleName, instances=[moduleInstance],
                                                           parameterlist=parameterList)

                    itemMembersFaultModule.append(moduleInstanceList)  # FaultModule initialization
        else:
            print("Implement fault modules: Error appeared during instantiation in wire section!")
            sys.exit(9)

    # Last preperations steps
    # Ports
    itemMembers.extend(itemMembersPortInputVector)
    # itemMembers.extend(itemMembersPortInput)                      # In this way for every signal is a new line used
    itemMembers.append(vast.Decl(list=itemMembersPortInput))        # In this way it is more "bulk" like

    itemMembers.extend(itemMembersPortOutputVector)
    # itemMembers.extend(itemMembersPortOutput)
    itemMembers.append(vast.Decl(list=itemMembersPortOutput))
    # Wires
    itemMembers.extend(itemMembersWireVector)
    #itemMembers.extend(itemMembersWire)
    itemMembers.append(vast.Decl(list=itemMembersWire))
    # Module Declaration
    itemMembers.extend(itemMembersGate)
    itemMembers.extend(itemMembersFaultModule)


    # Wire Arrays

    # Actual code generation
    portList = vast.Portlist(portMembers)
    ast = vast.ModuleDef(name=outputName, paramlist=None, portlist=portList, items=itemMembers)

    codegen = ASTCodeGenerator()
    result = codegen.visit(ast)

    if(verbose):
        print(result)
    # Writing to the code to output file
    outputFile = open((outputName + ".v"), 'w')
    outputFile.write(result)
    outputFile.close()
    print("Finished writing process!")

    return 0
Example #22
0
    def ce_module(self, module_name, dip_list):
        # module for checking ce
        state_width = vast.Width(vast.IntConst(self.state_size_msb),
                                 vast.IntConst('0'))
        ce_name = module_name + '_ce'
        step = 1

        # module port list
        portslist = []
        portslist.append(vast.Ioport(vast.Input('clk')))
        portslist.append(
            vast.Ioport(vast.Input('ce_iv_s0', width=self.inp_width)))
        portslist.append(
            vast.Ioport(vast.Input('ce_state_s0', width=state_width)))
        portslist = vast.Portlist(portslist)

        # create other components for dis_generator
        inst_list = []
        inst_list.append(vast.Wire('ce_state1_s0', width=state_width))
        inst_list.append(vast.Wire('ce_state2_s0', width=state_width))
        inst_list.append(vast.Wire('ce_state1_s1', width=state_width))
        inst_list.append(vast.Wire('ce_state2_s1', width=state_width))

        inst_list.append(vast.Wire('ce_ov1_s0', width=self.out_width))
        inst_list.append(vast.Wire('ce_ov2_s0', width=self.out_width))

        inst_list.append(vast.Identifier('assign ce_state1_s0 = ce_state_s0;'))
        inst_list.append(vast.Identifier('assign ce_state2_s0 = ce_state_s0;'))

        for s in range(step):
            # create instances for obf1_ce, obf2_ce
            ports = create_ports('ce_iv_s' + str(s), 'ce_ov1_s' + str(s),
                                 self.orcl_cir)
            key_ports = [vast.PortArg("", vast.Identifier('k1'))]
            state_ports = [
                vast.PortArg("", vast.Identifier('ce_state1_s{}'.format(s)))
            ]
            nstate_ports = [
                vast.PortArg("",
                             vast.Identifier('ce_state1_s{}'.format(s + 1)))
            ]
            inst = vast.Instance(
                ce_name, "obf1_ce_s{}".format(s),
                ports + key_ports + state_ports + nstate_ports, "")
            obf1_ce = vast.InstanceList(ce_name, "", [inst])

            ports = create_ports('ce_iv_s' + str(s), 'ce_ov2_s' + str(s),
                                 self.orcl_cir)
            state_ports = [
                vast.PortArg("", vast.Identifier('ce_state2_s{}'.format(s)))
            ]
            key_ports = [vast.PortArg("", vast.Identifier('k2'))]
            nstate_ports = [
                vast.PortArg("",
                             vast.Identifier('ce_state2_s{}'.format(s + 1)))
            ]
            inst = vast.Instance(
                ce_name, 'obf2_ce_s{}'.format(s),
                ports + key_ports + state_ports + nstate_ports, "")
            obf2_ce = vast.InstanceList(ce_name, "", [inst])

            inst_list.extend([obf1_ce, obf2_ce])

        # add always block
        sens = vast.Sens(vast.Identifier('clk'), type='posedge')
        senslist = vast.SensList([sens])

        blocks = []
        for s in range(step):
            blocks.append(
                vast.Identifier('assert (ce_ov1_s{} == ce_ov2_s{});'.format(
                    s, s)))
            blocks.append(
                vast.Identifier(
                    'assert (ce_state1_s{} == ce_state2_s{});'.format(
                        s + 1, s + 1)))

        if len(dip_list) > 0:
            for i, dip in enumerate(dip_list):
                inst_list.append(
                    vast.Identifier('reg [{}:0] dip{} [0:{}];'.format(
                        self.input_size_msb, i,
                        len(dip) - 1)))

        # add always block
        blocks.append(vast.Identifier('cycle <= cycle + 1;'))
        statement = vast.Block(blocks)

        sens = vast.Sens(vast.Identifier('clk'), type='posedge')
        inst_list.append(vast.Always(vast.SensList([sens]), statement))

        if len(dip_list) > 0:
            for i, dip in enumerate(dip_list):
                inst_list.append(
                    vast.Identifier(
                        'dip_checker dc{} (clk, dip{}[cycle], k1, k2);'.format(
                            i, i)))

        # add always block
        blocks = []
        for i, dip in enumerate(dip_list):
            for j, inp in enumerate(dip):
                blocks.append(
                    vast.Identifier('dip{}[{}] = {};'.format(i, j, inp)))
        statement = vast.Block(blocks)
        inst_list.append(vast.Always(senslist, statement))

        # for s in range(step):
        #     blocks.append(vast.Identifier('assume (ce_state1_s{} != ce_state2_s{});'.format(s+1, s+1)))

        statement = vast.Block(blocks)
        inst_list.append(vast.Always(senslist, statement))
        self.ce = vast.ModuleDef("ce", None, portslist, inst_list)
Example #23
0
from __future__ import absolute_import
from __future__ import print_function
import sys
import os
sys.path.insert(
    0,
    os.path.dirname(
        os.path.dirname(
            os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))

import pyverilog.vparser.ast as vast
from pyverilog.ast_code_generator.codegen import ASTCodeGenerator

params = vast.Paramlist(())
clk = vast.Ioport(vast.Input('CLK'))
rst = vast.Ioport(vast.Input('RST'))
width = vast.Width(vast.IntConst('7'), vast.IntConst('0'))
led = vast.Ioport(vast.Output('led', width=width))
ports = vast.Portlist((clk, rst, led))
items = (vast.Assign(vast.Identifier('led'), vast.IntConst('8')), )
ast = vast.ModuleDef("top", params, ports, items)

codegen = ASTCodeGenerator()
rslt = codegen.visit(ast)
print(rslt)