OpenCores
URL https://opencores.org/ocsvn/ag_6502/ag_6502/trunk

Subversion Repositories ag_6502

[/] [ag_6502/] [trunk/] [genstates/] [genstates.c] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 olegodints
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#include <assert.h>
5
#include <ctype.h>
6
 
7
 
8
#define ACTION_INVALID  0
9
#define ACTION_ASSIGN   1
10
#define ACTION_EXEC     2
11
 
12
 
13
int opt_level = 1; // 0 to allow verilog optimizer to produce better design, 
14
                   // (-1) to do not even find common bits
15
 
16
struct STATE_ACTION
17
{
18
        int     atype;
19
        const char*astr;
20
        const char*astr_parsed; // w/o spaces, used to compare
21
};
22
 
23
#define TIME_ANY        (-1)
24
#define TIME_INC        (-2)
25
#define PHASE_ANY       (-1)
26
 
27
#define NO_CODE (-1)
28
#define NO_MACROS (-1)
29
 
30
#define MIN_TIME 0
31
#define MAX_TIME 7
32
#define MIN_PHASE 1
33
#define MAX_PHASE 2
34
 
35
#define TIME_COUNT (MAX_TIME - MIN_TIME + 1)
36
 
37
struct STATE_ENTRY
38
{
39
        int     time, phase;
40
        int     action_id;
41
};
42
 
43
#define MAX_MACROS_SIZE 256
44
 
45
struct STATE_MACROS
46
{
47
        const char*name;
48
        int     n_entries;
49
        int     entries[MAX_MACROS_SIZE];
50
};
51
 
52
#define MAX_CODE_SIZE 64
53
struct STATE_CODE
54
{
55
        const char*comment;
56
        int     n_entries;
57
        int     entries[MAX_CODE_SIZE];
58
};
59
 
60
 
61
#define MAX_ACTIONS     8192
62
#define MAX_ENTRIES     8192
63
#define MAX_MACROSES    8192
64
#define MAX_CODES       512
65
 
66
#define MAX_STRING      1024
67
 
68
struct STATE_DATA
69
{
70
        int n_actions, n_entries, n_macroses;
71
        struct STATE_ACTION actions[MAX_ACTIONS];
72
        struct STATE_ENTRY entries[MAX_ENTRIES];
73
        struct STATE_MACROS macroses[MAX_MACROSES];
74
        struct STATE_CODE codes[MAX_CODES];
75
 
76
        int cur_time, cur_phase, cur_code, cur_macros;
77
};
78
 
79
static const char SPACES[] = " \t";
80
 
81
int get_action_code(const char*str)
82
{
83
        return strstr(str, "<=")?ACTION_EXEC: ACTION_ASSIGN;
84
}
85
 
86
void clean_action(const char*str, char*buf)
87
{
88
        for (; *str; ++str) if (!strchr(SPACES, *str)) *buf++ = *str;
89
        *buf = 0;
90
}
91
 
92
void action_to_name(const char*str, char*buf)
93
{
94
        for (; *str; ++str, ++buf) {
95
                if (!isalnum(*str)) *buf = '_';
96
                else *buf = *str;
97
        }
98
        *buf = 0;
99
}
100
 
101
int find_action(struct STATE_DATA*sd, const char*buf)
102
{
103
        int i;
104
        for (i = 0; i < sd->n_actions; ++i) {
105
                if (!strcmp(sd->actions[i].astr_parsed, buf)) return i;
106
        }
107
        return -1;
108
}
109
 
110
int append_action(struct STATE_DATA*sd, const char*str)
111
{
112
        char buf[MAX_STRING];
113
        struct STATE_ACTION*a = sd->actions + sd->n_actions;
114
        int r;
115
        assert(sd->n_actions < MAX_ACTIONS);
116
        clean_action(str, buf);
117
//      puts(buf);
118
        r = find_action(sd, buf);
119
        if (r >= 0) return r;
120
        a->atype = get_action_code(buf);
121
        if (a->atype == ACTION_INVALID) {
122
                fprintf(stderr, "invalid action: %s\n", str);
123
                abort();
124
        }
125
        a->astr = _strdup(str);
126
        a->astr_parsed = _strdup(buf);
127
        return sd->n_actions++;
128
}
129
 
130
int find_entry(struct STATE_DATA*sd, int time, int phase, int action_id)
131
{
132
        int i;
133
        struct STATE_ENTRY*e = sd->entries;
134
        for (i = 0; i < sd->n_entries; ++i, ++e) {
135
                if (e->time == time && e->phase == phase && e->action_id == action_id) return i;
136
        }
137
        return -1;
138
}
139
 
140
int append_entry_copy(struct STATE_DATA*sd, int time, int phase, int action_id)
141
{
142
        struct STATE_ENTRY*e = sd->entries + sd->n_entries;
143
        int r;
144
        r = find_entry(sd, time, phase, action_id);
145
        if (r >= 0) return r;
146
        assert(sd->n_entries < MAX_ENTRIES);
147
        e->time = time;
148
        e->phase = phase;
149
        e->action_id = action_id;
150
        return sd->n_entries++;
151
}
152
 
153
 
154
int append_entry(struct STATE_DATA*sd, int time, int phase, const char*str)
155
{
156
        return append_entry_copy(sd, time, phase, append_action(sd, str));
157
}
158
 
159
int find_macros(struct STATE_DATA*sd, const char*name)
160
{
161
        int i;
162
        for (i = 0; i < sd->n_macroses; ++i) {
163
                if (!strcmp(sd->macroses[i].name, name)) return i;
164
        }
165
        return -1;
166
}
167
 
168
int append_macros(struct STATE_DATA*sd, const char*name)
169
{
170
        struct STATE_MACROS*m = sd->macroses + sd->n_macroses;
171
        int r;
172
        assert(sd->n_macroses < MAX_MACROSES);
173
        r = find_macros(sd, name);
174
        if (r >= 0) return r;
175
        m->name = _strdup(name);
176
        m->n_entries = 0;
177
        return sd->n_macroses++;
178
}
179
 
