OpenASIP 2.2
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Private Attributes | List of all members
FUTestbenchGenerator Class Reference

#include <FUTestbenchGenerator.hh>

Inheritance diagram for FUTestbenchGenerator:
Inheritance graph
Collaboration diagram for FUTestbenchGenerator:
Collaboration graph

Public Member Functions

 FUTestbenchGenerator (HDB::FUEntry *fu)
 
virtual ~FUTestbenchGenerator ()
 
virtual void generateTestbench (std::ofstream &file)
 
- Public Member Functions inherited from TestbenchGenerator
 TestbenchGenerator ()
 
virtual ~TestbenchGenerator ()
 

Private Member Functions

void parseFuPorts ()
 
void createMachineState ()
 
void createTbInstantiation ()
 
void createStimulus ()
 
void createTbCode ()
 
void writeInputPortStimulus (PortDataArray &inputs, const std::string &operation, const std::string &portName, uint32_t stimulus)
 
void readValuesFromOutPorts (PortDataArray &outputs)
 
void createStimulusArrays (PortDataArray &inputStimulus, std::vector< uint32_t > &loadStimulus, std::vector< std::string > &operations, PortDataArray &outputStimulus)
 
bool isShiftOrRotOp (const std::string &operation) const
 
uint32_t truncateStimulus (uint32_t operand, int nBits) const
 

Private Attributes

HDB::FUEntryfuEntry_
 
HDB::FUImplementationfuImpl_
 
HDB::FUArchitecturefuArch_
 
MachineStatemsm_
 
std::vector< std::string > inputPorts_
 
std::vector< std::string > outputPorts_
 
std::string opcodePort_
 
TTAMachine::Machinemachine_
 
MemorySystemmemSystem_
 

Additional Inherited Members

- Protected Types inherited from TestbenchGenerator
typedef std::map< std::string, std::vector< uint32_t > > PortDataArray
 
- Protected Member Functions inherited from TestbenchGenerator
virtual void writeStimulusArray (std::ostringstream &stream, std::vector< uint32_t > &dataArray, std::string portName, int portWidth)
 
void writeTbConstants (int totalCycles, int outputIgnoreCycles)
 
void writeTestbench (std::ofstream &file, HDB::HWBlockImplementation *impl)
 
std::ostringstream & declarationStream ()
 
std::ostringstream & bindingStream ()
 
std::ostringstream & signalStream ()
 
std::ostringstream & instantiationStream ()
 
std::ostringstream & inputArrayStream ()
 
std::ostringstream & opcodeArrayStream ()
 
std::ostringstream & loadArrayStream ()
 
std::ostringstream & outputArrayStream ()
 
std::ostringstream & tbCodeStream ()
 

Detailed Description

Definition at line 54 of file FUTestbenchGenerator.hh.

Constructor & Destructor Documentation

◆ FUTestbenchGenerator()

FUTestbenchGenerator::FUTestbenchGenerator ( HDB::FUEntry fu)

Definition at line 67 of file FUTestbenchGenerator.cc.

67 :
68 fuEntry_(fu), fuImpl_(NULL), fuArch_(NULL), msm_(NULL), inputPorts_(),
69 outputPorts_(), opcodePort_(), machine_(NULL), memSystem_(NULL) {
70}
HDB::FUArchitecture * fuArch_
TTAMachine::Machine * machine_
std::vector< std::string > outputPorts_
HDB::FUImplementation * fuImpl_
std::vector< std::string > inputPorts_

◆ ~FUTestbenchGenerator()

FUTestbenchGenerator::~FUTestbenchGenerator ( )
virtual

Definition at line 72 of file FUTestbenchGenerator.cc.

72 {
73
74 if (msm_) {
75 delete(msm_);
76 }
77 if (machine_) {
78 delete(machine_);
79 }
80 if (memSystem_) {
81 delete(memSystem_);
82 }
83}

References machine_, memSystem_, and msm_.

Member Function Documentation

◆ createMachineState()

void FUTestbenchGenerator::createMachineState ( )
private

Create a machine architecture object model with the tested FU in it

Definition at line 104 of file FUTestbenchGenerator.cc.

104 {
105
108
109 MachineStateBuilder msmBuilder;
110
112
113 msm_ = msmBuilder.build(*machine_, *memSystem_);
114}
TTAMachine::FunctionUnit & architecture() const
MachineState * build(const TTAMachine::Machine &machine, MemorySystem &memSys)
virtual void addFunctionUnit(FunctionUnit &unit)
Definition Machine.cc:202

