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

Subversion Repositories or1k_old

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 901 to Rev 902
    Reverse comparison

Rev 901 → Rev 902

/trunk/or1ksim/cuc/bb.c
375,7 → 375,7
|| !(f->bb[pred].insn[f->bb[pred].ninsn - 1].type & IT_BRANCH)) type = 1;
if (type == 0 && f->bb[succ].prev[0] == f->bb[succ].next[0]) add_cond = 1;
ninsn = f->bb[pred].ninsn + f->bb[succ].ninsn + (type == 0 || type == 2 ? 1 : 0)
ninsn = f->bb[pred].ninsn + f->bb[succ].ninsn + (type == 0 ? 1 : type == 1 ? 0 : 2)
+ (add_cond ? MAX_REGS : 0);
 
insn = (cuc_insn *) malloc (ninsn * sizeof (cuc_insn));
386,14 → 386,37
cond_op = insn[add - 1].op[1];
cond_opt = insn[add - 1].opt[1];
change_insn_type (&insn[add - 1], II_NOP);
/* and when type == 2, we must add sfor instruction, to quit when either is true */
if (type == 2) {
/* TODO */
assert (0);
}
}
/* Copy second block */
for (i = 0; i < f->bb[succ].ninsn; i++) insn[i + f->bb[pred].ninsn] = f->bb[succ].insn[i];
 
 
/* and when type == 2, we may need to add sfor instruction, to quit when either is true */
if (type == 2) {
assert (0);
}
 
/* LRBB at start of succ BB is not valid, it should be set when */
if (insn[add].index == II_LRBB) {
assert (0); /* not tested yet */
change_insn_type (&insn[add], II_NOP);
for (i = add; i < ninsn; i++)
if (insn[i].index == II_CMOV && insn[i].op[3] == REF (succ, add)) {
assert (insn[i].opt[3] == OPT_REF);
insn[i].op[3] = cond_op;
insn[i].opt[3] = cond_opt;
if (f->bb[pred].next[0] != succ) {
unsigned long t; /* negate conditional -- exchange */
assert (f->bb[pred].next[1] == succ);
t = insn[i].op[1];
insn[i].op[1] = insn[i].op[2];
insn[i].op[2] = t;
t = insn[i].opt[1];
insn[i].opt[1] = insn[i].opt[2];
insn[i].opt[2] = t;
}
}
}
for (i = 0; i < ninsn; i++) reloc[i] = -1;
 
/trunk/or1ksim/cuc/insn.c
252,6 → 252,103
return 0;
}
 
/* First primary input */
static unsigned long tmp_op, tmp_opt;
 
/* Recursive function that searches for primary inputs;
returns 0 if cmov can be replaced by add */
static int cmov_needed (cuc_func *f, int ref)
{
cuc_insn *ii = &f->INSN(ref);
int j;
//printf (" %x", ref);
/* mark visited, if already marked, we have a loop, ignore */
if (ii->tmp) return 0;
ii->tmp = 1;
 
/* handle normal movs separately */
if ((ii->index == II_ADD || !(ii->type & IT_VOLATILE))
&& ii->opt[2] == OPT_CONST && ii->op[2] == 0) {
if (ii->opt[1] == OPT_REF) {
if (cmov_needed (f, ii->op[1])) {
ii->tmp = 0;
return 1;
}
} else {
if (tmp_opt == OPT_NONE) {
tmp_op = ii->op[1];
tmp_opt = ii->opt[1];
} else if (tmp_opt != ii->opt[1] || tmp_op != ii->op[1]) {
ii->tmp = 0;
return 1;
}
}
ii->tmp = 0;
return 0;
}
 
/* Is this instruction CMOV? no => add to primary inputs */
if (ii->index != II_CMOV || ii->type & IT_VOLATILE)
if (tmp_opt == OPT_NONE) {
tmp_op = ref;
tmp_opt = OPT_REF;
ii->tmp = 0;
return 0;
} else if (tmp_opt != OPT_REF || tmp_op != ref) {
ii->tmp = 0;
return 1;
}
 
for (j = 1; j < 3; j++) {
//printf ("(%x:%i)", ref, j);
if (ii->opt[j] == OPT_REF) {
if (cmov_needed (f, ii->op[j])) {
ii->tmp = 0;
return 1;
}
} else {
if (tmp_opt == OPT_NONE) {
tmp_op = ii->op[j];
tmp_opt = ii->opt[j];
} else if (tmp_opt != ii->opt[j] || tmp_op != ii->op[j]) {
ii->tmp = 0;
return 1;
}
}
}
 
ii->tmp = 0;
return 0;
}
 