180
int find_macros_entry(struct STATE_DATA*sd, int macro_id, int entry_id)
181
{
182
        struct STATE_MACROS*m = sd->macroses + macro_id;
183
        int i;
184
        assert(macro_id >= 0 && macro_id < sd->n_macroses);
185
        for (i = 0; i < m->n_entries; ++i) {
186
                if (m->entries[i] == entry_id) return i;
187
        }
188
        return -1;
189
}
190
 
191
int append_macros_entry(struct STATE_DATA*sd, int macro_id, int entry_id)
192
{
193
        struct STATE_MACROS*m = sd->macroses + macro_id;
194
        int r;
195
//      r = find_macros_entry(sd, macro_id, entry_id);
196
//      if (r >= 0) return r;
197
        assert(macro_id >= 0 && macro_id < sd->n_macroses);
198
        assert(m->n_entries < MAX_MACROS_SIZE);
199
        m->entries[m->n_entries++] = entry_id;
200
        return m->n_entries - 1;
201
}
202
 
203
 
204
int append_code(struct STATE_DATA*sd, int value, const char*comment)
205
{
206
        struct STATE_CODE*c = sd->codes + value;
207
        assert(value >= 0 && value < MAX_CODES);
208
        if (!c->comment) c->comment = comment?_strdup(comment):NULL;
209
        else return -5;
210
        return value;
211
}
212
 
213
 
214
int find_code_entry(struct STATE_DATA*sd, int code_id, int entry_id)
215
{
216
        struct STATE_CODE*c = sd->codes + code_id;
217
        int i;
218
        assert(code_id >= 0 && code_id < MAX_CODES);
219
        for (i = 0; i < c->n_entries; ++i) {
220
                if (c->entries[i] == entry_id) return i;
221
        }
222
        return -1;
223
}
224
 
225
int append_code_entry(struct STATE_DATA*sd, int code_id, int entry_id)
226
{
227
        struct STATE_CODE*c = sd->codes + code_id;
228
        int r;
229
        r = find_code_entry(sd, code_id, entry_id);
230
        if (r >= 0) return r;
231
        assert(code_id >= 0 && code_id < MAX_CODES);
232
        assert(c->n_entries < MAX_CODE_SIZE);
233
        c->entries[c->n_entries++] = entry_id;
234
        return c->n_entries - 1;
235
}
236
 
237
int clear_data(struct STATE_DATA*sd)
238
{
239
        memset(sd, 0, sizeof(*sd));
240
        sd->cur_time = TIME_ANY;
241
        sd->cur_phase = PHASE_ANY;
242
        sd->cur_code = NO_CODE;
243
        sd->cur_macros = NO_MACROS;
244
        return 0;
245
}
246
 
247
int append_code_macros(struct STATE_DATA*sd, int code_id, int m_id)
248
{
249
        struct STATE_MACROS*s = sd->macroses + m_id;
250
        int i, r;
251
//      printf("append_code_macros (%02X, %i): n_entries = %i\n", code_id, m_id, s->n_entries);
252
        for (i = 0; i < s->n_entries; ++i) {
253
                int e = s->entries[i];
254
                int t = sd->entries[e].time;
255
                int ph = sd->entries[e].phase;
256
                if (t == TIME_INC) {
257
                        if (sd->cur_time == TIME_ANY) {
258
                                return -4;
259
                        }
260
                        t = sd->cur_time + 1;
261
                }
262
                if (t == TIME_ANY) t = sd->cur_time;
263
                if (ph == PHASE_ANY) ph = sd->cur_phase;
264
                if (t == TIME_ANY) return -1;
265
                if (ph == PHASE_ANY) return -2;
266
                sd->cur_time = t;
267
                sd->cur_phase = ph;
268
                r = append_code_entry(sd, code_id, append_entry_copy(sd, t, ph, sd->entries[e].action_id));
269
//              printf("append_code_entry: %i: action_id = %i\n", r, sd->entries[e].action_id);
270
                if (r < 0) return -3;
271
        }
272
        return 0;
273
}
274
 
275
int append_macros_macros(struct STATE_DATA*sd, int macro_id, int m_id)
276
{
277
        struct STATE_MACROS*s = sd->macroses + m_id;
278
        int i, r;
279
        for (i = 0; i < s->n_entries; ++i) {
280
                int e = s->entries[i];
281
                int t = sd->entries[e].time;
282
                int ph = sd->entries[e].phase;
283
                if (t == TIME_ANY) t = sd->cur_time;
284
                if (ph == PHASE_ANY) ph = sd->cur_phase;
285
                sd->cur_time = t;
286
                sd->cur_phase = ph;
287
                r = append_macros_entry(sd, macro_id, append_entry_copy(sd, t, ph, sd->entries[e].action_id));
288
                if (r < 0) return -3;
289
        }
290
        return 0;
291
}
292
 
293
 
294
int insert_macros(struct STATE_DATA*sd, const char*str)
295
{
296
        int m_id, r;
297
        m_id = find_macros(sd, str);
298
//      printf("insert_macros: %s (%i)\n", str, m_id);
299
        if (m_id < 0) {
300
                fprintf(stderr, "error: unable to find macros: %s\n", str);
301
                return 50;
302
        }
303
        if (sd->cur_code != NO_CODE) {
304
                r = append_code_macros(sd, sd->cur_code, m_id);
305
        } else {
306
                r = append_macros_macros(sd, sd->cur_macros, m_id);
307
        }
308
        if (r < 0) {
309
                fprintf(stderr, "error: unable to insert macros: %s: %i\n", str, r);
310
                return 51;
311
        }
312
        return 0;
313
}
314
 
