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

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc
    from Rev 48 to Rev 49
    Reverse comparison

Rev 48 → Rev 49

/trunk/orpsocv2/bench/sysc/include/Or1200MonitorSC.h
51,23 → 51,30
 
// Constructor
Or1200MonitorSC (sc_core::sc_module_name name,
OrpsocAccess *_accessor);
OrpsocAccess *_accessor,
int argc,
char *argv[]);
 
// Method to check instructions
void checkInstruction();
 
// Methods to setup and output state of processor to a file
void init_displayState(int argc,char *argv[]);
void displayState();
 
// Function to calculate performance of the sim
void perfSummary();
 
// Print out the command-line switches for this module's options
void printSwitches();
 
// Print out the usage for each option
void printUsage();
 
// The ports
sc_in<bool> clk;
 
private:
 
// Function to calculate performance of the sim
void perfSummary();
 
// Special NOP instructions
static const uint32_t NOP_NOP = 0x15000000; //!< Normal nop instruction
static const uint32_t NOP_EXIT = 0x15000001; //!< End of simulation
/trunk/orpsocv2/bench/sysc/include/TraceSC.h
33,6 → 33,7
 
#include "Vorpsoc_top.h"
 
 
#if VM_TRACE
#include <SpTraceVcdC.h>
#endif
57,8 → 58,13
// Method to drive the trace
void driveTrace();
 
// VCD dump controling vars
int dump_start_delay, dump_stop_set;
int dumping_now;
sc_time dump_start,dump_stop;
/* The port */
sc_in<bool> clk;
//sc_in<bool> clk;
 
private:
 
65,6 → 71,7
//! The ORPSoC module we are tracing
Vorpsoc_top *traceTarget;
 
 
#if VM_TRACE
//! The System Perl Trace file
SpTraceVcdCFile *spTraceFile;
/trunk/orpsocv2/bench/sysc/include/OrpsocAccess.h
55,7 → 55,9
// Accessor functions
bool getWbFreeze ();
uint32_t getWbInsn ();
uint32_t getIdInsn ();
uint32_t getWbPC ();
uint32_t getIdPC ();
bool getExceptFlushpipe ();
bool getExDslot ();
// Get a specific GPR from the register file
/trunk/orpsocv2/bench/sysc/src/Or1200MonitorSC.cpp
45,25 → 45,96
//! @param[in] accessor Accessor class for this Verilated ORPSoC model
 
Or1200MonitorSC::Or1200MonitorSC (sc_core::sc_module_name name,
OrpsocAccess *_accessor) :
OrpsocAccess *_accessor,
int argc,
char *argv[]) :
sc_module (name),
accessor (_accessor)
{
SC_METHOD (checkInstruction);
 
// If not -log option, then don't log
string logfileDefault("vlt-executed.log");
string logfileNameString;
 
exit_perf_summary_enabled = 1; // Simulation exit performance summary is
// on by default. Turn off with "-q" on the cmd line
 
// Parse the command line options
int cmdline_name_found=0;
if (argc > 1)
{
// Search through the command line parameters for the "-log" option
for(int i=1; i < argc; i++)
{
if ((strcmp(argv[i], "-l")==0) ||
(strcmp(argv[i], "--log")==0))
{
logfileNameString = (argv[i+1]);
cmdline_name_found=1;
break;
}
}
// Search through the command line parameters for the "-q","--no-perf-summary" option
for(int i=1; i < argc; i++)
{
if ((strcmp(argv[i], "-q")==0) ||
(strcmp(argv[i], "--quiet")==0))
{
exit_perf_summary_enabled = 0;
break;
}
}
}
 
if(cmdline_name_found==1) // No -log option specified so don't turn on logging
{
 
logging_enabled = 0; // Default is logging disabled
statusFile.open(logfileNameString.c_str(), ios::out ); // open file to write to it
 
if(statusFile.is_open())
{
// If we could open the file then turn on logging
logging_enabled = 1;
cout << "* Processor execution logged to file: " << logfileNameString << endl;
}
}
 
SC_METHOD (displayState);
sensitive << clk.pos();
dont_initialize();
start = clock();
 
SC_METHOD (displayState);
logging_enabled = 0; // Default is logging disabled
exit_perf_summary_enabled = 1; // Simulation exit performance summary is on by default. Turn off with "-q" on the cmd line
// checkInstruction monitors the bus for special NOP instructionsl
SC_METHOD (checkInstruction);
sensitive << clk.pos();
dont_initialize();
 
start = clock();
} // Or1200MonitorSC ()
 
//! Print command line switches for the options of this module
void
Or1200MonitorSC::printSwitches()
{
printf(" [-l <file>] [-q]");
}
 
//! Print usage for the options of this module
void
Or1200MonitorSC::printUsage()
{
printf(" -l, --log\t\tLog processor execution to file\n");
printf(" -q, --quiet\t\tDisable the performance summary at end of simulation\n");
}
 
//! Method to handle special instrutions
 
//! These are l.nop instructions with constant values. At present the
73,7 → 144,7
//! - l.nop 2 Report the value in R3
//! - l.nop 3 Printf the string with the arguments in R3, etc
//! - l.nop 4 Print a character
 
extern int SIM_RUNNING;
void
Or1200MonitorSC::checkInstruction()
{
91,8 → 162,9
ts = sc_time_stamp().to_seconds() * 1000000000.0;
std::cout << std::fixed << std::setprecision (2) << ts;
std::cout << " ns: Exiting (" << r3 << ")" << std::endl;
if (exit_perf_summary_enabled) perfSummary();
perfSummary();
if (logging_enabled != 0) statusFile.close();
SIM_RUNNING=0;
sc_stop();
break;
 
121,65 → 193,12
 
} // checkInstruction()
 
//! Method to setup the files for outputting the state of the processor
 
//! This function will setup the output file, if enabled.
 
void
Or1200MonitorSC::init_displayState(int argc, char *argv[])
{
 
string logfileDefault("vlt-executed.log");
string logfileNameString;
 
// Parse the command line options
int cmdline_name_found=0;
if (argc > 1)
{
// Search through the command line parameters for the "-log" option
for(int i=1; i < argc; i++)
{
if (strcmp(argv[i], "-log")==0)
{
logfileNameString = (argv[i+1]);
cmdline_name_found=1;
break;
}
}
// Search through the command line parameters for the "-q","--no-perf-summary" option
for(int i=1; i < argc; i++)
{
if ((strcmp(argv[i], "-q")==0)||(strcmp(argv[i], "--no-perf-summary")==0))
{
exit_perf_summary_enabled = 0;
break;
}
}
 
}
 
if(cmdline_name_found==0) // No -log option specified so don't turn on logging
return;
 
statusFile.open(logfileNameString.c_str(), ios::out ); // open file to write to it
 
if(statusFile.is_open())
{
// If we could open the file then turn on logging
logging_enabled = 1;
cout << "Processor execution logged to file: " << logfileNameString << endl;
}
 
return;
 
}
 
//! Method to output the state of the processor
 
//! This function will output to a file, if enabled, the status of the processor
//! For now, it's just the PPC and instruction.
 
#define PRINT_REGS 0
void
Or1200MonitorSC::displayState()
{
198,10 → 217,10
{
// Print PC, instruction
statusFile << "\nEXECUTED("<< std::setfill(' ') << std::setw(11) << dec << insn_count << "): " << std::setfill('0') << hex << std::setw(8) << accessor->getWbPC() << ": " << hex << accessor->getWbInsn() << endl;
 
#if PRINT_REGS
// Print general purpose register contents
for (int i=0; i<32; i++)
{
{
if ((i%4 == 0)&&(i>0)) statusFile << endl;
statusFile << std::setfill('0');
statusFile << "GPR" << dec << std::setw(2) << i << ": " << hex << std::setw(8) << (uint32_t) accessor->getGpr(i) << " ";
212,6 → 231,7
statusFile << "EPCR0: " << hex << std::setw(8) << (uint32_t) accessor->getSprEpcr() << " ";
statusFile << "EEAR0: " << hex << std::setw(8) << (uint32_t) accessor->getSprEear() << " ";
statusFile << "ESR0 : " << hex << std::setw(8) << (uint32_t) accessor->getSprEsr() << endl;
#endif
 
}
 
223,18 → 243,22
void
Or1200MonitorSC::perfSummary()
{
double ts;
ts = sc_time_stamp().to_seconds() * 1000000000.0;
int cycles = ts / (BENCH_CLK_HALFPERIOD*2); // Number of clock cycles we had
if (exit_perf_summary_enabled)
{
double ts;
ts = sc_time_stamp().to_seconds() * 1000000000.0;
int cycles = ts / (BENCH_CLK_HALFPERIOD*2); // Number of clock cycles we had
clock_t finish = clock();
double elapsed_time = (double(finish)-double(start))/CLOCKS_PER_SEC;
// It took elapsed_time seconds to do insn_count instructions. Divide insn_count by the time to get instructions/second.
double ips = (insn_count/elapsed_time);
double mips = (insn_count/elapsed_time)/1000000;
int hertz = (int) ((cycles/elapsed_time)/1000);
std::cout << "* Or1200Monitor: simulated " << sc_time_stamp() << ",time elapsed: " << elapsed_time << " seconds" << endl;
std::cout << "* Or1200Monitor: simulated " << dec << cycles << " clock cycles, executed at approx " << hertz << "kHz" << endl;
std::cout << "* Or1200Monitor: simulated " << insn_count << " instructions, insn/sec. = " << ips << ", mips = " << mips << endl;
}
return;
} // perfSummary
 
clock_t finish = clock();
double elapsed_time = (double(finish)-double(start))/CLOCKS_PER_SEC;
// It took elapsed_time seconds to do insn_count instructions. Divide insn_count by the time to get instructions/second.
double ips = (insn_count/elapsed_time);
double mips = (insn_count/elapsed_time)/1000000;
std::cout << "Or1200Monitor: real time elapsed: " << elapsed_time << " seconds" << endl;
std::cout << "Or1200Monitor: simulated " << dec << cycles << " clock cycles, executed " << insn_count << " instructions" << endl;
std::cout << "Or1200Monitor: simulated insn/sec = " << ips << ", simulator mips = " << mips << endl;
return;
} // calculateMips()
 
/trunk/orpsocv2/bench/sysc/src/Modules.make
26,8 → 26,13
# Tools and flags
ARFLAGS = rcs
#CXXFLAGS += $(OPT_FAST) $(OPT_SLOW) $(OPT) $(PROF_FLAGS)
 
ifdef VLT_CPPFLAGS
CXXFLAGS += $(VLT_CPPFLAGS)
endif
 
CXX ?= g++
PROF_OPTS ?= -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer
#PROF_OPTS ?= -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -O3
OPT_ALL ?= $(OPT_SLOW) $(OPT_FAST) $(OPT)
 
# Sub-directories
40,6 → 45,10
UartSC.o
LIB = libmodules.a
 
ifdef VLT_DEBUG
CXXFLAGS += -g
endif
 
# -----------------------------------------------------------------------------
# Rule to make dependency files
%.d: %.cpp
50,7 → 59,7
 
# Rule to make object files
%.o: %.cpp
$(CXX) $(CPPFLAGS) $(INCDIRS) $(CXXFLAGS) -c $<
$(CXX) $(CPPFLAGS) $(PROF_OPTS) $(INCDIRS) $(CXXFLAGS) -c $<
 
 
# -----------------------------------------------------------------------------
/trunk/orpsocv2/bench/sysc/src/TraceSC.cpp
27,9 → 27,12
// $Id: TraceSC.cpp 302 2009-02-13 17:22:07Z jeremy $
 
#include "TraceSC.h"
#include <systemc.h>
 
using namespace std;
 
#define DEBUG_TRACESC 1
 
SC_HAS_PROCESS( TraceSC );
 
//! Constructor for the trace module
52,31 → 55,62
string testNameString;
string vcdDumpFile;
 
// Search through the command line parameters for the "-vcd" option
// Search through the command line parameters for VCD dump options
dump_start_delay = 0;
dump_stop_set = 0;
int time_val;
int cmdline_name_found=0;
if (argc > 1)
{
for(int i=1; i<argc; i++)
{
if (strcmp(argv[i], "-vcd")==0)
if ((strcmp(argv[i], "-vcd")==0) ||
(strcmp(argv[i], "--vcd")==0))
{
testNameString = (argv[i+1]);
vcdDumpFile = testNameString;
cmdline_name_found=1;
}
else if ( (strcmp(argv[i], "-vcdstart")==0) ||
(strcmp(argv[i], "--vcdstart")==0) )
{
time_val = atoi(argv[i+1]);
sc_time dump_start_time(time_val,SC_NS);
dump_start = dump_start_time;
if (DEBUG_TRACESC) cout << "TraceSC(): Dump start time set at " << dump_start.to_string() << endl;
dump_start_delay = 1;
break;
}
else if ( (strcmp(argv[i], "-vcdstop")==0) ||
(strcmp(argv[i], "--vcdstop")==0) )
{
time_val = atoi(argv[i+1]);
sc_time dump_stop_time(time_val,SC_NS);
dump_stop = dump_stop_time;
if (DEBUG_TRACESC) cout << "TraceSC(): Dump stop time set at " << dump_stop.to_string() << endl;
dump_stop_set = 1;
break;
}
}
}
 
if(cmdline_name_found==0) // otherwise use our default VCD dump file name
vcdDumpFile = dumpNameDefault;
Verilated::traceEverOn (true);
cout << "Enabling VCD trace" << endl;
cout << "* Enabling VCD trace";
if (dump_start_delay)
cout << ", on at time " << dump_start.to_string();
if (dump_stop_set)
cout << ", off at time " << dump_stop.to_string();
cout << endl;
 
printf("VCD dumpfile: %s\n", vcdDumpFile.c_str());
 
printf("* VCD dumpfile: %s\n", vcdDumpFile.c_str());
 
// Establish a new trace with its correct time resolution, and trace to
// great depth.
spTraceFile = new SpTraceVcdCFile ();
84,9 → 118,15
traceTarget->trace (spTraceFile, 99);
spTraceFile->open (vcdDumpFile.c_str());
 
if (dump_start_delay == 1)
dumping_now = 0; // We'll wait for the time to dump
else
dumping_now = 1; // Begin with dumping turned on
 
 
// Method to drive the dump on each clock edge
SC_METHOD (driveTrace);
sensitive << clk;
//SC_METHOD (driveTrace);
//sensitive << clk;
#endif
106,13 → 146,40
} // ~TraceSC ()
 
 
//! Method to drive the trace. We're called on ever clock edge, and also at
//! Method to drive the trace. We're called on every clock edge, and also at
//! initialization (to get initial values into the dump).
void
TraceSC::driveTrace()
{
#if VM_TRACE
spTraceFile->dump (sc_time_stamp().to_double());
 
if (DEBUG_TRACESC) cout << "TraceSC(): " << endl;
if (dumping_now == 0)
{
// Check the time, see if we should enable dumping
if (sc_time_stamp() >= dump_start)
{
// Give a message
cout << "* VCD tracing turned on at time " << dump_start.to_string() << endl;
dumping_now = 1;
}
}
 
if (dumping_now == 1)
spTraceFile->dump (sc_time_stamp().to_double());
 
// Should we turn off tracing?
if ((dumping_now == 1) && (dump_stop_set == 1))
{
if (sc_time_stamp() >= dump_stop)
{
// Give a message
cout << "* VCD tracing turned off at time " << dump_stop.to_string() << endl;
dumping_now = 0; // Turn off the dump
}
}
 
#endif
 
} // driveTrace()
135,7 → 202,7
 
if (secs < 1.0e-15)
{
cerr << "VCD time resolution " << secs << " too small: ignored" << endl;
cerr << "* VCD time resolution " << secs << " too small: ignored" << endl;
return;
}
else if (secs < 1.0e-12)
/trunk/orpsocv2/bench/sysc/src/OrpsocAccess.cpp
90,9 → 90,20
 
} // getExDslot ()
 
//! Access for the id_pc register
 
//! @return The value of the or1200_except.id_pc register
 
uint32_t
OrpsocAccess::getIdPC ()
{
return (or1200_except->get_id_pc) ();
 
} // getIdPC ()
 
//! Access for the wb_pc register
 
//! @return The value of the or1200_except.wb_insn register
//! @return The value of the or1200_except.wb_pc register
 
uint32_t
OrpsocAccess::getWbPC ()
112,7 → 123,17
 
} // getWbInsn ()
 
//! Access for the id_insn register
 
//! @return The value of the or1200_ctrl.wb_insn register
 
uint32_t
OrpsocAccess::getIdInsn ()
{
return (or1200_ctrl->get_id_insn) ();
 
} // getIdInsn ()
 
//! Access for the OR1200 GPRs
 
//! These are extracted from memory using the Verilog function
/trunk/orpsocv2/bench/sysc/src/OrpsocMain.cpp
45,16 → 45,22
 
#include "Vorpsoc_top.h"
#include "OrpsocAccess.h"
#include "TraceSC.h"
 
//#if VM_TRACE
//#include <systemc.h>
#include <SpTraceVcdC.h>
//#endif
 
