Esempio n. 1
0
def test():
    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) * 2
    count_plus_1 = vast.Plus(vast.Identifier('count'), vast.IntConst('1'))
    cp1_times_2 = vast.Times(count_plus_1, vast.IntConst('2'))
    cp1t2_plus_1 = vast.Plus(cp1_times_2, vast.IntConst('1'))
    assign_count_false = vast.NonblockingSubstitution(
        vast.Lvalue(vast.Identifier('count')),
        vast.Rvalue(cp1t2_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)
    
    assert(expected == rslt)
Esempio n. 2
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
Esempio n. 3
0
 def visit_Slice(self, node):
     var = self.visit(node.var)
     msb = self.visit(node.msb)
     lsb = self.visit(node.lsb)
     return vast.Partselect(var, msb, lsb)