315
int parse_action(struct STATE_DATA*sd, char*str)
316
{
317
        int e, r;
318
        char*p;
319
        p = strchr(str, '%');
320
        if (p) *p = 0; // remove comment
321
//      printf("action: %s\n", str);
322
        if (sd->cur_code == NO_CODE && sd->cur_macros == NO_MACROS) {
323
                fprintf(stderr, "error: no current macros or code in action: %s\n", str);
324
                return 41;
325
        }
326
        if (str[0] == '@') return insert_macros(sd, str + 1);
327
        if (sd->cur_code != NO_CODE && (sd->cur_time == TIME_ANY || sd->cur_phase == PHASE_ANY)) {
328
                fprintf(stderr, "error: no current phase or time in action: %s\n", str);
329
                return 42;
330
        }
331
        e = append_entry(sd, sd->cur_time, sd->cur_phase, str);
332
        if (sd->cur_code != NO_CODE) {
333
                r = append_code_entry(sd, sd->cur_code, e);
334
        } else {
335
                r = append_macros_entry(sd, sd->cur_macros, e);
336
        }
337
        if (r < 0) {
338
                fprintf(stderr, "error: unable to append action: %s\n", str);
339
                return 43;
340
        }
341
        return 0;
342
}
343
 
344
int parse_code(struct STATE_DATA*sd, char*str)
345
{
346
        char*p, *c = NULL;
347
        int v;
348
        v = strtoul(str, &p, 16);
349
        if (p[0] != ':') {
350
                fprintf(stderr, "error: invalid code format: %s\n", str);
351
                return 20;
352
        }
353
        ++ p; p += strspn(p, SPACES);
354
        if (p[0]) {
355
                if (p[0] == '%') {
356
                        c = p + 1;
357
                } else {
358
                        fprintf(stderr, "error: invalid code comment %s: %i\n", str, sd->cur_code);
359
                        return 22;
360
                }
361
        }
362
        sd->cur_code = append_code(sd, v, c);
363
        if (sd->cur_code < 0) {
364
                fprintf(stderr, "error: unable to append code %s: %i\n", str, sd->cur_code);
365
                return 21;
366
        }
367
        sd->cur_macros = NO_MACROS;
368
        sd->cur_time = TIME_ANY;
369
        sd->cur_phase = PHASE_ANY;
370
        return 0;
371
}
372
 
373
int parse_macros(struct STATE_DATA*sd, char*str)
374
{
375
        char*p = strchr(str, ':');
376
        if (!p || p[1]) {
377
                fprintf(stderr, "error: invalid macros format: %s\n", str);
378
                return 30;
379
        }
380
        *p = 0;
381
        sd->cur_macros = append_macros(sd, str);
382
        if (sd->cur_macros < 0) {
383
                fprintf(stderr, "error: unable to append macros %s: %i\n", str, sd->cur_macros);
384
                return 31;
385
        }
386
        sd->cur_code = NO_CODE;
387
        sd->cur_time = TIME_ANY;
388
        sd->cur_phase = PHASE_ANY;
389
        return 0;
390
}
391
 
392
int parse_place(struct STATE_DATA*sd, char*str)
393
{
394
        int t, ph;
395
        char*p, *s0 = str;
396
        if (str[0] == '+' && str[1] == ':') {
397
                if (sd->cur_time == TIME_ANY) {
398
                        if (sd->cur_code != NO_CODE) {
399
                                fprintf(stderr, "error: no current time for increment: %s\n", str);
400
                                return 14;
401
                        } else {
402
                                sd->cur_time = TIME_INC;
403
                        }
404
                } else ++sd->cur_time;
405
                ++str;
406
        }
407
        if (str[0] != ':') {
408
                t = strtoul(str, &p, 10);
409
                if (*p != ':') {
410
                        fprintf(stderr, "error: invalid place format: %s\n", str);
411
                        return 10;
412
                }
413
                if (t < MIN_TIME || t > MAX_TIME) {
414
                        fprintf(stderr, "error: invalid time value: %i\n", t);
415
                        return 11;
416
                }
417
                sd->cur_time = t;
418
                str = p;
419
        }
420
        ++str;
421
        if (!strchr(SPACES, str[0])) {
422
                ph = strtoul(str, &p, 10);
423
                if (!strchr(SPACES, *p)) {
424
                        fprintf(stderr, "error: invalid place format: %s\n", str);
425
                        return 12;
426
                }
427
                if (ph < MIN_PHASE || ph > MAX_PHASE) {
428
                        fprintf(stderr, "error: invalid phase value: %i\n", ph);
429
                        return 13;
430
                }
431
                sd->cur_phase = ph;
432
                str = p;
433
        }
434
        ++str;
435
        return str - s0 + strspn(str, SPACES) + 1;
436
}
437
 
438
int parse_line(struct STATE_DATA*sd, char*str)
439
{
440
        int n = strspn(str, SPACES), r;
441
        if (!str[n]) return 0;
442
        switch (str[0]) {
443
        case '#':
444
                return parse_code(sd, str + 1);
445
        case '@':
446
                return parse_macros(sd, str + 1);
447
        case '(':
448
                n = parse_place(sd, str + 1);
449
                if (n < 0) return n;
450
        case ' ': case '\t':
451
                r = parse_action(sd, str + n);
452
                if (sd->cur_time == TIME_INC) sd->cur_time = TIME_ANY;
453
                return r;
454
        case '%':
455
                return 0; // comment
456
        }
457
        fprintf(stderr, "error: invalid string format: %s\n", str);
458
        return 9;
459
}
460
 
461
int load_data(struct STATE_DATA*sd, const char*fname)
462
{
463
        FILE*in;
464
        int lno = 0;
465
        int r = 0;
466
        char buf[MAX_STRING];
467
 
468
        in = fopen(fname, "rt");
469
        if (!in) {
470
                perror(fname);
471
                return -1;
472
        }
473
 
474
        while (fgets(buf, sizeof(buf), in)) {
475
                int l;
476
                ++ lno;
477
                l = strlen(buf);
478
                if (l && buf[l - 1] == '\n') buf[--l] = 0;
479
                r = parse_line(sd, buf);
480
                if (r) {
481
                        fprintf(stderr, "%s: error parsing line %i: %i\n", fname, lno, r);
482
                        break;
483
                }
484
        }
485
        fclose(in);
486
        return r;
487
}
488
 
