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

#include <DefaultDecoderGenerator.hh>

Collaboration diagram for DefaultDecoderGenerator:
Collaboration graph

Public Member Functions

 DefaultDecoderGenerator (const TTAMachine::Machine &machine, const BinaryEncoding &bem, const CentralizedControlICGenerator &icGenerator)
 
virtual ~DefaultDecoderGenerator ()
 
void setGenerateDebugger (bool generate)
 
void setGenerateNoLoopbackGlock (bool generate)
 
void setSyncReset (bool value)
 
void setGenerateBusEnable (bool value)
 
void SetHDL (ProGe::HDL language)
 
void completeDecoderBlock (const ProGe::NetlistGenerator &nlGenerator, ProGe::NetlistBlock &coreBlock)
 
void generateInstructionDecoder (const ProGe::NetlistGenerator &nlGenerator, const std::string &dstDirectory)
 
std::set< int > requiredRFLatencies (const TTAMachine::ImmediateUnit &iu) const
 
void verifyCompatibility () const
 
int glockRequestWidth () const
 
int glockPortWidth () const
 
void setGenerateLockTrace (bool generate)
 
void setLockTraceStartingCycle (unsigned int startCycle)
 

Static Public Attributes

static const std::string RISCV_SIMM_PORT_IN_NAME = "simm_in"
 
static const std::string GLOCK_PORT_NAME = "glock"
 

Private Types

typedef std::set< TTAMachine::Bus * > BusSet
 Set type for buses.
 
typedef int GlockBitType
 Types for mapping global lock and global lock request signals.
 
typedef int GlockReqBitType
 
typedef std::map< GlockBitType, const TTAMachine::Unit * > UnitGlockBitMapType
 
typedef std::map< const TTAMachine::Unit *, GlockReqBitTypeUnitGlockReqBitMapType
 

Private Member Functions

void addLockReqPortToDecoder ()
 
void addGlockPortToDecoder ()
 
void writeComment (std::ostream &stream, int indent, std::string comment) const
 
void writeSignalDeclaration (std::ostream &stream, ProGe::DataType type, std::string sigName, int width) const
 
void writeInstructionDecoder (std::ostream &stream)
 
void writeLockDumpCode (std::ostream &stream) const
 void writeDecompressSignalsVHDL(std::ostream& stream) const; TBR
 
void writeMoveFieldSignals (std::ostream &stream) const
 
void writeImmediateSlotSignals (std::ostream &stream) const
 
void writeLongImmediateTagSignal (std::ostream &stream) const
 
void writeSquashSignals (std::ostream &stream) const
 
void writeSocketCntrlSignals (std::ostream &stream)
 
void writeFUCntrlSignals (std::ostream &stream)
 
void writeFUCntrlSignals (const TTAMachine::FunctionUnit &fu, std::ostream &stream)
 
void writeRFCntrlSignals (std::ostream &stream)
 
void writeGlockHandlingSignals (std::ostream &stream) const
 
void writePipelineFillSignals (std::ostream &stream) const
 
void writeFullNOPConstant (std::ostream &stream) const
 
std::string writeNOPEncodingVHDL () const
 
void writeDismemberingAndITDecompression (std::ostream &stream) const
 
void writeInstructionDismembering (std::ostream &stream) const
 
void writeSquashSignalGenerationProcesses (std::ostream &stream) const
 
void writeSquashSignalGenerationProcess (const TTAMachine::Bus &bus, std::ostream &stream) const
 
void writeLongImmediateWriteProcess (std::ostream &stream) const
 
void writeControlRegisterMappings (std::ostream &stream) const
 
void writeRFSRAMDecodingProcess (std::ostream &stream) const
 
void writeMainDecodingProcess (std::ostream &stream) const
 
void writeGlockMapping (std::ostream &stream) const
 
void writePipelineFillProcess (std::ostream &stream) const
 
void writeResettingOfControlRegisters (std::ostream &stream) const
 
void writeInstructionDecoding (std::ostream &stream) const
 
void writeRulesForSourceControlSignals (std::ostream &stream) const
 
void writeRulesForDestinationControlSignals (std::ostream &stream) const
 
void writeSimmDataSignal (const TTAMachine::Bus &bus, std::ostream &stream) const
 
void writeBusControlRulesOfOutputSocket (const TTAMachine::Socket &socket, std::ostream &stream) const
 
void writeBusControlRulesOfSImmSocketOfBus (const TTAMachine::Bus &bus, std::ostream &stream) const
 
void writeControlRulesOfRFReadPort (const TTAMachine::RFPort &port, std::ostream &stream) const
 
void writeControlRulesOfFUOutputPort (const TTAMachine::BaseFUPort &port, std::ostream &stream) const
 
void writeControlRulesOfFUInputPort (const TTAMachine::BaseFUPort &port, std::ostream &stream) const
 
void writeControlRulesOfRFWritePort (const TTAMachine::RFPort &port, std::ostream &stream) const
 
void writeInstructionTemplateProcedures (const ProGe::HDL language, const TTAMachine::InstructionTemplate &iTemp, int indLevel, std::ostream &stream) const
 
void writeBusMuxControlLogic (const TTAMachine::Bus &bus, const std::set< TTAMachine::Socket * > outputSockets, std::ostream &stream) const
 
TTAMachine::RegisterGuardfindGuard (const GPRGuardEncoding &encoding) const
 
TTAMachine::PortGuardfindGuard (const FUGuardEncoding &encoding) const
 
int opcodeWidth (const TTAMachine::FunctionUnit &fu) const
 
std::string instructionTemplateCondition (const ProGe::HDL language, const std::string &iTempName) const
 
std::string busCntrlSignalPinOfSocket (const TTAMachine::Socket &socket, const TTAMachine::Bus &bus) const
 
int opcode (const TTAMachine::HWOperation &operation) const
 
bool sacEnabled (const std::string &rfName) const
 

Static Private Member Functions

static void writeSquashSignalSubstitution (const ProGe::HDL language, const TTAMachine::Bus &bus, const GuardEncoding &enc, const TTAMachine::Guard &guard, std::ostream &stream, int indLevel)
 
static bool containsSimilarGuard (const std::set< TTAMachine::PortGuard * > &guardSet, const TTAMachine::PortGuard &guard)
 
static bool containsSimilarGuard (const std::set< TTAMachine::RegisterGuard * > &guardSet, const TTAMachine::RegisterGuard &guard)
 
static bool needsBusControl (const TTAMachine::Socket &socket)
 
static bool needsDataControl (const TTAMachine::Socket &socket)
 
static std::string simmDataPort (const std::string &busName)
 
static std::string simmControlPort (const std::string &busName)
 
static int simmPortWidth (const TTAMachine::Bus &bus)
 
static std::string simmDataSignalName (const std::string &busName)
 
static std::string simmCntrlSignalName (const std::string &busName)
 
static std::string fuLoadCntrlPort (const std::string &fuName, const std::string &portName)
 
static std::string fuLoadSignalName (const std::string &fuName, const std::string &portName)
 
static std::string fuOpcodeCntrlPort (const std::string &fu)
 
static std::string fuOpcodeSignalName (const std::string &fu)
 
static std::string rfLoadCntrlPort (const std::string &rfName, const std::string &portName)
 
static std::string rfLoadSignalName (const std::string &rfName, const std::string &portName, bool async=false)
 
static std::string rfOpcodeSignalName (const std::string &rfName, const std::string &portName, bool async=false)
 
static std::string rfOpcodeCntrlPort (const std::string &rfName, const std::string &portName)
 
static std::string iuReadOpcodeCntrlPort (const std::string &unitName, const std::string &portName)
 
static std::string iuReadOpcodeCntrlSignal (const std::string &unitName, const std::string &portName)
 
static std::string iuReadLoadCntrlPort (const std::string &unitName, const std::string &portName)
 
static std::string iuReadLoadCntrlSignal (const std::string &unitName, const std::string &portName)
 
static std::string iuWritePort (const std::string &iuName)
 
static std::string iuWriteSignal (const std::string &iuName)
 
static std::string iuWriteOpcodeCntrlPort (const std::string &unitName)
 
static std::string iuWriteOpcodeCntrlSignal (const std::string &unitName)
 
static std::string iuWriteLoadCntrlPort (const std::string &unitName)
 
static std::string iuWriteLoadCntrlSignal (const std::string &unitName)
 
static std::string busMuxCntrlSignal (const TTAMachine::Bus &bus)
 
static std::string busMuxCntrlRegister (const TTAMachine::Bus &bus)
 
static std::string busMuxEnableSignal (const TTAMachine::Bus &bus)
 
static std::string busMuxEnableRegister (const TTAMachine::Bus &bus)
 
static std::string socketBusControlPort (const std::string &name)
 
static std::string socketDataControlPort (const std::string &name)
 
static std::string moveFieldSignal (const std::string &busName)
 
static std::string guardPortName (const TTAMachine::Guard &guard)
 
static std::string srcFieldSignal (const std::string &busName)
 
static std::string dstFieldSignal (const std::string &busName)
 
static std::string guardFieldSignal (const std::string &busName)
 
static std::string immSlotSignal (const std::string &immSlot)
 
static std::string squashSignal (const std::string &busName)
 
static std::string socketBusCntrlSignalName (const std::string &name)
 
static std::string socketDataCntrlSignalName (const std::string &name)
 
static std::string gcuDataPort (const std::string &nameInADF)
 
static int busControlWidth (const TTAMachine::Socket &socket)
 
static int dataControlWidth (const TTAMachine::Socket &socket)
 
static int rfOpcodeWidth (const TTAMachine::BaseRegisterFile &rf)
 
static BusSet connectedBuses (const TTAMachine::Socket &socket)
 
static std::string socketEncodingCondition (const ProGe::HDL language, const SlotField &srcField, const std::string &socketName)
 
static std::string portCodeCondition (const ProGe::HDL language, const SocketEncoding &socketEnc, const PortCode &code)
 
static std::string rfOpcodeFromSrcOrDstField (const ProGe::HDL language, const SocketEncoding &socketEnc, const PortCode &code)
 
static std::string indentation (unsigned int level)
 

Private Attributes

const TTAMachine::Machinemachine_
 The machine.
 
const BinaryEncodingbem_
 The binary encoding map.
 
const CentralizedControlICGeneratoricGenerator_
 The IC generator.
 
const ProGe::NetlistGeneratornlGenerator_
 The netlist generator.
 
ProGe::NetlistBlockdecoderBlock_
 The instruction decoder block in the netlist.
 
bool generateLockTrace_
 Tells whether to generate global lock tracing code.
 
TCEString entityNameStr_
 
ProGe::HDL language_
 
bool generateDebugger_
 Generate debugger signals?
 
bool syncReset_
 Reset synchronously (otherwise asynchronous)
 
bool generateBusEnable_
 Bus enable signals for bustrace.
 
unsigned int lockTraceStartingCycle_
 The starting cycle for bus tracing.
 
bool generateAlternateGlockReqHandling_
 The flag to generate global lock request handling in decoder. False means delegating the lock request towards instruction fetch.
 
UnitGlockBitMapType unitGlockBitMap_
 Maps connected glock port bits to associated TTA Units.
 
UnitGlockReqBitMapType unitGlockReqBitMap_
 Maps TTA Units to associated glock request port bits.
 
std::vector< std::string > registerVectors
 Bookkeeping for reset-needing signals.
 
std::vector< std::string > registerBits
 

Detailed Description

Generates the default instruction decoder in VHDL.

Definition at line 86 of file DefaultDecoderGenerator.hh.

Member Typedef Documentation

◆ BusSet

Set type for buses.

Definition at line 121 of file DefaultDecoderGenerator.hh.

◆ GlockBitType

Types for mapping global lock and global lock request signals.

Definition at line 123 of file DefaultDecoderGenerator.hh.

◆ GlockReqBitType

Definition at line 124 of file DefaultDecoderGenerator.hh.

◆ UnitGlockBitMapType

Definition at line 126 of file DefaultDecoderGenerator.hh.

◆ UnitGlockReqBitMapType

Definition at line 128 of file DefaultDecoderGenerator.hh.

Constructor & Destructor Documentation

◆ DefaultDecoderGenerator()

DefaultDecoderGenerator::DefaultDecoderGenerator ( const TTAMachine::Machine machine,
const BinaryEncoding bem,
const CentralizedControlICGenerator icGenerator 
)

The constructor.

Parameters
machineThe machine.
bemThe binary encoding map.
icGeneratorThe IC generator.

Definition at line 155 of file DefaultDecoderGenerator.cc.

158 : machine_(machine),
159 bem_(bem),
160 icGenerator_(icGenerator),
161 nlGenerator_(NULL),
162 decoderBlock_(NULL),
163 generateLockTrace_(false),
165 generateDebugger_(false),
TTAMachine::Machine * machine
the architecture definition of the estimated processor
bool generateAlternateGlockReqHandling_
The flag to generate global lock request handling in decoder. False means delegating the lock request...
unsigned int lockTraceStartingCycle_
The starting cycle for bus tracing.
const CentralizedControlICGenerator & icGenerator_
The IC generator.
UnitGlockReqBitMapType unitGlockReqBitMap_
Maps TTA Units to associated glock request port bits.
ProGe::NetlistBlock * decoderBlock_
The instruction decoder block in the netlist.
const BinaryEncoding & bem_
The binary encoding map.
UnitGlockBitMapType unitGlockBitMap_
Maps connected glock port bits to associated TTA Units.
bool generateDebugger_
Generate debugger signals?
const ProGe::NetlistGenerator * nlGenerator_
The netlist generator.
bool generateLockTrace_
Tells whether to generate global lock tracing code.
const TTAMachine::Machine & machine_
The machine.
@ VHDL
VHDL.
Definition ProGeTypes.hh:41

◆ ~DefaultDecoderGenerator()

DefaultDecoderGenerator::~DefaultDecoderGenerator ( )
virtual

The destructor.

Definition at line 211 of file DefaultDecoderGenerator.cc.

211 {
212}

Member Function Documentation

◆ addGlockPortToDecoder()

void DefaultDecoderGenerator::addGlockPortToDecoder ( )
private

Adds the global lock port to decoder and connects it to the glock ports of units.

Precondition: addLockReqPortToDecoder() must be called before this.

Definition at line 508 of file DefaultDecoderGenerator.cc.

508 {
509 int glockWidth = glockPortWidth();
510
511 if (glockWidth == 0) {
512 return;
513 }
514 int bitToConnect = 0;
515
518 NetlistPort* decGlockPort = new NetlistPort(
519 GLOCK_PORT_NAME, Conversion::toString(glockWidth), glockWidth,
521
523 for (int i = 0; i < fuNav.count(); i++) {
524 FunctionUnit* fu = fuNav.item(i);
525 if (fu->portCount() == 0) {
526 continue;
527 }
528 const NetlistBlock& fuBlock = nlGenerator_->netlistBlock(*fu);
529 if (nlGenerator_->hasGlockPort(fuBlock)) {
530 NetlistPort& glockPort = nlGenerator_->glockPort(fuBlock);
531 assert(bitToConnect < glockWidth);
532 netlist.connect(*decGlockPort, glockPort, bitToConnect, 0, 1);
533 unitGlockBitMap_[bitToConnect] = fu;
534 bitToConnect++;
535 }
536 }
537
539 for (int i = 0; i < rfNav.count(); i++) {
540 RegisterFile* rf = rfNav.item(i);
541 if (rf->portCount() == 0) {
542 continue;
543 }
544 const NetlistBlock& rfBlock = nlGenerator_->netlistBlock(*rf);
545 if (nlGenerator_->hasGlockPort(rfBlock)) {
546 NetlistPort& glockPort = nlGenerator_->glockPort(rfBlock);
547 assert(bitToConnect < glockWidth);
548 netlist.connect(*decGlockPort, glockPort, bitToConnect, 0, 1);
549 unitGlockBitMap_[bitToConnect] = rf;
550 bitToConnect++;
551 }
552 }
553
555 for (int i = 0; i < iuNav.count(); i++) {
556 ImmediateUnit* iu = iuNav.item(i);
557 if (iu->portCount() == 0) {
558 continue;
559 }
560 const NetlistBlock& iuBlock = nlGenerator_->netlistBlock(*iu);
561 if (nlGenerator_->hasGlockPort(iuBlock)) {
562 NetlistPort& glockPort = nlGenerator_->glockPort(iuBlock);
563 assert(bitToConnect < glockWidth);
564 netlist.connect(*decGlockPort, glockPort, bitToConnect, 0, 1);
565 unitGlockBitMap_[bitToConnect] = iu;
566 bitToConnect++;
567 }
568 }
569
570 // If IC requests glock port.
572 netlist.connect(
573 *decGlockPort, icGenerator_.glockPort(), bitToConnect, 0, 1);
574 bitToConnect++;
575 }
576}
#define assert(condition)
static std::string toString(const T &source)
static const std::string GLOCK_PORT_NAME
virtual bool hasParentBlock() const
virtual const NetlistBlock & parentBlock() const override
virtual const Netlist & netlist() const
NetlistBlock & netlistBlock(const TTAMachine::Unit &unit) const
bool hasGlockPort(const NetlistBlock &block) const
NetlistPort & glockPort(const NetlistBlock &block) const
bool connect(const NetlistPort &port1, const NetlistPort &port2, int port1FirstBit, int port2FirstBit, int width=1)
Definition Netlist.cc:83
ComponentType * item(int index) const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition Machine.cc:416
virtual int portCount() const
Definition Unit.cc:135
@ BIT_VECTOR
Several bits.
Definition ProGeTypes.hh:48
@ OUT
Output port.
Definition ProGeTypes.hh:54

References assert, ProGe::BIT_VECTOR, ProGe::Netlist::connect(), TTAMachine::Machine::Navigator< ComponentType >::count(), decoderBlock_, TTAMachine::Machine::functionUnitNavigator(), GLOCK_PORT_NAME, CentralizedControlICGenerator::glockPort(), ProGe::NetlistGenerator::glockPort(), glockPortWidth(), CentralizedControlICGenerator::hasGlockPort(), ProGe::NetlistGenerator::hasGlockPort(), ProGe::BaseNetlistBlock::hasParentBlock(), icGenerator_, TTAMachine::Machine::immediateUnitNavigator(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, ProGe::NetlistBlock::netlist(), ProGe::NetlistGenerator::netlistBlock(), nlGenerator_, ProGe::OUT, ProGe::NetlistBlock::parentBlock(), TTAMachine::Unit::portCount(), TTAMachine::Machine::registerFileNavigator(), Conversion::toString(), and unitGlockBitMap_.

Referenced by completeDecoderBlock().

Here is the call graph for this function:

◆ addLockReqPortToDecoder()

void DefaultDecoderGenerator::addLockReqPortToDecoder ( )
private

Adds the lock request input port to decoder and connects the global lock request ports of FU's to it.

Definition at line 468 of file DefaultDecoderGenerator.cc.

468 {
469
470 int lockReqWidth = glockRequestWidth();
471
472 if (lockReqWidth == 0) {
473 return;
474 }
475
478
479 // add lock request port to decoder
480 NetlistPort* lockReqPort = new NetlistPort(
481 LOCK_REQ_PORT_NAME, Conversion::toString(lockReqWidth), lockReqWidth,
483
484 // connect the glock request ports of FUs to the lock request port
485 int bitToConnect(0);
486 for (int i = 0; i < fuNav.count(); i++) {
487 FunctionUnit* fu = fuNav.item(i);
488 if (fu->portCount() == 0) {
489 continue;
490 }
491 const NetlistBlock& fuBlock = nlGenerator_->netlistBlock(*fu);
492 if (nlGenerator_->hasGlockReqPort(fuBlock)) {
493 NetlistPort& glockReqPort = nlGenerator_->glockReqPort(fuBlock);
494 netlist.connect(*lockReqPort, glockReqPort, bitToConnect, 0, 1);
495 unitGlockReqBitMap_[fu] = bitToConnect;
496 bitToConnect++;
497 }
498 }
499}
const string LOCK_REQ_PORT_NAME
bool hasGlockReqPort(const NetlistBlock &block) const
NetlistPort & glockReqPort(const NetlistBlock &block) const
@ IN
Input port.
Definition ProGeTypes.hh:53

References ProGe::BIT_VECTOR, ProGe::Netlist::connect(), TTAMachine::Machine::Navigator< ComponentType >::count(), decoderBlock_, TTAMachine::Machine::functionUnitNavigator(), ProGe::NetlistGenerator::glockReqPort(), glockRequestWidth(), ProGe::NetlistGenerator::hasGlockReqPort(), ProGe::IN, TTAMachine::Machine::Navigator< ComponentType >::item(), LOCK_REQ_PORT_NAME, machine_, ProGe::NetlistBlock::netlist(), ProGe::NetlistGenerator::netlistBlock(), nlGenerator_, ProGe::NetlistBlock::parentBlock(), TTAMachine::Unit::portCount(), Conversion::toString(), and unitGlockReqBitMap_.

Referenced by completeDecoderBlock().

Here is the call graph for this function:

◆ busCntrlSignalPinOfSocket()

std::string DefaultDecoderGenerator::busCntrlSignalPinOfSocket ( const TTAMachine::Socket socket,
const TTAMachine::Bus bus 
) const
private

Returns the signal pin that controls the bus of the given output socket.

Parameters
socketThe socket.
busThe bus.
Returns
The signal pin.

Definition at line 4885 of file DefaultDecoderGenerator.cc.

4887 {
4888
4889 assert(socket.direction() == Socket::OUTPUT);
4891 socket, *bus.segment(0));
4892 return socketBusCntrlSignalName(socket.name())
4893 + ((language_==VHDL)?"(":"[")
4894 + Conversion::toString(pin)
4895 + ((language_==VHDL)?")":"]");
4896}
virtual int outputSocketCntrlPinForSegment(const TTAMachine::Socket &socket, const TTAMachine::Segment &segment) const =0
static std::string socketBusCntrlSignalName(const std::string &name)
virtual Segment * segment(int index) const
Definition Bus.cc:329
virtual TCEString name() const
@ OUTPUT
Data goes from port to bus.
Definition Socket.hh:60
Direction direction() const

References assert, TTAMachine::Socket::direction(), icGenerator_, language_, TTAMachine::Component::name(), TTAMachine::Socket::OUTPUT, CentralizedControlICGenerator::outputSocketCntrlPinForSegment(), TTAMachine::Bus::segment(), socketBusCntrlSignalName(), Conversion::toString(), and ProGe::VHDL.

Referenced by writeBusControlRulesOfOutputSocket().

Here is the call graph for this function:

◆ busControlWidth()

int DefaultDecoderGenerator::busControlWidth ( const TTAMachine::Socket socket)
staticprivate

Returns the number of bits required to control the bus connections of the given socket.

Parameters
socketThe socket.
Returns
The control width.

Definition at line 4663 of file DefaultDecoderGenerator.cc.

4663 {
4664 if (socket.direction() == Socket::INPUT) {
4665 return MathTools::bitLength(socket.segmentCount() - 1);
4666 } else {
4667 return socket.segmentCount();
4668 }
4669}
static unsigned int bitLength(long unsigned int number)
@ INPUT
Data goes from bus to port.
Definition Socket.hh:59
int segmentCount() const

References MathTools::bitLength(), TTAMachine::Socket::direction(), TTAMachine::Socket::INPUT, and TTAMachine::Socket::segmentCount().

Referenced by completeDecoderBlock(), and writeSocketCntrlSignals().

Here is the call graph for this function:

◆ busMuxCntrlRegister()

std::string DefaultDecoderGenerator::busMuxCntrlRegister ( const TTAMachine::Bus bus)
staticprivate

Definition at line 4463 of file DefaultDecoderGenerator.cc.

4463 {
4464 return busMuxCntrlSignal(bus) + "_reg";
4465}
static std::string busMuxCntrlSignal(const TTAMachine::Bus &bus)

References busMuxCntrlSignal().

Here is the call graph for this function:

◆ busMuxCntrlSignal()

std::string DefaultDecoderGenerator::busMuxCntrlSignal ( const TTAMachine::Bus bus)
staticprivate

Definition at line 4458 of file DefaultDecoderGenerator.cc.

4458 {
4459 return bus.name() + "_src_sel";
4460}

References TTAMachine::Component::name().

Referenced by busMuxCntrlRegister().

Here is the call graph for this function:

◆ busMuxEnableRegister()

std::string DefaultDecoderGenerator::busMuxEnableRegister ( const TTAMachine::Bus bus)
staticprivate

Definition at line 4473 of file DefaultDecoderGenerator.cc.

4473 {
4474 return busMuxEnableSignal(bus) + "_reg";
4475}
static std::string busMuxEnableSignal(const TTAMachine::Bus &bus)

References busMuxEnableSignal().

Referenced by writeSocketCntrlSignals().

Here is the call graph for this function:

◆ busMuxEnableSignal()

std::string DefaultDecoderGenerator::busMuxEnableSignal ( const TTAMachine::Bus bus)
staticprivate

Definition at line 4468 of file DefaultDecoderGenerator.cc.

4468 {
4469 return bus.name() + "_src_ena";
4470}

References TTAMachine::Component::name().

Referenced by busMuxEnableRegister().

Here is the call graph for this function:

◆ completeDecoderBlock()

void DefaultDecoderGenerator::completeDecoderBlock ( const ProGe::NetlistGenerator nlGenerator,
ProGe::NetlistBlock coreBlock 
)

Completes the decoder block in the given netlist block representing the TTA core by adding the IC-interface and connecting the decoder to the interconnection network and machine building units.

Parameters
nlGeneratorThe netlist generator that generated the netlist.
coreBlockThe netlist block that contains the decoder.

Definition at line 223 of file DefaultDecoderGenerator.cc.

225 {
226 nlGenerator_ = &nlGenerator;
227 NetlistBlock& decoder = nlGenerator.instructionDecoder();
228 decoderBlock_ = &decoder;
229
230 entityNameStr_ = coreBlock.moduleName();
231
232 // add ports for short immediates to decoder and connect them to IC
234 for (int i = 0; i < busNav.count(); i++) {
235 Bus* bus = busNav.item(i);
236 if (bus->immediateWidth() > 0) {
238 bus->name());
239 NetlistPort& icSimmCntrlPort = icGenerator_.
240 simmCntrlPort(bus->name());
241 NetlistPort* decSimmPort = new NetlistPort(
242 simmDataPort(bus->name()),
245 coreBlock.netlist().connect(*decSimmPort, icSimmPort);
246 NetlistPort* decSimmCntrlPort = new NetlistPort(
247 simmControlPort(bus->name()), "1", 1, ProGe::BIT_VECTOR,
248 ProGe::OUT, decoder);
249 coreBlock.netlist().connect(*decSimmCntrlPort, icSimmCntrlPort);
250 }
251 }
252
253 // add socket control ports to decoder and connect them to IC
255 for (int i = 0; i < socketNav.count(); i++) {
256 Socket* socket = socketNav.item(i);
257 if ((socket->portCount() == 0 || socket->segmentCount() == 0) &&
258 (socket->direction() == Socket::OUTPUT)) {
259 continue;
260 }
261 if (needsBusControl(*socket)) {
262 NetlistPort* busCntrlPort = new NetlistPort(
263 socketBusControlPort(socket->name()),
266 decoder);
268 socket->name());
269 coreBlock.netlist().connect(icBusCntrlPort, *busCntrlPort);
270 }
271 if (needsDataControl(*socket)) {
272 NetlistPort* dataCntrlPort = new NetlistPort(
273 socketDataControlPort(socket->name()),
276 decoder);
277 NetlistPort& icDataCntrlPort =
279 coreBlock.netlist().connect(icDataCntrlPort, *dataCntrlPort);
280 }
281 }
282
283 // add FU control ports to decoder and connect them to the FUs
286 for (int i = 0; i < fuNav.count(); i++) {
287 FunctionUnit* fu = fuNav.item(i);
288 for (int i = 0; i < fu->portCount(); i++) {
289 BaseFUPort* port = fu->port(i);
290 NetlistPort& nlPort = nlGenerator.netlistPort(*port);
291 if (nlPort.direction() == ProGe::IN) {
292 NetlistPort& loadPort = nlGenerator.loadPort(nlPort);
293 NetlistPort* loadCntrlPort = new NetlistPort(
294 fuLoadCntrlPort(fu->name(), port->name()), "1", 1,
295 ProGe::BIT, ProGe::OUT, decoder);
296 coreBlock.netlist().connect(*loadCntrlPort, loadPort);
297 }
298 }
299
300 if (opcodeWidth(*fu) > 0) {
301 const NetlistBlock& fuBlock = nlGenerator.netlistBlock(*fu);
302 NetlistPort& opcodePort = nlGenerator.fuOpcodePort(fuBlock);
303 NetlistPort* opcodeCntrlPort = new NetlistPort(
304 fuOpcodeCntrlPort(fu->name()),
306 ProGe::BIT_VECTOR, ProGe::OUT, decoder);
307 coreBlock.netlist().connect(opcodePort, *opcodeCntrlPort);
308 }
309 }
310 // Add GCU control ports for operand ports (other than RA ports).
312 for (int i = 0; i < gcu->portCount(); i++) {
313 BaseFUPort* port = gcu->port(i);
314 if (!port->isInput() ||
315 port->name() == gcu->returnAddressPort()->name() ||
316 port->isTriggering()) {
317 continue;
318 }
319 NetlistPort& nlPort = nlGenerator.netlistPort(*port);
320 NetlistPort& loadPort = nlGenerator.loadPort(nlPort);
321 NetlistPort* loadCntrlPort = new NetlistPort(
322 fuLoadCntrlPort(gcu->name(), port->name()), "1", 1, ProGe::BIT,
323 ProGe::OUT, decoder);
324 coreBlock.netlist().connect(*loadCntrlPort, loadPort);
325 }
326
327 // add RF control ports to decoder and connect them to the RFs
330 for (int i = 0; i < rfNav.count(); i++) {
331 RegisterFile* rf = rfNav.item(i);
332 for (int i = 0; i < rf->portCount(); i++) {
333 RFPort* port = rf->port(i);
334 NetlistPort& nlPort = nlGenerator.netlistPort(*port);
335 NetlistPort& loadPort = nlGenerator.loadPort(nlPort);
336
337 NetlistPort* loadCntrlPort = new NetlistPort(
338 rfLoadCntrlPort(rf->name(), port->name()),
339 loadPort.widthFormula(), 1, ProGe::BIT, ProGe::OUT, decoder);
340
341 coreBlock.netlist().connect(loadPort, *loadCntrlPort);
342
343 int opcodeWidth = rfOpcodeWidth(*rf);
344 assert(!(!nlGenerator.hasOpcodePort(nlPort) &&
345 opcodeWidth > 1));
346 if (nlGenerator.hasOpcodePort(nlPort) && opcodeWidth >= 0) {
347 NetlistPort& opcodePort = nlGenerator.rfOpcodePort(nlPort);
348 NetlistPort* opcodeCntrlPort = new NetlistPort(
349 rfOpcodeCntrlPort(rf->name(), port->name()),
351 ProGe::BIT_VECTOR, ProGe::OUT, decoder);
352 coreBlock.netlist().connect(opcodePort, *opcodeCntrlPort);
353 }
354 }
355 }
356
357 // add IU control ports to decoder and connect them to the IU's
360 for (int i = 0; i < iuNav.count(); i++) {
361 ImmediateUnit* iu = iuNav.item(i);
362
363 // add control ports for read ports
364 for (int i = 0; i < iu->portCount(); i++) {
365 RFPort* port = iu->port(i);
366 NetlistPort& iuDataPort = nlGenerator.netlistPort(*port);
367 NetlistPort& loadPort = nlGenerator.loadPort(iuDataPort);
368 std::string portName =
369 iuReadLoadCntrlPort(iu->name(), port->name());
370 NetlistPort* loadCntrlPort = new NetlistPort(
371 portName, "1", 1, ProGe::BIT, ProGe::OUT, decoder);
372 coreBlock.netlist().connect(loadPort, *loadCntrlPort);
373
374 int opcodeWidth = rfOpcodeWidth(*iu);
375 assert(!(!nlGenerator.hasOpcodePort(iuDataPort) &&
376 opcodeWidth > 1));
377 if (nlGenerator.hasOpcodePort(iuDataPort) && opcodeWidth >= 0) {
378 NetlistPort& opcodePort = nlGenerator.rfOpcodePort(
379 iuDataPort);
380 portName = iuReadOpcodeCntrlPort(iu->name(), port->name());
381 NetlistPort* opcodeCntrlPort = new NetlistPort(
383 ProGe::BIT_VECTOR, ProGe::OUT, decoder);
384 coreBlock.netlist().connect(opcodePort, *opcodeCntrlPort);
385 }
386 }
387
388 // add IU data write port and control ports
389 NetlistPort& iuDataPort = nlGenerator.immediateUnitWritePort(*iu);
390 NetlistPort* decIUDataPort = new NetlistPort(
392 iu->width(), ProGe::BIT_VECTOR, ProGe::OUT, decoder);
393 coreBlock.netlist().connect(iuDataPort, *decIUDataPort);
394 NetlistPort& loadPort = nlGenerator.loadPort(iuDataPort);
395 NetlistPort* loadCntrlPort = new NetlistPort(
397 decoder);
398 coreBlock.netlist().connect(loadPort, *loadCntrlPort);
399
400 int opcodeWidth = rfOpcodeWidth(*iu);
401 if (nlGenerator.hasOpcodePort(iuDataPort) && opcodeWidth >= 0) {
402 NetlistPort& opcodePort = nlGenerator.rfOpcodePort(iuDataPort);
403 NetlistPort* opcodeCntrlPort = new NetlistPort(
406 ProGe::BIT_VECTOR, ProGe::OUT, decoder);
407 coreBlock.netlist().connect(opcodePort, *opcodeCntrlPort);
408 }
409 }
410
411 // add guard ports to decoder and connect them to RF's and FU's
412 std::set<PortGuard*> generatedPortGuards;
413 std::set<RegisterGuard*> generatedRegGuards;
414 for (int i = 0; i < busNav.count(); i++) {
415 Bus* bus = busNav.item(i);
416 for (int i = 0; i < bus->guardCount(); i++) {
417 Guard* guard = bus->guard(i);
418 PortGuard* portGuard = dynamic_cast<PortGuard*>(guard);
419 RegisterGuard* regGuard = dynamic_cast<RegisterGuard*>(guard);
420 if (portGuard != NULL) {
422 generatedPortGuards, *portGuard)) {
423 continue;
424 }
425 FUPort* port = portGuard->port();
426 NetlistPort& nlPort = nlGenerator.netlistPort(*port);
427 NetlistPort& nlGuardPort = nlGenerator.fuGuardPort(
428 nlPort);
429 NetlistPort* decGuardPort = new NetlistPort(
430 guardPortName(*guard), "1", 1, ProGe::BIT, ProGe::IN,
431 decoder);
432 coreBlock.netlist().connect(nlGuardPort, *decGuardPort);
433 generatedPortGuards.insert(portGuard);
434 } else if (regGuard != NULL) {
436 generatedRegGuards, *regGuard)) {
437 continue;
438 }
439 const RegisterFile* rf = regGuard->registerFile();
440 assert(rf->portCount() > 0);
441 const NetlistBlock& nlRf = nlGenerator.netlistBlock(*rf);
442 NetlistPort& nlGuardPort = nlGenerator.rfGuardPort(nlRf);
443 NetlistPort* decGuardPort = new NetlistPort(
444 guardPortName(*guard), "1", 1, ProGe::BIT, ProGe::IN,
445 decoder);
446 coreBlock.netlist().connect(
447 nlGuardPort, *decGuardPort, regGuard->registerIndex(), 0,
448 1);
449 generatedRegGuards.insert(regGuard);
450 }
451 }
452 }
453
456
457 if (generateDebugger_) {
458 /*NetlistPort* dbgResetPort = */ new NetlistPort(
459 "db_tta_nreset", "1", 1, ProGe::BIT, ProGe::IN, decoder);
460 }
461}
ProGe::NetlistPort & busCntrlPortOfSocket(const std::string &socketName) const
ProGe::NetlistPort & dataCntrlPortOfSocket(const std::string &socketName) const
ProGe::NetlistPort & simmDataPort(const std::string &busName) const
static std::string socketDataControlPort(const std::string &name)
static std::string iuWriteOpcodeCntrlPort(const std::string &unitName)
static int busControlWidth(const TTAMachine::Socket &socket)
static std::string fuLoadCntrlPort(const std::string &fuName, const std::string &portName)
static int rfOpcodeWidth(const TTAMachine::BaseRegisterFile &rf)
static std::string iuWriteLoadCntrlPort(const std::string &unitName)
static std::string rfLoadCntrlPort(const std::string &rfName, const std::string &portName)
static std::string iuReadLoadCntrlPort(const std::string &unitName, const std::string &portName)
static std::string iuWritePort(const std::string &iuName)
static std::string iuReadOpcodeCntrlPort(const std::string &unitName, const std::string &portName)
static bool containsSimilarGuard(const std::set< TTAMachine::PortGuard * > &guardSet, const TTAMachine::PortGuard &guard)
static std::string rfOpcodeCntrlPort(const std::string &rfName, const std::string &portName)
static int dataControlWidth(const TTAMachine::Socket &socket)
static std::string simmDataPort(const std::string &busName)
static std::string socketBusControlPort(const std::string &name)
static bool needsDataControl(const TTAMachine::Socket &socket)
static int simmPortWidth(const TTAMachine::Bus &bus)
static std::string fuOpcodeCntrlPort(const std::string &fu)
static std::string guardPortName(const TTAMachine::Guard &guard)
static bool needsBusControl(const TTAMachine::Socket &socket)
static std::string simmControlPort(const std::string &busName)
int opcodeWidth(const TTAMachine::FunctionUnit &fu) const
const std::string & moduleName() const
NetlistPort & fuGuardPort(const NetlistPort &fuPort) const
NetlistPort & loadPort(const NetlistPort &port) const
NetlistPort & rfOpcodePort(const NetlistPort &port) const
NetlistBlock & instructionDecoder() const
NetlistPort & immediateUnitWritePort(const TTAMachine::ImmediateUnit &iu) const
NetlistPort & netlistPort(const TTAMachine::Port &port, Direction dir=IN) const
bool hasOpcodePort(const NetlistPort &port) const
NetlistPort & fuOpcodePort(const NetlistBlock &fuBlock) const
NetlistPort & rfGuardPort(const NetlistBlock &rfBlock) const
std::string widthFormula() const
Direction direction() const
virtual bool isTriggering() const =0
virtual int width() const
virtual RFPort * port(const std::string &name) const
int immediateWidth() const
Definition Bus.cc:160
Guard * guard(int index) const
Definition Bus.cc:456
int guardCount() const
Definition Bus.cc:441
SpecialRegisterPort * returnAddressPort() const
virtual BaseFUPort * port(const std::string &name) const
virtual SocketNavigator socketNavigator() const
Definition Machine.cc:368
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
FUPort * port() const
virtual bool isInput() const
Definition Port.cc:298
virtual std::string name() const
Definition Port.cc:141
const RegisterFile * registerFile() const
int portCount() const
@ BIT
One bit.
Definition ProGeTypes.hh:47

