Line 22... |
Line 22... |
#include <stdarg.h>
|
#include <stdarg.h>
|
#include <assert.h>
|
#include <assert.h>
|
#include "cuc.h"
|
#include "cuc.h"
|
#include "insn.h"
|
#include "insn.h"
|
|
|
/* Find index of load/store */
|
/* returns log2(x) */
|
int find_ls_index (cuc_func *f, int ref)
|
int log2 (unsigned long x)
|
|
{
|
|
int c = 0;
|
|
assert (x >= 0);
|
|
if (!x) return 0; /* not by the book, but practical */
|
|
while (x != 1) x >>= 1, c++;
|
|
return c;
|
|
}
|
|
|
|
/* Find index of load/store/call */
|
|
int find_lsc_index (cuc_func *f, int ref)
|
{
|
{
|
int c = 0;
|
int c = 0;
|
int i;
|
int i;
|
int load = II_IS_LOAD (f->INSN(ref).index);
|
int load;
|
|
|
|
if (f->INSN(ref).index == II_CALL) {
|
for (i = 0; i < f->nmsched; i++) {
|
for (i = 0; i < f->nmsched; i++) {
|
if (f->msched[i] == ref) break;
|
if (f->msched[i] == ref) break;
|
if (load && (!(f->mtype[i] & MT_WRITE))
|
if (f->mtype[i] & MT_CALL) c++;
|
|| !load && (f->mtype[i] & MT_WRITE)) c++;
|
}
|
|
} else {
|
|
load = II_IS_LOAD (f->INSN(ref).index);
|
|
for (i = 0; i < f->nmsched; i++) {
|
|
if (f->msched[i] == ref) break;
|
|
if (load && (f->mtype[i] & MT_LOAD)
|
|
|| !load && (f->mtype[i] & MT_STORE)) c++;
|
|
}
|
}
|
}
|
return c;
|
return c;
|
}
|
}
|
|
|
/* Print out dependencies as verilog expression */
|
/* Print out dependencies as verilog expression */
|
void print_deps (FILE *fo, cuc_func *f, int b, dep_list *t, int registered)
|
void print_deps (FILE *fo, cuc_func *f, int b, dep_list *t, int registered)
|
{
|
{
|
if (t) {
|
if (t) {
|
int first = 0;
|
int first = 0;
|
while (t) {
|
while (t) {
|
if (!(f->INSN(t->ref).type & IT_MEMORY)) printf ("print_deps: err %x\n", t->ref);
|
if (f->INSN(t->ref).type & IT_MEMORY) {
|
assert (f->INSN(t->ref).type & IT_MEMORY);
|
|
fprintf (fo, "%s%c_end[%i]", first ? " && " : "",
|
fprintf (fo, "%s%c_end[%i]", first ? " && " : "",
|
II_IS_LOAD (f->INSN(t->ref).index) ? 'l' : 's', find_ls_index (f, t->ref));
|
II_IS_LOAD (f->INSN(t->ref).index) ? 'l' : 's', find_lsc_index (f, t->ref));
|
|
} else if (f->INSN(t->ref).index == II_CALL) {
|
|
int x;
|
|
fprintf (fo, "%sf_end[%i]", first ? " && " : "", find_lsc_index (f, t->ref));
|
|
} else {
|
|
printf ("print_deps: err %x\n", t->ref);
|
|
assert (0);
|
|
}
|
first = 1;
|
first = 1;
|
t = t->next;
|
t = t->next;
|
}
|
}
|
} else {
|
} else {
|
if (registered) fprintf (fo, "bb_start_r[%i]", b);
|
if (registered) fprintf (fo, "bb_start_r[%i]", b);
|
Line 70... |
Line 95... |
break;
|
break;
|
case OPT_REGISTER:
|
case OPT_REGISTER:
|
if (opt & OPT_DEST) sprintf (s, "t%x_%x", REF_BB(ref), REF_I(ref));
|
if (opt & OPT_DEST) sprintf (s, "t%x_%x", REF_BB(ref), REF_I(ref));
|
else sprintf (s, "r%i_%c", op, opt & OPT_DEST ? 'o' : 'i');
|
else sprintf (s, "r%i_%c", op, opt & OPT_DEST ? 'o' : 'i');
|
break;
|
break;
|
|
#if 0
|
|
case OPT_FREG: assert (opt & OPT_DEST);
|
|
sprintf (s, "fr%i_o", op);
|
|
break;
|
|
#endif
|
case OPT_REF: sprintf (s, "t%x_%x", REF_BB(op), REF_I(op)); break;
|
case OPT_REF: sprintf (s, "t%x_%x", REF_BB(op), REF_I(op)); break;
|
}
|
}
|
return s;
|
return s;
|
}
|
}
|
|
|
Line 92... |
Line 122... |
else sprintf (tmp, "%s%c", tmp, *s);
|
else sprintf (tmp, "%s%c", tmp, *s);
|
s++;
|
s++;
|
}
|
}
|
fprintf (fo, "%-40s /* %s */\n", tmp, ii->disasm);
|
fprintf (fo, "%-40s /* %s */\n", tmp, ii->disasm);
|
if (ii->type & IT_MEMORY) {
|
if (ii->type & IT_MEMORY) {
|
int j, nls = find_ls_index (f, REF (b, i));
|
int j, nls = find_lsc_index (f, REF (b, i));
|
if (II_IS_LOAD (ii->index)) {
|
if (II_IS_LOAD (ii->index)) {
|
int nm;
|
int nm;
|
for (nm = 0; nm < f->nmsched; nm++) if (f->msched[nm] == REF (b, i)) break;
|
for (nm = 0; nm < f->nmsched; nm++) if (f->msched[nm] == REF (b, i)) break;
|
assert (nm < f->nmsched);
|
assert (nm < f->nmsched);
|
|
|
Line 133... |
Line 163... |
REF_BB (ii->op[1]), REF_I (ii->op[1]));
|
REF_BB (ii->op[1]), REF_I (ii->op[1]));
|
}
|
}
|
}
|
}
|
|
|
/* Outputs binary number */
|
/* Outputs binary number */
|
char *bin_str (unsigned long x, int len)
|
static char *bin_str (unsigned long x, int len)
|
{
|
{
|
static char bx[33];
|
static char bx[33];
|
char *s = bx;
|
char *s = bx;
|
while (len > 0) *s++ = '0' + ((x >> --len) & 1);
|
while (len > 0) *s++ = '0' + ((x >> --len) & 1);
|
*s = '\0';
|
*s = '\0';
|
return bx;
|
return bx;
|
}
|
}
|
|
|
/* Returns index of branch instruction inside a block b */
|
/* Returns index of branch instruction inside a block b */
|
int branch_index (cuc_bb *bb)
|
static int branch_index (cuc_bb *bb)
|
{
|
{
|
int i;
|
int i;
|
for (i = bb->ninsn - 1; i >= 0; i--)
|
for (i = bb->ninsn - 1; i >= 0; i--)
|
if (bb->insn[i].type & IT_BRANCH) return i;
|
if (bb->insn[i].type & IT_BRANCH) return i;
|
return -1;
|
return -1;
|
}
|
}
|
|
|
|
static void print_turn_off_dep (FILE *fo, cuc_func *f, dep_list *dep)
|
|
{
|
|
while (dep) {
|
|
assert (f->INSN(dep->ref).type & IT_MEMORY || f->INSN(dep->ref).index == II_CALL);
|
|
fprintf (fo, " %c_stb[%i] <= #1 1'b0;\n", f->INSN(dep->ref).index == II_CALL ? 'f'
|
|
: II_IS_LOAD (f->INSN(dep->ref).index) ? 'l' : 's', find_lsc_index (f, dep->ref));
|
|
dep = dep->next;
|
|
}
|
|
}
|
|
|
|
static int func_index (cuc_func *f, int ref)
|
|
{
|
|
int i;
|
|
unsigned long addr;
|
|
assert (f->INSN(ref).index == II_CALL && f->INSN(ref).opt[0] & OPT_CONST);
|
|
addr = f->INSN(ref).op[0];
|
|
for (i = 0; i < f->nfdeps; i++)
|
|
if (f->fdeps[i]->start_addr == addr) return i;
|
|
|
|
assert (0);
|
|
return -1;
|
|
}
|
|
|
/* Generates verilog file out of insn dataflow */
|
/* Generates verilog file out of insn dataflow */
|
void output_verilog (cuc_func *f, char *filename)
|
void output_verilog (cuc_func *f, char *filename)
|
{
|
{
|
FILE *fo;
|
FILE *fo;
|
int b, i, j;
|
int b, i, j;
|
int ci = 0, co = 0;
|
int ci = 0, co = 0;
|
int nloads = 0, nstores = 0;
|
int nloads = 0, nstores = 0, ncalls = 0;
|
char tmp[256];
|
char tmp[256];
|
cuc_bb *end_bb = NULL;
|
cuc_bb *end_bb = NULL;
|
int end_bb_no = -1;
|
int end_bb_no = -1;
|
sprintf (tmp, "%s.v", filename);
|
sprintf (tmp, "%s.v", filename);
|
|
|
Line 202... |
Line 255... |
fprintf (fo, "r%i_o, ", i);
|
fprintf (fo, "r%i_o, ", i);
|
co++;
|
co++;
|
}
|
}
|
|
|
if (!co) fprintf (fo, "/* NONE */");
|
if (!co) fprintf (fo, "/* NONE */");
|
|
if (f->nfdeps) {
|
|
fprintf (fo, "\n/* f. calls */, fstart_o, %sfend_i, fr11_i, ",
|
|
log2 (f->nfdeps) > 0 ? "fid_o, " : "");
|
|
for (i = 0; i < 6; i++) fprintf (fo, "fr%i_o, ", i + 3);
|
|
}
|
fprintf (fo, "\n start_i, end_o);\n\n");
|
fprintf (fo, "\n start_i, end_o);\n\n");
|
|
|
fprintf (fo, "input clk, rst;\n");
|
fprintf (fo, "input clk, rst;\n");
|
fprintf (fo, "input start_i;\t/* Module starts when set to 1 */ \n");
|
fprintf (fo, "input start_i;\t/* Module starts when set to 1 */ \n");
|
fprintf (fo, "output end_o;\t/* Set when module finishes, cleared upon start_i == 1 */\n\n");
|
fprintf (fo, "output end_o;\t/* Set when module finishes, cleared upon start_i == 1 */\n\n");
|
Line 245... |
Line 303... |
first = 0;
|
first = 0;
|
}
|
}
|
fprintf (fo, ";\n");
|
fprintf (fo, ";\n");
|
}
|
}
|
|
|
|
if (f->nfdeps) {
|
|
fprintf (fo, "\n/* Function calls */\n");
|
|
fprintf (fo, "output [31:0] fr3_o");
|
|
for (i = 1; i < 6; i++) fprintf (fo, ", fr%i_o", i + 3);
|
|
fprintf (fo, ";\n");
|
|
if (log2(f->nfdeps) > 0) fprintf (fo, "output [%i:0] fid_o;\n", log2(f->nfdeps));
|
|
fprintf (fo, "output fstart_o;\n");
|
|
fprintf (fo, "input fend_i;\n");
|
|
}
|
|
|
/* Count loads & stores */
|
/* Count loads & stores */
|
for (i = 0; i < f->nmsched; i++)
|
for (i = 0; i < f->nmsched; i++)
|
if (f->mtype[i] & MT_WRITE) nstores++;
|
if (f->mtype[i] & MT_STORE) nstores++;
|
else nloads++;
|
else if (f->mtype[i] & MT_LOAD) nloads++;
|
|
else if (f->mtype[i] & MT_CALL) ncalls++;
|
|
|
/* Output internal registers for loads */
|
/* Output internal registers for loads */
|
if (nloads) {
|
if (nloads) {
|
int first = 1;
|
int first = 1;
|
int num = 0;
|
int num = 0;
|
fprintf (fo, "\n/* internal registers for loads */\n");
|
fprintf (fo, "\n/* internal registers for loads */\n");
|
for (i = 0; i < f->nmsched; i++)
|
for (i = 0; i < f->nmsched; i++)
|
if (!(f->mtype[i] & MT_WRITE)) {
|
if (f->mtype[i] & MT_LOAD) {
|
fprintf (fo, "%st%x_%x", first ? "reg [31:0] " : ", ",
|
fprintf (fo, "%st%x_%x", first ? "reg [31:0] " : ", ",
|
REF_BB(f->msched[i]), REF_I(f->msched[i]));
|
REF_BB(f->msched[i]), REF_I(f->msched[i]));
|
|
|
if (num >= 8) {
|
if (num >= 8) {
|
fprintf (fo, ";\n");
|
fprintf (fo, ";\n");
|
Line 272... |
Line 341... |
}
|
}
|
}
|
}
|
if (!first) fprintf (fo, ";\n");
|
if (!first) fprintf (fo, ";\n");
|
}
|
}
|
|
|
|
/* Internal register for function return value */
|
|
if (f->nfdeps) {
|
|
fprintf (fo, "\n/* Internal register for function return value */\n");
|
|
fprintf (fo, "reg [31:0] fr11_r;\n");
|
|
}
|
|
|
fprintf (fo, "\n/* 'zero or one' hot state machines */\n");
|
fprintf (fo, "\n/* 'zero or one' hot state machines */\n");
|
if (nloads) fprintf (fo, "reg [%i:0] l_stb; /* loads */\n", nloads - 1);
|
if (nloads) fprintf (fo, "reg [%i:0] l_stb; /* loads */\n", nloads - 1);
|
if (nstores) fprintf (fo, "reg [%i:0] s_stb; /* stores */\n", nstores - 1);
|
if (nstores) fprintf (fo, "reg [%i:0] s_stb; /* stores */\n", nstores - 1);
|
fprintf (fo, "reg [%i:0] bb_stb; /* basic blocks */\n", f->num_bb - 1);
|
fprintf (fo, "reg [%i:0] bb_stb; /* basic blocks */\n", f->num_bb - 1);
|
|
|
Line 363... |
Line 438... |
if (nloads || nstores) fprintf (fo, "\n/* dependencies */\n");
|
if (nloads || nstores) fprintf (fo, "\n/* dependencies */\n");
|
if (nloads) fprintf (fo, "wire [%i:0] l_end = l_stb & {%i{lwb_ack_i}};\n",
|
if (nloads) fprintf (fo, "wire [%i:0] l_end = l_stb & {%i{lwb_ack_i}};\n",
|
nloads - 1, nloads);
|
nloads - 1, nloads);
|
if (nstores) fprintf (fo, "wire [%i:0] s_end = s_stb & {%i{swb_ack_i}};\n",
|
if (nstores) fprintf (fo, "wire [%i:0] s_end = s_stb & {%i{swb_ack_i}};\n",
|
nstores - 1, nstores);
|
nstores - 1, nstores);
|
|
if (ncalls) fprintf (fo, "wire [%i:0] f_end = f_stb & {%i{fend_i}};\n",
|
|
ncalls - 1, ncalls);
|
|
|
fprintf (fo, "\n/* last dependency */\n");
|
fprintf (fo, "\n/* last dependency */\n");
|
fprintf (fo, "wire end_o = bb_stb[%i]", end_bb_no);
|
fprintf (fo, "wire end_o = bb_stb[%i]", end_bb_no);
|
if (end_bb->mdep) {
|
if (end_bb->mdep) {
|
fprintf (fo, " && ");
|
fprintf (fo, " && ");
|
print_deps (fo, f, end_bb_no, end_bb->mdep, 0);
|
print_deps (fo, f, end_bb_no, end_bb->mdep, 0);
|
}
|
}
|
|
|
/* Is there a loop right at end? */
|
/* Is there a loop right at end? */
|
if (end_bb->next[0] >= 0) {
|
if (end_bb->next[0] >= 0) {
|
int bidx = branch_index (end_bb);
|
int bidx = branch_index (end_bb);
|
char t[30];
|
char t[30];
|
print_op_v (f, t, REF (end_bb_no, bidx), 1);
|
print_op_v (f, t, REF (end_bb_no, bidx), 1);
|
Line 452... |
Line 530... |
int cur_store = 0;
|
int cur_store = 0;
|
fprintf (fo, "\n/* Memory stores */\n");
|
fprintf (fo, "\n/* Memory stores */\n");
|
fprintf (fo, "always @(posedge clk or posedge rst)\nbegin\n");
|
fprintf (fo, "always @(posedge clk or posedge rst)\nbegin\n");
|
fprintf (fo, " if (rst) swb_dat_o <= #1 32'h0;\n");
|
fprintf (fo, " if (rst) swb_dat_o <= #1 32'h0;\n");
|
for (i = 0; i < f->nmsched; i++)
|
for (i = 0; i < f->nmsched; i++)
|
if (f->mtype[i] & MT_WRITE) {
|
if (f->mtype[i] & MT_STORE) {
|
char t[30];
|
char t[30];
|
fprintf (fo, " else if (s_stb[%i]) swb_dat_o <= #1 %s;\n", cur_store++,
|
fprintf (fo, " else if (s_stb[%i]) swb_dat_o <= #1 %s;\n", cur_store++,
|
print_op_v (f, t, f->msched[i], 0));
|
print_op_v (f, t, f->msched[i], 0));
|
//printf ("msched[%i] = %x (mtype %x) %x\n", i, f->msched[i], f->mtype[i], f->INSN(f->msched[i]).op[0]);
|
//printf ("msched[%i] = %x (mtype %x) %x\n", i, f->msched[i], f->mtype[i], f->INSN(f->msched[i]).op[0]);
|
}
|
}
|
Line 474... |
Line 552... |
fprintf (fo, " lwb_sel_o[3:0] <= #1 4'b0000;\n");
|
fprintf (fo, " lwb_sel_o[3:0] <= #1 4'b0000;\n");
|
fprintf (fo, " lwb_linbrst_o <= #1 1'b0;\n");
|
fprintf (fo, " lwb_linbrst_o <= #1 1'b0;\n");
|
fprintf (fo, " lwb_adr_o <= #1 32'h0;\n");
|
fprintf (fo, " lwb_adr_o <= #1 32'h0;\n");
|
fprintf (fo, " end else begin\n");
|
fprintf (fo, " end else begin\n");
|
cucdebug (1, "loads \n");
|
cucdebug (1, "loads \n");
|
for (i = 0; i < f->nmsched; i++) if (!(f->mtype[i] & MT_WRITE)) {
|
for (i = 0; i < f->nmsched; i++) if (f->mtype[i] & MT_LOAD) {
|
char t[30];
|
char t[30];
|
dep_list *dep = f->INSN(f->msched[i]).dep;
|
dep_list *dep = f->INSN(f->msched[i]).dep;
|
cucdebug (1, "msched[%i] = %x (mtype %x)\n", i, f->msched[i], f->mtype[i]);
|
cucdebug (1, "msched[%i] = %x (mtype %x)\n", i, f->msched[i], f->mtype[i]);
|
assert (f->INSN(f->msched[i]).opt[1] & (OPT_REF | OPT_REGISTER));
|
assert (f->INSN(f->msched[i]).opt[1] & (OPT_REF | OPT_REGISTER));
|
fprintf (fo, " if (");
|
fprintf (fo, " if (");
|
print_deps (fo, f, REF_BB(f->msched[i]), f->INSN(f->msched[i]).dep, 1);
|
print_deps (fo, f, REF_BB(f->msched[i]), f->INSN(f->msched[i]).dep, 1);
|
fprintf (fo, ") begin\n");
|
fprintf (fo, ") begin\n");
|
while (dep) {
|
print_turn_off_dep (fo, f, dep);
|
assert (f->INSN(dep->ref).type & IT_MEMORY);
|
|
fprintf (fo, " %c_stb[%i] <= #1 1'b0;\n",
|
|
II_IS_LOAD (f->INSN(dep->ref).index) ? 'l' : 's', find_ls_index (f, dep->ref));
|
|
dep = dep->next;
|
|
}
|
|
fprintf (fo, " l_stb[%i] <= #1 1'b1;\n", cur_load++);
|
fprintf (fo, " l_stb[%i] <= #1 1'b1;\n", cur_load++);
|
fprintf (fo, " lwb_cycstb_o <= #1 1'b1;\n");
|
fprintf (fo, " lwb_cycstb_o <= #1 1'b1;\n");
|
fprintf (fo, " lwb_sel_o[3:0] <= #1 4'b");
|
fprintf (fo, " lwb_sel_o[3:0] <= #1 4'b");
|
switch (f->mtype[i] & MT_WIDTH) {
|
switch (f->mtype[i] & MT_WIDTH) {
|
case 1: fprintf (fo, "0001 << (%s & 32'h3);\n",
|
case 1: fprintf (fo, "0001 << (%s & 32'h3);\n",
|
Line 529... |
Line 602... |
fprintf (fo, " swb_sel_o[3:0] <= #1 4'b0000;\n");
|
fprintf (fo, " swb_sel_o[3:0] <= #1 4'b0000;\n");
|
fprintf (fo, " swb_linbrst_o <= #1 1'b0;\n");
|
fprintf (fo, " swb_linbrst_o <= #1 1'b0;\n");
|
fprintf (fo, " swb_adr_o <= #1 32'h0;\n");
|
fprintf (fo, " swb_adr_o <= #1 32'h0;\n");
|
fprintf (fo, " end else begin\n");
|
fprintf (fo, " end else begin\n");
|
cucdebug (1, "stores \n");
|
cucdebug (1, "stores \n");
|
for (i = 0; i < f->nmsched; i++) if (f->mtype[i] & MT_WRITE) {
|
for (i = 0; i < f->nmsched; i++) if (f->mtype[i] & MT_STORE) {
|
char t[30];
|
char t[30];
|
dep_list *dep = f->INSN(f->msched[i]).dep;
|
dep_list *dep = f->INSN(f->msched[i]).dep;
|
cucdebug (1, "msched[%i] = %x (mtype %x)\n", i, f->msched[i], f->mtype[i]);
|
cucdebug (1, "msched[%i] = %x (mtype %x)\n", i, f->msched[i], f->mtype[i]);
|
assert (f->INSN(f->msched[i]).opt[1] & (OPT_REF | OPT_REGISTER));
|
assert (f->INSN(f->msched[i]).opt[1] & (OPT_REF | OPT_REGISTER));
|
fprintf (fo, " if (");
|
fprintf (fo, " if (");
|
print_deps (fo, f, REF_BB(f->msched[i]), f->INSN(f->msched[i]).dep, 1);
|
print_deps (fo, f, REF_BB(f->msched[i]), f->INSN(f->msched[i]).dep, 1);
|
fprintf (fo, ") begin\n");
|
fprintf (fo, ") begin\n");
|
while (dep) {
|
print_turn_off_dep (fo, f, dep);
|
assert (f->INSN(dep->ref).type & IT_MEMORY);
|
|
fprintf (fo, " %c_stb[%i] <= #1 1'b0;\n",
|
|
II_IS_LOAD (f->INSN(dep->ref).index) ? 'l' : 's', find_ls_index (f, dep->ref));
|
|
dep = dep->next;
|
|
}
|
|
fprintf (fo, " s_stb[%i] <= #1 1'b1;\n", cur_store++);
|
fprintf (fo, " s_stb[%i] <= #1 1'b1;\n", cur_store++);
|
fprintf (fo, " swb_cycstb_o <= #1 1'b1;\n");
|
fprintf (fo, " swb_cycstb_o <= #1 1'b1;\n");
|
fprintf (fo, " swb_sel_o[3:0] <= #1 4'b");
|
fprintf (fo, " swb_sel_o[3:0] <= #1 4'b");
|
switch (f->mtype[i] & MT_WIDTH) {
|
switch (f->mtype[i] & MT_WIDTH) {
|
case 1: fprintf (fo, "0001 << (%s & 32'h3);\n",
|
case 1: fprintf (fo, "0001 << (%s & 32'h3);\n",
|
Line 571... |
Line 639... |
fprintf (fo, " end\n");
|
fprintf (fo, " end\n");
|
fprintf (fo, " end\n");
|
fprintf (fo, " end\n");
|
fprintf (fo, "end\n");
|
fprintf (fo, "end\n");
|
}
|
}
|
|
|
|
if (ncalls) {
|
|
int cur_call = 0;
|
|
fprintf (fo, "\n/* Function calls state machine */\n");
|
|
fprintf (fo, "always @(posedge clk or posedge rst)\n");
|
|
fprintf (fo, "begin\n");
|
|
fprintf (fo, " if (rst) begin\n");
|
|
fprintf (fo, " f_stb <= #1 %i'h0;\n", nstores);
|
|
for (i = 0; i < 6; i++) fprintf (fo, " fr%i_o <= #1 32'h0;\n", i + 3);
|
|
if (log2(ncalls)) fprintf (fo, " fid_o <= #1 %i'h0;\n", log2 (f->nfdeps));
|
|
fprintf (fo, " fstart_o <= #1 1'b0;\n");
|
|
//fprintf (fo, " f11_r <= #1 32'h0;\n");
|
|
fprintf (fo, " end else begin\n");
|
|
cucdebug (1, "calls \n");
|
|
for (i = 0; i < f->nmsched; i++) if (f->mtype[i] & MT_CALL) {
|
|
char t[30];
|
|
dep_list *dep = f->INSN(f->msched[i]).dep;
|
|
cucdebug (1, "msched[%i] = %x (mtype %x)\n", i, f->msched[i], f->mtype[i]);
|
|
assert (f->INSN(f->msched[i]).opt[1] & (OPT_REF | OPT_REGISTER));
|
|
fprintf (fo, " if (");
|
|
print_deps (fo, f, REF_BB(f->msched[i]), f->INSN(f->msched[i]).dep, 1);
|
|
fprintf (fo, ") begin\n");
|
|
print_turn_off_dep (fo, f, dep);
|
|
fprintf (fo, " f_stb[%i] <= #1 1'b1;\n", cur_call++);
|
|
fprintf (fo, " fstart_o <= #1 1'b1;\n");
|
|
if (log2 (f->nfdeps))
|
|
fprintf (fo, " fid_o <= #1 %i'h%x;\n", log2 (f->nfdeps), func_index (f, f->msched[i]));
|
|
|
|
for (j = 0; j < 6; j++)
|
|
fprintf (fo, " fr%i_o <= #1 t%x_%x;\n", j + 3,
|
|
REF_BB (f->msched[i]), REF_I (f->msched[i]) - 6 + i);
|
|
fprintf (fo, " end\n");
|
|
}
|
|
fprintf (fo, " if (f_end[%i]) begin\n", ncalls - 1);
|
|
fprintf (fo, " f_stb <= #1 %i'h0;\n", ncalls);
|
|
fprintf (fo, " f_start_o <= #1 1'b0;\n");
|
|
fprintf (fo, " end\n");
|
|
fprintf (fo, " end\n");
|
|
fprintf (fo, "end\n");
|
|
}
|
|
|
fprintf (fo, "\n/* Basic blocks state machine */\n");
|
fprintf (fo, "\n/* Basic blocks state machine */\n");
|
fprintf (fo, "always @(posedge clk or posedge rst)\n");
|
fprintf (fo, "always @(posedge clk or posedge rst)\n");
|
fprintf (fo, "begin\n");
|
fprintf (fo, "begin\n");
|
fprintf (fo, " if (rst) bb_stb <= #1 %i'h%x;\n", f->num_bb, 0);
|
fprintf (fo, " if (rst) bb_stb <= #1 %i'h%x;\n", f->num_bb, 0);
|
fprintf (fo, " else if (end_o) bb_stb <= #1 %i'h%x;\n", f->num_bb, 0);
|
fprintf (fo, " else if (end_o) bb_stb <= #1 %i'h%x;\n", f->num_bb, 0);
|