489
int write_data(struct STATE_DATA*sd, const char*fname)
490
{
491
        FILE*out;
492
        int i, j, k, l, ct, cp;
493
        out = fopen(fname, "wt");
494
        if (!out) {
495
                perror(fname);
496
                return -1;
497
        }
498
 
499
        for (i = 0; i < MAX_CODES; ++i) {
500
                struct STATE_CODE*c = sd->codes + i;
501
                if (!c->n_entries) continue;
502
                ct = TIME_ANY;
503
                cp = PHASE_ANY;
504
                if (c->comment) fprintf(out, "#%02X: %%%s\n", i, c->comment);
505
                else fprintf(out, "#%02X:\n", i);
506
                for (j = MIN_TIME; j <= MAX_TIME; ++j) {
507
                        for (k = MIN_PHASE; k <= MAX_PHASE; ++k) {
508
                                for (l = 0; l < c->n_entries; ++l) {
509
                                        struct STATE_ENTRY*e = sd->entries + c->entries[l];
510
                                        if (e->time != j || e->phase != k) continue;
511
                                        if (ct != j || cp != k) {
512
                                                fprintf(out, "(%i:%i", j, k);
513
                                                ct = j;
514
                                                cp = k;
515
                                        }
516
                                        fprintf(out, "\t%s\n", sd->actions[e->action_id].astr);
517
                                }
518
                        }
519
                }
520
                fprintf(out, "\n");
521
        }
522
 
523
        fclose(out);
524
        return 0;
525
}
526
 
527
int validate_data(struct STATE_DATA*sd)
528
{
529
        int i, j;
530
 
531
        for (i = 0; i < MAX_CODES; ++i) {
532
                struct STATE_CODE*c = sd->codes + i;
533
                if (!c->n_entries) continue;
534
                for (j = 0; j < c->n_entries; ++j) {
535
                        struct STATE_ENTRY*e = sd->entries + c->entries[j];
536
                        struct STATE_ACTION*a = sd->actions + e->action_id;
537
                        if (e->phase == 2 && a->atype == ACTION_ASSIGN) {
538
                                fprintf(stderr, "error: no assignments are valid in phase 2 for code %02X: %s\n",
539
                                                i, a->astr);
540
                                return -10;
541
                        }
542
                }
543
        }
544
        return 0;
545
}
546
 
547
 
548
int code_has_action(struct STATE_DATA*sd, int code_id, int time, int action_id)
549
{
550
        struct STATE_CODE*c = sd->codes + code_id;
551
        int i;
552
 
553
        for (i = 0; i < c->n_entries; ++i) {
554
                if (sd->entries[c->entries[i]].time == time && sd->entries[c->entries[i]].action_id == action_id) return 1;
555
        }
556
        return 0;
557
}
558
 
559
 
560
#define CODE_NONE       0
561
#define CODE_ACTION     1
562
 
563
#define BIT_COMMON      0
564
#define BIT_OTHER       1
565
 
566
#define N_BITS          (8+3)
567
 
568
#define VBIT_0          0
569
#define VBIT_1          1
570
#define VBIT_UNKNOWN    2
571
#define VBIT_VAR        3
572
 
573
unsigned prepare_selector(int code, int time)
574
{
575
        return code | (time << 8);
576
}
577
 
578
void print_selector(FILE*out, unsigned sel)
579
{
580
        int k;
581
        for (k = N_BITS - 1; k >= 0; --k, sel <<= 1) {
582
                int c;
583
                fputc((sel & (1<<(N_BITS - 1)))?'1': '0', out);
584
                if (!(k & 7)) fputc(' ', out);
585
        }
586
}
587
 
588
#define DEBUG 1
589
 
590
 
591
 
592
unsigned expand_common_bits(FILE*out, unsigned other_mask,
593
        const unsigned other_codes[], int n_other,
594
        int common_bit, int bit_val,
595
        unsigned *mask, unsigned*val,
596
        unsigned sel_mask, unsigned sel_val)
597
{
598
        int i, j, c;
599
        unsigned m, mc, vc, r;
600
        char out_bits[N_BITS];
601
        mc = 1 << common_bit;
602
        vc = bit_val ? mc: 0;
603
        other_mask &= ~mc;
604
        memset(out_bits, VBIT_UNKNOWN, sizeof(out_bits));
605
        for (j = 0; j < n_other; ++j) {
606
                if ((other_codes[j] & sel_mask) != sel_val) continue;
607
                if ((other_codes[j] & mc) != vc) continue;
608
                for (i = 0, m = 1; i < N_BITS; ++i, m <<= 1) {
609
                        if (!(other_mask & m)) continue;
610
                        if (out_bits[i] == VBIT_VAR) continue;
611
//                      fprintf(out, "bits[%03X:%i] = %i (%i)\n", other_codes[j], i, out_bits[i], (other_codes[j] & m)?1:0);
612
                        if (other_codes[j] & m) {
613
                                if (out_bits[i] == VBIT_UNKNOWN)
614
                                        out_bits[i] = VBIT_1;
615
                                else if (out_bits[i] != VBIT_1)
616
                                        out_bits[i] = VBIT_VAR;
617
                        } else {
618
                                if (out_bits[i] == VBIT_UNKNOWN)
619
                                        out_bits[i] = VBIT_0;
620
                                else if (out_bits[i] != VBIT_0)
621
                                        out_bits[i] = VBIT_VAR;
622
                        }
623
                }
624
        }
625
        *val = 0;
626
        for (i = 0, r = 0, m = 1, c = 0; i < N_BITS; ++i, m <<= 1) {
627
                if ((out_bits[i] == VBIT_1) || (out_bits[i] == VBIT_0)) {
628
                        r |= m;
629
                        if (out_bits[i] == VBIT_1) *val |= m;
630
                        ++ c;
631
                }
632
        }
633
        *mask = r;
634
        return c;
635
}
636
 
637
int check_full_bits(FILE*out, unsigned other_mask,
638
                const unsigned other_codes[], int n_other,
639
                unsigned sel_mask, unsigned sel_val)