References addGlockPortToDecoder(), addLockReqPortToDecoder(), assert, ProGe::BIT, ProGe::BIT_VECTOR, CentralizedControlICGenerator::busCntrlPortOfSocket(), busControlWidth(), TTAMachine::Machine::busNavigator(), ProGe::Netlist::connect(), containsSimilarGuard(), TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), CentralizedControlICGenerator::dataCntrlPortOfSocket(), dataControlWidth(), decoderBlock_, ProGe::NetlistPort::direction(), TTAMachine::Socket::direction(), entityNameStr_, ProGe::NetlistGenerator::fuGuardPort(), fuLoadCntrlPort(), TTAMachine::Machine::functionUnitNavigator(), fuOpcodeCntrlPort(), ProGe::NetlistGenerator::fuOpcodePort(), generateDebugger_, TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), guardPortName(), ProGe::NetlistGenerator::hasOpcodePort(), icGenerator_, TTAMachine::Machine::immediateUnitNavigator(), ProGe::NetlistGenerator::immediateUnitWritePort(), TTAMachine::Bus::immediateWidth(), ProGe::IN, ProGe::NetlistGenerator::instructionDecoder(), TTAMachine::Port::isInput(), TTAMachine::BaseFUPort::isTriggering(), TTAMachine::Machine::Navigator< ComponentType >::item(), iuReadLoadCntrlPort(), iuReadOpcodeCntrlPort(), iuWriteLoadCntrlPort(), iuWriteOpcodeCntrlPort(), iuWritePort(), ProGe::NetlistGenerator::loadPort(), machine_, ProGe::BaseNetlistBlock::moduleName(), TTAMachine::Component::name(), TTAMachine::Port::name(), needsBusControl(), needsDataControl(), ProGe::NetlistBlock::netlist(), ProGe::NetlistGenerator::netlistBlock(), ProGe::NetlistGenerator::netlistPort(), nlGenerator_, opcodeWidth(), ProGe::OUT, TTAMachine::Socket::OUTPUT, TTAMachine::PortGuard::port(), TTAMachine::BaseRegisterFile::port(), TTAMachine::FunctionUnit::port(), TTAMachine::Socket::portCount(), TTAMachine::Unit::portCount(), TTAMachine::RegisterGuard::registerFile(), TTAMachine::Machine::registerFileNavigator(), TTAMachine::RegisterGuard::registerIndex(), TTAMachine::ControlUnit::returnAddressPort(), ProGe::NetlistGenerator::rfGuardPort(), rfLoadCntrlPort(), rfOpcodeCntrlPort(), ProGe::NetlistGenerator::rfOpcodePort(), rfOpcodeWidth(), TTAMachine::Socket::segmentCount(), simmControlPort(), simmDataPort(), CentralizedControlICGenerator::simmDataPort(), simmPortWidth(), socketBusControlPort(), socketDataControlPort(), TTAMachine::Machine::socketNavigator(), Conversion::toString(), TTAMachine::BaseRegisterFile::width(), and ProGe::NetlistPort::widthFormula().

Referenced by DefaultICDecoderGenerator::completeNetlist().

◆ connectedBuses()

DefaultDecoderGenerator::BusSet DefaultDecoderGenerator::connectedBuses ( const TTAMachine::Socket socket)
staticprivate

Returns a set of buses connected to the given socket.

Parameters
socketThe socket.
Returns
The bus set.

Definition at line 4708 of file DefaultDecoderGenerator.cc.

4708 {
4709 BusSet set;
4710 int segmentCount = socket.segmentCount();
4711 for (int i = 0; i < segmentCount; i++) {
4712 set.insert(socket.segment(i)->parentBus());
4713 }
4714 return set;
4715}
std::set< TTAMachine::Bus * > BusSet
Set type for buses.
Bus * parentBus() const
Segment * segment(int index) const
Definition Socket.cc:401

References TTAMachine::Segment::parentBus(), TTAMachine::Socket::segment(), and TTAMachine::Socket::segmentCount().

Referenced by writeBusControlRulesOfOutputSocket(), writeControlRulesOfFUInputPort(), writeControlRulesOfFUOutputPort(), writeControlRulesOfRFReadPort(), writeControlRulesOfRFWritePort(), and writeRFSRAMDecodingProcess().

Here is the call graph for this function:

◆ containsSimilarGuard() [1/2]

bool DefaultDecoderGenerator::containsSimilarGuard ( const std::set< TTAMachine::PortGuard * > &  guardSet,
const TTAMachine::PortGuard guard 
)
staticprivate

Tells whether the given guard set contains similar guard to the given one. Similar means the guard refers to the same FU port.

Parameters
guardSetThe guard set.
guardThe guard.
Returns
True if the set contains similar guard, otherwise false.

Definition at line 3970 of file DefaultDecoderGenerator.cc.

3972 {
3973
3974 for (std::set<PortGuard*>::const_iterator iter = guardSet.begin();
3975 iter != guardSet.end(); iter++) {
3976 PortGuard* containedGuard = *iter;
3977 if (containedGuard->port() == guard.port()) {
3978 return true;
3979 }
3980 }
3981
3982 return false;
3983}

References TTAMachine::PortGuard::port().

Referenced by completeDecoderBlock().

Here is the call graph for this function:

◆ containsSimilarGuard() [2/2]

bool DefaultDecoderGenerator::containsSimilarGuard ( const std::set< TTAMachine::RegisterGuard * > &  guardSet,
const TTAMachine::RegisterGuard guard 
)
staticprivate

Tells whether the given guard set contains similar guard to the given one. Similar means the guard refers to the same register.

Parameters
guardSetThe guard set.
guardThe guard.
Returns
True if the set contains similar guard, otherwise false.

Definition at line 3995 of file DefaultDecoderGenerator.cc.

3997 {
3998
3999 for (std::set<RegisterGuard*>::const_iterator iter = guardSet.begin();
4000 iter != guardSet.end(); iter++) {
4001 RegisterGuard* containedGuard = *iter;
4002 if (containedGuard->registerFile() == guard.registerFile() &&
4003 containedGuard->registerIndex() == guard.registerIndex()) {
4004 return true;
4005 }
4006 }
4007
4008 return false;
4009}

References TTAMachine::RegisterGuard::registerFile(), and TTAMachine::RegisterGuard::registerIndex().

Here is the call graph for this function:

◆ dataControlWidth()

int DefaultDecoderGenerator::dataControlWidth ( const TTAMachine::Socket socket)
staticprivate

Returns the number of bits required to control from which port the data is written to the bus.

Parameters
socketThe socket.
Returns
The control width.

Definition at line 4680 of file DefaultDecoderGenerator.cc.

4680 {
4681 if (socket.direction() == Socket::OUTPUT) {
4682 return MathTools::bitLength(socket.portCount() - 1);
4683 } else {
4684 return 0;
4685 }
4686}

References MathTools::bitLength(), TTAMachine::Socket::direction(), TTAMachine::Socket::OUTPUT, and TTAMachine::Socket::portCount().

Referenced by completeDecoderBlock(), and writeSocketCntrlSignals().

Here is the call graph for this function:

◆ dstFieldSignal()

std::string DefaultDecoderGenerator::dstFieldSignal ( const std::string &  busName)
staticprivate

Returns the name of the signal for the destination field of the given bus.

Parameters
busNameName of the bus.
Returns
The name of the signal.

Definition at line 4555 of file DefaultDecoderGenerator.cc.

4555 {
4556 return "dst_" + busName;
4557}

Referenced by portCodeCondition(), rfOpcodeFromSrcOrDstField(), socketEncodingCondition(), writeControlRulesOfFUInputPort(), writeInstructionDismembering(), and writeMoveFieldSignals().

◆ findGuard() [1/2]

TTAMachine::PortGuard & DefaultDecoderGenerator::findGuard ( const FUGuardEncoding encoding) const
private

Finds the guard that is referred to by the given port guard encoding.

Parameters
encodingThe encoding.
Returns
The guard.

Definition at line 4086 of file DefaultDecoderGenerator.cc.

4086 {
4087
4088 GuardField* parent = encoding.parent();
4089 string busName = parent->parent()->name();
4090
4092 Bus* bus = busNav.item(busName);
4093 for (int i = 0; i < bus->guardCount(); i++) {
4094 Guard* guard = bus->guard(i);
4095 PortGuard* portGuard = dynamic_cast<PortGuard*>(guard);
4096 if (portGuard != NULL) {
4097 if (encoding.functionUnit() ==
4098 portGuard->port()->parentUnit()->name() &&
4099 encoding.port() == portGuard->port()->name() &&
4100 encoding.isGuardInverted() == portGuard->isInverted()) {
4101 return *portGuard;
4102 }
4103 }
4104 }
4105
4106 assert(false);
4107}
std::string port() const
std::string functionUnit() const
GuardField * parent() const
bool isGuardInverted() const
MoveSlot * parent() const
std::string name() const
Definition MoveSlot.cc:136
FunctionUnit * parentUnit() const
Definition BaseFUPort.cc:96
virtual bool isInverted() const

References assert, TTAMachine::Machine::busNavigator(), FUGuardEncoding::functionUnit(), TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), GuardEncoding::isGuardInverted(), TTAMachine::Guard::isInverted(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, MoveSlot::name(), TTAMachine::Component::name(), TTAMachine::Port::name(), GuardEncoding::parent(), GuardField::parent(), TTAMachine::BaseFUPort::parentUnit(), FUGuardEncoding::port(), and TTAMachine::PortGuard::port().

Here is the call graph for this function:

◆ findGuard() [2/2]

TTAMachine::RegisterGuard & DefaultDecoderGenerator::findGuard ( const GPRGuardEncoding encoding) const
private

Finds the guard that is referred to by the given register guard encoding.

Parameters
encodingThe encoding.
Returns
The guard.

Definition at line 4056 of file DefaultDecoderGenerator.cc.

4056 {
4057
4058 GuardField* parent = encoding.parent();
4059 string busName = parent->parent()->name();
4060
4062 Bus* bus = busNav.item(busName);
4063 for (int i = 0; i < bus->guardCount(); i++) {
4064 Guard* guard = bus->guard(i);
4065 RegisterGuard* regGuard = dynamic_cast<RegisterGuard*>(guard);
4066 if (regGuard != NULL) {
4067 if (encoding.registerFile() == regGuard->registerFile()->name()
4068 && encoding.registerIndex() == regGuard->registerIndex() &&
4069 encoding.isGuardInverted() == regGuard->isInverted()) {
4070 return *regGuard;
4071 }
4072 }
4073 }
4074
4075 assert(false);
4076}
int registerIndex() const
std::string registerFile() const

References assert, TTAMachine::Machine::busNavigator(), TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), GuardEncoding::isGuardInverted(), TTAMachine::Guard::isInverted(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, MoveSlot::name(), TTAMachine::Component::name(), GuardEncoding::parent(), GuardField::parent(), GPRGuardEncoding::registerFile(), TTAMachine::RegisterGuard::registerFile(), GPRGuardEncoding::registerIndex(), and TTAMachine::RegisterGuard::registerIndex().

Referenced by writeSquashSignalGenerationProcess().

Here is the call graph for this function:

◆ fuLoadCntrlPort()

std::string DefaultDecoderGenerator::fuLoadCntrlPort ( const std::string &  fuName,
const std::string &  portName 
)
staticprivate

Returns the name of the load control port for the given FU port.

Parameters
fuNameName of the FU.
portNameName of the FU data port.
Returns
The name of the load control port in decoder.

Definition at line 4186 of file DefaultDecoderGenerator.cc.

4188 {
4189
4190 return "fu_" + fuName + "_" + portName + "_load";
4191}

Referenced by completeDecoderBlock(), fuLoadSignalName(), and writeControlRegisterMappings().

◆ fuLoadSignalName()

std::string DefaultDecoderGenerator::fuLoadSignalName ( const std::string &  fuName,
const std::string &  portName 
)
staticprivate

Returns the name for the signal of load control port of the given FU port.

Parameters
fuNameName of the FU.
portNameName of the FU data port.
Returns
The name of the signal.

Definition at line 4203 of file DefaultDecoderGenerator.cc.

4205 {
4206
4207 return fuLoadCntrlPort(fuName, portName) + "_reg";
4208}

References fuLoadCntrlPort().

Referenced by writeControlRegisterMappings(), writeControlRulesOfFUInputPort(), and writeFUCntrlSignals().

Here is the call graph for this function:

◆ fuOpcodeCntrlPort()

std::string DefaultDecoderGenerator::fuOpcodeCntrlPort ( const std::string &  fu)
staticprivate

Returns the name of the opcode control port for the given FU.

Parameters
fuName of the FU.
Returns
The name of the opcode control port in decoder.

Definition at line 4218 of file DefaultDecoderGenerator.cc.

4218 {
4219 return "fu_" + fu + "_opc";
4220}

Referenced by completeDecoderBlock(), fuOpcodeSignalName(), and writeControlRegisterMappings().

◆ fuOpcodeSignalName()

std::string DefaultDecoderGenerator::fuOpcodeSignalName ( const std::string &  fu)
staticprivate

Returns the name for the signal of opcode control port of the given FU.

Parameters
fuName of the FU.
Returns
The name of the opcode control signal.

Definition at line 4230 of file DefaultDecoderGenerator.cc.

4230 {
4231 return fuOpcodeCntrlPort(fu) + "_reg";
4232}

References fuOpcodeCntrlPort().

Referenced by writeControlRegisterMappings(), writeControlRulesOfFUInputPort(), and writeFUCntrlSignals().

Here is the call graph for this function:

◆ gcuDataPort()

std::string DefaultDecoderGenerator::gcuDataPort ( const std::string &  nameInADF)
staticprivate

Returns the real name of the GCU data port that has the given name in ADF.

Parameters
nameInADFName of the port in ADF.

Definition at line 4628 of file DefaultDecoderGenerator.cc.

4628 {
4629 return nameInADF;
4630}

◆ generateInstructionDecoder()

void DefaultDecoderGenerator::generateInstructionDecoder ( const ProGe::NetlistGenerator nlGenerator,
const std::string &  dstDirectory 
)

Writes the instruction decoder to the given destination directory.

Parameters
dstDirectoryThe destination directory.
Exceptions
IOExceptionIf an IO error occurs.

Definition at line 666 of file DefaultDecoderGenerator.cc.

668 {
669 nlGenerator_ = &nlGenerator;
670
671 string iDecoderFile = dstDirectory
673 + ((language_==Verilog)?"decoder.v":"decoder.vhdl");
674 bool decCreated = FileSystem::createFile(iDecoderFile);
675 if (!decCreated) {
676 string errorMsg = "Unable to create file " + iDecoderFile;
677 throw IOException(__FILE__, __LINE__, __func__, errorMsg);
678 }
679 std::ofstream decoderStream(
680 iDecoderFile.c_str(), std::ofstream::out);
681 writeInstructionDecoder(decoderStream);
682 decoderStream.close();
683}
#define __func__
void writeInstructionDecoder(std::ostream &stream)
static bool createFile(const std::string &file)
static const std::string DIRECTORY_SEPARATOR
@ Verilog
Verilog.
Definition ProGeTypes.hh:42

References __func__, FileSystem::createFile(), FileSystem::DIRECTORY_SEPARATOR, language_, nlGenerator_, ProGe::Verilog, and writeInstructionDecoder().

Referenced by DefaultICDecoderGenerator::generate().

Here is the call graph for this function:

◆ glockPortWidth()

int DefaultDecoderGenerator::glockPortWidth ( ) const

Returns the width of the global lock port.

Returns
The bit width.

Definition at line 613 of file DefaultDecoderGenerator.cc.

613 {
614 int glockWidth = 0;
615
617 for (int i = 0; i < fuNav.count(); i++) {
618 FunctionUnit* fu = fuNav.item(i);
619 if (fu->portCount() == 0) {
620 continue;
621 }
622 const NetlistBlock& fuBlock = nlGenerator_->netlistBlock(*fu);
623 if (nlGenerator_->hasGlockPort(fuBlock)) {
624 glockWidth++;
625 }
626 }
627
629 for (int i = 0; i < rfNav.count(); i++) {
630 RegisterFile* rf = rfNav.item(i);
631 if (rf->portCount() == 0) {
632 continue;
633 }
634 const NetlistBlock& rfBlock = nlGenerator_->netlistBlock(*rf);
635 if (nlGenerator_->hasGlockPort(rfBlock)) {
636 glockWidth++;
637 }
638 }
639
641 for (int i = 0; i < iuNav.count(); i++) {
642 ImmediateUnit* iu = iuNav.item(i);
643 if (iu->portCount() == 0) {
644 continue;
645 }
646 const NetlistBlock& iuBlock = nlGenerator_->netlistBlock(*iu);
647 if (nlGenerator_->hasGlockPort(iuBlock)) {
648 glockWidth++;
649 }
650 }
651
653 glockWidth++;
654 }
655
656 return glockWidth;
657}

References TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::functionUnitNavigator(), CentralizedControlICGenerator::hasGlockPort(), ProGe::NetlistGenerator::hasGlockPort(), icGenerator_, TTAMachine::Machine::immediateUnitNavigator(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, ProGe::NetlistGenerator::netlistBlock(), nlGenerator_, TTAMachine::Unit::portCount(), and TTAMachine::Machine::registerFileNavigator().

Referenced by addGlockPortToDecoder(), writeGlockMapping(), and writeInstructionDecoder().

Here is the call graph for this function:

◆ glockRequestWidth()

int DefaultDecoderGenerator::glockRequestWidth ( ) const

Returns the width of the global lock request port.

Returns
The bit width.

Definition at line 585 of file DefaultDecoderGenerator.cc.

585 {
586
588
589 int lockReqWidth(0);
590 for (int i = 0; i < fuNav.count(); i++) {
591 FunctionUnit* fu = fuNav.item(i);
592 if (fu->portCount() == 0) {
593 continue;
594 }
595 const NetlistBlock& fuBlock = nlGenerator_->netlistBlock(*fu);
596 if (nlGenerator_->hasGlockReqPort(fuBlock)) {
597 lockReqWidth++;
598 }
599 }
600 if (generateDebugger_) {
601 lockReqWidth++;
602 }
603
604 return lockReqWidth;
605}

References TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::functionUnitNavigator(), generateDebugger_, ProGe::NetlistGenerator::hasGlockReqPort(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, ProGe::NetlistGenerator::netlistBlock(), nlGenerator_, and TTAMachine::Unit::portCount().

Referenced by addLockReqPortToDecoder(), DefaultICDecoderGenerator::generateDebuggerCode(), writeGlockMapping(), and writeInstructionDecoder().

Here is the call graph for this function:

◆ guardFieldSignal()

std::string DefaultDecoderGenerator::guardFieldSignal ( const std::string &  busName)
staticprivate

Returns the name of the signal for the guard field of the given bus.

Parameters
busNameName of the bus.
Returns
The name of the signal.

Definition at line 4567 of file DefaultDecoderGenerator.cc.

4567 {
4568 return "grd_" + busName;
4569}

Referenced by writeInstructionDismembering(), writeMoveFieldSignals(), and writeSquashSignalGenerationProcess().

◆ guardPortName()

std::string DefaultDecoderGenerator::guardPortName ( const TTAMachine::Guard guard)
staticprivate

Returns the name of the guard port in decoder for the given guard.

Parameters
guardThe guard.
Returns
The name of the port.

Definition at line 4492 of file DefaultDecoderGenerator.cc.

4492 {
4493 const PortGuard* portGuard = dynamic_cast<const PortGuard*>(&guard);
4494 const RegisterGuard* regGuard = dynamic_cast<const RegisterGuard*>(
4495 &guard);
4496 if (portGuard != NULL) {
4497 FUPort* port = portGuard->port();
4498 FunctionUnit* fu = port->parentUnit();
4499 return "fu_guard_" + fu->name() + "_" + port->name();
4500 } else if (regGuard != NULL) {
4501 const RegisterFile* rf = regGuard->registerFile();
4502 return "rf_guard_" + rf->name() + "_" +
4504 } else {
4505 return "";
4506 }
4507}

References TTAMachine::Component::name(), TTAMachine::Port::name(), TTAMachine::BaseFUPort::parentUnit(), TTAMachine::PortGuard::port(), TTAMachine::RegisterGuard::registerFile(), TTAMachine::RegisterGuard::registerIndex(), and Conversion::toString().

Referenced by completeDecoderBlock(), writeSquashSignalGenerationProcess(), and writeSquashSignalSubstitution().

Here is the call graph for this function:

◆ immSlotSignal()

std::string DefaultDecoderGenerator::immSlotSignal ( const std::string &  immSlot)
staticprivate

Returns the name of the signal for the given immediate slot.

Parameters
immSlotName of the immediate slot.
Returns
The name of the signal.

Definition at line 4579 of file DefaultDecoderGenerator.cc.

4579 {
4580 return "limmslot_" + immSlot;
4581}

Referenced by writeImmediateSlotSignals(), and writeInstructionDismembering().

◆ indentation()

std::string DefaultDecoderGenerator::indentation ( unsigned int  level)
staticprivate

◆ instructionTemplateCondition()

std::string DefaultDecoderGenerator::instructionTemplateCondition ( const ProGe::HDL  language,
const std::string &  iTempName 
) const
private

Returns the condition when the instruction is of the given template.

Parameters
iTempNameName of the instruction template.
Returns
The condition.

Definition at line 4822 of file DefaultDecoderGenerator.cc.

4824 {
4825
4828 assert(field.hasTemplateEncoding(iTempName));
4829 if(language==VHDL)
4830 return "conv_integer(unsigned(" + LIMM_TAG_SIGNAL + ")) = "
4831 + Conversion::toString(field.templateEncoding(iTempName));
4832 else
4833 return LIMM_TAG_SIGNAL + " == "
4834 + Conversion::toString(field.templateEncoding(iTempName));
4835}
const string LIMM_TAG_SIGNAL
ImmediateControlField & immediateControlField() const
bool hasImmediateControlField() const
unsigned int templateEncoding(const std::string &name) const
bool hasTemplateEncoding(const std::string &name) const

References assert, bem_, BinaryEncoding::hasImmediateControlField(), ImmediateControlField::hasTemplateEncoding(), BinaryEncoding::immediateControlField(), LIMM_TAG_SIGNAL, ImmediateControlField::templateEncoding(), Conversion::toString(), and ProGe::VHDL.

Referenced by writeLongImmediateWriteProcess().

Here is the call graph for this function:

◆ iuReadLoadCntrlPort()

std::string DefaultDecoderGenerator::iuReadLoadCntrlPort ( const std::string &  unitName,
const std::string &  portName 
)
staticprivate

Returns the name of the load control port of the given IU read port in in decoder.

Parameters
unitNameName of the IU.
portNameName of the read port.
Returns
The name of the load control port.

Definition at line 4356 of file DefaultDecoderGenerator.cc.

4358 {
4359
4360 return "iu_" + unitName + "_" + portName + "_read_load";
4361}

Referenced by completeDecoderBlock(), iuReadLoadCntrlSignal(), writeControlRegisterMappings(), writeControlRulesOfRFReadPort(), and writeRFCntrlSignals().

◆ iuReadLoadCntrlSignal()

std::string DefaultDecoderGenerator::iuReadLoadCntrlSignal ( const std::string &  unitName,
const std::string &  portName 
)
staticprivate

Returns the name of the load control signal of the given IU read port in in decoder.

Parameters
unitNameName of the IU.
portNameName of the read port.
Returns
The name of the load control port.

Definition at line 4373 of file DefaultDecoderGenerator.cc.

4375 {
4376
4377 return iuReadLoadCntrlPort(unitName, portName) + "_reg";
4378}

References iuReadLoadCntrlPort().

Referenced by writeControlRegisterMappings(), writeControlRulesOfRFReadPort(), and writeRFCntrlSignals().

Here is the call graph for this function:

◆ iuReadOpcodeCntrlPort()

std::string DefaultDecoderGenerator::iuReadOpcodeCntrlPort ( const std::string &  unitName,
const std::string &  portName 
)
staticprivate

Returns the name of the opcode control port of the given IU read port in decoder.

Parameters
unitNameName of the IU.
portNameName of the read port.
Returns
The name of the opcode control port.

Definition at line 4322 of file DefaultDecoderGenerator.cc.

4324 {
4325
4326 return "iu_" + unitName + "_" + portName + "_read_opc";
4327}

Referenced by completeDecoderBlock(), iuReadOpcodeCntrlSignal(), writeControlRegisterMappings(), writeControlRulesOfRFReadPort(), and writeRFCntrlSignals().

◆ iuReadOpcodeCntrlSignal()

std::string DefaultDecoderGenerator::iuReadOpcodeCntrlSignal ( const std::string &  unitName,
const std::string &  portName 
)
staticprivate

Returns the name of the opcode control signal of the given IU read port in decoder.

Parameters
unitNameName of the IU.
portNameName of the read port.
Returns
The name of the opcode control port.

Definition at line 4339 of file DefaultDecoderGenerator.cc.

4341 {
4342
4343 return iuReadOpcodeCntrlPort(unitName, portName) + "_reg";
4344}

References iuReadOpcodeCntrlPort().

Referenced by writeControlRegisterMappings(), writeControlRulesOfRFReadPort(), and writeRFCntrlSignals().

Here is the call graph for this function:

◆ iuWriteLoadCntrlPort()

std::string DefaultDecoderGenerator::iuWriteLoadCntrlPort ( const std::string &  unitName)
staticprivate

Returns the name of the load control port of the write port of the given IU in decoder.

Parameters
unitNameName of the IU.
Returns
The name of the load control port.

Definition at line 4440 of file DefaultDecoderGenerator.cc.

4440 {
4441 return iuWritePort(unitName) + "_load";
4442}

References iuWritePort().

Referenced by completeDecoderBlock(), iuWriteLoadCntrlSignal(), writeControlRegisterMappings(), writeInstructionTemplateProcedures(), and writeLongImmediateWriteProcess().

Here is the call graph for this function:

◆ iuWriteLoadCntrlSignal()

std::string DefaultDecoderGenerator::iuWriteLoadCntrlSignal ( const std::string &  unitName)
staticprivate

Returns the name of the load control Signal of the write port of the given IU in decoder.

Parameters
unitNameName of the IU.
Returns
The name of the load control port.

Definition at line 4453 of file DefaultDecoderGenerator.cc.

4453 {
4454 return iuWriteLoadCntrlPort(unitName) + "_reg";
4455}

References iuWriteLoadCntrlPort().

Referenced by writeControlRegisterMappings(), writeInstructionTemplateProcedures(), writeLongImmediateWriteProcess(), and writeRFCntrlSignals().

Here is the call graph for this function:

◆ iuWriteOpcodeCntrlPort()

std::string DefaultDecoderGenerator::iuWriteOpcodeCntrlPort ( const std::string &  unitName)
staticprivate

Returns the name of the opcode control port of the write port of the given IU in decoder.

Parameters
unitNameName of the IU.
Returns
The name of the opcode control port.

Definition at line 4413 of file DefaultDecoderGenerator.cc.

4413 {
4414 return iuWritePort(unitName) + "_opc";
4415}

References iuWritePort().

Referenced by completeDecoderBlock(), iuWriteOpcodeCntrlSignal(), writeControlRegisterMappings(), writeInstructionTemplateProcedures(), and writeLongImmediateWriteProcess().

Here is the call graph for this function:

◆ iuWriteOpcodeCntrlSignal()

std::string DefaultDecoderGenerator::iuWriteOpcodeCntrlSignal ( const std::string &  unitName)
staticprivate

Returns the name of the opcode control signal of the write port of the given IU in decoder.

Parameters
unitNameName of the IU.
Returns
The name of the opcode control port.

Definition at line 4426 of file DefaultDecoderGenerator.cc.

4427 {
4428 return iuWriteOpcodeCntrlPort(unitName) + "_reg";
4429}

References iuWriteOpcodeCntrlPort().

Referenced by writeControlRegisterMappings(), writeInstructionTemplateProcedures(), writeLongImmediateWriteProcess(), and writeRFCntrlSignals().

Here is the call graph for this function:

◆ iuWritePort()

std::string DefaultDecoderGenerator::iuWritePort ( const std::string &  iuName)
staticprivate

Returns the name of the IU write port of the given IU in decoder.

Parameters
iuNameName of the IU.
Returns
The name of the port.

Definition at line 4388 of file DefaultDecoderGenerator.cc.

4388 {
4389 return "iu_" + iuName + "_write";
4390}

Referenced by completeDecoderBlock(), iuWriteLoadCntrlPort(), iuWriteOpcodeCntrlPort(), iuWriteSignal(), writeControlRegisterMappings(), writeInstructionTemplateProcedures(), and writeLongImmediateWriteProcess().

◆ iuWriteSignal()

std::string DefaultDecoderGenerator::iuWriteSignal ( const std::string &  iuName)
staticprivate

Returns the name of the IU write signal of the given IU in decoder.

Parameters
iuNameName of the IU.
Returns
The name of the port.

Definition at line 4400 of file DefaultDecoderGenerator.cc.

4400 {
4401 return iuWritePort(iuName) + "_reg";
4402}

References iuWritePort().

Referenced by writeControlRegisterMappings(), writeInstructionTemplateProcedures(), writeLongImmediateWriteProcess(), and writeRFCntrlSignals().

Here is the call graph for this function:

◆ moveFieldSignal()

std::string DefaultDecoderGenerator::moveFieldSignal ( const std::string &  busName)
staticprivate

Returns the name of the signal for the move field of the given bus.

Definition at line 4481 of file DefaultDecoderGenerator.cc.

4481 {
4482 return "move_" + busName;
4483}

Referenced by writeInstructionDismembering(), and writeMoveFieldSignals().

◆ needsBusControl()

bool DefaultDecoderGenerator::needsBusControl ( const TTAMachine::Socket socket)
staticprivate

Tells whether the given socket needs controlling from which bus data is read or to which it is written.

Parameters
socketThe socket.
Returns
True if the socket needs controlling, otherwise false.

Definition at line 4020 of file DefaultDecoderGenerator.cc.

4020 {
4021 if (socket.segmentCount() == 0 || socket.portCount() == 0) {
4022 return false;
4023 }
4024 if (socket.segmentCount() > 1 ||
4025 (socket.segmentCount() == 1 &&
4026 socket.direction() == Socket::OUTPUT)) {
4027 return true;
4028 } else {
4029 return false;
4030 }
4031}

References TTAMachine::Socket::direction(), TTAMachine::Socket::OUTPUT, TTAMachine::Socket::portCount(), and TTAMachine::Socket::segmentCount().

Referenced by completeDecoderBlock(), writeControlRegisterMappings(), writeControlRulesOfFUInputPort(), writeControlRulesOfRFWritePort(), and writeSocketCntrlSignals().

Here is the call graph for this function:

◆ needsDataControl()

bool DefaultDecoderGenerator::needsDataControl ( const TTAMachine::Socket socket)
staticprivate

Tells whether the given output socket needs controlling from which port the data should be written to a bus.

Definition at line 4039 of file DefaultDecoderGenerator.cc.

4039 {
4040 if (socket.direction() == Socket::OUTPUT && socket.portCount() > 1) {
4041 return true;
4042 } else {
4043 return false;
4044 }
4045}

References TTAMachine::Socket::direction(), TTAMachine::Socket::OUTPUT, and TTAMachine::Socket::portCount().

Referenced by completeDecoderBlock(), writeControlRegisterMappings(), writeControlRulesOfRFReadPort(), and writeSocketCntrlSignals().

Here is the call graph for this function:

◆ opcode()

int DefaultDecoderGenerator::opcode ( const TTAMachine::HWOperation operation) const
private

Returns the opcode of the given operation.

Parameters
operationThe operation.
Returns
The opcode.

Definition at line 4906 of file DefaultDecoderGenerator.cc.

4907 {
4908
4909 string fuName = operation.parentUnit()->name();
4910 if (fuName == machine_.controlUnit()->name()) {
4911 return CUOpcodeGenerator(machine_).encoding(operation.name());
4912 } else {
4913 // This will make all opcodes based on their alphabetical order!
4914 FunctionUnit* fu =
4915 dynamic_cast<FunctionUnit*>(operation.parentUnit());
4916 std::vector<std::string> operations;
4917 for (int i = 0; i < fu->operationCount(); ++i) {
4918 operations.emplace_back(fu->operation(i)->name());
4919 }
4920 std::sort(operations.begin(), operations.end());
4921 for (size_t i = 0; i < operations.size(); ++i) {
4922 if (operations[i] == operation.name()) {
4923 return i;
4924 }
4925 }
4926 }
4927 assert(false && "should not get here");
4928 return -1; //
4929}
size_t encoding(const std::string &operName) const
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
const std::string & name() const
FunctionUnit * parentUnit() const

References assert, TTAMachine::Machine::controlUnit(), ProGe::CUOpcodeGenerator::encoding(), machine_, TTAMachine::HWOperation::name(), TTAMachine::Component::name(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), and TTAMachine::HWOperation::parentUnit().

Referenced by writeControlRulesOfFUInputPort().

Here is the call graph for this function:

◆ opcodeWidth()

int DefaultDecoderGenerator::opcodeWidth ( const TTAMachine::FunctionUnit fu) const
private

Returns the width of the opcode of the given FU.

Parameters
fuThe FU.
Returns
The width of the operation code.

Definition at line 4640 of file DefaultDecoderGenerator.cc.

4641 {
4642
4643 if (&fu == machine_.controlUnit()) {
4644 // Derive port width initially set by NetlistGenerator
4645 const NetlistBlock& gcuBlock = nlGenerator_->instructionDecoder();
4647 ->realWidth();
4648 } else {
4649 int ops = fu.operationCount();
4650 return ops > 1 ? static_cast<int>(std::ceil(std::log2(ops))) : 0;
4651 }
4652}
virtual NetlistPort * port(const std::string &portName, bool partialMatch=true)
static const std::string DECODER_PC_OPCODE_PORT
PC opcode port name in instruction decoder.
int realWidth() const

References TTAMachine::Machine::controlUnit(), ProGe::NetlistGenerator::DECODER_PC_OPCODE_PORT, ProGe::NetlistGenerator::instructionDecoder(), machine_, nlGenerator_, TTAMachine::FunctionUnit::operationCount(), ProGe::NetlistBlock::port(), and ProGe::NetlistPort::realWidth().

Referenced by completeDecoderBlock(), and writeFUCntrlSignals().

Here is the call graph for this function:

◆ portCodeCondition()

std::string DefaultDecoderGenerator::portCodeCondition ( const ProGe::HDL  language,
const SocketEncoding socketEnc,
const PortCode code 
)
staticprivate

Returns the condition when given port code of the given socket encoding is true.

Parameters
socketEncThe socket encoding;
codeThe RF port code.
Returns
The condition.

Definition at line 4772 of file DefaultDecoderGenerator.cc.

4775 {
4776
4777 // empty encoding is always true
4778 if (!code.encodingWidth()) {
4779 if (language==VHDL) {
4780 return "true";
4781 } else {
4782 return "1";
4783 }
4784 }
4785 SlotField* parent = socketEnc.parent();
4786 string signalName;
4787 if (dynamic_cast<SourceField*>(parent) != NULL) {
4788 signalName = srcFieldSignal(parent->parent()->name());
4789 } else {
4790 signalName = dstFieldSignal(parent->parent()->name());
4791 }
4792
4793 int codeStart;
4794 if (parent->componentIDPosition() == BinaryEncoding::RIGHT) {
4795 codeStart = socketEnc.socketIDWidth() + code.indexWidth();
4796 } else {
4797 codeStart = code.indexWidth();
4798 }
4799 int codeEnd = codeStart + code.encodingWidth() - 1;
4800 assert(codeEnd >= codeStart);
4801
4802 if(language==VHDL)
4803 return "conv_integer(unsigned(" + signalName + "(" +
4804 Conversion::toString(codeEnd) + " downto " +
4805 Conversion::toString(codeStart) + "))) = " +
4807 else
4808 return signalName + "[" +
4809 Conversion::toString(codeEnd) + " : " +
4810 Conversion::toString(codeStart) + "] == " +
4812}
static std::string dstFieldSignal(const std::string &busName)
static std::string srcFieldSignal(const std::string &busName)
int indexWidth() const
Definition PortCode.cc:215
int encodingWidth() const
Definition PortCode.cc:204
unsigned int encoding() const
Definition PortCode.cc:164
MoveSlot * parent() const
Definition SlotField.cc:98
BinaryEncoding::Position componentIDPosition() const
Definition SlotField.cc:296
int socketIDWidth() const
SlotField * parent() const

References assert, SlotField::componentIDPosition(), dstFieldSignal(), PortCode::encoding(), PortCode::encodingWidth(), PortCode::indexWidth(), MoveSlot::name(), SlotField::parent(), SocketEncoding::parent(), BinaryEncoding::RIGHT, SocketEncoding::socketIDWidth(), srcFieldSignal(), Conversion::toString(), and ProGe::VHDL.

Referenced by writeControlRulesOfFUInputPort(), writeControlRulesOfFUOutputPort(), writeControlRulesOfRFReadPort(), and writeControlRulesOfRFWritePort().

Here is the call graph for this function:

◆ requiredRFLatencies()

std::set< int > DefaultDecoderGenerator::requiredRFLatencies ( const TTAMachine::ImmediateUnit iu) const

Returns the set of acceptable latencies of the hardware implementation of the given immediate unit.

Parameters
iuThe immediate unit.

Definition at line 692 of file DefaultDecoderGenerator.cc.

693 {
694 int acceptableLatencies[] = {0, 1};
695 return std::set<int>(acceptableLatencies, acceptableLatencies + 2);
696}

Referenced by DefaultICDecoderGenerator::requiredRFLatencies().

◆ rfLoadCntrlPort()

std::string DefaultDecoderGenerator::rfLoadCntrlPort ( const std::string &  rfName,
const std::string &  portName 
)
staticprivate

Returns the name of the load control port of the given RF data port.

Parameters
rfNameName of the RF.
portNameName of the RF data port.
Returns
The name of the load control port in decoder.

Definition at line 4243 of file DefaultDecoderGenerator.cc.

4245 {
4246
4247 return "rf_" + rfName + "_" + portName + "_load";
4248}

Referenced by completeDecoderBlock(), rfLoadSignalName(), and writeControlRegisterMappings().

◆ rfLoadSignalName()

std::string DefaultDecoderGenerator::rfLoadSignalName ( const std::string &  rfName,
const std::string &  portName,
bool  async = false 
)
staticprivate

Returns the name for the load control signal for the given RF port.

Parameters
rfNameName of the RF.
portNameName of the RF data port.
asyncFlag to generate name for asynchronous signal. Default value is false.
Returns
The name of the signal.

Definition at line 4261 of file DefaultDecoderGenerator.cc.

4264 {
4265
4266 if (async) {
4267 return rfLoadCntrlPort(rfName, portName) + "_wire";
4268 } else {
4269 return rfLoadCntrlPort(rfName, portName) + "_reg";
4270 }
4271}

References rfLoadCntrlPort().

Referenced by writeControlRegisterMappings(), writeControlRulesOfRFReadPort(), writeControlRulesOfRFWritePort(), writeRFCntrlSignals(), and writeRFSRAMDecodingProcess().

Here is the call graph for this function:

◆ rfOpcodeCntrlPort()

std::string DefaultDecoderGenerator::rfOpcodeCntrlPort ( const std::string &  rfName,
const std::string &  portName 
)
staticprivate

Returns the name of the opcode control port of the given RF port.

Parameters
rfNameName of the RF.
portNameName of the RF data port.
Returns
The opcode control port in decoder.

Definition at line 4305 of file DefaultDecoderGenerator.cc.

4307 {
4308
4309 return "rf_" + rfName + "_" + portName + "_opc";
4310}

Referenced by completeDecoderBlock(), rfOpcodeSignalName(), and writeControlRegisterMappings().

◆ rfOpcodeFromSrcOrDstField()

std::string DefaultDecoderGenerator::rfOpcodeFromSrcOrDstField ( const ProGe::HDL  language,
const SocketEncoding socketEnc,
const PortCode code 
)
staticprivate

Returns the part of the source or destination field signal that contains the opcode of the given RF port code.

Parameters
socketEncThe socket encoding.
codeThe RF port code.
Returns
The part of the source or destination field signal.

Definition at line 4847 of file DefaultDecoderGenerator.cc.

4850 {
4851
4852 SlotField* slotField = socketEnc.parent();
4853 string signalName;
4854 if (dynamic_cast<SourceField*>(slotField) != NULL) {
4855 signalName = srcFieldSignal(slotField->parent()->name());
4856 } else {
4857 signalName = dstFieldSignal(slotField->parent()->name());
4858 }
4859
4860 int opcStart;
4861 SocketCodeTable& table = socketEnc.socketCodes();
4862 if (slotField->componentIDPosition() == BinaryEncoding::RIGHT) {
4863 opcStart = slotField->width() - table.width();
4864 } else {
4865 opcStart = 0;
4866 }
4867 int opcEnd = opcStart + code.indexWidth() - 1;
4868 if(language==VHDL)
4869 return signalName + "(" + Conversion::toString(opcEnd) + " downto " +
4870 Conversion::toString(opcStart) + ")";
4871 else
4872 return signalName + "[" + Conversion::toString(opcEnd) + " : " +
4873 Conversion::toString(opcStart) + "]";
4874}
virtual int width() const
Definition SlotField.cc:307
SocketCodeTable & socketCodes() const

References SlotField::componentIDPosition(), dstFieldSignal(), PortCode::indexWidth(), MoveSlot::name(), SlotField::parent(), SocketEncoding::parent(), BinaryEncoding::RIGHT, SocketEncoding::socketCodes(), srcFieldSignal(), Conversion::toString(), ProGe::VHDL, SlotField::width(), and SocketCodeTable::width().

Referenced by writeControlRulesOfRFReadPort(), and writeControlRulesOfRFWritePort().

Here is the call graph for this function:

◆ rfOpcodeSignalName()

std::string DefaultDecoderGenerator::rfOpcodeSignalName ( const std::string &  rfName,
const std::string &  portName,
bool  async = false 
)
staticprivate

Returns the name for the signal of opcode control port of the given RF port.

Parameters
rfNameName of the register file.
portNameName of the RF data port.
asyncFlag to generate name for asynchronous signal. Default value is false.
Returns
The name of the signal.

Definition at line 4285 of file DefaultDecoderGenerator.cc.

4288 {
4289
4290 if (async) {
4291 return rfOpcodeCntrlPort(rfName, portName) + "_wire";
4292 } else {
4293 return rfOpcodeCntrlPort(rfName, portName) + "_reg";
4294 }
4295}

References rfOpcodeCntrlPort().

Referenced by writeControlRegisterMappings(), writeControlRulesOfRFReadPort(), writeControlRulesOfRFWritePort(), writeRFCntrlSignals(), and writeRFSRAMDecodingProcess().

Here is the call graph for this function:

◆ rfOpcodeWidth()

int DefaultDecoderGenerator::rfOpcodeWidth ( const TTAMachine::BaseRegisterFile rf)
staticprivate

Returns the width of the opcode port in the given RF.

Parameters
rfThe register file.
Returns
The bit width of the opcode port.

Definition at line 4696 of file DefaultDecoderGenerator.cc.

4696 {
4697 return MathTools::bitLength(rf.numberOfRegisters() - 1);
4698}
virtual int numberOfRegisters() const

References MathTools::bitLength(), and TTAMachine::BaseRegisterFile::numberOfRegisters().

Referenced by completeDecoderBlock(), writeControlRegisterMappings(), writeInstructionTemplateProcedures(), writeLongImmediateWriteProcess(), writeRFCntrlSignals(), and writeRFSRAMDecodingProcess().

Here is the call graph for this function:

◆ sacEnabled()

bool DefaultDecoderGenerator::sacEnabled ( const std::string &  rfName) const
private

Queries if given register file by name has separate address cycle (SAC) flag enabled.

Parameters
rfNameName of register file in ADF.
Returns
Status of the SAC flag.

Definition at line 4953 of file DefaultDecoderGenerator.cc.

4954{
4955 assert(nlGenerator_ != NULL);
4956 const RFEntry& rfEntry = nlGenerator_->rfEntry(rfName);
4958}
RFImplementation & implementation() const
Definition RFEntry.cc:102
bool separateAddressCycleParameter() const
HDB::RFEntry & rfEntry(const std::string &rfName) const

References assert, HDB::RFEntry::implementation(), nlGenerator_, ProGe::NetlistGenerator::rfEntry(), and HDB::RFImplementation::separateAddressCycleParameter().

Referenced by writeControlRegisterMappings(), writeControlRulesOfRFReadPort(), writeRFCntrlSignals(), writeRFSRAMDecodingProcess(), and writeRulesForSourceControlSignals().

Here is the call graph for this function:

◆ setGenerateBusEnable()

void DefaultDecoderGenerator::setGenerateBusEnable ( bool  value)

Definition at line 192 of file DefaultDecoderGenerator.cc.

192 {
193 generateBusEnable_ = value;
194}
bool generateBusEnable_
Bus enable signals for bustrace.

References generateBusEnable_.

Referenced by DefaultICDecoderGenerator::readParameters().

◆ setGenerateDebugger()

void DefaultDecoderGenerator::setGenerateDebugger ( bool  generate)

Definition at line 182 of file DefaultDecoderGenerator.cc.

182 {
183 generateDebugger_ = generate;
184}

References generateDebugger_.

Referenced by DefaultICDecoderGenerator::readParameters().

◆ setGenerateLockTrace()

void DefaultDecoderGenerator::setGenerateLockTrace ( bool  generate)

Controls whenever global lock trace dump process will be generated.

Parameters
generateGenerate lock trace process if true.

Definition at line 759 of file DefaultDecoderGenerator.cc.

759 {
760 generateLockTrace_ = generate;
761}

References generateLockTrace_.

Referenced by DefaultICDecoderGenerator::readParameters().

◆ setGenerateNoLoopbackGlock()

void DefaultDecoderGenerator::setGenerateNoLoopbackGlock ( bool  generate)

Generates alternate global lock wiring where FU will not receive global lock back if the FU did request the lock unless there are other FUs requesting global lock.

Parameters
generateSet to true enables the feature.

Definition at line 204 of file DefaultDecoderGenerator.cc.

204 {
206}

References generateAlternateGlockReqHandling_.

Referenced by DefaultICDecoderGenerator::generate().

◆ SetHDL()

void DefaultDecoderGenerator::SetHDL ( ProGe::HDL  language)

SetHDL.

Parameters
languageThe HDL language.

Definition at line 177 of file DefaultDecoderGenerator.cc.

177 {
178 language_=language;
179}

References language_.

Referenced by DefaultICDecoderGenerator::generate().

◆ setLockTraceStartingCycle()

void DefaultDecoderGenerator::setLockTraceStartingCycle ( unsigned int  startCycle)

Sets starting cycle to begin global lock tracing.

Parameters
startCyclenth cycle to begin tracing.

Definition at line 769 of file DefaultDecoderGenerator.cc.

769 {
770 lockTraceStartingCycle_ = startCycle;
771}

References lockTraceStartingCycle_.

Referenced by DefaultICDecoderGenerator::readParameters().

◆ setSyncReset()

void DefaultDecoderGenerator::setSyncReset ( bool  value)

Definition at line 187 of file DefaultDecoderGenerator.cc.

187 {
188 syncReset_ = value;
189}
bool syncReset_
Reset synchronously (otherwise asynchronous)

References syncReset_.

Referenced by DefaultICDecoderGenerator::readParameters().

◆ simmCntrlSignalName()

std::string DefaultDecoderGenerator::simmCntrlSignalName ( const std::string &  busName)
staticprivate

Returns the name of the short immediate control signal of the given bus.

Parameters
busNameName of the bus.
Returns
The name of the signal.

Definition at line 4173 of file DefaultDecoderGenerator.cc.

4173 {
4174 return "simm_cntrl_" + busName + "_reg";
4175}

Referenced by writeBusControlRulesOfSImmSocketOfBus(), writeControlRegisterMappings(), and writeSocketCntrlSignals().

◆ simmControlPort()

std::string DefaultDecoderGenerator::simmControlPort ( const std::string &  busName)
staticprivate

Returns the name of the control port for short immediate of the given bus.

Parameters
busNameName of the bus.
Returns
The name of the port.

Definition at line 4130 of file DefaultDecoderGenerator.cc.

4130 {
4131 return "simm_cntrl_" + busName;
4132}

Referenced by completeDecoderBlock(), and writeControlRegisterMappings().

◆ simmDataPort()

std::string DefaultDecoderGenerator::simmDataPort ( const std::string &  busName)
staticprivate

Returns the name of the data port for short immediate of the given bus.

Parameters
busNameName of the bus.
Returns
The name of the port.

Definition at line 4117 of file DefaultDecoderGenerator.cc.

4117 {
4118 return "simm_" + busName;
4119}

Referenced by completeDecoderBlock(), and writeControlRegisterMappings().

◆ simmDataSignalName()

std::string DefaultDecoderGenerator::simmDataSignalName ( const std::string &  busName)
staticprivate

Returns the name of the short immediate data signal.

Parameters
busNameName of the bus that transports the short immediate.
Returns
The name of the signal.

Definition at line 4161 of file DefaultDecoderGenerator.cc.

4161 {
4162 return "simm_" + busName + "_reg";
4163}

Referenced by writeBusControlRulesOfSImmSocketOfBus(), writeControlRegisterMappings(), writeSimmDataSignal(), and writeSocketCntrlSignals().

◆ simmPortWidth()

int DefaultDecoderGenerator::simmPortWidth ( const TTAMachine::Bus bus)
staticprivate

Returns the required width of the short immediate port of the given bus.

Parameters
busThe bus.
Returns
The width of the port.

Definition at line 4142 of file DefaultDecoderGenerator.cc.

4142 {
4143 if (bus.signExtends()) {
4144 return bus.width();
4145 } else if (bus.zeroExtends()) {
4146 return bus.immediateWidth();
4147 } else {
4148 assert(false && "Unknown extension policy.");
4149 return -1;
4150 }
4151}
int width() const
Definition Bus.cc:149
bool signExtends() const
Definition Bus.cc:171
bool zeroExtends() const
Definition Bus.cc:182

References assert, TTAMachine::Bus::immediateWidth(), TTAMachine::Bus::signExtends(), TTAMachine::Bus::width(), and TTAMachine::Bus::zeroExtends().

Referenced by completeDecoderBlock(), and writeSocketCntrlSignals().

Here is the call graph for this function:

◆ socketBusCntrlSignalName()

std::string DefaultDecoderGenerator::socketBusCntrlSignalName ( const std::string &  name)
staticprivate

Returns the name of the bus connection control signal for the socket of the given name.

Parameters
nameName of the socket.
Returns
The name of the control signal.

Definition at line 4604 of file DefaultDecoderGenerator.cc.

4604 {
4605 return socketBusControlPort(name) + "_reg";
4606}

References socketBusControlPort().

Referenced by busCntrlSignalPinOfSocket(), writeControlRegisterMappings(), writeControlRulesOfFUInputPort(), writeControlRulesOfRFWritePort(), and writeSocketCntrlSignals().

Here is the call graph for this function:

◆ socketBusControlPort()

std::string DefaultDecoderGenerator::socketBusControlPort ( const std::string &  name)
staticprivate

Returns the name of the bus connection control port of the given socket.

Parameters
nameName of the socket.
Returns
The name of the control port.

Definition at line 4518 of file DefaultDecoderGenerator.cc.

4518 {
4519 return "socket_" + name + "_bus_cntrl";
4520}

Referenced by completeDecoderBlock(), socketBusCntrlSignalName(), and writeControlRegisterMappings().

◆ socketDataCntrlSignalName()

std::string DefaultDecoderGenerator::socketDataCntrlSignalName ( const std::string &  name)
staticprivate

Returns the name of the data control signal for the socket of the given name.

Parameters
nameName of the socket.
Returns
The name of the control signal.

Definition at line 4617 of file DefaultDecoderGenerator.cc.

4617 {
4618 return socketDataControlPort(name) + "_reg";
4619}

References socketDataControlPort().

Referenced by writeControlRegisterMappings(), writeControlRulesOfFUOutputPort(), writeControlRulesOfRFReadPort(), and writeSocketCntrlSignals().

Here is the call graph for this function:

◆ socketDataControlPort()

std::string DefaultDecoderGenerator::socketDataControlPort ( const std::string &  name)
staticprivate

Returns the name of the data control port of the given socket.

Parameters
nameName of the socket.
Returns
The name of the control port.

Definition at line 4530 of file DefaultDecoderGenerator.cc.

4530 {
4531 return "socket_" + name + "_data_cntrl";
4532}

Referenced by completeDecoderBlock(), socketDataCntrlSignalName(), and writeControlRegisterMappings().

◆ socketEncodingCondition()

std::string DefaultDecoderGenerator::socketEncodingCondition ( const ProGe::HDL  language,
const SlotField slotField,
const std::string &  socketName 
)
staticprivate

Returns the condition when data is transferred by the given socket in the given source field.

Parameters
srcFieldThe source field.
socketNameName of the socket.
Returns
The conditional clause.

Definition at line 4727 of file DefaultDecoderGenerator.cc.

4730 {
4731
4732 string signalName;
4733 if (dynamic_cast<const SourceField*>(&slotField) != NULL) {
4734 signalName = srcFieldSignal(slotField.parent()->name());
4735 } else {
4736 signalName = dstFieldSignal(slotField.parent()->name());
4737 }
4738 SocketEncoding& enc = slotField.socketEncoding(socketName);
4739 int start = enc.socketIDPosition();
4740 int end = start + enc.socketIDWidth() - 1;
4741 if (language == VHDL) {
4742 if (enc.socketIDWidth() == 0) {
4743 return "true";
4744 } else {
4745 return "conv_integer(unsigned(" + signalName + "("
4746 + Conversion::toString(end) + " downto "
4747 + Conversion::toString(start)
4748 + "))) = " + Conversion::toString(enc.encoding());
4749 }
4750 } else {
4751 if (enc.socketIDWidth() == 0) {
4752 return "1";
4753 } else {
4754 return signalName + "["
4755 + Conversion::toString(end) + " : "
4756 + Conversion::toString(start)
4757 + "] == " + Conversion::toString(enc.encoding());
4758 }
4759 }
4760}
unsigned int encoding() const
Definition Encoding.cc:108
SocketEncoding & socketEncoding(int index) const
Definition SlotField.cc:170
int socketIDPosition() const

References dstFieldSignal(), Encoding::encoding(), MoveSlot::name(), SlotField::parent(), SlotField::socketEncoding(), SocketEncoding::socketIDPosition(), SocketEncoding::socketIDWidth(), srcFieldSignal(), Conversion::toString(), and ProGe::VHDL.

Referenced by writeBusControlRulesOfOutputSocket(), writeControlRulesOfFUInputPort(), writeControlRulesOfFUOutputPort(), writeControlRulesOfRFReadPort(), and writeControlRulesOfRFWritePort().

Here is the call graph for this function:

◆ squashSignal()

std::string DefaultDecoderGenerator::squashSignal ( const std::string &  busName)
staticprivate

Returns the name of the squash signal for the given bus.

Parameters
busNameName of the bus.
Returns
The name of the signal.

Definition at line 4591 of file DefaultDecoderGenerator.cc.

4591 {
4592 return "squash_" + busName;
4593}

Referenced by writeBusControlRulesOfOutputSocket(), writeBusControlRulesOfSImmSocketOfBus(), writeControlRulesOfFUInputPort(), writeControlRulesOfFUOutputPort(), writeControlRulesOfRFReadPort(), writeControlRulesOfRFWritePort(), writeRFSRAMDecodingProcess(), writeSquashSignalGenerationProcess(), writeSquashSignals(), and writeSquashSignalSubstitution().

◆ srcFieldSignal()

std::string DefaultDecoderGenerator::srcFieldSignal ( const std::string &  busName)
staticprivate

Returns the name of the signal for the source field of the given bus.

Parameters
busNameName of the bus.
Returns
The name of the signal.

Definition at line 4542 of file DefaultDecoderGenerator.cc.

4542 {
4543 return "src_" + busName;
4544}

Referenced by portCodeCondition(), rfOpcodeFromSrcOrDstField(), socketEncodingCondition(), writeBusControlRulesOfSImmSocketOfBus(), writeControlRulesOfFUInputPort(), writeInstructionDismembering(), writeMoveFieldSignals(), writeRFSRAMDecodingProcess(), and writeSimmDataSignal().

◆ verifyCompatibility()

void DefaultDecoderGenerator::verifyCompatibility ( ) const

Verifies that the decoder generator is compatible with the machine.

Exceptions
InvalidDataIf the decoder generator is incompatible.

Definition at line 704 of file DefaultDecoderGenerator.cc.

704 {
705 // check that the GCU does not have other operations than the ones
706 // specified below.
708 assert(cu != NULL);
710 MachineInfo::OperationSet supportedOps{JUMP, CALL};
712 BLTUR, BGER, BGEUR, APC, CALLR};
713 MachineInfo::OperationSet unsupportedOps;
714 if (machine_.isRISCVMachine()) {
715 supportedOps.insert(riscvOps.begin(), riscvOps.end());
716 }
717 std::set_difference(
718 cuOps.begin(), cuOps.end(), supportedOps.begin(), supportedOps.end(),
719 std::inserter(unsupportedOps, unsupportedOps.begin()));
720 if (!unsupportedOps.empty()) {
721 format errorMsg(
722 "Decoder generator does not support operation %1% in CU.");
723 errorMsg % TCEString::makeString(unsupportedOps, ", ");
724 THROW_EXCEPTION(InvalidData, errorMsg.str());
725 }
726
729 string errorMsg =
730 TCEString("APC operation requires an output port in the GCU");
731 throw InvalidData(__FILE__, __LINE__, __func__, errorMsg);
732 }
733 // check that there are 3 delay slots in the transport pipeline
734 // RISC-V supports 2 "delay slots"
735 if (cu->delaySlots() != 3 &&
736 (!(cu->delaySlots() == 2 && machine_.isRISCVMachine()))) {
737 throw InvalidData(
738 __FILE__, __LINE__, __func__,
739 TCEString("Decoder generator supports only 4-stage transport ") +
740 "pipeline of CU. Given machine has " +
741 Conversion::toString(cu->delaySlots() + 1) + " stages");
742 }
743
744 // check that global guard latency is 1
745 if (!(cu->globalGuardLatency() == 0 || (cu->globalGuardLatency() == 1))) {
746 string errorMsg = TCEString("Decoder generator supports only ") +
747 "global guard latency of 1. Given machine has " +
749 throw InvalidData(__FILE__, __LINE__, __func__, errorMsg);
750 }
751}
const string CALLA
const string BLTUR
const string CALLR
const string BNER
const string BLTR
const string BGER
const string APC
const string BGEUR
const string BEQR
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
Definition Exception.hh:39
const string JUMP
const string CALL
TCETools::CIStringSet OperationSet
static OperationSet getOpset(const TTAMachine::Machine &mach)
static std::string makeString(const IterableContainer &container, const std::string &separator=", ")
int globalGuardLatency() const
bool hasOperation(const TCEString &opName) const
Definition Machine.cc:1042
bool isRISCVMachine() const
Definition Machine.cc:1057
virtual int outputPortCount(bool countBidir=false) const
Definition Unit.cc:145