References TTAMachine::Machine::addFunctionUnit(), HDB::FUArchitecture::architecture(), MachineStateBuilder::build(), fuArch_, machine_, memSystem_, and msm_.

Referenced by generateTestbench().

Here is the call graph for this function:

◆ createStimulus()

void FUTestbenchGenerator::createStimulus ( )
private

Creates input and output data tables

Creates input and output data tables and control signals for the testbench. Every operation is tested STIMULUS_PER_OP times and command execution is pipelined. Only fully pipelined FUs are supported.

Definition at line 268 of file FUTestbenchGenerator.cc.

268 {
269
271 assert(&simFU != &NullFUState::instance());
272
273 // stimulus for each port in each clock cycle
274 PortDataArray inputStimulus;
275
276 // stimulus for load ports. Notice that all load ports get the same
277 // signal!
278 // TODO: Exploit this when supporting non-fully pipelined operations
279 // (if latency(op N) > latency(op N+1) there needs to be no-load
280 // cycles when switching operations)
281 vector<uint32_t> loadStimulus;
282
283 // operations started in each clock cycle (names)
284 vector<string> startedOperations;
285
286 // expected output for each port in each clock cycle
287 PortDataArray outputs;
288
289 // initialize a random number generator for the stimuli
290 boost::uniform_int<> distribution(INT_MIN, INT_MAX);
291 boost::mt19937 rng;
292 rng.seed(time(NULL));
293 boost::variate_generator<boost::mt19937&, boost::uniform_int<> >
294 randomNumber(rng, distribution);
295
296 const int cyclesToSimulate = STIMULUS_PER_OP;
297 for (int opIndex = 0; opIndex < fuArch_->architecture().operationCount();
298 ++opIndex) {
299 const string operation =
300 fuArch_->architecture().operation(opIndex)->name();
301
302 for (int i = 0; i < cyclesToSimulate; i++) {
303 startedOperations.push_back(operation);
304
305 // generate stimulus for each port
306 for (std::size_t i = 0; i < inputPorts_.size(); ++i) {
307 const string portName = inputPorts_.at(i);
309 inputStimulus,
310 operation, portName, (uint32_t)randomNumber());
311 }
312
313 // load signal stimulus
314 uint32_t loadOnThisCycle = 1;
315 loadStimulus.push_back(loadOnThisCycle);
316
317 readValuesFromOutPorts(outputs);
318 // advance the simulation clock
319 simFU.endClock();
320 simFU.advanceClock();
321 }
322 }
323 // flush the pipeline
324 int lastOpIndex = fuArch_->architecture().operationCount()-1;
325 int pipelineClearCycles =
326 fuArch_->architecture().operation(lastOpIndex)->latency();
327 for (int i = 0; i < pipelineClearCycles; i++) {
328 if (fuArch_->architecture().operationCount() > 1) {
329 // insert dummy values for opcode port
330 const string operation =
331 fuArch_->architecture().operation(lastOpIndex)->name();
332 startedOperations.push_back(operation);
333 }
334 for (std::size_t j = 0; j < inputPorts_.size(); ++j) {
335 const string portName = inputPorts_.at(j);
336 // operation does not matter
337 const string operation =
338 fuArch_->architecture().operation(lastOpIndex)->name();
339 uint32_t inputStim = 0;
341 inputStimulus, operation, portName, inputStim);
342 }
343 // no load on these cycles
344 uint32_t loadStim = 0;
345 loadStimulus.push_back(loadStim);
346
347 readValuesFromOutPorts(outputs);
348 // advance the simulation clock
349 simFU.endClock();
350 simFU.advanceClock();
351 }
353 inputStimulus, loadStimulus, startedOperations, outputs);
354
355 int waitCycles =
356 fuArch_->architecture().operation(startedOperations.at(0))->latency();
357 // TODO: change this when supporting different pipelines
358 int opCount = fuArch_->architecture().operationCount();
359 int latencyOfLastOp =
360 fuArch_->architecture().operation(opCount-1)->latency();
361 int totalCycles =
362 STIMULUS_PER_OP * opCount + latencyOfLastOp;
363 writeTbConstants(totalCycles, waitCycles);
364}
#define assert(condition)
#define STIMULUS_PER_OP
virtual void advanceClock()
Definition FUState.cc:152
virtual void endClock()
Definition FUState.cc:122
void writeInputPortStimulus(PortDataArray &inputs, const std::string &operation, const std::string &portName, uint32_t stimulus)
void createStimulusArrays(PortDataArray &inputStimulus, std::vector< uint32_t > &loadStimulus, std::vector< std::string > &operations, PortDataArray &outputStimulus)
void readValuesFromOutPorts(PortDataArray &outputs)
FUState & fuState(const std::string &name)
static NullFUState & instance()
Definition FUState.cc:392
virtual TCEString name() const
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
const std::string & name() const
std::map< std::string, std::vector< uint32_t > > PortDataArray
void writeTbConstants(int totalCycles, int outputIgnoreCycles)