640
{
641
        int i, j;
642
        unsigned m;
643
        int nv;
644
        unsigned test_codes[MAX_CODES * TIME_COUNT];
645
        int n_codes, f_codes;
646
 
647
 
648
/*      fprintf(out, "****check_full_bits: other_mask = ");
649
        print_selector(out, other_mask);
650
        fprintf(out, ", sel_mask = ");
651
        print_selector(out, sel_mask);
652
        fprintf(out, ", sel_val = ");
653
        print_selector(out, sel_val);
654
        fprintf(out, "\n");*/
655
 
656
        if (!other_mask) return 1;
657
 
658
 
659
        for (i = 0, nv = 0, m = 1; i < N_BITS; ++i, m <<= 1) {
660
                if (other_mask & m) ++ nv;
661
        }
662
        assert(nv);
663
        f_codes = 1 << nv;
664
 
665
        for (j = 0, n_codes = 0; j < n_other; ++j) {
666
                int f = 0;
667
                unsigned oc;
668
                if ((other_codes[j] & sel_mask) != sel_val) continue;
669
                oc = other_codes[j] & other_mask;
670
                for (i = 0; i < n_codes; ++i) {
671
                        if (test_codes[i] == oc) {
672
                                f = 1;
673
                                break;
674
                        }
675
                }
676
                if (f) continue;
677
        /*      fprintf(out,"uniq code: ");
678
                print_selector(out, oc);
679
                fprintf(out, "\n");        */
680
                test_codes[n_codes++] = oc;
681
                if (n_codes == f_codes) return 1;
682
        }
683
        return 0;
684
}
685
 
686
 
687
 
688
int find_common_bit(FILE*out, unsigned other_mask,
689
                const unsigned other_codes[], int n_other,
690
                unsigned sel_mask, unsigned sel_val,
691
                int nn[2], unsigned mm[2], unsigned vv[2])
692
{
693
        int counts[N_BITS][2];
694
        unsigned masks[N_BITS][2];
695
        unsigned vals[N_BITS][2];
696
//      int fulls[N_BITS][2];
697
        unsigned m, mv;
698
        int i, j;
699
        int max_count = -1;
700
        int max_bit = -1;
701
 
702
        memset(counts, 0, sizeof(counts));
703
 
704
        // print available codes
705
/*
706
        for (j = 0; j < n_other; ++j) {
707
                if ((other_codes[j] & sel_mask) != sel_val) continue;
708
                fprintf(out, "***code[%i]: ", j);
709
                print_selector(out, other_codes[j]);
710
                fprintf(out, "\n");
711
        }
712
*/
713
        // compute counts
714
/*      for (i = 0, m = 1; i < N_BITS; ++i, m <<= 1) {
715
                if (!(other_mask & m)) continue;
716
                for (j = 0; j < n_other; ++j) {
717
                        if ((other_codes[j] & sel_mask) != sel_val) continue;
718
                        ++ counts[i][(other_codes[j] & m)?1:0];
719
                }
720
        }
721
*/
722
 
723
        for (i = 0, m = 1; i < N_BITS; ++i, m <<= 1) {
724
                if (!(other_mask & m)) continue;
725
                counts[i][0] = expand_common_bits(out, other_mask,
726
                                other_codes, n_other, i, 0,
727
                                masks[i] + 0, vals[i] + 0,
728
                                sel_mask, sel_val);
729
                counts[i][1] = expand_common_bits(out, other_mask,
730
                                other_codes, n_other, i, 1,
731
                                masks[i] + 1, vals[i] + 1,
732
                                sel_mask, sel_val);
733
/*              fulls[i][0] = check_full_bits(out,
734
                                        other_mask & ~(masks[i][0] | m),
735
                                        other_codes, n_other,
736
                                        sel_mask | (masks[i][0] | m),
737
                                        sel_val | (vals[i][0]));
738
                fulls[i][1] = check_full_bits(out,
739
                                        other_mask & ~(masks[i][1] | m),
740
                                        other_codes, n_other,
741
                                        sel_mask | (masks[i][1] | m),
742
                                        sel_val | (vals[i][1] | m));*/
743
//              fprintf(out, "counts[%i] = %i, %i (%i,%i)\n", i, 
744
//                              counts[i][0], counts[i][1],
745
//                              fulls[i][0], fulls[i][1]);
746
        }
747
 
748
        for (i = 0, m = 1; i < N_BITS; ++i, m <<= 1) {
749
                if (!(other_mask & m)) continue;
750
                if (max_count < counts[i][0]) {
751
                        max_count = counts[i][0];
752
                        max_bit = i;
753
                } else if (max_count < counts[i][1]) {
754
                        max_count = counts[i][1];
755
                        max_bit = i;
756
                }
757
        }
758
        if (max_bit == -1) return -1;
759
 
760
        // compute result counts
761
        nn[0] = nn[1] = 0;
762
        mv = 1 << max_bit;
763
        for (j = 0; j < n_other; ++j) {
764
                if ((other_codes[j] & sel_mask) != sel_val) continue;
765
                if (other_codes[j] & mv) ++nn[1]; else ++nn[0];
766
        }
767
 
768
//      nn[0] = counts[max_bit][0];
769
//      nn[1] = counts[max_bit][1];
770
 
771
        mm[0] = masks[max_bit][0];
772
        mm[1] = masks[max_bit][1];
773
 
774
        vv[0] = vals[max_bit][0];
775
        vv[1] = vals[max_bit][1];
776
 
777
 
778
 
779
 
780
        // print counts
781
/*      fprintf(out, "****Counts for mask (max_bit = %i): ", max_bit);
782
        print_selector(out, other_mask);
783
        fprintf(out, "\n");
784
        for (i = 0, m = 1; i < N_BITS; ++i, m <<= 1) {
785
                if (!(other_mask & m)) continue;
786
                fprintf(out, "//\t\tbit %i: (%i, %i)\n", i, counts[i][0], counts[i][1]);
787
        }*/
788
 
789
        return max_bit;
790
}
791
 
