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

#include <RFTestbenchGenerator.hh>

Inheritance diagram for RFTestbenchGenerator:
Inheritance graph
Collaboration diagram for RFTestbenchGenerator:
Collaboration graph

Public Member Functions

 RFTestbenchGenerator (HDB::RFEntry *rf)
 
virtual ~RFTestbenchGenerator ()
 
virtual void generateTestbench (std::ofstream &file)
 
- Public Member Functions inherited from TestbenchGenerator
 TestbenchGenerator ()
 
virtual ~TestbenchGenerator ()
 

Private Member Functions

void createMachineState ()
 
void parseRfPorts ()
 
void createTbInstantiation ()
 
void createStimulus ()
 
void createTbCode ()
 
void createStimulusArrays (PortDataArray &inputData, PortDataArray &inputOpcode, PortDataArray &inputLoad, PortDataArray &outputData, PortDataArray &outputOpcode, PortDataArray &outputLoad)
 
void writeDataArrays (std::ostringstream &stream, PortDataArray &array, int portWidth)
 
int opcodePortWidth () const
 

Private Attributes

HDB::RFEntryrfEntry_
 
HDB::RFImplementationrfImpl_
 
HDB::RFArchitecturerfArch_
 
TTAMachine::RegisterFilemachRf_
 
MachineStatemsm_
 
TTAMachine::Machinemachine_
 
MemorySystemmemSystem_
 
std::vector< std::string > inputPorts_
 
std::vector< std::string > inputLoadPorts_
 
std::vector< std::string > inputOpcodePorts_
 
std::vector< std::string > outputPorts_
 
std::vector< std::string > outputLoadPorts_
 
std::vector< std::string > outputOpcodePorts_
 

Static Private Attributes

static const std::string RF_NAME_ = "testRF"
 

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 51 of file RFTestbenchGenerator.hh.

Constructor & Destructor Documentation

◆ RFTestbenchGenerator()

RFTestbenchGenerator::RFTestbenchGenerator ( HDB::RFEntry rf)

Definition at line 64 of file RFTestbenchGenerator.cc.

64 :
65 rfEntry_(rf), rfImpl_(NULL), rfArch_(NULL), machRf_(NULL), msm_(NULL),
68
69}
HDB::RFArchitecture * rfArch_
TTAMachine::RegisterFile * machRf_
std::vector< std::string > outputPorts_
std::vector< std::string > inputPorts_
HDB::RFImplementation * rfImpl_
std::vector< std::string > outputOpcodePorts_
std::vector< std::string > inputLoadPorts_
std::vector< std::string > inputOpcodePorts_
std::vector< std::string > outputLoadPorts_

◆ ~RFTestbenchGenerator()

RFTestbenchGenerator::~RFTestbenchGenerator ( )
virtual

Definition at line 71 of file RFTestbenchGenerator.cc.

71 {
72 if (msm_) {
73 delete(msm_);
74 }
75 if (machine_) {
76 delete(machine_);
77 }
78 if (memSystem_) {
79 delete(memSystem_);
80 }
81}
TTAMachine::Machine * machine_

References machine_, memSystem_, and msm_.

Member Function Documentation

◆ createMachineState()

void RFTestbenchGenerator::createMachineState ( )
private

Creates machine state model with the RF under test in it

Definition at line 106 of file RFTestbenchGenerator.cc.

106 {
107
109 int size = 0;
111 // set reasonable default value
112 size = 16;
113 rfArch_->setSize(size);
114 } else {
115 size = rfArch_->size();
116 }
117 int width = 0;
119 width = 32;
120 rfArch_->setWidth(width);
121 } else {
122 width = rfArch_->width();
123 }
124
125 string name = RF_NAME_;
126 // create simulation model of the RF
128 name, size, width, rfArch_->maxReads(), rfArch_->maxWrites(),
132
133 MachineStateBuilder msmBuilder;
134
136
137 msm_ = msmBuilder.build(*machine_, *memSystem_);
138}
bool hasParameterizedWidth() const
void setSize(int size)
bool zeroRegister() const
void setWidth(int width)
bool hasParameterizedSize() const
MachineState * build(const TTAMachine::Machine &machine, MemorySystem &memSys)
static const std::string RF_NAME_
virtual void addRegisterFile(RegisterFile &unit)
Definition Machine.cc:236
@ NORMAL
Used for general register allocation.