References __func__, APC, assert, BEQR, BGER, BGEUR, BLTR, BLTUR, BNER, CALL, CALLA, CALLR, TTAMachine::Machine::controlUnit(), TTAMachine::ControlUnit::delaySlots(), MachineInfo::getOpset(), TTAMachine::ControlUnit::globalGuardLatency(), TTAMachine::Machine::hasOperation(), TTAMachine::Machine::isRISCVMachine(), JUMP, machine_, TCEString::makeString(), TTAMachine::Unit::outputPortCount(), THROW_EXCEPTION, and Conversion::toString().

Referenced by DefaultICDecoderGenerator::verifyCompatibility().

Here is the call graph for this function:

◆ writeBusControlRulesOfOutputSocket()

void DefaultDecoderGenerator::writeBusControlRulesOfOutputSocket ( const TTAMachine::Socket socket,
std::ostream &  stream 
) const
private

Writes the control signal rules of the given output socket.

Parameters
socketThe socket.
streamThe stream to write.

Definition at line 2731 of file DefaultDecoderGenerator.cc.

2733 {
2734
2735 assert(socket.direction() == Socket::OUTPUT);
2736 if(language_==VHDL){
2737 int indent;
2738 indent = 4;
2739 // collect to a set all the buses the socket is connected to
2741 for (BusSet::const_iterator iter = connectedBuses.begin();
2742 iter != connectedBuses.end(); iter++) {
2743 Bus* bus = *iter;
2744 MoveSlot& slot = bem_.moveSlot(bus->name());
2745 SourceField& srcField = slot.sourceField();
2746 stream << indentation(indent) << "if ("
2747 << squashSignal(bus->name()) << " = '0' and ";
2748 stream << socketEncodingCondition(VHDL, srcField, socket.name());
2749 stream << ") then" << endl;
2750 string busCntrlPin = busCntrlSignalPinOfSocket(socket, *bus);
2751 stream << indentation(indent + 1) << busCntrlPin << " <= '1';"
2752 << endl;
2753
2754 stream << indentation(indent) << "else" << endl;
2755 stream << indentation(indent + 1) << busCntrlPin << " <= '0';"
2756 << endl;
2757 stream << indentation(indent) << "end if;" << endl;
2758 }
2759 } else{
2760 // collect to a set all the buses the socket is connected to
2762 for (BusSet::const_iterator iter = connectedBuses.begin();
2763 iter != connectedBuses.end(); iter++) {
2764 Bus* bus = *iter;
2765 MoveSlot& slot = bem_.moveSlot(bus->name());
2766 SourceField& srcField = slot.sourceField();
2767 stream << indentation(4) << "if ("
2768 << squashSignal(bus->name()) << " == 0 && "
2769 << socketEncodingCondition(Verilog, srcField, socket.name()) << ")"
2770 << endl;
2771 string busCntrlPin = busCntrlSignalPinOfSocket(socket, *bus);
2772 stream << indentation(5) << busCntrlPin << " <= 1'b1;" << endl
2773 << indentation(4) << "else" << endl
2774 << indentation(5) << busCntrlPin << " <= 1'b0;" << endl << endl;
2775 }
2776 }
2777}
MoveSlot & moveSlot(int index) const
static std::string squashSignal(const std::string &busName)
static BusSet connectedBuses(const TTAMachine::Socket &socket)
static std::string socketEncodingCondition(const ProGe::HDL language, const SlotField &srcField, const std::string &socketName)
std::string busCntrlSignalPinOfSocket(const TTAMachine::Socket &socket, const TTAMachine::Bus &bus) const
SourceField & sourceField() const
Definition MoveSlot.cc:277

References assert, bem_, busCntrlSignalPinOfSocket(), connectedBuses(), TTAMachine::Socket::direction(), indentation(), language_, BinaryEncoding::moveSlot(), TTAMachine::Component::name(), TTAMachine::Socket::OUTPUT, socketEncodingCondition(), MoveSlot::sourceField(), squashSignal(), ProGe::Verilog, and ProGe::VHDL.

Referenced by writeRulesForSourceControlSignals().

Here is the call graph for this function:

◆ writeBusControlRulesOfSImmSocketOfBus()

void DefaultDecoderGenerator::writeBusControlRulesOfSImmSocketOfBus ( const TTAMachine::Bus bus,
std::ostream &  stream 
) const
private

Writes the control signal rules for the socket that transports the short immediate to the given bus.

Parameters
busThe bus.
streamThe stream to write.

Definition at line 2806 of file DefaultDecoderGenerator.cc.

2808 {
2809
2810 assert(bus.immediateWidth() > 0);
2811 MoveSlot& slot = bem_.moveSlot(bus.name());
2812 SourceField& srcField = slot.sourceField();
2813 assert(srcField.hasImmediateEncoding());
2814 ImmediateEncoding& enc = srcField.immediateEncoding();
2815
2816 if(language_==VHDL){
2817 int indent = 4;
2818 stream << indentation(indent) << "if (" << squashSignal(bus.name())
2819 << " = '0'";
2820 if (enc.encodingWidth() > 0) {
2821 stream << " and ";
2822 stream << "conv_integer(unsigned(" << srcFieldSignal(bus.name())
2823 << "(" << enc.encodingPosition() + enc.encodingWidth() - 1
2824 << " downto " << enc.encodingPosition()
2825 << "))) = " << enc.encoding();
2826 }
2827
2828 stream << ") then" << endl;
2829 stream << indentation(indent + 1) << simmCntrlSignalName(bus.name())
2830 << "(0) <= '1';" << endl;
2831 writeSimmDataSignal(bus, stream);
2832 stream << indentation(indent) << "else" << endl;
2833 stream << indentation(indent + 1) << simmCntrlSignalName(bus.name())
2834 << "(0) <= '0';" << endl;
2835 stream << indentation(4) << "end if;" << endl;
2836 } else {
2837 stream << indentation(4) << "if ("
2838 << squashSignal(bus.name()) << " == 0";
2839 if (enc.encodingWidth() > 0) {
2840 stream << " && "
2841 << srcFieldSignal(bus.name()) << "["
2842 << enc.encodingPosition() + enc.encodingWidth() - 1 << " : "
2843 << enc.encodingPosition() << "] == " << enc.encoding();
2844 }
2845 stream << ")" << endl << indentation(4) << "begin" << endl;
2846 stream << indentation(5) << simmCntrlSignalName(bus.name())
2847 << "[0] <= 1'b1;" << endl;
2848 stream << indentation(5) << simmDataSignalName(bus.name()) << " <= ";
2849
2850 if (bus.signExtends()) {
2851 stream << "$signed(";
2852 } else {
2853 stream << "$unsigned(";
2854 }
2855 stream << srcFieldSignal(bus.name()) << "["
2856 << enc.immediatePosition() + enc.immediateWidth() - 1
2857 << " : " << enc.immediatePosition() << "]);" << endl
2858 << indentation(4) << "end" << endl
2859 << indentation(4) << "else" << endl
2860 << indentation(4) << "begin" << endl
2861 << indentation(5) << simmCntrlSignalName(bus.name())
2862 << "[0] <= 1'b0;" << endl
2863 << indentation(4) << "end" << endl;
2864 }
2865}
void writeSimmDataSignal(const TTAMachine::Bus &bus, std::ostream &stream) const
static std::string simmCntrlSignalName(const std::string &busName)
static std::string simmDataSignalName(const std::string &busName)
int immediatePosition() const
ImmediateEncoding & immediateEncoding() const
bool hasImmediateEncoding() const

References assert, bem_, Encoding::encoding(), ImmediateEncoding::encodingPosition(), ImmediateEncoding::encodingWidth(), SourceField::hasImmediateEncoding(), SourceField::immediateEncoding(), ImmediateEncoding::immediatePosition(), ImmediateEncoding::immediateWidth(), TTAMachine::Bus::immediateWidth(), indentation(), language_, BinaryEncoding::moveSlot(), TTAMachine::Component::name(), TTAMachine::Bus::signExtends(), simmCntrlSignalName(), simmDataSignalName(), MoveSlot::sourceField(), squashSignal(), srcFieldSignal(), ProGe::VHDL, and writeSimmDataSignal().

Referenced by writeRulesForSourceControlSignals().

Here is the call graph for this function:

◆ writeBusMuxControlLogic()

void DefaultDecoderGenerator::writeBusMuxControlLogic ( const TTAMachine::Bus bus,
const std::set< TTAMachine::Socket * >  outputSockets,
std::ostream &  stream 
) const
private

◆ writeComment()

void DefaultDecoderGenerator::writeComment ( std::ostream &  stream,
int  indent,
std::string  comment 
) const
private

Definition at line 795 of file DefaultDecoderGenerator.cc.

796 {
797 std::string delim = language_ == VHDL ? "-- " : "// ";
798 stream << indentation(indent) << delim << comment << endl;
799}

References indentation(), language_, and ProGe::VHDL.

Referenced by writeFUCntrlSignals(), writeImmediateSlotSignals(), writeLongImmediateTagSignal(), writeMoveFieldSignals(), writeRFCntrlSignals(), writeRulesForDestinationControlSignals(), writeRulesForSourceControlSignals(), and writeSocketCntrlSignals().

Here is the call graph for this function:

◆ writeControlRegisterMappings()

void DefaultDecoderGenerator::writeControlRegisterMappings ( std::ostream &  stream) const
private

Writes the mappings of control registers to control ports to the given stream.

Parameters
streamThe stream.

Definition at line 3547 of file DefaultDecoderGenerator.cc.

3548 {
3549 if(language_==VHDL){
3550 stream << indentation(1) << "-- map control registers to outputs"
3551 << endl;
3552
3553 // map FU control signals
3555 functionUnitNavigator();
3556 for (int i = 0; i < fuNav.count(); i++) {
3557 FunctionUnit* fu = fuNav.item(i);
3558 for (int i = 0; i < fu->portCount(); i++) {
3559 BaseFUPort* port = fu->port(i);
3560 if (port->inputSocket() != NULL) {
3561 // map load signal
3562 stream << indentation(1)
3563 << fuLoadCntrlPort(fu->name(), port->name())
3564 << " <= "
3565 << fuLoadSignalName(fu->name(), port->name())
3566 << ";" << endl;
3567 }
3568 }
3569
3570 // map opcode signal
3571 if (fu->operationCount() > 1) {
3572 stream << indentation(1) << fuOpcodeCntrlPort(fu->name())
3573 << " <= " << fuOpcodeSignalName(fu->name()) << ";"
3574 << endl;
3575 }
3576 stream << endl;
3577 }
3578
3579 // map pc_load and ra_load signals
3581 if (gcu->hasReturnAddressPort()) {
3582 SpecialRegisterPort* raPort = gcu->returnAddressPort();
3584 << " <= " << fuLoadSignalName(gcu->name(), raPort->name())
3585 << ";" << endl;
3586 }
3587
3588 // find the PC port
3589 BaseFUPort* pcPort = gcu->triggerPort();
3590 if (pcPort != NULL) {
3592 << " <= " << fuLoadSignalName(gcu->name(), pcPort->name())
3593 << ";" << endl;
3594 }
3595
3596 // map pc_opcode signal
3597 if (gcu->hasOperation(JUMP) || gcu->hasOperation(CALL)) {
3598 stream << indentation(1)
3600 << " <= " << fuOpcodeSignalName(gcu->name()) << ";"
3601 << endl;
3602 }
3603
3604 // map other GCU's load signals
3605 for (int i = 0; i < gcu->portCount(); i++) {
3606 BaseFUPort* port = gcu->port(i);
3607 if (!port->isInput() ||
3608 port->name() == gcu->returnAddressPort()->name() ||
3609 port->isTriggering()) {
3610 continue;
3611 }
3612 stream << indentation(1)
3613 << fuLoadCntrlPort(gcu->name(), port->name())
3614 << " <= " << fuLoadSignalName(gcu->name(), port->name())
3615 << ";" << endl;
3616 }
3617
3618 // map other GCU's load signals
3619 for (int i = 0; i < gcu->portCount(); i++) {
3620 BaseFUPort* port = gcu->port(i);
3621 if (!port->isInput() ||
3622 port->name() == gcu->returnAddressPort()->name() ||
3623 port->isTriggering()) {
3624 continue;
3625 }
3626 stream << indentation(1)
3627 << fuLoadCntrlPort(gcu->name(), port->name())
3628 << " <= " << fuLoadSignalName(gcu->name(), port->name())
3629 << ";" << endl;
3630 }
3631
3632 // map RF control signals
3634 registerFileNavigator();
3635 for (int i = 0; i < rfNav.count(); i++) {
3636 RegisterFile* rf = rfNav.item(i);
3637
3638 for (int i = 0; i < rf->portCount(); i++) {
3639 RFPort* port = rf->port(i);
3640 bool async_signal = sacEnabled(rf->name())
3641 && port->outputSocket() != NULL;
3642
3643 // map load signal
3644 stream << indentation(1)
3645 << rfLoadCntrlPort(rf->name(), port->name()) << " <= "
3646 << rfLoadSignalName(rf->name(), port->name(),
3647 async_signal) << ";"
3648 << endl;
3649
3650 // map opcode signal
3651 bool OpcodePortExists = decoderBlock_->port(
3652 rfOpcodeCntrlPort(rf->name(), port->name()));
3653 if (OpcodePortExists) {
3654 stream << indentation(1)
3655 << rfOpcodeCntrlPort(rf->name(), port->name())
3656 << " <= "
3657 << (rfOpcodeWidth(*rf) == 0 ? "\"0\"" :
3658 rfOpcodeSignalName(rf->name(), port->name(),
3659 async_signal))
3660 << ";"
3661 << endl;
3662 }
3663 }
3664 }
3665
3666 // map IU write/read opcode signals (only 0 downto 0) to 0
3667 // TODO: mapping of these ports should probably be elsewhere
3670 for (int i = 0; i < iuNav.count(); i++) {
3671 ImmediateUnit* iu = iuNav.item(i);
3672 for (int i = 0; i < iu->portCount(); i++) {
3673 RFPort* port = iu->port(i);
3674 bool readOpcodePortExists = decoderBlock_->port(
3675 iuReadOpcodeCntrlPort(iu->name(), port->name()));
3676 bool writeOpcodePortExists =
3678 assert(readOpcodePortExists == writeOpcodePortExists);
3679 if (rfOpcodeWidth(*iu) == 0 and readOpcodePortExists and
3680 writeOpcodePortExists) {
3681
3682 stream << indentation(1)
3683 << iuReadOpcodeCntrlPort(iu->name(), port->name())
3684 << " <= \"0\";"
3685 << endl;
3686
3687 stream << indentation(1)
3689 << " <= \"0\";"
3690 << endl;
3691 }
3692 }
3693 }
3694
3695
3696 // map socket control signals
3698 for (int i = 0; i < socketNav.count(); i++) {
3699 Socket* socket = socketNav.item(i);
3700 if (socket->portCount() == 0 || socket->segmentCount() == 0) {
3701 continue;
3702 }
3703
3704 if (needsBusControl(*socket)) {
3705 stream << indentation(1) << socketBusControlPort(socket->name())
3706 << " <= " << socketBusCntrlSignalName(socket->name())
3707 << ";" << endl;
3708 }
3709 if (needsDataControl(*socket)) {
3710 stream << indentation(1) << socketDataControlPort(socket->name())
3711 << " <= " << socketDataCntrlSignalName(socket->name())
3712 << ";" << endl;
3713 }
3714 }
3715 // map short immediate signals
3717 for (int i = 0; i < busNav.count(); i++) {
3718 Bus* bus = busNav.item(i);
3719 if (bus->immediateWidth() > 0) {
3720 stream << indentation(1) << simmControlPort(bus->name())
3721 << " <= " << simmCntrlSignalName(bus->name()) << ";"
3722 << endl;
3723 if (!machine_.isRISCVMachine()) {
3724 stream << indentation(1) << simmDataPort(bus->name())
3725 << " <= " << simmDataSignalName(bus->name()) << ";"
3726 << endl;
3727 } else {
3728 stream << indentation(1) << simmDataPort(bus->name())
3729 << " <= " << RISCV_SIMM_PORT_IN_NAME << ";"
3730 << endl;
3731 }
3732 }
3733 }
3734 } else {
3735 stream << indentation(1) << "// map control registers to outputs"
3736 << endl;
3737
3738 // map FU control signals
3740 functionUnitNavigator();
3741 for (int i = 0; i < fuNav.count(); i++) {
3742 FunctionUnit* fu = fuNav.item(i);
3743 for (int i = 0; i < fu->portCount(); i++) {
3744 BaseFUPort* port = fu->port(i);
3745 if (port->inputSocket() != NULL) {
3746 // map load signal
3747 stream << indentation(1)
3748 << "assign "
3749 << fuLoadCntrlPort(fu->name(), port->name())
3750 << " = "
3751 << fuLoadSignalName(fu->name(), port->name())
3752 << ";" << endl;
3753 }
3754 }
3755
3756 // map opcode signal
3757 if (fu->operationCount() > 1) {
3758 stream << indentation(1)
3759 << "assign "
3760 << fuOpcodeCntrlPort(fu->name())
3761 << " = " << fuOpcodeSignalName(fu->name()) << ";"
3762 << endl;
3763 }
3764 stream << endl;
3765 }
3766
3767 // map pc_load and ra_load signals
3769 if (gcu->hasReturnAddressPort()) {
3770 SpecialRegisterPort* raPort = gcu->returnAddressPort();
3771 stream << indentation(1)
3772 << "assign "
3774 << " = " << fuLoadSignalName(gcu->name(), raPort->name())
3775 << ";" << endl;
3776 }
3777
3778 // find the PC port
3779 FUPort* pcPort = NULL;
3780 if (gcu->hasOperation(CALL)) {
3781 HWOperation* callOp = gcu->operation(CALL);
3782 pcPort = callOp->port(1);
3783 } else if (gcu->hasOperation(JUMP)) {
3784 HWOperation* jumpOp = gcu->operation(JUMP);
3785 pcPort = jumpOp->port(1);
3786 }
3787 if (pcPort != NULL) {
3788 stream << indentation(1)
3789 << "assign "
3791 << " = " << fuLoadSignalName(gcu->name(), pcPort->name())
3792 << ";" << endl;
3793 }
3794
3795 // map pc_opcode signal
3796 if (gcu->hasOperation(JUMP) || gcu->hasOperation(CALL)) {
3797 stream << indentation(1)
3798 << "assign "
3800 << " = " << fuOpcodeSignalName(gcu->name()) << ";" << endl;
3801 }
3802
3803 // map RF control signals
3805 registerFileNavigator();
3806 for (int i = 0; i < rfNav.count(); i++) {
3807 RegisterFile* rf = rfNav.item(i);
3808 for (int i = 0; i < rf->portCount(); i++) {
3809 RFPort* port = rf->port(i);
3810 bool async_signal = sacEnabled(rf->name())
3811 && port->outputSocket() != NULL;
3812
3813 // map load signal
3814 stream << indentation(1)
3815 << "assign "
3816 << rfLoadCntrlPort(rf->name(), port->name()) << " = "
3817 << rfLoadSignalName(rf->name(), port->name(),
3818 async_signal) << ";"
3819 << endl;
3820 // map opcode signal
3821 stream << indentation(1)
3822 << "assign "
3823 << rfOpcodeCntrlPort(rf->name(), port->name())
3824 << " = "
3825 << (rfOpcodeWidth(*rf) == 0 ? "\"0\"" :
3826 rfOpcodeSignalName(rf->name(), port->name(),
3827 async_signal))
3828 << ";"
3829 << endl;
3830 }
3831 }
3832
3835 for (int i = 0; i < iuNav.count(); i++) {
3836 ImmediateUnit* iu = iuNav.item(i);
3837 for (int i = 0; i < iu->portCount(); i++) {
3838 RFPort* port = iu->port(i);
3839
3840 stream << indentation(1) << "assign "
3841 << iuReadLoadCntrlPort(iu->name(), port->name())
3842 << " = "
3843 << iuReadLoadCntrlSignal(iu->name(), port->name())
3844 << ";" << endl;
3845 if (rfOpcodeWidth(*iu) == 0) {
3846 stream << indentation(1) << "assign "
3847 << iuReadOpcodeCntrlPort(iu->name(), port->name())
3848 << " = 1'b0;"
3849 << endl;
3850
3851 } else {
3852 stream << indentation(1) << "assign "
3853 << iuReadOpcodeCntrlPort(iu->name(), port->name())
3854 << " = "
3855 << iuReadOpcodeCntrlSignal(iu->name(), port->name())
3856 << ";" << endl;
3857
3858 }
3859 } // Loop for IU ports
3860 stream << indentation(1) << "assign "
3861 << iuWritePort(iu->name()) << " = "
3862 << iuWriteSignal(iu->name()) << ";" << endl;
3863 stream << indentation(1) << "assign "
3864 << iuWriteLoadCntrlPort(iu->name()) << " = "
3865 << iuWriteLoadCntrlSignal(iu->name()) << ";" << endl;
3866 if (rfOpcodeWidth(*iu) == 0) {
3867 stream << indentation(1) << "assign "
3869 << " = 1'b0;" << endl;
3870 } else {
3871 stream << indentation(1) << "assign "
3873 << " = "
3875 << ";" << endl;
3876 }
3877 } // Loop for IUs
3878
3879
3880 // map socket control signals
3882 for (int i = 0; i < socketNav.count(); i++) {
3883 Socket* socket = socketNav.item(i);
3884 if (socket->portCount() == 0 || socket->segmentCount() == 0) {
3885 continue;
3886 }
3887
3888 if (needsBusControl(*socket)) {
3889 stream << indentation(1)
3890 << "assign "
3891 << socketBusControlPort(socket->name())
3892 << " = " << socketBusCntrlSignalName(socket->name())
3893 << ";" << endl;
3894 }
3895 if (needsDataControl(*socket)) {
3896 stream << indentation(1)
3897 << "assign "
3898 << socketDataControlPort(socket->name())
3899 << " = " << socketDataCntrlSignalName(socket->name())
3900 << ";" << endl;
3901 }
3902 }
3903
3904 // map short immediate signals
3906 for (int i = 0; i < busNav.count(); i++) {
3907 Bus* bus = busNav.item(i);
3908 if (bus->immediateWidth() > 0) {
3909 stream << indentation(1)
3910 << "assign "
3911 << simmControlPort(bus->name())
3912 << " = " << simmCntrlSignalName(bus->name()) << ";"
3913 << endl
3914 << indentation(1)
3915 << "assign "
3916 << simmDataPort(bus->name()) << " = "
3917 << simmDataSignalName(bus->name()) << ";" << endl;
3918 }
3919 }
3920 }
3921}
static std::string iuWriteLoadCntrlSignal(const std::string &unitName)
static const std::string RISCV_SIMM_PORT_IN_NAME
static std::string iuWriteSignal(const std::string &iuName)
static std::string rfOpcodeSignalName(const std::string &rfName, const std::string &portName, bool async=false)
static std::string iuReadOpcodeCntrlSignal(const std::string &unitName, const std::string &portName)
bool sacEnabled(const std::string &rfName) const
static std::string fuOpcodeSignalName(const std::string &fu)
static std::string iuWriteOpcodeCntrlSignal(const std::string &unitName)
static std::string rfLoadSignalName(const std::string &rfName, const std::string &portName, bool async=false)
static std::string socketDataCntrlSignalName(const std::string &name)
static std::string fuLoadSignalName(const std::string &fuName, const std::string &portName)
static std::string iuReadLoadCntrlSignal(const std::string &unitName, const std::string &portName)
static const std::string DECODER_PC_LOAD_PORT
PC load port name in instruction decoder.
static const std::string DECODER_RA_LOAD_PORT
RA load port name in instruction decoder.
bool hasReturnAddressPort() const
virtual BaseFUPort * triggerPort() const
virtual bool hasOperation(const std::string &name) const
virtual FUPort * port(int operand) const
virtual Socket * outputSocket() const
Definition Port.cc:281
virtual Socket * inputSocket() const
Definition Port.cc:261

References assert, TTAMachine::Machine::busNavigator(), CALL, TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), ProGe::NetlistGenerator::DECODER_PC_LOAD_PORT, ProGe::NetlistGenerator::DECODER_PC_OPCODE_PORT, ProGe::NetlistGenerator::DECODER_RA_LOAD_PORT, decoderBlock_, fuLoadCntrlPort(), fuLoadSignalName(), fuOpcodeCntrlPort(), fuOpcodeSignalName(), TTAMachine::FunctionUnit::hasOperation(), TTAMachine::ControlUnit::hasReturnAddressPort(), TTAMachine::Machine::immediateUnitNavigator(), TTAMachine::Bus::immediateWidth(), indentation(), TTAMachine::Port::inputSocket(), TTAMachine::Port::isInput(), TTAMachine::Machine::isRISCVMachine(), TTAMachine::BaseFUPort::isTriggering(), TTAMachine::Machine::Navigator< ComponentType >::item(), iuReadLoadCntrlPort(), iuReadLoadCntrlSignal(), iuReadOpcodeCntrlPort(), iuReadOpcodeCntrlSignal(), iuWriteLoadCntrlPort(), iuWriteLoadCntrlSignal(), iuWriteOpcodeCntrlPort(), iuWriteOpcodeCntrlSignal(), iuWritePort(), iuWriteSignal(), JUMP, language_, machine_, TTAMachine::Component::name(), TTAMachine::Port::name(), needsBusControl(), needsDataControl(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), TTAMachine::Port::outputSocket(), TTAMachine::BaseRegisterFile::port(), TTAMachine::FunctionUnit::port(), ProGe::NetlistBlock::port(), TTAMachine::HWOperation::port(), TTAMachine::Socket::portCount(), TTAMachine::Unit::portCount(), TTAMachine::ControlUnit::returnAddressPort(), rfLoadCntrlPort(), rfLoadSignalName(), rfOpcodeCntrlPort(), rfOpcodeSignalName(), rfOpcodeWidth(), RISCV_SIMM_PORT_IN_NAME, sacEnabled(), TTAMachine::Socket::segmentCount(), simmCntrlSignalName(), simmControlPort(), simmDataPort(), simmDataSignalName(), socketBusCntrlSignalName(), socketBusControlPort(), socketDataCntrlSignalName(), socketDataControlPort(), TTAMachine::Machine::socketNavigator(), TTAMachine::FunctionUnit::triggerPort(), and ProGe::VHDL.

Referenced by writeInstructionDecoder().

◆ writeControlRulesOfFUInputPort()

void DefaultDecoderGenerator::writeControlRulesOfFUInputPort ( const TTAMachine::BaseFUPort port,
std::ostream &  stream 
) const
private

Writes the rules for control signals related to the given FU input port.

Parameters
portThe port.
streamThe stream to write.

Definition at line 3138 of file DefaultDecoderGenerator.cc.