References FUState::advanceClock(), HDB::FUArchitecture::architecture(), assert, createStimulusArrays(), FUState::endClock(), fuArch_, MachineState::fuState(), inputPorts_, NullFUState::instance(), TTAMachine::HWOperation::latency(), msm_, TTAMachine::HWOperation::name(), TTAMachine::Component::name(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), readValuesFromOutPorts(), STIMULUS_PER_OP, writeInputPortStimulus(), and TestbenchGenerator::writeTbConstants().

Referenced by generateTestbench().

Here is the call graph for this function:

◆ createStimulusArrays()

void FUTestbenchGenerator::createStimulusArrays ( PortDataArray inputStimulus,
std::vector< uint32_t > &  loadStimulus,
std::vector< std::string > &  operations,
PortDataArray outputStimulus 
)
private

Writes input, output and control signal data to output streams

Parameters
inputStimulusInput port data
loadStimulusLoad port data
operationsTriggered operations
outputStimulusOutput port data

Definition at line 499 of file FUTestbenchGenerator.cc.

502 {
503
504 // input array(s)
505 for (PortDataArray::iterator i = inputStimulus.begin();
506 i != inputStimulus.end(); i++) {
509 const string hwPortName = port->name();
510 const int hwPortWidth =
511 fuArch_->architecture().port((*i).first)->width();
512 vector<uint32_t> data = i->second;
513 writeStimulusArray(inputArrayStream(), data, hwPortName, hwPortWidth);
514
515 const string loadPortName = port->loadPort();
516 if (!loadPortName.empty()) {
517 int loadPortWidth = 1;
518 writeStimulusArray(loadArrayStream(), loadStimulus, loadPortName,
519 loadPortWidth);
520 }
521 }
522
523 // opcode arrays
524 // Special case so we can print the operation names to the testbench
525 const int operationsInFU = fuArch_->architecture().operationCount();
526 if (operationsInFU > 1) {
527 const string hwPortName = fuImpl_->opcodePort();
528 const int hwPortWidth = fuImpl_->maxOpcodeWidth();
530 << INDENT INDENT
531 << "type " << hwPortName << "_data_array is array "
532 << "(natural range <>) of" << std::endl << INDENT INDENT INDENT
533 << "std_logic_vector(" << hwPortWidth - 1 << " downto 0);"
534 << std::endl << std::endl
535 << INDENT INDENT
536 << "constant "<< hwPortName << "_data : " << hwPortName
537 << "_data_array :=" << std::endl;
538
539 for (std::size_t i = 0; i < operations.size(); ++i) {
540 uint32_t input = fuImpl_->opcode(operations.at(i));
541 std::string inputAsBinaryLiteral =
542 Conversion::toBinary(input, hwPortWidth);
544 if (i == 0) {
545 opcodeArrayStream() << "(";
546 } else {
547 opcodeArrayStream() << " ";
548 }
549 opcodeArrayStream() << "\"" << inputAsBinaryLiteral << "\"";
550 if (i == operations.size() - 1) {
551 opcodeArrayStream() << ");";
552 } else {
553 opcodeArrayStream() << ",";
554 }
556 << "\t -- @" << i << " = " << input << " ("
557 << operations.at(i) << ")" << std::endl;
558 }
559 }
560
561 // output arrays
562 for (PortDataArray::iterator i = outputStimulus.begin();
563 i != outputStimulus.end(); ++i) {
564 const std::string hwPortName =
566 const int hwPortWidth =
567 fuArch_->architecture().port((*i).first)->width();
568 vector<uint32_t> data = i->second;
569 writeStimulusArray(outputArrayStream(), data, hwPortName,
570 hwPortWidth);
571 }
572}
#define INDENT
static std::string toBinary(unsigned int source, unsigned int stringWidth=0)
FUPortImplementation & portImplementationByArchitectureName(const std::string &architectureName) const
std::string opcodePort() const
int opcode(const std::string &operation) const
std::string loadPort() const
virtual int width() const
virtual BaseFUPort * port(const std::string &name) const
std::ostringstream & opcodeArrayStream()
std::ostringstream & inputArrayStream()
std::ostringstream & outputArrayStream()
std::ostringstream & loadArrayStream()
virtual void writeStimulusArray(std::ostringstream &stream, std::vector< uint32_t > &dataArray, std::string portName, int portWidth)