References TTAMachine::Machine::addRegisterFile(), MachineStateBuilder::build(), HDB::RFArchitecture::guardLatency(), HDB::RFArchitecture::hasParameterizedSize(), HDB::RFArchitecture::hasParameterizedWidth(), machine_, machRf_, HDB::RFArchitecture::maxReads(), HDB::RFArchitecture::maxWrites(), memSystem_, msm_, TTAMachine::RegisterFile::NORMAL, RF_NAME_, rfArch_, HDB::RFArchitecture::setSize(), HDB::RFArchitecture::setWidth(), HDB::RFArchitecture::size(), HDB::RFArchitecture::width(), and HDB::RFArchitecture::zeroRegister().

Referenced by generateTestbench().

Here is the call graph for this function:

◆ createStimulus()

void RFTestbenchGenerator::createStimulus ( )
private

Creates input and output data tables

Creates input and output data and control signals as well for the testbench. Testbench writes to and reads from every register. If RF has multiple write or read ports maximum number of ports is used on every cycle. Ports are written and read in round robin order. Test is pipelined in such way that writing starts on the first cycle and reading starts when all the registers can be read without stall cycles.

Definition at line 339 of file RFTestbenchGenerator.cc.

339 {
340
343
344 PortDataArray inputData;
345 PortDataArray inputOpcode;
346 PortDataArray inputLoad;
347
348 PortDataArray outputData;
349 PortDataArray outputOpcode;
350 PortDataArray outputLoad;
351
352 // initialize a random number generator for the stimuli
353 boost::uniform_int<> distribution(INT_MIN, INT_MAX);
354 boost::mt19937 rng;
355 rng.seed(time(NULL));
356 boost::variate_generator<boost::mt19937&, boost::uniform_int<> >
357 randomNumber(rng, distribution);
358
359 // Number of cycles needed to write to all registers
360 int fillCycles = 0;
361 if (rfArch_->size() >= rfArch_->writePortCount()) {
362 double size = rfArch_->size();
363 double ports = rfArch_->writePortCount();
364 fillCycles = static_cast<int>(ceil(size/ports));
365 } else {
366 // RF has more write ports than registers
367 fillCycles = rfArch_->size();
368 }
369 // Number of cycles needed to read all registers (this includes flush
370 // cycles)
371 int readCycles =
372 static_cast<int>(ceil(rfArch_->size() / rfArch_->readPortCount()));
373
374 // Number of cycles needed to wait before we can start reading from RF
375 int outputWaitCycles = 0;
376 // Number of cycles needed to read rest of the register after fill cycles
377 int pipelineFlushCycles = 0;
378 if (fillCycles > readCycles) {
379 pipelineFlushCycles = rfArch_->latency();
380 // total cycles - read cycles
381 outputWaitCycles = fillCycles + pipelineFlushCycles - readCycles;
382 } else {
383 pipelineFlushCycles = rfArch_->latency() + (readCycles - fillCycles);
384 outputWaitCycles = rfArch_->latency();
385 }
386
387 // port index and register where next input should be written to
388 int wrPortIndex = 0;
389 int wrRegIndex = 0;
390 // port index and register where next output should be read from
391 int rdPortIndex = 0;
392 int rdRegIndex = 0;
393 // port index and register where next output load is written to
394 int rdLoadPortIndex = 0;
395 int rdLoadRegIndex = 0;
396
397 // Write data to registers and also start reading them when possible
398 for (int i = 0; i < fillCycles; i++) {
399 // Handle output first because register state is updated immediately
400 if (i < outputWaitCycles) {
401 for (int j = 0; j < rfArch_->readPortCount(); j++) {
402 string portName = outputPorts_.at(j);
403 outputData[portName].push_back(0);
404 }
405 } else {
406 for (int j = 0; j < rfArch_->readPortCount(); j++) {
407 string portName = outputPorts_.at(rdPortIndex);
408 outputData[portName].push_back(
409 simRF.registerState(rdRegIndex).value().unsignedValue());
410 // round robin regs and ports
411 rdRegIndex++;
412 rdRegIndex = rdRegIndex % rfArch_->size();
413 rdPortIndex++;
414 rdPortIndex = rdPortIndex % rfArch_->readPortCount();
415 }
416 }
417
418 // write output load and opcode signals
419 if ( i < (outputWaitCycles - rfArch_->latency())) {
420 for (int j = 0; j < rfArch_->readPortCount(); j++) {
421 string opcodePort = outputOpcodePorts_.at(j);
422 string loadPort = outputLoadPorts_.at(j);
423 outputOpcode[opcodePort].push_back(0);
424 outputLoad[loadPort].push_back(0);
425 }
426 } else {
427 for (int j = 0; j < rfArch_->readPortCount(); j++) {
428 string opcodePort = outputOpcodePorts_.at(rdLoadPortIndex);
429 string loadPort = outputLoadPorts_.at(rdLoadPortIndex);
430 outputOpcode[opcodePort].push_back(rdLoadRegIndex);
431 outputLoad[loadPort].push_back(1);
432 // round robin regs and ports
433 rdLoadRegIndex++;
434 rdLoadRegIndex = rdLoadRegIndex % rfArch_->size();
435 rdLoadPortIndex++;
436 rdLoadPortIndex = rdLoadPortIndex % rfArch_->readPortCount();
437 }
438 }
439
440
441 // write inputs
442 for (int j = 0; j < rfArch_->writePortCount(); j++) {
443 int nopPortIndex = wrPortIndex;
444 // write only to as many ports per cycle as possible
445 // and write only once to every register
446 if (j < rfArch_->maxWrites() && wrRegIndex < rfArch_->size()) {
447 uint32_t stimulus = (uint32_t)randomNumber();
448 const int portWidth = rfArch_->width();
449 SimValue simStim(portWidth);
450 stimulus = (stimulus << (32 - portWidth) >> (32 - portWidth));
451 simStim = stimulus;
452 simRF.registerState(wrRegIndex).setValue(simStim);
453
454 string portName = inputPorts_.at(wrPortIndex);
455 inputData[portName].push_back(stimulus);
456
457 string opcodePort = inputOpcodePorts_.at(wrPortIndex);
458 uint32_t opcode = static_cast<uint32_t>(wrRegIndex);
459 inputOpcode[opcodePort].push_back(opcode);
460
461 string loadPort = inputLoadPorts_.at(wrPortIndex);
462 uint32_t load = 1;
463 inputLoad[loadPort].push_back(load);
464
465 wrRegIndex++;
466 // use round robin for write ports
467 wrPortIndex++;
468 wrPortIndex = wrPortIndex % rfArch_->writePortCount();
469 } else {
470 // write nop to other ports
471 uint32_t stimulus = 0;
472 uint32_t opcode = 0;
473 uint32_t load = 0;
474
475 string portName = inputPorts_.at(nopPortIndex);
476 inputData[portName].push_back(stimulus);
477
478 string opcodePort = inputOpcodePorts_.at(nopPortIndex);
479 inputOpcode[opcodePort].push_back(opcode);
480 string loadPort = inputLoadPorts_.at(nopPortIndex);
481 inputLoad[loadPort].push_back(load);
482
483 // round robin
484 wrPortIndex++;
485 wrPortIndex = wrPortIndex % rfArch_->writePortCount();
486 }
487 }
488 }
489
490 // No more data to be written, read rest of the registers
491 for (int i = 0; i < pipelineFlushCycles; i++) {
492 for (int j = 0; j < rfArch_->writePortCount(); j++) {
493 // write nop to write ports
494 uint32_t stimulus = 0;
495 uint32_t opcode = 0;
496 uint32_t load = 0;
497
498 string portName = inputPorts_.at(j);
499 inputData[portName].push_back(stimulus);
500
501 string opcodePort = inputOpcodePorts_.at(j);
502 inputOpcode[opcodePort].push_back(opcode);
503 string loadPort = inputLoadPorts_.at(j);
504 inputLoad[loadPort].push_back(load);
505 }
506 // write output load signals
507 for (int j = 0; j < rfArch_->readPortCount(); j++) {
508 string opcodePort = outputOpcodePorts_.at(rdLoadPortIndex);
509 string loadPort = outputLoadPorts_.at(rdLoadPortIndex);
510 outputOpcode[opcodePort].push_back(rdLoadRegIndex);
511 outputLoad[loadPort].push_back(1);
512 // round robin regs and ports
513 rdLoadRegIndex++;
514 rdLoadRegIndex = rdLoadRegIndex % rfArch_->size();
515 rdLoadPortIndex++;
516 rdLoadPortIndex = rdLoadPortIndex % rfArch_->readPortCount();
517 }
518 // write output data, opcodes and loads
519 for (int j = 0; j < rfArch_->readPortCount(); j++) {
520 string portName = outputPorts_.at(rdPortIndex);
521 outputData[portName].push_back(
522 simRF.registerState(rdRegIndex).value().unsignedValue());
523 // round robin regs and ports
524 rdRegIndex++;
525 rdRegIndex = rdRegIndex % rfArch_->size();
526 rdPortIndex++;
527 rdPortIndex = rdPortIndex % rfArch_->readPortCount();
528 }
529 }
530
531 createStimulusArrays(inputData, inputOpcode, inputLoad, outputData,
532 outputOpcode, outputLoad);
533
534 int totalCycleCount = fillCycles + pipelineFlushCycles;
535 writeTbConstants(totalCycleCount, outputWaitCycles);
536}
#define assert(condition)
RegisterFileState & registerFileState(const std::string &name)
static NullRegisterFileState & instance()
void createStimulusArrays(PortDataArray &inputData, PortDataArray &inputOpcode, PortDataArray &inputLoad, PortDataArray &outputData, PortDataArray &outputOpcode, PortDataArray &outputLoad)
virtual RegisterState & registerState(int index)
virtual void setValue(const SimValue &value)
virtual const SimValue & value() const
unsigned int unsignedValue() const
Definition SimValue.cc:919
std::map< std::string, std::vector< uint32_t > > PortDataArray
void writeTbConstants(int totalCycles, int outputIgnoreCycles)

