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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_36/] [or1ksim/] [cuc/] [verilog.c] - Blame information for rev 906

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

powered by: WebSVN 2.1.0

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