792
 
793
int print_sel_bits(FILE*out, unsigned mask, unsigned val)
794
{
795
        int nv, rv;
796
        int i, iv, vv;
797
        unsigned m;
798
        for (i = 0, nv = 0, m = 1; i < N_BITS; ++i, m <<= 1) {
799
                if (mask & m) {
800
                        ++ nv;
801
                        iv = i;
802
                        vv = (val & m)?1:0;
803
                }
804
        }
805
        if (nv == 1) {
806
                fprintf(out, "%sL[%i]", vv?"":"!", iv);
807
                return 1;
808
        }
809
        fprintf(out, "({");
810
        for (i = 0, rv = 0, m = 1; i < N_BITS; ++i, m <<= 1) {
811
                if (mask & m) {
812
                        if (rv) fprintf(out, ",");
813
                        fprintf(out, "L[%i]", i);
814
                        ++ rv;
815
                }
816
        }
817
        fprintf(out, "} == %i'b", nv);
818
        for (i = 0, m = 1; i < N_BITS; ++i, m <<= 1) {
819
                if (mask & m) {
820
                        fprintf(out, "%c", (val & m)?'1':'0');
821
                }
822
        }
823
        fprintf(out, ")");
824
        return nv;
825
 
826
}
827
 
828
void print_other(FILE*out, unsigned other_mask, const unsigned other_codes[], int n_other, unsigned sel_mask, unsigned sel_val)
829
{
830
        int j, nn = 0;
831
        for (j = 0; j < n_other; ++j) {
832
                if ((other_codes[j] & sel_mask) != sel_val) continue;
833
//              if (!nn) fprintf(out, "(");
834
                if (nn) fprintf(out, " || ");
835
                print_sel_bits(out, other_mask, other_codes[j]);
836
                ++nn;
837
        }
838
//      if (nn) fprintf(out, ")");
839
}
840
 
841
 
842
void recurse_other(FILE*out, unsigned other_mask, const unsigned other_codes[], int n_other, unsigned sel_mask, unsigned sel_val, int level)
843
{
844
        int nn[2];
845
        unsigned mm[2], vv[2];
846
        unsigned cbm;
847
        int cb;
848
        unsigned sm0, sm1, sv0, sv1;
849
        int cf0, cf1;
850
 
851
/*      fprintf(out, "\n**recurse_other[%i]: n_other = %i, other_mask = ", level, n_other);
852
        print_selector(out, other_mask);
853
        fprintf(out, ", sel_mask = ");
854
        print_selector(out, sel_mask);
855
        fprintf(out, ", sel_val = ");
856
        print_selector(out, sel_val);
857
        fprintf(out, "\n");
858
*/
859
        if (opt_level != -1 && level >= opt_level) {
860
                print_other(out, other_mask, other_codes, n_other, sel_mask, sel_val);
861
                return;
862
        }
863
 
864
        if (!other_mask) return;
865
 
866
 
867
        cb = find_common_bit(out, other_mask, other_codes, n_other,
868
                        sel_mask, sel_val, nn, mm, vv);
869
        if (cb == -1) exit(100);
870
        cbm = 1<<cb;
871
//      expand_common_bits(out, other_mask, other_codes, n_other, cb, 0, &m0, &v0, sel_mask, sel_val);
872
//      expand_common_bits(out, other_mask, other_codes, n_other, cb, 1, &m1, &v1, sel_mask, sel_val);
873
/*      fprintf(out, "** find_common_bit: %i: ", cb);
874
        print_selector(out, mm[0]);
875
        fprintf(out, ", ");
876
        print_selector(out, mm[1]);
877
        fprintf(out, "\n");
878
*/
879
        if (cbm == other_mask && !mm[0] && !mm[1]) {
880
                fprintf(out, "1'b1");
881
                return;
882
        }
883
 
884
        mm[0] |= cbm;
885
        mm[1] |= cbm;
886
        vv[1] |= cbm;
887
 
888
        sm0 = sel_mask | mm[0];
889
        sm1 = sel_mask | mm[1];
890
 
891
        sv0 = sel_val | vv[0];
892
        sv1 = sel_val | vv[1];
893
 
894
        cf0 = check_full_bits(out, other_mask & ~mm[0], other_codes, n_other, sm0, sv0);
895
        cf1 = check_full_bits(out, other_mask & ~mm[1], other_codes, n_other, sm1, sv1);
896
 
897
//      fprintf(out, "\nnn[0] = %i, nn[1] = %i, cf0 = %i, cf1 = %i\n", nn[0], nn[1], cf0, cf1);
898
 
899
        if (nn[0]) {
900
                if (!cf0 && nn[1]) {
901
                        fprintf(out, "(");
902
                }
903
                print_sel_bits(out, mm[0], vv[0]);
904
                if (!cf0) {
905
                        fprintf(out, " && (");
906
                        recurse_other(out, other_mask & ~mm[0], other_codes, n_other, sm0, sv0, level + 1);
907
                        fprintf(out, ")");
908
                        if (nn[1]) fprintf(out, ")");
909
                }
910
                if (nn[1]) fprintf(out, " || ");
911
        }
912
        if (nn[1]) {
913
                if (!cf1 && nn[0]) {
914
                        fprintf(out, "(");
915
                }
916
                print_sel_bits(out, mm[1], vv[1]);
917
                if (!cf1) {
918
                        fprintf(out, " && (");
919
                        recurse_other(out, other_mask & ~mm[1], other_codes, n_other,  sm1, sv1, level + 1);
920
                        fprintf(out, ")");
921
                        if (nn[0]) fprintf(out, ")");
922
                }
923
        }
924
}
925
 
