1

I am struggling to parse an FPGA simulation file (.vwf), specifically at the point where the input waveforms are specified using a kind of nested loop system. An example of the file format is:

TRANSITION_LIST("ADDR[0]")
{
    NODE
    {
        REPEAT = 1;
        LEVEL 0 FOR 100.0;
        LEVEL 1 FOR 100.0;
        NODE
        {
            REPEAT = 3;
            LEVEL 0 FOR 100.0;
            LEVEL 1 FOR 100.0;
            NODE
            {
                REPEAT = 2;
                LEVEL 0 FOR 200.0;
                LEVEL 1 FOR 200.0;
            }
        }
        LEVEL 0 FOR 100.0;
    }
}

So this means that the channel named "ADDR[0]" has its logic value switched as follows:

LEVEL 0 FOR 100.0;
LEVEL 1 FOR 100.0;
LEVEL 0 FOR 100.0;
LEVEL 1 FOR 100.0;
LEVEL 0 FOR 200.0;
LEVEL 1 FOR 200.0;
LEVEL 0 FOR 200.0;
LEVEL 1 FOR 200.0;
LEVEL 0 FOR 100.0;
LEVEL 1 FOR 100.0;
LEVEL 0 FOR 200.0;
LEVEL 1 FOR 200.0;
LEVEL 0 FOR 200.0;
LEVEL 1 FOR 200.0;
LEVEL 0 FOR 100.0;
LEVEL 1 FOR 100.0;
LEVEL 0 FOR 200.0;
LEVEL 1 FOR 200.0;
LEVEL 0 FOR 200.0;
LEVEL 1 FOR 200.0;
LEVEL 0 FOR 100.0;

I have set out to try and get this information into a list structure that looks like:

[[0, 100], [1, 100], [0, 100], [1, 100], [0, 200], [1, 200], [0, 200], [1, 200], [0, 100], [1, 100], [0, 200], [1, 200], [0, 200], [1, 200], [0, 100], [1, 100], [0, 200], [1, 200], [0, 200], [1, 200], [0, 200]]

However, I am struggling to come up with how to do this. I had attempted something that I though worked but upon revisiting it I spotted my mistakes.

import pyparsing as pp


def get_data(LINES):
    node_inst = []
    total_inst = []
    r = []
    c = 0

    rep_search = pp.Literal('REPEAT = ') + pp.Word(pp.nums)
    log_search = pp.Literal('LEVEL') + pp.Word('01') + pp.Literal('FOR') + pp.Word(pp.nums + '.')
    bra_search = pp.Literal('}')

    for line in LINES:
        print(line)
        rep = rep_search.searchString(line)
        log = log_search.searchString(line)
        bra = bra_search.searchString(line)

        if rep:
            #print(line)
            c += 1
            if c > 1: # no logic values have been found when c == 1
                for R in range(r[-1]):
                    for n in node_inst:
                        total_inst.append(n)
                node_inst = []
            r.append(int(rep[0][-1]))

        elif log:
            #print(line)
            node_inst.append([int(log[0][1]),
                              int(round(1000 * float(log[0][-1])))])

        elif bra:
            #print(line)
            if node_inst:
                for R in range(r[-1]):
                    for n in node_inst:
                        total_inst.append(n)
                node_inst = []
            if r:
                del r[-1]

    return total_inst

where essentially r is a list that keeps track of the repeat values but deletes the last value if a '}' is encountered. This produces something close but any values within the loop that repeats 2 times will only be repeated 2 times instead of being a part of the loop that repeats 3 times as well.

Any help or tips would be appreciated. I am just drawing a blank with what is some pretty rough scripting. Anything to do with my code can be changed but the input file format cannot to my knowledge.

1 Answer 1

2

Something like that, consider that it heavily depends on formatting.

import re

class Node:
    def __init__(self, parent, items, repeat):
        self.parent = parent
        self.items = items
        self.repeat = repeat

root = Node(None, [], 1)
node = root

with open('levels.txt') as f:
    for line in f:
        line = line.strip()
        if line == 'NODE':
            new_node = Node(node, [], 1)
            node.items.append(new_node)
            node = new_node

        if line == '}':
            node = node.parent

        res = re.match('REPEAT = (\d+)', line)
        if res:
            node.repeat=int(res.group(1))

        res = re.match('LEVEL (\d+) FOR ([\d.]+)', line)
        if res:
            node.items.append((int(res.group(1)), float(res.group(2))))


def generate(node):
    res = []
    for i in xrange(node.repeat):
        for item in node.items:
            if isinstance(item, Node):
                res.extend(generate(item))
            elif isinstance(item, tuple):
                res.append(item)
    return res

res = generate(root)

for r in res:
    print r
Sign up to request clarification or add additional context in comments.

1 Comment

Something that works and that uses an approach I can learn from is exactly what I was after. I'll try and use the same techniques on the rest of the file. Cheers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.