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

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc2/] [or1ksim/] [cuc/] [verilog.c] - Blame information for rev 879

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

Line No. Rev Author Line
1 879 markom
/* verilog.c -- OpenRISC Custom Unit Compiler, verilog generator
2
 *    Copyright (C) 2002 Marko Mlinar, markom@opencores.org
3
 *
4
 *    This file is part of OpenRISC 1000 Architectural Simulator.
5
 *
6
 *    This program is free software; you can redistribute it and/or modify
7
 *    it under the terms of the GNU General Public License as published by
8
 *    the Free Software Foundation; either version 2 of the License, or
9
 *    (at your option) any later version.
10
 *
11
 *    This program is distributed in the hope that it will be useful,
12
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *    GNU General Public License for more details.
15
 *
16
 *    You should have received a copy of the GNU General Public License
17
 *    along with this program; if not, write to the Free Software
18
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
#include <stdio.h>
21
#include <stdlib.h>
22
#include <stdarg.h>
23
#include <assert.h>
24
#include "cuc.h"
25
#include "insn.h"
26
 
27
/* Find index of load/store */
28
int find_ls_index (cuc_func *f, int ref)
29
{
30
  int c = 0;
31
  int i;
32
  int load = II_IS_LOAD (f->INSN(ref).index);
33
  for (i = 0; i < f->nmsched; i++) {
34
    if (f->msched[i] == ref) break;
35
    if (load && (!(f->mtype[i] & MT_WRITE))
36
     || !load && (f->mtype[i] & MT_WRITE)) c++;
37
  }
38
  return c;
39
}
40
 
41
/* Print out dependencies as verilog expression */
42
void print_deps (FILE *fo, cuc_func *f, int b, dep_list *t, int registered)
43
{
44
  if (t) {
45
    int first = 0;
46
    while (t) {
47
      assert (f->INSN(t->ref).type & IT_MEMORY);
48
      fprintf (fo, "%s%c_end[%i]", first ? " && " : "",
49
                  II_IS_LOAD (f->INSN(t->ref).index) ? 'l' : 's', find_ls_index (f, t->ref));
50
      first = 1;
51
      t = t->next;
52
    }
53
  } else {
54
    if (registered) fprintf (fo, "bb_start_r[%i]", b);
55
    else fprintf (fo, "bb_start[%i]", b);
56
  }
57
}
58
 
59
char *print_op_v (cuc_func *f, char *s, int ref, int j)
60
{
61
  unsigned long op = f->INSN(ref).op[j];
62
  unsigned long opt = f->INSN(ref).opt[j];
63
  switch (opt & ~OPT_DEST) {
64
    case OPT_NONE: assert (0); break;
65
    case OPT_CONST: sprintf (s, "32'h%x", op); break;
66
    case OPT_REGISTER:
67
                    if (opt & OPT_DEST) sprintf (s, "t%x_%x", REF_BB(ref), REF_I(ref));
68
                    else sprintf (s, "r%i_%c", op, opt & OPT_DEST ? 'o' : 'i');
69
                    break;
70
    case OPT_REF:   sprintf (s, "t%x_%x", REF_BB(op), REF_I(op)); break;
71
  }
72
  return s;
73
}
74
 