References assert, createStimulusArrays(), inputLoadPorts_, inputOpcodePorts_, inputPorts_, NullRegisterFileState::instance(), HDB::RFArchitecture::latency(), msm_, outputLoadPorts_, outputOpcodePorts_, outputPorts_, HDB::RFArchitecture::readPortCount(), MachineState::registerFileState(), RegisterFileState::registerState(), RF_NAME_, rfArch_, RegisterState::setValue(), HDB::RFArchitecture::size(), SimValue::unsignedValue(), RegisterState::value(), HDB::RFArchitecture::width(), HDB::RFArchitecture::writePortCount(), and TestbenchGenerator::writeTbConstants().

Referenced by generateTestbench().

Here is the call graph for this function:

◆ createStimulusArrays()

void RFTestbenchGenerator::createStimulusArrays ( PortDataArray inputData,
PortDataArray inputOpcode,
PortDataArray inputLoad,
PortDataArray outputData,
PortDataArray outputOpcode,
PortDataArray outputLoad 
)
private

Writes input, output and control signal data to output streams

Parameters
inputDataArray containing input ports and their values
inputOpcodeArray containing input port opcode ports and their values
inputLoadArray containing input port load ports and their values
outputDataArray containing output ports and their values
outputOpcodeArray containing output port opcode ports and their values
outputLoadArray containing output port load ports and their values

