aboutsummaryrefslogtreecommitdiffstats
path: root/tests/share/generate.py
blob: 7e87bd64808997c5245314d2775089279b33838f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/env python3

import argparse
import sys
import random
from contextlib import contextmanager

@contextmanager
def redirect_stdout(new_target):
    old_target, sys.stdout = sys.stdout, new_target
    try:
        yield new_target
    finally:
        sys.stdout = old_target

def random_plus_x():
    return "%s x" % random.choice(['+', '+', '+', '-', '-', '|', '&', '^'])

def maybe_plus_x(expr):
    if random.randint(0, 4) == 0:
        return "(%s %s)" % (expr, random_plus_x())
    else:
        return expr

parser = argparse.ArgumentParser(formatter_class = argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-S', '--seed',  type = int, help = 'seed for PRNG')
parser.add_argument('-c', '--count', type = int, default = 100, help = 'number of test cases to generate')
args = parser.parse_args()

if args.seed is not None:
    print("PRNG seed: %d" % args.seed)
    random.seed(args.seed)

for idx in range(args.count):
    with open('temp/uut_%05d.v' % idx, 'w') as f:
        with redirect_stdout(f):
            if random.choice(['bin', 'uni']) == 'bin':
                print('module uut_%05d(a, b, c, d, x, s, y);' % (idx))
                op = random.choice([
                    random.choice(['+', '-', '*', '/', '%']),
                    random.choice(['<', '<=', '==', '!=', '===', '!==', '>=', '>' ]),
                    random.choice(['<<', '>>', '<<<', '>>>']),
                    random.choice(['|', '&', '^', '~^', '||', '&&']),
                ])
                print('  input%s [%d:0] a;' % (random.choice(['', ' signed']), random.randint(0, 8)))
                print('  input%s [%d:0] b;' % (random.choice(['', ' signed']), random.randint(0, 8)))
                print('  input%s [%d:0] c;' % (random.choice(['', ' signed']), random.randint(0, 8)))
                print('  input%s [%d:0] d;' % (random.choice(['', ' signed']), random.randint(0, 8)))
                print('  input%s [%d:0] x;' % (random.choice(['', ' signed']), random.randint(0, 8)))
                print('  input s;')
                print('  output [%d:0] y;' % random.randint(0, 8))
                print('  assign y = (s ? %s(%s %s %s) : %s(%s %s %s))%s;' %
                        (random.choice(['', '$signed', '$unsigned']), maybe_plus_x('a'), op, maybe_plus_x('b'),
                         random.choice(['', '$signed', '$unsigned']), maybe_plus_x('c'), op, maybe_plus_x('d'),
                         random_plus_x() if random.randint(0, 4) == 0 else ''))
                print('endmodule')
            else:
                print('module uut_%05d(a, b, x, s, y);' % (idx))
                op = random.choice(['~', '-', '!'])
                print('  input%s [%d:0] a;' % (random.choice(['', ' signed']), random.randint(0, 8)))
                print('  input%s [%d:0] b;' % (random.choice(['', ' signed']), random.randint(0, 8)))
                print('  input%s [%d:0] x;' % (random.choice(['', ' signed']), random.randint(0, 8)))
                print('  input s;')
                print('  output [%d:0] y;' % random.randint(0, 8))
                print('  assign y = (s ? %s(%s%s) : %s(%s%s))%s;' %
                        (random.choice(['', '$signed', '$unsigned']), op, maybe_plus_x('a'),
                         random.choice(['', '$signed', '$unsigned']), op, maybe_plus_x('b'),
                         random_plus_x() if random.randint(0, 4) == 0 else ''))
                print('endmodule')
    with open('temp/uut_%05d.ys' % idx, 'w') as f:
        with redirect_stdout(f):
            print('read_verilog temp/uut_%05d.v' % idx)
            print('proc;;')
            print('copy uut_%05d gold' % idx)
            print('rename uut_%05d gate' % idx)
            print('tee -a temp/all_share_log.txt log')
            print('tee -a temp/all_share_log.txt log #job# uut_%05d' % idx)
            print('tee -a temp/all_share_log.txt wreduce')
            print('tee -a temp/all_share_log.txt share -aggressive gate')
            print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter')
            print('sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter')
span> tap_aio_completion_thread, ctx)) != 0) { DPRINTF("Unable to create completion thread\n"); return -1; } ctx->pollfd = ctx->completion_fd[0]; ctx->poll_in_thread = 1; tap_aio_continue(ctx); return 0; } int tap_aio_get_events(tap_aio_internal_context_t *ctx) { int nr_events = 0; if (!ctx->poll_in_thread) nr_events = io_getevents(ctx->aio_ctx, 1, ctx->max_aio_events, ctx->aio_events, NULL); else { int r; r = read(ctx->completion_fd[0], &nr_events, sizeof(nr_events)); if (r < 0) { if (errno == EAGAIN || errno == EINTR) return 0; /* This is pretty bad, we'll probably spin */ DPRINTF("Aargh, read completion_fd failed: %s", strerror(errno)); } else if (r != sizeof(nr_events)) { /* Should never happen because sizeof(nr_events) * fits in the guaranteed atomic pipe write size. * Blundering on is slightly nicer than asserting */ DPRINTF("Aargh, read completion_fd short read %d", r); } } return nr_events; } int tap_aio_more_events(tap_aio_internal_context_t *ctx) { return io_getevents(ctx->aio_ctx, 0, ctx->max_aio_events, ctx->aio_events, NULL); } int tap_aio_init(tap_aio_context_t *ctx, uint64_t sectors, int max_aio_reqs) { int i, ret; long ioidx; ctx->iocb_list = NULL; ctx->pending_aio = NULL; ctx->aio_events = NULL; ctx->iocb_free = NULL; ctx->iocb_queue = NULL; /*Initialize Locking bitmap*/ ctx->sector_lock = calloc(1, sectors); if (!ctx->sector_lock) { DPRINTF("Failed to allocate sector lock\n"); goto fail; } /* Initialize AIO */ ctx->max_aio_reqs = max_aio_reqs; ctx->iocb_free_count = ctx->max_aio_reqs; ctx->iocb_queued = 0; if (!(ctx->iocb_list = malloc(sizeof(struct iocb) * ctx->max_aio_reqs)) || !(ctx->pending_aio = malloc(sizeof(struct pending_aio) * ctx->max_aio_reqs)) || !(ctx->aio_events = malloc(sizeof(struct io_event) * ctx->max_aio_reqs)) || !(ctx->iocb_free = malloc(sizeof(struct iocb *) * ctx->max_aio_reqs)) || !(ctx->iocb_queue = malloc(sizeof(struct iocb *) * ctx->max_aio_reqs))) { DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n", ctx->max_aio_reqs); goto fail; } ret = tap_aio_setup(&ctx->aio_ctx, ctx->aio_events, ctx->max_aio_reqs); if (ret < 0) { if (ret == -EAGAIN) { DPRINTF("Couldn't setup AIO context. If you are " "trying to concurrently use a large number " "of blktap-based disks, you may need to " "increase the system-wide aio request limit. " "(e.g. 'echo echo 1048576 > /proc/sys/fs/" "aio-max-nr')\n"); } else { DPRINTF("Couldn't setup AIO context.\n"); } goto fail; } for (i=0;i<ctx->max_aio_reqs;i++) ctx->iocb_free[i] = &ctx->iocb_list[i]; DPRINTF("AIO state initialised\n"); return 0; fail: return -1; } void tap_aio_free(tap_aio_context_t *ctx) { if (ctx->sector_lock) free(ctx->sector_lock); if (ctx->iocb_list) free(ctx->iocb_list); if (ctx->pending_aio) free(ctx->pending_aio); if (ctx->aio_events) free(ctx->aio_events); if (ctx->iocb_free) free(ctx->iocb_free); if (ctx->iocb_queue) free(ctx->iocb_queue); } /*TODO: Fix sector span!*/ int tap_aio_can_lock(tap_aio_context_t *ctx, uint64_t sector) { return (ctx->sector_lock[sector] ? 0 : 1); } int tap_aio_lock(tap_aio_context_t *ctx, uint64_t sector) { return ++ctx->sector_lock[sector]; } void tap_aio_unlock(tap_aio_context_t *ctx, uint64_t sector) { if (!ctx->sector_lock[sector]) return; --ctx->sector_lock[sector]; return; } int tap_aio_read(tap_aio_context_t *ctx, int fd, int size, uint64_t offset, char *buf, td_callback_t cb, int id, uint64_t sector, void *private) { struct iocb *io; struct pending_aio *pio; long ioidx; if (ctx->iocb_free_count == 0) return -ENOMEM; io = ctx->iocb_free[--ctx->iocb_free_count]; ioidx = IOCB_IDX(ctx, io); pio = &ctx->pending_aio[ioidx]; pio->cb = cb; pio->id = id; pio->private = private; pio->nb_sectors = size/512; pio->buf = buf; pio->sector = sector; io_prep_pread(io, fd, buf, size, offset); io->data = (void *)ioidx; ctx->iocb_queue[ctx->iocb_queued++] = io; return 0; } int tap_aio_write(tap_aio_context_t *ctx, int fd, int size, uint64_t offset, char *buf, td_callback_t cb, int id, uint64_t sector, void *private) { struct iocb *io; struct pending_aio *pio; long ioidx; if (ctx->iocb_free_count == 0) return -ENOMEM; io = ctx->iocb_free[--ctx->iocb_free_count]; ioidx = IOCB_IDX(ctx, io); pio = &ctx->pending_aio[ioidx]; pio->cb = cb; pio->id = id; pio->private = private; pio->nb_sectors = size/512; pio->buf = buf; pio->sector = sector; io_prep_pwrite(io, fd, buf, size, offset); io->data = (void *)ioidx; ctx->iocb_queue[ctx->iocb_queued++] = io; return 0; } int tap_aio_submit(tap_aio_context_t *ctx) { int ret; if (!ctx->iocb_queued) return 0; ret = io_submit(ctx->aio_ctx.aio_ctx, ctx->iocb_queued, ctx->iocb_queue); /* XXX: TODO: Handle error conditions here. */ /* Success case: */ ctx->iocb_queued = 0; return 0; }