References HDB::FUArchitecture::architecture(), fuArch_, fuImpl_, INDENT, TestbenchGenerator::inputArrayStream(), TestbenchGenerator::loadArrayStream(), HDB::PortImplementation::loadPort(), HDB::FUImplementation::maxOpcodeWidth(), HDB::PortImplementation::name(), HDB::FUImplementation::opcode(), TestbenchGenerator::opcodeArrayStream(), HDB::FUImplementation::opcodePort(), TTAMachine::FunctionUnit::operationCount(), TestbenchGenerator::outputArrayStream(), TTAMachine::FunctionUnit::port(), HDB::FUImplementation::portImplementationByArchitectureName(), Conversion::toBinary(), TTAMachine::BaseFUPort::width(), and TestbenchGenerator::writeStimulusArray().

Referenced by createStimulus().

Here is the call graph for this function:

◆ createTbCode()

void FUTestbenchGenerator::createTbCode ( )
private

Writes the testbench main process code

Definition at line 371 of file FUTestbenchGenerator.cc.

371 {
372
373 for (std::size_t i = 0; i < inputPorts_.size(); ++i) {
374 const std::string portName = inputPorts_.at(i);
375 const std::string hwDataPortName =
377 const std::string hwLoadPortName =
378 fuImpl_->
379 portImplementationByArchitectureName(portName).loadPort();
381 << INDENT INDENT
382 << hwDataPortName << " <= " << hwDataPortName << "_data("
383 << "current_cycle);" << std::endl
384 << INDENT INDENT << hwLoadPortName << " <= "
385 << hwLoadPortName << "_data(current_cycle);" << std::endl;
386 }
387
388 if (fuArch_->architecture().operationCount() > 1) {
389 tbCodeStream()
390 << INDENT INDENT
391 << fuImpl_->opcodePort()
392 << " <= " << fuImpl_->opcodePort() << "_data(current_cycle); ";
393 }
394
396 << std::endl << std::endl
397 << INDENT INDENT
398 << "if current_cycle >= IGNORE_OUTPUT_COUNT then" << std::endl;
399
400 for (std::size_t i = 0; i < outputPorts_.size(); ++i) {
401 const std::string portName = outputPorts_.at(i);
402 const std::string hwDataPortName =
404 tbCodeStream()
406 << "assert " << hwDataPortName << " = " << hwDataPortName
407 << "_data(current_cycle)" << std::endl
409 << "report lf & \"TCE Assert: Verification failed at cycle \" "
410 << "& integer'image(current_cycle) & \" for output " << i << "\"" << std::endl
411 << INDENT INDENT INDENT INDENT <<"& \" actual: \" "
412 << "& to_hstring(" << hwDataPortName << ")"
413 << std::endl
414 << INDENT INDENT INDENT INDENT << "& "
415 << "\" expected: \" & to_hstring(" << hwDataPortName
416 << "_data(current_cycle)) severity error;"
417 << std::endl << std::endl;
418 }
419
421 << INDENT INDENT
422 << "end if;" << std::endl;
423}
std::ostringstream & tbCodeStream()

References HDB::FUArchitecture::architecture(), fuArch_, fuImpl_, INDENT, inputPorts_, HDB::PortImplementation::name(), HDB::FUImplementation::opcodePort(), TTAMachine::FunctionUnit::operationCount(), outputPorts_, HDB::FUImplementation::portImplementationByArchitectureName(), and TestbenchGenerator::tbCodeStream().

Referenced by generateTestbench().