/* Search and optimize complex cmov assignments */
void optimize_cmovs (cuc_func *f)
{
int b, i, j;
 
/* Mark all instructions unvisited */
for (b = 0; b < f->num_bb; b++) if (!(f->bb[b].type & BB_DEAD))
for (i = 0; i < f->bb[b].ninsn; i++) f->bb[b].insn[i].tmp = 0;
for (b = 0; b < f->num_bb; b++) if (!(f->bb[b].type & BB_DEAD)) {
for (i = 0; i < f->bb[b].ninsn; i++) {
cuc_insn *ii = &f->bb[b].insn[i];
if (ii->index == II_CMOV && !(ii->type & IT_VOLATILE)) {
tmp_opt = OPT_NONE;
printf ("\n");
if (!cmov_needed (f, REF(b, i))) {
assert (tmp_opt != OPT_NONE);
change_insn_type (ii, II_ADD);
ii->op[1] = tmp_op; ii->opt[1] = tmp_opt;
ii->op[2] = 0; ii->opt[2] = OPT_CONST;
ii->opt[3] = OPT_NONE;
}
}
}
}
}
 
/* Optimizes dataflow tree */
void optimize_tree (cuc_func *f)
{
480,6 → 577,7
f->lur[i] = -1;
f->used_regs[i] = 0;
}
if (cuc_debug > 5) print_cuc_bb (f, "SET_IO");
for (b = 0; b < f->num_bb; b++) {
for (i = 0; i < f->bb[b].ninsn; i++)
for (j = 0; j < MAX_OPERANDS; j++)
/trunk/or1ksim/cuc/verilog.c
161,8 → 161,8
int end_bb_no = -1;
sprintf (tmp, "%s.v", filename);
 
log ("Generating verilog file \"%s\"\n", filename);
printf ("Generating verilog file \"%s\"\n", filename);
log ("Generating verilog file \"%s\"\n", tmp);
printf ("Generating verilog file \"%s\"\n", tmp);
if ((fo = fopen (tmp, "wt+")) == NULL) {
fprintf (stderr, "Cannot open '%s'\n", tmp);
exit (1);
173,7 → 173,11
assert (end_bb && end_bb->type & BB_END);
 
/* output header */
fprintf (fo, "/* %s -- generated by OpenRISC Custom Unit Compiler (c) OpenCores */\n", tmp);
fprintf (fo, "/* %s -- generated by OpenRISC Custom Unit Compiler\n", tmp);
fprintf (fo, " (C) 2002 OpenCores.\n");
fprintf (fo, " function \"%s\"\n", filename);
fprintf (fo, " at %08x - %08x\n", f->start_addr, f->end_addr);
fprintf (fo, " num BBs %i */\n\n", f->num_bb);
fprintf (fo, "module %s (clk, rst,\n", filename);
fprintf (fo, " lwb_adr_o, lwb_dat_i, lwb_cycstb_o,\n");
fprintf (fo, " lwb_sel_o, lwb_linbrst_o, lwb_ack_i,\n");
418,7 → 422,8
fprintf (fo, "reg [%2i:0] bb_start_r;\n\n", f->num_bb - 1);
fprintf (fo, "always @(posedge rst or posedge clk)\n");
fprintf (fo, "begin\n");
fprintf (fo, " if (rst || end_o) bb_start_r <= #1 %i'b0;\n", f->num_bb);
fprintf (fo, " if (rst) bb_start_r <= #1 %i'b0;\n", f->num_bb);
fprintf (fo, " else if (end_o) bb_start_r <= #1 %i'b0;\n", f->num_bb);
fprintf (fo, " else bb_start_r <= #1 bb_start;\n");
fprintf (fo, "end\n");
 
477,7 → 482,7
fprintf (fo, ") begin\n");
while (dep) {
assert (f->INSN(dep->ref).type & IT_MEMORY);
fprintf (fo, " %c_end[%i] <= #1 1'b0;\n",
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;
}
485,9 → 490,9
fprintf (fo, " lwb_cycstb_o <= #1 1'b1;\n");
fprintf (fo, " lwb_sel_o[3:0] <= #1 4'b");
switch (f->mtype[i] & MT_WIDTH) {
case 1: fprintf (fo, "0001 << (%s & 32h'3);\n",
case 1: fprintf (fo, "0001 << (%s & 32'h3);\n",
print_op_v (f, t, f->msched[i], 1)); break;
case 2: fprintf (fo, "0011 << ((%s & 32h'1) << 1);\n",
case 2: fprintf (fo, "0011 << ((%s & 32'h1) << 1);\n",
print_op_v (f, t, f->msched[i], 1)); break;
case 4: fprintf (fo, "1111;\n"); break;
default: assert (0);
532,7 → 537,7
fprintf (fo, ") begin\n");
while (dep) {
assert (f->INSN(dep->ref).type & IT_MEMORY);
fprintf (fo, " %c_end[%i] <= #1 1'b0;\n",
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;
}
540,9 → 545,9
fprintf (fo, " swb_cycstb_o <= #1 1'b1;\n");
fprintf (fo, " swb_sel_o[3:0] <= #1 4'b");
switch (f->mtype[i] & MT_WIDTH) {
case 1: fprintf (fo, "0001 << (%s & 32h'3);\n",
case 1: fprintf (fo, "0001 << (%s & 32'h3);\n",
print_op_v (f, t, f->msched[i], 1)); break;
case 2: fprintf (fo, "0011 << ((%s & 32h'1) << 1);\n",
case 2: fprintf (fo, "0011 << ((%s & 32'h1) << 1);\n",
print_op_v (f, t, f->msched[i], 1)); break;
case 4: fprintf (fo, "1111;\n"); break;
default: assert (0);
567,10 → 572,10
fprintf (fo, "\n/* Basic blocks state machine */\n");
fprintf (fo, "always @(posedge clk or posedge rst)\n");
fprintf (fo, "begin\n");
fprintf (fo, " if (rst || end_o) begin\n");
fprintf (fo, " 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);
for (i = 0; i < f->num_bb; i++) {
fprintf (fo, " end else if (bb_start[%i]) begin\n", i);
fprintf (fo, " else if (bb_start[%i]) begin\n", i);
fprintf (fo, " bb_stb <= #1 %i'h%x;\n", f->num_bb, 1 << i);
}
fprintf (fo, " end else if (end_o) begin\n");
/trunk/or1ksim/cuc/cuc.c
49,10 → 49,12
if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_PREUNROLL");
 
log ("Optimizing.\n");
optimize_cmovs (func);
if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_OPT_CMOVS");
optimize_tree (func);
if (cuc_debug >= 6) //print_cuc_bb (func, "AFTER_OPT_TREE1");
if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_OPT_TREE1");
remove_nops (func);
if (cuc_debug >= 6) //print_cuc_bb (func, "NO_NOPS");
if (cuc_debug >= 6) print_cuc_bb (func, "NO_NOPS");
remove_dead (func);
if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_DEAD1");
optimize_bb (func);
138,6 → 140,8
 
log ("Detecting dependencies\n");
if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_REG_DEP");
optimize_cmovs (func);
if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_OPT_CMOVS");
optimize_tree (func);
log ("Optimizing.\n");
if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_OPT_TREE1");
358,7 → 362,7
log ("Generating function %s.\n", name);
printf ("Generating function %s.\n", name);
 
print_cuc_bb (f, "BEFORE_GENERATE");
if (cuc_debug >= 2) print_cuc_bb (f, "BEFORE_GENERATE");
add_latches (f);
set_io (f);
if (cuc_debug >= 1) print_cuc_bb (f, "AFTER_LATCHES");
365,7 → 369,7
format_func_options (tmp, rf);
if (strlen (tmp)) printf ("Applying options: %s\n", tmp);
else printf ("Basic options.\n");
else printf ("Using basic options.\n");
 
/* Generate function as specified by options */
for (b = 0; b < f->num_bb; b++) {
626,6 → 630,8
}
if (any) printf ("--------------------------------------------------------\n");
else printf ("Sorry. No available options.\n");
} else if (strcmp (tmp1, "") == 0) {
/* Ignore empty string */
} else {
/* help command */
if (strcmp (tmp1, "h") != 0 && strcmp (tmp1, "help") != 0)
/trunk/or1ksim/cuc/insn.h
97,6 → 97,9
/* Find known instruction and attach them to insn */
void change_insn_type (cuc_insn *i, int index);
 
/* Search and otimize complex cmov assignments */
void optimize_cmovs (cuc_func *f);
 
/* Returns instruction name */
const char *cuc_insn_name (cuc_insn *ii);
 

powered by: WebSVN 2.1.0

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