37 #include <boost/random.hpp>
38 #include <boost/nondet_random.hpp>
64 #define STIMULUS_PER_OP 10
68 fuEntry_(fu), fuImpl_(NULL), fuArch_(NULL), msm_(NULL), inputPorts_(),
69 outputPorts_(), opcodePort_(), machine_(NULL), memSystem_(NULL) {
134 InvalidData e(__FILE__, __LINE__,
"ImplementationTester",
135 "Port not found in state");
138 InvalidData e(__FILE__, __LINE__,
"ImplementationTester",
139 "Port " + portName +
" has unknown direction.");
153 <<
INDENT <<
"for tested_fu_0 : fu_under_test use entity work.";
157 <<
INDENT <<
"component fu_under_test" << std::endl
161 <<
INDENT <<
"tested_fu_0\t:\tfu_under_test " << std::endl
174 <<
INDENT <<
"signal " << port.
name() <<
"\t: ";
184 <<
" std_logic_vector("
185 << portWidth - 1 <<
" downto 0);" << std::endl;
188 <<
"std_logic_vector("
189 << portWidth - 1 <<
" downto 0);" << std::endl;
194 <<
"\t: in std_logic;" << std::endl;
198 <<
"\t: std_logic_vector(1-1 downto 0);" << std::endl;
205 if (i < fuImpl_->architecturePortCount() - 1) {
211 <<
"in" <<
" std_logic_vector("
222 <<
"std_logic_vector("
224 <<
" downto 0);" << std::endl;
247 <<
INDENT <<
"end component;"
281 vector<uint32_t> loadStimulus;
284 vector<string> startedOperations;
290 boost::uniform_int<> distribution(INT_MIN, INT_MAX);
292 rng.seed(time(NULL));
293 boost::variate_generator<boost::mt19937&, boost::uniform_int<> >
294 randomNumber(rng, distribution);
299 const string operation =
302 for (
int i = 0; i < cyclesToSimulate; i++) {
303 startedOperations.push_back(operation);
306 for (std::size_t i = 0; i <
inputPorts_.size(); ++i) {
310 operation, portName, (uint32_t)randomNumber());
314 uint32_t loadOnThisCycle = 1;
315 loadStimulus.push_back(loadOnThisCycle);
325 int pipelineClearCycles =
327 for (
int i = 0; i < pipelineClearCycles; i++) {
330 const string operation =
332 startedOperations.push_back(operation);
334 for (std::size_t j = 0; j <
inputPorts_.size(); ++j) {
337 const string operation =
339 uint32_t inputStim = 0;
341 inputStimulus, operation, portName, inputStim);
344 uint32_t loadStim = 0;
345 loadStimulus.push_back(loadStim);
353 inputStimulus, loadStimulus, startedOperations, outputs);
359 int latencyOfLastOp =
373 for (std::size_t i = 0; i <
inputPorts_.size(); ++i) {
375 const std::string hwDataPortName =
377 const std::string hwLoadPortName =
379 portImplementationByArchitectureName(portName).loadPort();
382 << hwDataPortName <<
" <= " << hwDataPortName <<
"_data("
383 <<
"current_cycle);" << std::endl
385 << hwLoadPortName <<
"_data(current_cycle);" << std::endl;
396 << std::endl << std::endl
398 <<
"if current_cycle >= IGNORE_OUTPUT_COUNT then" << std::endl;
402 const std::string hwDataPortName =
406 <<
"assert " << hwDataPortName <<
" = " << hwDataPortName
407 <<
"_data(current_cycle)" << std::endl
409 <<
"report lf & \"TCE Assert: Verification failed at cycle \" "
410 <<
"& str(current_cycle, 10)" << std::endl
412 <<
"& str(conv_integer(signed(" << hwDataPortName <<
")), 10)"
415 <<
"\" expected: \" & str(conv_integer(signed(" << hwDataPortName
416 <<
"_data(current_cycle))), 10) severity error;"
417 << std::endl << std::endl;
422 <<
"end if;" << std::endl;
436 const std::string& operation,
437 const std::string& portName, uint32_t stimulus) {
439 string operationString =
"";
441 bool isOpcodePort =
false;
446 std::string(
".") + operation);
451 portName + operationString,
454 const int inputWidth = simulatedPort->
value().
width();
457 int wantedBits = inputWidth;
465 inputs[portName].push_back(stimulus);
485 outputs[portName].push_back(
501 std::vector<uint32_t>& loadStimulus,
502 std::vector<std::string>& operations,
PortDataArray& outputStimulus) {
505 for (PortDataArray::iterator i = inputStimulus.begin();
506 i != inputStimulus.end(); i++) {
509 const string hwPortName = port->
name();
510 const int hwPortWidth =
512 vector<uint32_t> data = i->second;
515 const string loadPortName = port->
loadPort();
516 if (!loadPortName.empty()) {
517 int loadPortWidth = 1;
526 if (operationsInFU > 1) {
531 <<
"type " << hwPortName <<
"_data_array is array "
533 <<
"std_logic_vector(" << hwPortWidth - 1 <<
" downto 0);"
534 << std::endl << std::endl
536 <<
"constant "<< hwPortName <<
"_data : " << hwPortName
537 <<
"_data_array :=" << std::endl;
539 for (std::size_t i = 0; i < operations.size(); ++i) {
541 std::string inputAsBinaryLiteral =
550 if (i == operations.size() - 1) {
556 <<
"\t -- @" << i <<
" = " << input <<
" ("
557 << operations.at(i) <<
")" << std::endl;
562 for (PortDataArray::iterator i = outputStimulus.begin();
563 i != outputStimulus.end(); ++i) {
564 const std::string hwPortName =
566 const int hwPortWidth =
568 vector<uint32_t> data = i->second;
586 if (opName ==
"shl" || opName ==
"shr" || opName ==
"shru") {
588 }
else if (opName ==
"rotl" || opName ==
"rotr") {
604 InvalidData exc(__FILE__, __LINE__,
"ImplementationTester",
605 "Negative amount f wanted bits");
609 unsigned int dataWidth = 32;
611 (operand << (dataWidth - nBits) >> (dataWidth - nBits));