Here is the call graph for this function:

◆ createTbInstantiation()

void FUTestbenchGenerator::createTbInstantiation ( )
private

Creates component declaration, connection signals and connects FU component to testbench

Definition at line 150 of file FUTestbenchGenerator.cc.

150 {
151
153 << INDENT << "for tested_fu_0 : fu_under_test use entity work.";
154 bindingStream() << fuImpl_->moduleName() << ";" << std::endl;
155
157 << INDENT << "component fu_under_test" << std::endl
158 << INDENT INDENT << "port(" << std::endl;
159
161 << INDENT << "tested_fu_0\t:\tfu_under_test " << std::endl
162 << INDENT INDENT << "port map (" << std::endl;
163
164 for (int i = 0; i < fuImpl_->architecturePortCount(); ++i) {
166 // this might not always work..
167 const int portWidth = fuArch_->architecture().port(i)->width();
168 const bool isInput =
172 << INDENT INDENT << port.name() << "\t: ";
174 << INDENT << "signal " << port.name() << "\t: ";
176 << INDENT INDENT INDENT << port.name() << " => " << port.name();
177
178 if (isInput)
179 declarationStream() << "in";
180 else
181 declarationStream() << "out";
182
184 << " std_logic_vector("
185 << portWidth - 1 << " downto 0);" << std::endl;
186
188 << "std_logic_vector("
189 << portWidth - 1 << " downto 0);" << std::endl;
190
191 if (isInput) {
193 << INDENT INDENT << port.loadPort()
194 << "\t: in std_logic;" << std::endl;
195
197 << INDENT << "signal " << port.loadPort()
198 << "\t: std_logic_vector(1-1 downto 0);" << std::endl;
199
201 << "," << std::endl
202 << INDENT INDENT INDENT << port.loadPort() << " => "
203 << port.loadPort() << "(0)";
204 }
205 if (i < fuImpl_->architecturePortCount() - 1) {
206 instantiationStream() << "," << std::endl;
207 } else {
208 if (fuImpl_->opcodePort() != "") {
210 << INDENT INDENT << fuImpl_->opcodePort() << "\t: "
211 << "in" << " std_logic_vector("
212 << fuImpl_->maxOpcodeWidth() - 1 << " downto 0);"
213 << std::endl;
215 << "," << std::endl
217 << fuImpl_->opcodePort()
218 << " => " << fuImpl_->opcodePort();
220 << INDENT << "signal " << fuImpl_->opcodePort() << "\t: ";
222 << "std_logic_vector("
223 << fuImpl_->maxOpcodeWidth() - 1
224 << " downto 0);" << std::endl;
225 }
226 }
227 }
229 << "," << std::endl
231 << fuImpl_->clkPort() << " => " << fuImpl_->clkPort()
232 << "," << std::endl
234 << fuImpl_->rstPort() << " => " << fuImpl_->rstPort()
235 << "," << std::endl
237 << fuImpl_->glockPort() << " => " << fuImpl_->glockPort()
238 << ");";
239
241 << INDENT INDENT << fuImpl_->glockPort() << "\t: in std_logic;"
242 << std::endl
243 << INDENT INDENT << fuImpl_->rstPort() << "\t: in std_logic;"
244 << std::endl
245 << INDENT INDENT << fuImpl_->clkPort() << "\t: in std_logic);"
246 << std::endl
247 << INDENT << "end component;"
248 << std::endl;
249
251 << INDENT << "signal " << fuImpl_->glockPort() << "\t: std_logic;"
252 << std::endl
253 << INDENT << "signal " << fuImpl_->rstPort() << "\t: std_logic;"
254 << std::endl
255 << INDENT << "signal " << fuImpl_->clkPort() << "\t: std_logic;"
256 << std::endl;
257}
static bool containsValue(const ContainerType &aContainer, const ElementType &aKey)
FUPortImplementation & architecturePort(int index) const
std::string architecturePort() const
std::ostringstream & instantiationStream()
std::ostringstream & bindingStream()
std::ostringstream & declarationStream()
std::ostringstream & signalStream()