Definition at line 606 of file RFTestbenchGenerator.cc.

612 {
613
614 int portWidth = rfArch_->width();
615 writeDataArrays(inputArrayStream(), inputData, portWidth);
616 writeDataArrays(outputArrayStream(), outputData, portWidth);
617
618 int loadWidth = 1;
619 writeDataArrays(loadArrayStream(), inputLoad, loadWidth);
620 writeDataArrays(loadArrayStream(), outputLoad, loadWidth);
621
622 int opcodeWidth = opcodePortWidth();
623 writeDataArrays(opcodeArrayStream(), inputOpcode, opcodeWidth);
624 writeDataArrays(opcodeArrayStream(), outputOpcode, opcodeWidth);
625}
void writeDataArrays(std::ostringstream &stream, PortDataArray &array, int portWidth)
std::ostringstream & opcodeArrayStream()
std::ostringstream & inputArrayStream()
std::ostringstream & outputArrayStream()
std::ostringstream & loadArrayStream()

References TestbenchGenerator::inputArrayStream(), TestbenchGenerator::loadArrayStream(), TestbenchGenerator::opcodeArrayStream(), opcodePortWidth(), TestbenchGenerator::outputArrayStream(), rfArch_, HDB::RFArchitecture::width(), and writeDataArrays().

