orca-sim
Orca.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * This file is part of project ORCA. More information on the project
3  * can be found at the following repositories at GitHub's website.
4  *
5  * http://https://github.com/andersondomingues/orca-sim
6  * http://https://github.com/andersondomingues/orca-software
7  * http://https://github.com/andersondomingues/orca-mpsoc
8  * http://https://github.com/andersondomingues/orca-tools
9  *
10  * Copyright (C) 2018-2020 Anderson Domingues, <ti.andersondomingues@gmail.com>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License along
23  * with this program; if not, write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 ******************************************************************************/
26 
27 // signal manip
28 #include <signal.h>
29 
30 #include <iostream>
31 #include <iomanip>
32 #include <chrono>
33 #include <cmath>
34 
35 // simulation artifacts (from URSA)
36 #include "Event.hpp"
37 #include "Simulator.hpp"
38 
39 // built-in models (from URSA)
40 #include "UMemory.hpp"
41 
42 // reusable models
43 #include "THFRiscV.hpp"
44 
45 // orca-specific hardware
46 #include "ProcessingTile.hpp"
47 
48 // instantiates a mesh of MxN PE
50 
51 // interrupt signal catcher
52 static volatile sig_atomic_t interruption = 0;
53 
54 int _status = 0;
55 
56 static void sig_handler(int _) {
57  (void)_;
58 
59  switch (interruption) {
60  case 0:
61  interruption = 1;
62  std::cout << std::endl <<
63  "Simulation interrupted. Wait for the current epoch to finish " <<
64  "or press CTRL+C again to force quit." << std::endl;
65  break;
66  case 1:
67  exit(0);
68  break;
69  case 2:
70  std::cout << std::endl << "Hold your horses!" << std::endl;
71  break;
72  }
73 }
74 
75 void check_params() {
76  #ifndef ORCA_EPOCH_LENGTH
77  std::runtime_error(
78  "ORCA_EPOCH_LENGTH must be defined in Configuration.mk\n");
79  #else
80  std::cout << "ORCA_EPOCH_LENGTH set to " << ORCA_EPOCH_LENGTH << std::endl;
81  #endif
82 
83  #ifndef ORCA_EPOCHS_TO_SIM
84  std::cout << "ORCA_EPOCHS_TO_SIM set to INFINITE" << std::endl;
85  #else
86  std::cout << "ORCA_EPOCHS_TO_SIM set to "
87  << ORCA_EPOCHS_TO_SIM << std::endl;
88  #endif
89 
90  // ursa params
91  #ifndef URSA_ZERO_TIME_CHECKING
92  std::cout << "URSA_ZERO_TIME_CHECKING disabled" << std::endl;
93  #else
94  std::cout << "URSA_ZERO_TIME_CHECKING set to "
95  << URSA_ZERO_TIME_CHECKING << std::endl;
96  #endif
97 
98  #ifndef URSA_QUEUE_SIZE_CHECKING
99  std::cout << "URSA_QUEUE_SIZE_CHECKING disabled" << std::endl;
100  #else
101  std::cout << "URSA_QUEUE_SIZE_CHECKING set to "
102  << URSA_QUEUE_SIZE_CHECKING << std::endl;
103  #endif
104 
105  // memory
106  #ifndef MEMORY_WRITE_ADDRESS_CHECKING
107  std::cout << "MEMORY_WRITE_ADDRESS_CHECKING disabled" << std::endl;
108  #else
109  std::cout << "MEMORY_WRITE_ADDRESS_CHECKING enabled" << std::endl;
110  #endif
111 
112  #ifndef MEMORY_READ_ADDRESS_CHECKING
113  std::cout << "MEMORY_READ_ADDRESS_CHECKING disabled" << std::endl;
114  #else
115  std::cout << "MEMORY_READ_ADDRESS_CHECKING enabled" << std::endl;
116  #endif
117 
118  #ifndef MEMORY_WIPE_ADDRESS_CHECKING
119  std::cout << "MEMORY_WIPE_ADDRESS_CHECKING disabled" << std::endl;
120  #else
121  std::cout << "MEMORY_WIPE_ADDRESS_CHECKING enabled" << std::endl;
122  #endif
123 
124  #ifndef MEMORY_ENABLE_COUNTERS
125  std::cout << "MEMORY_ENABLE_COUNTERS disabled" << std::endl;
126  #else
127  std::cout << "MEMORY_ENABLE_COUNTERS enabled" << std::endl;
128  #endif
129 
130  // hfriscv
131  #ifndef HFRISCV_WRITE_ADDRESS_CHECKING
132  std::cout << "HFRISCV_WRITE_ADDRESS_CHECKING disabled" << std::endl;
133  #else
134  std::cout << "HFRISCV_WRITE_ADDRESS_CHECKING enabled" << std::endl;
135  #endif
136 
137  #ifndef HFRISCV_READ_ADDRESS_CHECKING
138  std::cout << "HFRISCV_READ_ADDRESS_CHECKING disabled" << std::endl;
139  #else
140  std::cout << "HFRISCV_READ_ADDRESS_CHECKING enabled" << std::endl;
141  #endif
142 
143  #ifndef HFRISCV_ENABLE_COUNTERS
144  std::cout << "HFRISCV_ENABLE_COUNTERS disabled" << std::endl;
145  #else
146  std::cout << "HFRISCV_ENABLE_COUNTERS enabled" << std::endl;
147  #endif
148 }
149 
150 int main(int __attribute__((unused)) argc, char** argv) {
151  // argc = argc; //workaround to use -Wextra
152 
153  // register interruption handler
154  signal(SIGINT, sig_handler);
155 
156  std::cout << "URSA/ORCA Platform " << std::endl;
157 
158  std::cout << "==============[ PARAMETERS ]" << std::endl;
159  try {
160  check_params();
161  } catch (std::runtime_error& e) {
162  std::cout << e.what() << std::endl;
163  return 1;
164  }
165 
166  std::cout << "==============[ TILE COMPOSITION ]" << std::endl;
167 
168  // create new tile (single)
169  tile = new ProcessingTile();
170 
171  // load bin into memory
172  tile->GetMem0()->LoadBin(std::string(argv[1]), MEM0_BASE, MEM0_SIZE);
173 
174  std::cout << "==============[ SIMULATION ]" << std::endl;
175 
176  // instantiate simulation
177  Simulator* s = new Simulator();
178 
179  std::cout << "Scheduling..." << std::endl;
180 
181  // schedule pcore
182  s->Schedule(Event(3, tile->GetCpu()));
183 
184  // schedule dma
185  s->Schedule(Event(2, tile->GetDma()));
186 
187  std::cout << "Epoch set to " << ORCA_EPOCH_LENGTH
188  << " cycles." << std::endl;
189  std::cout << "Please wait..." << std::endl;
190 
191  try {
192  std::chrono::high_resolution_clock::time_point t1, t2;
193  while (!interruption) {
194  t1 = std::chrono::high_resolution_clock::now();
195  s->Run(ORCA_EPOCH_LENGTH);
196  t2 = std::chrono::high_resolution_clock::now();
197 
198  auto duration =
199  std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1)
200  .count();
201  s->NextEpoch();
202 
203  // converts mili to seconds before calculating the frequency
204  double hertz = static_cast<double>(ORCA_EPOCH_LENGTH) /
205  (static_cast<double>(duration) / 1000.0);
206 
207  // divide frequency by 1k (Hz -> KHz)
208  std::cout << "notice: epoch #" << s->GetEpochs() << " took ~"
209  << duration << "ms (running @ " << (hertz / 1000000.0)
210  << " MHz)" << std::endl;
211 
212  #ifdef ORCA_EPOCHS_TO_SIM
213  // simulate until reach the limit of pulses
214  if (s->GetEpochs() >= ORCA_EPOCHS_TO_SIM)
215  break;
216  #endif
217  }
218  } catch(std::runtime_error& e) {
219  std::cout << e.what() << std::endl;
220  _status = 1;
221  }
222 
223  // CPU statuses
224  std::cout
225  << tile->GetName()
226  << ": INTR=" << static_cast<int>((tile->GetSignalIntr()->Read()))
227  << ", STALL=" << static_cast<int>((tile->GetSignalStall()->Read()))
228  << std::endl;
229 
230  delete(s);
231  delete(tile);
232 
233  if (_status)
234  std::cout << "Simulation failed!" << std::endl;
235  else
236  std::cout << "Simulation ended without errors." << std::endl;
237 
238  return _status;
239 }
240 
241 
242 
243 
#define MEM0_BASE
TDmaMult * GetDma()
Signal< uint8_t > * GetSignalIntr()
#define MEM0_SIZE
This file is part of project URSA.
static volatile sig_atomic_t interruption
Definition: Orca.cpp:52
#define ORCA_EPOCHS_TO_SIM
Definition: Simulator.cpp:34
#define ORCA_EPOCH_LENGTH
Definition: Simulator.cpp:33
Signal< uint8_t > * GetSignalStall()
std::string GetName()
T Read()
Get the last value writen to the bus.
Definition: Signal.cpp:118
int main(int __attribute__((unused)) argc, char **argv)
Definition: Orca.cpp:87
Memory * GetMem0()
int _status
Definition: Orca.cpp:54
ProcessingTile * tile
Definition: Orca.cpp:49
HFRiscV * GetCpu()
static void sig_handler(int _)
Definition: Orca.cpp:56
void check_params()
Definition: Orca.cpp:75