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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [libtoplevel.c] - Blame information for rev 1756

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1745 jeremybenn
/* libtoplevel.c -- Top level simulator library source file
2
 
3
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4
   Copyright (C) 2008 Embecosm Limited
5
 
6
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7
 
8
   This file is part of OpenRISC 1000 Architectural Simulator.
9
 
10
   This program is free software; you can redistribute it and/or modify it
11
   under the terms of the GNU General Public License as published by the Free
12
   Software Foundation; either version 3 of the License, or (at your option)
13
   any later version.
14
 
15
   This program is distributed in the hope that it will be useful, but WITHOUT
16
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18
   more details.
19
 
20
   You should have received a copy of the GNU General Public License along
21
   with this program.  If not, see <http://www.gnu.org/licenses/>. */
22
 
23 1748 jeremybenn
/* This program is commented throughout in a fashion suitable for processing
24
   with Doxygen. */
25 1745 jeremybenn
 
26
 
27 1748 jeremybenn
/* Autoconf and/or portability configuration */
28
#include "config.h"
29
 
30 1745 jeremybenn
/* System includes */
31 1748 jeremybenn
#include <stdlib.h>
32 1745 jeremybenn
#include <unistd.h>
33 1748 jeremybenn
#include <signal.h>
34 1745 jeremybenn
 
35 1748 jeremybenn
/* Package includes */
36
#include "or1ksim.h"
37 1745 jeremybenn
#include "sim-config.h"
38 1748 jeremybenn
#include "toplevel-support.h"
39
#include "sched.h"
40 1745 jeremybenn
#include "execute.h"
41 1748 jeremybenn
#include "pic.h"
42 1745 jeremybenn
 
43
 
44 1748 jeremybenn
/*---------------------------------------------------------------------------*/
45
/*!Initialize the simulator.
46 1745 jeremybenn
 
47 1748 jeremybenn
   Allows specification of an (optional) config file and an image file. Builds
48
   up dummy argc/argv to pass to the existing argument parser.
49 1745 jeremybenn
 
50 1748 jeremybenn
   @param[in] config_file  Or1ksim configuration file name
51
   @param[in] image_file   The program image to execute
52
   @param[in] class_ptr    Pointer to a C++ class instance (for use when
53
                           called by C++)
54
   @param[in] upr          Upcall routine for reads
55
   @param[in] upw          Upcall routine for writes
56 1745 jeremybenn
 
57 1748 jeremybenn
   @return  0 on success and an error code on failure                        */
58
/*---------------------------------------------------------------------------*/
59
int
60
or1ksim_init (const char *config_file,
61
              const char *image_file,
62
              void       *class_ptr,
63
              unsigned long int (*upr) (void *class_ptr,
64
                                        unsigned long int addr,
65
                                        unsigned long int mask),
66
              void (*upw) (void *class_ptr,
67
                           unsigned long int addr,
68
                           unsigned long int mask, unsigned long int wdata))
69 1745 jeremybenn
{
70
  int   dummy_argc = 4;
71
  char *dummy_argv[4];
72
 
73
  /* Dummy argv array */
74
  dummy_argv[0] = "libsim";
75
  dummy_argv[1] = "-f";
76 1748 jeremybenn
  dummy_argv[2] = (char *) ((NULL != config_file) ? config_file : "sim.cfg");
77
  dummy_argv[3] = (char *) image_file;
78 1745 jeremybenn
 
79
  /* Initialization copied from existing main() */
80 1748 jeremybenn
  srand (getpid ());
81
  init_defconfig ();
82
  reg_config_secs ();
83 1745 jeremybenn
 
84 1748 jeremybenn
  if (parse_args (dummy_argc, dummy_argv))
85
    {
86
      return OR1KSIM_RC_BADINIT;
87
    }
88 1745 jeremybenn
 
89 1748 jeremybenn
  config.sim.profile   = 0;      /* No profiling */
90 1745 jeremybenn
  config.sim.mprofile  = 0;
91
 
92
  config.ext.class_ptr = class_ptr;     /* SystemC linkage */
93
  config.ext.read_up   = upr;
94
  config.ext.write_up  = upw;
95
 
96 1748 jeremybenn
  print_config ();              /* Will go eventually */
97
  signal (SIGINT, ctrl_c);      /* Not sure we want this really */
98 1745 jeremybenn
 
99 1748 jeremybenn
  runtime.sim.hush = 1;         /* Not sure if this is needed */
100
  do_stats = config.cpu.superscalar ||
101
             config.cpu.dependstats ||
102
             config.sim.history     ||
103
             config.sim.exe_log;
104 1745 jeremybenn
 
105
  sim_init ();
106
 
107 1756 jeremybenn
  runtime.sim.ext_int_set = 0;   /* No interrupts pending to be set */
108
  runtime.sim.ext_int_clr = 0;   /* No interrupts pending to be cleared */
109 1745 jeremybenn
 
110 1748 jeremybenn
  return OR1KSIM_RC_OK;
111 1745 jeremybenn
 
112
}       /* or1ksim_init() */
113
 