926
int print_verilog_line(FILE*out, const char bits[N_BITS], const char vbits[N_BITS], const int codes[MAX_CODES][MAX_TIME-MIN_TIME + 1])
927
{
928
        int i;
929
        int n_bits[4] = {0, 0, 0, 0};
930
        int common_vals[N_BITS], common_inds[N_BITS];
931
        int other_inds[N_BITS];
932
        unsigned other_mask = 0, m;
933
        unsigned other_codes[MAX_CODES * TIME_COUNT];
934
        int n_other;
935
        for (i = 0, m = 1; i < N_BITS; ++i, m <<= 1) {
936
                int n = n_bits[bits[i]] ++;
937
                switch (bits[i]) {
938
                case BIT_COMMON:
939
                        common_vals[n] = (vbits[i] == VBIT_0)?0:1;
940
                        common_inds[n] = i;
941
                        break;
942
                case BIT_OTHER:
943
                        other_inds[n] = i;
944
                        other_mask |= m;
945
                        break;
946
                }
947
        }
948
 
949
        // check for full other list
950
        if (n_bits[BIT_OTHER]) {
951
                int j, t;
952
                n_other = 0;
953
                for (j = 0; j < MAX_CODES; ++j) {
954
                        for (t = MIN_TIME; t <= MAX_TIME; ++t) {
955
                                unsigned int val = prepare_selector(j, t) & other_mask;
956
                                int r = -1;
957
                                if (codes[j][t] != CODE_ACTION) continue;
958
                                for (i = 0; i < n_other; ++i) {
959
                                        if (other_codes[i] == val) { r = i; break; }
960
                                }
961
                                if (r == -1) other_codes[n_other++] = val;
962
                        }
963
                }
964
//              fprintf(out, "//\tn_other = %i (%i)\n", n_other, 1 << n_bits[BIT_OTHER]);
965
                if (n_other == (1 << n_bits[BIT_OTHER])) n_bits[BIT_OTHER] = 0;
966
        }
967
 
968
        if (!n_bits[BIT_COMMON] && !n_bits[BIT_OTHER]) {
969
                fprintf(out, "1'b1");
970
                return 0;
971
        }
972
        if (n_bits[BIT_COMMON]) {
973
                fprintf(out, "({");
974
                for (i = 0; i < n_bits[BIT_COMMON]; ++i) {
975
                        fprintf(out, "L[%i]", common_inds[i]);
976
                        if (i < n_bits[BIT_COMMON] - 1) fprintf(out, ",");
977
                }
978
                fprintf(out, "} == %i'b", n_bits[BIT_COMMON]);
979
                for (i = 0; i < n_bits[BIT_COMMON]; ++i) {
980
                        fprintf(out, "%i", common_vals[i]);
981
                }
982
                fprintf(out, ")");
983
                if (n_bits[BIT_OTHER]) fprintf(out, " && (");
984
        }
985
        if (n_bits[BIT_OTHER]) {
986
//              fprintf(out, "(");
987
                recurse_other(out, other_mask, other_codes, n_other, 0, 0, 1);
988
//              fprintf(out, ")");
989
        }
990
        if (n_bits[BIT_COMMON]) {
991
                if (n_bits[BIT_OTHER]) fprintf(out, ")");
992
        }
993
/*      if (n_bits[BIT_OTHER]) {
994
                int j, t;
995
                fprintf(out, "(");
996
                n_other = 0;
997
                for (j = 0; j < MAX_CODES; ++j) {
998
                        for (t = MIN_TIME; t <= MAX_TIME; ++t) {
999
                                unsigned int val = prepare_selector(j, t) & other_mask;
1000
                                int r = -1;
1001
 
1002
                                if (codes[j][t] != CODE_ACTION) continue;
1003
 
1004
                                for (i = 0; i < n_other; ++i) {
1005
                                        if (other_codes[i] == val) { r = i; break; }
1006
                                }
1007
                                if (r != -1) continue;
1008
 
1009
                                if (n_other) fprintf(out, " || ");
1010
                                fprintf(out, "({");
1011
                                for (i = 0; i < n_bits[BIT_OTHER]; ++i) {
1012
                                        fprintf(out, "L[%i]", other_inds[i]);
1013
                                        if (i < n_bits[BIT_OTHER] - 1) fprintf(out, ",");
1014
                                }
1015
                                fprintf(out, "} == %i'b", n_bits[BIT_OTHER]);
1016
                                for (i = 0, m = 1; i < N_BITS; ++i, m <<= 1) {
1017
                                        if (other_mask & m) {
1018
                                                fprintf(out, "%i", (val&m)?1:0);
1019
                                        }
1020
                                }
1021
                                fprintf(out, ")");
1022
                                other_codes[n_other++] = val;
1023
                        }
1024
                }
1025
                fprintf(out, ")");
1026
        }*/
1027
        return 0;
1028
}
1029
 
1030
 