Referenced by createStimulus().

Here is the call graph for this function:

◆ createTbCode()

void RFTestbenchGenerator::createTbCode ( )
private

Writes the testbench main process code

Definition at line 542 of file RFTestbenchGenerator.cc.

542 {
543
544 // input ports
545 for (int i = 0; i < rfArch_->writePortCount(); i++) {
546 string portName = inputPorts_.at(i);
547 string loadPort = inputLoadPorts_.at(i);
548 string opcodePort = inputOpcodePorts_.at(i);
549
551 << INDENT INDENT << portName << " <= " << portName << "_data("
552 << "current_cycle);" << std::endl
553 << INDENT INDENT << loadPort << " <= " << loadPort
554 <<"_data(current_cycle);" << std::endl
555 << INDENT INDENT << opcodePort << " <= " << opcodePort
556 << "_data(current_cycle);" << std::endl;
557 }
558 // output port load and opcode signals
559 for (int i = 0; i < rfArch_->readPortCount(); i++) {
560 string loadPort = outputLoadPorts_.at(i);
561 string opcodePort = outputOpcodePorts_.at(i);
562
563 tbCodeStream()
564 << INDENT INDENT << loadPort << " <= " << loadPort
565 <<"_data(current_cycle);" << std::endl
566 << INDENT INDENT << opcodePort << " <= " << opcodePort
567 << "_data(current_cycle);" << std::endl;
568 }
569 // output ports
571 << std::endl << std::endl << INDENT INDENT
572 << "if current_cycle >= IGNORE_OUTPUT_COUNT then" << std::endl;
573 for (int i = 0; i < rfArch_->readPortCount(); i++) {
574 string portName = outputPorts_.at(i);
575 tbCodeStream()
577 << "assert " << portName << " = " << portName << "_data"
578 << "(current_cycle)" << std::endl
580 << "report lf & \"TCE Assert: Verification failed at cycle \" "
581 << "& integer'image(current_cycle)" << std::endl
582 << INDENT INDENT INDENT INDENT <<"& \" output: \" "
583 << "& to_hstring(" << portName << ")"
584 << std::endl
585 << INDENT INDENT INDENT INDENT << "& "
586 << "\" expected: \" & to_hstring(" << portName
587 << "_data(current_cycle)) severity error;"
588 << std::endl << std::endl;
589 }
590 tbCodeStream() << INDENT INDENT << "end if;" << std::endl;
591}
#define INDENT
std::ostringstream & tbCodeStream()

References INDENT, inputLoadPorts_, inputOpcodePorts_, inputPorts_, outputLoadPorts_, outputOpcodePorts_, outputPorts_, HDB::RFArchitecture::readPortCount(), rfArch_, TestbenchGenerator::tbCodeStream(), and HDB::RFArchitecture::writePortCount().

Referenced by generateTestbench().

Here is the call graph for this function:

◆ createTbInstantiation()

void RFTestbenchGenerator::createTbInstantiation ( )
private

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

Definition at line 168 of file RFTestbenchGenerator.cc.