114
 
115 1748 jeremybenn
/*---------------------------------------------------------------------------*/
116
/*!Run the simulator
117 1745 jeremybenn
 
118 1748 jeremybenn
   The argument is a time in seconds, which is converted to a number of
119
   cycles, if positive. A negative value means "run for ever".
120 1745 jeremybenn
 
121 1748 jeremybenn
   The semantics are that the duration for which the run may occur may be
122
   changed mid-run by a call to or1ksim_reset_duration(). This is to allow for
123
   the upcalls to generic components adding time, and reducing the time
124
   permitted for ISS execution before synchronization of the parent SystemC
125
   wrapper.
126 1745 jeremybenn
 
127 1748 jeremybenn
   This is over-ridden if the call was for a negative duration, which means
128
   run forever!
129 1745 jeremybenn
 
130 1748 jeremybenn
   Uses a simplified version of the old main program loop. Returns success if
131
   the requested number of cycles were run and an error code otherwise.
132
 
133
   @param[in] duration  Time to execute for (seconds)
134
 
135
   @return  OR1KSIM_RC_OK if we run to completion, OR1KSIM_RC_BRKPT if we hit
136
            a breakpoint (not clear how this can be set without CLI access)  */
137
/*---------------------------------------------------------------------------*/
138
int
139
or1ksim_run (double duration)
140 1745 jeremybenn
{
141 1756 jeremybenn
  const int  num_ints = sizeof (runtime.sim.ext_int_set) * 8;
142
 
143 1748 jeremybenn
  or1ksim_reset_duration (duration);
144 1745 jeremybenn
 
145
  /* Loop until we have done enough cycles (or forever if we had a negative
146 1748 jeremybenn
     duration) */
147
  while (duration < 0.0 || (runtime.sim.cycles < runtime.sim.end_cycles))
148
    {
149 1745 jeremybenn
 
150 1748 jeremybenn
      long long int time_start = runtime.sim.cycles;
151
      int i;                    /* Interrupt # */
152 1745 jeremybenn
 
153 1748 jeremybenn
      /* Each cycle has counter of mem_cycles; this value is joined with cycles
154
       * at the end of the cycle; no sim originated memory accesses should be
155
       * performed inbetween.
156
       */
157 1745 jeremybenn
 
158 1748 jeremybenn
      runtime.sim.mem_cycles = 0;
159 1745 jeremybenn
 
160 1748 jeremybenn
      if (cpu_clock ())
161
        {
162
          return OR1KSIM_RC_BRKPT;      /* Hit a breakpoint */
163
        }
164 1745 jeremybenn
 
165 1748 jeremybenn
      runtime.sim.cycles += runtime.sim.mem_cycles;
166 1745 jeremybenn
 
167 1756 jeremybenn
      /* Take any external interrupts. Outer test is for the common case for
168 1748 jeremybenn
         efficiency. */
169 1756 jeremybenn
      if (0 != runtime.sim.ext_int_set)
170 1748 jeremybenn
        {
171 1756 jeremybenn
          for (i = 0; i < num_ints; i++)
172 1748 jeremybenn
            {
173 1756 jeremybenn
              if (0x1 == ((runtime.sim.ext_int_set >> i) & 0x1))
174 1748 jeremybenn
                {
175
                  report_interrupt (i);
176 1756 jeremybenn
                  runtime.sim.ext_int_set &= ~(1 << i); /* Clear req flag */
177 1748 jeremybenn
                }
178
            }
179 1745 jeremybenn
        }
180
 
181 1756 jeremybenn
      /* Clear any interrupts as requested. For edge triggered interrupts this
182
         will happen in the same cycle. For level triggered, it must be an
183
         explicit call. */
184
      if (0 != runtime.sim.ext_int_clr)
185
        {
186
          for (i = 0; i < num_ints; i++)
187
            {
188
              /* Only clear interrupts that have been explicitly cleared */
189
              if(0x1 == ((runtime.sim.ext_int_clr >> i) & 0x1))
190
                {
191
                  clear_interrupt(i);
192
                  runtime.sim.ext_int_clr &= ~(1 << i); /* Clear clr flag */
193
                }
194
            }
195
        }
196
 
197 1748 jeremybenn
      /* Update the scheduler queue */
198 1745 jeremybenn
 
199 1748 jeremybenn
      scheduler.job_queue->time -= (runtime.sim.cycles - time_start);
200 1745 jeremybenn
 
201 1748 jeremybenn
      if (scheduler.job_queue->time <= 0)
202
        {
203
          do_scheduler ();
204
        }
205 1745 jeremybenn
    }
206
 
207 1748 jeremybenn
  return  OR1KSIM_RC_OK;
208
 
209 1745 jeremybenn
}       /* or1ksim_run() */
210
 
211
 
212 1748 jeremybenn
/*---------------------------------------------------------------------------*/
213
/*!Reset the run-time simulation end point
214 1745 jeremybenn
 
215 1748 jeremybenn
  Reset the time for which the simulation should run to the specified duration
216
  from NOW (i.e. NOT from when the run started).
217
 
218
  @param[in] duration  Time to run for in seconds                            */
219
/*---------------------------------------------------------------------------*/
220
void
221
or1ksim_reset_duration (double duration)
222 1745 jeremybenn
{
223 1748 jeremybenn
  runtime.sim.end_cycles =
224 1745 jeremybenn
    runtime.sim.cycles +
225 1748 jeremybenn
    (long long int) (duration * 1.0e12 / (double) config.sim.clkcycle_ps);
226 1745 jeremybenn
 
227
}       /* or1ksim_reset_duration() */
228
 
229
 
230 1748 jeremybenn
/*---------------------------------------------------------------------------*/
231
/*!Return time executed so far
232 1745 jeremybenn
 
233 1748 jeremybenn
   Internal utility to return the time executed so far. Note that this is a
234
   re-entrant routine.
235
 
236
   @return  Time executed so far in seconds                                  */
237
/*---------------------------------------------------------------------------*/
238
static double
239
internal_or1ksim_time ()
240 1745 jeremybenn
{
241 1748 jeremybenn
  return (double) runtime.sim.cycles * (double) config.sim.clkcycle_ps /
242
    1.0e12;
243 1745 jeremybenn
 
244
}       // or1ksim_cycle_count()
245
 
246
 
247 1748 jeremybenn
/*---------------------------------------------------------------------------*/
248
/*!Mark a time point in the simulation
249 1745 jeremybenn
 
250 1748 jeremybenn
   Sets the internal parameter recording this point in the simulation        */
251
/*---------------------------------------------------------------------------*/
252
void
253
or1ksim_set_time_point ()
254 1745 jeremybenn
{
255 1748 jeremybenn
  runtime.sim.time_point = internal_or1ksim_time ();
256 1745 jeremybenn
 
257
}       /* or1ksim_set_time_point() */
258
 
259
 
260 1748 jeremybenn
/*---------------------------------------------------------------------------*/
261
/*!Return the time since the time point was set
262 1745 jeremybenn
 
263 1748 jeremybenn
  Get the value from the internal parameter                                  */
264
/*---------------------------------------------------------------------------*/
265
double
266
or1ksim_get_time_period ()
267 1745 jeremybenn
{
268 1748 jeremybenn
  return internal_or1ksim_time () - runtime.sim.time_point;
269 1745 jeremybenn
 
270
}       /* or1ksim_get_time_period() */
271
 
272
 
273 1748 jeremybenn
/*---------------------------------------------------------------------------*/
274
/*!Return the endianism of the model
275 1745 jeremybenn
 
276 1748 jeremybenn
   Note that this is a re-entrant routine.
277
 
278
   @return 1 if the model is little endian, 0 otherwise.                     */
279
/*---------------------------------------------------------------------------*/
280
int
281
or1ksim_is_le ()
282 1745 jeremybenn
{
283 1751 jeremybenn
#ifdef OR32_BIG_ENDIAN
284 1745 jeremybenn
  return 0;
285
#else
286
  return 1;
287
#endif
288
 
289 1748 jeremybenn
}       /* or1ksim_is_le() */
290 1745 jeremybenn
 
291
 
292 1748 jeremybenn
/*---------------------------------------------------------------------------*/
293
/*!Return the clock rate
294 1745 jeremybenn
 
295 1748 jeremybenn
   Value is part of the configuration
296
 
297
   @return  Clock rate in Hz.                                                */
298
/*---------------------------------------------------------------------------*/
299
unsigned long int
300
or1ksim_clock_rate ()
301 1745 jeremybenn
{
302 1748 jeremybenn
  return (unsigned long int) (1000000000000ULL /
303
                              (unsigned long long int) (config.sim.
304
                                                        clkcycle_ps));
305
}       /* or1ksim_clock_rate() */
306 1745 jeremybenn
 
307
 
308 1748 jeremybenn
/*---------------------------------------------------------------------------*/
309 1756 jeremybenn
/*!Trigger an edge triggered interrupt
310 1745 jeremybenn
 
311 1756 jeremybenn
   This function is appropriate for edge triggered interrupts, which are taken
312
   and then immediately cleared.
313 1745 jeremybenn
 
314 1756 jeremybenn
   @note There is no check that the specified interrupt number is reasonable
315
   (i.e. <= 31).
316
 
317 1748 jeremybenn
   @param[in] i  The interrupt number                                        */
318
/*---------------------------------------------------------------------------*/
319
void
320
or1ksim_interrupt (int i)
321 1745 jeremybenn
{
322 1756 jeremybenn
  if (!config.pic.edge_trigger)
323
    {
324
      fprintf (stderr, "Warning: or1ksim_interrupt should not be used for "
325
               "edge triggered interrupts. Ignored\n");
326
    }
327
  else
328
    {
329
      runtime.sim.ext_int_set |= 1 << i;        // Better not be > 31!
330
      runtime.sim.ext_int_clr |= 1 << i;        // Better not be > 31!
331
    }
332
}       /* or1ksim_interrupt() */
333 1745 jeremybenn
 
334 1756 jeremybenn
 
335
/*---------------------------------------------------------------------------*/
336
/*!Set a level triggered interrupt
337
 
338
   This function is appropriate for level triggered interrupts, which must be
339
   explicitly cleared in a separate call.
340
 
341
   @note There is no check that the specified interrupt number is reasonable
342
   (i.e. <= 31).
343
 
344
   @param[in] i  The interrupt number to set                                 */
345
/*---------------------------------------------------------------------------*/
346
void
347
or1ksim_interrupt_set (int i)
348
{
349
  if (config.pic.edge_trigger)
350
    {
351
      fprintf (stderr, "Warning: or1ksim_interrupt_set should not be used for "
352
               "level triggered interrupts. Ignored\n");
353
    }
354
  else
355
    {
356
      runtime.sim.ext_int_set |= 1 << i;        // Better not be > 31!
357
    }
358 1745 jeremybenn
}       /* or1ksim_interrupt() */
359 1756 jeremybenn
 
360
 
361
/*---------------------------------------------------------------------------*/
362
/*!Clear a level triggered interrupt
363
 
364
   This function is appropriate for level triggered interrupts, which must be
365
   explicitly set first in a separate call.
366
 
367
   @note There is no check that the specified interrupt number is reasonable
368
   (i.e. <= 31).
369
 
370
   @param[in] i  The interrupt number to clear                               */
371
/*---------------------------------------------------------------------------*/
372
void
373
or1ksim_interrupt_clear (int i)
374
{
375
  if (config.pic.edge_trigger)
376
    {
377
      fprintf (stderr, "Warning: or1ksim_interrupt_clear should not be used "
378
               "for level triggered interrupts. Ignored\n");
379
    }
380
  else
381
    {
382
      runtime.sim.ext_int_clr |= 1 << i;        // Better not be > 31!
383
    }
384
}       /* or1ksim_interrupt() */

powered by: WebSVN 2.1.0

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