1031
int process_data(struct STATE_DATA*sd, const char*fname)
1032
{
1033
        int i, j, k, l, t;
1034
        int r;
1035
        unsigned m;
1036
        FILE*out;
1037
        int codes[MAX_CODES][TIME_COUNT];
1038
        char bits[N_BITS];
1039
        char vbits[N_BITS];
1040
        out = fopen(fname, "wt");
1041
        if (!out) {
1042
                perror(fname);
1043
                return -1;
1044
        }
1045
        fprintf(out, "// This file has been generated automatically\n"
1046
                        "//\tby the GenStates tool\n"
1047
                        "// Copyright (c) Oleg Odintsov\n"
1048
                        "// This tool is a part of Agat hardware project\n\n");
1049
 
1050
        if (opt_level == -1) {
1051
                fprintf(out, "//\tLevel of optimization: infinite\n");
1052
        } else {
1053
                fprintf(out, "//\tLevel of optimization: %i\n", opt_level);
1054
        }
1055
 
1056
        fprintf(out, "//\tTotal number of actions: %i\n", sd->n_actions);
1057
        for (i = 0; i < sd->n_actions; ++i) {
1058
                char name[MAX_STRING];
1059
                action_to_name(sd->actions[i].astr_parsed, name);
1060
                fprintf(out, "\twire %s%s;\n", (sd->actions[i].atype == ACTION_EXEC)?"E_": "A_", name);
1061
        }
1062
        fprintf(out, "\n//\tActions assignments\n");
1063
        // for all actions
1064
        for (i = 0; i < sd->n_actions; ++i) {
1065
                const char*p;
1066
                int n;
1067
                char name[MAX_STRING];
1068
                int n_active = 0;
1069
#if DEBUG
1070
                fprintf(out, "\n//\taction: %s:\n", sd->actions[i].astr);
1071
#endif
1072
                memset(codes, CODE_NONE, sizeof(codes));
1073
                // find codes with this action
1074
                for (j = 0; j < MAX_CODES; ++j) {
1075
                        for (t = MIN_TIME; t <= MAX_TIME; ++t)
1076
                                if (code_has_action(sd, j, t, i)) {
1077
                                        codes[j][t] = CODE_ACTION;
1078
                                        ++ n_active;
1079
/*#if DEBUG
1080
                                        fprintf(out, "//\t\t(%i, %02X: ", t, j);
1081
                                        print_selector(out, prepare_selector(j, t));
1082
                                        fprintf(out, ")\n");
1083
#endif*/
1084
                                }
1085
                }
1086
                if (!n_active) {
1087
                        action_to_name(sd->actions[i].astr_parsed, name);
1088
                        fprintf(out, "\tassign %s%s = 1'b0;\n", (sd->actions[i].atype == ACTION_EXEC)?"E_": "A_", name);
1089
                        continue;
1090
                }
1091
 
1092
 
1093
                // Selecting common bits@action (BIT_COMMON)
1094
                if (opt_level == 1) {
1095
                        memset(bits, BIT_COMMON, sizeof(bits));
1096
                        memset(vbits, VBIT_UNKNOWN, sizeof(vbits));
1097
                for (j = 0; j < MAX_CODES; ++j) {
1098
                        for (t = MIN_TIME; t <= MAX_TIME; ++t) {
1099
                                unsigned int val = prepare_selector(j, t);
1100
                                if (codes[j][t] != CODE_ACTION) continue;
1101
                                for (k = 0, m = 1; k < N_BITS; ++k, m<<=1) {
1102
                                        if (bits[k] != BIT_COMMON) continue;
1103
                                        if (val & m) {
1104
                                                if (vbits[k] == VBIT_UNKNOWN)
1105
                                                        vbits[k] = VBIT_1;
1106
                                                else if (vbits[k] != VBIT_1)
1107
                                                        bits[k] = BIT_OTHER;
1108
                                        } else {
1109
                                                if (vbits[k] == VBIT_UNKNOWN)
1110
                                                        vbits[k] = VBIT_0;
1111
                                                else if (vbits[k] != VBIT_0)
1112
                                                        bits[k] = BIT_OTHER;
1113
                                        }
1114
                                }
1115
                        }
1116
                }
1117
                } else {
1118
                        memset(bits, BIT_OTHER, sizeof(bits));
1119
                        memset(vbits, VBIT_UNKNOWN, sizeof(vbits));
1120
                }
1121
                // debug print
1122
/*
1123
#if DEBUG
1124
                fprintf(out, "//        %14s: ", sd->actions[i].astr);
1125
                for (k = N_BITS - 1; k >= 0; --k) {
1126
                        int c;
1127
                        if (bits[k] == BIT_COMMON) c = (vbits[k] == VBIT_0)?'0':(vbits[k] == VBIT_1)?'1':'2';
1128
                        else c = '?';
1129
                        fprintf(out, "%c", c);
1130
                        if (!(k & 7)) fprintf(out, " ");
1131
                }
1132
                fprintf(out, "\n");
1133
#endif
1134
*/
1135
                // verilog output
1136
                action_to_name(sd->actions[i].astr_parsed, name);
1137
                fprintf(out, "\tassign %s%s = ", (sd->actions[i].atype == ACTION_EXEC)?"E_": "A_", name);
1138
                print_verilog_line(out, bits, vbits, codes);
1139
                fprintf(out, ";\n");
1140
        }
1141
        fclose(out);
1142
        return 0;
1143
}
1144
 
1145
 
1146
void print_help(const char*cmd)
1147
{
1148
        printf("Use %s [-Olevel | -h] [states.txt] [states_out.txt] [states.v]\n"
1149
                "\t-h\tPrint this help;\n"
1150
                "\t-Olevel\tSpecify level of optimization (default is 1):\n"
1151
                "\t\t0 - no optimization\n"
1152
                "\t\t1 - just group common bits (default, best for hardware)\n"
1153
                "\t\t>1 - higher levels\n"
1154
                "\t\t-1 - infinite optimization (best for simulation).\n\n"
1155
                "Copyright (c) Odintsov Oleg, nnop@newmail.ru\n"
1156
                "This tool is a part of Agat hardware project.\n", cmd);
1157
        exit(100);
1158
}
1159
 
1160
struct STATE_DATA sd;
1161
 
1162
int main(int argc, const char*argv[])
1163
{
1164
        int r;
1165
        int s = 0;
1166
        if (argc > 1 && argv[1][0] == '-') {
1167
                switch (argv[1][1]) {
1168
                case '?': case 'h': case 'H': print_help(argv[0]);
1169
                case 'O':
1170
                        opt_level = atoi(argv[1] + 2);
1171
                        if (opt_level == -1) {
1172
                                printf("level of optimization: infinite\n");
1173
                        } else {
1174
                                printf("level of optimization: %i\n", opt_level);
1175
                        }
1176
                }
1177
                s = 1;
1178
        }
1179
        clear_data(&sd);
1180
        r = load_data(&sd, (argc > (s + 1))? argv[s + 1]: "states.txt");
1181
        if (r) return r;
1182
        r = validate_data(&sd);
1183
        if (r) return r;
1184
        r = write_data(&sd, (argc > (s + 2))? argv[s + 2]: "states_out.txt");
1185
        if (r) return r;
1186
        r = process_data(&sd, (argc > (s + 3))? argv[s + 3]: "states.v");
1187
        if (r) return r;
1188
        return 0;
1189
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.