168 {
169
171 << INDENT << "for tested_rf_0 : rf_under_test use entity work.";
172 bindingStream() << rfImpl_->moduleName() << ";" << std::endl;
173
175 << INDENT << "component rf_under_test" << std::endl;
177 << INDENT << "tested_rf_0\t:\trf_under_test " << std::endl;
178
179 string sizeGeneric = rfImpl_->sizeParameter();
180 string widthGeneric = rfImpl_->widthParameter();
181 if (!sizeGeneric.empty() || !widthGeneric.empty()) {
183 << INDENT INDENT << "generic(" << std::endl;
185 << INDENT INDENT << "generic map (" << std::endl;
186 if (!sizeGeneric.empty()) {
188 << INDENT INDENT INDENT << sizeGeneric
189 << "\t: integer := " << rfArch_->size();
191 << INDENT INDENT INDENT << sizeGeneric << " => "
192 << rfArch_->size();
193 if (!widthGeneric.empty()) {
194 declarationStream() << ";" << std::endl;
195 instantiationStream() << "," << std::endl;
196 }
197 }
198
199 if (!widthGeneric.empty()) {
201 << INDENT INDENT INDENT << widthGeneric
202 << "\t: integer := " << rfArch_->width();
204 << INDENT INDENT INDENT << widthGeneric << " => "
205 << rfArch_->width();
206 }
208 << ");" << std::endl;
210 << ")" << std::endl;
211 }
212
214 << INDENT INDENT << "port(" << std::endl;
216 << INDENT INDENT << "port map (" << std::endl;
217
218 const int portWidth = rfArch_->width();
219 int opcodeWidth = opcodePortWidth();
220 for (int i = 0; i < rfArch_->writePortCount(); i++) {
221 // data port
223 << INDENT INDENT << inputPorts_.at(i) << "\t: "
224 << "in std_logic_vector(" << portWidth
225 << "-1 downto 0);" << std::endl;
226 // load port
228 << INDENT INDENT << inputLoadPorts_.at(i) << "\t: "
229 << "in std_logic;" << std::endl;
230 // opcode port
232 << INDENT INDENT << inputOpcodePorts_.at(i) << "\t: "
233 << "in std_logic_vector(" << opcodeWidth
234 << "-1 downto 0);" << std::endl;
235
237 << INDENT << "signal " << inputPorts_.at(i) << "\t: "
238 << "std_logic_vector(" << portWidth << "-1 downto 0);"
239 << std::endl;
241 << INDENT << "signal " << inputLoadPorts_.at(i)
242 << "\t: std_logic_vector(1-1 downto 0);" << std::endl;
244 << INDENT << "signal " << inputOpcodePorts_.at(i) << "\t: "
245 << "std_logic_vector(" << opcodeWidth << "-1 downto 0);"
246 << std::endl;
247
249 << INDENT INDENT INDENT << inputPorts_.at(i) << " => "
250 << inputPorts_.at(i) << "," << std::endl;
252 << INDENT INDENT INDENT << inputLoadPorts_.at(i) << " => "
253 << inputLoadPorts_.at(i) << "(0)," << std::endl;
255 << INDENT INDENT INDENT << inputOpcodePorts_.at(i) << " => "
256 << inputOpcodePorts_.at(i) << "," << std::endl;
257 }
258
259 for (int i = 0; i < rfArch_->readPortCount(); i++) {
261 << INDENT INDENT << outputPorts_.at(i) << "\t: "
262 << "out std_logic_vector(" << portWidth
263 << "-1 downto 0);" << std::endl;
264 // load port
266 << INDENT INDENT << outputLoadPorts_.at(i) << "\t: "
267 << "in std_logic;" << std::endl;
268 // opcode port
270 << INDENT INDENT << outputOpcodePorts_.at(i) << "\t: "
271 << "in std_logic_vector(" << opcodeWidth
272 << "-1 downto 0);" << std::endl;
273
275 << INDENT << "signal " << outputPorts_.at(i) << "\t: "
276 << "std_logic_vector(" << portWidth << "-1 downto 0);"
277 << std::endl;
279 << INDENT << "signal " << outputLoadPorts_.at(i)
280 << "\t: std_logic_vector(1-1 downto 0);" << std::endl;
282 << INDENT << "signal " << outputOpcodePorts_.at(i) << "\t: "
283 << "std_logic_vector(" << opcodeWidth << "-1 downto 0);"
284 << std::endl;
285
287 << INDENT INDENT INDENT << outputPorts_.at(i) << " => "
288 << outputPorts_.at(i) << "," << std::endl;
290 << INDENT INDENT INDENT << outputLoadPorts_.at(i) << " => "
291 << outputLoadPorts_.at(i) << "(0)," << std::endl;
293 << INDENT INDENT INDENT << outputOpcodePorts_.at(i) << " => "
294 << outputOpcodePorts_.at(i) << "," << std::endl;
295 }
298 << rfImpl_->clkPort() << " => " << rfImpl_->clkPort()
299 << "," << std::endl
301 << rfImpl_->rstPort() << " => " << rfImpl_->rstPort()
302 << "," << std::endl
304 << rfImpl_->glockPort() << " => " << rfImpl_->glockPort()
305 << ");";
306
308 << INDENT INDENT << rfImpl_->glockPort() << "\t: in std_logic;"
309 << std::endl
310 << INDENT INDENT << rfImpl_->rstPort() << "\t: in std_logic;"
311 << std::endl
312 << INDENT INDENT << rfImpl_->clkPort() << "\t: in std_logic);"
313 << std::endl
314 << INDENT << "end component;"
315 << std::endl;
316
318 << INDENT << "signal " << rfImpl_->glockPort() << "\t: std_logic;"
319 << std::endl
320 << INDENT << "signal " << rfImpl_->rstPort() << "\t: std_logic;"
321 << std::endl
322 << INDENT << "signal " << rfImpl_->clkPort() << "\t: std_logic;"
323 << std::endl;
324
325}
std::string sizeParameter() const
std::string widthParameter() const
std::ostringstream & instantiationStream()
std::ostringstream & bindingStream()
std::ostringstream & declarationStream()
std::ostringstream & signalStream()