3140 {
3141 int indent = 4;
3142 FunctionUnit* fu = port.parentUnit();
3143 Socket* socket = port.inputSocket();
3144 assert(socket != NULL);
3145 BusSet buses = connectedBuses(*socket);
3146 stream << indentation(indent) << "if (";
3147 if(language_==VHDL){
3148 string opcodeAssignString = "";
3149 string cntrlSignalString = "";
3150 for (BusSet::const_iterator iter = buses.begin(); iter != buses.end();
3151 iter++) {
3152 Bus* bus = *iter;
3153 MoveSlot& moveSlot = bem_.moveSlot(bus->name());
3154 DestinationField& dstField = moveSlot.destinationField();
3155 SocketEncoding& enc = dstField.socketEncoding(socket->name());
3156 stream << squashSignal(bus->name()) << " = '0' and ";
3157 stream << socketEncodingCondition(VHDL, dstField, socket->name());
3158 if (enc.hasSocketCodes()) {
3159 SocketCodeTable& scTable = enc.socketCodes();
3160 if (port.isOpcodeSetting()) {
3161 stream << ") then" << endl;
3162
3163 ControlUnit* gcu = dynamic_cast<ControlUnit*>(fu);
3164
3165 // Check
3166 bool ordered=true;
3167 for (int i = 0; i < fu->operationCount(); i++) {
3168 HWOperation* operation = fu->operation(i);
3169 FUPortCode& code = scTable.fuPortCode(
3170 fu->name(), port.name(), operation->name());
3171 if ((int)(code.encoding()) != (int)(opcode(*operation))) {
3172 ordered=false;
3173 break;
3174 }
3175 }
3176 if (!ordered) {
3177 stream << indentation(indent + 1) << "if (";
3178 for (int i = 0; i < fu->operationCount(); i++) {
3179 HWOperation* operation = fu->operation(i);
3180 FUPortCode& code = scTable.fuPortCode(
3181 fu->name(), port.name(), operation->name());
3182 stream << portCodeCondition(VHDL, enc, code) << ") then"
3183 << endl;
3184 stream
3185 << indentation(indent + 2)
3186 << fuLoadSignalName(fu->name(), port.name())
3187 << " <= '1';" << endl;
3188 if (gcu != nullptr) {
3189 if (operation->name() == JUMP) {
3190 stream << indentation(indent + 2)
3191 << fuOpcodeSignalName(fu->name())
3192 << " <= "
3193 "std_logic_vector(conv_"
3194 "unsigned(IFE_JUMP, "
3195 << fuOpcodeSignalName(fu->name())
3196 << "'length));" << endl;
3197 } else if (operation->name() == CALL) {
3198 stream << indentation(indent + 2)
3199 << fuOpcodeSignalName(fu->name())
3200 << " <= "
3201 "std_logic_vector(conv_"
3202 "unsigned(IFE_CALL, "
3203 << fuOpcodeSignalName(fu->name())
3204 << "'length));" << endl;
3205 }
3206 } else {
3207 stream << indentation(indent + 2)
3208 << fuOpcodeSignalName(fu->name())
3209 << " <= conv_std_logic_vector("
3210 << opcode(*operation) << ", "
3211 << fuOpcodeSignalName(fu->name())
3212 << "'length);" << endl;
3213 }
3214 if (i+1 < fu->operationCount()) {
3215 stream << indentation(indent + 1)
3216 << "elsif (";
3217 }
3218 }
3219 stream << indentation(indent + 1) << "else" << endl;
3220 stream << indentation(indent + 2)
3221 << fuLoadSignalName(fu->name(), port.name())
3222 << " <= '0';" << endl;
3223 stream << indentation(indent + 1) << "end if;"
3224 << endl;
3225 } else {
3226 FUPortCode& code = scTable.fuPortCode(
3227 fu->name(), port.name(), fu->operation(0)->name());
3228 SlotField* parent = enc.parent();
3229 string signalName;
3230 if (dynamic_cast<SourceField*>(parent) != NULL) {
3231 signalName = srcFieldSignal(parent->parent()->name());
3232 } else {
3233 signalName = dstFieldSignal(parent->parent()->name());
3234 }
3235
3236 int codeStart;
3237 if (parent->componentIDPosition() == BinaryEncoding::RIGHT) {
3238 codeStart = enc.socketIDWidth() + code.indexWidth();
3239 } else {
3240 codeStart = code.indexWidth();
3241 }
3242 int codeEnd = codeStart + code.encodingWidth() - 1;
3243 assert(codeEnd >= codeStart);
3244 stream << indentation(indent + 1)
3245 << fuLoadSignalName(fu->name(), port.name())
3246 << " <= '1';" << endl;
3247 opcodeAssignString =
3248 indentation(indent + 1) +
3249 fuOpcodeSignalName(fu->name()) +
3250 " <= " + signalName + "(" +
3251 Conversion::toString(codeEnd) + " downto " +
3252 Conversion::toString(codeStart) + ")" + ";";
3253 stream << opcodeAssignString << endl;
3254 }
3255 } else {
3256 FUPortCode& code = scTable.fuPortCode(
3257 fu->name(), port.name());
3258 stream << " and " << portCodeCondition(VHDL, enc, code) << ") then"
3259 << endl;
3260 stream << indentation(indent + 1)
3261 << fuLoadSignalName(fu->name(), port.name())
3262 << " <= '1';" << endl;
3263 }
3264
3265 } else {
3266 stream << ") then" << endl;
3267 stream << indentation(indent + 1)
3268 << fuLoadSignalName(fu->name(), port.name())
3269 << " <= '1';" << endl;
3270 }
3271 if (needsBusControl(*socket)) {
3272 cntrlSignalString =
3273 indentation(indent + 1) +
3274 socketBusCntrlSignalName(socket->name()) +
3275 " <= conv_std_logic_vector(" +
3277 *socket, *bus->segment(0))) +
3278 ", " + socketBusCntrlSignalName(socket->name()) +
3279 "'length);";
3280 stream << cntrlSignalString << endl;
3281 }
3282
3283 BusSet::const_iterator nextIter = iter;
3284 nextIter++;
3285 if (nextIter != buses.end()) {
3286 stream << indentation(indent) << "elsif (";
3287 };
3288 }
3289
3290 stream << indentation(indent) << "else" << endl;
3291 stream << indentation(indent + 1)
3292 << fuLoadSignalName(fu->name(), port.name()) << " <= '0';"
3293 << endl;
3294 stream << indentation(indent) << "end if;" << endl;
3295 } else { // language == Verilog
3296 for (BusSet::const_iterator iter = buses.begin(); iter != buses.end();
3297 iter++) {
3298 Bus* bus = *iter;
3299 MoveSlot& moveSlot = bem_.moveSlot(bus->name());
3300 DestinationField& dstField = moveSlot.destinationField();
3301 SocketEncoding& enc = dstField.socketEncoding(socket->name());
3302 stream << squashSignal(bus->name()) << " == 0 && "
3303 << socketEncodingCondition(Verilog, dstField, socket->name());
3304 if (enc.hasSocketCodes()) {
3305 SocketCodeTable& scTable = enc.socketCodes();
3306 if (port.isOpcodeSetting()) {
3307 stream << ")" << endl
3308 << indentation(4) << "begin" << endl
3309 << indentation(5) << "if (";
3310 for (int i = 0; i < fu->operationCount(); i++) {
3311 HWOperation* operation = fu->operation(i);
3312 FUPortCode& code = scTable.fuPortCode(
3313 fu->name(), port.name(), operation->name());
3314 stream << portCodeCondition(Verilog, enc, code) << ")"
3315 << endl
3316 << indentation(5) << "begin" << endl
3317 << indentation(6)
3318 << fuLoadSignalName(fu->name(), port.name())
3319 << " <= 1'b1;" << endl;
3320 ControlUnit* gcu = dynamic_cast<ControlUnit*>(fu);
3321 if (gcu != NULL) {
3322 if (operation->name() == JUMP) {
3323 stream << indentation(5)
3324 << fuOpcodeSignalName(fu->name())
3325 << " <= IFE_JUMP;" << endl;
3326 } else if (operation->name() == CALL) {
3327 stream << indentation(5)
3328 << fuOpcodeSignalName(fu->name())
3329 << " <= IFE_CALL;" << endl;
3330 }
3331 } else {
3332 stream << indentation(6)
3333 << fuOpcodeSignalName(fu->name())
3334 << " <= "
3335 << opcode(*operation)
3336 << ";"
3337 << endl;
3338 }
3339 if (i+1 < fu->operationCount()) {
3340 stream << indentation(5) << "end" << endl
3341 << indentation(5) << "else if (";
3342 }
3343 }
3344 stream << indentation(5) << "end" << endl
3345 << indentation(5) << "else" << endl
3346 << indentation(6)
3347 << fuLoadSignalName(fu->name(), port.name())
3348 << " <= 1'b0;"
3349 << endl;
3350 } else {
3351 FUPortCode& code = scTable.fuPortCode(
3352 fu->name(), port.name());
3353 stream << " && " << portCodeCondition(Verilog, enc, code) << ")"
3354 << endl
3355 << indentation(4) << "begin" << endl
3356 << indentation(5)
3357 << fuLoadSignalName(fu->name(), port.name())
3358 << " <= 1'b1;" << endl;
3359 }
3360 } else {
3361 stream << ")" << endl
3362 << indentation(4) << "begin" << endl
3363 << indentation(5)
3364 << fuLoadSignalName(fu->name(), port.name()) << " <= 1'b1;"
3365 << endl;
3366 ControlUnit* gcu = dynamic_cast<ControlUnit*>(fu);
3367 if (gcu != NULL) {
3368 if (gcu->hasOperation(JUMP)) {
3369 HWOperation* jumpOp = gcu->operation(JUMP);
3370 if (&port == jumpOp->port(1)) {
3371 stream << indentation(5)
3372 << fuOpcodeSignalName(fu->name())
3373 << " <= IFE_JUMP;" << endl;
3374 }
3375 }
3376 if (gcu->hasOperation(CALL)) {
3377 HWOperation* callOp = gcu->operation(CALL);
3378 if (&port == callOp->port(1)) {
3379 stream << indentation(5)
3380 << fuOpcodeSignalName(fu->name())
3381 << " <= IFE_CALL;" << endl;
3382 }
3383 }
3384 }
3385 }
3386 if (needsBusControl(*socket)) {
3387 stream << indentation(5)
3388 << socketBusCntrlSignalName(socket->name())
3389 << " <= "
3391 *socket, *bus->segment(0)) << ";"
3392 << endl;
3393 }
3394
3395 BusSet::const_iterator nextIter = iter;
3396 nextIter++;
3397 stream << indentation(4) << "end" << endl;
3398 if (nextIter != buses.end()) {
3399 stream << indentation(4) << "else if(";
3400 };
3401 }
3402
3403 stream << indentation(4) << "else" << endl;
3404 stream << indentation(5) << fuLoadSignalName(fu->name(), port.name())
3405 << " <= 1'b0;" << endl;
3406 }
3407}
virtual int inputSocketControlValue(const TTAMachine::Socket &socket, const TTAMachine::Segment &segment) const =0
static std::string portCodeCondition(const ProGe::HDL language, const SocketEncoding &socketEnc, const PortCode &code)
int opcode(const TTAMachine::HWOperation &operation) const
DestinationField & destinationField() const
Definition MoveSlot.cc:341
FUPortCode & fuPortCode(int index) const
bool hasSocketCodes() const
virtual bool isOpcodeSetting() const =0

References assert, bem_, CALL, SlotField::componentIDPosition(), connectedBuses(), MoveSlot::destinationField(), dstFieldSignal(), PortCode::encoding(), PortCode::encodingWidth(), fuLoadSignalName(), fuOpcodeSignalName(), SocketCodeTable::fuPortCode(), TTAMachine::FunctionUnit::hasOperation(), SocketEncoding::hasSocketCodes(), icGenerator_, indentation(), PortCode::indexWidth(), TTAMachine::Port::inputSocket(), CentralizedControlICGenerator::inputSocketControlValue(), TTAMachine::BaseFUPort::isOpcodeSetting(), JUMP, language_, BinaryEncoding::moveSlot(), MoveSlot::name(), TTAMachine::HWOperation::name(), TTAMachine::Component::name(), TTAMachine::Port::name(), needsBusControl(), opcode(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), SlotField::parent(), SocketEncoding::parent(), TTAMachine::BaseFUPort::parentUnit(), TTAMachine::HWOperation::port(), portCodeCondition(), BinaryEncoding::RIGHT, TTAMachine::Bus::segment(), socketBusCntrlSignalName(), SocketEncoding::socketCodes(), SlotField::socketEncoding(), socketEncodingCondition(), SocketEncoding::socketIDWidth(), squashSignal(), srcFieldSignal(), Conversion::toString(), ProGe::Verilog, and ProGe::VHDL.

Referenced by writeRulesForDestinationControlSignals().

Here is the call graph for this function:

◆ writeControlRulesOfFUOutputPort()

void DefaultDecoderGenerator::writeControlRulesOfFUOutputPort ( const TTAMachine::BaseFUPort port,
std::ostream &  stream 
) const
private

Writes the data control signal rules of the socket connected to the given FU output port.

Parameters
portThe port.
streamThe stream to write.

Definition at line 2876 of file DefaultDecoderGenerator.cc.

2878 {
2879 int indent = 4;
2880
2881 Socket* socket = port.outputSocket();
2882 assert(socket != NULL);
2884 if(language_==VHDL){
2885 for (BusSet::const_iterator iter = connectedBuses.begin();
2886 iter != connectedBuses.end(); iter++) {
2887 Bus* bus = *iter;
2888 MoveSlot& slot = bem_.moveSlot(bus->name());
2889 SourceField& srcField = slot.sourceField();
2890 SocketEncoding& enc = srcField.socketEncoding(socket->name());
2891 stream << indentation(indent) << "if ("
2892 << squashSignal(bus->name()) << " = '0' and ";
2893 stream << socketEncodingCondition(VHDL, srcField, socket->name());
2894 if (enc.hasSocketCodes()) {
2895 SocketCodeTable& scTable = enc.socketCodes();
2896 FUPortCode& code = scTable.fuPortCode(
2897 port.parentUnit()->name(), port.name());
2898 stream << " and " << portCodeCondition(VHDL, enc, code)
2899 << ") then" << endl;
2900 } else {
2901 stream << ") then" << endl;
2902 }
2903 stream << indentation(indent + 1)
2904 << socketDataCntrlSignalName(socket->name()) << " <= "
2905 << "conv_std_logic_vector("
2907 << ", " << socketDataCntrlSignalName(socket->name())
2908 << "'length);" << endl;
2909 stream << indentation(indent) << "end if;" << endl;
2910 }
2911 } else {
2912 for (BusSet::const_iterator iter = connectedBuses.begin();
2913 iter != connectedBuses.end(); iter++) {
2914 Bus* bus = *iter;
2915 MoveSlot& slot = bem_.moveSlot(bus->name());
2916 SourceField& srcField = slot.sourceField();
2917 SocketEncoding& enc = srcField.socketEncoding(socket->name());
2918 stream << indentation(indent) << "if ("
2919 << squashSignal(bus->name()) << " == 0 && "
2921 Verilog, srcField, socket->name());
2922 if (enc.hasSocketCodes()) {
2923 SocketCodeTable& scTable = enc.socketCodes();
2924 FUPortCode& code = scTable.fuPortCode(
2925 port.parentUnit()->name(), port.name());
2926 stream << " && " << portCodeCondition(Verilog, enc, code) << ")"
2927 << endl;
2928 } else {
2929 stream << ")" << endl;
2930 }
2931 stream << indentation(indent)
2932 << socketDataCntrlSignalName(socket->name()) << " <= "
2934 << ";" << endl;
2935 }
2936 }
2937}
virtual int outputSocketDataControlValue(const TTAMachine::Socket &socket, const TTAMachine::Port &port) const =0

References assert, bem_, connectedBuses(), SocketCodeTable::fuPortCode(), SocketEncoding::hasSocketCodes(), icGenerator_, indentation(), language_, BinaryEncoding::moveSlot(), TTAMachine::Component::name(), TTAMachine::Port::name(), TTAMachine::Port::outputSocket(), CentralizedControlICGenerator::outputSocketDataControlValue(), TTAMachine::BaseFUPort::parentUnit(), portCodeCondition(), SocketEncoding::socketCodes(), socketDataCntrlSignalName(), SlotField::socketEncoding(), socketEncodingCondition(), MoveSlot::sourceField(), squashSignal(), ProGe::Verilog, and ProGe::VHDL.

Referenced by writeRulesForSourceControlSignals().

Here is the call graph for this function:

◆ writeControlRulesOfRFReadPort()

void DefaultDecoderGenerator::writeControlRulesOfRFReadPort ( const TTAMachine::RFPort port,
std::ostream &  stream 
) const
private

Writes the control signal rules related to the given RF read port.

Parameters
portThe RF read port.
streamThe stream to write.

Definition at line 2947 of file DefaultDecoderGenerator.cc.

2949 {
2950 int indent = 4;
2951 assert(port.outputSocket() != NULL);
2952
2953 // Do not write load signal when port is bidirectional
2954 // (where load = write enable)
2955 bool writeLoadSignal = true;
2956 if (port.inputSocket() != NULL) {
2957 writeLoadSignal = false;
2958 }
2959
2960 Socket* socket = port.outputSocket();
2961 BaseRegisterFile* rf = port.parentUnit();
2962 bool async_signal = sacEnabled(rf->name());
2963
2964 // collect to a set all the buses the socket is connected to
2966 string opcodeString = "";
2967 if (language_ == VHDL) {
2968 for (BusSet::const_iterator iter = connectedBuses.begin();
2969 iter != connectedBuses.end();iter++) {
2970 BusSet::const_iterator nextIter = iter;
2971 nextIter++;
2972 if (iter == connectedBuses.begin()) {
2973 stream << indentation(indent) << "if (";
2974 } else {
2975 stream << indentation(indent) << "elsif (";
2976 }
2977
2978 Bus* bus = *iter;
2979 MoveSlot& slot = bem_.moveSlot(bus->name());
2980 SourceField& srcField = slot.sourceField();
2981 SocketEncoding& enc = srcField.socketEncoding(socket->name());
2982 SocketCodeTable* scTable = NULL;
2983 if (enc.hasSocketCodes()) {
2984 scTable = &enc.socketCodes();
2985 }
2986
2987 PortCode* code = NULL;
2988 if (scTable != NULL) {
2989 if (dynamic_cast<ImmediateUnit*>(rf) != NULL) {
2990 code = &scTable->iuPortCode(rf->name());
2991 } else {
2992 code = &scTable->rfPortCode(rf->name());
2993 }
2994 }
2995 stream << squashSignal(bus->name()) << " = '0' and ";
2996 stream << socketEncodingCondition(VHDL, srcField, socket->name());
2997 if (code != NULL && code->hasEncoding()) {
2998 stream << " and " << portCodeCondition(VHDL, enc, *code);
2999 }
3000 stream << ") then" << endl;
3001
3002 string loadSignalName;
3003 string opcodeSignalName;
3004 if (dynamic_cast<ImmediateUnit*>(rf) != NULL) {
3005 loadSignalName =
3006 iuReadLoadCntrlPort(rf->name(), port.name());
3007 opcodeSignalName =
3008 iuReadOpcodeCntrlPort(rf->name(), port.name());
3009 } else {
3010 loadSignalName = rfLoadSignalName(rf->name(), port.name(),
3011 async_signal);
3012 opcodeSignalName = rfOpcodeSignalName(rf->name(), port.name(),
3013 async_signal);
3014 }
3015 if (writeLoadSignal) {
3016 stream << indentation(indent + 1) << loadSignalName
3017 << " <= '1';" << endl;
3018 }
3019 if (code != NULL) {
3020 opcodeString = indentation(indent + 1) + opcodeSignalName +
3021 " <= tce_ext(" +
3022 rfOpcodeFromSrcOrDstField(VHDL, enc, *code) +
3023 ", " + opcodeSignalName + "'length);";
3024 stream << opcodeString << endl;
3025 }
3026
3027 if (needsDataControl(*socket)) {
3028 stream << indentation(indent)
3029 << socketDataCntrlSignalName(socket->name())
3030 << " <= conv_std_logic_vector("
3032 *socket, port)
3033 << ", " << socketDataCntrlSignalName(socket->name())
3034 << "'length);" << endl;
3035 }
3036 }
3037
3038 if (writeLoadSignal) {
3039 stream << indentation(indent) << "else" << endl;
3040 stream << indentation(indent + 1);
3041 if (dynamic_cast<ImmediateUnit*>(rf) != NULL) {
3042 stream << iuReadLoadCntrlPort(rf->name(), port.name());
3043 } else {
3044 stream << rfLoadSignalName(
3045 rf->name(), port.name(), async_signal);
3046 }
3047 stream << " <= '0';" << endl;
3048 }
3049 stream << indentation(indent) << "end if;" << endl;
3050 } else { // language_ == Verilog
3051 for (BusSet::const_iterator iter = connectedBuses.begin();
3052 iter != connectedBuses.end();iter++) {
3053 BusSet::const_iterator nextIter = iter;
3054 nextIter++;
3055 if (iter == connectedBuses.begin()) {
3056 stream << indentation(4) << "if (";
3057 } else {
3058 stream << indentation(4) << "else if(";
3059 }
3060
3061 Bus* bus = *iter;
3062 MoveSlot& slot = bem_.moveSlot(bus->name());
3063 SourceField& srcField = slot.sourceField();
3064 SocketEncoding& enc = srcField.socketEncoding(socket->name());
3065 SocketCodeTable* scTable = NULL;
3066 if (enc.hasSocketCodes()) {
3067 scTable = &enc.socketCodes();
3068 }
3069
3070 PortCode* code = NULL;
3071 if (scTable != NULL) {
3072 if (dynamic_cast<ImmediateUnit*>(rf) != NULL) {
3073 code = &scTable->iuPortCode(rf->name());
3074 } else {
3075 code = &scTable->rfPortCode(rf->name());
3076 }
3077 }
3078 stream << squashSignal(bus->name()) << " == 0 && "
3079 << socketEncodingCondition(Verilog, srcField, socket->name());
3080 if (code != NULL && code->hasEncoding()) {
3081 stream << " && " << portCodeCondition(Verilog, enc, *code);
3082 }
3083 stream << ")" << endl
3084 << indentation(4) << "begin" << endl;
3085
3086 string loadSignalName;
3087 string opcodeSignalName;
3088 if (dynamic_cast<ImmediateUnit*>(rf) != NULL) {
3089 loadSignalName =
3090 iuReadLoadCntrlSignal(rf->name(), port.name());
3091 opcodeSignalName =
3092 iuReadOpcodeCntrlSignal(rf->name(), port.name());
3093 } else {
3094 loadSignalName = rfLoadSignalName(rf->name(), port.name(),
3095 async_signal);
3096 opcodeSignalName = rfOpcodeSignalName(rf->name(), port.name(),
3097 async_signal);
3098 }
3099
3100 stream << indentation(5) << loadSignalName << " <= 1'b1;" << endl;
3101 if (code != NULL) {
3102 stream << indentation(5) << opcodeSignalName
3103 << " <= $unsigned("
3104 << rfOpcodeFromSrcOrDstField(Verilog, enc, *code)
3105 << ");" << endl;
3106 }
3107
3108 if (needsDataControl(*socket)) {
3109 stream << indentation(5)
3110 << socketDataCntrlSignalName(socket->name())
3111 << " <= "
3113 << ";" << endl;
3114 }
3115 stream << indentation(4) << "end" << endl;
3116 }
3117 stream << indentation(4) << "else" << endl
3118 << indentation(4) << "begin" << endl
3119 << indentation(5);
3120 if (dynamic_cast<ImmediateUnit*>(rf) != NULL) {
3121 stream << iuReadLoadCntrlSignal(rf->name(), port.name());
3122 } else {
3123 stream << rfLoadSignalName(rf->name(), port.name(), async_signal);
3124 }
3125 stream << " <= 1'b0;" << endl
3126 << indentation(4) << "end" << endl;
3127 }
3128}
static std::string rfOpcodeFromSrcOrDstField(const ProGe::HDL language, const SocketEncoding &socketEnc, const PortCode &code)
bool hasEncoding() const
Definition PortCode.cc:151
RFPortCode & rfPortCode(int index) const
IUPortCode & iuPortCode(int index) const
BaseRegisterFile * parentUnit() const
Definition RFPort.cc:93

References assert, bem_, connectedBuses(), PortCode::hasEncoding(), SocketEncoding::hasSocketCodes(), icGenerator_, indentation(), TTAMachine::Port::inputSocket(), SocketCodeTable::iuPortCode(), iuReadLoadCntrlPort(), iuReadLoadCntrlSignal(), iuReadOpcodeCntrlPort(), iuReadOpcodeCntrlSignal(), language_, BinaryEncoding::moveSlot(), TTAMachine::Component::name(), TTAMachine::Port::name(), needsDataControl(), TTAMachine::Port::outputSocket(), CentralizedControlICGenerator::outputSocketDataControlValue(), TTAMachine::RFPort::parentUnit(), portCodeCondition(), rfLoadSignalName(), rfOpcodeFromSrcOrDstField(), rfOpcodeSignalName(), SocketCodeTable::rfPortCode(), sacEnabled(), SocketEncoding::socketCodes(), socketDataCntrlSignalName(), SlotField::socketEncoding(), socketEncodingCondition(), MoveSlot::sourceField(), squashSignal(), ProGe::Verilog, and ProGe::VHDL.

Referenced by writeRFSRAMDecodingProcess(), and writeRulesForSourceControlSignals().

Here is the call graph for this function:

◆ writeControlRulesOfRFWritePort()

void DefaultDecoderGenerator::writeControlRulesOfRFWritePort ( const TTAMachine::RFPort port,
std::ostream &  stream 
) const
private

Writes the rules for control signals related to the given RF write port.

Parameters
portThe port.
streamThe stream to write.

Definition at line 3417 of file DefaultDecoderGenerator.cc.

3419 {
3420 int indent = 4;
3421 BaseRegisterFile* rf = port.parentUnit();
3422 Socket* socket = port.inputSocket();
3423 assert(socket != NULL);
3424 BusSet buses = connectedBuses(*socket);
3425 stream << indentation(indent) << "if (";
3426 if(language_==VHDL){
3427 string opcodeSignalString = "";
3428 string controlSignalString = "";
3429 for (BusSet::const_iterator iter = buses.begin(); iter != buses.end();
3430 iter++) {
3431 Bus* bus = *iter;
3432 MoveSlot& moveSlot = bem_.moveSlot(bus->name());
3433 DestinationField& dstField = moveSlot.destinationField();
3434 SocketEncoding& enc = dstField.socketEncoding(socket->name());
3435 stream << squashSignal(bus->name()) << " = '0' and ";
3436 stream << socketEncodingCondition(VHDL, dstField, socket->name());
3437 if (enc.hasSocketCodes()) {
3438 SocketCodeTable& scTable = enc.socketCodes();
3439 RFPortCode& code = scTable.rfPortCode(rf->name());
3440 if (code.hasEncoding()) {
3441 stream << " and " << portCodeCondition(VHDL, enc, code);
3442
3443 }
3444 stream << ") then" << endl;
3445 stream << indentation(indent + 1)
3446 << rfLoadSignalName(rf->name(), port.name())
3447 << " <= '1';" << endl;
3448 opcodeSignalString =
3449 indentation(indent + 1) +
3450 rfOpcodeSignalName(rf->name(), port.name()) +
3451 " <= " + rfOpcodeFromSrcOrDstField(VHDL, enc, code) + ";";
3452 stream << opcodeSignalString << endl;
3453
3454 } else {
3455 stream << ") then" << endl;
3456 stream << indentation(indent + 1)
3457 << rfLoadSignalName(rf->name(), port.name())
3458 << " <= '1';" << endl;
3459 }
3460
3461 if (needsBusControl(*socket)) {
3462 controlSignalString =
3463 indentation(indent + 1) +
3464 socketBusCntrlSignalName(socket->name()) +
3465 " <= conv_std_logic_vector(" +
3467 *socket, *bus->segment(0))) +
3468 ", " + socketBusCntrlSignalName(socket->name()) +
3469 "'length);";
3470
3471 stream << controlSignalString << endl;
3472 }
3473
3474 BusSet::const_iterator nextIter = iter;
3475 nextIter++;
3476 if (nextIter != buses.end()) {
3477 stream << indentation(indent) << "elsif (";
3478 }
3479 }
3480 stream << indentation(indent) << "else" << endl;
3481 stream << indentation(indent + 1)
3482 << rfLoadSignalName(rf->name(), port.name()) << " <= '0';"
3483 << endl;
3484 stream << indentation(indent) << "end if;" << endl;
3485 } else {
3486 for (BusSet::const_iterator iter = buses.begin(); iter != buses.end();
3487 iter++) {
3488 Bus* bus = *iter;
3489 MoveSlot& moveSlot = bem_.moveSlot(bus->name());
3490 DestinationField& dstField = moveSlot.destinationField();
3491 SocketEncoding& enc = dstField.socketEncoding(socket->name());
3492 stream << squashSignal(bus->name()) << " == 0 && "
3493 << socketEncodingCondition(Verilog, dstField, socket->name());
3494 if (enc.hasSocketCodes()) {
3495 SocketCodeTable& scTable = enc.socketCodes();
3496 RFPortCode& code = scTable.rfPortCode(rf->name());
3497 if (code.hasEncoding()) {
3498 stream << " && " << portCodeCondition(Verilog, enc, code);
3499
3500 }
3501 stream << ")" << endl
3502 << indentation(4) << "begin" << endl
3503 << indentation(5)
3504 << rfLoadSignalName(rf->name(), port.name()) << " <= 1'b1;"
3505 << endl
3506 << indentation(5)
3507 << rfOpcodeSignalName(rf->name(), port.name()) << " <= "
3508 << rfOpcodeFromSrcOrDstField(Verilog, enc, code) << ";" << endl;
3509 } else {
3510 stream << ")" << endl
3511 << indentation(4) << "begin" << endl
3512 << indentation(5)
3513 << rfLoadSignalName(rf->name(), port.name()) << " <= 1'b1;"
3514 << endl;
3515 }
3516
3517 if (needsBusControl(*socket)) {
3518 stream << indentation(5)
3519 << socketBusCntrlSignalName(socket->name())
3520 << " <= "
3522 *socket, *bus->segment(0)) << ";"
3523 << endl;
3524 }
3525
3526 BusSet::const_iterator nextIter = iter;
3527 nextIter++;
3528 stream << indentation(4) << "end" << endl;
3529 if (nextIter != buses.end()) {
3530 stream << indentation(4) << "else if (";
3531 }
3532 }
3533 stream << indentation(4) << "else" << endl
3534 << indentation(5) << rfLoadSignalName(rf->name(), port.name())
3535 << " <= 1'b0;" << endl;
3536 }
3537}

References assert, bem_, connectedBuses(), MoveSlot::destinationField(), PortCode::hasEncoding(), SocketEncoding::hasSocketCodes(), icGenerator_, indentation(), TTAMachine::Port::inputSocket(), CentralizedControlICGenerator::inputSocketControlValue(), language_, BinaryEncoding::moveSlot(), TTAMachine::Component::name(), TTAMachine::Port::name(), needsBusControl(), TTAMachine::RFPort::parentUnit(), portCodeCondition(), rfLoadSignalName(), rfOpcodeFromSrcOrDstField(), rfOpcodeSignalName(), SocketCodeTable::rfPortCode(), TTAMachine::Bus::segment(), socketBusCntrlSignalName(), SocketEncoding::socketCodes(), SlotField::socketEncoding(), socketEncodingCondition(), squashSignal(), Conversion::toString(), ProGe::Verilog, and ProGe::VHDL.

Referenced by writeRulesForDestinationControlSignals().

Here is the call graph for this function:

◆ writeDismemberingAndITDecompression()

void DefaultDecoderGenerator::writeDismemberingAndITDecompression ( std::ostream &  stream) const
private

◆ writeFUCntrlSignals() [1/2]

void DefaultDecoderGenerator::writeFUCntrlSignals ( const TTAMachine::FunctionUnit fu,
std::ostream &  stream 
)
private

Writes the control signals of the given FU to the given stream.

Parameters
fuThe FU.
streamThe stream to write.

Definition at line 1279 of file DefaultDecoderGenerator.cc.

1280 {
1281 for (int i = 0; i < fu.portCount(); i++) {
1282 BaseFUPort* port = fu.port(i);
1283
1284 if (port->inputSocket() != NULL) {
1285 // if input port
1286 std::string sigName = fuLoadSignalName(fu.name(), port->name());
1287 writeSignalDeclaration(stream, ProGe::BIT, sigName, 1);
1288 registerBits.push_back(sigName);
1289 }
1290 }
1291
1292 // write opcode signal if the FU needs opcode
1293 int opcWidth = opcodeWidth(fu);
1294 if (opcWidth > 0) {
1295 std::string sigName = fuOpcodeSignalName(fu.name());
1296 writeSignalDeclaration(stream, ProGe::BIT_VECTOR, sigName, opcWidth);
1297 registerVectors.push_back(sigName);
1298 }
1299}
void writeSignalDeclaration(std::ostream &stream, ProGe::DataType type, std::string sigName, int width) const
std::vector< std::string > registerVectors
Bookkeeping for reset-needing signals.
std::vector< std::string > registerBits

References ProGe::BIT, ProGe::BIT_VECTOR, fuLoadSignalName(), fuOpcodeSignalName(), TTAMachine::Port::inputSocket(), TTAMachine::Component::name(), TTAMachine::Port::name(), opcodeWidth(), TTAMachine::FunctionUnit::port(), TTAMachine::Unit::portCount(), registerBits, registerVectors, and writeSignalDeclaration().

Here is the call graph for this function:

◆ writeFUCntrlSignals() [2/2]

void DefaultDecoderGenerator::writeFUCntrlSignals ( std::ostream &  stream)
private

Writes the FU control signals to the given stream.

Parameters
streamThe stream.

Definition at line 1256 of file DefaultDecoderGenerator.cc.

1256 {
1257 writeComment(stream, 1, "FU control signals");
1258
1260 functionUnitNavigator();
1261 for (int i = 0; i < fuNav.count(); i++) {
1262 FunctionUnit* fu = fuNav.item(i);
1263 writeFUCntrlSignals(*fu, stream);
1264 }
1265
1266 if (machine_.controlUnit() != NULL) {
1268 writeFUCntrlSignals(*gcu, stream);
1269 }
1270}
void writeComment(std::ostream &stream, int indent, std::string comment) const
void writeFUCntrlSignals(std::ostream &stream)

References TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, writeComment(), and writeFUCntrlSignals().

Referenced by writeFUCntrlSignals(), and writeInstructionDecoder().

Here is the call graph for this function:

◆ writeFullNOPConstant()

void DefaultDecoderGenerator::writeFullNOPConstant ( std::ostream &  stream) const
private

◆ writeGlockHandlingSignals()

void DefaultDecoderGenerator::writeGlockHandlingSignals ( std::ostream &  stream) const
private

Definition at line 1386 of file DefaultDecoderGenerator.cc.

1387 {
1388 assert(language_ == VHDL && "Support for other HDL not yet implemented.");
1397}
const string INTERNAL_MERGED_GLOCK_REQ_SIGNAL
const string PRE_DECODE_MERGED_GLOCK_SIGNAL
const string POST_DECODE_MERGED_GLOCK_OUTREG
const string POST_DECODE_MERGED_GLOCK_SIGNAL

References assert, ProGe::BIT, INTERNAL_MERGED_GLOCK_REQ_SIGNAL, language_, POST_DECODE_MERGED_GLOCK_OUTREG, POST_DECODE_MERGED_GLOCK_SIGNAL, PRE_DECODE_MERGED_GLOCK_SIGNAL, ProGe::VHDL, and writeSignalDeclaration().

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeGlockMapping()

void DefaultDecoderGenerator::writeGlockMapping ( std::ostream &  stream) const
private

Generates global lock and lock request wiring.

Definition at line 2404 of file DefaultDecoderGenerator.cc.

2404 {
2405 assert(
2406 language_ == VHDL &&
2407 "writeGlockMapping() is not yet implemented "
2408 "for other HDLs.");
2409
2410 // Generate output register for core lock status signal //
2411 string propagateGlock(
2413 " <= " + POST_DECODE_MERGED_GLOCK_SIGNAL + ";");
2414 string assertGlock(POST_DECODE_MERGED_GLOCK_OUTREG + " <= '1'" + ";");
2415 if (syncReset_) {
2416 stream << " lock_reg_proc : process (clk)\n"
2417 << " begin\n"
2418 << " if (clk'event and clk = '1') then\n"
2419 << " if (rstx = '0') then\n"
2420 << " -- Locked during active reset\n"
2421 << " " << assertGlock << "\n"
2422 << " else\n"
2423 << " " << propagateGlock << "\n"
2424 << " end if;\n"
2425 << " end if;\n"
2426 << " end process lock_reg_proc;\n\n";
2427 } else {
2428 stream << " lock_reg_proc : process (clk, rstx)\n"
2429 << " begin\n"
2430 << " if (rstx = '0') then\n"
2431 << " -- Locked during active reset\n"
2432 << " " << assertGlock << "\n"
2433 << " elsif (clk'event and clk = '1') then\n"
2434 << " " << propagateGlock << "\n"
2435 << " end if;\n"
2436 << " end process lock_reg_proc;\n\n";
2437 }
2438
2439 // Generate global lock request wiring //
2440 int lockReqWidth = glockRequestWidth();
2442 << " <= " << INTERNAL_MERGED_GLOCK_REQ_SIGNAL << ";" << endl;
2443 stream << indentation(1) << INTERNAL_MERGED_GLOCK_REQ_SIGNAL << " <= ";
2444 if (lockReqWidth > 0) {
2445 for (int i = 0; i < lockReqWidth; i++) {
2446 stream << LOCK_REQ_PORT_NAME << "(" << i << ")";
2447 if (i + 1 < lockReqWidth) {
2448 stream << " or ";
2449 }
2450 }
2451 stream << ";" << endl;
2452 } else {
2453 stream << "'0';" << endl;
2454 }
2455
2458 if (lockReqWidth > 0) {
2459 stream << " or " << INTERNAL_MERGED_GLOCK_REQ_SIGNAL << ";" << endl;
2460 } else {
2461 stream << ";" << endl;
2462 }
2464 << " <= " << PRE_DECODE_MERGED_GLOCK_SIGNAL << " or "
2465 << PIPELINE_FILL_LOCK_SIGNAL << ";" << endl;
2467 << " <= " << POST_DECODE_MERGED_GLOCK_OUTREG << ";" << endl;
2468
2469 // Generate global lock wiring //
2470 const int glockWidth = glockPortWidth();
2471 for (GlockBitType glockBitToConnect = 0; glockBitToConnect < glockWidth;
2472 glockBitToConnect++) {
2473 stream << indentation(1) << GLOCK_PORT_NAME << "("
2474 << Conversion::toString(glockBitToConnect) << ") <= ";
2475
2476 // If the feature for alternate glock wiring is enabled and current
2477 // glock signal to be wired for the TTA Unit has glock request port.
2479 MapTools::containsKey(unitGlockBitMap_, glockBitToConnect) &&
2482 unitGlockBitMap_.find(glockBitToConnect)->second)) {
2483 // Specialized global lock port map to avoid self-locking of FU.
2484 // Each FU that has global lock request will not receive
2485 // global lock signal unless another FU request global lock.
2486 const Unit* associatedToGlockReq =
2487 unitGlockBitMap_.find(glockBitToConnect)->second;
2488 UnitGlockReqBitMapType::const_iterator gr_it;
2489 for (gr_it = unitGlockReqBitMap_.begin();
2490 gr_it != unitGlockReqBitMap_.end(); gr_it++) {
2491 if (gr_it->first == associatedToGlockReq) {
2492 continue;
2493 }
2494 GlockReqBitType glockReqBitToConnect = gr_it->second;
2495 stream << LOCK_REQ_PORT_NAME << "("
2496 << Conversion::toString(glockReqBitToConnect)
2497 << ") or ";
2498 }
2500 } else {
2501 // Regular global lock port map.
2502 stream << POST_DECODE_MERGED_GLOCK_SIGNAL << ";";
2503 }
2504 if (MapTools::containsKey(unitGlockBitMap_, glockBitToConnect)) {
2505 stream
2506 << " -- to "
2507 << unitGlockBitMap_.find(glockBitToConnect)->second->name();
2508 }
2509 stream << endl;
2510 }
2511}
const string PIPELINE_FILL_LOCK_SIGNAL
int GlockBitType
Types for mapping global lock and global lock request signals.
static bool containsKey(const MapType &aMap, const KeyType &aKey)
static const std::string DECODER_LOCK_REQ_OUT_PORT
Lock request out port name in instruction decoder.
static const std::string DECODER_LOCK_REQ_IN_PORT
Lock request in port name in instruction decoder.
static const std::string DECODER_LOCK_STATUS_PORT

References assert, MapTools::containsKey(), ProGe::NetlistGenerator::DECODER_LOCK_REQ_IN_PORT, ProGe::NetlistGenerator::DECODER_LOCK_REQ_OUT_PORT, ProGe::NetlistGenerator::DECODER_LOCK_STATUS_PORT, generateAlternateGlockReqHandling_, GLOCK_PORT_NAME, glockPortWidth(), glockRequestWidth(), indentation(), INTERNAL_MERGED_GLOCK_REQ_SIGNAL, language_, LOCK_REQ_PORT_NAME, TTAMachine::Component::name(), PIPELINE_FILL_LOCK_SIGNAL, POST_DECODE_MERGED_GLOCK_OUTREG, POST_DECODE_MERGED_GLOCK_SIGNAL, PRE_DECODE_MERGED_GLOCK_SIGNAL, syncReset_, Conversion::toString(), unitGlockBitMap_, unitGlockReqBitMap_, and ProGe::VHDL.

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeImmediateSlotSignals()

void DefaultDecoderGenerator::writeImmediateSlotSignals ( std::ostream &  stream) const
private

Writes the signals for dedicated immediate slots to the given stream.

Parameters
streamThe stream.

Definition at line 1135 of file DefaultDecoderGenerator.cc.

1136 {
1137 writeComment(stream, 1, "signals for dedicated immediate slots");
1138 for (int i = 0; i < bem_.immediateSlotCount(); i++) {
1141 stream, ProGe::BIT_VECTOR, immSlotSignal(slot.name()),
1142 slot.width());
1143 }
1144}
int immediateSlotCount() const
ImmediateSlotField & immediateSlot(int index) const
static std::string immSlotSignal(const std::string &immSlot)
virtual int width() const
std::string name() const

References bem_, ProGe::BIT_VECTOR, BinaryEncoding::immediateSlot(), BinaryEncoding::immediateSlotCount(), immSlotSignal(), ImmediateSlotField::name(), ImmediateSlotField::width(), writeComment(), and writeSignalDeclaration().

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeInstructionDecoder()

void DefaultDecoderGenerator::writeInstructionDecoder ( std::ostream &  stream)
private

Writes the instruction decoder to the given stream.

Parameters
streamThe stream.

Definition at line 807 of file DefaultDecoderGenerator.cc.

807 {
808 if (language_ == VHDL) {
809 stream << "library IEEE;" << endl;
810 stream << "use IEEE.std_logic_1164.all;" << endl;
811 stream << "use IEEE.std_logic_arith.all;" << endl;
812 if (generateLockTrace_) {
813 stream << "use STD.textio.all;" << endl;
814 }
815 stream << "use work." << entityNameStr_ << "_globals.all;" << endl;
816 stream << "use work." << entityNameStr_ << "_gcu_opcodes.all;"
817 << endl;
818 stream << "use work.tce_util.all;" << endl << endl;
819
820 string entityName = entityNameStr_ + "_decoder";
821 stream << "entity " << entityName << " is" << endl << endl;
822
823 // create generic and port declarations
825 *decoderBlock_, 1, indentation(1), stream);
827 *decoderBlock_, 1, indentation(1), stream);
828
829 stream << endl;
830 stream << "end " << entityName << ";" << endl << endl;
831 string architectureName = "rtl_andor";
832 stream << "architecture " << architectureName << " of " << entityName
833 << " is" << endl << endl;
834
835 writeMoveFieldSignals(stream);
836 stream << endl;
838 stream << endl;
840 stream << endl;
841 writeSquashSignals(stream);
842 stream << endl;
844 stream << endl;
845 writeFUCntrlSignals(stream);
846 stream << endl;
847 writeRFCntrlSignals(stream);
848 stream << endl;
850 stream << endl;
852
853 stream << "begin" << endl << endl;
854
855 if (generateLockTrace_) {
856 writeLockDumpCode(stream);
857 stream << endl;
858 }
859
861 stream << endl;
863 stream << endl;
865 stream << endl;
867 stream << endl;
869 stream << endl;
871 stream << endl;
872 writeGlockMapping(stream);
873 stream << endl;
875
876 stream << endl << "end " << architectureName << ";" << endl;
877 } else { //language_ == Verilog
878 const std::string DS = FileSystem::DIRECTORY_SEPARATOR;
879 string entityName = entityNameStr_ + "_decoder";
880 stream << "`timescale 1ns/1ns" << endl
881 << "module " << entityName << endl
882 << "#(" << endl
883 << "`include \""
884 << entityNameStr_ << "_globals_pkg.vh\"" << endl
885 << "," << endl
886 << "`include \"" << "gcu_opcodes_pkg.vh\"" << endl
887 << ")" << endl;
888
890 *decoderBlock_, 1, indentation(1), stream);
891
892 // create generic and port declarations
894 *decoderBlock_, 1, indentation(1), stream);
895
896 stream << endl;
897
898 writeMoveFieldSignals(stream);
899 stream << endl;
901 stream << endl;
903 stream << endl;
904 writeSquashSignals(stream);
905 stream << endl;
907 stream << endl;
908 writeFUCntrlSignals(stream);
909 stream << endl;
910 writeRFCntrlSignals(stream);
911 stream << endl;
912
913 if (generateLockTrace_) {
914 writeLockDumpCode(stream);
915 stream << endl;
916 }
917
919 stream << endl;
921 stream << endl;
923 stream << endl;
925 stream << endl;
927 stream << endl;
929 stream << endl;
930
931 int lockReqWidth = glockRequestWidth();
932 stream << indentation(1) << "assign "
934 if (lockReqWidth > 0) {
935 for (int i = 0; i < lockReqWidth; i++) {
936 stream << LOCK_REQ_PORT_NAME << "[" << i << "]";
937 if (i+1 < lockReqWidth) {
938 stream << " | ";
939 }
940 }
941 stream << ";" << endl;
942 } else {
943 stream << "1'b0;" << endl;
944 }
945
946 const int glockWidth = glockPortWidth();
947 stream << indentation(1) << "assign " << GLOCK_PORT_NAME << " = {"
948 << Conversion::toString(glockWidth) << "{"
950 << endl;
951 stream << endl << "endmodule" << endl;
952 }
953}
#define DS
void writeImmediateSlotSignals(std::ostream &stream) const
void writeMainDecodingProcess(std::ostream &stream) const
void writeInstructionDismembering(std::ostream &stream) const
void writeLongImmediateWriteProcess(std::ostream &stream) const
void writeRFSRAMDecodingProcess(std::ostream &stream) const
void writeGlockHandlingSignals(std::ostream &stream) const
void writeSquashSignalGenerationProcesses(std::ostream &stream) const
void writePipelineFillProcess(std::ostream &stream) const
void writeSocketCntrlSignals(std::ostream &stream)
void writeSquashSignals(std::ostream &stream) const
void writePipelineFillSignals(std::ostream &stream) const
void writeMoveFieldSignals(std::ostream &stream) const
void writeLockDumpCode(std::ostream &stream) const
void writeDecompressSignalsVHDL(std::ostream& stream) const; TBR
void writeGlockMapping(std::ostream &stream) const
void writeRFCntrlSignals(std::ostream &stream)
void writeLongImmediateTagSignal(std::ostream &stream) const
void writeControlRegisterMappings(std::ostream &stream) const
static void writePortDeclaration(const BaseNetlistBlock &block, unsigned int indentationLevel, const std::string &indentation, std::ostream &stream)
static void writeGenericDeclaration(const BaseNetlistBlock &block, unsigned int indentationLevel, const std::string &indentation, std::ostream &stream)
static void writeGenericDeclaration(const BaseNetlistBlock &block, unsigned int indentationLevel, const std::string &indentation, std::ostream &stream)
static void writePortDeclaration(const BaseNetlistBlock &block, unsigned int indentationLevel, const std::string &indentation, std::ostream &stream)

References ProGe::NetlistGenerator::DECODER_LOCK_REQ_IN_PORT, ProGe::NetlistGenerator::DECODER_LOCK_REQ_OUT_PORT, decoderBlock_, FileSystem::DIRECTORY_SEPARATOR, DS, entityNameStr_, generateLockTrace_, GLOCK_PORT_NAME, glockPortWidth(), glockRequestWidth(), indentation(), language_, LOCK_REQ_PORT_NAME, Conversion::toString(), ProGe::VHDL, writeControlRegisterMappings(), writeFUCntrlSignals(), ProGe::VerilogNetlistWriter::writeGenericDeclaration(), ProGe::VHDLNetlistWriter::writeGenericDeclaration(), writeGlockHandlingSignals(), writeGlockMapping(), writeImmediateSlotSignals(), writeInstructionDismembering(), writeLockDumpCode(), writeLongImmediateTagSignal(), writeLongImmediateWriteProcess(), writeMainDecodingProcess(), writeMoveFieldSignals(), writePipelineFillProcess(), writePipelineFillSignals(), ProGe::VerilogNetlistWriter::writePortDeclaration(), ProGe::VHDLNetlistWriter::writePortDeclaration(), writeRFCntrlSignals(), writeRFSRAMDecodingProcess(), writeSocketCntrlSignals(), writeSquashSignalGenerationProcesses(), and writeSquashSignals().

Referenced by generateInstructionDecoder().

Here is the call graph for this function:

◆ writeInstructionDecoding()

void DefaultDecoderGenerator::writeInstructionDecoding ( std::ostream &  stream) const
private

Writes the instruction decoding section to the main process in decoder.

Parameters
streamThe stream to write.

Definition at line 2583 of file DefaultDecoderGenerator.cc.

2584 {
2585
2587 stream << endl;
2589}
void writeRulesForDestinationControlSignals(std::ostream &stream) const
void writeRulesForSourceControlSignals(std::ostream &stream) const

References writeRulesForDestinationControlSignals(), and writeRulesForSourceControlSignals().

Referenced by writeMainDecodingProcess().

Here is the call graph for this function:

◆ writeInstructionDismembering()

void DefaultDecoderGenerator::writeInstructionDismembering ( std::ostream &  stream) const
private

Writes dismembering of instruction word to signals to the given stream.

Parameters
streamThe stream.

Definition at line 1414 of file DefaultDecoderGenerator.cc.

1415 {
1416 std::string instructionPort = NetlistGenerator::DECODER_INSTR_WORD_PORT;
1417
1418 if (language_ == VHDL) {
1419 stream << indentation(1) << "-- dismembering of instruction" << endl;
1420 stream << indentation(1) << "process (" << instructionPort << ")"
1421 << endl;
1422 stream << indentation(1) << "begin --process" << endl;
1423
1424 for (int i = 0; i < bem_.moveSlotCount(); i++) {
1425 MoveSlot& slot = bem_.moveSlot(i);
1426 int slotPosition = slot.bitPosition();
1427
1428 if (slot.width() > 0) {
1429 stream << indentation(2) << moveFieldSignal(slot.name())
1430 << " <= " << instructionPort << "("
1431 << slotPosition + slot.width() << "-1 downto "
1432 << slotPosition << ");" << endl;
1433 }
1434 if (slot.hasSourceField() && slot.sourceField().width() != 0) {
1435 SourceField& srcField = slot.sourceField();
1436 stream << indentation(2) << srcFieldSignal(slot.name())
1437 << " <= " << instructionPort << "("
1438 << slotPosition + srcField.bitPosition() +
1439 srcField.width() - 1
1440 << " downto " << slotPosition + srcField.bitPosition()
1441 << ");" << endl;
1442 }
1443 if (slot.hasDestinationField() &&
1444 slot.destinationField().width() != 0) {
1445 DestinationField& dstField = slot.destinationField();
1446 stream << indentation(2) << dstFieldSignal(slot.name())
1447 << " <= " << instructionPort << "("
1448 << slotPosition + dstField.bitPosition() +
1449 dstField.width() - 1
1450 << " downto " << slotPosition + dstField.bitPosition()
1451 << ");" << endl;
1452 }
1453 if (slot.hasGuardField()) {
1454 GuardField& grdField = slot.guardField();
1455 stream << indentation(2) << guardFieldSignal(slot.name())
1456 << " <= " << instructionPort << "("
1457 << slotPosition + grdField.bitPosition() +
1458 grdField.width() - 1
1459 << " downto " << slotPosition + grdField.bitPosition()
1460 << ");" << endl;
1461 }
1462 }
1463 stream << endl;
1464 for (int i = 0; i < bem_.immediateSlotCount(); i++) {
1466 stream << indentation(2) << immSlotSignal(slot.name())
1467 << " <= " << instructionPort << "("
1468 << slot.bitPosition() + slot.width() - 1 << " downto "
1469 << slot.bitPosition() << ");" << endl;
1470 }
1473 stream << indentation(2) << LIMM_TAG_SIGNAL
1474 << " <= " << instructionPort << "("
1475 << icField.bitPosition() + icField.width() - 1
1476 << " downto " << icField.bitPosition() << ");" << endl;
1477 }
1478 stream << indentation(1) << "end process;" << endl;
1479 } else { // language == Verilog
1480 stream << indentation(1) << "// dismembering of instruction" << endl;
1481 stream << indentation(1) << "always@(*)" << endl;
1482 stream << indentation(1) << "begin //process" << endl;
1483
1484 for (int i = 0; i < bem_.moveSlotCount(); i++) {
1485 MoveSlot& slot = bem_.moveSlot(i);
1486 int slotPosition = slot.bitPosition();
1487
1488 if (slot.width() > 0) {
1489 stream << indentation(2) << moveFieldSignal(slot.name())
1490 << " = " << instructionPort << "["
1491 << slotPosition + slot.width() - 1 << " : "
1492 << slotPosition << "];" << endl;
1493 }
1494 if (slot.hasSourceField() && slot.sourceField().width() != 0) {
1495 SourceField& srcField = slot.sourceField();
1496 stream << indentation(2) << srcFieldSignal(slot.name())
1497 << " = " << instructionPort << "["
1498 << slotPosition + srcField.bitPosition() +
1499 srcField.width() - 1
1500 << " : " << slotPosition + srcField.bitPosition()
1501 << "];" << endl;
1502 }
1503 if (slot.hasDestinationField() &&
1504 slot.destinationField().width() != 0) {
1505 DestinationField& dstField = slot.destinationField();
1506 stream << indentation(2) << dstFieldSignal(slot.name())
1507 << " = " << instructionPort << "["
1508 << slotPosition + dstField.bitPosition() +
1509 dstField.width() - 1
1510 << " : " << slotPosition + dstField.bitPosition()
1511 << "];" << endl;
1512 }
1513 if (slot.hasGuardField()) {
1514 GuardField& grdField = slot.guardField();
1515 stream << indentation(2) << guardFieldSignal(slot.name())
1516 << " = " << instructionPort << "["
1517 << slotPosition + grdField.bitPosition() +
1518 grdField.width() - 1
1519 << " : " << slotPosition + grdField.bitPosition()
1520 << "];" << endl;
1521 }
1522 }
1523 stream << endl;
1524 for (int i = 0; i < bem_.immediateSlotCount(); i++) {
1526 stream << indentation(2) << immSlotSignal(slot.name()) << " = "
1527 << instructionPort << "["
1528 << slot.bitPosition() + slot.width() - 1 << " : "
1529 << slot.bitPosition() << "];" << endl;
1530 }
1533 stream << indentation(2) << LIMM_TAG_SIGNAL << " = "
1534 << instructionPort << "["
1535 << icField.bitPosition() + icField.width() - 1 << " : "
1536 << icField.bitPosition() << "];" << endl;
1537 }
1538 stream << indentation(1) << "end" << endl;
1539 }
1540}
int moveSlotCount() const
static std::string guardFieldSignal(const std::string &busName)
static std::string moveFieldSignal(const std::string &busName)
virtual int width() const
virtual int width() const
Definition MoveSlot.cc:406
GuardField & guardField() const
Definition MoveSlot.cc:215
bool hasSourceField() const
Definition MoveSlot.cc:264
bool hasDestinationField() const
Definition MoveSlot.cc:327
bool hasGuardField() const
Definition MoveSlot.cc:202
static const std::string DECODER_INSTR_WORD_PORT
Instruction word port name in instruction decoder.
virtual int width() const

References bem_, InstructionField::bitPosition(), ProGe::NetlistGenerator::DECODER_INSTR_WORD_PORT, MoveSlot::destinationField(), dstFieldSignal(), MoveSlot::guardField(), guardFieldSignal(), MoveSlot::hasDestinationField(), MoveSlot::hasGuardField(), BinaryEncoding::hasImmediateControlField(), MoveSlot::hasSourceField(), BinaryEncoding::immediateControlField(), BinaryEncoding::immediateSlot(), BinaryEncoding::immediateSlotCount(), immSlotSignal(), indentation(), language_, LIMM_TAG_SIGNAL, moveFieldSignal(), BinaryEncoding::moveSlot(), BinaryEncoding::moveSlotCount(), ImmediateSlotField::name(), MoveSlot::name(), MoveSlot::sourceField(), srcFieldSignal(), ProGe::VHDL, GuardField::width(), ImmediateControlField::width(), ImmediateSlotField::width(), MoveSlot::width(), SlotField::width(), and SourceField::width().

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeInstructionTemplateProcedures()

void DefaultDecoderGenerator::writeInstructionTemplateProcedures ( const ProGe::HDL  language,
const TTAMachine::InstructionTemplate iTemp,
int  indLevel,
std::ostream &  stream 
) const
private

Writes the procedures required if the instruction is of the given instruction template.

Parameters
iTempThe instruction template.
indLevelThe indentation level.
streamThe stream to write.

Definition at line 1955 of file DefaultDecoderGenerator.cc.

1959 {
1960
1963 if (language == VHDL) {
1964 if (iTemp.slotCount() == 0) {
1965 for (int i = 0; i < iuNav.count(); i++) {
1966 ImmediateUnit* iu = iuNav.item(i);
1967 stream << indentation(indLevel)
1968 << iuWriteLoadCntrlPort(iu->name()) << " <= '0';"
1969 << endl;
1970
1971 stream << indentation(indLevel) << iuWritePort(iu->name())
1972 << "(" << (iu->width() - 1) << " downto 0"
1973 << ") <= tce_sxt(\"0\", " << iu->width() << ");"
1974 << endl;
1975 }
1976 } else {
1977 for (int i = 0; i < iuNav.count(); i++) {
1978 ImmediateUnit* iu = iuNav.item(i);
1979 if (iTemp.isOneOfDestinations(*iu)) {
1980 int msb = iu->width() - 1;
1981 int lsb = iTemp.supportedWidth(*iu) -
1982 iTemp.supportedWidth(iTemp.slotOfDestination(*iu, 0));
1983 for (int j = 0; j < iTemp.numberOfSlots(*iu); j++) {
1984 string slot = iTemp.slotOfDestination(*iu, j);
1985 if (j != 0) {
1986 msb = lsb-1;
1987 lsb = msb - iTemp.supportedWidth(slot) + 1;
1988 }
1989
1990 int immPartWidth = msb - lsb + 1;
1991 stream << indentation(indLevel)
1992 << iuWritePort(iu->name())
1993 << "(" << msb << " downto " << lsb << ") <= ";
1994 if (j == 0) {
1995 if (iu->extensionMode() == Machine::SIGN) {
1996 stream << "tce_sxt(";
1997 } else {
1998 stream << "tce_ext(";
1999 }
2000 }
2001
2002 if (machine_.busNavigator().hasItem(slot)) {
2003 MoveSlot& mSlot = bem_.moveSlot(slot);
2005 << "(" << mSlot.bitPosition() +
2006 iTemp.supportedWidth(slot) - 1
2007 << " downto " << mSlot.bitPosition() << ")";
2008 } else {
2009 ImmediateSlotField& iSlot =
2010 bem_.immediateSlot(slot);
2012 << "(" << iSlot.bitPosition() +
2013 iTemp.supportedWidth(slot) - 1
2014 << " downto " << iSlot.bitPosition() << ")";
2015 }
2016
2017 if (j == 0) {
2018 stream << ", " << immPartWidth << ");" << endl;
2019 } else {
2020 stream << ";" << endl;
2021 }
2022
2023 }
2024 if (iu->numberOfRegisters() > 1) {
2025 LImmDstRegisterField& field =
2027 iTemp.name(), iu->name());
2028 stream << indentation(indLevel)
2029 << iuWriteOpcodeCntrlPort(iu->name()) << " <= "
2030 << "tce_ext("
2032 << "("
2033 << field.bitPosition() + rfOpcodeWidth(*iu) - 1
2034 << " downto " << field.bitPosition() << "), "
2036 << "'length);" << endl;
2037 }
2038 stream << indentation(indLevel)
2039 << iuWriteLoadCntrlPort(iu->name()) << " <= '1';"
2040 << endl;
2041 } else {
2042 stream << indentation(indLevel)
2043 << iuWriteLoadCntrlPort(iu->name()) << " <= '0';"
2044 << endl;
2045 }
2046 }
2047 }
2048 } else { // language == Verilog
2049 if (iTemp.slotCount() == 0) {
2050 for (int i = 0; i < iuNav.count(); i++) {
2051 ImmediateUnit* iu = iuNav.item(i);
2052 stream << indentation(indLevel)
2054 << " <= 1'b0;" << endl;
2055
2056 stream << indentation(indLevel)
2057 << iuWriteSignal(iu->name())
2058 << "[" << (iu->width() - 1) << " : 0"
2059 << "] <= {" << iu->width() <<"{1'b0}};" << endl;
2060 }
2061 } else {
2062 for (int i = 0; i < iuNav.count(); i++) {
2063 ImmediateUnit* iu = iuNav.item(i);
2064 if (iTemp.isOneOfDestinations(*iu)) {
2065 int msb = iu->width() - 1;
2066 int lsb = iTemp.supportedWidth(*iu) -
2067 iTemp.supportedWidth(iTemp.slotOfDestination(*iu, 0));
2068 for (int j = 0; j < iTemp.numberOfSlots(*iu); j++) {
2069 string slot = iTemp.slotOfDestination(*iu, j);
2070 if (j != 0) {
2071 msb = lsb-1;
2072 lsb = msb - iTemp.supportedWidth(slot) + 1;
2073 }
2074
2075 stream << indentation(indLevel)
2076 << iuWriteSignal(iu->name())
2077 << "[" << msb << " : " << lsb << "] <= ";
2078 if (j == 0) {
2079 if (iu->extensionMode() == Machine::SIGN) {
2080 stream << "$signed(";
2081 } else {
2082 stream << "$unsigned(";
2083 }
2084 }
2085
2086 if (machine_.busNavigator().hasItem(slot)) {
2087 MoveSlot& mSlot = bem_.moveSlot(slot);
2089 << "[" << mSlot.bitPosition() +
2090 iTemp.supportedWidth(slot) - 1
2091 << " : " << mSlot.bitPosition() << "]";
2092 } else {
2093 ImmediateSlotField& iSlot =
2094 bem_.immediateSlot(slot);
2096 << "[" << iSlot.bitPosition() +
2097 iTemp.supportedWidth(slot) - 1
2098 << " : " << iSlot.bitPosition() << "]";
2099 }
2100
2101 if (j == 0) {
2102 stream << ");" << endl;
2103 } else {
2104 stream << ";" << endl;
2105 }
2106 }
2107 if (iu->numberOfRegisters() > 1) {
2108 LImmDstRegisterField& field =
2110 iTemp.name(), iu->name());
2111 stream << indentation(indLevel)
2113 << " <= " << "$unsigned("
2115 << "["
2116 << field.bitPosition() + rfOpcodeWidth(*iu) - 1
2117 << " : " << field.bitPosition() << "]);"
2118 << endl;
2119 }
2120 stream << indentation(indLevel)
2121 << iuWriteLoadCntrlSignal(iu->name()) << " <= 1'b1;"
2122 << endl;
2123 } else {
2124 stream << indentation(indLevel)
2125 << iuWriteLoadCntrlSignal(iu->name()) << " <= 1'b0;"
2126 << endl;
2127 }
2128 }
2129 }
2130 }
2131}
LImmDstRegisterField & longImmDstRegisterField(int index) const
virtual Machine::Extension extensionMode() const
virtual bool isOneOfDestinations(const ImmediateUnit &dstUnit) const
virtual int numberOfSlots(const ImmediateUnit &dstUnit) const
virtual std::string slotOfDestination(const ImmediateUnit &dstUnit, int index) const
bool hasItem(const std::string &name) const
@ SIGN
Sign extension.
Definition Machine.hh:82

References bem_, InstructionField::bitPosition(), TTAMachine::Machine::busNavigator(), TTAMachine::Machine::Navigator< ComponentType >::count(), ProGe::NetlistGenerator::DECODER_INSTR_WORD_PORT, TTAMachine::ImmediateUnit::extensionMode(), TTAMachine::Machine::Navigator< ComponentType >::hasItem(), BinaryEncoding::immediateSlot(), TTAMachine::Machine::immediateUnitNavigator(), indentation(), TTAMachine::InstructionTemplate::isOneOfDestinations(), TTAMachine::Machine::Navigator< ComponentType >::item(), iuWriteLoadCntrlPort(), iuWriteLoadCntrlSignal(), iuWriteOpcodeCntrlPort(), iuWriteOpcodeCntrlSignal(), iuWritePort(), iuWriteSignal(), BinaryEncoding::longImmDstRegisterField(), machine_, BinaryEncoding::moveSlot(), TTAMachine::Component::name(), TTAMachine::BaseRegisterFile::numberOfRegisters(), TTAMachine::InstructionTemplate::numberOfSlots(), rfOpcodeWidth(), TTAMachine::Machine::SIGN, TTAMachine::InstructionTemplate::slotCount(), TTAMachine::InstructionTemplate::slotOfDestination(), TTAMachine::InstructionTemplate::supportedWidth(), ProGe::VHDL, and TTAMachine::BaseRegisterFile::width().

Referenced by writeLongImmediateWriteProcess().

Here is the call graph for this function:

◆ writeLockDumpCode()

void DefaultDecoderGenerator::writeLockDumpCode ( std::ostream &  stream) const
private

void writeDecompressSignalsVHDL(std::ostream& stream) const; TBR

Writes process that captures state of global lock per clock cycle.

The captured contents are dumped into an output file.

Parameters
streamThe stream to write.

Definition at line 963 of file DefaultDecoderGenerator.cc.

963 {
964 if (language_==VHDL){
965 stream << indentation(1)
966 << "-- Dump the status of global lock into a file once "
967 "in clock cycle"
968 << endl
969 << indentation(1)
970 << "-- setting DUMP false will disable dumping"
971 << endl << endl;
972
973 stream << indentation(1)
974 << "-- Do not synthesize this process!"
975 << endl
976 << indentation(1)
977 << "-- pragma synthesis_off"
978 << endl << endl;
979
980 stream << indentation(1)
981 << "file_output : process" << endl;
982 stream << indentation(2)
983 << "file fileout : text;" << endl << endl
984 << indentation(2)
985 << "variable lineout : line;" << endl
986 << indentation(2)
987 << "variable start : boolean := true;" << endl
988 << indentation(2)
989 << "variable count : integer := 0;" << endl
990 << indentation(2)
991 << "constant SEPARATOR : string := \" | \";" << endl
992 << indentation(2)
993 << "constant DUMP : boolean := true;" << endl
994 << indentation(2)
995 << "constant DUMPFILE : string := \"lock.dump\";" << endl;
996
997 stream << indentation(1)
998 << "begin" << endl;
999
1000 stream << indentation(2)
1001 << "if DUMP = true then" << endl;
1002
1003 stream << indentation(3)
1004 << "if start = true then" << endl;
1005
1006 stream << indentation(4)
1007 << "file_open(fileout, DUMPFILE, write_mode);" << endl
1008 << indentation(4)
1009 << "start := false;" << endl;
1010
1011 stream << indentation(3)
1012 << "end if;" << endl;
1013
1014 stream << indentation(3)
1015 << "wait on clk until clk = '1' and clk'last_value = '0';"
1016 << endl;
1017
1018 stream << indentation(3)
1019 << "if count > " << (lockTraceStartingCycle_ - 1)
1020 << " then" << endl;
1021
1022 stream << indentation(4) << "write(lineout, count-"
1023 << lockTraceStartingCycle_ << ", right, 12);" << endl
1024 << indentation(4) << "write(lineout, SEPARATOR);" << endl
1025 << indentation(4)
1026 << "write(lineout, conv_integer(unsigned'(\"\" & "
1027 << POST_DECODE_MERGED_GLOCK_SIGNAL << ")), right, 12);" << endl
1028 << indentation(4) << "write(lineout, SEPARATOR);" << endl
1029 << indentation(4) << "writeline(fileout, lineout);" << endl;
1030
1031 stream << indentation(3)
1032 << "end if;" << endl;
1033 stream << indentation(3)
1034 << "count := count + 1;" << endl;
1035
1036 stream << indentation(2)
1037 << "end if;" << endl;
1038
1039 stream << indentation(1)
1040 << "end process file_output;" << endl;
1041
1042 stream << indentation(1)
1043 << "-- pragma synthesis_on"
1044 << endl;
1045
1046 } else { // language_==Verilog
1047 stream << indentation(1)
1048 << "// Dump the status of global lock into a file once "
1049 << "in clock cycle"
1050 << endl
1051 << indentation(1)
1052 << "// setting DUMP false will disable dumping"
1053 << endl << endl
1054 << indentation(1) << "// Do not synthesize!" << endl
1055 << indentation(1) << "//synthesis translate_off" << endl
1056 << indentation(1) << "integer fileout;" << endl << endl
1057 << indentation(1) << "integer count=0;" << endl << endl
1058 << indentation(1) << "`define DUMPFILE \"lock.dump\""
1059 << endl << endl
1060
1061 << indentation(1) << "initial" << endl
1062 << indentation(1) << "begin" << endl
1063 << indentation(2) << "fileout = $fopen(`DUMPFILE,\"w\");"
1064 << endl
1065 << indentation(2) << "$fclose(fileout);" << endl
1066 << indentation(2) << "forever" << endl
1067 << indentation(2) << "begin" << endl
1068 << indentation(3) << "#PERIOD;" << endl
1069 << indentation(3) << "if ( count > "
1070 << (lockTraceStartingCycle_ - 1) << ")" << endl;
1071
1072 stream << indentation(3) << "begin" << endl
1073 << indentation(4) << "fileout = $fopen(`DUMPFILE,\"a\");"
1074 << endl
1075 << indentation(4) << "$fwrite(fileout," << "\""
1076 << " %11d | %11d | \\n\"" << ", count - "
1077 << lockTraceStartingCycle_ << ", "
1079 << endl
1080 << indentation(4) << "$fclose(fileout);" << endl
1081 << indentation(3) << "end" << endl
1082 << indentation(3) << "count = count + 1;" << endl
1083 << indentation(2) << "end" << endl
1084 << indentation(1) << "end" << endl
1085 << indentation(1) << "//synthesis translate_on" << endl;
1086 }
1087}

References ProGe::NetlistGenerator::DECODER_LOCK_REQ_IN_PORT, indentation(), language_, lockTraceStartingCycle_, POST_DECODE_MERGED_GLOCK_SIGNAL, and ProGe::VHDL.

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeLongImmediateTagSignal()

void DefaultDecoderGenerator::writeLongImmediateTagSignal ( std::ostream &  stream) const
private

Writes the signal for long immediate tag to the given stream.

Parameters
streamThe stream.

Definition at line 1152 of file DefaultDecoderGenerator.cc.

1153 {
1155 writeComment(stream, 1, "signal for long immediate tag");
1156
1160 }
1161}

References bem_, ProGe::BIT_VECTOR, BinaryEncoding::hasImmediateControlField(), BinaryEncoding::immediateControlField(), LIMM_TAG_SIGNAL, ImmediateControlField::width(), writeComment(), and writeSignalDeclaration().

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeLongImmediateWriteProcess()

void DefaultDecoderGenerator::writeLongImmediateWriteProcess ( std::ostream &  stream) const
private

Writes the process that writes long immediates to immediate units.

Parameters
streamThe stream to write.

Definition at line 1801 of file DefaultDecoderGenerator.cc.

1802 {
1803
1806 if (itNav.count() == 0 || (itNav.count() == 1 &&
1807 itNav.item(0)->isEmpty())) {
1808 return;
1809 }
1810
1811 string resetPort = NetlistGenerator::DECODER_RESET_PORT;
1812 string clockPort = NetlistGenerator::DECODER_CLOCK_PORT;
1813 // If bypass decoder registers, implement combinatorial process
1814 string listStr;
1815 if (language_ == VHDL) {
1816 int indentLevel = 1;
1817 stream << indentation(indentLevel) << "--long immediate write process"
1818 << endl;
1819 stream << indentation(indentLevel) << "process (";
1820 stream << clockPort;
1821 if (!syncReset_) {
1822 stream << ", " << resetPort;
1823 }
1824 stream << ")" << endl;
1825 stream << indentation(indentLevel) << "begin --process" << endl;
1826 // reset
1827 indentLevel += 1;
1828 if (syncReset_) {
1829 stream << indentation(indentLevel)
1830 << "if (clk'event and clk = '1') then" << endl;
1831 indentLevel += 1;
1832 }
1833 stream << indentation(indentLevel) << "if (" << resetPort
1834 << " = '0') then" << endl;
1835 indentLevel += 1;
1838
1839 for (int i = 0; i < iuNav.count(); i++) {
1840 ImmediateUnit* iu = iuNav.item(i);
1841 stream << indentation(indentLevel)
1842 << iuWriteLoadCntrlPort(iu->name()) << " <= '0';" << endl;
1843 stream << indentation(indentLevel) << iuWritePort(iu->name())
1844 << " <= (others => '0');" << endl;
1845 if (rfOpcodeWidth(*iu) != 0)
1846 stream << indentation(indentLevel)
1848 << " <= (others => '0');" << endl;
1849 }
1850 // else
1851 stream << indentation(indentLevel - 1) << "elsif ";
1852 if (!syncReset_) {
1853 stream << "(clk'event and clk = '1') then" << endl
1854 << indentation(indentLevel) << "if ";
1855 indentLevel += 1;
1856 }
1857 // global lock test
1858 stream << PRE_DECODE_MERGED_GLOCK_SIGNAL << " = '0' then" << endl;
1859 for (int i = 0; i < itNav.count(); i++) {
1860 InstructionTemplate* iTemp = itNav.item(i);
1862 if (i == 0) {
1863 stream << indentation(indentLevel) << "if ("
1865 VHDL, iTemp->name())
1866 << ") then" << endl;
1867 } else if (i+1 < itNav.count()) {
1868 stream << indentation(indentLevel) << "elsif ("
1870 VHDL, iTemp->name())
1871 << ") then" << endl;
1872 } else {
1873 stream << indentation(indentLevel) << "else" << endl;
1874 }
1875 }
1877 VHDL, *iTemp, indentLevel + 1, stream);
1878 }
1879
1881 stream << indentation(indentLevel) << "end if;" << endl;
1882 }
1883 // global lock test endif
1884 stream << indentation(3) << "end if;" << endl;
1885 // reset (async) or clk edge (sync) endif
1886 stream << indentation(2) << "end if;" << endl;
1887 stream << indentation(1) << "end process;" << endl;
1888 } else { // language_ == Verilog
1889 stream << indentation(1) << "//long immediate write process" << endl
1890 << indentation(1) << "always@(posedge "
1891 << clockPort << " or negedge " << resetPort << ")" << endl
1892 // reset
1893 << indentation(2) << "if (" << resetPort << " == 0)"
1894 << endl
1895 << indentation(2) << "begin" << endl;
1898
1899 for (int i = 0; i < iuNav.count(); i++) {
1900 ImmediateUnit* iu = iuNav.item(i);
1901 stream << indentation(3) << iuWriteLoadCntrlSignal(iu->name())
1902 << " <= 1'b0;" << endl
1903 << indentation(3) << iuWriteSignal(iu->name())
1904 << " <= 0;" << endl;
1905 if (rfOpcodeWidth(*iu) != 0)
1906 stream << indentation(3) << iuWriteOpcodeCntrlSignal(iu->name())
1907 << " <= 0;" << endl;
1908 }
1909 stream << indentation(2) << "end" << endl
1910 << indentation(2) << "else" << endl
1911 << indentation(2) << "begin" << endl
1912 << indentation(3) << "if ("
1914 << endl
1915 << indentation(3) << "begin" << endl;
1916 for (int i = 0; i < itNav.count(); i++) {
1917 InstructionTemplate* iTemp = itNav.item(i);
1918 int indLevel = 4;
1920 indLevel = 5;
1921 if (i == 0) {
1922 stream << indentation(4) << "if ("
1924 Verilog, iTemp->name())
1925 << ")" << endl;
1926 } else if (i+1 < itNav.count()) {
1927 stream << indentation(4) << "else if ("
1929 Verilog, iTemp->name())
1930 << ")" << endl;
1931 } else {
1932 stream << indentation(4) << "else" << endl;
1933 }
1934 }
1935 stream << indentation(4) << "begin" << endl;
1937 Verilog, *iTemp, indLevel, stream);
1938 stream << indentation(4) << "end" << endl;
1939 }
1940 stream << indentation(3) << "end" << endl
1941 << indentation(2) << "end" << endl;
1942 }
1943}
std::string instructionTemplateCondition(const ProGe::HDL language, const std::string &iTempName) const
void writeInstructionTemplateProcedures(const ProGe::HDL language, const TTAMachine::InstructionTemplate &iTemp, int indLevel, std::ostream &stream) const
static const std::string DECODER_CLOCK_PORT
Clock port name in instruction decoder.
static const std::string DECODER_RESET_PORT
Reset port name in instruction decoder.
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition Machine.cc:428

References bem_, TTAMachine::Machine::Navigator< ComponentType >::count(), ProGe::NetlistGenerator::DECODER_CLOCK_PORT, ProGe::NetlistGenerator::DECODER_LOCK_REQ_IN_PORT, ProGe::NetlistGenerator::DECODER_RESET_PORT, BinaryEncoding::hasImmediateControlField(), TTAMachine::Machine::immediateUnitNavigator(), indentation(), instructionTemplateCondition(), TTAMachine::Machine::instructionTemplateNavigator(), TTAMachine::Machine::Navigator< ComponentType >::item(), iuWriteLoadCntrlPort(), iuWriteLoadCntrlSignal(), iuWriteOpcodeCntrlPort(), iuWriteOpcodeCntrlSignal(), iuWritePort(), iuWriteSignal(), language_, machine_, TTAMachine::Component::name(), PRE_DECODE_MERGED_GLOCK_SIGNAL, rfOpcodeWidth(), syncReset_, ProGe::Verilog, ProGe::VHDL, and writeInstructionTemplateProcedures().

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeMainDecodingProcess()

void DefaultDecoderGenerator::writeMainDecodingProcess ( std::ostream &  stream) const
private

Writes the main decoding process to the given stream.

Parameters
streamThe stream to write.

Definition at line 2323 of file DefaultDecoderGenerator.cc.

2324 {
2325 if(language_==VHDL){
2326 string resetPort = NetlistGenerator::DECODER_RESET_PORT;
2327 string clockPort = NetlistGenerator::DECODER_CLOCK_PORT;
2328
2329 stream << indentation(1) << "-- main decoding process" << endl;
2330 string listStr;
2331 stream << indentation(1) << "process (";
2332 stream << clockPort;
2333 if (!syncReset_) {
2334 stream << ", " << resetPort;
2335 }
2336 stream << ")" << endl;
2337 stream << indentation(1) << "begin" << endl;
2338
2339 // if reset is active
2340 if (syncReset_) {
2341 stream << indentation(2) << "if (clk'event and clk = '1') then"
2342 << endl
2343 << indentation(2) << "if (" << resetPort << " = '0') then"
2344 << endl;
2346 stream << endl << indentation(2) << "else" << endl;
2347 } else {
2348 stream << indentation(2) << "if (" << resetPort << " = '0') then"
2349 << endl;
2351 stream << endl
2352 << indentation(2)
2353 << "elsif (clk'event and clk = '1') then "
2354 << "-- rising clock edge" << endl;
2355 }
2356 if (generateDebugger_) {
2357 string softResetPort = "db_tta_nreset";
2358 stream << indentation(3) << "if (" << softResetPort
2359 << " = '0') then"
2360 << endl;
2362 stream << indentation(3) << "elsif ("
2363 << PRE_DECODE_MERGED_GLOCK_SIGNAL << " = '0') then" << endl
2364 << endl;
2365 } else {
2366 stream << indentation(2) << "if ("
2368 stream << " = '0')";
2369 stream << " then" << endl << endl;
2370 }
2371
2373 stream << indentation(3) << "end if;" << endl;
2374 stream << indentation(2) << "end if;" << endl;
2375 stream << indentation(1) << "end process;" << endl;
2376 } else {
2377 string resetPort = NetlistGenerator::DECODER_RESET_PORT;
2378 string clockPort = NetlistGenerator::DECODER_CLOCK_PORT;
2379
2380 stream << indentation(1) << "// main decoding process" << endl
2381 << indentation(1) << "always@(posedge " << clockPort
2382 << " or negedge " << resetPort << ")" << endl
2383 // if reset is active
2384 << indentation(2) << "if (" << resetPort << " == 0)" << endl
2385 << indentation(2) <<"begin" << endl;
2387 stream << indentation(2) << "end" << endl
2388 << indentation(2) << "else" << endl
2389 << indentation(3) << "begin"<< endl
2390 << indentation(3) << "if ("
2392 << " == 0)" << endl << endl
2393 << indentation(3) << "begin"<< endl;
2395 stream << indentation(3) << "end" << endl
2396 << indentation(2) << "end" << endl;
2397 }
2398}
void writeResettingOfControlRegisters(std::ostream &stream) const
void writeInstructionDecoding(std::ostream &stream) const

References ProGe::NetlistGenerator::DECODER_CLOCK_PORT, ProGe::NetlistGenerator::DECODER_LOCK_REQ_IN_PORT, ProGe::NetlistGenerator::DECODER_RESET_PORT, generateDebugger_, indentation(), language_, PRE_DECODE_MERGED_GLOCK_SIGNAL, syncReset_, ProGe::VHDL, writeInstructionDecoding(), and writeResettingOfControlRegisters().

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeMoveFieldSignals()

void DefaultDecoderGenerator::writeMoveFieldSignals ( std::ostream &  stream) const
private

Writes the signals for source, destination and guard fields to the given stream.

Parameters
streamThe stream.

Definition at line 1096 of file DefaultDecoderGenerator.cc.

1096 {
1098 stream, 1, "signals for source, destination and guard fields");
1099
1100 for (int i = 0; i < bem_.moveSlotCount(); i++) {
1101 MoveSlot& slot = bem_.moveSlot(i);
1102 if (slot.width() > 0) {
1104 stream, ProGe::BIT_VECTOR, moveFieldSignal(slot.name()),
1105 slot.width());
1106 }
1107 if (slot.hasSourceField() && slot.sourceField().width() != 0) {
1108 SourceField& srcField = slot.sourceField();
1110 stream, ProGe::BIT_VECTOR, srcFieldSignal(slot.name()),
1111 srcField.width());
1112 }
1113 if (slot.hasDestinationField() &&
1114 slot.destinationField().width() != 0) {
1115 DestinationField& dstField = slot.destinationField();
1117 stream, ProGe::BIT_VECTOR, dstFieldSignal(slot.name()),
1118 dstField.width());
1119 }
1120 if (slot.hasGuardField()) {
1121 GuardField& grdField = slot.guardField();
1123 stream, ProGe::BIT_VECTOR, guardFieldSignal(slot.name()),
1124 grdField.width());
1125 }
1126 }
1127}

References bem_, ProGe::BIT_VECTOR, MoveSlot::destinationField(), dstFieldSignal(), MoveSlot::guardField(), guardFieldSignal(), MoveSlot::hasDestinationField(), MoveSlot::hasGuardField(), MoveSlot::hasSourceField(), moveFieldSignal(), BinaryEncoding::moveSlot(), BinaryEncoding::moveSlotCount(), MoveSlot::name(), MoveSlot::sourceField(), srcFieldSignal(), GuardField::width(), MoveSlot::width(), SlotField::width(), SourceField::width(), writeComment(), and writeSignalDeclaration().

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeNOPEncodingVHDL()

std::string DefaultDecoderGenerator::writeNOPEncodingVHDL ( ) const
private

◆ writePipelineFillProcess()

void DefaultDecoderGenerator::writePipelineFillProcess ( std::ostream &  stream) const
private

Writes process that keeps machine locked until first decoded instruction is available.

Definition at line 2518 of file DefaultDecoderGenerator.cc.

2519 {
2520 auto indstream = [&](unsigned level) -> std::ostream& {
2521 stream << indentation(level);
2522 return stream;
2523 };
2524 if (language_ == VHDL) {
2525 if (syncReset_) {
2526 indstream(1) << "decode_pipeline_fill_lock: process (clk)"
2527 << endl;
2528 indstream(1) << "begin" << endl;
2529 indstream(2) << "if clk'event and clk = '1' then" << endl;
2530 indstream(3) << "if rstx = '0' then" << endl;
2531 indstream(4) << PIPELINE_FILL_LOCK_SIGNAL << " <= '1';" << endl;
2532 indstream(3) << "elsif lock = '0' then" << endl;
2533 } else {
2534 indstream(1) << "decode_pipeline_fill_lock: process (clk, rstx)"
2535 << endl;
2536 indstream(1) << "begin" << endl;
2537 indstream(2) << "if rstx = '0' then" << endl;
2538 indstream(3) << PIPELINE_FILL_LOCK_SIGNAL << " <= '1';" << endl;
2539 indstream(2) << "elsif clk'event and clk = '1' then" << endl;
2540 indstream(3) << "if lock = '0' then" << endl;
2541 }
2542 indstream(4) << "decode_fill_lock_reg <= '0';" << endl;
2543 indstream(3) << "end if;" << endl;
2544 indstream(2) << "end if;" << endl;
2545 indstream(1) << "end process decode_pipeline_fill_lock;" << endl;
2546
2547 } else { // language_ == Verilog
2548 // todo
2549 }
2550}

References indentation(), language_, PIPELINE_FILL_LOCK_SIGNAL, syncReset_, and ProGe::VHDL.

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writePipelineFillSignals()

void DefaultDecoderGenerator::writePipelineFillSignals ( std::ostream &  stream) const
private

Writes signals used in decode pipeline fill process.

Definition at line 1403 of file DefaultDecoderGenerator.cc.

References ProGe::BIT, PIPELINE_FILL_LOCK_SIGNAL, and writeSignalDeclaration().

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeResettingOfControlRegisters()

void DefaultDecoderGenerator::writeResettingOfControlRegisters ( std::ostream &  stream) const
private

Writes resetting of all the control registers to the given stream.

Parameters
streamThe stream.

Definition at line 2558 of file DefaultDecoderGenerator.cc.

2559 {
2560 std::string vector_reset = " <= (others => '0');";
2561 std::string bit_reset = " <= '0';";
2562 if (language_ == Verilog) {
2563 vector_reset = " <= 0;";
2564 bit_reset = " <= 1'b0;";
2565 }
2566
2567 for (auto const& signal : registerVectors) {
2568 stream << indentation(3) << signal << vector_reset << endl;
2569 }
2570 stream << endl;
2571 for (auto const& signal : registerBits) {
2572 stream << indentation(3) << signal << bit_reset << endl;
2573 }
2574 stream << endl;
2575}

References indentation(), language_, registerBits, registerVectors, and ProGe::Verilog.

Referenced by writeMainDecodingProcess().

Here is the call graph for this function:

◆ writeRFCntrlSignals()

void DefaultDecoderGenerator::writeRFCntrlSignals ( std::ostream &  stream)
private

Writes the RF control signals to the given stream.

Parameters
streamThe stream.

Definition at line 1307 of file DefaultDecoderGenerator.cc.

1307 {
1308 writeComment(stream, 1, "RF control signals");
1309
1311 registerFileNavigator();
1312 for (int i = 0; i < rfNav.count(); i++) {
1313 RegisterFile* rf = rfNav.item(i);
1314
1315 for (int i = 0; i < rf->portCount(); i++) {
1316 RFPort* port = rf->port(i);
1317 bool async_signal = sacEnabled(rf->name())
1318 && port->outputSocket() != NULL;
1319
1320 // load signal
1321 std::string sigName =
1322 rfLoadSignalName(rf->name(), port->name(), async_signal);
1323 writeSignalDeclaration(stream, ProGe::BIT, sigName, 1);
1324 if (!async_signal) registerBits.push_back(sigName);
1325
1326 // opcode signal
1327 if (0 < rfOpcodeWidth(*rf)) {
1328 std::string sigName = rfOpcodeSignalName(
1329 rf->name(), port->name(), async_signal);
1331 stream, ProGe::BIT_VECTOR, sigName, rfOpcodeWidth(*rf));
1332
1333 if (!async_signal) registerVectors.push_back(sigName);
1334 }
1335 }
1336 }
1337
1339 for (int i = 0; i < iuNav.count(); i++) {
1340 ImmediateUnit* iu = iuNav.item(i);
1341 for (int i = 0; i < iu->portCount(); i++) {
1342 RFPort* port = iu->port(i);
1343 if (port->isOutput()) {
1344 if (language_ == VHDL) {
1345 registerBits.push_back(
1346 iuReadLoadCntrlPort(iu->name(), port->name()));
1347 if (0 < rfOpcodeWidth(*iu)) {
1348 registerVectors.push_back(
1349 iuReadOpcodeCntrlPort(iu->name(), port->name()));
1350 }
1351 } else {
1352 std::string sigName =
1353 iuReadLoadCntrlSignal(iu->name(), port->name());
1354 writeSignalDeclaration(stream, ProGe::BIT, sigName, 1);
1355 registerBits.push_back(sigName);
1356
1357 if (0 < rfOpcodeWidth(*iu)) {
1358 sigName =
1359 iuReadOpcodeCntrlSignal(iu->name(), port->name());
1361 stream, ProGe::BIT_VECTOR, sigName,
1362 rfOpcodeWidth(*iu));
1363 registerVectors.push_back(sigName);
1364 }
1365 }
1366 }
1367 }
1368 if (language_ == Verilog) {
1369 stream << indentation(1) << "reg[" << iu->width()-1 << ":0] "
1370 << iuWriteSignal(iu->name())
1371 << ";" << endl;
1372 stream << indentation(1) << "reg "
1374 << ";" << endl;
1375 if (0 < rfOpcodeWidth(*iu)) {
1376 stream << indentation(1) << "reg["
1377 << rfOpcodeWidth(*iu) - 1 << ":0] "
1379 << ";" << endl;
1380 }
1381 }
1382 }
1383}
virtual bool isOutput() const
Definition Port.cc:308

References ProGe::BIT, ProGe::BIT_VECTOR, TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::immediateUnitNavigator(), indentation(), TTAMachine::Port::isOutput(), TTAMachine::Machine::Navigator< ComponentType >::item(), iuReadLoadCntrlPort(), iuReadLoadCntrlSignal(), iuReadOpcodeCntrlPort(), iuReadOpcodeCntrlSignal(), iuWriteLoadCntrlSignal(), iuWriteOpcodeCntrlSignal(), iuWriteSignal(), language_, machine_, TTAMachine::Component::name(), TTAMachine::Port::name(), TTAMachine::Port::outputSocket(), TTAMachine::BaseRegisterFile::port(), TTAMachine::Unit::portCount(), registerBits, registerVectors, rfLoadSignalName(), rfOpcodeSignalName(), rfOpcodeWidth(), sacEnabled(), ProGe::Verilog, ProGe::VHDL, TTAMachine::BaseRegisterFile::width(), writeComment(), and writeSignalDeclaration().

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeRFSRAMDecodingProcess()

void DefaultDecoderGenerator::writeRFSRAMDecodingProcess ( std::ostream &  stream) const
private

Writes separate combinational decoding process for SRAM register files.

Parameters
streamThe stream to write.

Definition at line 2139 of file DefaultDecoderGenerator.cc.

2140 {
2141
2142 set<const RegisterFile*> sramRFset;
2143 set<const RegisterFile*>::const_iterator sramrf_it;
2144
2145 // Write only when there is SRAM RFs.
2146 bool hasSramRFs = false;
2147 const Machine::RegisterFileNavigator& rfNav =
2149 for (int i = 0; i < rfNav.count(); i++) {
2150 if(sacEnabled(rfNav.item(i)->name())) {
2151 hasSramRFs = true;
2152 sramRFset.insert(rfNav.item(i));
2153 }
2154 }
2155
2156 if(!hasSramRFs) {
2157 return;
2158 }
2159
2160 if (language_ == VHDL) {
2161 string resetPort = NetlistGenerator::DECODER_RESET_PORT;
2162
2163 // Begin process //
2164 stream << indentation(1)
2165 << "-- separate SRAM RF read decoding process" << endl;
2166 stream << indentation(1) << "process (" << resetPort;
2167
2168 // Sensitivity list //
2169 BusSet connectedToSramRFs;
2170 for (sramrf_it = sramRFset.begin(); sramrf_it != sramRFset.end();
2171 sramrf_it++) {
2172 const RegisterFile& rf = **sramrf_it;
2173 assert(sacEnabled(rf.name()));
2174 for (int ip = 0; ip < rf.portCount(); ip++) {
2175 const RFPort& port = *rf.port(ip);
2176 if (port.outputSocket() != NULL) {
2177 BusSet tmp = connectedBuses(*port.outputSocket());
2178 connectedToSramRFs.insert(tmp.begin(), tmp.end());
2179 }
2180 }
2181 }
2182
2183 BusSet::const_iterator busSet_it;
2184 for (busSet_it = connectedToSramRFs.begin();
2185 busSet_it != connectedToSramRFs.end();
2186 busSet_it++) {
2187 string busName = (*busSet_it)->name();
2188 stream << ", " << srcFieldSignal(busName)
2189 << ", " << squashSignal(busName);
2190 }
2191 stream << ")" << endl;
2192 stream << indentation(1) << "begin" << endl;
2193
2194 // Signal resets //
2195 stream << indentation(2) << "if (" << resetPort << " = '0') then"
2196 << endl;
2197 for (sramrf_it = sramRFset.begin(); sramrf_it != sramRFset.end();
2198 sramrf_it++) {
2199 const RegisterFile& rf = **sramrf_it;
2200 assert(sacEnabled(rf.name()));
2201 for (int i = 0; i < rf.portCount(); i++) {
2202 const RFPort& port = *rf.port(i);
2203 if (port.outputSocket() == NULL) {
2204 continue;
2205 }
2206
2207 stream << indentation(3)
2208 << rfLoadSignalName(rf.name(), port.name(), true)
2209 << " <= '0';" << endl;
2210 if (0 < rfOpcodeWidth(rf)) {
2211 stream << indentation(3)
2212 << rfOpcodeSignalName(rf.name(), port.name(), true)
2213 << " <= (others => '0');" << endl;
2214 }
2215 }
2216 }
2217
2218 // Write decoding rules //
2219 stream << endl << indentation(2) << "else" << endl;
2220 for (sramrf_it = sramRFset.begin(); sramrf_it != sramRFset.end();
2221 sramrf_it++) {
2222 const RegisterFile& rf = **sramrf_it;
2223 assert(sacEnabled(rf.name()));
2224 for(int i = 0; i < rf.portCount(); i++) {
2225 const RFPort& port = *rf.port(i);
2226 if (port.outputSocket() != NULL) {
2227 writeControlRulesOfRFReadPort(port, stream);
2228 }
2229 }
2230 }
2231 stream << indentation(2) << "end if;" << endl;
2232
2233 // End process //
2234 stream << indentation(1) << "end process;" << endl;
2235
2236 } else { // language_ == VERILOG
2237 // Begin process //
2238 string resetPort = NetlistGenerator::DECODER_RESET_PORT;
2239
2240 stream << indentation(1)
2241 << "// separate SRAM RF read decoding process" << endl;
2242 stream << indentation(1) << "always@(" << resetPort;
2243
2244 // Sensitivity list //
2245 BusSet connectedToSramRFs;
2246 for (sramrf_it = sramRFset.begin(); sramrf_it != sramRFset.end();
2247 sramrf_it++) {
2248 const RegisterFile& rf = **sramrf_it;
2249 assert(sacEnabled(rf.name()));
2250 for (int ip = 0; ip < rf.portCount(); ip++) {
2251 const RFPort& port = *rf.port(ip);
2252 if (port.outputSocket() != NULL) {
2253 BusSet tmp = connectedBuses(*port.outputSocket());
2254 connectedToSramRFs.insert(tmp.begin(), tmp.end());
2255 }
2256 }
2257 }
2258
2259 BusSet::const_iterator busSet_it;
2260 for (busSet_it = connectedToSramRFs.begin();
2261 busSet_it != connectedToSramRFs.end();
2262 busSet_it++) {
2263 string busName = (*busSet_it)->name();
2264 stream << ", " << srcFieldSignal(busName)
2265 << ", " << squashSignal(busName);
2266 }
2267 stream << ")" << endl;
2268 stream << indentation(1) << "begin" << endl;
2269
2270 // Signal resets //
2271 stream << indentation(2) << "if (" << resetPort << " == 0)" << endl
2272 << indentation(2) << "begin" << endl;
2273
2274 for (sramrf_it = sramRFset.begin(); sramrf_it != sramRFset.end();
2275 sramrf_it++) {
2276 const RegisterFile& rf = **sramrf_it;
2277 assert(sacEnabled(rf.name()));
2278 for (int i = 0; i < rf.portCount(); i++) {
2279 const RFPort& port = *rf.port(i);
2280 if (port.outputSocket() == NULL) {
2281 continue;
2282 }
2283
2284 stream << indentation(3)
2285 << rfLoadSignalName(rf.name(), port.name(), true)
2286 << " <= 1'b0;" << endl;
2287 if (0 < rfOpcodeWidth(rf)) {
2288 stream << indentation(3)
2289 << rfOpcodeSignalName(rf.name(), port.name(), true)
2290 << " <= 0;" << endl;
2291 }
2292 }
2293 }
2294 stream << indentation(2) << "end" << endl;
2295
2296 // Decoding rules //
2297 stream << indentation(2) << "else" << endl;
2298 stream << indentation(2) << "begin" << endl;
2299 for (sramrf_it = sramRFset.begin(); sramrf_it != sramRFset.end();
2300 sramrf_it++) {
2301 const RegisterFile& rf = **sramrf_it;
2302 assert(sacEnabled(rf.name()));
2303 for(int i = 0; i < rf.portCount(); i++) {
2304 const RFPort& port = *rf.port(i);
2305 if (port.outputSocket() != NULL) {
2306 writeControlRulesOfRFReadPort(port, stream);
2307 }
2308 }
2309 }
2310 stream << indentation(2) << "end" << endl;
2311
2312 // End process //
2313 stream << indentation(1) << "end // process" << endl;
2314 }
2315}
void writeControlRulesOfRFReadPort(const TTAMachine::RFPort &port, std::ostream &stream) const