75
/* Prints out specified instruction */
76
void print_insn_v (FILE *fo, cuc_func *f, int b, int i)
77
{
78
  cuc_insn *ii = &f->bb[b].insn[i];
79
  char *s = known[ii->index].rtl;
80
  char tmp[200] = "";
81
  while (*s) {
82
    if (*s <= MAX_OPERANDS) {
83
      char t[30];
84
      sprintf (tmp, "%s%s", tmp, print_op_v (f, t, REF(b, i), *s - 1));
85
    } else if (*s == '\b') sprintf (tmp, "%s%i", b);
86
    else sprintf (tmp, "%s%c", tmp, *s);
87
    s++;
88
  }
89
  fprintf (fo, "%-40s /* %s */\n", tmp, ii->disasm);
90
  if (ii->type & IT_MEMORY) {
91
    int j, nls = find_ls_index (f, REF (b, i));
92
    if (II_IS_LOAD (ii->index)) {
93
      int nm;
94
      for (nm = 0; nm < f->nmsched; nm++) if (f->msched[nm] == REF (b, i)) break;
95
      assert (nm < f->nmsched);
96
 
97
      fprintf (fo, "  if (rst) t%x_%x <= #1 32'h0;\n", b, i);
98
      fprintf (fo, "  else if (l_end[%i]) t%x_%x <= #1 ", nls, b, i);
99
      switch (f->mtype[nm] & (MT_WIDTH | MT_SIGNED)) {
100
        case 1: fprintf (fo, "lwb_dat_i & 32'hff;\n");
101
                break;
102
        case 2: fprintf (fo, "lwb_dat_i & 32'hffff;\n");
103
                break;
104
        case 4 | MT_SIGNED:
105
        case 4: fprintf (fo, "lwb_dat_i;\n");
106
                break;
107
        case 1 | MT_SIGNED:
108
                fprintf (fo, "{24{lwb_dat_i[7]}, lwb_dat_i[7:0]};\n");
109
                break;
110
        case 2 | MT_SIGNED:
111
                fprintf (fo, "{16{lwb_dat_i[15]}, lwb_dat_i[15:0]};\n");
112
                break;
113
        default: assert (0);
114
      }
115
    }
116
  } else if (ii->index == II_LRBB) {
117
    fprintf (fo, "  if (rst) t%x_%x <= #1 1'b0;\n", b, i);
118
    assert (f->bb[b].prev[0] >= 0);
119
    fprintf (fo, "  else if (bb_start[%i]) t%x_%x <= #1 bb_stb[%i];\n", b, b, i, f->bb[b].prev[0]);
120
  } else if (ii->index == II_REG) {
121
    fprintf (fo, "  if (rst) t%x_%x <= #1 32'h0;\n", b, i);
122
    assert (ii->opt[1] == OPT_REF);
123
    fprintf (fo, "  else if (");
124
    if (f->bb[b].mdep) print_deps (fo, f, b, f->bb[b].mdep, 0);
125
    else fprintf (fo, "bb_stb[%i]", b);
126
    fprintf (fo, ") t%x_%x <= #1 t%x_%x;\n",  b, i,
127
                    REF_BB (ii->op[1]), REF_I (ii->op[1]));
128
  }
129
}
130
 
131
/* Outputs binary number */
132
char *bin_str (unsigned long x, int len)
133
{
134
  static char bx[33];
135
  char *s = bx;
136
  while (len > 0) *s++ = '0' + ((x >> --len) & 1);
137
  *s = '\0';
138
  return bx;
139
}
140
 
141
/* Returns index of branch instruction inside a block b */
142
int branch_index (cuc_bb *bb)
143
{
144
  int i;
145
  for (i = bb->ninsn - 1; i >= 0; i--)
146
    if (bb->insn[i].type & IT_BRANCH) return i;
147
  return -1;
148
}
149
 
