Пример #1
0
def lts_to_verilog(lts:LTS, module_name:str) -> str:
    s = StrAwareList()

    s += 'module {module}({inputs}, {outputs});'.format(
        inputs=', '.join(map(lambda sig: sig.name, lts.input_signals)),
        outputs=', '.join(map(lambda sig: sig.name, lts.output_signals)),
        module=module_name)
    s.newline()

    s += '\n'.join(['input {sig};'.format(sig=sig.name) for sig in lts.input_signals])
    s.newline()

    s += '\n'.join(['output {sig};'.format(sig=sig.name) for sig in lts.output_signals])
    s.newline()

    # TODO: don't use latches for state-less models
    nof_state_bits = math.ceil(math.log2(len(lts.states)))
    s += 'reg [{max_bit}:0] {state};'.format(max_bit=int(max(0., nof_state_bits-1)),  # max_bit is at least 0
                                                         state=lts.state_name)
    s.newline()

    s += '\n'.join(['wire {out};'.format(out=sig.name) for sig in lts.output_signals])
    s.newline()

    for out_sig, value_tuples in lts.output_models.items():
        labels_true = lmap(lambda x: x[0],
                           filter(lambda label_value: label_value[1],
                                  value_tuples.items()))
        assign = 'assign {sig} = {true_expr};'.format(sig=out_sig.name,
                                                      true_expr=' || '.join(map(_label_to_verilog, labels_true))
                                                                if labels_true else '0')
        s += assign
    s.newline()

    s += 'initial begin'
    s += '{state} = 0;'.format(state=lts.state_name)
    s += 'end'
    s.newline()

    s += 'always@($global_clock)'
    s += 'begin'

    # you can also use '=' instead of '<=' here, but we will be strict
    tau_items = tuple(lts.tau_model.items())
    s += 'if ({expr}) {state} <= {next_val};'.format(expr=_label_to_verilog(tau_items[0][0]),
                                                     state=lts.state_name,
                                                     next_val=tau_items[0][1])
    for lbl, val in tau_items[1:]:
        s += 'else if ({expr}) {state} <= {next_val};'.format(expr=_label_to_verilog(lbl),
                                                              state=lts.state_name,
                                                              next_val=val)
    s += 'end'
    s += 'endmodule'
    return s.to_str()
Пример #2
0
def lts_to_verilog(lts:LTS) -> str:
    s = StrAwareList()

    s += 'module model(i_clk, \n{inputs}, \n{outputs});'.format(inputs=', '.join(map(lambda sig: sig.name,
                                                                                     lts.input_signals)),
                                                                outputs=', '.join(map(lambda sig: sig.name,
                                                                                      lts.output_signals)))
    s.newline()

    s += 'input i_clk;'
    s += '\n'.join(['input {sig};'.format(sig=sig.name) for sig in lts.input_signals])
    s.newline()

    s += '\n'.join(['output {sig};'.format(sig=sig.name) for sig in lts.output_signals])
    s.newline()

    nof_state_bits = max(1, math.ceil(math.log2(len(lts.states))))
    s += 'reg [{max_bit}:0] {state};'.format(max_bit=nof_state_bits-1, state=lts.state_name)
    s.newline()

    s += '\n'.join(['wire {out};'.format(out=sig.name) for sig in lts.output_signals])
    s.newline()

    for out_sig, value_tuples in lts.output_models.items():
        labels_true = lmap(lambda x: x[0],
                           filter(lambda label_value: label_value[1],
                                  value_tuples.items()))
        assign = 'assign {sig} = {true_expr};'.format(sig=out_sig.name,
                                                      true_expr=' || '.join(map(_label_to_verilog,
                                                                                labels_true))
                                                                if labels_true else '0')
        s += assign
    s.newline()

    s += 'initial begin'
    s += '{state} = 0;'.format(state=lts.state_name)
    s += 'end'
    s.newline()

    s += 'always@(posedge i_clk)'
    s += 'begin'

    tau_items = tuple(lts.tau_model.items())
    s += 'if ({expr}) {state} = {next_val};'.format(expr=_label_to_verilog(tau_items[0][0]),
                                                    state=lts.state_name,
                                                    next_val=tau_items[0][1])
    for lbl, val in tau_items[1:]:
        s += 'else if ({expr}) {state} = {next_val};'.format(expr=_label_to_verilog(lbl),
                                                             state=lts.state_name,
                                                             next_val=val)
    s += 'end'
    s += 'endmodule'
    return s.to_str()
Пример #3
0
def atm_to_verilog(atm: Automaton, sys_inputs: Iterable[Signal],
                   sys_outputs: Iterable[Signal], module_name: str,
                   bad_out_name: str) -> str:
    assert len(lfilter(lambda n: is_final_sink(n), atm.nodes)) == 1,\
        'for now I support only one bad state which must be a sink'
    sys_inputs = set(sys_inputs)
    sys_outputs = set(sys_outputs)

    verilog_by_sig = {s: 'controllable_' + s.name for s in sys_outputs}
    verilog_by_sig.update({s: s.name for s in sys_inputs})

    verilog_by_node = {q: '__q' + q.name for q in atm.nodes}
    sink_q = lfilter(lambda n: is_final_sink(n), atm.nodes)[0]

    module_inputs = list(
        chain(map(lambda i: i.name, sys_inputs),
              map(lambda o: 'controllable_' + o.name, sys_outputs)))

    s = StrAwareList()
    s += 'module {module_name}({inputs}, {output});'.format(
        module_name=module_name,
        inputs=', '.join(module_inputs),
        output=bad_out_name)
    s.newline()

    s += '\n'.join('input %s;' % i for i in module_inputs)
    s.newline()

    s += 'output %s;' % bad_out_name
    s.newline()

    s += '\n'.join('reg %s;' % vq for vq in verilog_by_node.values())
    s.newline()

    s += 'wire %s;' % bad_out_name
    s += 'assign {bad} = {sink_q};'.format(bad=bad_out_name,
                                           sink_q=verilog_by_node[sink_q])
    s.newline()

    s += 'initial begin'
    s += '\n'.join('%s = 1;' % verilog_by_node[iq] for iq in atm.init_nodes)
    s += '\n'.join('%s = 0;' % verilog_by_node[q]
                   for q in atm.nodes - atm.init_nodes)
    s += 'end'
    s.newline()

    s += 'always@($global_clock)'
    s += 'begin'

    def lbl_to_v(lbl: Label) -> str:
        return ' && '.join(
            ('!%s', '%s')[lbl[s]] % verilog_by_sig[s] for s in lbl) or '1'

    for q in atm.nodes:
        incoming_edges = incoming_transitions(q, atm)
        if not incoming_edges:
            update_expr = '0'
        else:
            update_expr = ' || '.join('{src} && {lbl}'.format(
                src=verilog_by_node[edge[0]], lbl=lbl_to_v(edge[1]))
                                      for edge in incoming_edges)
        s += '  {q} <= {update_expr};'.format(q=verilog_by_node[q],
                                              update_expr=update_expr)
    s += 'end'
    s += 'endmodule'
    return s.to_str()