Line 20... |
Line 20... |
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <stdarg.h>
|
#include <stdarg.h>
|
#include <assert.h>
|
#include <assert.h>
|
#include <math.h>
|
#include <math.h>
|
|
#include "sim-config.h"
|
#include "cuc.h"
|
#include "cuc.h"
|
#include "insn.h"
|
#include "insn.h"
|
|
|
/* average memory delays in cycles {read single, read burst, write single, write burst} */
|
|
static const int mdelay[4] = {4, 1, 3, 1};
|
|
|
|
double cycle_duration;
|
|
double max_bb_delay;
|
|
|
|
static cuc_timing_table *timing_table;
|
static cuc_timing_table *timing_table;
|
|
static double max_bb_delay;
|
|
|
/* Returns instruction delay */
|
/* Returns instruction delay */
|
double insn_time (cuc_insn *ii)
|
double insn_time (cuc_insn *ii)
|
{
|
{
|
if (ii->opt[2] & OPT_CONST)
|
if (ii->opt[2] & OPT_CONST)
|
Line 87... |
Line 83... |
int i;
|
int i;
|
int d = 0;
|
int d = 0;
|
for (i = 0; i < f->nmsched; i++)
|
for (i = 0; i < f->nmsched; i++)
|
if (REF_BB (f->msched[i]) == b) {
|
if (REF_BB (f->msched[i]) == b) {
|
if (f->mtype[i] & MT_WRITE) {
|
if (f->mtype[i] & MT_WRITE) {
|
if (!(f->mtype[i] & MT_BURST) || f->mtype[i] & MT_BURSTE) d += mdelay[2];
|
if (!(f->mtype[i] & MT_BURST) || f->mtype[i] & MT_BURSTE) d += runtime.cuc.mdelay[2];
|
else d += mdelay[3];
|
else d += runtime.cuc.mdelay[3];
|
} else {
|
} else {
|
if (!(f->mtype[i] & MT_BURST) || f->mtype[i] & MT_BURSTE) d += mdelay[0];
|
if (!(f->mtype[i] & MT_BURST) || f->mtype[i] & MT_BURSTE) d += runtime.cuc.mdelay[0];
|
else d += mdelay[1];
|
else d += runtime.cuc.mdelay[1];
|
}
|
}
|
}
|
}
|
//printf ("md%i=%i\n", b, d);
|
//printf ("md%i=%i\n", b, d);
|
return d;
|
return d;
|
}
|
}
|
Line 134... |
Line 130... |
md += insn_time (&bb->insn[i]);
|
md += insn_time (&bb->insn[i]);
|
//printf ("md%.1f mg%i %.1f\n", md, mg, sd);
|
//printf ("md%.1f mg%i %.1f\n", md, mg, sd);
|
bb->insn[i].tmp = mg;
|
bb->insn[i].tmp = mg;
|
if (md > sd) {
|
if (md > sd) {
|
bb->insn[i].type |= IT_CUT;
|
bb->insn[i].type |= IT_CUT;
|
if (md > cycle_duration)
|
if (md > runtime.cuc.cycle_duration)
|
log ("WARNING: operation t%x_%x may need to be registered inbetween\n", b, i);
|
log ("WARNING: operation t%x_%x may need to be registered inbetween\n", b, i);
|
depths[i] = 0.;
|
depths[i] = 0.;
|
} else depths[i] = md;
|
} else depths[i] = md;
|
}
|
}
|
free (depths);
|
free (depths);
|
Line 147... |
Line 143... |
/* How many cycles we need now to get through the BB */
|
/* How many cycles we need now to get through the BB */
|
static int new_bb_cycles (cuc_func *f, int b, int cut)
|
static int new_bb_cycles (cuc_func *f, int b, int cut)
|
{
|
{
|
long d;
|
long d;
|
double x = max_delay (f, b);
|
double x = max_delay (f, b);
|
d = ceil (x / cycle_duration);
|
d = ceil (x / runtime.cuc.cycle_duration);
|
if (d < 1) d = 1;
|
if (d < 1) d = 1;
|
if (cut && x > cycle_duration) cut_tree (f, b, x / d);
|
if (cut && x > runtime.cuc.cycle_duration) cut_tree (f, b, x / d);
|
|
|
if (x / d > max_bb_delay) max_bb_delay = x / d;
|
if (x / d > max_bb_delay) max_bb_delay = x / d;
|
|
|
return memory_delay (f, b) + d;
|
return memory_delay (f, b) + d;
|
}
|
}
|
Line 163... |
Line 159... |
{
|
{
|
int b, i;
|
int b, i;
|
for (b = 0; b < f->num_bb; b++)
|
for (b = 0; b < f->num_bb; b++)
|
for (i = 0; i < f->bb[b].ninsn; i++)
|
for (i = 0; i < f->bb[b].ninsn; i++)
|
f->bb[b].insn[i].tmp = 0; /* Set starting groups */
|
f->bb[b].insn[i].tmp = 0; /* Set starting groups */
|
if (no_multicycle)
|
if (config.cuc.no_multicycle)
|
for (b = 0; b < f->num_bb; b++)
|
for (b = 0; b < f->num_bb; b++)
|
new_bb_cycles (f, b, 1);
|
new_bb_cycles (f, b, 1);
|
}
|
}
|
|
|
/* Returns basic block circuit area */
|
/* Returns basic block circuit area */
|
Line 245... |
Line 241... |
{
|
{
|
int i;
|
int i;
|
FILE *fi;
|
FILE *fi;
|
|
|
log ("Loading timings from %s\n", filename);
|
log ("Loading timings from %s\n", filename);
|
log ("Using clock delay %.2fns (frequency %.0fMHz)\n", cycle_duration, 1000. / cycle_duration);
|
log ("Using clock delay %.2fns (frequency %.0fMHz)\n", runtime.cuc.cycle_duration,
|
|
1000. / runtime.cuc.cycle_duration);
|
assert (fi = fopen (filename, "rt"));
|
assert (fi = fopen (filename, "rt"));
|
|
|
timing_table = (cuc_timing_table *)malloc ((II_LAST + 1) * sizeof (cuc_timing_table));
|
timing_table = (cuc_timing_table *)malloc ((II_LAST + 1) * sizeof (cuc_timing_table));
|
assert (timing_table);
|
assert (timing_table);
|
for (i = 0; i <= II_LAST; i++) {
|
for (i = 0; i <= II_LAST; i++) {
|