Line 102... |
Line 102... |
config.sim.history ||
|
config.sim.history ||
|
config.sim.exe_log;
|
config.sim.exe_log;
|
|
|
sim_init ();
|
sim_init ();
|
|
|
runtime.sim.ext_int = 0; /* No interrupts pending */
|
runtime.sim.ext_int_set = 0; /* No interrupts pending to be set */
|
|
runtime.sim.ext_int_clr = 0; /* No interrupts pending to be cleared */
|
|
|
return OR1KSIM_RC_OK;
|
return OR1KSIM_RC_OK;
|
|
|
} /* or1ksim_init() */
|
} /* or1ksim_init() */
|
|
|
Line 135... |
Line 136... |
a breakpoint (not clear how this can be set without CLI access) */
|
a breakpoint (not clear how this can be set without CLI access) */
|
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
int
|
int
|
or1ksim_run (double duration)
|
or1ksim_run (double duration)
|
{
|
{
|
|
const int num_ints = sizeof (runtime.sim.ext_int_set) * 8;
|
|
|
or1ksim_reset_duration (duration);
|
or1ksim_reset_duration (duration);
|
|
|
/* Loop until we have done enough cycles (or forever if we had a negative
|
/* Loop until we have done enough cycles (or forever if we had a negative
|
duration) */
|
duration) */
|
while (duration < 0.0 || (runtime.sim.cycles < runtime.sim.end_cycles))
|
while (duration < 0.0 || (runtime.sim.cycles < runtime.sim.end_cycles))
|
Line 159... |
Line 162... |
return OR1KSIM_RC_BRKPT; /* Hit a breakpoint */
|
return OR1KSIM_RC_BRKPT; /* Hit a breakpoint */
|
}
|
}
|
|
|
runtime.sim.cycles += runtime.sim.mem_cycles;
|
runtime.sim.cycles += runtime.sim.mem_cycles;
|
|
|
/* Taken any external interrupts. Outer test is for the common case for
|
/* Take any external interrupts. Outer test is for the common case for
|
efficiency. */
|
efficiency. */
|
|
if (0 != runtime.sim.ext_int_set)
|
if (0 != runtime.sim.ext_int)
|
|
{
|
{
|
for (i = 0; i < sizeof (runtime.sim.ext_int); i++)
|
for (i = 0; i < num_ints; i++)
|
{
|
{
|
if (0x1 == ((runtime.sim.ext_int >> i) & 0x1))
|
if (0x1 == ((runtime.sim.ext_int_set >> i) & 0x1))
|
{
|
{
|
report_interrupt (i);
|
report_interrupt (i);
|
runtime.sim.ext_int &= ~(1 << i); /* Clear int */
|
runtime.sim.ext_int_set &= ~(1 << i); /* Clear req flag */
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Clear any interrupts as requested. For edge triggered interrupts this
|
|
will happen in the same cycle. For level triggered, it must be an
|
|
explicit call. */
|
|
if (0 != runtime.sim.ext_int_clr)
|
|
{
|
|
for (i = 0; i < num_ints; i++)
|
|
{
|
|
/* Only clear interrupts that have been explicitly cleared */
|
|
if(0x1 == ((runtime.sim.ext_int_clr >> i) & 0x1))
|
|
{
|
|
clear_interrupt(i);
|
|
runtime.sim.ext_int_clr &= ~(1 << i); /* Clear clr flag */
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
/* Update the scheduler queue */
|
/* Update the scheduler queue */
|
Line 286... |
Line 304... |
clkcycle_ps));
|
clkcycle_ps));
|
} /* or1ksim_clock_rate() */
|
} /* or1ksim_clock_rate() */
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
/*!Take an interrupt
|
/*!Trigger an edge triggered interrupt
|
|
|
|
This function is appropriate for edge triggered interrupts, which are taken
|
|
and then immediately cleared.
|
|
|
@note There is no check that the specified interrupt number is reasonable
|
@note There is no check that the specified interrupt number is reasonable
|
(i.e. <= 31).
|
(i.e. <= 31).
|
|
|
@param[in] i The interrupt number */
|
@param[in] i The interrupt number */
|
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
void
|
void
|
or1ksim_interrupt (int i)
|
or1ksim_interrupt (int i)
|
{
|
{
|
runtime.sim.ext_int |= 1 << i; // Better not be > 31!
|
if (!config.pic.edge_trigger)
|
|
{
|
|
fprintf (stderr, "Warning: or1ksim_interrupt should not be used for "
|
|
"edge triggered interrupts. Ignored\n");
|
|
}
|
|
else
|
|
{
|
|
runtime.sim.ext_int_set |= 1 << i; // Better not be > 31!
|
|
runtime.sim.ext_int_clr |= 1 << i; // Better not be > 31!
|
|
}
|
|
} /* or1ksim_interrupt() */
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/*!Set a level triggered interrupt
|
|
|
|
This function is appropriate for level triggered interrupts, which must be
|
|
explicitly cleared in a separate call.
|
|
|
|
@note There is no check that the specified interrupt number is reasonable
|
|
(i.e. <= 31).
|
|
|
|
@param[in] i The interrupt number to set */
|
|
/*---------------------------------------------------------------------------*/
|
|
void
|
|
or1ksim_interrupt_set (int i)
|
|
{
|
|
if (config.pic.edge_trigger)
|
|
{
|
|
fprintf (stderr, "Warning: or1ksim_interrupt_set should not be used for "
|
|
"level triggered interrupts. Ignored\n");
|
|
}
|
|
else
|
|
{
|
|
runtime.sim.ext_int_set |= 1 << i; // Better not be > 31!
|
|
}
|
|
} /* or1ksim_interrupt() */
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/*!Clear a level triggered interrupt
|
|
|
|
This function is appropriate for level triggered interrupts, which must be
|
|
explicitly set first in a separate call.
|
|
|
|
@note There is no check that the specified interrupt number is reasonable
|
|
(i.e. <= 31).
|
|
|
|
@param[in] i The interrupt number to clear */
|
|
/*---------------------------------------------------------------------------*/
|
|
void
|
|
or1ksim_interrupt_clear (int i)
|
|
{
|
|
if (config.pic.edge_trigger)
|
|
{
|
|
fprintf (stderr, "Warning: or1ksim_interrupt_clear should not be used "
|
|
"for level triggered interrupts. Ignored\n");
|
|
}
|
|
else
|
|
{
|
|
runtime.sim.ext_int_clr |= 1 << i; // Better not be > 31!
|
|
}
|
} /* or1ksim_interrupt() */
|
} /* or1ksim_interrupt() */
|
|
|
No newline at end of file
|
No newline at end of file
|