//#include "TraceSC.h"
#include "ResetSC.h"
#include "Or1200MonitorSC.h"
#include "UartSC.h"
 
 
int SIM_RUNNING;
int sc_main (int argc,
char *argv[] )
{
 
sc_set_time_resolution( 1, TIMESCALE_UNIT);
// CPU clock (also used as JTAG TCK) and reset (both active high and low)
sc_time clkPeriod (BENCH_CLK_HALFPERIOD * 2.0, TIMESCALE_UNIT);
 
83,13 → 89,30
sc_signal<bool> spi1_ss;
sc_signal<bool> spi1_sclk;
 
SIM_RUNNING = 0;
 
// Setup the name of the VCD dump file
int VCD_enabled = 0;
string dumpNameDefault("vlt-dump.vcd");
string testNameString;
string vcdDumpFile;
// VCD dump controling vars
int dump_start_delay, dump_stop_set;
int dumping_now;
int dump_depth = 99; // Default dump depth
sc_time dump_start,dump_stop, finish_time;
int finish_time_set = 0; // By default we will let the simulation finish naturally
SpTraceVcdCFile *spTraceFile;
int time_val;
int cmdline_name_found=0;
 
// Verilator accessor
OrpsocAccess *accessor;
 
// Modules
Vorpsoc_top *orpsoc; // Verilated ORPSoC
TraceSC *trace; // Drive VCD
//TraceSC *trace; // Drive VCD
ResetSC *reset; // Generate a RESET signal
Or1200MonitorSC *monitor; // Handle l.nop x instructions
97,14 → 120,117
 
// Instantiate the Verilator model, VCD trace handler and accessor
orpsoc = new Vorpsoc_top ("orpsoc");
trace = new TraceSC ("trace", orpsoc, argc, argv);
//trace = new TraceSC ("trace", orpsoc, argc, argv);
accessor = new OrpsocAccess (orpsoc);
// Instantiate the SystemC modules
reset = new ResetSC ("reset", BENCH_RESET_TIME);
monitor = new Or1200MonitorSC ("monitor", accessor);
monitor = new Or1200MonitorSC ("monitor", accessor, argc, argv);
uart = new UartSC("uart"); // TODO: Probalby some sort of param
 
 
// Parse command line options
// Default is for VCD generation OFF, only turned on if specified on command line
dump_start_delay = 0;
dump_stop_set = 0;
dumping_now = 0;
 
// Search through the command line parameters for options
if (argc > 1)
{
for(int i=1; i<argc; i++)
{
if ((strcmp(argv[i], "-d")==0) ||
(strcmp(argv[i], "--vcdfile")==0))
{
testNameString = (argv[i+1]);
vcdDumpFile = testNameString;
cmdline_name_found=1;
}
else if ((strcmp(argv[i], "-v")==0) ||
(strcmp(argv[i], "--vcdon")==0))
{
dumping_now = 1;
}
else if ( (strcmp(argv[i], "-e")==0) ||
(strcmp(argv[i], "--endtime")==0) )
{
time_val = atoi(argv[i+1]);
sc_time opt_end_time(time_val,TIMESCALE_UNIT);
finish_time = opt_end_time;
//if (DEBUG_TRACESC) cout << "* Commmand line opt: Sim. will end at " << finish_time.to_string() << endl;
finish_time_set = 1;
}
//#if VM_TRACE
else if ( (strcmp(argv[i], "-s")==0) ||
(strcmp(argv[i], "--vcdstart")==0) )
{
time_val = atoi(argv[i+1]);
sc_time dump_start_time(time_val,TIMESCALE_UNIT);
dump_start = dump_start_time;
//if (DEBUG_TRACESC) cout << "* Commmand line opt: Dump start time set at " << dump_start.to_string() << endl;
dump_start_delay = 1;
dumping_now = 0;
}
else if ( (strcmp(argv[i], "-t")==0) ||
(strcmp(argv[i], "--vcdstop")==0) )
{
time_val = atoi(argv[i+1]);
sc_time dump_stop_time(time_val,TIMESCALE_UNIT);
dump_stop = dump_stop_time;
//if (DEBUG_TRACESC) cout << "* Commmand line opt: Dump stop time set at " << dump_stop.to_string() << endl;
dump_stop_set = 1;
}
/* Depth setting of VCD doesn't appear to work, I think it's set during verilator script compile time */
/* else if ( (strcmp(argv[i], "-p")==0) ||
(strcmp(argv[i], "--vcddepth")==0) )
{
dump_depth = atoi(argv[i+1]);
//if (DEBUG_TRACESC) cout << "* Commmand line opt: Dump depth set to " << dump_depth << endl;
}*/
else if ( (strcmp(argv[i], "-h")==0) ||
(strcmp(argv[i], "--help")==0) )
{
printf("\n ORPSoC Cycle Accurate model usage:\n");
printf(" %s [-vh] [-d <file>] [-e <time>] [-s <time>] [-t <time>]",argv[0]);
monitor->printSwitches();
printf("\n\n");
printf(" -h, --help\t\tPrint this help message\n");
printf(" -e, --endtime\t\tStop the sim at this time (ns)\n");
printf(" -v, --vcdon\t\tEnable VCD generation\n");
printf(" -d, --vcdfile\t\tEnable and specify target VCD file name\n");
 
printf(" -s, --vcdstart\tEnable and delay VCD generation until this time (ns)\n");
printf(" -t, --vcdstop\t\tEnable and terminate VCD generation at this time (ns)\n");
monitor->printUsage();
printf("\n");
return 0;
}
}
}
 
if(cmdline_name_found==0) // otherwise use our default VCD dump file name
vcdDumpFile = dumpNameDefault;
// Determine if we're going to setup a VCD dump:
// Pretty much setting any option will enable VCD dumping.
if ((cmdline_name_found) || (dumping_now) || (dump_start_delay) || (dump_stop_set))
{
VCD_enabled = 1;
cout << "* Enabling VCD trace";
if (dump_start_delay)
cout << ", on at time " << dump_start.to_string();
if (dump_stop_set)
cout << ", off at time " << dump_stop.to_string();
cout << endl;
}
 
 
// Connect up ORPSoC
orpsoc->clk_pad_i (clk);
orpsoc->rst_pad_i (rstn);
131,11 → 257,10
 
orpsoc->gpio_a_pad_io (gpio_a); // GPIO bus - output only in
// verilator sims
 
// Connect up the VCD trace handler
trace->clk (clk); // Trace
 
//trace->clk (clk); // Trace
// Connect up the SystemC modules
reset->clk (clk); // Reset
reset->rst (rst);
154,18 → 279,124
spi_sd_miso = 0; // Tie off master-in/slave-out of SD SPI bus
 
spi1_miso = 0;
 
//#if VM_TRACE
if (VCD_enabled)
{
Verilated::traceEverOn (true);
printf("* VCD dumpfile: %s\n", vcdDumpFile.c_str());
// Establish a new trace with its correct time resolution, and trace to
// great depth.
spTraceFile = new SpTraceVcdCFile ();
//spTraceFile->spTrace()->set_time_resolution (sc_get_time_resolution());
//setSpTimeResolution (sc_get_time_resolution ());
//traceTarget->trace (spTraceFile, 99);
orpsoc->trace (spTraceFile, dump_depth);
if (dumping_now)
{
spTraceFile->open (vcdDumpFile.c_str());
}
//#endif
}
printf("Beginning test\n");
printf("* Beginning test\n");
 
// Init the UART function
uart->initUart(25000000, 115200);
 
// Turn on logging by setting the "-log logfilename" option on the command line
monitor->init_displayState(argc, argv);
SIM_RUNNING = 1;
 
// Execute until we stop
sc_start ();
// First check how we should run the sim.
if (VCD_enabled || finish_time_set)
{ // We'll run sim with step
if (!VCD_enabled && finish_time_set)
{
// We just run the sim until the set finish time
sc_start((double)(finish_time.to_double()), TIMESCALE_UNIT);
SIM_RUNNING=0;
sc_stop();
// Print performance summary
monitor->perfSummary();
}
else
{
if (dump_start_delay)
{
// Run the sim until we want to dump
sc_start((double)(dump_start.to_double()),TIMESCALE_UNIT);
// Open the trace file
spTraceFile->open (vcdDumpFile.c_str());
dumping_now = 1;
}
 
if (dumping_now)
{
// Step the sim and generate the trace
// Execute until we stop
while(!Verilated::gotFinish())
{
if (SIM_RUNNING) // Changed by Or1200MonitorSC when finish NOP
sc_start (1,TIMESCALE_UNIT); // Step the sim
else
{
spTraceFile->close();
break;
}
spTraceFile->dump (sc_time_stamp().to_double());
if (dump_stop_set)
{
if (sc_time_stamp() >= dump_stop)
{
// Close dump file
spTraceFile->close();
// Now continue on again until the end
if (!finish_time_set)
sc_start();
else
{
// Determine how long we should run for
sc_time sim_time_remaining =
finish_time - sc_time_stamp();
sc_start((double)(sim_time_remaining.to_double()),
TIMESCALE_UNIT);
// Officially stop the sim
sc_stop();
// Print performance summary
monitor->perfSummary();
}
break;
}
}
if (finish_time_set)
{
if (sc_time_stamp() >= finish_time)
{
// Officially stop the sim
sc_stop();
// Close dump file
spTraceFile->close();
// Print performance summary
monitor->perfSummary();
break;
}
}
}
}
}
}
else
{
// Simple run case
sc_start();
}
// Free memory
delete monitor;
delete reset;
172,7 → 403,7
 
delete accessor;
 
delete trace;
//delete trace;
delete orpsoc;
 
return 0;
/trunk/orpsocv2/bench/verilog/eth_stim.v
49,7 → 49,7
initial
begin
 
repeat(30000) @(posedge eth_clk);
repeat(170000) @(posedge eth_clk);
rx_packet_length = 16'd96; // Bytes
58,9 → 58,18
set_rx_addr_type(0, 48'h0102_0304_0506, 48'h0708_090A_0B0C, 16'h0D0E);
append_rx_crc(0, rx_packet_length, 1'b0, 1'b0);
 
/*
// write to phy's control register for 10Mbps
#Tp eth_phy0.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
#Tp eth_phy0.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD
*/
/*
// write to phy's control register for 100Mbps
#Tp eth_phy0.control_bit14_10 = 5'b01000; // bit 13 reset - speed 100
#Tp eth_phy0.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD
*/
 
//#Tp eth_phy0.carrier_sense_tx_fd_detect(1); // Full duplex CRS detect normally off
 
/*
74,9 → 83,10
input plus_drible_nibble; // if length is longer for one nibble
*/
#100000 eth_phy0.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, 0, rx_packet_length, 1'b0);
 
// while (1)
// begin
#300000 eth_phy0.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, 0, rx_packet_length, 1'b0);
//end
/* TODO: Some checking here that the packet's contents actually ended up in RAM correctly */
end
/trunk/orpsocv2/bench/verilog/eth_phy_defines.v
54,7 → 54,7
// LED/Configuration pins on PHY device - see the specification, page 26, table 8
// Initial set of bits 13, 12 and 8 of Control Register
`define LED_CFG1 1'b0
`define LED_CFG2 1'b0
`define LED_CFG2 1'b1
`define LED_CFG3 1'b1
 
 
/trunk/orpsocv2/bench/verilog/eth_phy.v
79,7 → 79,7
`define UNICAST_WRONG_XFR 3
 
 
//`define ETH_PHY_VERBOSE 1
`define ETH_PHY_VERBOSE 1
 
module eth_phy // This PHY model simulate simplified Intel LXT971A PHY
(
/trunk/orpsocv2/bench/verilog/smii_phy.v
44,7 → 44,7
// SMII
input smii_tx,
input smii_sync,
output smii_rx,
output reg smii_rx,
// MII
// TX
89,6 → 89,10
/* Generate the state counter, based on incoming sync signal */
/* 10-bit shift register, indicating where we are */
reg [10:1] state_shiftreg;
/* A wire hooked up from bit 0 with the last byte of the state counter/shiftreg */
wire [7:0] state_shiftreg_top_byte;
assign state_shiftreg_top_byte[7:0] = state_shiftreg[10:3];
 
always @(posedge clk)
begin
127,94 → 131,133
else /* Increment */
segment_ctr <= segment_ctr + 1'b1;
end
end
end // always @ (posedge clk)
 
/**************************************************************************/
/* RX path logic PHY->(MII->SMII)->MAC */
/**************************************************************************/
 
reg rx_nibble_sel, rx_byte_valid;
reg [7:0] rx_data_byte_rx_clk;
reg [7:0] rx_data_byte_rx_clk;
 
/* Receive the RX data from the PHY and serialise it */
/* If RX data valid goes high, then it's the beginning of a
proper data segment*/
reg [4:0] rx_dv_nib_0;
reg rx_nib_first,rx_nib_first_r; // if high, nib_0 contains the "first" of the pair of nibs
reg [3:0] rx_segment_begin_num;
 
// Allow us to check if RX DV has been low for a while
reg [3:0] rx_dv_long_low_sr;
wire dv_long_low;
always @(posedge ethphy_mii_rx_clk)
rx_dv_long_low_sr[3:0] <= {rx_dv_long_low_sr[2:0], ethphy_mii_rx_dv};
assign rx_dv_long_low = ~(|rx_dv_long_low_sr);
reg rx_dv;
wire [8:0] rx_fifo_out;
wire rx_fifo_empty,rx_fifo_almost_empty;
reg rx_fifo_pop;
always @(posedge ethphy_mii_rx_clk or negedge rst_n)
begin
if(!rst_n)
begin
rx_nibble_sel <= 0; /* start with low nibble receiving */
rx_data_byte_rx_clk <= 0;
rx_byte_valid <= 0;
rx_dv_nib_0 <= 0;
rx_nib_first <= 0;
rx_nib_first_r <= 0;
end
else
begin
/* Half way through, and at the end of each 10-bit section
and whenever we should load a new segment (each time for
fast ethernet, else once every 10 times; whenever segment_ctr
is 0)*/
//if ((state_shiftreg[6] | state_shiftreg[10]) & (segment_ctr==4'h0))
// begin
/* Alternate the nibble we're selecting when RX_dv */
if(!ethphy_mii_rx_dv) /* data on rx line is not valid */
rx_nibble_sel <= 0;
else
rx_nibble_sel <= ~rx_nibble_sel;
if (!rx_nib_first)
rx_dv_nib_0 <= {ethphy_mii_rx_dv,ethphy_mii_rx_d};
if(ethphy_mii_rx_dv)
rx_nib_first <= ~rx_nib_first;
 
if (!ethphy_mii_rx_dv & !rx_nibble_sel)
rx_byte_valid <= 0;
else if (rx_nibble_sel) /* sampled high nibble, byte OK*/
rx_byte_valid <= 1;
if (ethphy_mii_rx_dv & !rx_nibble_sel)
/* Sampling low nibble */
rx_data_byte_rx_clk[3:0] <= ethphy_mii_rx_d;
else if (ethphy_mii_rx_dv & rx_nibble_sel)
/* Sample high nibble */
rx_data_byte_rx_clk[7:4] <= ethphy_mii_rx_d;
//end // if ((state_shiftreg[4] | state_shiftreg[9]) & (segment_ctr==4'h0))
end // else: !if(!rst_n)
end // always @ (posedge clk)'
rx_nib_first_r <= rx_nib_first;
end
end // always @ (posedge ethphy_mii_rx_clk or negedge rst_n)
 
/* SMII domain RX signals */
reg [7:0] rx_data_byte;
reg rx_line_rx_dv; /* Reg for second bit of SMII RX sequence, RX_DV */
always @(posedge clk or negedge rst_n)
begin
if (!rst_n) rx_fifo_pop <= 0;
else rx_fifo_pop <= (rx_fifo_almost_empty) ? (rx_fifo_pop ? ~rx_fifo_empty : rx_fifo_pop) : 1;
 
/* A wire hooked up from bit 0 with the last byte of the state counter/shiftreg */
wire [7:0] state_shiftreg_top_byte;
assign state_shiftreg_top_byte[7:0] = state_shiftreg[10:3];
rx_dv <= (state_shiftreg[10] & (((rx_segment_begin_num == (segment_ctr-1)) && !fast_ethernet)| fast_ethernet)) ? (rx_fifo_pop) : rx_dv;
end
/* Move RX's DV and data into SMII clk domain */
always @(posedge clk)
begin
if(!rst_n)
begin
rx_line_rx_dv <= 0;
end
else
begin
/* When we're at the beginning of a new 10-bit sequence and
the beginning of the 10-segment loop load the valid bit */
if(state_shiftreg[1] & (segment_ctr==4'h0))
begin
rx_line_rx_dv <= rx_byte_valid;
rx_data_byte <= rx_data_byte_rx_clk;
end
end // else: !if(!rst_n)
end // always @ (posedge clk)
/* remember which counter value we were at when rx enable/valid
went high.
This is only useful when not doing fast ethernet*/
 
/* rx en has gone high - remember the sequence number we're in */
if ((rx_segment_begin_num == 4'hf) & (~rx_dv_long_low))
rx_segment_begin_num <= segment_ctr;
/* If rx enable goes low again, reset the segment number */
if (rx_dv_long_low)
/* reset to 0xf */
rx_segment_begin_num <= 4'hf;
end
/* Assign the rx line out */
assign smii_rx = state_shiftreg[1] ? ethphy_mii_crs : /* 1st bit is MII CRS */
/* next is RX_DV bit */
state_shiftreg[2] ? ((rx_byte_valid & (segment_ctr==4'h0)) |
rx_line_rx_dv) :
/* Depending on RX_DV, output the status byte or data byte */
rx_line_rx_dv ? |(state_shiftreg_top_byte & rx_data_byte) :
/* Output status byte */
|(state_shiftreg_top_byte &
 
/* A fifo, storing RX bytes coming from the PHY interface */
generic_fifo #(9, 64) rx_fifo
(
// Outputs
.psh_full (),
.pop_q (rx_fifo_out),
.pop_empty (rx_fifo_empty),
.almost_empty (rx_fifo_almost_empty),
// Inputs
.async_rst_n (rst_n),
.psh_clk (ethphy_mii_rx_clk),
.psh_we (rx_nib_first_r),
.psh_d ({ethphy_mii_rx_err,ethphy_mii_rx_d,rx_dv_nib_0[3:0]}),
.pop_clk (clk),
.pop_re ((state_shiftreg[1] & rx_fifo_pop)&(((rx_segment_begin_num == segment_ctr) && !fast_ethernet)| fast_ethernet)));
 
`ifdef RX_SYNC_1
/* Assign the rx line out */
always @(posedge clk)
smii_rx <= state_shiftreg[1] ? ethphy_mii_crs : /* 1st bit is MII CRS */
state_shiftreg[2] ? ((rx_dv & (segment_ctr==4'h0) & !fast_ethernet) |
rx_dv) :
// inter-frame status byte or data byte
state_shiftreg[3] ? (rx_dv ? (rx_fifo_out[0]) : ethphy_mii_rx_err) :
state_shiftreg[4] ? (rx_dv ? (rx_fifo_out[1]) : fast_ethernet) :
state_shiftreg[5] ? (rx_dv ? (rx_fifo_out[2]) : duplex) :
state_shiftreg[6] ? (rx_dv ? (rx_fifo_out[3]) : link) :
state_shiftreg[7] ? (rx_dv ? (rx_fifo_out[4]) : jabber) :
state_shiftreg[8] ? (rx_dv ? (rx_fifo_out[5]) : 1) :
state_shiftreg[9] ? (rx_dv ? (rx_fifo_out[6]) : 0) :
state_shiftreg[10] ? (rx_dv ? (rx_fifo_out[7]) : 1) : 0;
 
`else // !`ifdef RX_SYNC_1
/* Assign the rx line out */
always @(posedge clk)
smii_rx <= state_shiftreg[10] ? ethphy_mii_crs : /* 1st bit is MII CRS */
state_shiftreg[1] ? ((rx_dv & (segment_ctr==4'h0) & !fast_ethernet) |
rx_dv) :
// inter-frame status byte or data byte
state_shiftreg[2] ? (rx_dv ? (rx_fifo_out[0]) : ethphy_mii_rx_err) :
state_shiftreg[3] ? (rx_dv ? (rx_fifo_out[1]) : fast_ethernet) :
state_shiftreg[4] ? (rx_dv ? (rx_fifo_out[2]) : duplex) :
state_shiftreg[5] ? (rx_dv ? (rx_fifo_out[3]) : link) :
state_shiftreg[6] ? (rx_dv ? (rx_fifo_out[4]) : jabber) :
state_shiftreg[7] ? (rx_dv ? (rx_fifo_out[5]) : 1) :
state_shiftreg[8] ? (rx_dv ? (rx_fifo_out[6]) : 0) :
state_shiftreg[9] ? (rx_dv ? (rx_fifo_out[7]) : 1) : 0;
`endif // !`ifdef RX_SYNC_1
 
/* Status seq.: CRS, DV, ER, Speed, Duplex, Link, Jabber, UPV, FCD, 1 */
{1'b1,1'b0,1'b1,jabber,link,duplex,fast_ethernet,ethphy_mii_rx_err});
// {1'b1,1'b0,1'b1,jabber,link,duplex,,ethphy_mii_rx_err});
 
/**************************************************************************/
/* TX path logic MAC->(SMII->MII)->PHY */
229,25 → 272,49
reg tx_en_seqbit_scratch;
reg [7:0] tx_data_byte_scratch;
 
reg [1:0] tx_byte_to_phy; /* PHY sourced TX_CLK domain */
reg [2:0] tx_byte_to_phy; /* PHY sourced TX_CLK domain */
wire tx_fifo_empty;
wire tx_fifo_empty, tx_fifo_almost_empty;
wire tx_fifo_full;
wire [7:0] tx_fifo_q_dat;
wire tx_fifo_q_err;
reg tx_fifo_pop;
reg [3:0] tx_segment_begin_num;
wire [3:0] tx_segment_load_num;
 
assign tx_segment_load_num = (tx_segment_begin_num == 0) ? 4'h9 : tx_segment_begin_num - 1;
/* Signal to tell us an appropriate time to copy the values out of the
temp regs we put the incoming TX line into when we've received a
sequence off the SMII TX line that has TX_EN high */
wire tx_seqbits_copy;
assign tx_seqbits_copy = ((((!fast_ethernet) & (segment_ctr==4'h1)) |
((fast_ethernet) & (state_shiftreg[1])))
& tx_en_seqbit_scratch);
assign tx_seqbits_copy = (
(
((!fast_ethernet) & (segment_ctr == tx_segment_load_num)) |
fast_ethernet
)
& tx_en_seqbit_scratch & state_shiftreg[1]
);
 
always @(posedge clk)
begin
/* remember which counter value we were at when tx enable/valid
went high.
This is only useful when not doing fast ethernet*/
 
/* tx en has gone high - remember the sequence number we're in */
if ((tx_segment_begin_num == 4'hf) & (tx_en_seqbit_scratch))
tx_segment_begin_num <= segment_ctr;
/* If tx enable goes low again, reset the segment number */
if (!tx_en_seqbit_scratch)
/* reset to 0xf */
tx_segment_begin_num <= 4'hf;
end
 
always @(posedge clk)
begin
if (!rst_n)
begin
tx_er_seqbit_scratch <= 0;
256,39 → 323,27
end
else
begin
if (segment_ctr==4'h0)
begin
if(state_shiftreg[1])
tx_er_seqbit_scratch <= smii_tx;
if(state_shiftreg[2])
tx_en_seqbit_scratch <= smii_tx;
/* Preserve all but current bit of interest, as indicated
by state vector bit (reversed, becuase we get MSbit
first) and OR in the current smii_tx line value at this
position*/
if((|state_shiftreg[10:3]) & tx_en_seqbit_scratch)
tx_data_byte_scratch <= (tx_data_byte_scratch & ~state_shiftreg_top_byte) |
({8{smii_tx}} & state_shiftreg_top_byte);
end // if (segment_ctr==4'h0)
 
/* If we've just received a sequence with TX_EN then put
these values in the proper regs at the appropriate time,
depending on the speed , ready for transmission to the PHY */
if (tx_seqbits_copy)
begin
/* Now clear the tx_en scratch bit so we don't do
this again */
tx_en_seqbit_scratch <= 0;
end // if (tx_seqbits_copy)
if(state_shiftreg[1])
tx_er_seqbit_scratch <= smii_tx;
if(state_shiftreg[2])
tx_en_seqbit_scratch <= smii_tx;
/* Preserve all but current bit of interest, as indicated
by state vector bit (reversed, becuase we get MSbit
first) and OR in the current smii_tx line value at this
position*/
if((|state_shiftreg[10:3]) & tx_en_seqbit_scratch)
tx_data_byte_scratch <= (tx_data_byte_scratch & ~state_shiftreg_top_byte) |
({8{smii_tx}} & state_shiftreg_top_byte);
end
end // always @ (posedge clk)
 
 
reg [3:0] nib;
/* In the event we have a valid byte frame then get it to the
PHY as quickly as possible - this is TX_CLK domain */
always @(posedge ethphy_mii_tx_clk or negedge rst_n)
305,42 → 360,53
end
else
begin
if(!tx_fifo_empty) /* A byte ready to go to the MAC */
/* If fast_ethernet/100mbs we wait until the FIFO is full
otherwise, we push out the byte each time we get one */
//if((!tx_fifo_empty && !fast_ethernet) ||
//(tx_fifo_full && fast_ethernet))
if (!tx_fifo_almost_empty)
begin
if(tx_byte_to_phy == 2'b00)
if(tx_byte_to_phy == 0)
begin
/* Pop */
tx_byte_to_phy <= 1;
tx_fifo_pop <= 1;
tx_byte_to_phy <= 2'b01;
end
end
 
/* FIFO control loop */
if (tx_byte_to_phy == 2'b01) /* Output bits 3-0 (bottom nibble ) */
if (tx_byte_to_phy == 1)/* Output bits 3-0 (bottom nibble ) */
begin
 
ethphy_mii_tx_en <= 1;
 
tx_fifo_pop <= 0;
tx_byte_to_phy <= 2;
 
ethphy_mii_tx_d <= tx_fifo_q_dat[3:0];
ethphy_mii_tx_en <= 1;
nib <= tx_fifo_q_dat[7:4];
ethphy_mii_tx_err <= tx_fifo_q_err;
tx_fifo_pop <= 0;
tx_byte_to_phy <= 2'b10;
 
end
else if (tx_byte_to_phy == 2'b10) /* Output bits 7-4 (top nibble) */
else if (tx_byte_to_phy == 2) /* Output bits 7-4 (top nibble) */
begin
ethphy_mii_tx_d <= tx_fifo_q_dat[7:4];
//ethphy_mii_tx_d <= tx_fifo_q_dat[7:4];
ethphy_mii_tx_d <= nib;
if(!tx_fifo_empty) /* Check if more in FIFO */
begin
tx_fifo_pop <= 1; /* Pop again */
tx_byte_to_phy <= 2'b01;
tx_fifo_pop <= 1;
tx_byte_to_phy <= 1;
end
else /* Finish up */
begin
tx_byte_to_phy <= 2'b11;
tx_byte_to_phy <= 3;
ethphy_mii_tx_en <= 0;
end
end
else if (tx_byte_to_phy == 2'b11) /* De-assert TX_EN */
else if (tx_byte_to_phy == 3) /* De-assert TX_EN */
begin
ethphy_mii_tx_en <= 0;
tx_byte_to_phy <= 2'b00;
end
end // else: !if(!rst_n)
353,12 → 419,13
.psh_full (tx_fifo_full),
.pop_q ({tx_fifo_q_err,tx_fifo_q_dat}),
.pop_empty (tx_fifo_empty),
.almost_empty (tx_fifo_almost_empty),
// Inputs
.async_rst_n (rst_n),
.psh_clk (clk),
.psh_we (tx_seqbits_copy),
.psh_d ({tx_er_seqbit_scratch,tx_data_byte_scratch}),
.pop_clk (),
.pop_clk (ethphy_mii_tx_clk),
.pop_re (tx_fifo_pop));
369,11 → 436,12
 
 
/* Generic fifo - this is bad, should probably be done some other way */
module generic_fifo (async_rst_n, psh_clk, psh_we, psh_d, psh_full, pop_clk, pop_re, pop_q, pop_empty);
module generic_fifo (async_rst_n, psh_clk, psh_we, psh_d, psh_full, pop_clk, pop_re, pop_q, pop_empty, almost_empty);
 
parameter dw = 8;
parameter size = 64;
 
parameter size = 16;
parameter size_log_2 = 4;
/* Asynch. reset, active low */
input async_rst_n;
386,83 → 454,63
/* Pop side signals */
input pop_clk;
input pop_re;
//output reg [dw-1:0] pop_q;
output reg [dw-1:0] pop_q;
output pop_empty;
output wire almost_empty;
/* Actual FIFO memory */
reg [dw-1:0] fifo_mem [0:size-1];
 
/* Poorly defined pointer logic -- will need to be changed if the size paramter is too big - Verilog needs some log base 2 thing */
reg [7:0] ptr; /* Only 8 bits, so max size of 255 of fifo! */
 
/* FIFO position ptr regs */
reg [size_log_2 - 1 : 0 ] wr_ptr, rd_ptr, ctr;
 
integer i;
 
/* FIFO full signal for push side */
assign psh_full = (ptr == size-1) ? 1 : 0;
//assign psh_full = (ptr == size-1) ? 1 : 0;
/* This full logic means we all but one slot in the FIFO */
assign psh_full = ctr == size;
/* FIFO empty signal for pop side */
assign pop_empty = (ptr == 0) ? 1 : 0;
//assign pop_empty = (ptr == 0) ? 1 : 0;
//assign pop_empty = ctr==0;
assign pop_empty = rd_ptr == wr_ptr;
 
assign almost_empty = ctr < 2;
always @(posedge pop_re or negedge async_rst_n)
begin
if (!async_rst_n)
rd_ptr <= 0;
else
begin
pop_q = fifo_mem[rd_ptr];
rd_ptr <= rd_ptr + 1;
ctr <= ctr - 1;
end
end
 
/* This will work if pushing side is a lot faster than popping side */
reg pop_re_psh_clk;
wire pop_re_risingedge_psh_clk; /* Signal to help push side see when
there's been a pop_re rising edge,
sampled on push clock */
 
/* Detect edge of signal in pop domain for psh domain */
assign pop_re_risingedge_psh_clk = (pop_re & !pop_re_psh_clk);
 
 
integer i;
always @(posedge psh_clk or negedge async_rst_n)
always @(posedge psh_we or negedge async_rst_n)
begin
if (!async_rst_n)
begin
ptr <= 0;
 
 
for (i=0;i<size;i=i+1) fifo_mem[i] <= 0;
 
pop_re_psh_clk <= 0;
wr_ptr <= 0;
ctr <= 0;
end
else
else
begin
pop_re_psh_clk <= pop_re; /* Register pop command in psh domain */
if (psh_we) /* Push into FIFO */
begin
if (!pop_re_psh_clk) /* If no pop at the same time, simple */
begin
fifo_mem[ptr] <= psh_d;
ptr <= ptr + 1'b1;
end
else /* Pop at same edge */
begin
/* Shift fifo contents */
for(i=1;i<size;i=i+1)
fifo_mem[i-1] <= fifo_mem[i];
fifo_mem[size-1] <= 0;
pop_q <= fifo_mem[0];
fifo_mem[ptr] <= psh_d;
/* ptr remains unchanged */
end // else: !if!(pop_re_psh_clk)
end // if (psh_we)
else /* No push, see if there's a pop */
begin
if (pop_re_risingedge_psh_clk) /* Detected a pop */
begin
for(i=1;i<size;i=i+1)
fifo_mem[i-1] <= fifo_mem[i];
fifo_mem[size-1] <= 0;
pop_q <= fifo_mem[0];
ptr <= ptr - 1'b1;
end
end // else: !if(psh_we)
end // else: !if(!async_rst_n)
end // always @ (posedge psh_clk or negedge async_rst_n)
fifo_mem[wr_ptr] <= psh_d;
wr_ptr <= #1 wr_ptr + 1;
ctr <= ctr + 1;
end
end
endmodule // generic_fifo
 
/trunk/orpsocv2/bench/verilog/orpsoc_testbench.v
338,6 → 338,6
endmodule // orpsoc_testbench
 
// Local Variables:
// verilog-library-files:("../../rtl/verilog/orp_soc.v")
// verilog-library-files:("../../rtl/verilog/orpsoc_top.v")
// verilog-library-directories:("." "../../rtl/verilog")
// End:
// End:
/trunk/orpsocv2/bench/verilog/or1200_monitor.v
239,6 → 239,9
* shouldn't be needed - but is handy if someone changes something and stops
* the test continuing forever.
*/
integer num_nul_inst;
initial num_nul_inst = 0;
task monitor_for_crash;
`define OR1200_MONITOR_CRASH_TRACE_SIZE 32
reg [31:0] insn_trace [0:`OR1200_MONITOR_CRASH_TRACE_SIZE-1]; //Trace buffer of 32 instructions
247,6 → 250,9
begin
if (`OR1200_TOP.or1200_cpu.or1200_ctrl.wb_insn == 32'h00000000)
num_nul_inst = num_nul_inst + 1;
 
if (num_nul_inst == 1000) // Sat a loop a bit too long...
begin
$fdisplay(fgeneral, "ERROR - no instruction at PC %h", `OR1200_TOP.or1200_cpu.or1200_except.wb_pc);
$fdisplay(fgeneral, "Crash trace: Last %d instructions: ",`OR1200_MONITOR_CRASH_TRACE_SIZE);
/trunk/orpsocv2/bench/verilog/vpi/c/rsp-rtl_sim.h
103,13 → 103,13
int dbg_wb_write_block32(uint32_t adr, uint32_t *data, int len);
 
/* read a register from cpu */
int dbg_cpu0_read(uint32_t adr, uint32_t *data);
int dbg_cpu0_read(uint32_t adr, uint32_t *data, uint32_t length);
 
/* read a register from cpu module */
int dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data);
 
/* write a cpu register */
int dbg_cpu0_write(uint32_t adr, uint32_t data);
int dbg_cpu0_write(uint32_t adr, uint32_t *data, uint32_t length);
 
/* write a cpu module register */
int dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data);
/trunk/orpsocv2/bench/verilog/vpi/c/gdb.h
120,6 → 120,25
order.
*/
 
/* Special purpose groups */
 
#define OR1K_SPG_SIZE_BITS 11
#define OR1K_SPG_SIZE (1 << OR1K_SPG_SIZE_BITS)
 
#define OR1K_SPG_SYS 0
#define OR1K_SPG_DMMU 1
#define OR1K_SPG_IMMU 2
#define OR1K_SPG_DC 3
#define OR1K_SPG_IC 4
#define OR1K_SPG_MAC 5
#define OR1K_SPG_DEBUG 6
#define OR1K_SPG_PC 7
#define OR1K_SPG_PM 8
#define OR1K_SPG_PIC 9
#define OR1K_SPG_TT 10
#define OR1K_SPG_FPU 11
 
 
typedef struct {
uint32_t command;
uint32_t length;
/trunk/orpsocv2/bench/verilog/vpi/c/rsp-rtl_sim.c
514,7 → 514,7
}
 
/* read a register from cpu */
int dbg_cpu0_read(uint32_t adr, uint32_t *data)
int dbg_cpu0_read(uint32_t adr, uint32_t *data, uint32_t length)
{
 
if (DBG_CALLS)printf("dbg_cpu0_read: adr 0x%.8x\n",adr);
524,9 → 524,11
send_command_to_vpi(CMD_CPU_RD_REG);
send_address_to_vpi(adr);
 
send_data_to_vpi(length); // Added 090901 --jb
 
get_block_data_from_vpi(length, data); // changed 090901 --jb //get_data_from_vpi(data);
get_data_from_vpi(data);
get_response_from_vpi();
return 0;
534,7 → 536,7
}
 
/* write a cpu register */
int dbg_cpu0_write(uint32_t adr, uint32_t data)
int dbg_cpu0_write(uint32_t adr, uint32_t *data, uint32_t length)
{
 
if (DBG_CALLS)printf("dbg_cpu0_write: adr 0x%.8x\n",adr);
545,7 → 547,9
send_address_to_vpi(adr);
send_data_to_vpi(data);
send_data_to_vpi(length); // Added 090901 -- jb
 
send_block_data_to_vpi(length, data); // Added 090901 -- jb
get_response_from_vpi();
621,14 → 625,16
printf("\tor1k stall failed. read: 0x%x\n", stalled); // check stall or1k
//exit(1);
}
 
/* Read NPC,PPC and SR regs, they are consecutive in CPU, at adr. 16, 17 and 18 */
uint32_t pcs_and_sr[3];
debug2(" Reading npc, ppc\n");
dbg_cpu0_read(16, (uint32_t *)pcs_and_sr, 3 * 4);
debug2(" Reading npc\n");
dbg_cpu0_read((0 << 11) + 16, &npc);
debug2(" Reading ppc\n");
dbg_cpu0_read((0 << 11) + 18, &ppc);
debug2(" Reading r1\n");
dbg_cpu0_read(0x401, &r1);
printf(" Read npc = %.8x ppc = %.8x r1 = %.8x\n", npc, ppc, r1);
dbg_cpu0_read(0x401, &r1, 4);
printf(" Read npc = %.8x ppc = %.8x r1 = %.8x\n",
pcs_and_sr[0], pcs_and_sr[2], r1);
}
 
/trunk/orpsocv2/bench/verilog/vpi/c/gdb.c
144,6 → 144,7
string. So at least NUMREGBYTES*2 + 1 (for the 'G' or the EOS) are needed
for register packets */
#define GDB_BUF_MAX ((NUM_REGS) * 8 + 1)
//#define GDB_BUF_MAX 1500
 
/*! Size of the matchpoint hash table. Largest prime < 2^10 */
#define MP_HASH_SIZE 1021
191,7 → 192,24
#define SPR_DRR_FPE 0x00001000 //!< Floating point
#define SPR_DRR_TE 0x00002000 //!< Trap
 
/* Defines for Debug Mode Register 1 bits. */
#define SPR_DMR1_CW 0x00000003 /* Mask for CW bits */
#define SPR_DMR1_CW_AND 0x00000001 /* Chain watchpoint 0 AND */
#define SPR_DMR1_CW_OR 0x00000002 /* Chain watchpoint 0 OR */
#define SPR_DMR1_CW_SZ 2 /* Number of bits for each WP */
#define SPR_DMR1_ST 0x00400000 /* Single-step trace */
#define SPR_DMR1_BT 0x00800000 /* Branch trace */
 
/* Defines for Debug Mode Register 2 bits. */
#define SPR_DMR2_WCE0 0x00000001 /* Watchpoint counter enable 0 */
#define SPR_DMR2_WCE1 0x00000002 /* Watchpoint counter enable 1 */
#define SPR_DMR2_AWTC_MASK 0x00000ffc /* Assign watchpoints to ctr mask */
#define SPR_DMR2_WGB_MASK 0x003ff000 /* Watchpoints generaing brk mask */
#define SPR_DMR2_WBS_MASK 0xffc00000 /* Watchpoint brkpt status mask */
#define SPR_DMR2_AWTC_OFF 2 /* Assign watchpoints to ctr offset */
#define SPR_DMR2_WGB_OFF 12 /* Watchpoints generating brk offset */
#define SPR_DMR2_WBS_OFF 22 /* Watchpoint brkpt status offset */
 
/*! Definition of GDB target signals. Data taken from the GDB 6.8
source. Only those we use defined here. The exact meaning of
signal number is defined by the header `include/gdb/signals.h'
231,6 → 249,55
int npcIsCached; //!< Is the NPC cached - should be bool
uint32_t npcCachedValue; //!< Cached value of the NPC
 
/* Debug registers cache */
#define OR1K_MAX_MATCHPOINTS 8
 
enum dcr_cc {
OR1K_CC_MASKED = 0,
OR1K_CC_EQ = 1,
OR1K_CC_LT = 2,
OR1K_CC_LE = 3,
OR1K_CC_GT = 4,
OR1K_CC_GE = 5,
OR1K_CC_NE = 6,
OR1K_CC_RESERVED = 7
}; /* Compare operation */
enum dcr_ct {
OR1K_CT_DISABLED = 0, /* Disabled */
OR1K_CT_FETCH = 1, /* Compare to fetch EA */
OR1K_CT_LEA = 2, /* Compare to load EA */
OR1K_CT_SEA = 3, /* Compare to store EA */
OR1K_CT_LDATA = 4, /* Compare to load data */
OR1K_CT_SDATA = 5, /* Compare to store data */
OR1K_CT_AEA = 6, /* Compare to load/store EA */
OR1K_CT_ADATA = 7 /* Compare to load/store data */
}; /* Compare to what? */
 
/*! Cached OR1K debug register values (ignores counters for now). */
static struct {
uint32_t dvr[OR1K_MAX_MATCHPOINTS];
struct {
uint32_t dp : 1; /* DVR/DCP present - Read Only */
enum dcr_cc cc : 3; /* Compare condition */
uint32_t sc : 1; /* Signed comparison? */
enum dcr_ct ct : 3; /* Compare to */
uint32_t dcr_reserved : 24;
} dcr[OR1K_MAX_MATCHPOINTS];
uint32_t dmr1;
uint32_t dmr2;
uint32_t dcrw0;
uint32_t dcrw1;
uint32_t dsr;
uint32_t drr;
} or1k_dbg_group_regs_cache;
 
// Value to indicate status of the registers
// Init to -1, meaning we don't have a copy, 0 = clean copy, 1 = dirty copy
static int dbg_regs_cache_dirty = -1;
 
static uint32_t gpr_regs[MAX_GPRS]; // Static array to block read the GPRs into
 
static int err = 0;
 
 
331,6 → 398,15
static void mp_hash_add (enum mp_type type, uint32_t addr, uint32_t instr);
static struct mp_entry * mp_hash_lookup (enum mp_type type, uint32_t addr);
static struct mp_entry * mp_hash_delete (enum mp_type type, uint32_t addr);
static void get_debug_registers(void);
static void put_debug_registers(void);
static int find_free_dcrdvr_pair(void);
static int count_free_dcrdvr_pairs(void);
static int find_matching_dcrdvr_pair(uint32_t addr, uint32_t cc);
static void insert_hw_watchpoint(int wp_num, uint32_t address, uint32_t cc);
static void remove_hw_watchpoint(int wp_num);
static void enable_hw_breakpoint(int wp_num);
static void disable_hw_breakpoint(int wp_num);
static void rsp_remove_matchpoint (struct rsp_buf *p_buf);
static void rsp_insert_matchpoint (struct rsp_buf *p_buf);
static void rsp_command (struct rsp_buf *p_buf);
388,6 → 464,9
rsp.sigval = 0; /* No exception */
rsp.start_addr = EXCEPT_RESET; /* Default restart point */
 
/* Clear the debug registers cache */
bzero((char*) &or1k_dbg_group_regs_cache, sizeof(or1k_dbg_group_regs_cache));
 
/* Set up the matchpoint hash table */
mp_hash_init ();
520,12 → 599,15
 
gdb_set_chain(SC_RISC_DEBUG);
 
// Now read the DRR (Debug Reason Register)
gdb_read_reg(DRR_CPU_REG_ADD, &drr);
get_debug_registers();
 
// Now check the DRR (Debug Reason Register)
//gdb_read_reg(DRR_CPU_REG_ADD, &drr);
drr = or1k_dbg_group_regs_cache.drr;
 
if (DEBUG_GDB) printf("DRR: 0x%08x\n", drr);
switch ((int)(drr&0xffffffff))
switch (drr)
{
case SPR_DRR_RSTE: rsp.sigval = TARGET_SIGNAL_PWR; break;
case SPR_DRR_BUSEE: rsp.sigval = TARGET_SIGNAL_BUS; break;
777,6 → 859,7
signal (SIGPIPE, SIG_IGN); /* So we don't exit if client dies */
 
printf ("Remote debugging from host %s\n", inet_ntoa (sock_addr.sin_addr));
} /* rsp_get_client () */
 
 
1947,31 → 2030,21
/* Set the address as the value of the next program counter */
set_npc (addr);
/* Clear Debug Reason Register (DRR) 0x3015 */
// Arc sim --> cpu_state.sprs[SPR_DRR] = 0;
if(gdb_write_reg(DRR_CPU_REG_ADD, 0)) printf("Error write to DRR register\n");
or1k_dbg_group_regs_cache.drr = 0; // Clear DRR
or1k_dbg_group_regs_cache.dmr1 &= ~SPR_DMR1_ST; // Continuing, so disable step if it's enabled
or1k_dbg_group_regs_cache.dsr |= SPR_DSR_TE; // If breakpoints-cause-traps is not enabled
dbg_regs_cache_dirty = 1; // Always write the cache back
 
/* Commit all debug registers */
if (dbg_regs_cache_dirty == 1)
put_debug_registers();
/* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) 0x3011 */
// Arc sim --> cpu_state.sprs[SPR_DMR2] &= ~SPR_DMR2_WGB;
if(gdb_read_reg(DMR2_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR2 register\n");
temp_uint32 &= ~SPR_DMR2_WGB;
if(gdb_write_reg(DMR2_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR2 register\n");
/* Clear the single step trigger in Debug Mode Register 1 (DMR1) Register 0x3010 */
// Arc sim --> cpu_state.sprs[SPR_DMR1] &= ~SPR_DMR1_ST;
if(gdb_read_reg(DMR1_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR1 register\n");
temp_uint32 &= ~SPR_DMR1_ST;
if(gdb_write_reg(DMR1_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR1 register\n");
/* Set traps to be handled by the debug unit in the Debug Stop Register (DSR) Register 0x3014 */
// Arc sim --> cpu_state.sprs[SPR_DSR] |= SPR_DSR_TE;
if(gdb_read_reg(DSR_CPU_REG_ADD, &temp_uint32)) printf("Error read from DSR register\n");
temp_uint32 |= SPR_DSR_TE;
if(gdb_write_reg(DSR_CPU_REG_ADD, temp_uint32)) printf("Error write to DSR register\n");
 
/* Unstall the processor */
set_stall_state (0);
 
/* Debug regs cache is now invalid */
dbg_regs_cache_dirty = -1;
 
/* Note the GDB client is now waiting for a reply. */
rsp.client_waiting = 1;
 
2002,15 → 2075,18
// Read all GPRs
gdb_read_block(0x400, (uint32_t *) &gpr_regs, MAX_GPRS*4);
for (r = 0; r < MAX_GPRS; r++){
err = gdb_read_reg(0x400 + r, &temp_uint32);
/*err = gdb_read_reg(0x400 + r, &temp_uint32);
if(err > 0){
if (DEBUG_GDB) printf("Error %d in gdb_read_reg at reg. %d\n", err, r);
put_str_packet ("E01");
return;
}
reg2hex (temp_uint32, &(buffer.data[r * 8]));
*/
reg2hex (gpr_regs[r], &(buffer.data[r * 8]));
if (DEBUG_GDB_DUMP_DATA){
switch(r % 4)
2029,38 → 2105,19
break;
}
}
}
/* ---------- PPC ---------- */
err = gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32);
if(err > 0){
if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> PPC\n", err);
put_str_packet ("E01");
return;
}
reg2hex (temp_uint32, &(buffer.data[PPC_REGNUM * 8]));
if (DEBUG_GDB_DUMP_DATA) printf("PPC 0x%08x\n", temp_uint32);
/* ---------- NPC ---------- */
temp_uint32 = get_npc();
/*
err = gdb_read_reg(NPC_CPU_REG_ADD, &temp_uint32);
if(err > 0){
if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> NPC\n", err);
put_str_packet ("E01");
return;
}
*/
reg2hex (temp_uint32, &(buffer.data[NPC_REGNUM * 8]));
if (DEBUG_GDB_DUMP_DATA) printf("NPC 0x%08x\n", temp_uint32);
/* ---------- SR ---------- */
err = gdb_read_reg(SR_CPU_REG_ADD, &temp_uint32);
if(err > 0){
if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> SP\n", err);
put_str_packet ("E01");
return;
}
reg2hex (temp_uint32, &(buffer.data[SR_REGNUM * 8]));
if (DEBUG_GDB_DUMP_DATA) printf("SR 0x%08x\n", temp_uint32);
/* Read NPC,PPC and SR regs, they are consecutive in CPU, at adr. 16, 17 and 18 */
uint32_t pcs_and_sr[3];
gdb_read_block(NPC_CPU_REG_ADD, (uint32_t *)pcs_and_sr, 3 * 4);
reg2hex (pcs_and_sr[0], &(buffer.data[NPC_REGNUM * 8]));
reg2hex (pcs_and_sr[1], &(buffer.data[SR_REGNUM * 8]));
reg2hex (pcs_and_sr[2], &(buffer.data[PPC_REGNUM * 8]));
if (DEBUG_GDB_DUMP_DATA) printf("PPC 0x%08x\n", pcs_and_sr[2]);
if (DEBUG_GDB_DUMP_DATA) printf("NPC 0x%08x\n", pcs_and_sr[0]);
if (DEBUG_GDB_DUMP_DATA) printf("SR 0x%08x\n", pcs_and_sr[1]);
 
/* Finalize the packet and send it */
buffer.data[NUM_REGS * 8] = 0;
2090,16 → 2147,6
rsp_write_all_regs (struct rsp_buf *p_buf)
{
uint32_t regnum; /* Register index */
// char valstr[9]; /* Allow for EOS on the string */
 
// /* Check for valid data */
// if (0 != (strcmp ("G", p_buf->data)) && (GDB_BUF_MAX != strlen(p_buf->data)))
// {
// fprintf (stderr, "Warning: Failed to recognize RSP write register "
// "command: %s\n", p_buf->data);
// // put_str_packet ("E01");
// return;
// }
// Make sure the processor is stalled
gdb_ensure_or1k_stalled();
2111,44 → 2158,30
put_str_packet ("E01");
return;
}
 
/* ---------- GPRS ---------- */
for (regnum = 0; regnum < MAX_GPRS; regnum++)
{
err = gdb_write_reg(0x400 + regnum, hex2reg (&p_buf->data[regnum * 8 + 1]));
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> GPRS\n", err);
put_str_packet ("E01");
return;
}
}
gpr_regs[regnum] = hex2reg (&p_buf->data[regnum * 8 + 1]);
/* Do a block write */
gdb_write_block(0x400, (uint32_t *) gpr_regs, MAX_GPRS*32);
/* ---------- PPC ---------- */
err = gdb_write_reg(PPC_CPU_REG_ADD, hex2reg (&p_buf->data[PPC_REGNUM * 8 + 1]));
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> PPC\n", err);
put_str_packet ("E01");
return;
}
/* ---------- SR ---------- */
err = gdb_write_reg(SR_CPU_REG_ADD, hex2reg (&p_buf->data[SR_REGNUM * 8 + 1]));
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> SR\n", err);
put_str_packet ("E01");
return;
}
/* Write PPC and SR regs, they are consecutive in CPU, at adr. 17 and 18 */
/* We handle NPC specially */
uint32_t pcs_and_sr[2];
pcs_and_sr[0] = hex2reg (&p_buf->data[SR_REGNUM * 8 + 1]);
pcs_and_sr[1] = hex2reg (&p_buf->data[PPC_REGNUM * 8 + 1]);
gdb_write_block(SR_CPU_REG_ADD, (uint32_t *)pcs_and_sr, 2 * 4);
/* ---------- NPC ---------- */
set_npc(hex2reg (&p_buf->data[NPC_REGNUM * 8 + 1]));
/*
err = gdb_write_reg(NPC_CPU_REG_ADD, hex2reg (&p_buf->data[NPC_REGNUM * 8 + 1]));
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> NPC\n", err);
put_str_packet ("E01");
return;
}
*/
/* Acknowledge. TODO: We always succeed at present, even if the data was
defective. */
put_str_packet ("OK");
} /* rsp_write_all_regs () */
 
2763,9 → 2796,19
// First set the chain
gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
// special case for NPC
/* special case for NPC */
if(regno == NPC_CPU_REG_ADD)
temp_uint32 = get_npc();
/* Also special case for debug group (group 6) registers */
else if (((regno >> OR1K_SPG_SIZE_BITS) & 0xff) == OR1K_SPG_DEBUG)
{
if (dbg_regs_cache_dirty == -1) // Regs invalid, get them
get_debug_registers();
uint32_t * dbg_reg_array = (uint32_t *) &or1k_dbg_group_regs_cache;
temp_uint32 = dbg_reg_array[(regno & 0xff)];
dbg_regs_cache_dirty = 0;
}
else
{
err = gdb_read_reg(regno, &temp_uint32);
2817,6 → 2860,16
// special case for NPC
if(regno == NPC_CPU_REG_ADD)
set_npc(val);
/* Also special case for debug group (group 6) registers */
else if (((regno >> OR1K_SPG_SIZE_BITS) & 0xff) == OR1K_SPG_DEBUG)
{
if (dbg_regs_cache_dirty == -1) // Regs invalid, get them
get_debug_registers();
uint32_t * dbg_reg_array = (uint32_t *) &or1k_dbg_group_regs_cache;
dbg_reg_array[(regno & 0xff)] = val;
dbg_regs_cache_dirty = 1;
}
else
{
2883,25 → 2936,14
// First set the chain
err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
if(err > 0){
if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
put_str_packet ("E01");
return;
}
// OR32 Arc sim equivalent --> set_npc (rsp.start_addr);
return;
}
/* Set NPC to reset vector 0x100 */
set_npc(rsp.start_addr);
/*
err = gdb_write_reg(NPC_CPU_REG_ADD, rsp.start_addr);
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_restart write Reg. %x = 0x%08x\n", err, NPC_CPU_REG_ADD, rsp.start_addr);
put_str_packet ("E01");
return;
}
else{
if (DEBUG_GDB) printf("Error %d Command Reset. Set NPC to Start vector %x = 0x%08x\n", err, NPC_CPU_REG_ADD, rsp.start_addr);
}
*/
 
} /* rsp_restart () */
 
 
2931,17 → 2973,8
 
if (0 == strcmp ("s", p_buf->data))
{
// Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
/* ---------- Npc ---------- */
addr = get_npc();
/*
err = gdb_read_reg(NPC_CPU_REG_ADD, &addr);
if(err > 0){
printf("Error %d to read NPC in the STEP command 's'\n", err);
rsp_client_close ();
return;
}
*/
}
else if (1 != sscanf (p_buf->data, "s%x", &addr))
{
2948,21 → 2981,11
fprintf (stderr,
"Warning: RSP step address %s not recognized: ignored\n",
p_buf->data);
 
// Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
/* ---------- NPC ---------- */
addr = get_npc();
/*
err = gdb_read_reg(NPC_CPU_REG_ADD, &addr);
if(err > 0){
printf("Error %d to read NPC in the STEP command 's'\n", err);
rsp_client_close ();
return;
}
*/
}
 
//if (DEBUG_GDB) printf("rsp_step() --> Read NPC = 0x%08x\n", addr);
rsp_step_generic (addr, EXCEPT_NONE);
 
} /* rsp_step () */
3005,30 → 3028,21
set_npc (addr);
/* Clear Debug Reason Register (DRR) 0x3015 */
// Arc sim --> cpu_state.sprs[SPR_DRR] = 0;
if(gdb_write_reg(DRR_CPU_REG_ADD, 0)) printf("Error write to DRR register\n");
/* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) 0x3011 */
// Arc sim --> cpu_state.sprs[SPR_DMR2] &= ~SPR_DMR2_WGB;
if(gdb_read_reg(DMR2_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR2 register\n");
temp_uint32 &= ~SPR_DMR2_WGB;
if(gdb_write_reg(DMR2_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR2 register\n");
/* Set the single step trigger in Debug Mode Register 1 (DMR1) Register 0x3010 */
// Arc sim --> cpu_state.sprs[SPR_DMR1] |= SPR_DMR1_ST;
if(gdb_read_reg(DMR1_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR1 register\n");
temp_uint32 |= SPR_DMR1_ST;
if(gdb_write_reg(DMR1_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR1 register\n");
/* Set traps to be handled by the debug unit in the Debug Stop Register (DSR) Register 0x3014 */
// Arc sim --> cpu_state.sprs[SPR_DSR] |= SPR_DSR_TE;
if(gdb_read_reg(DSR_CPU_REG_ADD, &temp_uint32)) printf("Error read from DSR register\n");
temp_uint32 |= SPR_DSR_TE;
if(gdb_write_reg(DSR_CPU_REG_ADD, temp_uint32)) printf("Error write to DSR register\n");
or1k_dbg_group_regs_cache.drr = 0; // Clear DRR
or1k_dbg_group_regs_cache.dmr1 |= SPR_DMR1_ST; // Stepping, so enable step in DMR1
or1k_dbg_group_regs_cache.dsr |= SPR_DSR_TE; // Enable trap handled by DU
or1k_dbg_group_regs_cache.dmr2 &= ~SPR_DMR2_WGB; // Stepping, so disable breakpoints from watchpoints
dbg_regs_cache_dirty = 1; // Always write the cache back
 
/* Commit all debug registers */
if (dbg_regs_cache_dirty == 1)
put_debug_registers();
 
/* Unstall the processor */
set_stall_state (0);
/* Debug regs cache now in invalid state */
dbg_regs_cache_dirty = -1;
 
/* Note the GDB client is now waiting for a reply. */
rsp.client_waiting = 1;
3264,6 → 3278,248
} /* rsp_write_mem_bin () */
 
/*---------------------------------------------------------------------------*/
/*!Copy the debug group registers from the processor into our cache struct
*/
/*---------------------------------------------------------------------------*/
static void
get_debug_registers(void)
{
 
if (dbg_regs_cache_dirty != -1) return; // Don't need to update them
 
if (DEBUG_GDB)
printf("gdb - get_debug_registers() - reading %d bytes for debug regs\n",sizeof(or1k_dbg_group_regs_cache));
 
 
err = gdb_set_chain(SC_RISC_DEBUG); /* Register Chain */
/* Fill our debug group registers struct */
gdb_read_block((OR1K_SPG_DEBUG << OR1K_SPG_SIZE_BITS),
(uint32_t *) &or1k_dbg_group_regs_cache,
(uint32_t) sizeof(or1k_dbg_group_regs_cache));
dbg_regs_cache_dirty = 0; // Just updated it so not dirty
 
if (DEBUG_GDB)
{
printf("gdb - get_debug_registers() - registers:\n\t");
uint32_t * regs_ptr = (uint32_t*) &or1k_dbg_group_regs_cache;
int i;
for(i=0;i<(sizeof(or1k_dbg_group_regs_cache)/4);i++)
{ if (i%4==0)printf("\n\t");
if (i<8)
printf("DVR%.2d %.8x ",i,regs_ptr[i]);
else if (i<16)
printf("DCR%.2d %.8x ",i-8,regs_ptr[i]);
else if (i<17)
printf("DMR1 %.8x ",regs_ptr[i]);
else if (i<18)
printf("DMR2 %.8x ",regs_ptr[i]);
else if (i<19)
printf("DCWR0 %.8x ",regs_ptr[i]);
else if (i<20)
printf("DCWR1 %.8x ",regs_ptr[i]);
else if (i<21)
printf("DSR %.8x ",regs_ptr[i]);
else if (i<22)
printf("DRR %.8x ",regs_ptr[i]);
 
}
printf("\n");
}
return;
} /* get_debug_registers() */
 
/*---------------------------------------------------------------------------*/
/*!Copy the debug group registers from our cache to the processor
*/
/*---------------------------------------------------------------------------*/
static void
put_debug_registers(void)
{
/* TODO: Block CPU registers write functionality */
if (DEBUG_GDB) printf("gdb - put_debug_registers()\n");
int i;
uint32_t *dbg_regs_ptr = (uint32_t *) &or1k_dbg_group_regs_cache;
 
if (DEBUG_GDB)
{
printf("gdb - put_debug_registers() - registers:\n\t");
uint32_t * regs_ptr = (uint32_t*) &or1k_dbg_group_regs_cache;
int i;
for(i=0;i<(sizeof(or1k_dbg_group_regs_cache)/4);i++)
{ if (i%4==0)printf("\n\t");
if (i<8)
printf("DVR%.2d %.8x ",i,regs_ptr[i]);
else if (i<16)
printf("DCR%.2d %.8x ",i-8,regs_ptr[i]);
else if (i<17)
printf("DMR1 %.8x ",regs_ptr[i]);
else if (i<18)
printf("DMR2 %.8x ",regs_ptr[i]);
else if (i<19)
printf("DCWR0 %.8x ",regs_ptr[i]);
else if (i<20)
printf("DCWR1 %.8x ",regs_ptr[i]);
else if (i<21)
printf("DSR %.8x ",regs_ptr[i]);
else if (i<22)
printf("DRR %.8x ",regs_ptr[i]);
}
printf("\n");
}
err = gdb_set_chain(SC_RISC_DEBUG); /* Register Chain */
gdb_write_block((OR1K_SPG_DEBUG << OR1K_SPG_SIZE_BITS),
(uint32_t *) &or1k_dbg_group_regs_cache,
sizeof(or1k_dbg_group_regs_cache));
 
return;
 
} /* put_debug_registers() */
 
/*---------------------------------------------------------------------------*/
/*!Find the DVR/DCR pair corresponding to the address
 
@return the number, 0-7 of the DCR/DVR pair, if possible, -1 else. */
/*---------------------------------------------------------------------------*/
static int
find_matching_dcrdvr_pair(uint32_t addr, uint32_t cc)
{
int i;
for (i=0;i<OR1K_MAX_MATCHPOINTS; i++)
{
// Find the one matching according to address, and in use
if ((or1k_dbg_group_regs_cache.dvr[i] == addr) &&
(or1k_dbg_group_regs_cache.dcr[i].cc == cc))
{
/*
if (DEBUG_GDB) printf("gdb - find_matching_dcrdvr_pair(%.8x, %d)\n",addr, cc);
if (DEBUG_GDB) printf("gdb - find_matching_dcrdvr_pair match in %d: dvr[%d] = %.8x dcr[%d].cc=%d\n",
i,i,or1k_dbg_group_regs_cache.dvr[i],i,or1k_dbg_group_regs_cache.dcr[i].cc);
*/
return i;
}
}
// If the loop finished, no appropriate matchpoints
return -1;
} /* find_matching_dcrdvr_pair() */
/*---------------------------------------------------------------------------*/
/*!Count number of free DCR/DVR pairs
 
@return the number, 0-7 */
/*---------------------------------------------------------------------------*/
static int
count_free_dcrdvr_pairs(void)
{
int i, free=0;
for (i=0;i<OR1K_MAX_MATCHPOINTS; i++)
{
if ((or1k_dbg_group_regs_cache.dcr[i].cc == OR1K_CC_MASKED) // If compare condition is masked, it's not used
&& or1k_dbg_group_regs_cache.dcr[i].dp ) // and the debug point is present
free++;
}
return free;
} /* count_free_dcrdvr_pairs() */
 
/*---------------------------------------------------------------------------*/
/*!Find a free hardware breakpoint register, DCR/DVR pair
 
@return the number, 0-7 of the DCR/DVR pair, if possible, -1 else. */
/*---------------------------------------------------------------------------*/
static int
find_free_dcrdvr_pair(void)
{
int i;
for (i=0;i<OR1K_MAX_MATCHPOINTS; i++)
{
if ((or1k_dbg_group_regs_cache.dcr[i].cc == OR1K_CC_MASKED) // If compare condition is masked, it's not used
&& or1k_dbg_group_regs_cache.dcr[i].dp ) // and the debug point is present
return i;
}
// If the loop finished, no free matchpoints
return -1;
} /* find_free_dcrdvr_pair() */
 
/*---------------------------------------------------------------------------*/
/*!Setup a DCR/DVR pair for our watchpoint.
@param[in] wp_num The watchpoint number
@param[in] address The address for watchpoint
*/
/*---------------------------------------------------------------------------*/
static void
insert_hw_watchpoint(int wp_num, uint32_t address, uint32_t cc)
{
if (DEBUG_GDB) printf("gdb - insert_hw_watchpoint(%d, 0x%.8x)\n",wp_num, address);
or1k_dbg_group_regs_cache.dvr[wp_num] = address;
or1k_dbg_group_regs_cache.dcr[wp_num].cc = cc;
or1k_dbg_group_regs_cache.dcr[wp_num].sc = 0;
or1k_dbg_group_regs_cache.dcr[wp_num].ct = OR1K_CT_FETCH; // Instruction fetch address
// Mark the debug reg cache as dirty
dbg_regs_cache_dirty = 1;
return;
} /* insert_hw_watchpoint() */
 
/*---------------------------------------------------------------------------*/
/*!Remove/free a DCR/DVR watchpoint pair
@param[in] wp_num The watchpoint number
*/
/*---------------------------------------------------------------------------*/
static void
remove_hw_watchpoint(int wp_num)
{
or1k_dbg_group_regs_cache.dvr[wp_num] = 0;
or1k_dbg_group_regs_cache.dcr[wp_num].cc = OR1K_CC_MASKED; // We only do equals for now
or1k_dbg_group_regs_cache.dcr[wp_num].sc = 0;
 
/* Auto-disable it as generating a breakpoint, too, although maybe gets done after
this call anyway. Best to ensure. */
disable_hw_breakpoint(wp_num);
// Mark the debug reg cache as dirty
dbg_regs_cache_dirty = 1;
return;
} /* remove_hw_watchpoint() */
 
/*---------------------------------------------------------------------------*/
/*!Enable a DCR/DVR watchpoint to generate a breakpoint
@param[in] wp_num The watchpoint number
*/
/*---------------------------------------------------------------------------*/
static void
enable_hw_breakpoint(int wp_num)
{
// Set the corresponding bit in DMR2 to enable matchpoint 'num' to trigger a breakpoint
or1k_dbg_group_regs_cache.dmr2 |= (uint32_t) (1 << (SPR_DMR2_WGB_OFF + wp_num));
// Mark the debug reg cache as dirty
dbg_regs_cache_dirty = 1;
return;
} /* enable_hw_breakpoint() */
 
/*---------------------------------------------------------------------------*/
/*!Disable a DCR/DVR watchpoint from generating a breakpoint
@param[in] wp_num The watchpoint number
*/
/*---------------------------------------------------------------------------*/
static void
disable_hw_breakpoint(int wp_num)
{
// Set the corresponding bit in DMR2 to enable matchpoint 'num' to trigger a breakpoint
or1k_dbg_group_regs_cache.dmr2 &= (uint32_t) ~(1 << (SPR_DMR2_WGB_OFF + wp_num));
// Mark the debug reg cache as dirty
dbg_regs_cache_dirty = 1;
return;
} /* disable_hw_breakpoint() */
/*---------------------------------------------------------------------------*/
/*!Handle a RSP remove breakpoint or matchpoint request
3283,6 → 3539,7
uint32_t addr; /* Address specified */
int len; /* Matchpoint length (not used) */
struct mp_entry *mpe; /* Info about the replaced instr */
int wp_num;
 
/* Break out the instruction */
if (3 != sscanf (p_buf->data, "z%1d,%x,%1d", (int *)&type, &addr, &len))
3334,7 → 3591,42
return;
case BP_HARDWARE:
put_str_packet (""); /* Not supported */
/* Adding support -- jb 090901 */
if (dbg_regs_cache_dirty == -1) // Regs invalid, get them
get_debug_registers();
 
if (DEBUG_GDB) printf("gdb - rsp_remove_matchpoint() - hardware mp remove at addr %.8x\n",addr);
#ifdef HWBP_BTWN
// Find the first of the pair of dcr/dvr registers
wp_num = find_matching_dcrdvr_pair(addr-4,OR1K_CC_GE);
#else
wp_num = find_matching_dcrdvr_pair(addr,OR1K_CC_EQ);
remove_hw_watchpoint(wp_num);
#endif
if ( wp_num < 0 )
{
printf("gdb - rsp_remove_matchpoint() failed to remove hardware breakpoint at addr %.8x\n",
addr);
put_str_packet ("E01"); /* Cannot remove */
return;
}
 
if (DEBUG_GDB) printf("gdb - rsp_remove_matchpoint() - mp to remove in DCR/DVR pair %d \n",wp_num);
remove_hw_watchpoint(wp_num);
 
#ifdef HWBP_BTWN
wp_num++;
/* Should probably check here that this is correct. Oh well. */
remove_hw_watchpoint(wp_num);
// Unchain these
or1k_dbg_group_regs_cache.dmr1 &= ~(SPR_DMR1_CW << (wp_num * SPR_DMR1_CW_SZ));
#endif
// Disable breakpoint generation
disable_hw_breakpoint(wp_num);
 
put_str_packet ("OK");
return;
 
case WP_WRITE:
3358,7 → 3650,6
}
} /* rsp_remove_matchpoint () */
 
/*---------------------------------------------------------------------------*/
/*!Handle a RSP insert breakpoint or matchpoint request
 
3376,7 → 3667,8
enum mp_type type; /* What sort of matchpoint */
uint32_t addr; /* Address specified */
int len; /* Matchpoint length (not used) */
uint32_t instr;
uint32_t instr;
int wp_num;
 
/* Break out the instruction */
if (3 != sscanf (p_buf->data, "Z%1d,%x,%1d", (int *)&type, &addr, &len))
3423,7 → 3715,53
return;
case BP_HARDWARE: // hardware-breakpoint Z1 hbreak
put_str_packet (""); /* Not supported */
/* Adding support -- jb 090901 */
get_debug_registers(); // First update our copy of the debug registers
 
#ifdef HWBP_BTWN
if (count_free_dcrdvr_pairs() < 2) /* Need at least two spare watchpoints free */
put_str_packet (""); /* Cannot add */
#endif
 
wp_num = find_free_dcrdvr_pair();
if (wp_num == -1)
{
put_str_packet (""); /* Could not find a place to put the breakpoint */
}
 
#ifdef HWBP_BTWN
if ((wp_num >= OR1K_MAX_MATCHPOINTS-1)
|| (wp_num %2 != 0)) /* Should have gotten either, 0,2,4,6 */
{
/* Something is wrong - can't do it */
put_str_packet ("");
return;
}
 
// First watchpoint to watch for address greater than the address
insert_hw_watchpoint(wp_num, addr-4, OR1K_CC_GE);
 
wp_num++; // The watchpoints should be next to each other.
// Second watchpoint to watch for address less than the address
insert_hw_watchpoint(wp_num, addr+4, OR1K_CC_LE);
 
// Chain these two together
// First clear the chain settings for this wp (2 bits per)
or1k_dbg_group_regs_cache.dmr1 &= ~(SPR_DMR1_CW << (wp_num * SPR_DMR1_CW_SZ));
// We will trigger a match when wp-1 {_-*{>AND<}*-_} wp go off.
or1k_dbg_group_regs_cache.dmr1 |= (SPR_DMR1_CW_AND << (wp_num * SPR_DMR1_CW_SZ));
// Now enable this send wp (the higher of the two) to trigger a matchpoint
#else
/* Simply insert a watchpoint at the address */
insert_hw_watchpoint(wp_num, addr, OR1K_CC_EQ);
 
#endif
 
enable_hw_breakpoint(wp_num);
put_str_packet ("OK");
return;
case WP_WRITE: // write-watchpoint Z2 watch
3505,7 → 3843,7
int gdb_read_reg(uint32_t adr, uint32_t *data) {
if (DEBUG_CMDS) printf("rreg %d\n", gdb_chain);
switch (gdb_chain) {
case SC_RISC_DEBUG: return dbg_cpu0_read(adr, data) ? ERR_CRC : ERR_NONE;
case SC_RISC_DEBUG: return dbg_cpu0_read(adr, data, 4) ? ERR_CRC : ERR_NONE;
case SC_REGISTER: return dbg_cpu0_read_ctrl(adr, (unsigned char*)data) ?
ERR_CRC : ERR_NONE;
case SC_WISHBONE: return dbg_wb_read32(adr, data) ? ERR_CRC : ERR_NONE;
3536,7 → 3874,7
if (DEBUG_CMDS) printf("wreg %d\n", gdb_chain); fflush (stdout);
switch (gdb_chain) { /* remap registers, to be compatible with jp1 */
case SC_RISC_DEBUG: if (adr == JTAG_RISCOP) adr = 0x00;
return dbg_cpu0_write(adr, data) ? ERR_CRC : ERR_NONE;
return dbg_cpu0_write(adr, &data, 4) ? ERR_CRC : ERR_NONE;
case SC_REGISTER: return dbg_cpu0_write_ctrl(adr, data) ? ERR_CRC : ERR_NONE;
case SC_WISHBONE: return dbg_wb_write32(adr, data) ? ERR_CRC : ERR_NONE;
case SC_TRACE: return 0;
3545,10 → 3883,10
}
 
int gdb_read_block(uint32_t adr, uint32_t *data, int len) {
if (DEBUG_CMDS) printf("rb %d\n", gdb_chain); fflush (stdout);
if (DEBUG_CMDS) printf("rb %d len %d\n", gdb_chain, len); fflush (stdout);
switch (gdb_chain) {
case SC_WISHBONE: return dbg_wb_read_block32(adr, data, len) ?
ERR_CRC : ERR_NONE;
case SC_RISC_DEBUG: return dbg_cpu0_read(adr, data, len) ? ERR_CRC : ERR_NONE;
case SC_WISHBONE: return dbg_wb_read_block32(adr, data, len) ? ERR_CRC : ERR_NONE;
default: return JTAG_PROXY_INVALID_CHAIN;
}
}
3556,6 → 3894,7
int gdb_write_block(uint32_t adr, uint32_t *data, int len) {
if (DEBUG_CMDS) printf("wb %d\n", gdb_chain); fflush (stdout);
switch (gdb_chain) {
case SC_RISC_DEBUG: return dbg_cpu0_write(adr, data, len) ? ERR_CRC : ERR_NONE;
case SC_WISHBONE: return dbg_wb_write_block32(adr, data, len) ?
ERR_CRC : ERR_NONE;
default: return JTAG_PROXY_INVALID_CHAIN;
/trunk/orpsocv2/bench/verilog/vpi/verilog/vpi_debug_module.v
201,15 → 201,24
begin
$get_command_address(cmd_adr);
 
$get_command_data(block_cmd_length);
 
$get_command_block_data(block_cmd_length, data_storage);
$get_command_data(cmd_data);
 
if (block_cmd_length > 4)
cpu_write_block(cmd_adr, block_cmd_length);
else
begin
cmd_data = data_storage[0]; // Get the single word we'll write
cpu_write_32(cmd_data, cmd_adr,16'h3);
`ifdef VPI_DEBUG_INFO
$display("CPU reg write. adr: 0x%x (reg group: %d reg#: %d), val: 0x%x",
cmd_adr,cmd_adr[15:11], cmd_adr[10:0], cmd_data);
`endif
end
cpu_write_32(cmd_data, cmd_adr,16'h3);
 
end
218,15 → 227,27
 
$get_command_address(cmd_adr);
 
cpu_read_32(cmd_data, cmd_adr, 16'h3);
$get_command_data(block_cmd_length); // Added 090901 --jb
 
/* Depending on size, issue a block or single read */
if (block_cmd_length > 4 )
cpu_read_block(cmd_adr, block_cmd_length);
else
cpu_read_32(cmd_data, cmd_adr, 16'h3);
 
`ifdef VPI_DEBUG_INFO
$display("CPU reg read. adr: 0x%x (reg group: %d reg#: %d), val: 0x%x",
cmd_adr,cmd_adr[15:11], cmd_adr[10:0], cmd_data);
if (cmd_size > 4 )
$display("CPU reg read. block adr: 0x%x (reg group: %d reg#: %d), num: %d",
cmd_adr,cmd_adr[15:11], cmd_adr[10:0], block_cmd_length);
else
$display("CPU reg read. adr: 0x%x (reg group: %d reg#: %d), val: 0x%x",
cmd_adr,cmd_adr[15:11], cmd_adr[10:0], cmd_data);
`endif
 
$return_command_data(cmd_data);
$return_command_block_data(block_cmd_length, data_storage);
end
`CMD_WB_WR :
1255,8 → 1276,32
end
endtask
 
// block of 32-bit reads from cpu
task cpu_read_block;
//output [31:0] data;
input [`DBG_WB_ADR_LEN -1:0] addr;
input [`DBG_WB_LEN_LEN -1:0] length;
 
reg [31:0] tmp;
 
begin
debug_cpu_wr_comm(`DBG_CPU_READ, addr, length-1, 1'b0);
last_cpu_cmd = `DBG_CPU_READ; last_cpu_cmd_text = "DBG_CPU_READ";
length_global = length;
debug_cpu_go(1'b0, 1'b0);
//data = data_storage[0];
//if (length>3)
// $display("WARNING: Only first data word is returned( See module %m.)");
end
endtask
 
 
// 32-bit write to cpu
task cpu_write_32;
input [31:0] data;
1276,8 → 1321,24
end
endtask
 
// block of 32-bit writes to cpu
// Data will already be in data_storage
task cpu_write_block;
//input [31:0] data;
input [`DBG_WB_ADR_LEN -1:0] addr;
input [`DBG_WB_LEN_LEN -1:0] length;
 
reg [31:0] tmp;
 
begin
debug_cpu_wr_comm(`DBG_CPU_WRITE, addr, length-1, 1'b0);
last_cpu_cmd = `DBG_CPU_WRITE; last_cpu_cmd_text = "DBG_CPU_WRITE";
length_global = length;
debug_cpu_go(1'b0, 1'b0);
end
endtask
 
 
task debug_cpu_wr_comm;
input [`DBG_CPU_ACC_TYPE_LEN -1:0] acc_type;
input [`DBG_CPU_ADR_LEN -1:0] addr;
/trunk/orpsocv2/rtl/verilog/or1200_defines.v
363,8 → 363,8
// (consider available FPGA memory resources)
//
//`define OR1200_IC_1W_512B
`define OR1200_IC_1W_4KB
//`define OR1200_IC_1W_8KB
//`define OR1200_IC_1W_4KB
`define OR1200_IC_1W_8KB
`define OR1200_DC_1W_4KB
//`define OR1200_DC_1W_8KB
 
985,7 → 985,7
// however already enough for use
// with or32 gdb)
//
//`define OR1200_DU_HWBKPTS
`define OR1200_DU_HWBKPTS
 
// Number of DVR/DCR pairs if HW breakpoints enabled
`define OR1200_DU_DVRDCR_PAIRS 8
1061,8 → 1061,8
// DMR2 bits
`define OR1200_DU_DMR2_WCE0 0
`define OR1200_DU_DMR2_WCE1 1
`define OR1200_DU_DMR2_AWTC 12:2
`define OR1200_DU_DMR2_WGB 23:13
`define OR1200_DU_DMR2_AWTC 11:2
`define OR1200_DU_DMR2_WGB 23:12
 
// DWCR bits
`define OR1200_DU_DWCR_COUNT 15:0
/trunk/orpsocv2/rtl/verilog/components/smii/smii_txrx.v
1,293 → 1,371
//////////////////////////////////////////////////////////////////////
//// ////
//// SMII ////
//// ////
//// Description ////
//// Low pin count serial MII ethernet interface ////
//// ////
//// To Do: ////
//// - ////
//// ////
//// Author(s): ////
//// - Michael Unneback, unneback@opencores.org ////
//// ORSoC AB michael.unneback@orsoc.se ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source 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 Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
module smii_txrx
(
// SMII
output tx,
input rx,
// MII
// TX
input [3:0] mtxd,
input mtxen,
input mtxerr,
output mtx_clk,
// RX
output reg [3:0] mrxd,
output reg mrxdv,
output reg mrxerr,
output mrx_clk,
output mcoll,
output reg mcrs,
`ifdef SMII_SPEED
output reg speed,
`endif
`ifdef SMII_DUPLEX
output reg duplex,
`endif
`ifdef SMII_LINK
output reg link,
`endif
// internal
input [10:1] state,
// clock and reset
input clk,
input rst
);
 
reg [7:0] tx_data_reg;
reg tx_data_reg_valid;
reg a0;
reg state_data;
 
reg [3:0] rx_tmp;
`ifndef SMII_SPEED
reg speed;
`endif
`ifndef SMII_DUPLEX
reg duplex;
`endif
`ifndef SMII_LINK
reg link;
`endif
reg jabber;
 
reg mtx_clk_tmp, mrx_clk_tmp;
 
reg [3:0] tx_cnt;
reg [3:0] rx_cnt;
/////////////////////////////////////////////////
// Speed
 
always @ (posedge clk or posedge rst)
if (rst)
tx_cnt <= 4'd0;
else
if (speed)
tx_cnt <= 4'd0;
else if (state[10])
if (tx_cnt == 4'd9)
tx_cnt <= 4'd0;
else
tx_cnt <= tx_cnt + 4'd1;
/////////////////////////////////////////////////
// Transmit
 
/* Timing scheme:
On the first clock of segment 0 (so each segment when 100Mb/s,
fast ethernet, or every 10 segments for 10Mb/s ethernet) we
deteremine if that segment is data or not, depending on what is
in the tx_data_reg_valid register. If the MAC wants to transmit
something, we overwrite the previously sent values when they're
no longer needed. Once the first nibble is sent, we can then
overwrite it, and same for the second - so we generate the TX
clock when state is 5, and sample the new nibble on the next
clock, same with the second nibble, that is clocked when state
is 9, and sampled when it is 10, so it gets overwritten when
we've finished putting it on the serial line.*/
always @ (posedge clk or posedge rst)
if (rst)
mtx_clk_tmp <= 1'b0;
else
if ((state[5] | state[9]) & (tx_cnt == 4'd0))
mtx_clk_tmp <= 1'b1;
else if (state[6] | state[10])
mtx_clk_tmp <= 1'b0;
 
`ifdef ACTEL
gbuf bufg1
(
.CLK(mtx_clk_tmp),
.GL(mtx_clk)
);
`else
assign #1 mtx_clk = mtx_clk_tmp;
`endif
 
// storage of data from MII
always @ (posedge clk or posedge rst)
if (rst)
begin
tx_data_reg <= 8'd0;
tx_data_reg_valid <= 1'b0;
a0 <= 1'b0;
end
else
if ((state[6] | state[10]) & (tx_cnt == 4'd0))
begin
/* Toggale a0 when MII TX_EN goes high */
if (!mtxen)
a0 <= 1'b0;
else
a0 <= ~a0;
 
/* byte will be valid when MII TX_EN
is high from the MAC */
if (!mtxen & !a0)
tx_data_reg_valid <= 1'b0;
else if (a0)
tx_data_reg_valid <= 1'b1;
 
/* Sample the nibble */
if (mtxen & !a0)
tx_data_reg[3:0] <= mtxd;
else if (mtxen & a0)
tx_data_reg[7:4] <= mtxd;
end // if ((state[4] | state[9]) & (tx_cnt == 4'd0))
 
/* Determine if we output a data byte or the inter-frame sequence
with status information */
always @ (posedge clk or posedge rst)
if (rst)
state_data <= 1'b0;
else
if (state[1] & (tx_cnt == 4'd0))
state_data <= tx_data_reg_valid;
/* A wire hooked up from bit 0 with the last byte of the state counter/shiftreg */
wire [7:0] state_data_byte;
assign state_data_byte[7:0] = state[10:3];
/* Assign the SMII TX wire */
/* First bit always TX_ERR, then depending on the next bit, TX_EN, output
either the inter-frame status byte or a data byte */
assign tx = state[1] ? mtxerr :
state[2] ? ((tx_data_reg_valid & (tx_cnt == 4'd0)) | state_data) :
state_data ? |(state_data_byte & tx_data_reg) :
|(state_data_byte & {3'b111,jabber,link,duplex,speed,mtxerr});
 
/////////////////////////////////////////////////
// Receive
 
always @ (posedge clk or posedge rst)
if (rst)
rx_cnt <= 4'd0;
else
if (speed)
rx_cnt <= 4'd0;
else if (!mrxdv & state[8] & rx_tmp[3])
rx_cnt <= 4'd9;
else if (state[10])
if (rx_cnt == 4'd9)
rx_cnt <= 4'd0;
else
rx_cnt <= rx_cnt + 4'd1;
always @ (posedge clk or posedge rst)
if (rst)
begin
{mcrs, mrxdv, mrxerr, speed, duplex, link, jabber} <= 7'b0001110;
rx_tmp <= 4'h0;
mrxd <= 4'h0;
end
else
begin
/* Continually shift rx into rx_tmp bit 2, and shift rx_tmp along */
rx_tmp[2:0] <= {rx,rx_tmp[2:1]};
 
/* We appear to be beginning our sampling when state bit 3 is set */
if (state[3])
mcrs <= rx;
/* rx_tmp[3] is used as the RX_DV bit*/
if (state[4])
rx_tmp[3] <= rx;
 
if (rx_tmp[3]) //If data byte valid, and when we've got the first nibble, output it */
begin
/* At this stage we've got the first 3 bits of the bottom
nibble - we can sample the rx line directly to get the
4th, and we'll also indicate that this byte is valid by
raising the MII RX data valid (dv) line. */
if (state[8])
{mrxdv,mrxd} <= #1 {rx_tmp[3],rx,rx_tmp[2:0]};
/* High nibble, we have 3 bits and the final one is on
the line - put it out for the MAC to read.*/
else if (state[2])
mrxd <= #1 {rx,rx_tmp[2:0]};
end
else
begin
/* Not a data byte, it's the inter-frame status byte */
if (state[5])
mrxerr <= #1 rx;
if (state[6])
speed <= #1 rx;
if (state[7])
duplex <= #1 rx;
if (state[8])
begin
link <= #1 rx;
mrxdv <= #1 1'b0;
end
if (state[9])
jabber <= #1 rx;
end
end // else: !if(rst)
always @ (posedge clk or posedge rst)
if (rst)
mrx_clk_tmp <= 1'b0;
else
if ((state[1] | state[6]) & (rx_cnt == 4'd0))
mrx_clk_tmp <= 1'b1;
else if (state[3] | state[8])
mrx_clk_tmp <= 1'b0;
 
`ifdef ACTEL
gbuf bufg2
(
.CLK(mrx_clk_tmp),
.GL(mrx_clk)
);
`else
assign #1 mrx_clk = mrx_clk_tmp;
`endif
assign mcoll = mcrs & mtxen & !duplex;
endmodule // smii_top
//////////////////////////////////////////////////////////////////////
//// ////
//// SMII ////
//// ////
//// Description ////
//// Low pin count serial MII ethernet interface ////
//// ////
//// To Do: ////
//// - ////
//// ////
//// Author(s): ////
//// - Michael Unneback, unneback@opencores.org ////
//// ORSoC AB michael.unneback@orsoc.se ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source 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 Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
module smii_txrx
(
// SMII
output tx,
input rx,
// MII
// TX
input [3:0] mtxd,
input mtxen,
input mtxerr,
output mtx_clk,
// RX
output reg [3:0] mrxd,
output reg mrxdv,
output reg mrxerr,
output mrx_clk,
output mcoll,
output reg mcrs,
`ifdef SMII_SPEED
output reg speed,
`endif
`ifdef SMII_DUPLEX
output reg duplex,
`endif
`ifdef SMII_LINK
output reg link,
`endif
// internal
input [10:1] state,
// clock and reset
input clk,
input rst
);
 
reg [7:0] tx_data_reg;
reg tx_data_reg_valid;
reg a0;
reg state_data;
 
reg [3:0] rx_tmp;
`ifndef SMII_SPEED
reg speed;
`endif
`ifndef SMII_DUPLEX
reg duplex;
`endif
`ifndef SMII_LINK
reg link;
`endif
reg jabber;
 
reg mtx_clk_tmp, mrx_clk_tmp;
 
reg [3:0] tx_cnt;
reg [3:0] rx_cnt;
/////////////////////////////////////////////////
// Speed
 
always @ (posedge clk or posedge rst)
if (rst)
tx_cnt <= 4'd0;
else
if (speed)
tx_cnt <= 4'd0;
else if (state[10])
if (tx_cnt == 4'd9)
tx_cnt <= 4'd0;
else
tx_cnt <= tx_cnt + 4'd1;
/////////////////////////////////////////////////
// Transmit
 
/* Timing scheme:
If we're fast ethernet, we clock every segment. Otherwise it's every 10 segments for 10mbit ethernet.
For 10mbit ethernet it doesn't really matter where we clock it - we have plenty of time to put out the right bits.
For fast ethernet, we have to do it at the right points.
so the MII TX nibble clocks come on the 8th state of the segment prior to the one we will output, then on the 3rd clock of the segment we're currently outputting.*/
`define MII_TXNIB1_CLK 8
`define MII_TXNIB2_CLK 3
 
// tx_data_reg_valid here helps us make sure we always sample data beginning with the nib1 clock
`define MII_TX_CLK_ASSERT ( \
((state[`MII_TXNIB1_CLK] | (state[`MII_TXNIB2_CLK] & tx_data_reg_valid)) \
& \
( \
((tx_cnt == 4'd0) & speed) | \
((tx_cnt == 4'd9) & !(speed) & state[`MII_TXNIB1_CLK]) | \
((tx_cnt == 4'd0) & !(speed) & tx_data_reg_valid & state[`MII_TXNIB2_CLK]) \
)))
 
`define MII_TX_CLOCKED ( \
((state[`MII_TXNIB1_CLK+1] | (state[`MII_TXNIB2_CLK+1] & tx_data_reg_valid)) \
& \
( \
((tx_cnt == 4'd0) & speed) | \
((tx_cnt == 4'd9) & !(speed) & state[`MII_TXNIB1_CLK + 1]) | \
((tx_cnt == 4'd0) & !(speed) & tx_data_reg_valid & state[`MII_TXNIB2_CLK + 1]) \
)))
always @ (posedge clk or posedge rst)
if (rst)
mtx_clk_tmp <= 1'b0;
else
if (`MII_TX_CLK_ASSERT)
mtx_clk_tmp <= 1'b1;
else //if (state[`MII_TXNIB1_CLK + 1] | state[`MII_TXNIB2_CLK + 1])
mtx_clk_tmp <= 1'b0;
 
`ifdef ACTEL
gbuf bufg1
(
.CLK(mtx_clk_tmp),
.GL(mtx_clk)
);
`else
assign mtx_clk = mtx_clk_tmp;
`endif
 
// storage of data from MII
always @ (posedge clk or posedge rst)
if (rst)
begin
tx_data_reg <= 8'd0;
tx_data_reg_valid <= 1'b0;
a0 <= 1'b0;
end
else
if (`MII_TX_CLOCKED)
begin
/* Toggale a0 when MII TX_EN goes high */
if (!mtxen)
a0 <= 1'b0;
else
a0 <= ~a0;
 
tx_data_reg_valid <= mtxen;
/* Sample the nibble */
if (mtxen & !a0)
tx_data_reg[3:0] <= mtxd;
else if (mtxen & a0)
tx_data_reg[7:4] <= mtxd;
end // if ((state[4] | state[9]) & (tx_cnt == 4'd0))
 
/* Determine if we output a data byte or the inter-frame sequence
with status information */
always @ (posedge clk or posedge rst)
if (rst)
state_data <= 1'b0;
else
if (state[1] & (tx_cnt == 4'd0))
state_data <= tx_data_reg_valid;
/* A wire hooked up from bit 0 with the last byte of the state counter/shiftreg */
wire [7:0] state_data_byte;
assign state_data_byte[7:0] = state[10:3];
/* Assign the SMII TX wire */
/* First bit always TX_ERR, then depending on the next bit, TX_EN, output
either the inter-frame status byte or a data byte */
assign tx = state[1] ? mtxerr :
state[2] ? ((tx_data_reg_valid & (tx_cnt == 4'd0)) | state_data) :
state_data ? |(state_data_byte & tx_data_reg) :
|(state_data_byte & {3'b111,jabber,link,duplex,speed,mtxerr});
 
/////////////////////////////////////////////////
// Receive
 
always @ (posedge clk or posedge rst)
if (rst)
rx_cnt <= 4'd0;
else
if (speed)
rx_cnt <= 4'd0;
else if (!mrxdv & state[8] & rx_tmp[3]) // Getting ready for data
rx_cnt <= 4'd9;
else if (state[10]) // wrap
if (rx_cnt == 4'd9)
rx_cnt <= 4'd0;
else
rx_cnt <= rx_cnt + 4'd1;
always @ (posedge clk or posedge rst)
if (rst)
begin
{mcrs, mrxdv, mrxerr, speed, duplex, link, jabber} <= 7'b0001110;
rx_tmp <= 4'h0;
mrxd <= 4'h0;
end
else
begin
/* Continually shift rx into rx_tmp bit 2, and shift rx_tmp along */
rx_tmp[2:0] <= {rx,rx_tmp[2:1]};
`define RX_BEGIN_STATE 3
/* We appear to be beginning our sampling when state bit 3 is set */
if (state[`RX_BEGIN_STATE]) //3
mcrs <= rx;
/* rx_tmp[3] is used as the RX_DV bit*/
if (state[`RX_BEGIN_STATE+1])
rx_tmp[3] <= rx;
 
if (rx_tmp[3]) //If data byte valid, and when we've got the first nibble, output it */
begin
/* At this stage we've got the first 3 bits of the bottom
nibble - we can sample the rx line directly to get the
4th, and we'll also indicate that this byte is valid by
raising the MII RX data valid (dv) line. */
if (state[`RX_BEGIN_STATE+5])
{mrxdv,mrxd} <= {rx_tmp[3],rx,rx_tmp[2:0]};
/* High nibble, we have 3 bits and the final one is on
the line - put it out for the MAC to read.*/
else if (state[`RX_BEGIN_STATE-1])
mrxd <= {rx,rx_tmp[2:0]};
end
else
begin
/* Not a data byte, it's the inter-frame status byte */
if (state[`RX_BEGIN_STATE+2])
mrxerr <= rx;
if (state[`RX_BEGIN_STATE+3])
speed <= rx;
if (state[`RX_BEGIN_STATE+4])
duplex <= rx;
if (state[`RX_BEGIN_STATE+5])
begin
link <= rx;
mrxdv <= 1'b0;
end
if (state[`RX_BEGIN_STATE+6])
jabber <= rx;
end
end // else: !if(rst)
always @ (posedge clk or posedge rst)
if (rst)
mrx_clk_tmp <= 1'b0;
else
//if ((state[1] | state[6]) & (rx_cnt == 4'd0))
if (((state[`RX_BEGIN_STATE+3] | state[`RX_BEGIN_STATE-1]) & (rx_cnt == 4'd0) & speed)
| ((((state[`RX_BEGIN_STATE+3] & (rx_cnt == 4'd0)) | (state[`RX_BEGIN_STATE-1]) & (rx_cnt == 4'd1) & !speed ) )))
mrx_clk_tmp <= 1'b1;
//else if (state[3] | state[8])
else if (state[`RX_BEGIN_STATE+5] | state[`RX_BEGIN_STATE+1])
mrx_clk_tmp <= 1'b0;
 
`ifdef ACTEL
gbuf bufg2
(
.CLK(mrx_clk_tmp),
.GL(mrx_clk)
);
`else
assign mrx_clk = mrx_clk_tmp;
`endif
assign mcoll = mcrs & mtxen & !duplex;
endmodule // smii_top
 
module smii_sync
(
// SMII sync
output sync,
// internal
output reg [10:1] state,
// clock amd reset
input clk,
input rst
);
// sync shall go high every 10:th cycle
always @ (posedge clk or posedge rst)
if (rst)
state <= 10'b0000000001;
else
state <= {state[9:1],state[10]};
 
assign sync = state[1];
endmodule // smii_sync
 
module obufdff
(
input d,
output reg pad,
input clk,
input rst
);
always @ (posedge clk or posedge rst)
if (rst)
pad <= 1'b0;
else
pad <= d;
endmodule
module ibufdff
(
input pad,
output reg q,
input clk,
input rst
);
always @ (posedge clk or posedge rst)
if (rst)
q <= 1'b0;
else
q <= pad;
endmodule
module iobuftri
(
input i,
input oe,
output o,
inout pad
);
assign pad = oe ? i : 1'bz;
assign o = pad;
endmodule
module obuf
(
input i,
inout pad
);
assign pad = i;
endmodule
/trunk/orpsocv2/rtl/verilog/components/debug_if/dbg_cpu.v
685,7 → 685,8
else if (set_addr_cpu && (!set_addr_cpu_q)) // Setting starting address
cpu_addr_dsff <= #1 adr;
else if (cpu_ack_i && (!cpu_ack_q))
cpu_addr_dsff <= #1 cpu_addr_dsff + 3'd4;
//cpu_addr_dsff <= #1 cpu_addr_dsff + 3'd4;
cpu_addr_dsff <= #1 cpu_addr_dsff + 3'd1; // Increment by just 1, to allow block reading -- jb 090901
end
 
 
/trunk/orpsocv2/rtl/verilog/components/or1200r2/or1200_du.v
830,9 → 830,9
`ifdef OR1200_DU_DCR0
always @(posedge clk or posedge rst)
if (rst)
dcr0 <= 8'h00;
dcr0 <= 8'h01;
else if (dcr0_sel && spr_write)
dcr0 <= #1 spr_dat_i[7:0];
dcr0[7:1] <= #1 spr_dat_i[7:1];
`else
assign dcr0 = 8'h00;
`endif
843,9 → 843,9
`ifdef OR1200_DU_DCR1
always @(posedge clk or posedge rst)
if (rst)
dcr1 <= 8'h00;
dcr1 <= 8'h01;
else if (dcr1_sel && spr_write)
dcr1 <= #1 spr_dat_i[7:0];
dcr1[7:1] <= #1 spr_dat_i[7:1];
`else
assign dcr1 = 8'h00;
`endif
856,9 → 856,9
`ifdef OR1200_DU_DCR2
always @(posedge clk or posedge rst)
if (rst)
dcr2 <= 8'h00;
dcr2 <= 8'h01;
else if (dcr2_sel && spr_write)
dcr2 <= #1 spr_dat_i[7:0];
dcr2[7:1] <= #1 spr_dat_i[7:1];
`else
assign dcr2 = 8'h00;
`endif
869,9 → 869,9
`ifdef OR1200_DU_DCR3
always @(posedge clk or posedge rst)
if (rst)
dcr3 <= 8'h00;
dcr3 <= 8'h01;
else if (dcr3_sel && spr_write)
dcr3 <= #1 spr_dat_i[7:0];
dcr3[7:1] <= #1 spr_dat_i[7:1];
`else
assign dcr3 = 8'h00;
`endif
882,9 → 882,9
`ifdef OR1200_DU_DCR4
always @(posedge clk or posedge rst)
if (rst)
dcr4 <= 8'h00;
dcr4 <= 8'h01;
else if (dcr4_sel && spr_write)
dcr4 <= #1 spr_dat_i[7:0];
dcr4[7:1] <= #1 spr_dat_i[7:1];
`else
assign dcr4 = 8'h00;
`endif
895,9 → 895,9
`ifdef OR1200_DU_DCR5
always @(posedge clk or posedge rst)
if (rst)
dcr5 <= 8'h00;
dcr5 <= 8'h01;
else if (dcr5_sel && spr_write)
dcr5 <= #1 spr_dat_i[7:0];
dcr5[7:1] <= #1 spr_dat_i[7:1];
`else
assign dcr5 = 8'h00;
`endif
908,9 → 908,9
`ifdef OR1200_DU_DCR6
always @(posedge clk or posedge rst)
if (rst)
dcr6 <= 8'h00;
dcr6 <= 8'h01;
else if (dcr6_sel && spr_write)
dcr6 <= #1 spr_dat_i[7:0];
dcr6[7:1] <= #1 spr_dat_i[7:1];
`else
assign dcr6 = 8'h00;
`endif
921,9 → 921,9
`ifdef OR1200_DU_DCR7
always @(posedge clk or posedge rst)
if (rst)
dcr7 <= 8'h00;
dcr7 <= 8'h01;
else if (dcr7_sel && spr_write)
dcr7 <= #1 spr_dat_i[7:0];
dcr7[7:1] <= #1 spr_dat_i[7:1];
`else
assign dcr7 = 8'h00;
`endif
1111,34 → 1111,44
default:match_cond0_stb = dcpu_cycstb_i; // any load/store
endcase
 
//
// Match Condition 0
//
always @(match_cond0_stb or dcr0 or dvr0 or match_cond0_ct)
casex ({match_cond0_stb, dcr0[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match0 = 1'b0;
4'b1_001: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) ==
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]));
4'b1_010: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) <
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]));
4'b1_011: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) <=
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]));
4'b1_100: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) >
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]));
4'b1_101: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) >=
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]));
4'b1_110: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) !=
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]));
endcase
// Debugging hwbkpoint match conditions
wire match0_dbg1;
assign match0_dbg1 = (match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]);
wire match0_dbg2;
assign match0_dbg2 = (dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]);
 
//
// Match Condition 0
//
always @(match_cond0_stb or dcr0 or dvr0 or match_cond0_ct)
casex ({match_cond0_stb, dcr0[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match0 = 1'b0;
4'b1_001: match0 = ( match_cond0_ct[30:0] == dvr0[30:0] );
4'b1_010: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) <
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]))&&
( match_cond0_ct[30:0] < dvr0[30:0]);
4'b1_011: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) <=
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]))&&
( match_cond0_ct[30:0] <= dvr0[30:0]);
4'b1_100: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) >
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]))&&
( match_cond0_ct[30:0] > dvr0[30:0]);
4'b1_101: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) >=
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]))&&
( match_cond0_ct[30:0] >= dvr0[30:0]);
4'b1_110: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) !=
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]))&&
( match_cond0_ct[30:0] != dvr0[30:0]);
endcase
 
//
// Watchpoint 0
//
1175,33 → 1185,36
default:match_cond1_stb = dcpu_cycstb_i; // any load/store
endcase
 
//
// Match Condition 1
//
always @(match_cond1_stb or dcr1 or dvr1 or match_cond1_ct)
casex ({match_cond1_stb, dcr1[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match1 = 1'b0;
4'b1_001: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) ==
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]));
4'b1_010: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) <
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]));
4'b1_011: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) <=
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]));
4'b1_100: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) >
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]));
4'b1_101: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) >=
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]));
4'b1_110: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) !=
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]));
endcase
//
// Match Condition 1
//
always @(match_cond1_stb or dcr1 or dvr1 or match_cond1_ct)
casex ({match_cond1_stb, dcr1[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match1 = 1'b0;
4'b1_001: match1 = ( match_cond1_ct[30:0] == dvr1[30:0] );
4'b1_010: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) <
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]))&&
( match_cond1_ct[30:0] < dvr1[30:0]);
4'b1_011: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) <=
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]))&&
( match_cond1_ct[30:0] <= dvr1[30:0]);
4'b1_100: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) >
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]))&&
( match_cond1_ct[30:0] > dvr1[30:0]);
4'b1_101: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) >=
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]))&&
( match_cond1_ct[30:0] >= dvr1[30:0]);
4'b1_110: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) !=
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]))&&
( match_cond1_ct[30:0] != dvr1[30:0]);
endcase
 
//
// Watchpoint 1
1239,34 → 1252,38
default:match_cond2_stb = dcpu_cycstb_i; // any load/store
endcase
 
//
// Match Condition 2
//
always @(match_cond2_stb or dcr2 or dvr2 or match_cond2_ct)
casex ({match_cond2_stb, dcr2[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match2 = 1'b0;
4'b1_001: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) ==
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]));
4'b1_010: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) <
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]));
4'b1_011: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) <=
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]));
4'b1_100: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) >
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]));
4'b1_101: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) >=
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]));
4'b1_110: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) !=
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]));
endcase
 
//
// Match Condition 2
//
always @(match_cond2_stb or dcr2 or dvr2 or match_cond2_ct)
casex ({match_cond2_stb, dcr2[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match2 = 1'b0;
4'b1_001: match2 = ( match_cond2_ct[30:0] == dvr2[30:0] );
4'b1_010: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) <
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]))&&
( match_cond2_ct[30:0] < dvr2[30:0]);
4'b1_011: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) <=
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]))&&
( match_cond2_ct[30:0] <= dvr2[30:0]);
4'b1_100: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) >
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]))&&
( match_cond2_ct[30:0] > dvr2[30:0]);
4'b1_101: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) >=
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]))&&
( match_cond2_ct[30:0] >= dvr2[30:0]);
4'b1_110: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) !=
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]))&&
( match_cond2_ct[30:0] != dvr2[30:0]);
endcase
 
//
// Watchpoint 2
//
1303,33 → 1320,37
default:match_cond3_stb = dcpu_cycstb_i; // any load/store
endcase
 
//
// Match Condition 3
//
always @(match_cond3_stb or dcr3 or dvr3 or match_cond3_ct)
casex ({match_cond3_stb, dcr3[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match3 = 1'b0;
4'b1_001: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) ==
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]));
4'b1_010: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) <
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]));
4'b1_011: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) <=
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]));
4'b1_100: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) >
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]));
4'b1_101: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) >=
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]));
4'b1_110: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) !=
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]));
endcase
//
// Match Condition 3
//
always @(match_cond3_stb or dcr3 or dvr3 or match_cond3_ct)
casex ({match_cond3_stb, dcr3[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match3 = 1'b0;
4'b1_001: match3 = ( match_cond3_ct[30:0] == dvr3[30:0] );
4'b1_010: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) <
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]))&&
( match_cond3_ct[30:0] < dvr3[30:0]);
4'b1_011: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) <=
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]))&&
( match_cond3_ct[30:0] <= dvr3[30:0]);
4'b1_100: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) >
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]))&&
( match_cond3_ct[30:0] > dvr3[30:0]);
4'b1_101: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) >=
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]))&&
( match_cond3_ct[30:0] >= dvr3[30:0]);
4'b1_110: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) !=
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]))&&
( match_cond3_ct[30:0] != dvr3[30:0]);
endcase
 
//
// Watchpoint 3
1367,34 → 1388,39
default:match_cond4_stb = dcpu_cycstb_i; // any load/store
endcase
 
//
// Match Condition 4
//
always @(match_cond4_stb or dcr4 or dvr4 or match_cond4_ct)
casex ({match_cond4_stb, dcr4[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match4 = 1'b0;
4'b1_001: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) ==
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]));
4'b1_010: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) <
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]));
4'b1_011: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) <=
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]));
4'b1_100: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) >
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]));
4'b1_101: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) >=
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]));
4'b1_110: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) !=
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]));
endcase
 
//
// Match Condition 4
//
always @(match_cond4_stb or dcr4 or dvr4 or match_cond4_ct)
casex ({match_cond4_stb, dcr4[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match4 = 1'b0;
4'b1_001: match4 = ( match_cond4_ct[30:0] == dvr4[30:0] );
4'b1_010: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) <
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]))&&
( match_cond4_ct[30:0] < dvr4[30:0]);
4'b1_011: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) <=
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]))&&
( match_cond4_ct[30:0] <= dvr4[30:0]);
4'b1_100: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) >
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]))&&
( match_cond4_ct[30:0] > dvr4[30:0]);
4'b1_101: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) >=
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]))&&
( match_cond4_ct[30:0] >= dvr4[30:0]);
4'b1_110: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) !=
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]))&&
( match_cond4_ct[30:0] != dvr4[30:0]);
endcase
 
 
//
// Watchpoint 4
//
1431,33 → 1457,37
default:match_cond5_stb = dcpu_cycstb_i; // any load/store
endcase
 
//
// Match Condition 5
//
always @(match_cond5_stb or dcr5 or dvr5 or match_cond5_ct)
casex ({match_cond5_stb, dcr5[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match5 = 1'b0;
4'b1_001: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) ==
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]));
4'b1_010: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) <
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]));
4'b1_011: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) <=
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]));
4'b1_100: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) >
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]));
4'b1_101: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) >=
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]));
4'b1_110: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) !=
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]));
endcase
//
// Match Condition 5
//
always @(match_cond5_stb or dcr5 or dvr5 or match_cond5_ct)
casex ({match_cond5_stb, dcr5[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match5 = 1'b0;
4'b1_001: match5 = ( match_cond5_ct[30:0] == dvr5[30:0] );
4'b1_010: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) <
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]))&&
( match_cond5_ct[30:0] < dvr5[30:0]);
4'b1_011: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) <=
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]))&&
( match_cond5_ct[30:0] <= dvr5[30:0]);
4'b1_100: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) >
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]))&&
( match_cond5_ct[30:0] > dvr5[30:0]);
4'b1_101: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) >=
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]))&&
( match_cond5_ct[30:0] >= dvr5[30:0]);
4'b1_110: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) !=
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]))&&
( match_cond5_ct[30:0] != dvr5[30:0]);
endcase
 
//
// Watchpoint 5
1495,34 → 1525,39
default:match_cond6_stb = dcpu_cycstb_i; // any load/store
endcase
 
//
// Match Condition 6
//
always @(match_cond6_stb or dcr6 or dvr6 or match_cond6_ct)
casex ({match_cond6_stb, dcr6[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match6 = 1'b0;
4'b1_001: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) ==
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]));
4'b1_010: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) <
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]));
4'b1_011: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) <=
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]));
4'b1_100: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) >
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]));
4'b1_101: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) >=
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]));
4'b1_110: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) !=
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]));
endcase
//
// Match Condition 6
//
always @(match_cond6_stb or dcr6 or dvr6 or match_cond6_ct)
casex ({match_cond6_stb, dcr6[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match6 = 1'b0;
4'b1_001: match6 = ( match_cond6_ct[30:0] == dvr6[30:0] );
4'b1_010: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) <
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]))&&
( match_cond6_ct[30:0] < dvr6[30:0]);
4'b1_011: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) <=
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]))&&
( match_cond6_ct[30:0] <= dvr6[30:0]);
4'b1_100: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) >
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]))&&
( match_cond6_ct[30:0] > dvr6[30:0]);
4'b1_101: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) >=
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]))&&
( match_cond6_ct[30:0] >= dvr6[30:0]);
4'b1_110: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) !=
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]))&&
( match_cond6_ct[30:0] != dvr6[30:0]);
endcase
 
 
//
// Watchpoint 6
//
1558,36 → 1593,39
3'b001: match_cond7_stb = 1'b1; // insn fetch EA
default:match_cond7_stb = dcpu_cycstb_i; // any load/store
endcase
//
// Match Condition 7
//
always @(match_cond7_stb or dcr7 or dvr7 or match_cond7_ct)
casex ({match_cond7_stb, dcr7[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match7 = 1'b0;
4'b1_001: match7 = ( match_cond7_ct[30:0] == dvr7[30:0] );
4'b1_010: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) <
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]))&&
( match_cond7_ct[30:0] < dvr7[30:0]);
4'b1_011: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) <=
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]))&&
( match_cond7_ct[30:0] <= dvr7[30:0]);
4'b1_100: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) >
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]))&&
( match_cond7_ct[30:0] > dvr7[30:0]);
4'b1_101: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) >=
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]))&&
( match_cond7_ct[30:0] >= dvr7[30:0]);
4'b1_110: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) !=
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]))&&
( match_cond7_ct[30:0] != dvr7[30:0]);
endcase
 
//
// Match Condition 7
//
always @(match_cond7_stb or dcr7 or dvr7 or match_cond7_ct)
casex ({match_cond7_stb, dcr7[`OR1200_DU_DCR_CC]})
4'b0_xxx,
4'b1_000,
4'b1_111: match7 = 1'b0;
4'b1_001: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) ==
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]));
4'b1_010: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) <
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]));
4'b1_011: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) <=
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]));
4'b1_100: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) >
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]));
4'b1_101: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) >=
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]));
4'b1_110: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) !=
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]));
endcase
 
//
// Watchpoint 7
//
always @(dmr1 or match7 or wp)
/trunk/orpsocv2/rtl/verilog/components/or1200r2/or1200_cfgr.v
79,158 → 79,158
`include "or1200_defines.v"
 
module or1200_cfgr(
// RISC Internal Interface
spr_addr, spr_dat_o
);
// RISC Internal Interface
spr_addr, spr_dat_o
);
 
//
// RISC Internal Interface
//
input [31:0] spr_addr; // SPR Address
output [31:0] spr_dat_o; // SPR Read Data
//
// RISC Internal Interface
//
input [31:0] spr_addr; // SPR Address
output [31:0] spr_dat_o; // SPR Read Data
 
//
// Internal wires & registers
//
reg [31:0] spr_dat_o; // SPR Read Data
//
// Internal wires & registers
//
reg [31:0] spr_dat_o; // SPR Read Data
 
`ifdef OR1200_CFGR_IMPLEMENTED
 
//
// Implementation of VR, UPR and configuration registers
//
always @(spr_addr)
`ifdef OR1200_SYS_FULL_DECODE
if (~|spr_addr[31:4])
`endif
case(spr_addr[3:0]) // synopsys parallel_case
`OR1200_SPRGRP_SYS_VR: begin
spr_dat_o[`OR1200_VR_REV_BITS] = `OR1200_VR_REV;
spr_dat_o[`OR1200_VR_RES1_BITS] = `OR1200_VR_RES1;
spr_dat_o[`OR1200_VR_CFG_BITS] = `OR1200_VR_CFG;
spr_dat_o[`OR1200_VR_VER_BITS] = `OR1200_VR_VER;
end
`OR1200_SPRGRP_SYS_UPR: begin
spr_dat_o[`OR1200_UPR_UP_BITS] = `OR1200_UPR_UP;
spr_dat_o[`OR1200_UPR_DCP_BITS] = `OR1200_UPR_DCP;
spr_dat_o[`OR1200_UPR_ICP_BITS] = `OR1200_UPR_ICP;
spr_dat_o[`OR1200_UPR_DMP_BITS] = `OR1200_UPR_DMP;
spr_dat_o[`OR1200_UPR_IMP_BITS] = `OR1200_UPR_IMP;
spr_dat_o[`OR1200_UPR_MP_BITS] = `OR1200_UPR_MP;
spr_dat_o[`OR1200_UPR_DUP_BITS] = `OR1200_UPR_DUP;
spr_dat_o[`OR1200_UPR_PCUP_BITS] = `OR1200_UPR_PCUP;
spr_dat_o[`OR1200_UPR_PMP_BITS] = `OR1200_UPR_PMP;
spr_dat_o[`OR1200_UPR_PICP_BITS] = `OR1200_UPR_PICP;
spr_dat_o[`OR1200_UPR_TTP_BITS] = `OR1200_UPR_TTP;
spr_dat_o[`OR1200_UPR_RES1_BITS] = `OR1200_UPR_RES1;
spr_dat_o[`OR1200_UPR_CUP_BITS] = `OR1200_UPR_CUP;
end
`OR1200_SPRGRP_SYS_CPUCFGR: begin
spr_dat_o[`OR1200_CPUCFGR_NSGF_BITS] = `OR1200_CPUCFGR_NSGF;
spr_dat_o[`OR1200_CPUCFGR_HGF_BITS] = `OR1200_CPUCFGR_HGF;
spr_dat_o[`OR1200_CPUCFGR_OB32S_BITS] = `OR1200_CPUCFGR_OB32S;
spr_dat_o[`OR1200_CPUCFGR_OB64S_BITS] = `OR1200_CPUCFGR_OB64S;
spr_dat_o[`OR1200_CPUCFGR_OF32S_BITS] = `OR1200_CPUCFGR_OF32S;
spr_dat_o[`OR1200_CPUCFGR_OF64S_BITS] = `OR1200_CPUCFGR_OF64S;
spr_dat_o[`OR1200_CPUCFGR_OV64S_BITS] = `OR1200_CPUCFGR_OV64S;
spr_dat_o[`OR1200_CPUCFGR_RES1_BITS] = `OR1200_CPUCFGR_RES1;
end
`OR1200_SPRGRP_SYS_DMMUCFGR: begin
spr_dat_o[`OR1200_DMMUCFGR_NTW_BITS] = `OR1200_DMMUCFGR_NTW;
spr_dat_o[`OR1200_DMMUCFGR_NTS_BITS] = `OR1200_DMMUCFGR_NTS;
spr_dat_o[`OR1200_DMMUCFGR_NAE_BITS] = `OR1200_DMMUCFGR_NAE;
spr_dat_o[`OR1200_DMMUCFGR_CRI_BITS] = `OR1200_DMMUCFGR_CRI;
spr_dat_o[`OR1200_DMMUCFGR_PRI_BITS] = `OR1200_DMMUCFGR_PRI;
spr_dat_o[`OR1200_DMMUCFGR_TEIRI_BITS] = `OR1200_DMMUCFGR_TEIRI;
spr_dat_o[`OR1200_DMMUCFGR_HTR_BITS] = `OR1200_DMMUCFGR_HTR;
spr_dat_o[`OR1200_DMMUCFGR_RES1_BITS] = `OR1200_DMMUCFGR_RES1;
end
`OR1200_SPRGRP_SYS_IMMUCFGR: begin
spr_dat_o[`OR1200_IMMUCFGR_NTW_BITS] = `OR1200_IMMUCFGR_NTW;
spr_dat_o[`OR1200_IMMUCFGR_NTS_BITS] = `OR1200_IMMUCFGR_NTS;
spr_dat_o[`OR1200_IMMUCFGR_NAE_BITS] = `OR1200_IMMUCFGR_NAE;
spr_dat_o[`OR1200_IMMUCFGR_CRI_BITS] = `OR1200_IMMUCFGR_CRI;
spr_dat_o[`OR1200_IMMUCFGR_PRI_BITS] = `OR1200_IMMUCFGR_PRI;
spr_dat_o[`OR1200_IMMUCFGR_TEIRI_BITS] = `OR1200_IMMUCFGR_TEIRI;
spr_dat_o[`OR1200_IMMUCFGR_HTR_BITS] = `OR1200_IMMUCFGR_HTR;
spr_dat_o[`OR1200_IMMUCFGR_RES1_BITS] = `OR1200_IMMUCFGR_RES1;
end
`OR1200_SPRGRP_SYS_DCCFGR: begin
spr_dat_o[`OR1200_DCCFGR_NCW_BITS] = `OR1200_DCCFGR_NCW;
spr_dat_o[`OR1200_DCCFGR_NCS_BITS] = `OR1200_DCCFGR_NCS;
spr_dat_o[`OR1200_DCCFGR_CBS_BITS] = `OR1200_DCCFGR_CBS;
spr_dat_o[`OR1200_DCCFGR_CWS_BITS] = `OR1200_DCCFGR_CWS;
spr_dat_o[`OR1200_DCCFGR_CCRI_BITS] = `OR1200_DCCFGR_CCRI;
spr_dat_o[`OR1200_DCCFGR_CBIRI_BITS] = `OR1200_DCCFGR_CBIRI;
spr_dat_o[`OR1200_DCCFGR_CBPRI_BITS] = `OR1200_DCCFGR_CBPRI;
spr_dat_o[`OR1200_DCCFGR_CBLRI_BITS] = `OR1200_DCCFGR_CBLRI;
spr_dat_o[`OR1200_DCCFGR_CBFRI_BITS] = `OR1200_DCCFGR_CBFRI;
spr_dat_o[`OR1200_DCCFGR_CBWBRI_BITS] = `OR1200_DCCFGR_CBWBRI;
spr_dat_o[`OR1200_DCCFGR_RES1_BITS] = `OR1200_DCCFGR_RES1;
end
`OR1200_SPRGRP_SYS_ICCFGR: begin
spr_dat_o[`OR1200_ICCFGR_NCW_BITS] = `OR1200_ICCFGR_NCW;
spr_dat_o[`OR1200_ICCFGR_NCS_BITS] = `OR1200_ICCFGR_NCS;
spr_dat_o[`OR1200_ICCFGR_CBS_BITS] = `OR1200_ICCFGR_CBS;
spr_dat_o[`OR1200_ICCFGR_CWS_BITS] = `OR1200_ICCFGR_CWS;
spr_dat_o[`OR1200_ICCFGR_CCRI_BITS] = `OR1200_ICCFGR_CCRI;
spr_dat_o[`OR1200_ICCFGR_CBIRI_BITS] = `OR1200_ICCFGR_CBIRI;
spr_dat_o[`OR1200_ICCFGR_CBPRI_BITS] = `OR1200_ICCFGR_CBPRI;
spr_dat_o[`OR1200_ICCFGR_CBLRI_BITS] = `OR1200_ICCFGR_CBLRI;
spr_dat_o[`OR1200_ICCFGR_CBFRI_BITS] = `OR1200_ICCFGR_CBFRI;
spr_dat_o[`OR1200_ICCFGR_CBWBRI_BITS] = `OR1200_ICCFGR_CBWBRI;
spr_dat_o[`OR1200_ICCFGR_RES1_BITS] = `OR1200_ICCFGR_RES1;
end
`OR1200_SPRGRP_SYS_DCFGR: begin
spr_dat_o[`OR1200_DCFGR_NDP_BITS] = `OR1200_DCFGR_NDP;
spr_dat_o[`OR1200_DCFGR_WPCI_BITS] = `OR1200_DCFGR_WPCI;
spr_dat_o[`OR1200_DCFGR_RES1_BITS] = `OR1200_DCFGR_RES1;
end
default: spr_dat_o = 32'h0000_0000;
endcase
`ifdef OR1200_SYS_FULL_DECODE
else
spr_dat_o = 32'h0000_0000;
`endif
//
// Implementation of VR, UPR and configuration registers
//
always @(spr_addr)
`ifdef OR1200_SYS_FULL_DECODE
if (~|spr_addr[31:4])
`endif
case(spr_addr[3:0]) // synopsys parallel_case
`OR1200_SPRGRP_SYS_VR: begin
spr_dat_o[`OR1200_VR_REV_BITS] = `OR1200_VR_REV;
spr_dat_o[`OR1200_VR_RES1_BITS] = `OR1200_VR_RES1;
spr_dat_o[`OR1200_VR_CFG_BITS] = `OR1200_VR_CFG;
spr_dat_o[`OR1200_VR_VER_BITS] = `OR1200_VR_VER;
end
`OR1200_SPRGRP_SYS_UPR: begin
spr_dat_o[`OR1200_UPR_UP_BITS] = `OR1200_UPR_UP;
spr_dat_o[`OR1200_UPR_DCP_BITS] = `OR1200_UPR_DCP;
spr_dat_o[`OR1200_UPR_ICP_BITS] = `OR1200_UPR_ICP;
spr_dat_o[`OR1200_UPR_DMP_BITS] = `OR1200_UPR_DMP;
spr_dat_o[`OR1200_UPR_IMP_BITS] = `OR1200_UPR_IMP;
spr_dat_o[`OR1200_UPR_MP_BITS] = `OR1200_UPR_MP;
spr_dat_o[`OR1200_UPR_DUP_BITS] = `OR1200_UPR_DUP;
spr_dat_o[`OR1200_UPR_PCUP_BITS] = `OR1200_UPR_PCUP;
spr_dat_o[`OR1200_UPR_PMP_BITS] = `OR1200_UPR_PMP;
spr_dat_o[`OR1200_UPR_PICP_BITS] = `OR1200_UPR_PICP;
spr_dat_o[`OR1200_UPR_TTP_BITS] = `OR1200_UPR_TTP;
spr_dat_o[`OR1200_UPR_RES1_BITS] = `OR1200_UPR_RES1;
spr_dat_o[`OR1200_UPR_CUP_BITS] = `OR1200_UPR_CUP;
end
`OR1200_SPRGRP_SYS_CPUCFGR: begin
spr_dat_o[`OR1200_CPUCFGR_NSGF_BITS] = `OR1200_CPUCFGR_NSGF;
spr_dat_o[`OR1200_CPUCFGR_HGF_BITS] = `OR1200_CPUCFGR_HGF;
spr_dat_o[`OR1200_CPUCFGR_OB32S_BITS] = `OR1200_CPUCFGR_OB32S;
spr_dat_o[`OR1200_CPUCFGR_OB64S_BITS] = `OR1200_CPUCFGR_OB64S;
spr_dat_o[`OR1200_CPUCFGR_OF32S_BITS] = `OR1200_CPUCFGR_OF32S;
spr_dat_o[`OR1200_CPUCFGR_OF64S_BITS] = `OR1200_CPUCFGR_OF64S;
spr_dat_o[`OR1200_CPUCFGR_OV64S_BITS] = `OR1200_CPUCFGR_OV64S;
spr_dat_o[`OR1200_CPUCFGR_RES1_BITS] = `OR1200_CPUCFGR_RES1;
end
`OR1200_SPRGRP_SYS_DMMUCFGR: begin
spr_dat_o[`OR1200_DMMUCFGR_NTW_BITS] = `OR1200_DMMUCFGR_NTW;
spr_dat_o[`OR1200_DMMUCFGR_NTS_BITS] = `OR1200_DMMUCFGR_NTS;
spr_dat_o[`OR1200_DMMUCFGR_NAE_BITS] = `OR1200_DMMUCFGR_NAE;
spr_dat_o[`OR1200_DMMUCFGR_CRI_BITS] = `OR1200_DMMUCFGR_CRI;
spr_dat_o[`OR1200_DMMUCFGR_PRI_BITS] = `OR1200_DMMUCFGR_PRI;
spr_dat_o[`OR1200_DMMUCFGR_TEIRI_BITS] = `OR1200_DMMUCFGR_TEIRI;
spr_dat_o[`OR1200_DMMUCFGR_HTR_BITS] = `OR1200_DMMUCFGR_HTR;
spr_dat_o[`OR1200_DMMUCFGR_RES1_BITS] = `OR1200_DMMUCFGR_RES1;
end
`OR1200_SPRGRP_SYS_IMMUCFGR: begin
spr_dat_o[`OR1200_IMMUCFGR_NTW_BITS] = `OR1200_IMMUCFGR_NTW;
spr_dat_o[`OR1200_IMMUCFGR_NTS_BITS] = `OR1200_IMMUCFGR_NTS;
spr_dat_o[`OR1200_IMMUCFGR_NAE_BITS] = `OR1200_IMMUCFGR_NAE;
spr_dat_o[`OR1200_IMMUCFGR_CRI_BITS] = `OR1200_IMMUCFGR_CRI;
spr_dat_o[`OR1200_IMMUCFGR_PRI_BITS] = `OR1200_IMMUCFGR_PRI;
spr_dat_o[`OR1200_IMMUCFGR_TEIRI_BITS] = `OR1200_IMMUCFGR_TEIRI;
spr_dat_o[`OR1200_IMMUCFGR_HTR_BITS] = `OR1200_IMMUCFGR_HTR;
spr_dat_o[`OR1200_IMMUCFGR_RES1_BITS] = `OR1200_IMMUCFGR_RES1;
end
`OR1200_SPRGRP_SYS_DCCFGR: begin
spr_dat_o[`OR1200_DCCFGR_NCW_BITS] = `OR1200_DCCFGR_NCW;
spr_dat_o[`OR1200_DCCFGR_NCS_BITS] = `OR1200_DCCFGR_NCS;
spr_dat_o[`OR1200_DCCFGR_CBS_BITS] = `OR1200_DCCFGR_CBS;
spr_dat_o[`OR1200_DCCFGR_CWS_BITS] = `OR1200_DCCFGR_CWS;
spr_dat_o[`OR1200_DCCFGR_CCRI_BITS] = `OR1200_DCCFGR_CCRI;
spr_dat_o[`OR1200_DCCFGR_CBIRI_BITS] = `OR1200_DCCFGR_CBIRI;
spr_dat_o[`OR1200_DCCFGR_CBPRI_BITS] = `OR1200_DCCFGR_CBPRI;
spr_dat_o[`OR1200_DCCFGR_CBLRI_BITS] = `OR1200_DCCFGR_CBLRI;
spr_dat_o[`OR1200_DCCFGR_CBFRI_BITS] = `OR1200_DCCFGR_CBFRI;
spr_dat_o[`OR1200_DCCFGR_CBWBRI_BITS] = `OR1200_DCCFGR_CBWBRI;
spr_dat_o[`OR1200_DCCFGR_RES1_BITS] = `OR1200_DCCFGR_RES1;
end
`OR1200_SPRGRP_SYS_ICCFGR: begin
spr_dat_o[`OR1200_ICCFGR_NCW_BITS] = `OR1200_ICCFGR_NCW;
spr_dat_o[`OR1200_ICCFGR_NCS_BITS] = `OR1200_ICCFGR_NCS;
spr_dat_o[`OR1200_ICCFGR_CBS_BITS] = `OR1200_ICCFGR_CBS;
spr_dat_o[`OR1200_ICCFGR_CWS_BITS] = `OR1200_ICCFGR_CWS;
spr_dat_o[`OR1200_ICCFGR_CCRI_BITS] = `OR1200_ICCFGR_CCRI;
spr_dat_o[`OR1200_ICCFGR_CBIRI_BITS] = `OR1200_ICCFGR_CBIRI;
spr_dat_o[`OR1200_ICCFGR_CBPRI_BITS] = `OR1200_ICCFGR_CBPRI;
spr_dat_o[`OR1200_ICCFGR_CBLRI_BITS] = `OR1200_ICCFGR_CBLRI;
spr_dat_o[`OR1200_ICCFGR_CBFRI_BITS] = `OR1200_ICCFGR_CBFRI;
spr_dat_o[`OR1200_ICCFGR_CBWBRI_BITS] = `OR1200_ICCFGR_CBWBRI;
spr_dat_o[`OR1200_ICCFGR_RES1_BITS] = `OR1200_ICCFGR_RES1;
end
`OR1200_SPRGRP_SYS_DCFGR: begin
spr_dat_o[`OR1200_DCFGR_NDP_BITS] = `OR1200_DCFGR_NDP;
spr_dat_o[`OR1200_DCFGR_WPCI_BITS] = `OR1200_DCFGR_WPCI;
spr_dat_o[`OR1200_DCFGR_RES1_BITS] = `OR1200_DCFGR_RES1;
end
default: spr_dat_o = 32'h0000_0000;
endcase
`ifdef OR1200_SYS_FULL_DECODE
else
spr_dat_o = 32'h0000_0000;
`endif
 
`else
 
//
// When configuration registers are not implemented, only
// implement VR and UPR
//
always @(spr_addr)
`ifdef OR1200_SYS_FULL_DECODE
if (spr_addr[31:4] == 28'h0)
`endif
case(spr_addr[3:0])
`OR1200_SPRGRP_SYS_VR: begin
spr_dat_o[`OR1200_VR_REV_BITS] = `OR1200_VR_REV;
spr_dat_o[`OR1200_VR_RES1_BITS] = `OR1200_VR_RES1;
spr_dat_o[`OR1200_VR_CFG_BITS] = `OR1200_VR_CFG;
spr_dat_o[`OR1200_VR_VER_BITS] = `OR1200_VR_VER;
end
`OR1200_SPRGRP_SYS_UPR: begin
spr_dat_o[`OR1200_UPR_UP_BITS] = `OR1200_UPR_UP;
spr_dat_o[`OR1200_UPR_DCP_BITS] = `OR1200_UPR_DCP;
spr_dat_o[`OR1200_UPR_ICP_BITS] = `OR1200_UPR_ICP;
spr_dat_o[`OR1200_UPR_DMP_BITS] = `OR1200_UPR_DMP;
spr_dat_o[`OR1200_UPR_IMP_BITS] = `OR1200_UPR_IMP;
spr_dat_o[`OR1200_UPR_MP_BITS] = `OR1200_UPR_MP;
spr_dat_o[`OR1200_UPR_DUP_BITS] = `OR1200_UPR_DUP;
spr_dat_o[`OR1200_UPR_PCUP_BITS] = `OR1200_UPR_PCUP;
spr_dat_o[`OR1200_UPR_PMP_BITS] = `OR1200_UPR_PMP;
spr_dat_o[`OR1200_UPR_PICP_BITS] = `OR1200_UPR_PICP;
spr_dat_o[`OR1200_UPR_TTP_BITS] = `OR1200_UPR_TTP;
spr_dat_o[`OR1200_UPR_RES1_BITS] = `OR1200_UPR_RES1;
spr_dat_o[`OR1200_UPR_CUP_BITS] = `OR1200_UPR_CUP;
end
default: spr_dat_o = 32'h0000_0000;
endcase
`ifdef OR1200_SYS_FULL_DECODE
else
spr_dat_o = 32'h0000_0000;
`endif
//
// When configuration registers are not implemented, only
// implement VR and UPR
//
always @(spr_addr)
`ifdef OR1200_SYS_FULL_DECODE
if (spr_addr[31:4] == 28'h0)
`endif
case(spr_addr[3:0])
`OR1200_SPRGRP_SYS_VR: begin
spr_dat_o[`OR1200_VR_REV_BITS] = `OR1200_VR_REV;
spr_dat_o[`OR1200_VR_RES1_BITS] = `OR1200_VR_RES1;
spr_dat_o[`OR1200_VR_CFG_BITS] = `OR1200_VR_CFG;
spr_dat_o[`OR1200_VR_VER_BITS] = `OR1200_VR_VER;
end
`OR1200_SPRGRP_SYS_UPR: begin
spr_dat_o[`OR1200_UPR_UP_BITS] = `OR1200_UPR_UP;
spr_dat_o[`OR1200_UPR_DCP_BITS] = `OR1200_UPR_DCP;
spr_dat_o[`OR1200_UPR_ICP_BITS] = `OR1200_UPR_ICP;
spr_dat_o[`OR1200_UPR_DMP_BITS] = `OR1200_UPR_DMP;
spr_dat_o[`OR1200_UPR_IMP_BITS] = `OR1200_UPR_IMP;
spr_dat_o[`OR1200_UPR_MP_BITS] = `OR1200_UPR_MP;
spr_dat_o[`OR1200_UPR_DUP_BITS] = `OR1200_UPR_DUP;
spr_dat_o[`OR1200_UPR_PCUP_BITS] = `OR1200_UPR_PCUP;
spr_dat_o[`OR1200_UPR_PMP_BITS] = `OR1200_UPR_PMP;
spr_dat_o[`OR1200_UPR_PICP_BITS] = `OR1200_UPR_PICP;
spr_dat_o[`OR1200_UPR_TTP_BITS] = `OR1200_UPR_TTP;
spr_dat_o[`OR1200_UPR_RES1_BITS] = `OR1200_UPR_RES1;
spr_dat_o[`OR1200_UPR_CUP_BITS] = `OR1200_UPR_CUP;
end
default: spr_dat_o = 32'h0000_0000;
endcase
`ifdef OR1200_SYS_FULL_DECODE
else
spr_dat_o = 32'h0000_0000;
`endif
 
`endif
 
/trunk/orpsocv2/rtl/verilog/components/or1200r2/or1200_except.v
226,7 → 226,7
// Internal regs and wires
//
reg [`OR1200_EXCEPT_WIDTH-1:0] except_type;
reg [31:0] id_pc;
reg [31:0] id_pc /* verilator public */;
reg [31:0] ex_pc;
reg [31:0] wb_pc /* verilator public */;
reg [31:0] epcr;
306,6 → 306,17
`endif
 
 
`ifdef verilator
// Function to access id_pc (for Verilator). Have to hide this from
// simulator, since functions with no inputs are not allowed in IEEE
// 1364-2001.
function [31:0] get_id_pc;
// verilator public
get_id_pc = id_pc;
endfunction // get_id_pc
 
`endif
 
//
// PC and Exception flags pipelines
//
/trunk/orpsocv2/rtl/verilog/components/or1200r2/or1200_ic_ram.v
141,7 → 141,7
`ifdef OR1200_IC_1W_512B
or1200_spram #
(
.aw(9),
.aw(7),
.dw(32)
)
`endif
/trunk/orpsocv2/rtl/verilog/components/or1200r2/or1200_genpc.v
331,7 → 331,7
 
always @(pcreg_boot or pcreg_default or pcreg_select)
if (pcreg_select)
pcreg = pcreg_boot[31:2];
pcreg = pcreg_boot[31:2];
else
pcreg = pcreg_default ;
 
/trunk/orpsocv2/rtl/verilog/components/or1200r2/or1200_ctrl.v
200,7 → 200,7
wire ex_macrc_op;
`endif
reg [`OR1200_SHROTOP_WIDTH-1:0] shrot_op;
reg [31:0] id_insn;
reg [31:0] id_insn /* verilator public */;
reg [31:0] ex_insn;
reg [31:0] wb_insn;
reg [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addrw;
279,7 → 279,18
endfunction // get_wb_insn
`endif
 
`ifdef verilator
// Function to access id_insn (for Verilator). Have to hide this from
// simulator, since functions with no inputs are not allowed in IEEE
// 1364-2001.
function [31:0] get_id_insn;
// verilator public
get_id_insn = id_insn;
endfunction // get_id_insn
`endif
 
 
//
// Generation of sel_a
//
/trunk/orpsocv2/sim/bin/Makefile
8,9 → 8,6
#### ORPSoC(v2) design. ####
#### ####
#### To do: ####
#### * Arrange verilator make rules so that the whole thing ####
#### isn't recompiled when a single SystemC module is ####
#### updated. ####
#### * Test if each software test file gets made properly ####
#### before it's run in whatever model we're using ####
#### * Expand software test-suite (uClibc, ecos tests, LTP?) ####
210,19 → 207,8
# the cycle-accurate ORPSoC model to create the simulation executable. This
# executable is the cycle-representation of the system.
#
# VCDs can be generated if the model is made with VCD=1 specified on the
# command line. Specify a dump file with the "-vcd" option at runtime, eg:
# "./Vorpsoc_top -vcd dump.vcd"
# Note that this slows down the simulation.
# Run the resulting executable with the -h switch for usage.
#
# Logging of the processor's execution can be done by specifying a log file
# on the command line at runtime, eg: "./Vorpsoc_top -log or1200_exec.log"
# Note that this slows down the simulation.
#
# There are performance metrics printed at the conclusion of simulations. To
# disable these launch the executable with either the -q or --no-perf-summary
# options. eg: "./Vorpsoc_top -q"
#
# The compilation is all done with the GNU c++ compiler, g++.
#
# The compilation process is a little more complicated than the event-driven
246,6 → 232,7
# the system through its paces.
#
#
#
 
# Name of the directory we're currently in
CUR_DIR=$(shell pwd)
507,7 → 494,7
## Build the VPI library
$(MAKE) -C $(VPI_C_DIR) $(VPI_LIB_NAME)
 
clean_vpi:
clean-vpi:
$(MAKE) -C $(VPI_C_DIR) clean
 
rtl-debug: prepare_sw_uart_printf prepare_rtl prepare_vpi prepare_dirs
553,16 → 540,38
 
# List of System C models - use this list to link the sources into the Verilator
# build directory
SYSC_MODELS=OrpsocAccess TraceSC
SYSC_MODELS=OrpsocAccess
 
ifdef VCD
VLT_FLAGS +=-trace
ifdef VLT_DEBUG
VLT_DEBUG_COMPILE_FLAGS = -g
# Enabling the following generates a TON of debugging
# when running verilator. Not so helpful.
#VLT_DEBUG_OPTIONS = --debug --dump-tree
VLT_SYSC_DEBUG_DEFINE = VLT_DEBUG=1
endif
 
# If set on the command line we build the cycle accurate model which will generate verilator-specific profiling information. This is useful for checking the efficiency of the model - not really useful for checking code or the function of the model.
ifdef VLT_ORPSOC_PROFILING
VLT_CPPFLAGS=-g -pg
VLT_DEBUG_OPTIONS +=-profile-cfuncs
else
VLT_CPPFLAGS=-fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -O3
endif
 
ifdef VLT_DO_PROFILING
VLT_CPPFLAGS=-O3 -ftest-coverage -fprofile-generate
endif
 
# VCD Enabled by default when building, enable it at runtime
#ifdef VCD
VLT_FLAGS +=-trace
TRACE_FLAGS=-DVM_TRACE=1 -I${SYSTEMPERL}/src
#endif
 
# Only need the trace target if we are tracing
ifneq (,$(findstring -trace, $(VLT_FLAGS)))
#ifneq (,$(findstring -trace, $(VLT_FLAGS)))
VLT_TRACEOBJ = SpTraceVcdC
endif
#endif
 
# This is the list of extra models we'll issue make commands for
# Included is the SystemPerl trace model
573,12 → 582,12
$(SIM_VLT_DIR)/Vorpsoc_top: $(SIM_VLT_DIR)/libVorpsoc_top.a $(SIM_VLT_DIR)/OrpsocMain.o
# Final linking of the simulation executable. Order of libraries here is important!
@echo; echo "\tGenerating simulation executable"; echo
cd $(SIM_VLT_DIR) && g++ -I$(BENCH_SYSC_INCLUDE_DIR) -I$(SIM_VLT_DIR) -I$(VERILATOR_ROOT)/include -I$(SYSTEMC)/include -o Vorpsoc_top -L. -L$(BENCH_SYSC_SRC_DIR) -L$(SYSTEMC)/$(SYSC_LIB_ARCH_DIR) OrpsocMain.o -lVorpsoc_top -lmodules -lsystemc
cd $(SIM_VLT_DIR) && g++ $(VLT_DEBUG_COMPILE_FLAGS) $(VLT_CPPFLAGS) -I$(BENCH_SYSC_INCLUDE_DIR) -I$(SIM_VLT_DIR) -I$(VERILATOR_ROOT)/include -I$(SYSTEMC)/include -o Vorpsoc_top -L. -L$(BENCH_SYSC_SRC_DIR) -L$(SYSTEMC)/$(SYSC_LIB_ARCH_DIR) OrpsocMain.o -lVorpsoc_top -lmodules -lsystemc
 
$(SIM_VLT_DIR)/OrpsocMain.o:
# Now compile the top level systemC "testbench" module
@echo; echo "\tCompiling top level SystemC testbench"; echo
cd $(SIM_VLT_DIR) && g++ -I$(BENCH_SYSC_INCLUDE_DIR) -I$(SIM_VLT_DIR) -I$(VERILATOR_ROOT)/include -I$(SYSTEMC)/include -c $(BENCH_SYSC_SRC_DIR)/OrpsocMain.cpp
cd $(SIM_VLT_DIR) && g++ $(VLT_DEBUG_COMPILE_FLAGS) $(VLT_CPPFLAGS) $(TRACE_FLAGS) -I$(BENCH_SYSC_INCLUDE_DIR) -I$(SIM_VLT_DIR) -I$(VERILATOR_ROOT)/include -I$(SYSTEMC)/include -c $(BENCH_SYSC_SRC_DIR)/OrpsocMain.cpp
 
$(SIM_VLT_DIR)/libVorpsoc_top.a: $(SIM_VLT_DIR)/Vorpsoc_top__ALL.a vlt_modules_compile $(SIM_VLT_DIR)/verilated.o
# Now archive all of the libraries from verilator witht he other modules we might have
593,6 → 602,9
$(SIM_VLT_DIR)/verilated.o:
@echo; echo "\tCompiling verilated.o"; echo
@cd $(SIM_VLT_DIR) && \
export CXXFLAGS=$(VLT_DEBUG_COMPILE_FLAGS); \
export USER_CPPFLAGS="$(VLT_CPPFLAGS)"; \
export USER_LDDFLAGS="$(VLT_CPPFLAGS)"; \
$(MAKE) -f Vorpsoc_top.mk verilated.o
 
.PHONY: vlt_modules_compile
602,12 → 614,17
@cd $(SIM_VLT_DIR) && \
for SYSCMODEL in $(SYSC_MODELS_BUILD); do \
echo;echo "\t$$SYSCMODEL"; echo; \
$(MAKE) -f Vorpsoc_top.mk $$SYSCMODEL.o; \
done
export CXXFLAGS=$(VLT_DEBUG_COMPILE_FLAGS); \
export USER_CPPFLAGS="$(VLT_CPPFLAGS)"; \
export USER_LDDFLAGS="$(VLT_CPPFLAGS)"; \
$(MAKE) -f Vorpsoc_top.mk $$SYSCMODEL.o; \
done
 
$(SIM_VLT_DIR)/Vorpsoc_top__ALL.a: $(SIM_VLT_DIR)/Vorpsoc_top.mk
@echo; echo "\tCompiling main design"; echo
@cd $(SIM_VLT_DIR) && \
export USER_CPPFLAGS="$(VLT_CPPFLAGS)"; \
export USER_LDDFLAGS="$(VLT_CPPFLAGS)"; \
$(MAKE) -f Vorpsoc_top.mk Vorpsoc_top__ALL.a
 
$(SIM_VLT_DIR)/Vorpsoc_top.mk: $(SIM_VLT_DIR)/$(VLT_COMMAND_FILE).generated $(SIM_VLT_DIR)/libmodules.a
614,12 → 631,13
# Now call verilator to generate the .mk files
@echo; echo "\tGenerating makefiles with Verilator"; echo
cd $(SIM_VLT_DIR) && \
verilator -language 1364-2001 -Wno-lint --top-module orpsoc_top -Mdir . -sc $(VLT_FLAGS) -I$(BENCH_SYSC_INCLUDE_DIR) -I$(BENCH_SYSC_SRC_DIR) -f $(VLT_COMMAND_FILE).generated
verilator -language 1364-2001 -Wno-lint --top-module orpsoc_top $(VLT_DEBUG_OPTIONS) -Mdir . -sc $(VLT_FLAGS) -I$(BENCH_SYSC_INCLUDE_DIR) -I$(BENCH_SYSC_SRC_DIR) -f $(VLT_COMMAND_FILE).generated
 
# SystemC modules library
$(SIM_VLT_DIR)/libmodules.a:
@echo; echo "\tCompiling SystemC modules"; echo
@$(MAKE) -C $(BENCH_SYSC_SRC_DIR) -f $(BENCH_SYSC_SRC_DIR)/Modules.make
@export VLT_CPPFLAGS="$(VLT_CPPFLAGS)"; \
$(MAKE) -C $(BENCH_SYSC_SRC_DIR) -f $(BENCH_SYSC_SRC_DIR)/Modules.make $(VLT_SYSC_DEBUG_DEFINE)
 
 
# Verilator command script
678,7 → 696,21
done; \
echo "Test results: "$$TESTS_PASSED" out of "$$TESTS_PERFORMED" tests passed"; echo
 
###############################################################################
# Verilator profiled module make
###############################################################################
# To run this, first run a "make prepare_vlt VLT_DO_PROFILING=1" then do a
# "make clean" and then a "make prepare_vlt_profiled"
# This new make target copies athe results of the profiling back to the right
# paths before we create everything again
###############################################################################
prepare_vlt_profiled: vlt_restore_profileoutput prepare_rtl vlt_model_links $(SIM_VLT_DIR)/Vorpsoc_top
 
vlt_restore_profileoutput:
@echo;echo "\tRestoring profiling outputs"; echo
@mkdir -p ../vlt
@cp /tmp/*.gc* $(SIM_VLT_DIR)
@cp /tmp/*.gc* $(BENCH_SYSC_SRC_DIR)
 
################################################################################
# Architectural simulator test loop
722,7 → 754,7
# Cleaning rules
################################################################################
 
clean: clean-sw clean-sim clean-sysc clean-rtl clean_vpi
clean: clean-sw clean-sim clean-sysc clean-rtl clean-vpi
 
clean-sw:
@for SWDIR in `ls $(SW_DIR)`; do \
731,6 → 763,10
done
 
clean-sim:
#backup any profiling output files
@if [ -f $(SIM_VLT_DIR)/OrpsocMain.gcda ]; then echo "\tBacking up verilator profiling output"; \
cp $(SIM_VLT_DIR)/*.gc* /tmp; \
cp $(BENCH_SYSC_SRC_DIR)/*.gc* /tmp; fi
rm -rf $(SIM_RESULTS_DIR) $(SIM_RUN_DIR)/*.* $(SIM_VLT_DIR)
 
clean-sysc:
/trunk/orpsocv2/sw/dhry/dhry.c
15,6 → 15,7
****************************************************************************
*/
#include "support.h"
#include "time.h"
#include "dhry.h"
#ifndef NUM_RUNS
#define NUM_RUNS (1)
26,7 → 27,7
void buserr_except(){}
void dpf_except(){}
void ipf_except(){}
void lpint_except(){}
void lpint_except(){timer_interrupt();}
void align_except(){}
void illegal_except(){}
void hpint_except(){}
207,8 → 208,8
/***************/
/* printf("%d", my_test2(Number_Of_Runs));*/
start_timer(TIMER0);
Begin_Time = read_timer(TIMER0);
start_timer(TIMER0);
Begin_Time = read_timer(TIMER0);
 
for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
{
/trunk/orpsocv2/sw/dhry/Makefile
9,7 → 9,7
else
NUM_RUNS="(10)"
endif
 
GCC_OPT += -g
all: $(cases)
 
dhry-nocache-O0: dhry-O0.o ../support/reset-nocache.o $(common)
/trunk/orpsocv2/sw/support/time.c
0,0 → 1,44
#include "support.h"
#include "board.h"
#include "spr_defs.h"
 
/* Tick timer period */
#define SYS_CLKS_PER_TICK (IN_CLK/TICKS_PER_SEC)
#define USEC_PER_SEC (1000000)
#define USEC_PER_MSEC (1000)
#define MSEC_PER_SEC (1000)
#define USEC_PER_TICK (USEC_PER_SEC/TICKS_PER_SEC)
 
unsigned long tick_period = SYS_CLKS_PER_TICK;
unsigned long usec, msec, sec; // simple usec counter
 
/* Start the timer, enabling interrupt, self-restart and set the period */
void
init_timer(void)
{
/* enable counter interrupt */
mtspr(SPR_SR,(mfspr(SPR_SR)|SPR_SR_TEE));
/* Set counter period, enable timer and interrupt */
/* SPR_TTMR_RT bit makes timer reset and restart itself automatically */
/* This will start it, too. */
mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT | (SYS_CLKS_PER_TICK & SPR_TTMR_PERIOD));
usec = 0, msec=0, sec=0;
}
 
/* Update timecounters */
void
timer_interrupt(void)
{
/* Update our time counters */
usec += USEC_PER_TICK;
if (usec >= USEC_PER_MSEC ){ usec -= USEC_PER_MSEC; msec++; }
if (msec >= MSEC_PER_SEC ){ msec -= MSEC_PER_SEC; sec++; }
}
 
/* Return time in microseconds */
unsigned int
read_time_us(void)
{
return ((sec*((MSEC_PER_SEC*USEC_PER_MSEC)))+(msec*(USEC_PER_MSEC))+usec);
}
/trunk/orpsocv2/sw/support/time.h
0,0 → 1,4
 
extern unsigned long usec, msec, sec; // simple usec counter
void init_timer(void);
unsigned int read_time_us(void);
/trunk/orpsocv2/sw/support/except.S
1,5 → 1,115
#include "spr_defs.h"
 
/* Defines and macros to help us handle execptions */
#define INT_FRAME_SIZE 144
 
#include "or32_funcs.S"
 
 
 
#define EXCEPTION_HANDLE(handler) \
/* First store the SP like it was before execption to a temporary location, we use addr 0x80 */ ;\
l.sw 0x80(r0), r1 ;\
l.addi r1,r1,-(INT_FRAME_SIZE) ;\
l.sw GPR12(r1),r12 ;\
l.mfspr r12,r0,SPR_EPCR_BASE ;\
l.sw PC(r1),r12 ;\
l.mfspr r12,r0,SPR_ESR_BASE ;\
l.sw SR(r1),r12 ;\
l.lwz r12, 0x80(r0) ;\
/* Now store the previous SP onto except. stack*/ ;\
l.sw SP(r1),r12 ;\
/* save exception r4, set r4 = EA */ ;\
l.sw GPR4(r1),r4 ;\
l.mfspr r4,r0,SPR_EEAR_BASE ;\
/* r31: EA address of handler */ ;\
LOAD_SYMBOL_2_GPR(r12,handler) ;\
l.mtspr r0,r12,SPR_EPCR_BASE ;\
l.rfe
 
#define HANDLER_ENTRY(handler) \
.global handler ;\
handler: ;\
l.sw GPR2(r1),r2 ;\
l.sw GPR3(r1),r3 ;\
/*l.sw GPR4(r1),r4*/ ;\
l.sw GPR5(r1),r5 ;\
l.sw GPR6(r1),r6 ;\
l.sw GPR7(r1),r7 ;\
l.sw GPR8(r1),r8 ;\
l.sw GPR9(r1),r9 ;\
l.sw GPR10(r1),r10 ;\
l.sw GPR11(r1),r11 ;\
/*l.sw GPR12(r1),r12*/ ;\
l.sw GPR13(r1),r13 ;\
l.sw GPR14(r1),r14 ;\
l.sw GPR15(r1),r15 ;\
l.sw GPR16(r1),r16 ;\
l.sw GPR17(r1),r17 ;\
l.sw GPR18(r1),r18 ;\
l.sw GPR19(r1),r19 ;\
l.sw GPR20(r1),r20 ;\
l.sw GPR21(r1),r21 ;\
l.sw GPR22(r1),r22 ;\
l.sw GPR23(r1),r23 ;\
l.sw GPR24(r1),r24 ;\
l.sw GPR25(r1),r25 ;\
l.sw GPR26(r1),r26 ;\
l.sw GPR27(r1),r27 ;\
l.sw GPR28(r1),r28 ;\
l.sw GPR29(r1),r29 ;\
l.sw GPR30(r1),r30 ;\
l.sw GPR31(r1),r31 ;\
l.sw RESULT(r1),r0 ;\
 
/*
* We need to disable interrupts at beginning of RESTORE_ALL
* since interrupt might come in after we've loaded EPC return address
* and overwrite EPC with address somewhere in RESTORE_ALL
* which is of course wrong!
*/
#define RESTORE_ALL \
DISABLE_INTERRUPTS(r3,r4) ;\
l.lwz r3,PC(r1) ;\
l.mtspr r0,r3,SPR_EPCR_BASE ;\
l.lwz r3,SR(r1) ;\
l.mtspr r0,r3,SPR_ESR_BASE ;\
l.lwz r2,GPR2(r1) ;\
l.lwz r3,GPR3(r1) ;\
l.lwz r4,GPR4(r1) ;\
l.lwz r5,GPR5(r1) ;\
l.lwz r6,GPR6(r1) ;\
l.lwz r7,GPR7(r1) ;\
l.lwz r8,GPR8(r1) ;\
l.lwz r9,GPR9(r1) ;\
l.lwz r10,GPR10(r1) ;\
l.lwz r11,GPR11(r1) ;\
l.lwz r12,GPR12(r1) ;\
l.lwz r13,GPR13(r1) ;\
l.lwz r14,GPR14(r1) ;\
l.lwz r15,GPR15(r1) ;\
l.lwz r16,GPR16(r1) ;\
l.lwz r17,GPR17(r1) ;\
l.lwz r18,GPR18(r1) ;\
l.lwz r19,GPR19(r1) ;\
l.lwz r20,GPR20(r1) ;\
l.lwz r21,GPR21(r1) ;\
l.lwz r22,GPR22(r1) ;\
l.lwz r23,GPR23(r1) ;\
l.lwz r24,GPR24(r1) ;\
l.lwz r25,GPR25(r1) ;\
l.lwz r26,GPR26(r1) ;\
l.lwz r27,GPR27(r1) ;\
l.lwz r28,GPR28(r1) ;\
l.lwz r29,GPR29(r1) ;\
l.lwz r30,GPR30(r1) ;\
l.lwz r31,GPR31(r1) ;\
l.lwz r1,SP(r1) ;\
l.rfe
// Linked from 0x200, so add 0x200 to the .org for the physical address
.section .vectors, "ax"
 
33,11 → 143,27
l.nop
 
.org 0x300
_except_500:
 
_except_500:
#if 0
l.nop
l.j _lpint_except
l.nop
#else
/* First unset the timer interrupt bit */
l.addi r1,r1,-8
l.sw 0(r1),r31
l.sw 4(r1),r30
l.mfspr r31,r0,SPR_TTMR /* want to clear SPR_TTMR_IP bit from this reg*/
l.movhi r30,hi(SPR_TTMR_IP)
l.ori r30,r30,lo(SPR_TTMR_IP)
l.xor r31, r31, r30
l.mtspr r0,r31,SPR_TTMR
l.lwz r31,0(r1)
l.lwz r30,4(r1)
l.addi r1, r1, 8
EXCEPTION_HANDLE(_timer_handler)
#endif
 
.org 0x400
109,3 → 235,37
l.j _res2_except
l.nop
 
 
.section .text, "ax"
 
/* ---[ 0x500: Timer exception ]----------------------------------------- */
HANDLER_ENTRY(_timer_handler)
l.addi r3,r1,0
LOAD_SYMBOL_2_GPR(r8,_timer_interrupt)
l.jalr r8
l.nop
l.j _ret_from_intr
/* ---[ End of Timer exception ]----------------------------------------- */
 
ENTRY(_ret_from_intr)
// i386 version:
// GET_CURRENT(%ebx)
 
ENTRY(_ret_from_exception)
l.lwz r4,SR(r1)
l.andi r3,r4,SPR_SR_SM
l.sfeqi r3,0
l.bnf _restore_all
l.nop
/*
* return to usermode
*/
 
ENTRY(_restore_all)
// we need to save KSP here too
// or else fork's 'eat' stack space
l.addi r4,r1,INT_FRAME_SIZE
l.sw (TI_KSP)(r10),r4
RESTORE_ALL
 
/trunk/orpsocv2/sw/support/support.c
5,6 → 5,7
#endif
 
#include "spr_defs.h"
#include "time.h"
#include "support.h"
#include "int.h"
 
14,9 → 15,9
#include "uart.h"
#endif
 
#if OR32
 
void excpt_dummy();
void int_main();
//void int_main();
 
unsigned long excpt_buserr = (unsigned long) excpt_dummy;
unsigned long excpt_dpfault = (unsigned long) excpt_dummy;
92,18 → 93,6
l.nop %0": :"K" (NOP_PRINTF), "r" (fmt), "r" (args));
}
 
/*
void *memcpy (void *__restrict dstvoid,
__const void *__restrict srcvoid, size_t length)
{
char *dst = dstvoid;
const char *src = (const char *) srcvoid;
 
while (length--)
*dst++ = *src++;
return dst;
}
*/
#endif
 
 
125,6 → 114,7
/* start_TIMER */
void start_timer(int x)
{
init_timer();
}
 
/* read_TIMER */
131,12 → 121,7
/* Returns a value since started in uS */
unsigned int read_timer(int x)
{
unsigned long count = 0;
 
/* Read the Time Stamp Counter */
/* asm("simrdtsc %0" :"=r" (count)); */
/*asm("l.sys 201"); */
return count;
return read_time_us();
}
 
/* For writing into SPR. */
153,30 → 138,5
return value;
}
 
#else
void report(unsigned long value)
{
printf("report(0x%x);\n", (unsigned) value);
}
 
/* start_TIMER */
void start_timer(int tmrnum)
{
}
 
/* read_TIMER */
/* Returns a value since started in uS */
unsigned int read_timer(int tmrnum)
{
struct timeval tv;
struct timezone tz;
 
gettimeofday(&tv, &tz);
return(tv.tv_sec*1000000+tv.tv_usec);
}
 
#endif
 
 
void excpt_dummy() {}
/trunk/orpsocv2/sw/support/orp.ld
7,13 → 7,22
icm : ORIGIN = 0x00800000, LENGTH = 0x00004000
}
*/
 
MEMORY
{
reset : ORIGIN = 0x00000000, LENGTH = 0x00000200
vectors : ORIGIN = 0x00000200, LENGTH = 0x00001000
ram : ORIGIN = 0x00001200, LENGTH = 0x00FFED00
vectors : ORIGIN = 0x00000200, LENGTH = 0x00001E00
ram : ORIGIN = 0x00002000, LENGTH = 0x00FFE000
}
 
/*
MEMORY
{
reset : ORIGIN = 0xc0000000, LENGTH = 0x00000200
vectors : ORIGIN = 0xc0000200, LENGTH = 0x00001000
ram : ORIGIN = 0xc0001200, LENGTH = 0x00FFED00
}
*/
SECTIONS
{
.reset :
/trunk/orpsocv2/sw/support/support.h
8,9 → 8,8
#include <stdarg.h>
#include <stddef.h>
#include <limits.h>
#define OR1K 1 //ME added
#if OR1K
 
 
/* Register access macros */
#define REG8(add) *((volatile unsigned char *)(add))
#define REG16(add) *((volatile unsigned short *)(add))
24,12 → 23,7
/* For reading SPR. */
unsigned long mfspr(unsigned long spr);
 
#else /* OR1K */
 
#include <stdio.h>
 
#endif /* OR1K */
 
/* Function to be called at entry point - not defined here. */
int main ();
 
/trunk/orpsocv2/sw/support/int.c
5,8 → 5,8
#include "spr_defs.h"
#include "int.h"
 
#ifdef OR1K
 
 
/* Interrupt handlers table */
struct ihnd int_handlers[MAX_INT_HANDLERS];
 
42,7 → 42,7
{
if(vect >= MAX_INT_HANDLERS)
return -1;
 
mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(0x00000001L << vect));
return 0;
76,4 → 76,4
}
}
#endif
 
/trunk/orpsocv2/sw/support/Makefile
2,13 → 2,17
 
all: libsupport.a reset-nocache.o reset-ic.o reset-dc.o reset-icdc.o
 
libsupport.a: support.o int.o except.o uart.o vfnprintf.o
$(OR32_TOOL_PREFIX)-ar cru libsupport.a support.o except.o int.o uart.o vfnprintf.o
libsupport.a: support.o int.o except.o uart.o vfnprintf.o time.o
$(OR32_TOOL_PREFIX)-ar cru libsupport.a $?
$(OR32_TOOL_PREFIX)-ranlib libsupport.a
 
support.o: support.c
# A generic rule for c
%.o: %.c
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -O2 -c -o $@ $?
 
# A generic rule for assembly files
%.o: %.S
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -O2 -c -o $@ $?
# Rules for each specific reset type we want
reset-nocache.o: reset.S
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -O2 -c -DIC=0 -DDC=0 -o $@ $?
 
21,17 → 25,3
reset-icdc.o: reset.S
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -O2 -c -DIC=1 -DDC=1 -o $@ $?
 
except.o: except.S
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -O2 -c -o $@ $?
 
uart.o: uart.c
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -O2 -c -o $@ $?
 
#snprintf.o: snprintf.c
# $(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -O2 -c -o $@ $?
 
vfnprintf.o: vfnprintf.c
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -O2 -c -o $@ $?
 
int.o: int.c
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -O2 -c -o $@ $?

powered by: WebSVN 2.1.0

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