orca-sim
Functions | Variables
Orca.cpp File Reference
#include <iostream>
#include <iomanip>
#include <chrono>
#include <cmath>
#include <signal.h>
#include <Event.h>
#include <Simulator.h>
#include <UMemory.h>
#include <THFRiscV.h>
#include <MemoryMap.h>

Go to the source code of this file.

Functions

static void sig_handler (int _)
 Signal handler. More...
 
int main (int __attribute__((unused)) argc, char **argv)
 Main routine. More...
 

Variables

static volatile sig_atomic_t interruption = 0
 Implementation file for ORCA-SIM program. More...
 

Function Documentation

§ main()

int main ( int __attribute__((unused))  argc,
char **  argv 
)

Main routine.

Instantiate simulator, hardware models, connect these models, and start simulation.

Parameters
argcShould be always equals 2
argvOne-dimensional array containing the name of binary file to load in the program
Returns
int Simulation status (termination)

Definition at line 77 of file Orca.cpp.

77  {
78 
79  //show usage and abort if an image file is not informed
80  if(argc != 2){
81  std::cout << "Usage: " << argv[0] << " <software-image>" << std::endl;
82  abort();
83  }
84 
85  //register interruption handler
86  signal(SIGINT, sig_handler);
87 
88  std::cout << "URSA/ORCA Platform " << std::endl;
89 
90  //create new control signals
91  Signal<uint8_t> *signal_stall, *signal_intr;
92  signal_stall = new Signal<uint8_t>(SIGNAL_CPU_STALL, "cpu.stall");
93  signal_intr = new Signal<uint8_t>(SIGNAL_CPU_INTR, "cpu.intr");
94 
95  //create a cpu and memory
96  Memory* mem = new Memory("main-memory", MEM_SIZE, MEM_BASE);
97  HFRiscV* cpu = new HFRiscV("cpu", signal_intr, signal_stall, mem);
98 
99  //bind control signals to memory space
100  signal_stall->MapTo(mem->GetMap(SIGNAL_CPU_STALL), SIGNAL_CPU_STALL);
101  signal_intr->MapTo(mem->GetMap(SIGNAL_CPU_INTR), SIGNAL_CPU_INTR);
102 
103  //reset control wires
104  signal_stall->Write(0);
105  signal_intr->Write(0);
106 
107  //map counters to memory if hardware counters were enabled
108  #ifdef MEMORY_ENABLE_COUNTERS
109  //map main memory counter
110  mem->GetSignalCounterStore()->MapTo(mem->GetMap(M0_COUNTER_STORE_ADDR), M0_COUNTER_STORE_ADDR);
111  mem->GetSignalCounterLoad()->MapTo(mem->GetMap(M0_COUNTER_LOAD_ADDR), M0_COUNTER_LOAD_ADDR);
112  #endif
113 
114  #ifdef HFRISCV_ENABLE_COUNTERS
115  //memory mapping
116  cpu->GetSignalCounterArith()->MapTo(mem->GetMap(CPU_COUNTER_ARITH_ADDR), CPU_COUNTER_ARITH_ADDR);
117  cpu->GetSignalCounterLogical()->MapTo(mem->GetMap(CPU_COUNTER_LOGICAL_ADDR), CPU_COUNTER_LOGICAL_ADDR);
118  cpu->GetSignalCounterShift()->MapTo(mem->GetMap(CPU_COUNTER_SHIFT_ADDR), CPU_COUNTER_SHIFT_ADDR);
119  cpu->GetSignalCounterBranches()->MapTo(mem->GetMap(CPU_COUNTER_BRANCHES_ADDR), CPU_COUNTER_BRANCHES_ADDR);
120  cpu->GetSignalCounterJumps()->MapTo(mem->GetMap(CPU_COUNTER_JUMPS_ADDR), CPU_COUNTER_JUMPS_ADDR);
121  cpu->GetSignalCounterLoadStore()->MapTo(mem->GetMap(CPU_COUNTER_LOADSTORE_ADDR), CPU_COUNTER_LOADSTORE_ADDR);
122  cpu->GetSignalCounterCyclesTotal()->MapTo(mem->GetMap(CPU_COUNTER_CYCLES_TOTAL_ADDR), CPU_COUNTER_CYCLES_TOTAL_ADDR);
123  cpu->GetSignalCounterCyclesStall()->MapTo(mem->GetMap(CPU_COUNTER_CYCLES_STALL_ADDR), CPU_COUNTER_CYCLES_STALL_ADDR);
124  cpu->GetSignalHostTime()->MapTo(mem->GetMap(CPU_COUNTER_HOSTTIME_ADDR), CPU_COUNTER_HOSTTIME_ADDR);
125  #endif
126 
127  //load software image into memory
128  mem->LoadBin(std::string(argv[1]), MEM_BASE, MEM_SIZE);
129 
130  //instantiate a new simulation
131  Simulator* s = new Simulator();
132 
133  //schedule cpu
134  s->Schedule(Event(3, cpu));
135 
136  std::cout << "Epoch set to " << ORCA_EPOCH_LENGTH << " cycles." << std::endl;
137  std::cout << "Please wait..." << std::endl;
138 
139  try{
140 
141  std::chrono::high_resolution_clock::time_point t1, t2;
142 
143  while(!interruption && !cpu->GetState()->terminated){
144 
145  t1 = std::chrono::high_resolution_clock::now();
146  s->Run(ORCA_EPOCH_LENGTH);
147  t2 = std::chrono::high_resolution_clock::now();
148 
149  auto duration = std::chrono::duration_cast<std::chrono::milliseconds>( t2 - t1 ).count();
150  s->NextEpoch();
151 
152  //converts mili to seconds before calculating the frequency
153  double hertz = ((double)ORCA_EPOCH_LENGTH) / ((double)((double)duration / 1000.0));
154 
155  //divide frequency by 1k (Hz -> KHz)
156  std::cout << "notice: epoch #" << s->GetEpochs() << " took ~"
157  << duration << "ms (running @ " << (hertz / 1000000.0)
158  << " MHz)" << std::endl;
159 
160  #ifdef ORCA_EPOCHS_TO_SIM
161  //simulate until reach the limit of pulses
162  if(s->GetEpochs() >= ORCA_EPOCHS_TO_SIM)
163  break;
164  #endif
165  }
166 
167  }catch(std::runtime_error& e){
168  std::cout << e.what() << std::endl;
169  return -1; //abnormal termination, simulation failed
170  }
171 
172  //minimal reporting
173  std::cout << "cpu: INTR=" << (int)(signal_intr->Read())
174  << ", STALL=" << (int)(signal_stall->Read()) << std::endl;
175 
176  //if counters enabled, report them
177  #ifdef HFRISCV_ENABLE_COUNTERS
178  std::cout << "cpu"
179  "\tiarith\t\t" << (int)cpu->GetSignalCounterArith()->Read() << std::endl <<
180  "\tilogic\t\t" << (int)cpu->GetSignalCounterLogical()->Read() << std::endl <<
181  "\tishift\t\t" << (int)cpu->GetSignalCounterShift()->Read() << std::endl <<
182  "\tibranch\t\t" << (int)cpu->GetSignalCounterBranches()->Read() << std::endl <<
183  "\tijumps\t\t" << (int)cpu->GetSignalCounterJumps()->Read() << std::endl <<
184  "\timemop\t\t" << (int)cpu->GetSignalCounterLoadStore()->Read() << std::endl <<
185  "\ticycles\t\t" << (int)cpu->GetSignalCounterCyclesTotal()->Read() << std::endl <<
186  "\tistalls\t\t" << (int)cpu->GetSignalCounterCyclesStall()->Read() << std::endl <<
187  "\tihtime\t\t" << (int)cpu->GetSignalHostTime()->Read() << std::endl;
188 
189  #endif
190 
191  #ifdef MEMORY_ENABLE_COUNTERS
192  std::cout << "mem"
193  "\tloads\t\t" << (int)mem->GetSignalCounterStore()->Read() << std::endl <<
194  "\tstores\t\t" << (int)mem->GetSignalCounterLoad()->Read() << std::endl;
195  #endif
196 
197  int exit_status = cpu->GetState()->terminated;
198 
199  //free resources
200  delete(s);
201  delete(cpu);
202  delete(mem);
203  delete(signal_intr);
204  delete(signal_stall);
205 
206  //return existing code to upper system
207  return exit_status;
208 }
static void sig_handler(int _)
Signal handler.
Definition: Orca.cpp:54
#define ORCA_EPOCHS_TO_SIM
Definition: Simulator.cpp:34
#define ORCA_EPOCH_LENGTH
Definition: Simulator.cpp:33
#define SIGNAL_CPU_STALL
Definition: _MemoryMap.h:12
#define MEM_BASE
Definition: _MemoryMap.h:26
static volatile sig_atomic_t interruption
Implementation file for ORCA-SIM program.
Definition: Orca.cpp:43
#define MEM_SIZE
Definition: _MemoryMap.h:27
#define SIGNAL_CPU_INTR
Definition: _MemoryMap.h:13

§ sig_handler()

static void sig_handler ( int  _)
static

Signal handler.

This handler captures interruption from the keyboard (CTRL+C) and flag the simulation to end in the current epoch. If pressed CTRL+C again, simulation will abort.

Parameters
_This param is unused (must be here to comply with system's API)

Definition at line 54 of file Orca.cpp.

54  {
55 
56  (void)_;
57 
58  switch(interruption){
59  case 0:
60  interruption = 1;
61  std::cout << std::endl << "Simulation interrupted. Wait for the current epoch to finish or press CTRL+C again to force quit." << std::endl;
62  break;
63  case 1:
64  exit(0);
65  break;
66  }
67 }
static volatile sig_atomic_t interruption
Implementation file for ORCA-SIM program.
Definition: Orca.cpp:43

Variable Documentation

§ interruption

volatile sig_atomic_t interruption = 0
static

Implementation file for ORCA-SIM program.

This file is part of project URSA. http://https://github.com/andersondomingues/ursa

Copyright (C) 2018 Anderson Domingues, ti.an.nosp@m.ders.nosp@m.ondom.nosp@m.ingu.nosp@m.es@gm.nosp@m.ail..nosp@m.com

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

Definition at line 43 of file Orca.cpp.