References assert, connectedBuses(), TTAMachine::Machine::Navigator< ComponentType >::count(), ProGe::NetlistGenerator::DECODER_RESET_PORT, indentation(), TTAMachine::Machine::Navigator< ComponentType >::item(), language_, machine_, TTAMachine::Component::name(), TTAMachine::Port::name(), TTAMachine::Port::outputSocket(), TTAMachine::BaseRegisterFile::port(), TTAMachine::Unit::portCount(), TTAMachine::Machine::registerFileNavigator(), rfLoadSignalName(), rfOpcodeSignalName(), rfOpcodeWidth(), sacEnabled(), squashSignal(), srcFieldSignal(), ProGe::VHDL, and writeControlRulesOfRFReadPort().

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeRulesForDestinationControlSignals()

void DefaultDecoderGenerator::writeRulesForDestinationControlSignals ( std::ostream &  stream) const
private

Writes the rules for destination control signals to the instruction decoding section.

Parameters
streamThe stream to write.

Definition at line 2689 of file DefaultDecoderGenerator.cc.

2690 {
2691 writeComment(stream, 4, "control signals for FU inputs");
2693 for (int i = 0; i < fuNav.count(); i++) {
2694 FunctionUnit* fu = fuNav.item(i);
2695 for (int i = 0; i < fu->portCount(); i++) {
2696 BaseFUPort* port = fu->port(i);
2697 if (port->inputSocket() != NULL) {
2698 writeControlRulesOfFUInputPort(*port, stream);
2699 }
2700 }
2701 }
2702
2704 for (int i = 0; i < gcu->portCount(); i++) {
2705 BaseFUPort* port = gcu->port(i);
2706 if (port->inputSocket() != NULL) {
2707 writeControlRulesOfFUInputPort(*port, stream);
2708 }
2709 }
2710
2711 writeComment(stream, 4, "control signals for RF inputs");
2713 for (int i = 0; i < rfNav.count(); i++) {
2714 RegisterFile* rf = rfNav.item(i);
2715 for (int i = 0; i < rf->portCount(); i++) {
2716 RFPort* port = rf->port(i);
2717 if (port->inputSocket() != NULL) {
2718 writeControlRulesOfRFWritePort(*port, stream);
2719 }
2720 }
2721 }
2722}
void writeControlRulesOfRFWritePort(const TTAMachine::RFPort &port, std::ostream &stream) const
void writeControlRulesOfFUInputPort(const TTAMachine::BaseFUPort &port, std::ostream &stream) const

References TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::Port::inputSocket(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, TTAMachine::BaseRegisterFile::port(), TTAMachine::FunctionUnit::port(), TTAMachine::Unit::portCount(), TTAMachine::Machine::registerFileNavigator(), writeComment(), writeControlRulesOfFUInputPort(), and writeControlRulesOfRFWritePort().

Referenced by writeInstructionDecoding().

Here is the call graph for this function:

◆ writeRulesForSourceControlSignals()

void DefaultDecoderGenerator::writeRulesForSourceControlSignals ( std::ostream &  stream) const
private

Writes the rules for source control signals to the instruction decoding section.

Parameters
streamThe stream to write.

Definition at line 2599 of file DefaultDecoderGenerator.cc.

2600 {
2601 int indent;
2602 indent = 4;
2603
2605 for (int i = 0; i < socketNav.count(); i++) {
2606 Socket* socket = socketNav.item(i);
2607 if (socket->direction() == Socket::OUTPUT &&
2608 socket->segmentCount() > 0 && socket->portCount() > 0) {
2609 writeBusControlRulesOfOutputSocket(*socket, stream);
2610 }
2611
2613 stream, indent,
2614 "bus control signals for short immediate sockets");
2616 for (int i = 0; i < busNav.count(); i++) {
2617 Bus* bus = busNav.item(i);
2618 if (bus->immediateWidth() > 0) {
2620 }
2621 }
2622 }
2623
2625 stream, indent,
2626 "data control signals for output sockets connected to FUs");
2628 for (int i = 0; i < fuNav.count(); i++) {
2629 FunctionUnit* fu = fuNav.item(i);
2630 for (int i = 0; i < fu->portCount(); i++) {
2631 BaseFUPort* port = fu->port(i);
2632 if (port->outputSocket() != NULL &&
2633 port->outputSocket()->portCount() > 1) {
2634 writeControlRulesOfFUOutputPort(*port, stream);
2635 }
2636 }
2637 }
2638
2640 for (int i = 0; i < gcu->portCount(); i++) {
2641 BaseFUPort* port = gcu->port(i);
2642 if (port->outputSocket() != NULL &&
2643 port->outputSocket()->portCount() > 1) {
2644 writeControlRulesOfFUOutputPort(*port, stream);
2645 }
2646 }
2647
2648 writeComment(stream, indent, "control signals for RF read ports");
2650 for (int i = 0; i < rfNav.count(); i++) {
2651 RegisterFile* rf = rfNav.item(i);
2652 // Skip RFs with separate address cycle flag enabled.
2653 if (sacEnabled(rf->name())) {
2654 continue;
2655 }
2656 for (int i = 0; i < rf->portCount(); i++) {
2657 RFPort* port = rf->port(i);
2658 if (port->outputSocket() != NULL) {
2659 writeControlRulesOfRFReadPort(*port, stream);
2660 }
2661 }
2662 }
2663
2664 stream << endl
2665 << indentation(indent) << ((language_ == VHDL) ? "--" : "//")
2666 << "control signals for IU read ports" << endl;
2667 writeComment(stream, indent, "control signals for IU read ports");
2670 for (int i = 0; i < iuNav.count(); i++) {
2671 ImmediateUnit* iu = iuNav.item(i);
2672 for (int i = 0; i < iu->portCount(); i++) {
2673 RFPort* port = iu->port(i);
2674 if (port->outputSocket() != NULL) {
2675 writeControlRulesOfRFReadPort(*port, stream);
2676 }
2677 }
2678 }
2679}
void writeBusControlRulesOfSImmSocketOfBus(const TTAMachine::Bus &bus, std::ostream &stream) const
void writeControlRulesOfFUOutputPort(const TTAMachine::BaseFUPort &port, std::ostream &stream) const
void writeBusControlRulesOfOutputSocket(const TTAMachine::Socket &socket, std::ostream &stream) const

References TTAMachine::Machine::busNavigator(), TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Socket::direction(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::Machine::immediateUnitNavigator(), TTAMachine::Bus::immediateWidth(), indentation(), TTAMachine::Machine::Navigator< ComponentType >::item(), language_, machine_, TTAMachine::Component::name(), TTAMachine::Socket::OUTPUT, TTAMachine::Port::outputSocket(), TTAMachine::BaseRegisterFile::port(), TTAMachine::FunctionUnit::port(), TTAMachine::Socket::portCount(), TTAMachine::Unit::portCount(), TTAMachine::Machine::registerFileNavigator(), sacEnabled(), TTAMachine::Socket::segmentCount(), TTAMachine::Machine::socketNavigator(), ProGe::VHDL, writeBusControlRulesOfOutputSocket(), writeBusControlRulesOfSImmSocketOfBus(), writeComment(), writeControlRulesOfFUOutputPort(), and writeControlRulesOfRFReadPort().

Referenced by writeInstructionDecoding().

Here is the call graph for this function:

◆ writeSignalDeclaration()

void DefaultDecoderGenerator::writeSignalDeclaration ( std::ostream &  stream,
ProGe::DataType  type,
std::string  sigName,
int  width 
) const
private

Definition at line 774 of file DefaultDecoderGenerator.cc.

776 {
777 if (language_ == VHDL) {
778 stream << indentation(1) << "signal " << sigName;
779 if (type == ProGe::BIT_VECTOR) {
780 stream << " : std_logic_vector(" << width - 1 << " downto 0);"
781 << endl;
782 } else { // BIT
783 stream << " : std_logic;" << endl;
784 }
785 } else { // Verilog
786 stream << indentation(1) << "reg";
787 if (type == ProGe::BIT_VECTOR) {
788 stream << "[" << width - 1 << ":0]";
789 }
790 stream << " " << sigName << ";" << endl;
791 }
792}

References ProGe::BIT_VECTOR, indentation(), language_, and ProGe::VHDL.

Referenced by writeFUCntrlSignals(), writeGlockHandlingSignals(), writeImmediateSlotSignals(), writeLongImmediateTagSignal(), writeMoveFieldSignals(), writePipelineFillSignals(), writeRFCntrlSignals(), and writeSocketCntrlSignals().

Here is the call graph for this function:

◆ writeSimmDataSignal()

void DefaultDecoderGenerator::writeSimmDataSignal ( const TTAMachine::Bus bus,
std::ostream &  stream 
) const
private

Definition at line 2780 of file DefaultDecoderGenerator.cc.

2781 {
2782 int indent;
2783 indent = 4;
2784 SourceField& srcField = bem_.moveSlot(bus.name()).sourceField();
2785 ImmediateEncoding& enc = srcField.immediateEncoding();
2786 stream << indentation(indent) << simmDataSignalName(bus.name()) << " <= ";
2787 if (bus.signExtends()) {
2788 stream << "tce_sxt(";
2789 } else {
2790 stream << "tce_ext(";
2791 }
2792 stream << srcFieldSignal(bus.name()) << "("
2793 << enc.immediatePosition() + enc.immediateWidth() - 1 << " downto "
2794 << enc.immediatePosition() << "), "
2795 << simmDataSignalName(bus.name()) << "'length);" << endl;
2796}

References bem_, SourceField::immediateEncoding(), ImmediateEncoding::immediatePosition(), ImmediateEncoding::immediateWidth(), indentation(), BinaryEncoding::moveSlot(), TTAMachine::Component::name(), TTAMachine::Bus::signExtends(), simmDataSignalName(), MoveSlot::sourceField(), and srcFieldSignal().

Referenced by writeBusControlRulesOfSImmSocketOfBus().

Here is the call graph for this function:

◆ writeSocketCntrlSignals()

void DefaultDecoderGenerator::writeSocketCntrlSignals ( std::ostream &  stream)
private

Writes the socket control signals to the given stream.

Parameters
streamThe stream to write.

Definition at line 1202 of file DefaultDecoderGenerator.cc.

1202 {
1203 writeComment(stream, 1, "socket control signals");
1204
1206 for (int i = 0; i < socketNav.count(); i++) {
1207 Socket* socket = socketNav.item(i);
1208 if (socket->portCount() == 0 || socket->segmentCount() == 0) {
1209 continue;
1210 }
1211
1212 if (needsBusControl(*socket)) {
1213 std::string sigName = socketBusCntrlSignalName(socket->name());
1215 stream, ProGe::BIT_VECTOR, sigName, busControlWidth(*socket));
1216 registerVectors.push_back(sigName);
1217 }
1218 if (needsDataControl(*socket)) {
1219 std::string sigName = socketDataCntrlSignalName(socket->name());
1221 stream, ProGe::BIT_VECTOR, sigName,
1222 dataControlWidth(*socket));
1223 registerVectors.push_back(sigName);
1224 }
1225 }
1226
1227 // write signals for short immediate sockets (not visible in ADF)
1229 for (int i = 0; i < busNav.count(); i++) {
1230 Bus* bus = busNav.item(i);
1231 if (bus->immediateWidth() > 0) {
1233 stream, ProGe::BIT_VECTOR, simmDataSignalName(bus->name()),
1234 simmPortWidth(*bus));
1235 registerVectors.push_back(simmDataSignalName(bus->name()));
1238 1);
1239 registerVectors.push_back(simmCntrlSignalName(bus->name()));
1240 }
1241
1242 if (generateBusEnable_) {
1244 stream, ProGe::BIT, busMuxEnableRegister(*bus), 1);
1245 registerBits.push_back(busMuxEnableRegister(*bus));
1246 }
1247 }
1248}
static std::string busMuxEnableRegister(const TTAMachine::Bus &bus)

References ProGe::BIT, ProGe::BIT_VECTOR, busControlWidth(), busMuxEnableRegister(), TTAMachine::Machine::busNavigator(), TTAMachine::Machine::Navigator< ComponentType >::count(), dataControlWidth(), generateBusEnable_, TTAMachine::Bus::immediateWidth(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, TTAMachine::Component::name(), needsBusControl(), needsDataControl(), TTAMachine::Socket::portCount(), registerBits, registerVectors, TTAMachine::Socket::segmentCount(), simmCntrlSignalName(), simmDataSignalName(), simmPortWidth(), socketBusCntrlSignalName(), socketDataCntrlSignalName(), TTAMachine::Machine::socketNavigator(), writeComment(), and writeSignalDeclaration().

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeSquashSignalGenerationProcess()

void DefaultDecoderGenerator::writeSquashSignalGenerationProcess ( const TTAMachine::Bus bus,
std::ostream &  stream 
) const
private

Writes the generation process of squash signal for the given bus.

Parameters
busThe bus.
streamThe stream to write.

Definition at line 1566 of file DefaultDecoderGenerator.cc.

1568 {
1569 if(language_==VHDL){
1570 assert(bem_.hasMoveSlot(bus.name()));
1571 MoveSlot& slot = bem_.moveSlot(bus.name());
1572 GuardField* grdField = nullptr;
1573 std::set<InstructionTemplate*> affectingInstTemplates =
1575 bool ifClauseStarted = false;
1576
1577 if (!slot.hasGuardField() && affectingInstTemplates.size() == 0) {
1578 // the bus contains always true guard so squash has static value
1579 // Synthesis software should optimize it away
1580 string squashName = squashSignal(bus.name());
1581 stream << indentation(1) << "-- generate signal " << squashName
1582 << endl;
1583 stream << indentation(1) << squashName << " <= '0';" << endl;
1584 return;
1585 }
1586
1587 std::set<string> sensitivyList;
1588 for (int i = 0; i < bus.guardCount(); i++) {
1589 sensitivyList.insert(guardPortName(*bus.guard(i)));
1590 }
1591 if (slot.hasGuardField()) {
1592 sensitivyList.insert(guardFieldSignal(slot.name()));
1593 grdField = &slot.guardField();
1594 }
1595
1596 if (affectingInstTemplates.size() > 0) {
1597 sensitivyList.insert(LIMM_TAG_SIGNAL);
1598 }
1599
1600 stream << indentation(1) << "-- generate signal "
1601 << squashSignal(slot.name()) << endl;
1602 stream << indentation(1) << "process (";
1603 string listStr;
1604 for (const string& signal : sensitivyList) {
1605 TCEString::appendToNonEmpty(listStr, ", ");
1606 listStr += signal;
1607 }
1608 assert(!listStr.empty());
1609 stream << listStr << ")" << endl;
1610 if (slot.hasGuardField()) {
1611 stream << indentation(2) << "variable sel : integer;" << endl;
1612 }
1613 stream << indentation(1) << "begin --process" << endl;
1614 int indLevel = 2;
1615 if (affectingInstTemplates.size() > 0) {
1616 ifClauseStarted = true;
1617 stream << indentation(indLevel) << "if (";
1618 for (set<InstructionTemplate*>::const_iterator iter =
1619 affectingInstTemplates.begin();
1620 iter != affectingInstTemplates.end(); iter++) {
1621 if (iter != affectingInstTemplates.begin()) {
1622 stream << " or " << endl
1623 << indentation(indLevel) << " ";
1624 }
1626 InstructionTemplate* affectingTemp = *iter;
1627 stream << "conv_integer(unsigned(" << LIMM_TAG_SIGNAL
1628 << ")) = "
1629 << icField.templateEncoding(affectingTemp->name());
1630 stream << ") then" << endl;
1631 stream << indentation(indLevel+1) << squashSignal(bus.name())
1632 << " <= '1';" << endl;
1633 }
1634 }
1635
1636 if (ifClauseStarted) {
1637 stream << indentation(indLevel) << "else" << endl;
1638 indLevel += 1;
1639 }
1640 if (grdField != nullptr) {
1641 stream << indentation(indLevel) << "sel := conv_integer(unsigned("
1642 << guardFieldSignal(slot.name()) << "));" << endl;
1643 stream << indentation(indLevel) << "case sel is" << endl;
1644 indLevel++;
1645 for (int i = 0; i < grdField->gprGuardEncodingCount(); i++) {
1646 GPRGuardEncoding& enc = grdField->gprGuardEncoding(i);
1647 RegisterGuard& regGuard = findGuard(enc);
1649 bus, enc, regGuard, stream, indLevel);
1650 }
1651
1652 for (int i = 0; i < grdField->fuGuardEncodingCount(); i++) {
1653 FUGuardEncoding& enc = grdField->fuGuardEncoding(i);
1654 PortGuard& portGuard = findGuard(enc);
1656 bus, enc, portGuard, stream, indLevel);
1657 }
1658
1659 if (grdField->hasUnconditionalGuardEncoding(true)) {
1661 grdField->unconditionalGuardEncoding(true);
1662 stream << indentation(indLevel) << "when " << enc.encoding()
1663 << " => " << endl;
1664 stream << indentation(indLevel + 1)
1665 << squashSignal(slot.name()) << " <= '1';" << endl;
1666 }
1667
1668 stream << indentation(indLevel) << "when others =>" << endl;
1669 stream << indentation(indLevel + 1) << squashSignal(slot.name())
1670 << " <= '0';" << endl;
1671 stream << indentation(indLevel-1) << "end case;" << endl;
1672 } else {
1673 stream << indentation(indLevel) << squashSignal(slot.name())
1674 << " <= '0';" << endl;
1675 }
1676
1677 if (ifClauseStarted) {
1678 ifClauseStarted = false;
1679 stream << indentation(2) << "end if;" << endl;
1680 indLevel -= 1;
1681 assert(indLevel >= 0);
1682 }
1683 stream << indentation(1) << "end process;" << endl << endl;
1684 } else { // language == Verilog
1685 std::set<InstructionTemplate*> affectingInstTemplates =
1687 bool ifClauseStarted = false;
1688
1689 assert(bem_.hasMoveSlot(bus.name()));
1690 MoveSlot& slot = bem_.moveSlot(bus.name());
1691 if (slot.hasGuardField() || affectingInstTemplates.size() > 0) {
1692 GuardField& grdField = slot.guardField();
1693
1694 std::set<string> sensitivyList;
1695 for (int i = 0; i < bus.guardCount(); i++) {
1696 sensitivyList.insert(guardPortName(*bus.guard(i)));
1697 }
1698 if (slot.hasGuardField()) {
1699 sensitivyList.insert(guardFieldSignal(slot.name()));
1700 }
1701
1702 if (affectingInstTemplates.size() > 0) {
1703 sensitivyList.insert(LIMM_TAG_SIGNAL);
1704 }
1705
1706 stream << indentation(1) << "// generate signal "
1707 << squashSignal(slot.name()) << endl;
1708 stream << indentation(1) << "always@(";
1709 string listStr;
1710 for (const string& signal : sensitivyList) {
1711 TCEString::appendToNonEmpty(listStr, ", ");
1712 listStr += signal;
1713 }
1714 assert(!listStr.empty());
1715 stream << listStr << ")" << endl;
1716 stream << indentation(1) << "begin" << endl;
1717 int indLevel = 2;
1718
1719 if (affectingInstTemplates.size() > 0) {
1720 ifClauseStarted = true;
1721 stream << indentation(indLevel) << "if (";
1722 for (set<InstructionTemplate*>::const_iterator iter =
1723 affectingInstTemplates.begin();
1724 iter != affectingInstTemplates.end(); iter++) {
1725 if (iter != affectingInstTemplates.begin()) {
1726 stream << " || ";
1727 }
1728 ImmediateControlField& icField =
1730 InstructionTemplate* affectingTemp = *iter;
1731 stream << LIMM_TAG_SIGNAL
1732 << " == "
1733 << icField.templateEncoding(affectingTemp->name());
1734 }
1735 stream << ")" << endl;
1736 stream << indentation(indLevel+1) << squashSignal(bus.name())
1737 << " <= 1'b1;" << endl;
1738 }
1739
1740 if (ifClauseStarted) {
1741 stream << indentation(indLevel) << "else" << endl;
1742 indLevel++;
1743 }
1744 if (slot.hasGuardField()) {
1745 stream << indentation(indLevel) << "case("
1746 << guardFieldSignal(slot.name()) << ")" << endl;
1747 indLevel++;
1748 for (int i = 0; i < grdField.gprGuardEncodingCount(); i++) {
1749 GPRGuardEncoding& enc = grdField.gprGuardEncoding(i);
1750 RegisterGuard& regGuard = findGuard(enc);
1752 Verilog, bus, enc, regGuard, stream, indLevel);
1753 }
1754
1755 for (int i = 0; i < grdField.fuGuardEncodingCount(); i++) {
1756 FUGuardEncoding& enc = grdField.fuGuardEncoding(i);
1757 PortGuard& portGuard = findGuard(enc);
1759 Verilog, bus, enc, portGuard, stream, indLevel);
1760 }
1761
1762 if (grdField.hasUnconditionalGuardEncoding(true)) {
1764 grdField.unconditionalGuardEncoding(true);
1765 stream << indentation(indLevel) << enc.encoding() << " :"
1766 << endl;
1767 stream << indentation(indLevel + 1)
1768 << squashSignal(slot.name()) << " <= 1'b1;"
1769 << endl;
1770 }
1771
1772 stream << indentation(indLevel) << "default:" << endl;
1773 stream << indentation(indLevel + 1)
1774 << squashSignal(slot.name()) << " <= 1'b0;" << endl;
1775 stream << indentation(indLevel - 1) << "endcase" << endl;
1776 } else {
1777 string squashName = squashSignal(bus.name());
1778 stream << indentation(indLevel) << squashName << " <= 1'b0;"
1779 << endl;
1780 }
1781 stream << indentation(1) << "end" << endl << endl;
1782 } else {
1783 // the bus contains always true guard so squash has static value
1784 // Synthesis software should optimize it away
1785 string squashName = squashSignal(bus.name());
1786 stream << indentation(1) << "// generate signal " << squashName
1787 << endl;
1788 stream << indentation(1) << "assign " << squashName
1789 << " = 1'b0;" << endl;
1790 }
1791 }
1792}
bool hasMoveSlot(const std::string &name) const
static void writeSquashSignalSubstitution(const ProGe::HDL language, const TTAMachine::Bus &bus, const GuardEncoding &enc, const TTAMachine::Guard &guard, std::ostream &stream, int indLevel)
TTAMachine::RegisterGuard & findGuard(const GPRGuardEncoding &encoding) const
unsigned int encoding() const
FUGuardEncoding & fuGuardEncoding(int index) const
bool hasUnconditionalGuardEncoding(bool inverted) const
int gprGuardEncodingCount() const
UnconditionalGuardEncoding & unconditionalGuardEncoding(bool inverted) const
GPRGuardEncoding & gprGuardEncoding(int index) const
int fuGuardEncodingCount() const
static std::set< TTAMachine::InstructionTemplate * > templatesUsingSlot(const TTAMachine::Machine &mach, const std::string &slotName)
static std::string & appendToNonEmpty(std::string &toAppend, stringCRef appender)
Definition TCEString.cc:201

References TCEString::appendToNonEmpty(), assert, bem_, GuardEncoding::encoding(), findGuard(), GuardField::fuGuardEncoding(), GuardField::fuGuardEncodingCount(), GuardField::gprGuardEncoding(), GuardField::gprGuardEncodingCount(), TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), MoveSlot::guardField(), guardFieldSignal(), guardPortName(), MoveSlot::hasGuardField(), BinaryEncoding::hasMoveSlot(), GuardField::hasUnconditionalGuardEncoding(), BinaryEncoding::immediateControlField(), indentation(), language_, LIMM_TAG_SIGNAL, machine_, BinaryEncoding::moveSlot(), MoveSlot::name(), TTAMachine::Component::name(), squashSignal(), ImmediateControlField::templateEncoding(), MachineInfo::templatesUsingSlot(), GuardField::unconditionalGuardEncoding(), ProGe::Verilog, ProGe::VHDL, and writeSquashSignalSubstitution().

Referenced by writeSquashSignalGenerationProcesses().

Here is the call graph for this function:

◆ writeSquashSignalGenerationProcesses()

void DefaultDecoderGenerator::writeSquashSignalGenerationProcesses ( std::ostream &  stream) const
private

Writes the generation processes of squash signals to the given stream.

Parameters
streamThe stream.

Definition at line 1548 of file DefaultDecoderGenerator.cc.

1549 {
1550
1552 for (int i = 0; i < busNav.count(); i++) {
1553 Bus* bus = busNav.item(i);
1555 }
1556}
void writeSquashSignalGenerationProcess(const TTAMachine::Bus &bus, std::ostream &stream) const

References TTAMachine::Machine::busNavigator(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, and writeSquashSignalGenerationProcess().

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeSquashSignals()

void DefaultDecoderGenerator::writeSquashSignals ( std::ostream &  stream) const
private

Writes the squash signals of guards to the given stream.

Parameters
streamThe stream.

Definition at line 1169 of file DefaultDecoderGenerator.cc.

1170 {
1171
1172 TCEString comment = language_ == VHDL ? "-- " : "// ";
1174 stream << indentation(1) << comment << "squash signals" << endl;
1175 for (int i = 0; i < busNav.count(); i++) {
1176 Bus* bus = busNav.item(i);
1177 stream << indentation(1);
1178 if (language_ == VHDL) {
1179 stream << "signal " << squashSignal(bus->name())
1180 << " : std_logic;" << endl;
1181 } else {
1182 assert(bem_.hasMoveSlot(bus->name()));
1183 MoveSlot& slot = bem_.moveSlot(bus->name());
1184 if (slot.hasGuardField()) {
1185 stream << "reg ";
1186 } else {
1187 // Declare guard signal as wire for constant assignment
1188 stream << "wire ";
1189 }
1190 stream << squashSignal(bus->name()) << ";" << endl;
1191 }
1192 }
1193}

References assert, bem_, TTAMachine::Machine::busNavigator(), TTAMachine::Machine::Navigator< ComponentType >::count(), MoveSlot::hasGuardField(), BinaryEncoding::hasMoveSlot(), indentation(), TTAMachine::Machine::Navigator< ComponentType >::item(), language_, machine_, BinaryEncoding::moveSlot(), TTAMachine::Component::name(), squashSignal(), and ProGe::VHDL.

Referenced by writeInstructionDecoder().

Here is the call graph for this function:

◆ writeSquashSignalSubstitution()

void DefaultDecoderGenerator::writeSquashSignalSubstitution ( const ProGe::HDL  language,
const TTAMachine::Bus bus,
const GuardEncoding enc,
const TTAMachine::Guard guard,
std::ostream &  stream,
int  indLevel 
)
staticprivate

Writes substitution of guard value to the squash signal of the given bus.

Parameters
busThe bus.
encThe guard encoding.
guardThe guard.
streamThe stream to write.
indLevelThe indentation level.

Definition at line 3935 of file DefaultDecoderGenerator.cc.

3941 {
3942 if(language==VHDL){
3943 stream << indentation(indLevel) << "when " << enc.encoding()
3944 << " =>" << endl;
3945 stream << indentation(indLevel+1) << squashSignal(bus.name()) << " <= ";
3946 if (!guard.isInverted()) {
3947 stream << "not ";
3948 }
3949 stream << guardPortName(guard) << ";" << endl;
3950 } else {
3951 stream << indentation(indLevel) << enc.encoding() << " : "
3952 << squashSignal(bus.name()) << " = ";
3953 if (!guard.isInverted()) {
3954 stream << " !";
3955 }
3956 stream << guardPortName(guard) << ";" << endl;
3957 }
3958}

References GuardEncoding::encoding(), guardPortName(), indentation(), TTAMachine::Guard::isInverted(), TTAMachine::Component::name(), squashSignal(), and ProGe::VHDL.

Referenced by writeSquashSignalGenerationProcess().

Here is the call graph for this function:

Member Data Documentation

◆ bem_

const BinaryEncoding& DefaultDecoderGenerator::bem_
private

◆ decoderBlock_

ProGe::NetlistBlock* DefaultDecoderGenerator::decoderBlock_
private

The instruction decoder block in the netlist.

Definition at line 327 of file DefaultDecoderGenerator.hh.

Referenced by addGlockPortToDecoder(), addLockReqPortToDecoder(), completeDecoderBlock(), writeControlRegisterMappings(), and writeInstructionDecoder().

◆ entityNameStr_

TCEString DefaultDecoderGenerator::entityNameStr_
private

Definition at line 330 of file DefaultDecoderGenerator.hh.

Referenced by completeDecoderBlock(), and writeInstructionDecoder().

◆ generateAlternateGlockReqHandling_

bool DefaultDecoderGenerator::generateAlternateGlockReqHandling_
private

The flag to generate global lock request handling in decoder. False means delegating the lock request towards instruction fetch.

Definition at line 342 of file DefaultDecoderGenerator.hh.

Referenced by setGenerateNoLoopbackGlock(), and writeGlockMapping().

◆ generateBusEnable_

bool DefaultDecoderGenerator::generateBusEnable_
private

Bus enable signals for bustrace.

Definition at line 337 of file DefaultDecoderGenerator.hh.

Referenced by setGenerateBusEnable(), and writeSocketCntrlSignals().

◆ generateDebugger_

bool DefaultDecoderGenerator::generateDebugger_
private

Generate debugger signals?

Definition at line 333 of file DefaultDecoderGenerator.hh.

Referenced by completeDecoderBlock(), glockRequestWidth(), setGenerateDebugger(), and writeMainDecodingProcess().

◆ generateLockTrace_

bool DefaultDecoderGenerator::generateLockTrace_
private

Tells whether to generate global lock tracing code.

Definition at line 329 of file DefaultDecoderGenerator.hh.

Referenced by setGenerateLockTrace(), and writeInstructionDecoder().

◆ GLOCK_PORT_NAME

const string DefaultDecoderGenerator::GLOCK_PORT_NAME = "glock"
static

◆ icGenerator_

const CentralizedControlICGenerator& DefaultDecoderGenerator::icGenerator_
private

◆ language_

ProGe::HDL DefaultDecoderGenerator::language_
private

◆ lockTraceStartingCycle_

unsigned int DefaultDecoderGenerator::lockTraceStartingCycle_
private

The starting cycle for bus tracing.

Definition at line 339 of file DefaultDecoderGenerator.hh.

Referenced by setLockTraceStartingCycle(), and writeLockDumpCode().

◆ machine_

const TTAMachine::Machine& DefaultDecoderGenerator::machine_
private

◆ nlGenerator_

const ProGe::NetlistGenerator* DefaultDecoderGenerator::nlGenerator_
private

◆ registerBits

std::vector<std::string> DefaultDecoderGenerator::registerBits
private

◆ registerVectors

std::vector<std::string> DefaultDecoderGenerator::registerVectors
private

Bookkeeping for reset-needing signals.

Definition at line 349 of file DefaultDecoderGenerator.hh.

Referenced by writeFUCntrlSignals(), writeResettingOfControlRegisters(), writeRFCntrlSignals(), and writeSocketCntrlSignals().

◆ RISCV_SIMM_PORT_IN_NAME

const string DefaultDecoderGenerator::RISCV_SIMM_PORT_IN_NAME = "simm_in"
static

◆ syncReset_

bool DefaultDecoderGenerator::syncReset_
private

Reset synchronously (otherwise asynchronous)

Definition at line 335 of file DefaultDecoderGenerator.hh.

Referenced by setSyncReset(), writeGlockMapping(), writeLongImmediateWriteProcess(), writeMainDecodingProcess(), and writePipelineFillProcess().

◆ unitGlockBitMap_

UnitGlockBitMapType DefaultDecoderGenerator::unitGlockBitMap_
private

Maps connected glock port bits to associated TTA Units.

Definition at line 344 of file DefaultDecoderGenerator.hh.

Referenced by addGlockPortToDecoder(), and writeGlockMapping().

◆ unitGlockReqBitMap_

UnitGlockReqBitMapType DefaultDecoderGenerator::unitGlockReqBitMap_
private

Maps TTA Units to associated glock request port bits.

Definition at line 346 of file DefaultDecoderGenerator.hh.

Referenced by addLockReqPortToDecoder(), and writeGlockMapping().


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