References TestbenchGenerator::bindingStream(), HDB::HWBlockImplementation::clkPort(), TestbenchGenerator::declarationStream(), HDB::HWBlockImplementation::glockPort(), INDENT, inputLoadPorts_, inputOpcodePorts_, inputPorts_, TestbenchGenerator::instantiationStream(), HDB::HWBlockImplementation::moduleName(), opcodePortWidth(), outputLoadPorts_, outputOpcodePorts_, outputPorts_, HDB::RFArchitecture::readPortCount(), rfArch_, rfImpl_, HDB::HWBlockImplementation::rstPort(), TestbenchGenerator::signalStream(), HDB::RFArchitecture::size(), HDB::RFImplementation::sizeParameter(), HDB::RFArchitecture::width(), HDB::RFImplementation::widthParameter(), and HDB::RFArchitecture::writePortCount().

Referenced by generateTestbench().

Here is the call graph for this function:

◆ generateTestbench()

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

Creates the testbench and writes it to the given filestream

Parameters
fileFilestream where the testbench is written

Implements TestbenchGenerator.

Definition at line 89 of file RFTestbenchGenerator.cc.

89 {
90
93
100}
RFArchitecture & architecture() const
Definition RFEntry.cc:145
RFImplementation & implementation() const
Definition RFEntry.cc:102
void writeTestbench(std::ofstream &file, HDB::HWBlockImplementation *impl)

References HDB::RFEntry::architecture(), createMachineState(), createStimulus(), createTbCode(), createTbInstantiation(), HDB::RFEntry::implementation(), parseRfPorts(), rfArch_, rfEntry_, rfImpl_, and TestbenchGenerator::writeTestbench().

Here is the call graph for this function:

◆ opcodePortWidth()

int RFTestbenchGenerator::opcodePortWidth ( ) const
private

Definition at line 628 of file RFTestbenchGenerator.cc.

628 {
629
630 int width = 0;
631 if (rfArch_->size() > 1) {
632 unsigned int biggestIndex = rfArch_->size()-1;
633 width = MathTools::requiredBits(biggestIndex);
634 } else {
635 width = 1;
636 }
637 return width;
638}
static int requiredBits(unsigned long int number)

References MathTools::requiredBits(), rfArch_, and HDB::RFArchitecture::size().

Referenced by createStimulusArrays(), and createTbInstantiation().

Here is the call graph for this function:

◆ parseRfPorts()

void RFTestbenchGenerator::parseRfPorts ( )
private

Definition at line 142 of file RFTestbenchGenerator.cc.

