Line 28... |
Line 28... |
// $Id: Or1200MonitorSC.cpp 303 2009-02-16 11:20:17Z jeremy $
|
// $Id: Or1200MonitorSC.cpp 303 2009-02-16 11:20:17Z jeremy $
|
|
|
#include <iostream>
|
#include <iostream>
|
#include <iomanip>
|
#include <iomanip>
|
#include <fstream>
|
#include <fstream>
|
|
#include <sys/types.h>
|
|
#include <netinet/in.h>
|
using namespace std;
|
using namespace std;
|
|
|
#include "Or1200MonitorSC.h"
|
#include "Or1200MonitorSC.h"
|
#include "OrpsocMain.h"
|
#include "OrpsocMain.h"
|
|
|
Line 56... |
Line 57... |
|
|
// If not -log option, then don't log
|
// If not -log option, then don't log
|
|
|
string logfileDefault("vlt-executed.log");
|
string logfileDefault("vlt-executed.log");
|
string logfileNameString;
|
string logfileNameString;
|
int profiling_enabled = 0;
|
profiling_enabled = 0;
|
string profileFileName(DEFAULT_PROF_FILE);
|
string profileFileName(DEFAULT_PROF_FILE);
|
|
memdumpFileName = (DEFAULT_MEMDUMP_FILE);
|
|
int memdump_start = 0; int memdump_end = 0;
|
|
do_memdump = 0; // Default is not to do a dump of RAM at finish
|
|
|
insn_count=0;
|
insn_count=0;
|
cycle_count=0;
|
cycle_count=0;
|
|
|
exit_perf_summary_enabled = 1; // Simulation exit performance summary is
|
exit_perf_summary_enabled = 1; // Simulation exit performance summary is
|
// on by default. Turn off with "-q" on the cmd line
|
// on by default. Turn off with "-q" on the cmd line
|
Line 86... |
Line 91... |
}
|
}
|
else if ((strcmp(argv[i], "-p")==0) ||
|
else if ((strcmp(argv[i], "-p")==0) ||
|
(strcmp(argv[i], "--profile")==0))
|
(strcmp(argv[i], "--profile")==0))
|
{
|
{
|
profiling_enabled = 1;
|
profiling_enabled = 1;
|
// Check for !end of command line and it's not a command
|
// Check for !end of command line and that next thing is not a command
|
if ((i+1 < argc)){
|
if ((i+1 < argc)){
|
if(argv[i+1][0] != '-')
|
if(argv[i+1][0] != '-')
|
profileFileName = (argv[i+1]);
|
profileFileName = (argv[i+1]);
|
}
|
}
|
}
|
}
|
|
else if ((strcmp(argv[i], "-m")==0) ||
|
|
(strcmp(argv[i], "--mdump")==0))
|
|
{
|
|
do_memdump = 1;
|
|
// Check for !end of command line and that next thing is not a command
|
|
// or a memory address
|
|
if (i+1 < argc)
|
|
{
|
|
if((argv[i+1][0] != '-') && (strncmp("0x", argv[i+1],2) != 0))
|
|
{
|
|
// Hopefully this is the filename we want to use.
|
|
// All addresses should have preceeding hex identifier 0x
|
|
memdumpFileName = argv[i+1];
|
|
// We've used this next index, can safely increment i
|
|
i++;
|
|
}
|
|
}
|
|
if (i+1 < argc)
|
|
{
|
|
if((argv[i+1][0] != '-') && (strncmp("0x", argv[i+1],2) == 0))
|
|
{
|
|
// Hopefully this is is the start address
|
|
// All addresses should have preceeding hex identifier 0x
|
|
sscanf( argv[i+1], "0x%x", &memdump_start);
|
|
i++;
|
|
}
|
|
}
|
|
if (i+1 < argc)
|
|
{
|
|
if((argv[i+1][0] != '-') && (strncmp("0x", argv[i+1],2) == 0))
|
|
{
|
|
// Hopefully this is is the end address
|
|
// All addresses should have preceeding hex identifier 0x
|
|
sscanf( argv[i+1], "0x%x", &memdump_end);
|
|
i++;
|
|
}
|
|
}
|
|
}
|
}
|
}
|
}
|
}
|
|
|
|
|
|
|
if (profiling_enabled)
|
if (profiling_enabled)
|
{
|
{
|
profileFile.open(profileFileName.c_str(), ios::out); // Open profiling log file
|
profileFile.open(profileFileName.c_str(), ios::out); // Open profiling log file
|
if(profileFile.is_open())
|
if(profileFile.is_open())
|
{
|
{
|
Line 136... |
Line 180... |
sensitive << clk.pos();
|
sensitive << clk.pos();
|
dont_initialize();
|
dont_initialize();
|
start = clock();
|
start = clock();
|
}
|
}
|
|
|
|
// Check sizes we were given from memory dump command line options first
|
|
if (do_memdump)
|
|
{
|
|
if ((memdump_start > ORPSOC_SRAM_SIZE) || (memdump_end > ORPSOC_SRAM_SIZE) ||
|
|
((memdump_start > memdump_end) && (memdump_end != 0)))
|
|
{
|
|
do_memdump = 0;
|
|
cout << "* Memory dump addresses range incorrect. Limit of memory is 0x" << hex << ORPSOC_SRAM_SIZE << ". Memory dumping disabled." << endl;
|
|
}
|
|
}
|
|
|
|
if (do_memdump)
|
|
{
|
|
// Were we given dump addresses? If not, we dump all of the memory
|
|
// Size of memory isn't clearly defined in any one place. This could lead to
|
|
// big problems when changing size of the RAM in simulation.
|
|
|
|
if (memdump_start == 0 && memdump_end == 0)
|
|
memdump_end = ORPSOC_SRAM_SIZE;
|
|
|
|
if (memdump_start != 0 && memdump_end == 0)
|
|
{
|
|
// Probably just got the single memorydump param
|
|
// Interpet as a length from 0
|
|
memdump_end = memdump_start;
|
|
memdump_start = 0;
|
|
}
|
|
|
|
if (memdump_start & 0x3) memdump_start &= ~0x3; // word-align the start address
|
|
if (memdump_end & 0x3) memdump_end = (memdump_end+4) & ~0x3; // word-align the start address
|
|
|
|
memdump_start_addr = memdump_start;
|
|
memdump_end_addr = memdump_end;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
// checkInstruction monitors the bus for special NOP instructionsl
|
// checkInstruction monitors the bus for special NOP instructionsl
|
SC_METHOD (checkInstruction);
|
SC_METHOD (checkInstruction);
|
sensitive << clk.pos();
|
sensitive << clk.pos();
|
Line 151... |
Line 232... |
|
|
//! Print command line switches for the options of this module
|
//! Print command line switches for the options of this module
|
void
|
void
|
Or1200MonitorSC::printSwitches()
|
Or1200MonitorSC::printSwitches()
|
{
|
{
|
printf(" [-l <file>] [-q] [-p [<file>]]");
|
printf(" [-l <file>] [-q] [-p [<file>]] [-m [<file>] [<0xstardaddr> <0xendaddr>]]");
|
}
|
}
|
|
|
//! Print usage for the options of this module
|
//! Print usage for the options of this module
|
void
|
void
|
Or1200MonitorSC::printUsage()
|
Or1200MonitorSC::printUsage()
|
{
|
{
|
printf(" -p, --profile\t\tEnable execution profiling output to file (default "DEFAULT_PROF_FILE")\n");
|
printf(" -p, --profile\t\tEnable execution profiling output to file (default "DEFAULT_PROF_FILE")\n");
|
printf(" -l, --log\t\tLog processor execution to file\n");
|
printf(" -l, --log\t\tLog processor execution to file\n");
|
printf(" -q, --quiet\t\tDisable the performance summary at end of simulation\n");
|
printf(" -q, --quiet\t\tDisable the performance summary at end of simulation\n");
|
|
printf(" -m, --memdump\t\tDump data from the system's RAM to a file on finish\n\n");
|
}
|
}
|
|
|
//! Method to handle special instrutions
|
//! Method to handle special instrutions
|
|
|
//! These are l.nop instructions with constant values. At present the
|
//! These are l.nop instructions with constant values. At present the
|
Line 179... |
Line 261... |
Or1200MonitorSC::checkInstruction()
|
Or1200MonitorSC::checkInstruction()
|
{
|
{
|
uint32_t r3;
|
uint32_t r3;
|
double ts;
|
double ts;
|
|
|
|
cycle_count++;
|
// Check the instruction when the freeze signal is low.
|
// Check the instruction when the freeze signal is low.
|
if (!accessor->getWbFreeze())
|
//if (!accessor->getWbFreeze())
|
|
if ((!accessor->getWbFreeze()) && (accessor->getExceptType() == 0))
|
{
|
{
|
|
|
|
// Increment instruction counter
|
|
insn_count++;
|
|
|
// Do something if we have l.nop
|
// Do something if we have l.nop
|
switch (accessor->getWbInsn())
|
switch (accessor->getWbInsn())
|
{
|
{
|
case NOP_EXIT:
|
case NOP_EXIT:
|
r3 = accessor->getGpr (3);
|
r3 = accessor->getGpr (3);
|
ts = sc_time_stamp().to_seconds() * 1000000000.0;
|
ts = sc_time_stamp().to_seconds() * 1000000000.0;
|
std::cout << std::fixed << std::setprecision (2) << ts;
|
std::cout << std::fixed << std::setprecision (2) << ts;
|
std::cout << " ns: Exiting (" << r3 << ")" << std::endl;
|
std::cout << " ns: Exiting (" << r3 << ")" << std::endl;
|
perfSummary();
|
perfSummary();
|
if (logging_enabled != 0) statusFile.close();
|
if (logging_enabled) statusFile.close();
|
|
if (profiling_enabled) profileFile.close();
|
|
memdump();
|
SIM_RUNNING=0;
|
SIM_RUNNING=0;
|
sc_stop();
|
sc_stop();
|
break;
|
break;
|
|
|
case NOP_REPORT:
|
case NOP_REPORT:
|
Line 232... |
Line 322... |
uint32_t exinsn, delaypc;
|
uint32_t exinsn, delaypc;
|
uint32_t o_a; // operand a
|
uint32_t o_a; // operand a
|
uint32_t o_b; // operand b
|
uint32_t o_b; // operand b
|
struct label_entry *tmp;
|
struct label_entry *tmp;
|
|
|
cycle_count++;
|
|
// Instructions should be valid when freeze is low and there are no exceptions
|
// Instructions should be valid when freeze is low and there are no exceptions
|
//if (!accessor->getExFreeze())
|
//if (!accessor->getExFreeze())
|
if ((!accessor->getWbFreeze()) && (accessor->getExceptType() == 0))
|
if ((!accessor->getWbFreeze()) && (accessor->getExceptType() == 0))
|
{
|
{
|
// Increment instruction counter
|
|
insn_count++;
|
|
|
|
//exinsn = accessor->getExInsn();// & 0x3ffffff;
|
//exinsn = accessor->getExInsn();// & 0x3ffffff;
|
exinsn = accessor->getWbInsn();
|
exinsn = accessor->getWbInsn();
|
// Check the instruction
|
// Check the instruction
|
switch((exinsn >> 26) & 0x3f) { // Check Opcode - top 6 bits
|
switch((exinsn >> 26) & 0x3f) { // Check Opcode - top 6 bits
|
case 0x1:
|
case 0x1:
|
Line 357... |
Line 443... |
}
|
}
|
return;
|
return;
|
} // perfSummary
|
} // perfSummary
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|
|
//! Dump contents of simulation's RAM to file
|
|
void
|
|
Or1200MonitorSC::memdump()
|
|
{
|
|
if (!do_memdump) return;
|
|
uint32_t current_word;
|
|
int size_words = (memdump_end_addr/4) - (memdump_start_addr/4);
|
|
if (!(size_words > 0)) return;
|
|
|
|
// First try opening the file
|
|
memdumpFile.open(memdumpFileName.c_str(), ios::binary); // Open memorydump file
|
|
if(memdumpFile.is_open())
|
|
{
|
|
// If we could open the file then turn on logging
|
|
cout << "* Dumping system RAM from 0x" << hex << memdump_start_addr << "-0x" << hex << memdump_end_addr << " to file " << memdumpFileName << endl;
|
|
|
|
// Convert memdump_start_addr to word address
|
|
memdump_start_addr = memdump_start_addr / 4;
|
|
while (size_words)
|
|
{
|
|
// Read the data from the simulation memory
|
|
current_word = accessor->get_mem(memdump_start_addr);
|
|
//cout << hex << current_word << " ";
|
|
/*
|
|
cout << hex << ((current_word >> 24 ) & 0xff) << " ";
|
|
cout << hex << ((current_word >> 16) & 0xff) << " ";
|
|
cout << hex << ((current_word >> 8 ) & 0xff) << " " ;
|
|
cout << hex << ((current_word >> 0 ) & 0xff) << " ";
|
|
*/
|
|
// Change from whatever endian the host is (most
|
|
// cases little) to big endian
|
|
current_word = htonl(current_word);
|
|
memdumpFile.write((char*) ¤t_word, 4);
|
|
memdump_start_addr++; size_words--;
|
|
}
|
|
|
|
// Ideally we've now finished piping out the data
|
|
// not 100% about the endianess of this.
|
|
}
|
|
memdumpFile.close();
|
|
|
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|