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

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc1/] [or1ksim/] [libtoplevel.c] - Blame information for rev 1765

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 1748 jeremybenn
  runtime.sim.ext_int = 0;       /* No interrupts pending */
108 1745 jeremybenn
 
109 1748 jeremybenn
  return OR1KSIM_RC_OK;
110 1745 jeremybenn
 
111
}       /* or1ksim_init() */
112
 
113
 
114 1748 jeremybenn
/*---------------------------------------------------------------------------*/
115
/*!Run the simulator
116 1745 jeremybenn
 
117 1748 jeremybenn
   The argument is a time in seconds, which is converted to a number of
118
   cycles, if positive. A negative value means "run for ever".
119 1745 jeremybenn
 
120 1748 jeremybenn
   The semantics are that the duration for which the run may occur may be
121
   changed mid-run by a call to or1ksim_reset_duration(). This is to allow for
122
   the upcalls to generic components adding time, and reducing the time
123
   permitted for ISS execution before synchronization of the parent SystemC
124
   wrapper.
125 1745 jeremybenn
 
126 1748 jeremybenn
   This is over-ridden if the call was for a negative duration, which means
127
   run forever!
128 1745 jeremybenn
 
129 1748 jeremybenn
   Uses a simplified version of the old main program loop. Returns success if
130
   the requested number of cycles were run and an error code otherwise.
131
 
132
   @param[in] duration  Time to execute for (seconds)
133
 
134
   @return  OR1KSIM_RC_OK if we run to completion, OR1KSIM_RC_BRKPT if we hit
135
            a breakpoint (not clear how this can be set without CLI access)  */
136
/*---------------------------------------------------------------------------*/
137
int
138
or1ksim_run (double duration)
139 1745 jeremybenn
{
140 1748 jeremybenn
  or1ksim_reset_duration (duration);
141 1745 jeremybenn
 
142
  /* Loop until we have done enough cycles (or forever if we had a negative
143 1748 jeremybenn
     duration) */
144
  while (duration < 0.0 || (runtime.sim.cycles < runtime.sim.end_cycles))
145
    {
146 1745 jeremybenn
 
147 1748 jeremybenn
      long long int time_start = runtime.sim.cycles;
148
      int i;                    /* Interrupt # */
149 1745 jeremybenn
 
150 1748 jeremybenn
      /* Each cycle has counter of mem_cycles; this value is joined with cycles
151
       * at the end of the cycle; no sim originated memory accesses should be
152
       * performed inbetween.
153
       */
154 1745 jeremybenn
 
155 1748 jeremybenn
      runtime.sim.mem_cycles = 0;
156 1745 jeremybenn
 
157 1748 jeremybenn
      if (cpu_clock ())
158
        {
159
          return OR1KSIM_RC_BRKPT;      /* Hit a breakpoint */
160
        }
161 1745 jeremybenn
 
162 1748 jeremybenn
      runtime.sim.cycles += runtime.sim.mem_cycles;
163 1745 jeremybenn
 
164 1748 jeremybenn
      /* Taken any external interrupts. Outer test is for the common case for
165
         efficiency. */
166 1745 jeremybenn
 
167 1748 jeremybenn
      if (0 != runtime.sim.ext_int)
168
        {
169
          for (i = 0; i < sizeof (runtime.sim.ext_int); i++)
170
            {
171
              if (0x1 == ((runtime.sim.ext_int >> i) & 0x1))
172
                {
173
                  report_interrupt (i);
174
                  runtime.sim.ext_int &= ~(1 << i);     /* Clear int */
175
                }
176
            }
177 1745 jeremybenn
        }
178
 
179 1748 jeremybenn
      /* Update the scheduler queue */
180 1745 jeremybenn
 
181 1748 jeremybenn
      scheduler.job_queue->time -= (runtime.sim.cycles - time_start);
182 1745 jeremybenn
 
183 1748 jeremybenn
      if (scheduler.job_queue->time <= 0)
184
        {
185
          do_scheduler ();
186
        }
187 1745 jeremybenn
    }
188
 
189 1748 jeremybenn
  return  OR1KSIM_RC_OK;
190
 
191 1745 jeremybenn
}       /* or1ksim_run() */
192
 
193
 
194 1748 jeremybenn
/*---------------------------------------------------------------------------*/
195
/*!Reset the run-time simulation end point
196 1745 jeremybenn
 
197 1748 jeremybenn
  Reset the time for which the simulation should run to the specified duration
198
  from NOW (i.e. NOT from when the run started).
199
 
200
  @param[in] duration  Time to run for in seconds                            */