142 {
143
144 for (int i = 0; i < rfImpl_->portCount(); i++) {
145 string portName = rfImpl_->port(i).name();
146 string opcodePort = rfImpl_->port(i).opcodePort();
147 string loadPort = rfImpl_->port(i).loadPort();
148 if (rfImpl_->port(i).direction() == HDB::IN) {
149 inputPorts_.push_back(portName);
150 inputOpcodePorts_.push_back(opcodePort);
151 inputLoadPorts_.push_back(loadPort);
152 } else if (rfImpl_->port(i).direction() == HDB::OUT) {
153 outputPorts_.push_back(portName);
154 outputOpcodePorts_.push_back(opcodePort);
155 outputLoadPorts_.push_back(loadPort);
156 } else {
157 assert(false && "RF port implementation does not have direction");
158 }
159 }
160 }
std::string loadPort() const
RFPortImplementation & port(int index) const
@ OUT
Output port.
Definition HDBTypes.hh:42
@ IN
Input port.
Definition HDBTypes.hh:41

References assert, HDB::RFPortImplementation::direction(), HDB::IN, inputLoadPorts_, inputOpcodePorts_, inputPorts_, HDB::PortImplementation::loadPort(), HDB::PortImplementation::name(), HDB::RFPortImplementation::opcodePort(), HDB::OUT, outputLoadPorts_, outputOpcodePorts_, outputPorts_, HDB::RFImplementation::port(), HDB::RFImplementation::portCount(), and rfImpl_.

Referenced by generateTestbench().

Here is the call graph for this function:

◆ writeDataArrays()

void RFTestbenchGenerator::writeDataArrays ( std::ostringstream &  stream,
PortDataArray array,
int  portWidth 
)
private

Write one PortDataArray to output stream

Parameters
streamOutput stream
arrayArray to be written
portWidthWidth of the output port

Definition at line 648 of file RFTestbenchGenerator.cc.

651 {
652
653 for (PortDataArray::iterator i = array.begin(); i != array.end(); i++) {
654 string portName = i->first;
655 vector<uint32_t> data = i->second;
656 writeStimulusArray(stream, data, portName, portWidth);
657 }
658}
virtual void writeStimulusArray(std::ostringstream &stream, std::vector< uint32_t > &dataArray, std::string portName, int portWidth)

References TestbenchGenerator::writeStimulusArray().

Referenced by createStimulusArrays().

Here is the call graph for this function:

Member Data Documentation

◆ inputLoadPorts_

std::vector<std::string> RFTestbenchGenerator::inputLoadPorts_
private

◆ inputOpcodePorts_

std::vector<std::string> RFTestbenchGenerator::inputOpcodePorts_
private

◆ inputPorts_

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

◆ machine_

TTAMachine::Machine* RFTestbenchGenerator::machine_
private

Definition at line 93 of file RFTestbenchGenerator.hh.

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

◆ machRf_

TTAMachine::RegisterFile* RFTestbenchGenerator::machRf_
private

Definition at line 90 of file RFTestbenchGenerator.hh.

Referenced by createMachineState().

◆ memSystem_

MemorySystem* RFTestbenchGenerator::memSystem_
private

Definition at line 94 of file RFTestbenchGenerator.hh.

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

◆ msm_

MachineState* RFTestbenchGenerator::msm_
private

◆ outputLoadPorts_

std::vector<std::string> RFTestbenchGenerator::outputLoadPorts_
private

◆ outputOpcodePorts_

std::vector<std::string> RFTestbenchGenerator::outputOpcodePorts_
private

◆ outputPorts_

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

◆ RF_NAME_

const std::string RFTestbenchGenerator::RF_NAME_ = "testRF"
staticprivate

Definition at line 103 of file RFTestbenchGenerator.hh.

Referenced by createMachineState(), and createStimulus().

◆ rfArch_

HDB::RFArchitecture* RFTestbenchGenerator::rfArch_
private

◆ rfEntry_

HDB::RFEntry* RFTestbenchGenerator::rfEntry_
private

Definition at line 87 of file RFTestbenchGenerator.hh.

Referenced by generateTestbench().

◆ rfImpl_

HDB::RFImplementation* RFTestbenchGenerator::rfImpl_
private

Definition at line 88 of file RFTestbenchGenerator.hh.

Referenced by createTbInstantiation(), generateTestbench(), and parseRfPorts().


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