Пример #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)
Пример #2
0
def gen_lat(path):
    clk = vast.Ioport(vast.Input('en'))
    q = vast.Ioport(vast.Output('Q'))
    d = vast.Ioport(vast.Input('D'))
    r = vast.Ioport(vast.Input('rst'))
    ports = vast.Portlist([clk, q, d, r])

    q_reg = vast.Identifier('reg Q = 0;')

    sens = []
    sens.append(vast.Sens(vast.Identifier('en'), type='level'))
    sens.append(vast.Sens(vast.Identifier('rst'), type='level'))
    sens.append(vast.Sens(vast.Identifier('D'), type='level'))

    senslist = vast.SensList(sens)

    assign_q = vast.NonblockingSubstitution(vast.Lvalue(vast.Identifier('Q')),
                                            vast.Rvalue(vast.Identifier('D')))

    blocks = []
    blocks.append(
        vast.IfStatement(
            vast.Identifier('rst'), vast.Identifier('Q <= 0;'),
            vast.IfStatement(vast.Identifier('en'), assign_q, None), None))

    statement = vast.Block(blocks)
    always = vast.Always(senslist, statement)

    items = []
    items.append(q_reg)
    items.append(always)
    ast = vast.ModuleDef("lat", None, ports, items)

    write_verilog(ast, 'lat.v', path)
Пример #3
0
def lower_action(fsm_reg: vast.Reg, done_stage: vast.IntConst, action: Action):
    body = [lower_update(upd) for upd in action.updates]

    # Statement to update the FSM register to next state.
    st_upd = vast.NonblockingSubstitution(
        vast.Lvalue(vast.Identifier(fsm_reg.name)),
        lower_next(done_stage, action.next_state),
    )
    return vast.Block(body + [st_upd])
Пример #4
0
 def visit_Subst(self, node):
     left = self.visit(node.left)
     right = self.visit(node.right)
     ldelay = self.visit(node.ldelay) if node.ldelay else None
     rdelay = self.visit(node.rdelay) if node.rdelay else None
     lvalue = vast.Lvalue(left)
     rvalue = vast.Rvalue(right)
     if node.blk:
         return vast.BlockingSubstitution(lvalue, rvalue, ldelay, rdelay)
     return vast.NonblockingSubstitution(lvalue, rvalue, ldelay, rdelay)
Пример #5
0
def gen_dff(path):
    clk = vast.Ioport(vast.Input('clk'))
    q = vast.Ioport(vast.Output('Q'))
    d = vast.Ioport(vast.Input('D'))
    ports = vast.Portlist([clk, q, d])

    q_reg = vast.Identifier('reg Q = 0;')

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

    assign_q = vast.NonblockingSubstitution(vast.Lvalue(vast.Identifier('Q')),
                                            vast.Rvalue(vast.Identifier('D')))

    statement = vast.Block([assign_q])
    always = vast.Always(senslist, statement)

    items = []
    items.append(q_reg)
    items.append(always)
    ast = vast.ModuleDef("dff", None, ports, items)

    write_verilog(ast, 'dff.v', path)
Пример #6
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])
Пример #7
0
def lower_update(upd: Update):
    reg = upd.register.name
    return vast.NonblockingSubstitution(vast.Lvalue(vast.Identifier(reg)),
                                        vast.Rvalue(lower_expr(upd.expr)))