References HDB::FUArchitecture::architecture(), HDB::FUPortImplementation::architecturePort(), HDB::FUImplementation::architecturePort(), HDB::FUImplementation::architecturePortCount(), TestbenchGenerator::bindingStream(), HDB::HWBlockImplementation::clkPort(), ContainerTools::containsValue(), TestbenchGenerator::declarationStream(), fuArch_, fuImpl_, HDB::HWBlockImplementation::glockPort(), INDENT, inputPorts_, TestbenchGenerator::instantiationStream(), HDB::PortImplementation::loadPort(), HDB::FUImplementation::maxOpcodeWidth(), HDB::HWBlockImplementation::moduleName(), HDB::PortImplementation::name(), HDB::FUImplementation::opcodePort(), TTAMachine::FunctionUnit::port(), HDB::HWBlockImplementation::rstPort(), TestbenchGenerator::signalStream(), and TTAMachine::BaseFUPort::width().

Referenced by generateTestbench().

Here is the call graph for this function:

◆ generateTestbench()

void FUTestbenchGenerator::generateTestbench ( std::ofstream &  file)
virtual

◆ isShiftOrRotOp()

bool FUTestbenchGenerator::isShiftOrRotOp ( const std::string &  operation) const
private

Test if operation is shift or rotation operation

Parameters
operationName of the operation
Returns
Is operation shift or rotate

Definition at line 582 of file FUTestbenchGenerator.cc.

582 {
583
584 string opName = StringTools::stringToLower(operation);
585
586 if (opName == "shl" || opName == "shr" || opName == "shru") {
587 return true;
588 } else if (opName == "rotl" || opName == "rotr") {
589 return true;
590 }
591 return false;
592}
static std::string stringToLower(const std::string &source)

References StringTools::stringToLower().

Referenced by writeInputPortStimulus().

Here is the call graph for this function:

◆ parseFuPorts()

void FUTestbenchGenerator::parseFuPorts ( )
private

Definition at line 118 of file FUTestbenchGenerator.cc.

118 {
119
120 // divide ports into input and output ports
121 for (int i = 0; i < fuArch_->architecture().portCount(); i++) {
122 const std::string portName = fuArch_->architecture().port(i)->name();
123 PortState& simulatedPort =
124 msm_->portState(portName, fuArch_->architecture().name());
125
127 opcodePort_ = portName;
128
129 if (dynamic_cast<OutputPortState*>(&simulatedPort)) {
130 outputPorts_.push_back(portName);
131 } else if (dynamic_cast<InputPortState*>(&simulatedPort)) {
132 inputPorts_.push_back(portName);
133 } else if (&simulatedPort == &NullPortState::instance()) {
134 InvalidData e(__FILE__, __LINE__, "ImplementationTester",
135 "Port not found in state");
136 throw e;
137 } else {
138 InvalidData e(__FILE__, __LINE__, "ImplementationTester",
139 "Port " + portName + " has unknown direction.");
140 throw e;
141 }
142 }
143}
PortState & portState(const std::string &portName, const std::string &fuName)
static NullPortState & instance()
Definition PortState.cc:96
virtual bool isOpcodeSetting() const =0
virtual std::string name() const
Definition Port.cc:141

References HDB::FUArchitecture::architecture(), fuArch_, inputPorts_, NullPortState::instance(), TTAMachine::BaseFUPort::isOpcodeSetting(), msm_, TTAMachine::Component::name(), TTAMachine::Port::name(), opcodePort_, outputPorts_, TTAMachine::FunctionUnit::port(), and MachineState::portState().

Referenced by generateTestbench().

Here is the call graph for this function:

◆ readValuesFromOutPorts()

void FUTestbenchGenerator::readValuesFromOutPorts ( PortDataArray outputs)
private

Reads data from output ports and saves the values to an array

Parameters
outputsPortDataArray containing the output ports

Definition at line 476 of file FUTestbenchGenerator.cc.

476 {
477
478 for (std::size_t i = 0; i < outputPorts_.size(); ++i) {
479 const string portName = outputPorts_.at(i);
480
481 PortState* simulatedPort = NULL;
482 simulatedPort = &msm_->portState(
483 portName, fuArch_->architecture().name());
484
485 outputs[portName].push_back(
486 simulatedPort->value().intValue());
487 }
488}
virtual const SimValue & value() const
int intValue() const
Definition SimValue.cc:895

References HDB::FUArchitecture::architecture(), fuArch_, SimValue::intValue(), msm_, TTAMachine::Component::name(), outputPorts_, MachineState::portState(), and RegisterState::value().

Referenced by createStimulus().