150
/* Generates verilog file out of insn dataflow */
151
void output_verilog (cuc_func *f, char *filename)
152
{
153
  FILE *fo;
154
  int used_regs[MAX_REGS] = {0};
155
  int lur[MAX_REGS] = {0};
156
  int b, i, j;
157
  int ci = 0, co = 0;
158
  int nloads = 0, nstores = 0;
159
  char tmp[256];
160
  cuc_bb *end_bb = NULL;
161
  int end_bb_no = -1;
162
  sprintf (tmp, "%s.v", filename);
163
 
164
  if ((fo = fopen (tmp, "wt+")) == NULL) {
165
    fprintf (stderr, "Cannot open '%s'\n", tmp);
166
    exit (1);
167
  }
168
 
169
  /* Determine register usage */
170
  for (i = 0; i < MAX_REGS; i++) lur[i] = -1;
171
  for (b = 0; b < f->num_bb; b++) {
172
    for (i = 0; i < f->bb[b].ninsn; i++)
173
      for (j = 0; j < MAX_OPERANDS; j++)
174
        if (f->bb[b].insn[i].opt[j] & OPT_REGISTER && f->bb[b].insn[i].op[j] >= 0)
175
          if (f->bb[b].insn[i].opt[j] & OPT_DEST) lur[f->bb[b].insn[i].op[j]] = REF (b, i);
176
          else used_regs[f->bb[b].insn[i].op[j]] = 1;
177
    if (f->bb[b].type & BB_END) end_bb = &f->bb[end_bb_no = b];
178
  }
179
  assert (end_bb && end_bb->type & BB_END);
180
 
181
  /* output header */
182
  fprintf (fo, "/* %s -- generated by OpenRISC Custom Unit Compiler (c) OpenCores */\n", tmp);
183
  fprintf (fo, "module %s (clk, rst,\n", filename);
184
  fprintf (fo, "              lwb_adr_o, lwb_dat_i, lwb_cycstb_o,\n");
185
  fprintf (fo, "              lwb_sel_o, lwb_linbrst_o, lwb_ack_i,\n");
186
  fprintf (fo, "              swb_adr_o, swb_dat_o, swb_cycstb_o,\n");
187
  fprintf (fo, "              swb_sel_o, swb_linbrst_o, swb_ack_i,\n");
188
 
189
  fprintf (fo, "/* inputs */  ");
190
  for (i = 0; i < MAX_REGS; i++)
191
    if (used_regs[i]) {
192
      fprintf (fo, "r%i_i, ", i);
193
      ci++;
194
    }
195
  if (!ci) fprintf (fo, "/* NONE */");
196
 
197
  fprintf (fo, "\n/* outputs */ ");
198
  for (i = 0; i < MAX_REGS; i++)
199
    if (lur[i] >= 0 && !f->saved_regs[i]) {
200
      fprintf (fo, "r%i_o, ", i);
201
      co++;
202
    }
203
 
204
  if (!co) fprintf (fo, "/* NONE */");
205
  fprintf (fo, "\n              start_i, end_o);\n\n");
206
 
207
  fprintf (fo, "input         clk, rst;\n");
208
  fprintf (fo, "input         start_i;\t/* Module starts when set to 1 */ \n");
209
  fprintf (fo, "output        end_o;\t/* Set when module finishes, cleared upon start_i == 1 */\n\n");
210
  fprintf (fo, "/* Bus signals */\n");
211
  fprintf (fo, "output        lwb_cycstb_o, swb_cycstb_o;\n");
212
  fprintf (fo, "input         lwb_ack_i, swb_ack_i;\n");
213
  fprintf (fo, "output  [3:0] lwb_sel_o, swb_sel_o;\n");
214
  fprintf (fo, "output [31:0] lwb_adr_o, swb_adr_o;\n");
215
  fprintf (fo, "output        lwb_linbrst_o, swb_linbrst_o;\n");
216
  fprintf (fo, "input  [31:0] lwb_dat_i;\n");
217
  fprintf (fo, "output [31:0] swb_dat_o;\n\n");
218
 
219
  fprintf (fo, "reg           lwb_cycstb_o, swb_cycstb_o;\n");
220
  fprintf (fo, "reg    [31:0] lwb_adr_o, swb_adr_o;\n");
221
  fprintf (fo, "reg     [3:0] lwb_sel_o, swb_sel_o;\n");
222
  fprintf (fo, "reg    [31:0] swb_dat_o;\n");
223
  fprintf (fo, "reg           lwb_linbrst_o, swb_linbrst_o;\n");
224
 
225
  if (ci || co) fprintf (fo, "\n/* module ports */\n");
226
  if (ci) {
227
    int first = 1;
228
    fprintf (fo, "input  [31:0]");
229
    for (i = 0; i < MAX_REGS; i++)
230
      if (used_regs[i]) {
231
        fprintf (fo, "%sr%i_i", first ? " " : ", ", i);
232
        first = 0;
233
      }
234
    fprintf (fo, ";\n");
235
  }
236
 
237
  if (co) {
238
    int first = 1;
239
    fprintf (fo, "output [31:0]");
240
    for (i = 0; i < MAX_REGS; i++)
241
      if (lur[i] >= 0 && !f->saved_regs[i]) {
242
        fprintf (fo, "%sr%i_o", first ? " " : ", ", i);
243
        first = 0;
244
      }
245
    fprintf (fo, ";\n");
246
  }
247
 
248
  /* Count loads & stores */
249
  for (i = 0; i < f->nmsched; i++)
250
    if (f->mtype[i] & MT_WRITE) nstores++;
251
    else nloads++;
252
 
253
  /* Output internal registers for loads */
254
  if (nloads) {
255
    int first = 1;
256
    fprintf (fo, "\n/* internal registers for loads */\n");
257
    for (i = 0; i < f->nmsched; i++)
258
      if (!(f->mtype[i] & MT_WRITE)) {
259
        fprintf (fo, "%st%x_%x", first ? "reg    [31:0] " : ", ",
260
                REF_BB(f->msched[i]), REF_I(f->msched[i]));
261
        first = 0;
262
      }
263
    if (!first) fprintf (fo, ";\n");
264
  }
265
 
266
  fprintf (fo, "\n/* 'zero or one' hot state machines */\n");
267
  if (nloads) fprintf (fo, "reg     [%i:0] l_stb; /* loads */\n", nloads - 1);
268
  if (nstores) fprintf (fo, "reg     [%i:0] s_stb; /* stores */\n", nstores - 1);
269
  fprintf (fo, "reg     [%i:0] bb_stb; /* basic blocks */\n", f->num_bb - 1);
270
 
271
  {
272
    int first = 1;
273
    int num = 0;
274
    fprintf (fo, "\n/* basic block condition wires */\n");
275
    for (b = 0; b < f->num_bb; b++)
276
      for (i = 0; i < f->bb[b].ninsn; i++)
277
        if (f->bb[b].insn[i].type & IT_COND
278
         && f->bb[b].insn[i].index != II_REG
279
         && f->bb[b].insn[i].index != II_LRBB) {
280
          fprintf (fo, "%st%x_%x", first ? "wire          " : ", ", b, i);
281
          if (num >= 10) {
282
            fprintf (fo, ";\n");
283
            first = 1;
284
            num = 0;
285
          } else {
286
            first = 0;
287
            num++;
288
          }
289
        }
290
    if (!first) fprintf (fo, ";\n");
291
 
292
    fprintf (fo, "\n/* forward declaration of normal wires */\n");
293
    num = 0;
294
    first = 1;
295
    for (b = 0; b < f->num_bb; b++)
296
      for (i = 0; i < f->bb[b].ninsn; i++)
297
        if (!(f->bb[b].insn[i].type & (IT_COND | IT_BRANCH))
298
         && f->bb[b].insn[i].index != II_REG
299
         && f->bb[b].insn[i].index != II_LRBB) {
300
          /* Exclude loads */
301
          if (f->bb[b].insn[i].type & IT_MEMORY && II_IS_LOAD (f->bb[b].insn[i].index)) continue;
302
          fprintf (fo, "%st%x_%x", first ? "wire   [31:0] " : ", ", b, i);
303
          if (num >= 10) {
304
            fprintf (fo, ";\n");
305
            first = 1;
306
            num = 0;
307
          } else {
308
            first = 0;
309
            num++;
310
          }
311
        }
312
    if (!first) fprintf (fo, ";\n");
313
 
314
    fprintf (fo, "\n/* forward declaration registers */\n");
315
    num = 0;
316
    first = 1;
317
    for (b = 0; b < f->num_bb; b++)
318
      for (i = 0; i < f->bb[b].ninsn; i++)
319
        if (f->bb[b].insn[i].index == II_REG
320
         && f->bb[b].insn[i].index != II_LRBB) {
321
          fprintf (fo, "%st%x_%x", first ? "reg    [31:0] " : ", ", b, i);
322
          if (num >= 10) {
323
            fprintf (fo, ";\n");
324
            first = 1;
325
            num = 0;
326
          } else {
327
            first = 0;
328
            num++;
329
          }
330
        }
331
    if (!first) fprintf (fo, ";\n");
332
 
333
    num = 0;
334
    first = 1;
335
    for (b = 0; b < f->num_bb; b++)
336
      for (i = 0; i < f->bb[b].ninsn; i++)
337
        if (f->bb[b].insn[i].index != II_REG
338
         && f->bb[b].insn[i].index == II_LRBB) {
339
          fprintf (fo, "%st%x_%x", first ? "reg           " : ", ", b, i);
340
          if (num >= 10) {
341
            fprintf (fo, ";\n");
342
            first = 1;
343
            num = 0;
344
          } else {
345
            first = 0;
346
            num++;
347
          }
348
        }
349
    if (!first) fprintf (fo, ";\n");
350
  }
351
 
352
  if (nloads || nstores) fprintf (fo, "\n/* dependencies */\n");
353
  if (nloads) fprintf (fo, "wire    [%i:0] l_end = l_stb & {%i{lwb_ack_i}};\n",
354
                  nloads - 1, nloads);
355
  if (nstores) fprintf (fo, "wire    [%i:0] s_end = s_stb & {%i{swb_ack_i}};\n",
356
                  nstores - 1, nstores);
357
 
358
  fprintf (fo, "\n/* last dependency */\n");
359
  fprintf (fo, "wire   end_o = bb_stb[%i]", end_bb_no);
360
  if (end_bb->mdep) {
361
    fprintf (fo, " && ");
362
    print_deps (fo, f, end_bb_no, end_bb->mdep, 0);
363
  }
364
  /* Is there a loop right at end? */
365
  if (end_bb->next[0] >= 0) {
366
    int bidx = branch_index (end_bb);
367
    char t[30];
368
    print_op_v (f, t, REF (end_bb_no, bidx), 1);
369
    fprintf (fo, " && !%s", t);
370
  }
371
  fprintf (fo, ";\n");
372
 
373
  fprintf (fo, "\n/* Basic block triggers */\n");
374
  fprintf (fo, "wire   [%2i:0] bb_start = {\n", f->num_bb - 1);
375
  for (b = f->num_bb - 1; b >= 0; b--) {
376
    fprintf (fo, "    /* bb_start[%2i] */ ", b);
377
    if (f->bb[b].prev[0] < 0) fprintf (fo, "start_i");
378
    else {
379
      cuc_bb *prev = &f->bb[f->bb[b].prev[0]];
380
      int t;
381
      if (prev->mdep) {
382
        print_deps (fo, f, f->bb[b].prev[0], prev->mdep, 0);
383
        fprintf (fo, " && ");
384
      }
385
      fprintf (fo, "bb_stb[%i]", f->bb[b].prev[0]);
386
      if (prev->next[0] >= 0 && prev->next[1] >= 0) {
387
        int bidx = branch_index (&f->bb[f->bb[b].prev[0]]);
388
        assert (bidx >= 0);
389
        fprintf (fo, " && ");
390
        t = prev->next[0] == b;
391
        fprintf (fo, "%st%x_%x", t ? "" : "!", f->bb[b].prev[0], bidx);
392
      }
393
      if (f->bb[b].prev[1] >= 0) {
394
        prev = &f->bb[f->bb[b].prev[1]];
395
        fprintf (fo, "\n                    || ");
396
        if (prev->mdep) {
397
          print_deps (fo, f, f->bb[b].prev[1], prev->mdep, 0);
398
          fprintf (fo, " && ");
399
        }
400
        fprintf (fo, "bb_stb[%i]", f->bb[b].prev[1]);
401
        if (prev->next[0] >= 0 && prev->next[1] >= 0) {
402
          int bidx = branch_index (&f->bb[f->bb[b].prev[1]]);
403
          assert (bidx >= 0);
404
          fprintf (fo, " && ");
405
          t = prev->next[0] == b;
406
          fprintf (fo, "%st%x_%x", t ? "" : "!", f->bb[b].prev[1], bidx);
407
        }
408
      }
409
    }
410
    if (b == 0) fprintf (fo, "};\n");
411
    else fprintf (fo, ",\n");
412
  }
413
 
414
  fprintf (fo, "\n/* Register the bb_start */\n");
415
  fprintf (fo, "reg   [%2i:0] bb_start_r;\n\n", f->num_bb - 1);
416
  fprintf (fo, "always @(posedge rst or posedge clk)\n");
417
  fprintf (fo, "begin\n");
418
  fprintf (fo, "  if (rst || end_o) bb_start_r <= #1 %i'b0;\n", f->num_bb);
419
  fprintf (fo, "  else bb_start_r <= #1 bb_start;\n");
420
  fprintf (fo, "end\n");
421
 
422
  fprintf (fo, "\n/* Logic */\n");
423
  /* output body */
424
  for (b = 0; b < f->num_bb; b++) {
425
    fprintf (fo, "\t\t/* BB%i */\n", b);
426
    for (i = 0; i < f->bb[b].ninsn; i++)
427
      print_insn_v (fo, f, b, i);
428
    fprintf (fo, "\n");
429
  }
430
 
431
  if (co) {
432
    fprintf (fo, "\n/* Outputs */\n");
433
    for (i = 0; i < MAX_REGS; i++)
434
      if (lur[i] >= 0 && !f->saved_regs[i])
435
        fprintf (fo, "assign r%i_o = t%x_%x;\n", i, REF_BB(lur[i]),
436
                        REF_I(lur[i]));
437
  }
438
 
439
  if (nstores) {
440
    int cur_store = 0;
441
    fprintf (fo, "\n/* Memory stores */\n");
442
    fprintf (fo, "always @(posedge clk or posedge rst)\nbegin\n");
443
    fprintf (fo, "  if (rst) swb_dat_o <= #1 32'h0;\n");
444
    for (i = 0; i < f->nmsched; i++)
445
      if (f->mtype[i] & MT_WRITE) {
446
        char t[30];
447
        fprintf (fo, "  else if (s_stb[%i]) swb_dat_o <= #1 %s;\n", cur_store++,
448
                        print_op_v (f, t, f->msched[i], 0));
449
        //printf ("msched[%i] = %x (mtype %x) %x\n", i, f->msched[i], f->mtype[i], f->INSN(f->msched[i]).op[0]);
450
      }
451
    fprintf (fo, "end\n");
452
  }
453
 
454
  if (nloads) {
455
    int cur_load = 0;
456
    fprintf (fo, "\n/* Load state machine */\n");
457
    fprintf (fo, "always @(posedge clk or posedge rst)\n");
458
    fprintf (fo, "begin\n");
459
    fprintf (fo, "  if (rst) begin\n");
460
    fprintf (fo, "    l_stb <= #1 %i'h0;\n", nloads);
461
    fprintf (fo, "    lwb_cycstb_o <= #1 1'b0;\n");
462
    fprintf (fo, "    lwb_sel_o[3:0] <= #1 4'b0000;\n");
463
    fprintf (fo, "    lwb_linbrst_o <= #1 1'b0;\n");
464
    fprintf (fo, "    lwb_adr_o <= #1 32'h0;\n");
465
    fprintf (fo, "  end else begin\n");
466
    printf ("loads \n");
467
    for (i = 0; i < f->nmsched; i++) if (!(f->mtype[i] & MT_WRITE)) {
468
      char t[30];
469
      dep_list *dep = f->INSN(f->msched[i]).dep;
470
      printf ("msched[%i] = %x (mtype %x)\n", i, f->msched[i], f->mtype[i]);
471
      assert (f->INSN(f->msched[i]).opt[1] & (OPT_REF | OPT_REGISTER));
472
      fprintf (fo, "    if (");
473
      print_deps (fo, f, REF_BB(f->msched[i]), f->INSN(f->msched[i]).dep, 1);
474
      fprintf (fo, ") begin\n");
475
      while (dep) {
476
        assert (f->INSN(dep->ref).type & IT_MEMORY);
477
        fprintf (fo, "      %c_end[%i] <= #1 1'b0;\n",
478
                  II_IS_LOAD (f->INSN(dep->ref).index) ? 'l' : 's', find_ls_index (f, dep->ref));
479
        dep = dep->next;
480
      }
481
      fprintf (fo, "      l_stb[%i] <= #1 1'b1;\n", cur_load++);
482
      fprintf (fo, "      lwb_cycstb_o <= #1 1'b1;\n");
483
      fprintf (fo, "      lwb_sel_o[3:0] <= #1 4'b");
484
      switch (f->mtype[i] & MT_WIDTH) {
485
        case 1: fprintf (fo, "0001 << (%s & 32h'3);\n",
486
                                print_op_v (f, t, f->msched[i], 1)); break;
487
        case 2: fprintf (fo, "0011 << ((%s & 32h'1) << 1);\n",
488
                                print_op_v (f, t, f->msched[i], 1)); break;
489
        case 4: fprintf (fo, "1111;\n"); break;
490
        default: assert (0);
491
      }
492
      fprintf (fo, "      lwb_linbrst_o <= #1 1'b%i;\n",
493
                      (f->mtype[i] & MT_BURST) && !(f->mtype[i] & MT_BURSTE) ? 1 : 0);
494
      fprintf (fo, "      lwb_adr_o <= #1 t%x_%x & ~32'h3;\n",
495
                      REF_BB(f->INSN(f->msched[i]).op[1]), REF_I(f->INSN(f->msched[i]).op[1]));
496
      fprintf (fo, "    end\n");
497
    }
498
    fprintf (fo, "    if (l_end[%i]) begin\n", nloads - 1);
499
    fprintf (fo, "      l_stb <= #1 %i'h0;\n", nloads);
500
    fprintf (fo, "      lwb_cycstb_o <= #1 1'b0;\n");
501
    fprintf (fo, "      lwb_sel_o[3:0] <= #1 4'b0000;\n");
502
    fprintf (fo, "      lwb_linbrst_o <= #1 1'b0;\n");
503
    fprintf (fo, "      lwb_adr_o <= #1 32'h0;\n");
504
    fprintf (fo, "    end\n");
505
    fprintf (fo, "  end\n");
506
    fprintf (fo, "end\n");
507
  }
508
 
509
  if (nstores) {
510
    int cur_store = 0;
511
    fprintf (fo, "\n/* Store state machine */\n");
512
    fprintf (fo, "always @(posedge clk or posedge rst)\n");
513
    fprintf (fo, "begin\n");
514
    fprintf (fo, "  if (rst) begin\n");
515
    fprintf (fo, "    s_stb <= #1 %i'h0;\n", nstores);
516
    fprintf (fo, "    swb_cycstb_o <= #1 1'b0;\n");
517
    fprintf (fo, "    swb_sel_o[3:0] <= #1 4'b0000;\n");
518
    fprintf (fo, "    swb_linbrst_o <= #1 1'b0;\n");
519
    fprintf (fo, "    swb_adr_o <= #1 32'h0;\n");
520
    fprintf (fo, "  end else begin\n");
521
    printf ("stores \n");
522
    for (i = 0; i < f->nmsched; i++) if (f->mtype[i] & MT_WRITE) {
523
      char t[30];
524
      dep_list *dep = f->INSN(f->msched[i]).dep;
525
      printf ("msched[%i] = %x (mtype %x)\n", i, f->msched[i], f->mtype[i]);
526
      assert (f->INSN(f->msched[i]).opt[1] & (OPT_REF | OPT_REGISTER));
527
      fprintf (fo, "    if (");
528
      print_deps (fo, f, REF_BB(f->msched[i]), f->INSN(f->msched[i]).dep, 1);
529
      fprintf (fo, ") begin\n");
530
      while (dep) {
531
        assert (f->INSN(dep->ref).type & IT_MEMORY);
532
        fprintf (fo, "      %c_end[%i] <= #1 1'b0;\n",
533
                  II_IS_LOAD (f->INSN(dep->ref).index) ? 'l' : 's', find_ls_index (f, dep->ref));
534
        dep = dep->next;
535
      }
536
      fprintf (fo, "      s_stb[%i] <= #1 1'b1;\n", cur_store++);
537
      fprintf (fo, "      swb_cycstb_o <= #1 1'b1;\n");
538
      fprintf (fo, "      swb_sel_o[3:0] <= #1 4'b");
539
      switch (f->mtype[i] & MT_WIDTH) {
540
        case 1: fprintf (fo, "0001 << (%i & 32h'3);\n",
541
                                print_op_v (f, t, f->msched[i], 1)); break;
542
        case 2: fprintf (fo, "0011 << ((%i & 32h'1) << 1);\n",
543
                                print_op_v (f, t, f->msched[i], 1)); break;
544
        case 4: fprintf (fo, "1111;\n"); break;
545
        default: assert (0);
546
      }
547
      fprintf (fo, "      swb_linbrst_o <= #1 1'b%i;\n",
548
                      (f->mtype[i] & MT_BURST) && !(f->mtype[i] & MT_BURSTE) ? 1 : 0);
549
      fprintf (fo, "      swb_adr_o <= #1 t%x_%x & ~32'h3;\n",
550
                      REF_BB(f->INSN(f->msched[i]).op[1]), REF_I(f->INSN(f->msched[i]).op[1]));
551
      fprintf (fo, "    end\n");
552
    }
553
    fprintf (fo, "    if (s_end[%i]) begin\n", nstores - 1);
554
    fprintf (fo, "      s_stb <= #1 %i'h0;\n", nstores);
555
    fprintf (fo, "      swb_cycstb_o <= #1 1'b0;\n");
556
    fprintf (fo, "      swb_sel_o[3:0] <= #1 4'b0000;\n");
557
    fprintf (fo, "      swb_linbrst_o <= #1 1'b0;\n");
558
    fprintf (fo, "      swb_adr_o <= #1 32'h0;\n");
559
    fprintf (fo, "    end\n");
560
    fprintf (fo, "  end\n");
561
    fprintf (fo, "end\n");
562
  }
563
 
564
  fprintf (fo, "\n/* Basic blocks state machine */\n");
565
  fprintf (fo, "always @(posedge clk or posedge rst)\n");
566
  fprintf (fo, "begin\n");
567
  fprintf (fo, "  if (rst || end_o) begin\n");
568
  fprintf (fo, "    bb_stb <= #1 %i'h%x;\n", f->num_bb, 0);
569
  for (i = 0; i < f->num_bb; i++) {
570
    fprintf (fo, "  end else if (bb_start[%i]) begin\n", i);
571
    fprintf (fo, "    bb_stb <= #1 %i'h%x;\n", f->num_bb, 1 << i);
572
  }
573
  fprintf (fo, "  end else if (end_o) begin\n");
574
  fprintf (fo, "    bb_stb <= #1 %i'h%x;\n", f->num_bb, 0);
575
  fprintf (fo, "  end\n");
576
  fprintf (fo, "end\n");
577
 
578
  /* output footer */
579
  fprintf (fo, "\nendmodule\n");
580
 
581
  fclose (fo);
582
}
583
 

powered by: WebSVN 2.1.0

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