201
/*---------------------------------------------------------------------------*/
202
void
203
or1ksim_reset_duration (double duration)
204 1745 jeremybenn
{
205 1748 jeremybenn
  runtime.sim.end_cycles =
206 1745 jeremybenn
    runtime.sim.cycles +
207 1748 jeremybenn
    (long long int) (duration * 1.0e12 / (double) config.sim.clkcycle_ps);
208 1745 jeremybenn
 
209
}       /* or1ksim_reset_duration() */
210
 
211
 
212 1748 jeremybenn
/*---------------------------------------------------------------------------*/
213
/*!Return time executed so far
214 1745 jeremybenn
 
215 1748 jeremybenn
   Internal utility to return the time executed so far. Note that this is a
216
   re-entrant routine.
217
 
218
   @return  Time executed so far in seconds                                  */
219
/*---------------------------------------------------------------------------*/
220
static double
221
internal_or1ksim_time ()
222 1745 jeremybenn
{
223 1748 jeremybenn
  return (double) runtime.sim.cycles * (double) config.sim.clkcycle_ps /
224
    1.0e12;
225 1745 jeremybenn
 
226
}       // or1ksim_cycle_count()
227
 
228
 
229 1748 jeremybenn
/*---------------------------------------------------------------------------*/
230
/*!Mark a time point in the simulation
231 1745 jeremybenn
 
232 1748 jeremybenn
   Sets the internal parameter recording this point in the simulation        */
233
/*---------------------------------------------------------------------------*/
234
void
235
or1ksim_set_time_point ()
236 1745 jeremybenn
{
237 1748 jeremybenn
  runtime.sim.time_point = internal_or1ksim_time ();
238 1745 jeremybenn
 
239
}       /* or1ksim_set_time_point() */
240
 
241
 
242 1748 jeremybenn
/*---------------------------------------------------------------------------*/
243
/*!Return the time since the time point was set
244 1745 jeremybenn
 
245 1748 jeremybenn
  Get the value from the internal parameter                                  */
246
/*---------------------------------------------------------------------------*/
247
double
248
or1ksim_get_time_period ()
249 1745 jeremybenn
{
250 1748 jeremybenn
  return internal_or1ksim_time () - runtime.sim.time_point;
251 1745 jeremybenn
 
252
}       /* or1ksim_get_time_period() */
253
 
254
 
255 1748 jeremybenn
/*---------------------------------------------------------------------------*/
256
/*!Return the endianism of the model
257 1745 jeremybenn
 
258 1748 jeremybenn
   Note that this is a re-entrant routine.
259
 
260
   @return 1 if the model is little endian, 0 otherwise.                     */
261
/*---------------------------------------------------------------------------*/
262
int
263
or1ksim_is_le ()
264 1745 jeremybenn
{
265
#ifdef WORDS_BIGENDIAN
266
  return 0;
267
#else
268
  return 1;
269
#endif
270
 
271 1748 jeremybenn
}       /* or1ksim_is_le() */
272 1745 jeremybenn
 
273
 
274 1748 jeremybenn
/*---------------------------------------------------------------------------*/
275
/*!Return the clock rate
276 1745 jeremybenn
 
277 1748 jeremybenn
   Value is part of the configuration
278
 
279
   @return  Clock rate in Hz.                                                */
280
/*---------------------------------------------------------------------------*/
281
unsigned long int
282
or1ksim_clock_rate ()
283 1745 jeremybenn
{
284 1748 jeremybenn
  return (unsigned long int) (1000000000000ULL /
285
                              (unsigned long long int) (config.sim.
286
                                                        clkcycle_ps));
287
}       /* or1ksim_clock_rate() */
288 1745 jeremybenn
 
289
 
290 1748 jeremybenn
/*---------------------------------------------------------------------------*/
291
/*!Take an interrupt
292 1745 jeremybenn
 
293 1748 jeremybenn
  @note There is no check that the specified interrupt number is reasonable
294
  (i.e. <= 31).
295 1745 jeremybenn
 
296 1748 jeremybenn
   @param[in] i  The interrupt number                                        */
297
/*---------------------------------------------------------------------------*/
298
void
299
or1ksim_interrupt (int i)
300 1745 jeremybenn
{
301 1748 jeremybenn
  runtime.sim.ext_int |= 1 << i;        // Better not be > 31!
302 1745 jeremybenn
 
303
}       /* or1ksim_interrupt() */

powered by: WebSVN 2.1.0

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