Here is the call graph for this function:

◆ truncateStimulus()

uint32_t FUTestbenchGenerator::truncateStimulus ( uint32_t  operand,
int  nBits 
) const
private

Truncates shift operand to log2(32) bits

Parameters
operandOperand to be truncated
Returns
Truncated operand

Definition at line 601 of file FUTestbenchGenerator.cc.

601 {
602
603 if (nBits < 0) {
604 InvalidData exc(__FILE__, __LINE__, "ImplementationTester",
605 "Negative amount f wanted bits");
606 throw exc;
607 }
608
609 unsigned int dataWidth = 32;
610 uint32_t truncated =
611 (operand << (dataWidth - nBits) >> (dataWidth - nBits));
612 return truncated;
613}

Referenced by writeInputPortStimulus().

◆ writeInputPortStimulus()

void FUTestbenchGenerator::writeInputPortStimulus ( PortDataArray inputs,
const std::string &  operation,
const std::string &  portName,
uint32_t  stimulus 
)
private

Writes input data to the given port and saves the input value to an array

Parameters
inputsPortDataArray containing input ports
operationName of the triggered operation
portNameName of the port where data is written to
stimulusInput data

Definition at line 434 of file FUTestbenchGenerator.cc.

437 {
438
439 string operationString = "";
440 PortState* simulatedPort = NULL;
441 bool isOpcodePort = false;
442 // fetch the virtual opcode setting port for the triggered operation
443 if (portName == opcodePort_) {
444 operationString =
446 std::string(".") + operation);
447 isOpcodePort = true;
448 }
449
450 simulatedPort = &msm_->portState(
451 portName + operationString,
453
454 const int inputWidth = simulatedPort->value().width();
455 SimValue value(inputWidth);
456
457 int wantedBits = inputWidth;
458 if (isShiftOrRotOp(operation) && isOpcodePort
459 && inputWidth > 5) {
460 // log2(32) = 5 bits needed to express max shift
461 wantedBits = 5;
462 }
463 stimulus = truncateStimulus(stimulus, wantedBits);
464
465 inputs[portName].push_back(stimulus);
466 value = stimulus;
467 simulatedPort->setValue(value);
468}
uint32_t truncateStimulus(uint32_t operand, int nBits) const
bool isShiftOrRotOp(const std::string &operation) const
virtual void setValue(const SimValue &value)
int width() const
Definition SimValue.cc:103

References HDB::FUArchitecture::architecture(), fuArch_, isShiftOrRotOp(), msm_, TTAMachine::Component::name(), opcodePort_, MachineState::portState(), RegisterState::setValue(), StringTools::stringToLower(), truncateStimulus(), RegisterState::value(), and SimValue::width().

Referenced by createStimulus().

Here is the call graph for this function:

Member Data Documentation

◆ fuArch_

HDB::FUArchitecture* FUTestbenchGenerator::fuArch_
private

◆ fuEntry_

HDB::FUEntry* FUTestbenchGenerator::fuEntry_
private

Definition at line 92 of file FUTestbenchGenerator.hh.

Referenced by generateTestbench().

◆ fuImpl_

HDB::FUImplementation* FUTestbenchGenerator::fuImpl_
private

◆ inputPorts_

std::vector<std::string> FUTestbenchGenerator::inputPorts_
private

◆ machine_

TTAMachine::Machine* FUTestbenchGenerator::machine_
private

Definition at line 101 of file FUTestbenchGenerator.hh.

Referenced by createMachineState(), and ~FUTestbenchGenerator().

◆ memSystem_

MemorySystem* FUTestbenchGenerator::memSystem_
private

Definition at line 102 of file FUTestbenchGenerator.hh.

Referenced by createMachineState(), and ~FUTestbenchGenerator().

◆ msm_

MachineState* FUTestbenchGenerator::msm_
private

◆ opcodePort_

std::string FUTestbenchGenerator::opcodePort_
private

Definition at line 99 of file FUTestbenchGenerator.hh.

Referenced by parseFuPorts(), and writeInputPortStimulus().

◆ outputPorts_

std::vector<std::string> FUTestbenchGenerator::outputPorts_
private

Definition at line 98 of file FUTestbenchGenerator.hh.

Referenced by createTbCode(), parseFuPorts(), and readValuesFromOutPorts().


The documentation for this class was generated from the following files: