kulp / tenyr
1
#include "sim.h"
2
#include "stream.h"
3

4
#include "tenyr_vpi.h"
5

6
#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
7

8
struct dispatch_userdata {
9
    struct tenyr_sim_state *state;
10
    vpiHandle array;
11
};
12

13 1
static int vpi_dispatch(void *ud, int op, int32_t addr, int32_t *data)
14
{
15 1
    int rc = -1;
16 1
    struct dispatch_userdata *d = ud;
17

18 1
    vpiHandle word = vpi_handle_by_index(d->array, addr);
19 1
    struct t_vpi_value argval = { .format = vpiIntVal };
20 1
    switch (op) {
21 1
        case OP_WRITE:
22 1
            argval.value.integer = *data;
23 1
            vpi_put_value(word, &argval, NULL, vpiNoDelay);
24 1
            rc = 0;
25 1
            break;
26 1
        case OP_INSN_READ:
27
        case OP_DATA_READ:
28 1
            vpi_get_value(word, &argval);
29 1
            *data = argval.value.integer;
30 1
            rc = 0;
31 1
            break;
32
        // default case should be impossible -- leaves -1 in rc
33
    }
34

35 1
    return rc;
36
}
37

38 1
static int get_range(vpiHandle from, int which)
39
{
40 1
    vpiHandle lr = vpi_handle(which, from);
41 1
    struct t_vpi_value argval = { .format = vpiIntVal };
42 1
    vpi_get_value(lr, &argval);
43 1
    return argval.value.integer;
44
}
45

46 1
PLI_INT32 tenyr_sim_load(PLI_BYTE8 *userdata)
47
{
48 1
    struct tenyr_sim_state *state = (void*)userdata;
49 1
    vpiHandle array = vpi_handle_by_name("Top.tenyr.ram.store", NULL);
50

51 1
    struct dispatch_userdata data = {
52
        .state = state,
53
        .array = array,
54
    };
55

56 1
    int left  = get_range(array, vpiLeftRange);
57 1
    int right = get_range(array, vpiRightRange);
58 1
    int min = MIN(left, right);
59

60 1
    vpiHandle systfref  = vpi_handle(vpiSysTfCall, NULL),
61 1
              args_iter = vpi_iterate(vpiArgument, systfref),
62 1
              argh      = vpi_scan(args_iter);
63

64 1
    int rc = 0;
65 1
    do {
66 1
        struct t_vpi_value argval = { .format = vpiStringVal };
67 1
        vpi_get_value(argh, &argval);
68 1
        vpi_free_object(argh);
69 1
        const char *filename = argval.value.str;
70

71 1
        FILE *file = fopen(filename, "rb");
72 1
        rc = file == NULL;
73 1
        if (rc)
74
            break;
75

76 1
        STREAM stream_ = stream_make_from_file(file), *stream = &stream_;
77

78 1
        void *ud = NULL;
79 1
        const struct format *f = &tenyr_asm_formats[0];
80

81 1
        rc = f->init(stream, NULL, &ud);
82 1
        if (rc)
83
            break;
84

85 1
        rc |= load_sim(vpi_dispatch, &data, f, ud, stream, min);
86

87 1
        rc |= f->fini(stream, &ud);
88 1
    } while (0);
89

90 1
    vpiHandle second = vpi_scan(args_iter);
91 1
    if (second) { // The second argument might not be provided.
92 1
        s_vpi_value retval = {
93
            .format = vpiIntVal,
94
            .value.integer = rc,
95
        };
96

97 1
        vpi_put_value(second, &retval, NULL, vpiNoDelay);
98 1
        vpi_free_object(second);
99
    }
100

101 1
    return 0;
102
}
103

Read our documentation on viewing source code .

Loading