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

#include <RV32MicroCodeGenerator.hh>

Inheritance diagram for ProGe::RV32MicroCodeGenerator:
Inheritance graph
Collaboration diagram for ProGe::RV32MicroCodeGenerator:
Collaboration graph

Public Member Functions

 RV32MicroCodeGenerator (const Machine &machine, const BinaryEncoding &bem, const std::string &entityName)
 
 ~RV32MicroCodeGenerator ()
 
void generateRTL (HDLTemplateInstantiator &instantiator, const std::string &fileDst)
 
void setBypassInstructionRegister (const bool &value)
 
- Public Member Functions inherited from ProGe::MicroCodeGenerator
 MicroCodeGenerator (const Machine &machine, const BinaryEncoding &bem, const std::string &entityName)
 
 ~MicroCodeGenerator ()=default
 

Private Member Functions

void initializeOperations ()
 
void findOperationSources ()
 
void generateFUTargetProcess (std::ofstream &stream)
 
void addRs1ForwardingConditions (std::map< std::string, std::string > ops, std::unordered_map< std::string, InstructionBitVector * >(ProGe::RV32MicroCodeGenerator::*instructionFunc)(Port *p1, Port *p2) const, std::ofstream &stream) const
 
void addRs2ForwardingConditions (std::map< std::string, std::string > ops, std::unordered_map< std::string, InstructionBitVector * >(ProGe::RV32MicroCodeGenerator::*instructionFunc)(Port *p1, Port *p2) const, std::ofstream &stream) const
 
std::string generateOperationLatencyLogic (HDLTemplateInstantiator &instantiator)
 
std::set< Port * > operationPorts (const std::unordered_map< std::string, BaseFUPort * > &ports) const
 
void validateOperations () const
 
FunctionUnitmapFunctionUnit (const std::string &operation) const
 
void addR1Ports (const std::string &opName)
 
void addR1RPorts (const std::string &opName)
 
void addRPorts (const std::string &opName)
 
void addIPorts (const std::string &opName)
 
void addSPorts (const std::string &opName)
 
void addBPorts (const std::string &opName)
 
void addUJPorts (const std::string &opName)
 
void findOperationPorts ()
 
void connectRF ()
 
void findRF ()
 
void findBusWidths ()
 
bool findConnectedBusses (Connection &rs1, Connection &rs2, Connection &rd, Connection &simm, const bool &forwarding) const
 
std::unordered_map< std::string, InstructionBitVector * > constructRInstructions (Port *src1, Port *src2) const
 
std::unordered_map< std::string, InstructionBitVector * > constructIInstructions (Port *src1, Port *src2) const
 
std::unordered_map< std::string, InstructionBitVector * > constructSInstructions (Port *src1, Port *src2) const
 
std::unordered_map< std::string, InstructionBitVector * > constructBInstructions (Port *src1, Port *src2) const
 
std::unordered_map< std::string, InstructionBitVector * > constructUJInstructions () const
 
std::unordered_map< std::string, InstructionBitVector * > constructR1RInstructions (Port *src1, Port *src2) const
 
std::unordered_map< std::string, InstructionBitVector * > constructR1Instructions (Port *src1, Port *src2) const
 
void addBitsToMap (std::unordered_map< std::string, InstructionBitVector * > instructions, const std::map< std::string, std::string > encodings, std::ofstream &stream) const
 
void generateMap (const std::string &dstDirectory)
 
void generateWrapper (HDLTemplateInstantiator &instantiator, const std::string &fileDst)
 
void generateNOP ()
 
void throwOperationNotFoundError (const std::string &op) const
 
void throwTriggeringPortError (const BaseFUPort *port, const std::string &type) const
 
void throwInputPortError (const BaseFUPort *port, const std::string &type) const
 
void throwOutputPortError (const BaseFUPort *port, const std::string &type) const
 
void throwOperandCountError (const std::string &op, int required, int found) const
 

Private Attributes

std::unordered_map< std::string, BaseFUPort * > rs1Ports_
 
std::unordered_map< std::string, BaseFUPort * > rs2Ports_
 
std::unordered_map< std::string, BaseFUPort * > rdPorts_
 
std::unordered_map< std::string, BaseFUPort * > simmPorts_
 
std::unordered_map< Port *, int > sourcePortID_
 
std::unordered_map< Port *, std::vector< std::string > > sourceOperationMap_
 
std::map< std::string, std::string > rOperations_
 
std::map< std::string, std::string > r1rOperations_
 
std::map< std::string, std::string > r1Operations_
 
std::map< std::string, std::string > iOperations_
 
std::map< std::string, std::string > sOperations_
 
std::map< std::string, std::string > bOperations_
 
std::map< std::string, std::string > ujOperations_
 
std::vector< Bus * > busses_
 
RegisterFileRF_
 
int rs1BusWidth_
 
int rs2BusWidth_
 
int rdBusWidth_
 
int simmBusWidth_
 
int rs1BusStart_
 
int rs2BusStart_
 
int rdBusStart_
 
int simmBusStart_
 
int rs1RFStart_
 
int rs2RFStart_
 
int rdRFStart_
 
int simmRFStart_
 
Busrs1Bus_
 
Busrs2Bus_
 
BusrdBus_
 
BussimmBus_
 
RFPortrs1RFPort_
 
RFPortrs2RFPort_
 
RFPortrdRFPort_
 
ProgramImageGeneratorpig_
 
std::string NOP_
 
bool bypassInstructionRegister_
 
bool hasForwarding_
 
bool variableLengthOpLatency_
 
bool eVariant_
 
bool hasCustom0Operations_
 

Additional Inherited Members

- Protected Attributes inherited from ProGe::MicroCodeGenerator
const Machinemachine_
 
const BinaryEncodingbem_
 
const std::string entityName_
 

Detailed Description

Definition at line 67 of file RV32MicroCodeGenerator.hh.

Constructor & Destructor Documentation

◆ RV32MicroCodeGenerator()

ProGe::RV32MicroCodeGenerator::RV32MicroCodeGenerator ( const Machine machine,
const BinaryEncoding bem,
const std::string &  entityName 
)

Definition at line 81 of file RV32MicroCodeGenerator.cc.

84 :
85 MicroCodeGenerator(machine, bem, entityName),
86 RF_(NULL),
87 rs1Bus_(NULL),
88 rs2Bus_(NULL),
89 rdBus_(NULL),
90 rs1RFPort_(NULL),
91 rs2RFPort_(NULL),
92 rdRFPort_(NULL),
94 NOP_(""),
96 hasForwarding_(false),
98 eVariant_(false),
101 for (int i = 0; i < busNav.count(); i++) {
102 busses_.push_back(busNav.item(i));
103 }
104
106
109
110 pig_->loadBEM(bem);
112
113 generateNOP();
114
115 findRF();
116 connectRF();
119 if (hasForwarding_) {
120 std::cout << "Generated bypass logic" << std::endl;
121 } else {
122 std::cout << "Not required connectivity for bypass logic"
123 << std::endl;
124 }
125 }
126}
TTAMachine::Machine * machine
the architecture definition of the estimated processor
#define RV32_RTL_GEN_VERBOSE
MicroCodeGenerator(const Machine &machine, const BinaryEncoding &bem, const std::string &entityName)
void loadMachine(const TTAMachine::Machine &machine)
void loadBEM(const BinaryEncoding &bem)
ComponentType * item(int index) const
virtual BusNavigator busNavigator() const
Definition Machine.cc:356

References TTAMachine::Machine::busNavigator(), busses_, connectRF(), TTAMachine::Machine::Navigator< ComponentType >::count(), findBusWidths(), findOperationPorts(), findOperationSources(), findRF(), generateNOP(), hasForwarding_, initializeOperations(), TTAMachine::Machine::Navigator< ComponentType >::item(), ProgramImageGenerator::loadBEM(), ProgramImageGenerator::loadMachine(), machine, pig_, and RV32_RTL_GEN_VERBOSE.

Here is the call graph for this function:

◆ ~RV32MicroCodeGenerator()

ProGe::RV32MicroCodeGenerator::~RV32MicroCodeGenerator ( )

Definition at line 128 of file RV32MicroCodeGenerator.cc.

128{ delete pig_; }

References pig_.

Member Function Documentation

◆ addBitsToMap()

void ProGe::RV32MicroCodeGenerator::addBitsToMap ( std::unordered_map< std::string, InstructionBitVector * >  instructions,
const std::map< std::string, std::string >  encodings,
std::ofstream &  stream 
) const
private

Definition at line 1077 of file RV32MicroCodeGenerator.cc.

1080 {
1081 assert(instructions.size() == encodings.size());
1082 for (const auto& op : instructions) {
1083 stream << " elsif(fu_opcode(" << encodings.at(op.first).size()
1084 << " - 1 downto 0) = "
1085 << "\"" << encodings.at(op.first) << "\""
1086 << ") then" << std::endl
1087 << " moves <= \"" << op.second->toString() << "\";"
1088 << std::endl;
1089 delete op.second;
1090 }
1091}
#define assert(condition)

References assert.

◆ addBPorts()

void ProGe::RV32MicroCodeGenerator::addBPorts ( const std::string &  opName)
private

Definition at line 437 of file RV32MicroCodeGenerator.cc.

437 {
438 FunctionUnit* fu = mapFunctionUnit(opName);
439 HWOperation* op = fu->operation(opName);
440 if (op->operandCount() != 3) {
441 throwOperandCountError(opName, 3, op->operandCount());
442 }
443 FUPort* simmPort = op->port(1);
444 FUPort* rs1Port = op->port(2);
445 FUPort* rs2Port = op->port(3);
446 if (!simmPort->isTriggering()) {
447 throwTriggeringPortError(simmPort, "imm");
448 } else if (!rs1Port->isInput()) {
449 throwInputPortError(rs1Port, "rs1");
450 } else if (!rs2Port->isInput()) {
451 throwInputPortError(rs1Port, "rs2");
452 }
453 rs1Ports_.insert({opName, rs1Port});
454 simmPorts_.insert({opName, simmPort});
455 rs2Ports_.insert({opName, rs2Port});
456}
std::unordered_map< std::string, BaseFUPort * > rs1Ports_
FunctionUnit * mapFunctionUnit(const std::string &operation) const
std::unordered_map< std::string, BaseFUPort * > simmPorts_
std::unordered_map< std::string, BaseFUPort * > rs2Ports_
void throwTriggeringPortError(const BaseFUPort *port, const std::string &type) const
void throwOperandCountError(const std::string &op, int required, int found) const
void throwInputPortError(const BaseFUPort *port, const std::string &type) const
virtual bool isTriggering() const
Definition FUPort.cc:182
virtual HWOperation * operation(const std::string &name) const
virtual FUPort * port(int operand) const
virtual bool isInput() const
Definition Port.cc:298

References TTAMachine::Port::isInput(), TTAMachine::FUPort::isTriggering(), mapFunctionUnit(), TTAMachine::HWOperation::operandCount(), TTAMachine::FunctionUnit::operation(), TTAMachine::HWOperation::port(), rs1Ports_, rs2Ports_, simmPorts_, throwInputPortError(), throwOperandCountError(), and throwTriggeringPortError().

Referenced by findOperationPorts().

Here is the call graph for this function:

◆ addIPorts()

void ProGe::RV32MicroCodeGenerator::addIPorts ( const std::string &  opName)
private

Definition at line 408 of file RV32MicroCodeGenerator.cc.

408 {
409 if (rOperations_.count(opName)) {
410 return;
411 }
412 FunctionUnit* fu = mapFunctionUnit(opName);
413 HWOperation* op = fu->operation(opName);
414 const int operandCount = (opName == "calla") ? 2 : 3;
415 if (op->operandCount() != operandCount) {
416 throwOperandCountError(opName, operandCount, op->operandCount());
417 }
418 FUPort* rs1Port = op->port(1);
419 FUPort* simmPort = op->port(2);
420 BaseFUPort* rdPort;
421 if (opName != "calla") {
422 rdPort = op->port(3);
423 if (!rdPort->isOutput()) {
424 throwOutputPortError(rdPort, "rd");
425 }
426 } else {
427 rs1Port = op->port(2);
428 simmPort = op->port(1);
430 }
431 rs1Ports_.insert({opName, rs1Port});
432 simmPorts_.insert({opName, simmPort});
433 rdPorts_.insert({opName, rdPort});
434}
std::unordered_map< std::string, BaseFUPort * > rdPorts_
void throwOutputPortError(const BaseFUPort *port, const std::string &type) const
std::map< std::string, std::string > rOperations_
SpecialRegisterPort * returnAddressPort() const
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
virtual bool isOutput() const
Definition Port.cc:308

References TTAMachine::Machine::controlUnit(), TTAMachine::Port::isOutput(), ProGe::MicroCodeGenerator::machine_, mapFunctionUnit(), TTAMachine::HWOperation::operandCount(), TTAMachine::FunctionUnit::operation(), TTAMachine::HWOperation::port(), rdPorts_, TTAMachine::ControlUnit::returnAddressPort(), rOperations_, rs1Ports_, simmPorts_, throwOperandCountError(), and throwOutputPortError().

Referenced by findOperationPorts().

Here is the call graph for this function:

◆ addR1Ports()

void ProGe::RV32MicroCodeGenerator::addR1Ports ( const std::string &  opName)
private

Definition at line 394 of file RV32MicroCodeGenerator.cc.

394 {
395 FunctionUnit* fu = mapFunctionUnit(opName);
396 HWOperation* op = fu->operation(opName);
397 if (op->operandCount() != 1) {
398 throwOperandCountError(opName, 1, op->operandCount());
399 }
400 FUPort* rs1Port = op->port(1);
401 if (!rs1Port->isTriggering()) {
402 throwTriggeringPortError(rs1Port, "rs1");
403 }
404 rs1Ports_.insert({opName, rs1Port});
405}

References TTAMachine::FUPort::isTriggering(), mapFunctionUnit(), TTAMachine::HWOperation::operandCount(), TTAMachine::FunctionUnit::operation(), TTAMachine::HWOperation::port(), rs1Ports_, throwOperandCountError(), and throwTriggeringPortError().

Referenced by findOperationPorts().

Here is the call graph for this function:

◆ addR1RPorts()

void ProGe::RV32MicroCodeGenerator::addR1RPorts ( const std::string &  opName)
private

Definition at line 375 of file RV32MicroCodeGenerator.cc.

375 {
376 FunctionUnit* fu = mapFunctionUnit(opName);
377 HWOperation* op = fu->operation(opName);
378 if (op->operandCount() != 2) {
379 throwOperandCountError(opName, 2, op->operandCount());
380 }
381 FUPort* rs1Port = op->port(1);
382 FUPort* rdPort = op->port(2);
383 if (!rs1Port->isTriggering()) {
384 throwTriggeringPortError(rs1Port, "rs1");
385 }
386 if (!rdPort->isOutput()) {
387 throwOutputPortError(rdPort, "rd");
388 }
389 rs1Ports_.insert({opName, rs1Port});
390 rdPorts_.insert({opName, rdPort});
391}

References TTAMachine::Port::isOutput(), TTAMachine::FUPort::isTriggering(), mapFunctionUnit(), TTAMachine::HWOperation::operandCount(), TTAMachine::FunctionUnit::operation(), TTAMachine::HWOperation::port(), rdPorts_, rs1Ports_, throwOperandCountError(), throwOutputPortError(), and throwTriggeringPortError().

Referenced by findOperationPorts().

Here is the call graph for this function:

◆ addRPorts()

void ProGe::RV32MicroCodeGenerator::addRPorts ( const std::string &  opName)
private

Definition at line 341 of file RV32MicroCodeGenerator.cc.

341 {
342 FunctionUnit* fu = mapFunctionUnit(opName);
343 HWOperation* op = fu->operation(opName);
344 if (op->operandCount() != 3) {
345 throwOperandCountError(opName, 3, op->operandCount());
346 }
347 FUPort* rs1Port = op->port(1);
348 FUPort* rs2Port = op->port(2);
349 FUPort* rdPort = op->port(3);
350 if (!rs1Port->isTriggering()) {
351 throwTriggeringPortError(rs1Port, "rs1");
352 }
353 if (!rs2Port->isInput()) {
354 throwInputPortError(rs2Port, "rs2");
355 }
356 if (!rdPort->isOutput()) {
357 throwOutputPortError(rdPort, "rd");
358 }
359 rs1Ports_.insert({opName, rs1Port});
360 rs2Ports_.insert({opName, rs2Port});
361 // Do not add custom ops to simm ports
363 const std::string riscvOpName =MapTools::keyForValue
364 <string, map<string, string>, string>(RISCVFields::RISCVOperationNameTable, opName);
365 // Do not add M-extension ops
367 riscvOpName)) {
368 simmPorts_.insert({opName, rs2Port});
369 }
370 }
371 rdPorts_.insert({opName, rdPort});
372}
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)
static bool containsValue(const MapType &aMap, const ValueType &aValue)
static bool containsValue(const ContainerType &aVec, const ValueType &aValue)
const std::vector< std::string > RISCVMExtensionOperations
const std::map< std::string, std::string > RISCVOperationNameTable

References VectorTools::containsValue(), MapTools::containsValue(), TTAMachine::Port::isInput(), TTAMachine::Port::isOutput(), TTAMachine::FUPort::isTriggering(), MapTools::keyForValue(), mapFunctionUnit(), TTAMachine::HWOperation::operandCount(), TTAMachine::FunctionUnit::operation(), TTAMachine::HWOperation::port(), rdPorts_, RISCVFields::RISCVMExtensionOperations, RISCVFields::RISCVOperationNameTable, rs1Ports_, rs2Ports_, simmPorts_, throwInputPortError(), throwOperandCountError(), throwOutputPortError(), and throwTriggeringPortError().

Referenced by findOperationPorts().

Here is the call graph for this function:

◆ addRs1ForwardingConditions()

void ProGe::RV32MicroCodeGenerator::addRs1ForwardingConditions ( std::map< std::string, std::string >  ops,
std::unordered_map< std::string, InstructionBitVector * >(ProGe::RV32MicroCodeGenerator::*)(Port *p1, Port *p2) const  instructionFunc,
std::ofstream &  stream 
) const
private

Definition at line 1167 of file RV32MicroCodeGenerator.cc.

1172 {
1173 if (ops.size() == 0) {
1174 return;
1175 }
1176 bool firstOpcodeCond = true;
1177 for (const auto& op : ops) {
1178 std::string opcodeCond = " elsif ";
1179 if (firstOpcodeCond) {
1180 opcodeCond = " if ";
1181 firstOpcodeCond = false;
1182 }
1183 stream << opcodeCond << "fu_opcode(" << op.second.size()
1184 << "-1 downto 0) = \"" << op.second << "\"";
1185 if (rOperations_.count(op.first) && iOperations_.count(op.first)) {
1186 stream << " or fu_opcode(" << iOperations_.at(op.first).size()
1187 << "-1 downto 0) = \"" << iOperations_.at(op.first)
1188 << "\"";
1189 }
1190 stream << "then\n";
1191 bool firstTargetCond = true;
1192 for (const auto& p : sourceOperationMap_) {
1193 std::string targetCond = " elsif ";
1194 if (firstTargetCond) {
1195 targetCond = " if ";
1196 firstTargetCond = false;
1197 }
1198 stream << targetCond + "target_fu_r = "
1199 << sourcePortID_.at(p.first) << " then \n";
1200 std::unordered_map<std::string, InstructionBitVector*>
1201 instructions = (this->*instructionFunc)(p.first, rs2RFPort_);
1202 std::string bits = instructions.at(op.first)->toString();
1203 reverse(bits.begin(), bits.end());
1204 bits = bits.substr(rs1BusStart_, rs1BusWidth_);
1205 reverse(bits.begin(), bits.end());
1206 stream << " moves(rs1_start_c + rs1_width_c -1 downto"
1207 << " rs1_start_c)"
1208 << " <= \"" << bits << "\";\n";
1209 for (const auto& val : instructions) {
1210 delete val.second;
1211 }
1212 }
1213 stream << " end if;" << std::endl;
1214 }
1215 stream << " end if;" << std::endl;
1216}
std::map< std::string, std::string > iOperations_
std::unordered_map< Port *, std::vector< std::string > > sourceOperationMap_
std::unordered_map< Port *, int > sourcePortID_

◆ addRs2ForwardingConditions()

void ProGe::RV32MicroCodeGenerator::addRs2ForwardingConditions ( std::map< std::string, std::string >  ops,
std::unordered_map< std::string, InstructionBitVector * >(ProGe::RV32MicroCodeGenerator::*)(Port *p1, Port *p2) const  instructionFunc,
std::ofstream &  stream 
) const
private

Definition at line 1219 of file RV32MicroCodeGenerator.cc.

1224 {
1225 bool firstOpcodeCond = true;
1226 for (const auto& op : ops) {
1227 std::string opcodeCond = " elsif ";
1228 if (firstOpcodeCond) {
1229 opcodeCond = " if ";
1230 firstOpcodeCond = false;
1231 }
1232 stream << opcodeCond << "fu_opcode(" << op.second.size()
1233 << "-1 downto 0) = \"" << op.second << "\" then\n";
1234 bool firstTargetCond = true;
1235 for (const auto& p : sourceOperationMap_) {
1236 std::string targetCond = " elsif ";
1237 if (firstTargetCond) {
1238 targetCond = " if ";
1239 firstTargetCond = false;
1240 }
1241 stream << targetCond + "target_fu_r = "
1242 << sourcePortID_.at(p.first) << " then \n";
1243 std::unordered_map<std::string, InstructionBitVector*>
1244 instructions = (this->*instructionFunc)(rs1RFPort_, p.first);
1245 std::string bits = instructions.at(op.first)->toString();
1246 reverse(bits.begin(), bits.end());
1247 bits = bits.substr(rs2BusStart_, rs2BusWidth_);
1248 reverse(bits.begin(), bits.end());
1249 stream << " moves(rs2_start_c + rs2_width_c -1 downto"
1250 << " rs2_start_c)"
1251 << " <= \"" << bits << "\";\n";
1252 for (const auto& val : instructions) {
1253 delete val.second;
1254 }
1255 }
1256 stream << " end if;" << std::endl;
1257 }
1258 stream << " end if;" << std::endl;
1259}

◆ addSPorts()

void ProGe::RV32MicroCodeGenerator::addSPorts ( const std::string &  opName)
private

Definition at line 483 of file RV32MicroCodeGenerator.cc.

483 {
484 FunctionUnit* fu = mapFunctionUnit(opName);
485 HWOperation* op = fu->operation(opName);
486 if (op->operandCount() != 3) {
487 throwOperandCountError(opName, 3, op->operandCount());
488 }
489 FUPort* rs1Port = op->port(1);
490 FUPort* simmPort = op->port(2);
491 FUPort* rs2Port = op->port(3);
492 if (!rs1Port->isTriggering()) {
493 throwTriggeringPortError(rs1Port, "rs1");
494 }
495 if (!rs2Port->isInput()) {
496 throwInputPortError(rs2Port, "rs2");
497 }
498 if (!simmPort->isInput()) {
499 throwInputPortError(simmPort, "imm");
500 }
501 rs1Ports_.insert({opName, rs1Port});
502 simmPorts_.insert({opName, simmPort});
503 rs2Ports_.insert({opName, rs2Port});
504}

References TTAMachine::Port::isInput(), TTAMachine::FUPort::isTriggering(), mapFunctionUnit(), TTAMachine::HWOperation::operandCount(), TTAMachine::FunctionUnit::operation(), TTAMachine::HWOperation::port(), rs1Ports_, rs2Ports_, simmPorts_, throwInputPortError(), throwOperandCountError(), and throwTriggeringPortError().

Referenced by findOperationPorts().

Here is the call graph for this function:

◆ addUJPorts()

void ProGe::RV32MicroCodeGenerator::addUJPorts ( const std::string &  opName)
private

Definition at line 459 of file RV32MicroCodeGenerator.cc.

459 {
460 if (opName == "move") {
461 return;
462 }
463 ControlUnit* fu = dynamic_cast<ControlUnit*>(mapFunctionUnit(opName));
464 HWOperation* op = fu->operation(opName);
465 FUPort* simmPort = op->port(1);
466 BaseFUPort* rdPort;
467 if (opName == "apc") {
468 rdPort = op->port(2);
469 if (!rdPort->isOutput()) {
470 throwOutputPortError(rdPort, "rd");
471 }
472 } else {
473 rdPort = fu->returnAddressPort();
474 }
475 if (!simmPort->isTriggering()) {
476 throwTriggeringPortError(simmPort, "imm");
477 }
478 rdPorts_.insert({opName, rdPort});
479 simmPorts_.insert({opName, simmPort});
480}

References TTAMachine::Port::isOutput(), TTAMachine::FUPort::isTriggering(), mapFunctionUnit(), TTAMachine::FunctionUnit::operation(), TTAMachine::HWOperation::port(), rdPorts_, TTAMachine::ControlUnit::returnAddressPort(), simmPorts_, throwOutputPortError(), and throwTriggeringPortError().

Referenced by findOperationPorts().

Here is the call graph for this function:

◆ connectRF()

void ProGe::RV32MicroCodeGenerator::connectRF ( )
private

Definition at line 594 of file RV32MicroCodeGenerator.cc.

594 {
595 RFPort* rs1RFPort = NULL;
596 RFPort* rs2RFPort = NULL;
597 RFPort* rdRFPort = NULL;
598
599 std::vector<RFPort*> RFOutputPorts;
600 std::vector<RFPort*> RFInputPorts;
601 for (int i = 0; i < RF_->portCount(); i++) {
602 RFPort* tmpPort = RF_->port(i);
603 if (tmpPort->outputSocket() != NULL) {
604 RFOutputPorts.push_back(tmpPort);
605 } else if (tmpPort->inputSocket() != NULL) {
606 RFInputPorts.push_back(tmpPort);
607 }
608 }
609
610 assert(RFInputPorts.size() > 0);
611 assert(RFOutputPorts.size() > 1);
612
613 Connection rs1;
614 Connection rs2;
615 Connection rd;
616 Connection simm;
617
618 // Find candidates for rs1, rs2 and rd busses.
619 bool success = false;
620 bool forwarding = false;
621 for (int l = 0; l < 2 && !success; l++) {
622 // First try with forwarding enabled
623 forwarding = !forwarding;
624 for (unsigned int i = 0; i < RFOutputPorts.size() && !success; i++) {
625 std::vector<RFPort*> tmpRFOutputPorts = RFOutputPorts;
626 rs1RFPort = RFOutputPorts.at(i);
627 tmpRFOutputPorts.erase(tmpRFOutputPorts.begin() + i);
628 for (unsigned int j = 0; j < tmpRFOutputPorts.size() && !success;
629 j++) {
630 rs2RFPort = tmpRFOutputPorts.at(j);
631 for (unsigned int k = 0; k < RFInputPorts.size() && !success;
632 k++) {
633 std::vector<RFPort*> tmpRFInputPorts;
634 tmpRFInputPorts = RFInputPorts;
635 rdRFPort = RFInputPorts.at(k);
636
637 rs1.port = rs1RFPort;
638 rs2.port = rs2RFPort;
639 rd.port = rdRFPort;
640
641 rs1.bus = NULL;
642 rs2.bus = NULL;
643 rd.bus = NULL;
644 simm.bus = NULL;
645
646 success =
647 findConnectedBusses(rs1, rs2, rd, simm, forwarding);
648 if (success) {
649 break;
650 }
651 }
652 }
653 }
654 }
655
656 if (!success) {
657 std::string msg =
658 "Could not find enough connectivity in the "
659 "interconnect to construct RISC-V control and decode logic. Make "
660 "sure "
661 "the minimum connections are in place and that the operand-port "
662 "bindings are valid in FUs";
663 throw InvalidData(__FILE__, __LINE__, __func__, msg);
664 }
665 hasForwarding_ = forwarding;
666
667 rs1Bus_ = rs1.bus;
668 rs2Bus_ = rs2.bus;
669 rdBus_ = rd.bus;
670 simmBus_ = simm.bus;
671 rs1RFPort_ = rs1RFPort;
672 rs2RFPort_ = rs2RFPort;
673 rdRFPort_ = rdRFPort;
674}
#define __func__
bool findConnectedBusses(Connection &rs1, Connection &rs2, Connection &rd, Connection &simm, const bool &forwarding) const
virtual RFPort * port(const std::string &name) const
Segment * bus() const
virtual Socket * outputSocket() const
Definition Port.cc:281
virtual Socket * inputSocket() const
Definition Port.cc:261
virtual int portCount() const
Definition Unit.cc:135

References __func__, assert, ProGe::MicroCodeGenerator::Connection::bus, findConnectedBusses(), hasForwarding_, TTAMachine::Port::inputSocket(), TTAMachine::Port::outputSocket(), ProGe::MicroCodeGenerator::Connection::port, TTAMachine::BaseRegisterFile::port(), TTAMachine::Unit::portCount(), rdBus_, rdRFPort_, RF_, rs1Bus_, rs1RFPort_, rs2Bus_, rs2RFPort_, and simmBus_.

Referenced by RV32MicroCodeGenerator().

Here is the call graph for this function:

◆ constructBInstructions()

std::unordered_map< std::string, InstructionBitVector * > ProGe::RV32MicroCodeGenerator::constructBInstructions ( Port src1,
Port src2 
) const
private

Definition at line 968 of file RV32MicroCodeGenerator.cc.

968 {
969 std::unordered_map<std::string, InstructionBitVector*> retval;
970 CodeCompressorPlugin* compressor = &pig_->compressor();
971 for (const auto& op : bOperations_) {
972 Instruction* instruction = new Instruction();
973 HWOperation* operation =
974 mapFunctionUnit(op.first)->operation(op.first);
975
976 FUPort* rs1Port = static_cast<FUPort*>(rs1Ports_.at(op.first));
977 FUPort* simmPort = static_cast<FUPort*>(simmPorts_.at(op.first));
978 FUPort* rs2Port = static_cast<FUPort*>(rs2Ports_.at(op.first));
979
980 instruction->addMove(std::make_shared<Move>(
982 new TerminalFUPort(*simmPort, *operation), *simmBus_));
983
984 if (dynamic_cast<RFPort*>(src1)) {
985 instruction->addMove(std::make_shared<Move>(
986 new TerminalRegister(*src1, 0), new TerminalFUPort(*rs1Port),
987 *rs1Bus_));
988 } else {
989 instruction->addMove(std::make_shared<Move>(
990 new TerminalFUPort(*static_cast<BaseFUPort*>(src1)),
991 new TerminalFUPort(*rs1Port), *rs1Bus_));
992 }
993
994 if (dynamic_cast<RFPort*>(src2)) {
995 instruction->addMove(std::make_shared<Move>(
996 new TerminalRegister(*src2, 0), new TerminalFUPort(*rs2Port),
997 *rs2Bus_));
998 } else {
999 instruction->addMove(std::make_shared<Move>(
1000 new TerminalFUPort(*static_cast<BaseFUPort*>(src2)),
1001 new TerminalFUPort(*rs2Port), *rs2Bus_));
1002 }
1003
1004 InstructionBitVector* bits =
1005 compressor->bemInstructionBits(*instruction);
1006 delete instruction;
1007 retval.insert({op.first, bits});
1008 }
1009 return retval;
1010}
InstructionBitVector * bemInstructionBits(const TTAProgram::Instruction &)
std::map< std::string, std::string > bOperations_
CodeCompressorPlugin & compressor()
int width() const
Definition Bus.cc:149
void addMove(std::shared_ptr< Move > move)

References TTAProgram::Instruction::addMove(), CodeCompressorPlugin::bemInstructionBits(), bOperations_, ProgramImageGenerator::compressor(), mapFunctionUnit(), TTAMachine::FunctionUnit::operation(), pig_, rs1Bus_, rs1Ports_, rs2Bus_, rs2Ports_, simmBus_, simmPorts_, and TTAMachine::Bus::width().

Referenced by generateMap().

Here is the call graph for this function:

◆ constructIInstructions()

std::unordered_map< std::string, InstructionBitVector * > ProGe::RV32MicroCodeGenerator::constructIInstructions ( Port src1,
Port src2 
) const
private

Definition at line 860 of file RV32MicroCodeGenerator.cc.

861 {
862 std::unordered_map<std::string, InstructionBitVector*> retval;
863 CodeCompressorPlugin* compressor = &pig_->compressor();
864 for (const auto& op : iOperations_) {
865 Instruction* instruction = new Instruction();
866
867 HWOperation* operation =
868 mapFunctionUnit(op.first)->operation(op.first);
869
870 FUPort* rdPort = static_cast<FUPort*>(rdPorts_.at(op.first));
871
872 // ALU operations are a special case as they are shared with R type
873 if (op.first != "calla") {
874 FUPort* simmPort = static_cast<FUPort*>(simmPorts_.at(op.first));
875 FUPort* rs1Port = static_cast<FUPort*>(rs1Ports_.at(op.first));
876
877 if (dynamic_cast<RFPort*>(src1)) {
878 instruction->addMove(std::make_shared<Move>(
879 new TerminalRegister(*src1, 0),
880 new TerminalFUPort(*rs1Port, *operation), *rs1Bus_));
881 } else {
882 instruction->addMove(std::make_shared<Move>(
883 new TerminalFUPort(*static_cast<BaseFUPort*>(src1)),
884 new TerminalFUPort(*rs1Port, *operation), *rs1Bus_));
885 }
886
887 instruction->addMove(std::make_shared<Move>(
889 new TerminalFUPort(*simmPort), *simmBus_));
890
891 } else {
892 FUPort* rs1Port = static_cast<FUPort*>(rs1Ports_.at(op.first));
893 FUPort* simmPort = static_cast<FUPort*>(simmPorts_.at(op.first));
894
895 if (dynamic_cast<RFPort*>(src1)) {
896 instruction->addMove(std::make_shared<Move>(
897 new TerminalRegister(*src1, 0),
898 new TerminalFUPort(*rs1Port), *rs1Bus_));
899 } else {
900 instruction->addMove(std::make_shared<Move>(
901 new TerminalFUPort(*static_cast<BaseFUPort*>(src1)),
902 new TerminalFUPort(*rs1Port), *rs1Bus_));
903 }
904
905 instruction->addMove(std::make_shared<Move>(
907 new TerminalFUPort(*simmPort, *operation), *simmBus_));
908 }
909
910 instruction->addMove(std::make_shared<Move>(
911 new TerminalFUPort(*rdPort), new TerminalRegister(*rdRFPort_, 0),
912 *rdBus_));
913
915 compressor->bemInstructionBits(*instruction);
916 delete instruction;
917 retval.insert({op.first, bits});
918 }
919 return retval;
920}

References TTAProgram::Instruction::addMove(), CodeCompressorPlugin::bemInstructionBits(), ProgramImageGenerator::compressor(), iOperations_, mapFunctionUnit(), TTAMachine::FunctionUnit::operation(), pig_, rdBus_, rdPorts_, rdRFPort_, rs1Bus_, rs1Ports_, simmBus_, simmPorts_, and TTAMachine::Bus::width().

Referenced by generateMap().

Here is the call graph for this function:

◆ constructR1Instructions()

std::unordered_map< std::string, InstructionBitVector * > ProGe::RV32MicroCodeGenerator::constructR1Instructions ( Port src1,
Port src2 
) const
private

Definition at line 831 of file RV32MicroCodeGenerator.cc.

831 {
832 std::unordered_map<std::string, InstructionBitVector*> retval;
833 CodeCompressorPlugin* compressor = &pig_->compressor();
834 for (const auto& op : r1Operations_) {
835 Instruction* instruction = new Instruction();
836 HWOperation* operation =
837 mapFunctionUnit(op.first)->operation(op.first);
838
839 FUPort* rs1Port = static_cast<FUPort*>(rs1Ports_.at(op.first));
840
841 if (dynamic_cast<RFPort*>(src1)) {
842 instruction->addMove(std::make_shared<Move>(
843 new TerminalRegister(*src1, 0),
844 new TerminalFUPort(*rs1Port, *operation), *rs1Bus_));
845 } else {
846 instruction->addMove(std::make_shared<Move>(
847 new TerminalFUPort(*static_cast<BaseFUPort*>(src1)),
848 new TerminalFUPort(*rs1Port, *operation), *rs1Bus_));
849 }
850
852 compressor->bemInstructionBits(*instruction);
853 delete instruction;
854 retval.insert({op.first, bits});
855 }
856 return retval;
857}
std::map< std::string, std::string > r1Operations_

References TTAProgram::Instruction::addMove(), CodeCompressorPlugin::bemInstructionBits(), ProgramImageGenerator::compressor(), mapFunctionUnit(), TTAMachine::FunctionUnit::operation(), pig_, r1Operations_, rs1Bus_, and rs1Ports_.

Referenced by generateMap().

Here is the call graph for this function:

◆ constructR1RInstructions()

std::unordered_map< std::string, InstructionBitVector * > ProGe::RV32MicroCodeGenerator::constructR1RInstructions ( Port src1,
Port src2 
) const
private

Definition at line 797 of file RV32MicroCodeGenerator.cc.

797 {
798 std::unordered_map<std::string, InstructionBitVector*> retval;
799 CodeCompressorPlugin* compressor = &pig_->compressor();
800 for (const auto& op : r1rOperations_) {
801 Instruction* instruction = new Instruction();
802 HWOperation* operation =
803 mapFunctionUnit(op.first)->operation(op.first);
804
805 FUPort* rs1Port = static_cast<FUPort*>(rs1Ports_.at(op.first));
806 FUPort* rdPort = static_cast<FUPort*>(rdPorts_.at(op.first));
807
808 if (dynamic_cast<RFPort*>(src1)) {
809 instruction->addMove(std::make_shared<Move>(
810 new TerminalRegister(*src1, 0),
811 new TerminalFUPort(*rs1Port, *operation), *rs1Bus_));
812 } else {
813 instruction->addMove(std::make_shared<Move>(
814 new TerminalFUPort(*static_cast<BaseFUPort*>(src1)),
815 new TerminalFUPort(*rs1Port, *operation), *rs1Bus_));
816 }
817
818 instruction->addMove(std::make_shared<Move>(
819 new TerminalFUPort(*rdPort), new TerminalRegister(*rdRFPort_, 0),
820 *rdBus_));
821
823 compressor->bemInstructionBits(*instruction);
824 delete instruction;
825 retval.insert({op.first, bits});
826 }
827 return retval;
828}
std::map< std::string, std::string > r1rOperations_

References TTAProgram::Instruction::addMove(), CodeCompressorPlugin::bemInstructionBits(), ProgramImageGenerator::compressor(), mapFunctionUnit(), TTAMachine::FunctionUnit::operation(), pig_, r1rOperations_, rdBus_, rdPorts_, rdRFPort_, rs1Bus_, and rs1Ports_.

Referenced by generateMap().

Here is the call graph for this function:

◆ constructRInstructions()

std::unordered_map< std::string, InstructionBitVector * > ProGe::RV32MicroCodeGenerator::constructRInstructions ( Port src1,
Port src2 
) const
private

Definition at line 752 of file RV32MicroCodeGenerator.cc.

752 {
753 std::unordered_map<std::string, InstructionBitVector*> retval;
754 CodeCompressorPlugin* compressor = &pig_->compressor();
755 for (const auto& op : rOperations_) {
756 Instruction* instruction = new Instruction();
757 HWOperation* operation =
758 mapFunctionUnit(op.first)->operation(op.first);
759
760 FUPort* rs1Port = static_cast<FUPort*>(rs1Ports_.at(op.first));
761 FUPort* rs2Port = static_cast<FUPort*>(rs2Ports_.at(op.first));
762 FUPort* rdPort = static_cast<FUPort*>(rdPorts_.at(op.first));
763
764 if (dynamic_cast<RFPort*>(src1)) {
765 instruction->addMove(std::make_shared<Move>(
766 new TerminalRegister(*src1, 0),
767 new TerminalFUPort(*rs1Port, *operation), *rs1Bus_));
768 } else {
769 instruction->addMove(std::make_shared<Move>(
770 new TerminalFUPort(*static_cast<BaseFUPort*>(src1)),
771 new TerminalFUPort(*rs1Port, *operation), *rs1Bus_));
772 }
773
774 if (dynamic_cast<RFPort*>(src2)) {
775 instruction->addMove(std::make_shared<Move>(
776 new TerminalRegister(*src2, 0), new TerminalFUPort(*rs2Port),
777 *rs2Bus_));
778 } else {
779 instruction->addMove(std::make_shared<Move>(
780 new TerminalFUPort(*static_cast<BaseFUPort*>(src2)),
781 new TerminalFUPort(*rs2Port), *rs2Bus_));
782 }
783
784 instruction->addMove(std::make_shared<Move>(
785 new TerminalFUPort(*rdPort), new TerminalRegister(*rdRFPort_, 0),
786 *rdBus_));
787
789 compressor->bemInstructionBits(*instruction);
790 delete instruction;
791 retval.insert({op.first, bits});
792 }
793 return retval;
794}

References TTAProgram::Instruction::addMove(), CodeCompressorPlugin::bemInstructionBits(), ProgramImageGenerator::compressor(), mapFunctionUnit(), TTAMachine::FunctionUnit::operation(), pig_, rdBus_, rdPorts_, rdRFPort_, rOperations_, rs1Bus_, rs1Ports_, rs2Bus_, and rs2Ports_.

Referenced by generateMap().

Here is the call graph for this function:

◆ constructSInstructions()

std::unordered_map< std::string, InstructionBitVector * > ProGe::RV32MicroCodeGenerator::constructSInstructions ( Port src1,
Port src2 
) const
private

Definition at line 923 of file RV32MicroCodeGenerator.cc.

923 {
924 std::unordered_map<std::string, InstructionBitVector*> retval;
925 CodeCompressorPlugin* compressor = &pig_->compressor();
926 for (const auto& op : sOperations_) {
927 Instruction* instruction = new Instruction();
928 HWOperation* operation =
929 mapFunctionUnit(op.first)->operation(op.first);
930
931 FUPort* simmPort = static_cast<FUPort*>(simmPorts_.at(op.first));
932 FUPort* rs1Port = static_cast<FUPort*>(rs1Ports_.at(op.first));
933 FUPort* rs2Port = static_cast<FUPort*>(rs2Ports_.at(op.first));
934
935 if (dynamic_cast<RFPort*>(src1)) {
936 instruction->addMove(std::make_shared<Move>(
937 new TerminalRegister(*src1, 0),
938 new TerminalFUPort(*rs1Port, *operation), *rs1Bus_));
939 } else {
940 instruction->addMove(std::make_shared<Move>(
941 new TerminalFUPort(*static_cast<BaseFUPort*>(src1)),
942 new TerminalFUPort(*rs1Port, *operation), *rs1Bus_));
943 }
944
945 instruction->addMove(std::make_shared<Move>(
947 new TerminalFUPort(*simmPort), *simmBus_));
948
949 if (dynamic_cast<RFPort*>(src2)) {
950 instruction->addMove(std::make_shared<Move>(
951 new TerminalRegister(*src2, 0), new TerminalFUPort(*rs2Port),
952 *rs2Bus_));
953 } else {
954 instruction->addMove(std::make_shared<Move>(
955 new TerminalFUPort(*static_cast<BaseFUPort*>(src2)),
956 new TerminalFUPort(*rs2Port), *rs2Bus_));
957 }
958
960 compressor->bemInstructionBits(*instruction);
961 delete instruction;
962 retval.insert({op.first, bits});
963 }
964 return retval;
965}
std::map< std::string, std::string > sOperations_

References TTAProgram::Instruction::addMove(), CodeCompressorPlugin::bemInstructionBits(), ProgramImageGenerator::compressor(), mapFunctionUnit(), TTAMachine::FunctionUnit::operation(), pig_, rs1Bus_, rs1Ports_, rs2Bus_, rs2Ports_, simmBus_, simmPorts_, sOperations_, and TTAMachine::Bus::width().

Referenced by generateMap().

Here is the call graph for this function:

◆ constructUJInstructions()

std::unordered_map< std::string, InstructionBitVector * > ProGe::RV32MicroCodeGenerator::constructUJInstructions ( ) const
private

Definition at line 1013 of file RV32MicroCodeGenerator.cc.

1013 {
1014 std::unordered_map<std::string, InstructionBitVector*> retval;
1015 CodeCompressorPlugin* compressor = &pig_->compressor();
1017
1018 for (const auto& op : ujOperations_) {
1019 Instruction* instruction = new Instruction();
1020 if (op.first == "move") {
1021 HWOperation* operation = mapFunctionUnit("add")->operation("add");
1022 FUPort* rs1Port = static_cast<FUPort*>(rs1Ports_.at("add"));
1023 FUPort* simmPort = static_cast<FUPort*>(simmPorts_.at("add"));
1024 FUPort* rdPort = static_cast<FUPort*>(rdPorts_.at("add"));
1025 instruction->addMove(std::make_shared<Move>(
1027 new TerminalFUPort(*rs1Port, *operation), *rs1Bus_));
1028
1029 instruction->addMove(std::make_shared<Move>(
1031 new TerminalFUPort(*simmPort), *simmBus_));
1032
1033 instruction->addMove(std::make_shared<Move>(
1034 new TerminalFUPort(*rdPort),
1035 new TerminalRegister(*rdRFPort_, 0), *rdBus_));
1036
1037 bits = compressor->bemInstructionBits(*instruction);
1038 retval.insert({"move", bits});
1039 delete instruction;
1040 } else if (op.first == "callr" or op.first == "apc") {
1041 FUPort* rdPort = static_cast<FUPort*>(rdPorts_.at(op.first));
1042
1043 instruction->addMove(std::make_shared<Move>(
1044 new TerminalFUPort(*rdPort),
1045 new TerminalRegister(*rdRFPort_, 0), *rdBus_));
1046
1047 bits = compressor->bemInstructionBits(*instruction);
1048 delete instruction;
1049 retval.insert({op.first, bits});
1050
1051 } else {
1052 FUPort* simmPort = static_cast<FUPort*>(simmPorts_.at(op.first));
1053 FUPort* rdPort = static_cast<FUPort*>(rdPorts_.at(op.first));
1054
1055 HWOperation* operation =
1056 mapFunctionUnit(op.first)->operation(op.first);
1057
1058 instruction->addMove(std::make_shared<Move>(
1060 new TerminalFUPort(*simmPort, *operation), *simmBus_));
1061
1062 instruction->addMove(std::make_shared<Move>(
1063 new TerminalFUPort(*rdPort),
1064 new TerminalRegister(*rdRFPort_, 0), *rdBus_));
1065
1066 bits = compressor->bemInstructionBits(*instruction);
1067 delete instruction;
1068
1069 retval.insert({op.first, bits});
1070 }
1071 }
1072
1073 return retval;
1074}
std::map< std::string, std::string > ujOperations_

References TTAProgram::Instruction::addMove(), CodeCompressorPlugin::bemInstructionBits(), ProgramImageGenerator::compressor(), mapFunctionUnit(), TTAMachine::FunctionUnit::operation(), pig_, rdBus_, rdPorts_, rdRFPort_, rs1Bus_, rs1Ports_, rs1RFPort_, simmBus_, simmPorts_, ujOperations_, and TTAMachine::Bus::width().

Here is the call graph for this function:

◆ findBusWidths()

void ProGe::RV32MicroCodeGenerator::findBusWidths ( )
private

Definition at line 564 of file RV32MicroCodeGenerator.cc.

564 {
565 for (int i = 0; i < bem_->moveSlotCount(); i++) {
566 MoveSlot& slot = bem_->moveSlot(i);
567 if (slot.name() == rs1Bus_->name()) {
568 rs1BusWidth_ = slot.width();
571 rs1BusStart_ = slot.bitPosition();
572 } else if (slot.name() == rs2Bus_->name()) {
573 rs2BusWidth_ = slot.width();
576 rs2BusStart_ = slot.bitPosition();
577 } else if (slot.name() == rdBus_->name()) {
578 rdBusWidth_ = slot.width();
579 rdRFStart_ = 0;
580 rdBusStart_ = slot.bitPosition();
581 } else if (slot.name() == simmBus_->name()) {
582 simmBusWidth_ = slot.width();
583 simmRFStart_ = 0;
584 simmBusStart_ = slot.bitPosition();
585 }
586 }
587 assert(rs1BusWidth_ > 0);
588 assert(rs2BusWidth_ > 0);
589 assert(rdBusWidth_ > 0);
591}
int moveSlotCount() const
MoveSlot & moveSlot(int index) const
DestinationField & destinationField() const
Definition MoveSlot.cc:341
virtual int width() const
Definition MoveSlot.cc:406
std::string name() const
Definition MoveSlot.cc:136
bool hasDestinationField() const
Definition MoveSlot.cc:327
const BinaryEncoding * bem_
virtual int width() const
Definition SlotField.cc:307
virtual TCEString name() const

References assert, ProGe::MicroCodeGenerator::bem_, InstructionField::bitPosition(), MoveSlot::destinationField(), MoveSlot::hasDestinationField(), BinaryEncoding::moveSlot(), BinaryEncoding::moveSlotCount(), MoveSlot::name(), TTAMachine::Component::name(), rdBus_, rdBusStart_, rdBusWidth_, rdRFStart_, rs1Bus_, rs1BusStart_, rs1BusWidth_, rs1RFStart_, rs2Bus_, rs2BusStart_, rs2BusWidth_, rs2RFStart_, simmBus_, simmBusStart_, simmBusWidth_, simmRFStart_, MoveSlot::width(), and SlotField::width().

Referenced by RV32MicroCodeGenerator().

Here is the call graph for this function:

◆ findConnectedBusses()

bool ProGe::RV32MicroCodeGenerator::findConnectedBusses ( Connection rs1,
Connection rs2,
Connection rd,
Connection simm,
const bool &  forwarding 
) const
private

Definition at line 687 of file RV32MicroCodeGenerator.cc.

689 {
690 std::set<Port*> rs1Ports = operationPorts(rs1Ports_);
691 rs1Ports.insert(rs1.port);
692
693 std::set<Port*> rs2Ports = operationPorts(rs2Ports_);
694 rs2Ports.insert(rs2.port);
695
696 std::set<Port*> simmPorts = operationPorts(simmPorts_);
697
698 std::set<Port*> rdPorts = operationPorts(rdPorts_);
699
700 if (forwarding) {
701 rs1Ports.insert(rdPorts.begin(), rdPorts.end());
702 rs2Ports.insert(rdPorts.begin(), rdPorts.end());
703 }
704
705 rdPorts.insert(rd.port);
706
707 // Brute forces all combinations until all ports can be mapped to a bus
708 for (unsigned int i = 0; i < busses_.size(); i++) {
709 std::vector<Bus*> tmpBusses = busses_;
710 rs1.bus = NULL;
711 rs2.bus = NULL;
712 rd.bus = NULL;
713 simm.bus = NULL;
714 Bus* tmpBus = busses_.at(i);
715 if (!MachineConnectivityCheck::isConnected(rs1Ports, *tmpBus)) {
716 continue;
717 }
718 rs1.bus = tmpBus;
719 tmpBusses.erase(tmpBusses.begin() + i);
720 rs2.bus = NULL;
721 for (unsigned int j = 0; j < tmpBusses.size(); j++) {
722 tmpBus = tmpBusses.at(j);
723 if (!MachineConnectivityCheck::isConnected(rs2Ports, *tmpBus)) {
724 continue;
725 }
726 rs2.bus = tmpBus;
727 tmpBusses.erase(tmpBusses.begin() + j);
728 for (unsigned int k = 0; k < tmpBusses.size(); k++) {
729 tmpBus = tmpBusses.at(k);
731 rdPorts, *tmpBus)) {
732 continue;
733 }
734 rd.bus = tmpBus;
735 tmpBusses.erase(tmpBusses.begin() + k);
736 for (unsigned int h = 0; h < tmpBusses.size(); h++) {
737 tmpBus = tmpBusses.at(h);
739 simmPorts, *tmpBus) &&
740 tmpBus->immediateWidth() > 0) {
741 simm.bus = tmpBus;
742 return true;
743 }
744 }
745 }
746 }
747 }
748 return false;
749}
static bool isConnected(const TTAMachine::Port &sourcePort, const TTAMachine::Port &destinationPort, const TTAMachine::Guard *guard=NULL)
std::set< Port * > operationPorts(const std::unordered_map< std::string, BaseFUPort * > &ports) const
int immediateWidth() const
Definition Bus.cc:160

References ProGe::MicroCodeGenerator::Connection::bus, busses_, TTAMachine::Bus::immediateWidth(), MachineConnectivityCheck::isConnected(), operationPorts(), ProGe::MicroCodeGenerator::Connection::port, rdPorts_, rs1Ports_, rs2Ports_, and simmPorts_.

Referenced by connectRF().

Here is the call graph for this function:

◆ findOperationPorts()

void ProGe::RV32MicroCodeGenerator::findOperationPorts ( )
private

Definition at line 507 of file RV32MicroCodeGenerator.cc.

507 {
508 for (const auto& op : rOperations_) {
509 addRPorts(op.first);
510 }
511 for (const auto& op : iOperations_) {
512 addIPorts(op.first);
513 }
514 for (const auto& op : sOperations_) {
515 addSPorts(op.first);
516 }
517 for (const auto& op : bOperations_) {
518 addBPorts(op.first);
519 }
520 for (const auto& op : ujOperations_) {
521 addUJPorts(op.first);
522 }
523 for (const auto& op : r1rOperations_) {
524 addR1RPorts(op.first);
525 }
526 for (const auto& op : r1Operations_) {
527 addR1Ports(op.first);
528 }
529}
void addR1RPorts(const std::string &opName)
void addR1Ports(const std::string &opName)
void addRPorts(const std::string &opName)
void addSPorts(const std::string &opName)
void addUJPorts(const std::string &opName)
void addIPorts(const std::string &opName)
void addBPorts(const std::string &opName)

References addBPorts(), addIPorts(), addR1Ports(), addR1RPorts(), addRPorts(), addSPorts(), addUJPorts(), bOperations_, iOperations_, r1Operations_, r1rOperations_, rOperations_, sOperations_, and ujOperations_.

Referenced by RV32MicroCodeGenerator().

Here is the call graph for this function:

◆ findOperationSources()

void ProGe::RV32MicroCodeGenerator::findOperationSources ( )
private

Definition at line 131 of file RV32MicroCodeGenerator.cc.

131 {
132 for (const auto& op : rdPorts_) {
133 if (sourceOperationMap_.count(op.second)) {
134 sourceOperationMap_.at(op.second).push_back(op.first);
135 } else {
136 sourceOperationMap_.insert({op.second, {op.first}});
137 }
138 }
139}

References rdPorts_, and sourceOperationMap_.

Referenced by RV32MicroCodeGenerator().

◆ findRF()

void ProGe::RV32MicroCodeGenerator::findRF ( )
private

Definition at line 541 of file RV32MicroCodeGenerator.cc.

541 {
543 // TODO: Design can have multiple register files. Iterate over all of
544 // them and find one that fits based on connectivity.
545 for (int i = 0; i < rfNav.count(); i++) {
546 RegisterFile* rf = rfNav.item(0);
547 if (rf->inputPortCount() > 0 && rf->outputPortCount() > 1 &&
548 rf->zeroRegister()) {
549 if (rf->size() > 31 && rf->width() == 32) {
550 RF_ = rf;
551 } else if (rf->size() == 16 && rf->width() == 32) {
552 RF_ = rf;
553 eVariant_ = true;
554 }
555 }
556 }
557 if (RF_ == NULL) {
558 std::string msg = "Could not find a valid register file for RISC-V";
559 throw InvalidData(__FILE__, __LINE__, __func__, msg);
560 }
561}
virtual int size() const
virtual int width() const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
virtual bool zeroRegister() const
virtual int inputPortCount(bool countBidir=false) const
Definition Unit.cc:160
virtual int outputPortCount(bool countBidir=false) const
Definition Unit.cc:145

References __func__, TTAMachine::Machine::Navigator< ComponentType >::count(), eVariant_, TTAMachine::Unit::inputPortCount(), TTAMachine::Machine::Navigator< ComponentType >::item(), ProGe::MicroCodeGenerator::machine_, TTAMachine::Unit::outputPortCount(), TTAMachine::Machine::registerFileNavigator(), RF_, TTAMachine::BaseRegisterFile::size(), TTAMachine::BaseRegisterFile::width(), and TTAMachine::RegisterFile::zeroRegister().

Referenced by RV32MicroCodeGenerator().

Here is the call graph for this function:

◆ generateFUTargetProcess()

void ProGe::RV32MicroCodeGenerator::generateFUTargetProcess ( std::ofstream &  stream)
private

Definition at line 1094 of file RV32MicroCodeGenerator.cc.

1094 {
1095 std::unordered_map<std::string, std::string> operations;
1096 operations.insert(rOperations_.begin(), rOperations_.end());
1097 operations.insert(iOperations_.begin(), iOperations_.end());
1098 operations.insert(sOperations_.begin(), sOperations_.end());
1099 operations.insert(bOperations_.begin(), bOperations_.end());
1100 operations.insert(ujOperations_.begin(), ujOperations_.end());
1101 operations.insert(r1rOperations_.begin(), r1rOperations_.end());
1102 operations.insert(r1Operations_.begin(), r1Operations_.end());
1103 int len = std::ceil(std::log2(sourceOperationMap_.size()));
1104
1105 stream << " process(fu_opcode)" << std::endl
1106 << " begin" << std::endl
1107 << " target_fu <= to_unsigned(0, " << len << ");" << std::endl;
1108
1109 int id = 0;
1110 bool firstCond = true;
1111 std::string cond;
1112 for (const auto& p : sourceOperationMap_) {
1113 sourcePortID_.insert({p.first, id});
1114 for (const auto& op : p.second) {
1115 if (firstCond) {
1116 cond = " if ";
1117 firstCond = false;
1118 } else {
1119 cond = " elsif ";
1120 }
1121 // Add is a special case as it is used in LUI
1122 if (op == "add") {
1123 int iLen = iOperations_.at(op).size();
1124 int uLen = ujOperations_.at("move").size();
1125 stream << cond << "fu_opcode(" << iLen << "-1 downto 0)"
1126 << " = \"" << iOperations_.at(op) << "\""
1127 << " or "
1128 << "fu_opcode = \"" << rOperations_.at(op)
1129 << "\" or fu_opcode(" << uLen << "-1 downto 0) = \""
1130 << ujOperations_.at("move") << "\""
1131 << " then\n";
1132
1133 } else if (iOperations_.count(op) && rOperations_.count(op)) {
1134 int iLen = iOperations_.at(op).size();
1135 stream << cond << "fu_opcode(" << iLen << "-1 downto 0)"
1136 << " = \"" << iOperations_.at(op) << "\" or "
1137 << "fu_opcode = \"" << rOperations_.at(op)
1138 << "\" then\n";
1139 } else {
1140 int opLen = operations.at(op).size();
1141 stream << cond << "fu_opcode(" << opLen << "-1 downto 0)"
1142 << "= \"" << operations.at(op) << "\" then\n";
1143 }
1144 stream << " target_fu <= to_unsigned(" << id << ", " << len
1145 << ");\n";
1146 }
1147 id++;
1148 }
1149 stream << " end if;" << std::endl << " end process;" << std::endl;
1150
1151 stream << std::endl << std::endl;
1152 stream << " process(clk, rstx)" << std::endl
1153 << " begin" << std::endl
1154 << " if(rstx = '0') then" << std::endl
1155 << " target_fu_r <= (others => '0');" << std::endl
1156 << " elsif clk'event and clk = '1' then" << std::endl
1157 << " if glock_in = '0' and halt = '0' then" << std::endl
1158 << " target_fu_r <= target_fu;" << std::endl
1159 << " end if;" << std::endl
1160 << " end if;" << std::endl
1161 << " end process;" << std::endl
1162 << std::endl
1163 << std::endl;
1164}

References bOperations_, iOperations_, r1Operations_, r1rOperations_, rOperations_, sOperations_, sourceOperationMap_, sourcePortID_, and ujOperations_.

◆ generateMap()

void ProGe::RV32MicroCodeGenerator::generateMap ( const std::string &  dstDirectory)
private

Definition at line 1262 of file RV32MicroCodeGenerator.cc.

1262 {
1263 /*TODO: The if structure should be replaced with a case statement
1264 The problem is that the fu_opcode's width is different between
1265 formats. Don't care states in a case statement
1266 is a VHDL-2OO8 feature
1267 */
1268 const std::string DS = FileSystem::DIRECTORY_SEPARATOR;
1269 std::string mapFile = dstDirectory + DS + "rv32_microcode.vhdl";
1270
1271 std::ofstream stream;
1272 stream.open(mapFile);
1273 stream << LicenseGenerator::generateMITLicense("2023", "--");
1274
1275 stream << "library IEEE;" << std::endl
1276 << "use IEEE.std_logic_1164.all;" << std::endl
1277 << "use IEEE.numeric_std.all;" << std::endl
1278 << "use work." << entityName_ << "_globals.all;" << std::endl
1279 << std::endl
1280 << std::endl;
1281
1282 stream << "entity rv32_microcode is" << std::endl << "port(" << std::endl;
1283 if (hasForwarding_) {
1284 stream << " clk : in std_logic;" << std::endl
1285 << " rstx : in std_logic;" << std::endl
1286 << " glock_in : in std_logic;" << std::endl
1287 << " data_hazard_in : in std_logic;" << std::endl
1288 << " rs1_hazard_in : in std_logic;" << std::endl
1289 << " rs2_hazard_in : in std_logic;" << std::endl
1290 << " halt : in std_logic;" << std::endl;
1291 }
1292 stream << " fu_opcode_in : in std_logic_vector(16 downto 0);"
1293 << std::endl
1294 << " moves_out : out std_logic_vector(INSTRUCTIONWIDTH-1 "
1295 "downto 0));"
1296 << std::endl
1297 << std::endl
1298 << "end rv32_microcode;" << std::endl
1299 << std::endl
1300 << "architecture rtl of rv32_microcode is" << std::endl
1301 << " signal fu_opcode : std_logic_vector(16 downto 0);"
1302 << std::endl
1303 << " signal moves : std_logic_vector(INSTRUCTIONWIDTH-1 "
1304 "downto 0);"
1305 << std::endl
1306 << " constant rs1_start_c : integer := " << rs1BusStart_ << ";"
1307 << std::endl
1308 << " constant rs2_start_c : integer := " << rs2BusStart_ << ";"
1309 << std::endl
1310 << " constant rs1_width_c : integer := " << rs1BusWidth_ << ";"
1311 << std::endl
1312 << " constant rs2_width_c : integer := " << rs2BusWidth_ << ";"
1313 << std::endl;
1314 if (hasForwarding_) {
1315 int len = std::ceil(std::log2(sourceOperationMap_.size()));
1316 stream << " signal target_fu : unsigned(" << len << "-1 downto 0);"
1317 << std::endl;
1318 stream << " signal target_fu_r : unsigned (" << len
1319 << "-1 downto 0);" << std::endl
1320 << " signal data_hazard : std_logic;\n"
1321 << " signal rs1_hazard : std_logic;\n"
1322 << " signal rs2_hazard : std_logic;\n";
1323 }
1324
1325 stream << std::endl
1326 << " begin" << std::endl
1327 << std::endl
1328 << " fu_opcode <= fu_opcode_in;" << std::endl
1329 << " moves_out <= moves;" << std::endl
1330 << std::endl;
1331 if (hasForwarding_) {
1332 stream << " data_hazard <= data_hazard_in;" << std::endl
1333 << " rs1_hazard <= rs1_hazard_in;" << std::endl
1334 << " rs2_hazard <= rs2_hazard_in;" << std::endl;
1335 stream << std::endl;
1337 }
1338 stream << " process(fu_opcode";
1339 if (hasForwarding_) {
1340 stream << ", data_hazard, rs1_hazard, rs2_hazard, target_fu_r";
1341 }
1342 stream << ")" << std::endl;
1343 stream << " begin" << std::endl;
1344
1345 std::unordered_map<std::string, InstructionBitVector*> instructions =
1347 bool firstCond = true;
1348 for (const auto& op : instructions) {
1349 if (firstCond) {
1350 stream << " if(fu_opcode = \"" << rOperations_.at(op.first)
1351 << "\") then" << std::endl
1352 << " moves <= \"" << op.second->toString() << "\";"
1353 << std::endl;
1354 delete op.second;
1355 firstCond = false;
1356 continue;
1357 }
1358 stream << " elsif(fu_opcode(" << rOperations_.at(op.first).size()
1359 << " - 1 downto 0) = \"" << rOperations_.at(op.first) << "\""
1360 << ") then" << std::endl
1361 << " moves <= \"" << op.second->toString() << "\";"
1362 << std::endl;
1363 delete op.second;
1364 }
1365
1367 addBitsToMap(instructions, iOperations_, stream);
1368
1370 addBitsToMap(instructions, sOperations_, stream);
1371
1373 addBitsToMap(instructions, bOperations_, stream);
1374
1375 instructions = constructUJInstructions();
1376 addBitsToMap(instructions, ujOperations_, stream);
1377
1379 addBitsToMap(instructions, r1rOperations_, stream);
1380
1382 addBitsToMap(instructions, r1Operations_, stream);
1383
1384 stream << " else" << std::endl;
1385 stream << " moves <= \"" + NOP_ + "\";" << std::endl;
1386
1387 stream << " end if;" << std::endl;
1388
1389 if (hasForwarding_) {
1390 stream << " if(data_hazard = '1') then\n"
1391 << " if(rs1_hazard = '1') then\n";
1410 stream << " end if;\n"
1411 << " if(rs2_hazard = '1') then\n";
1421 stream << " end if;\n"
1422 << " end if;\n";
1423 }
1424
1425 stream << " end process;" << std::endl;
1426
1427 stream << "end architecture rtl;" << std::endl;
1428
1429 stream.close();
1430}
#define DS
static const std::string DIRECTORY_SEPARATOR
static std::string generateMITLicense(const std::string &year, const std::string &comment)
void addRs2ForwardingConditions(std::map< std::string, std::string > ops, std::unordered_map< std::string, InstructionBitVector * >(ProGe::RV32MicroCodeGenerator::*instructionFunc)(Port *p1, Port *p2) const, std::ofstream &stream) const
std::unordered_map< std::string, InstructionBitVector * > constructIInstructions(Port *src1, Port *src2) const
void addRs1ForwardingConditions(std::map< std::string, std::string > ops, std::unordered_map< std::string, InstructionBitVector * >(ProGe::RV32MicroCodeGenerator::*instructionFunc)(Port *p1, Port *p2) const, std::ofstream &stream) const
void addBitsToMap(std::unordered_map< std::string, InstructionBitVector * > instructions, const std::map< std::string, std::string > encodings, std::ofstream &stream) const
std::unordered_map< std::string, InstructionBitVector * > constructR1Instructions(Port *src1, Port *src2) const
std::unordered_map< std::string, InstructionBitVector * > constructRInstructions(Port *src1, Port *src2) const
std::unordered_map< std::string, InstructionBitVector * > constructSInstructions(Port *src1, Port *src2) const
void generateFUTargetProcess(std::ofstream &stream)
std::unordered_map< std::string, InstructionBitVector * > constructR1RInstructions(Port *src1, Port *src2) const
std::unordered_map< std::string, InstructionBitVector * > constructUJInstructions() const
std::unordered_map< std::string, InstructionBitVector * > constructBInstructions(Port *src1, Port *src2) const

References constructBInstructions(), constructIInstructions(), constructR1Instructions(), constructR1RInstructions(), constructRInstructions(), constructSInstructions(), FileSystem::DIRECTORY_SEPARATOR, DS, and LicenseGenerator::generateMITLicense().

Here is the call graph for this function:

◆ generateNOP()

void ProGe::RV32MicroCodeGenerator::generateNOP ( )
private

Definition at line 532 of file RV32MicroCodeGenerator.cc.

532 {
533 CodeCompressorPlugin* compressor = &pig_->compressor();
534 Instruction* instruction = new Instruction();
535 InstructionBitVector* bits = compressor->bemInstructionBits(*instruction);
536 NOP_ = bits->toString();
537 delete instruction;
538}
std::string toString() const
Definition BitVector.cc:130

References CodeCompressorPlugin::bemInstructionBits(), ProgramImageGenerator::compressor(), NOP_, pig_, and BitVector::toString().

Referenced by RV32MicroCodeGenerator().

Here is the call graph for this function:

◆ generateOperationLatencyLogic()

std::string ProGe::RV32MicroCodeGenerator::generateOperationLatencyLogic ( HDLTemplateInstantiator instantiator)
private

Definition at line 1433 of file RV32MicroCodeGenerator.cc.

1434 {
1435 std::map<std::string, std::string> operations;
1436 operations.insert(rOperations_.begin(), rOperations_.end());
1437 operations.insert(r1rOperations_.begin(), r1rOperations_.end());
1438 int maxVal = 1;
1439 for (const auto& op : iOperations_) {
1440 if (!rOperations_.count(op.first)) {
1441 operations.insert(op);
1442 }
1443 }
1444 std::map<std::string, int> opLatency;
1445 for (const auto& op : operations) {
1446 FunctionUnit* fu = mapFunctionUnit(op.first);
1447 HWOperation* operation = fu->operation(op.first);
1448 if (operation->latency() > 1) {
1449 opLatency.insert({op.first, operation->latency() - 1});
1450 if (operation->latency() > maxVal) {
1451 maxVal = operation->latency();
1452 }
1453 }
1454 }
1455 int len = std::ceil(std::log2((maxVal)) + 1);
1456 instantiator.replacePlaceholder("op-lat-width", std::to_string(len));
1457 if (opLatency.size() == 0) {
1458 return "op_latency <= to_unsigned(0,op_lat_width_c);";
1459 }
1461 std::string logic =
1462 "process(fu_opcode)\n"
1463 "begin\n";
1464 bool firstCond = true;
1465 for (const auto& op : opLatency) {
1466 std::string cond = " elsif ";
1467 if (firstCond) {
1468 cond = " if ";
1469 firstCond = false;
1470 }
1471 if (rOperations_.count(op.first) && iOperations_.count(op.first)) {
1472 cond += "fu_opcode = \"" + rOperations_.at(op.first) + "\" or " +
1473 "fu_opcode(" +
1474 std::to_string(iOperations_.at(op.first).size()) +
1475 "-1 downto 0) = \"" + iOperations_.at(op.first) +
1476 "\" then\n";
1477 } else {
1478 cond += "fu_opcode(" +
1479 std::to_string(operations.at(op.first).size()) +
1480 "-1 downto 0) = \"" + operations.at(op.first) +
1481 "\" then\n";
1482 }
1483 logic += cond + " op_latency <= to_unsigned(" +
1484 std::to_string(op.second) + ",op_lat_width_c);\n";
1485 }
1486 logic +=
1487 " else\n"
1488 " op_latency <= to_unsigned(0,op_lat_width_c);\n"
1489 " end if;\n"
1490 "end process;\n";
1491 return logic;
1492}
void replacePlaceholder(const std::string &key, const std::string &replacer, bool append=false)

References TTAMachine::HWOperation::latency(), TTAMachine::FunctionUnit::operation(), and HDLTemplateInstantiator::replacePlaceholder().

Here is the call graph for this function:

◆ generateRTL()

void ProGe::RV32MicroCodeGenerator::generateRTL ( HDLTemplateInstantiator instantiator,
const std::string &  fileDst 
)
virtual

Implements ProGe::MicroCodeGenerator.

Definition at line 1717 of file RV32MicroCodeGenerator.cc.

1718 {
1719 generateMap(fileDst);
1720 generateWrapper(instantiator, fileDst);
1721}
void generateWrapper(HDLTemplateInstantiator &instantiator, const std::string &fileDst)
void generateMap(const std::string &dstDirectory)

Referenced by DefaultICDecoderGenerator::generate().

◆ generateWrapper()

void ProGe::RV32MicroCodeGenerator::generateWrapper ( HDLTemplateInstantiator instantiator,
const std::string &  fileDst 
)
private

Definition at line 1495 of file RV32MicroCodeGenerator.cc.

1496 {
1497 instantiator.replacePlaceholder(
1498 "rs1-bus-width", std::to_string(rs1BusWidth_));
1499 instantiator.replacePlaceholder(
1500 "rs2-bus-width", std::to_string(rs2BusWidth_));
1501 instantiator.replacePlaceholder(
1502 "rd-bus-width", std::to_string(rdBusWidth_));
1503 instantiator.replacePlaceholder(
1504 "simm-bus-width", std::to_string(simmBusWidth_));
1505
1506 instantiator.replacePlaceholder(
1507 "rs1-bus-start", std::to_string(rs1BusStart_));
1508 instantiator.replacePlaceholder(
1509 "rs2-bus-start", std::to_string(rs2BusStart_));
1510 instantiator.replacePlaceholder(
1511 "rd-bus-start", std::to_string(rdBusStart_));
1512 instantiator.replacePlaceholder(
1513 "simm-bus-start", std::to_string(simmBusStart_));
1514
1515 instantiator.replacePlaceholder(
1516 "rs1-rf-start", std::to_string(rs1RFStart_));
1517 instantiator.replacePlaceholder(
1518 "rs2-rf-start", std::to_string(rs2RFStart_));
1519 instantiator.replacePlaceholder(
1520 "rd-rf-start", std::to_string(rdRFStart_));
1521 instantiator.replacePlaceholder(
1522 "simm-rf-start", std::to_string(simmRFStart_));
1523
1524 if (eVariant_) {
1525 instantiator.replacePlaceholder("rf-width", std::to_string(4));
1526 } else {
1527 instantiator.replacePlaceholder("rf-width", std::to_string(5));
1528 }
1529
1530 std::string nop = NOP_;
1531 reverse(nop.begin(), nop.end());
1532 nop = nop.substr(rdBusStart_, rdBusWidth_);
1533 reverse(nop.begin(), nop.end());
1534 const std::string rdNOP = nop;
1535
1536 instantiator.replacePlaceholder("rd-nop", rdNOP);
1537 instantiator.replacePlaceholder("nop-instruction", NOP_);
1538 instantiator.replacePlaceholder(
1539 "rv32-microcode-simm-assign", "simm_out <= simm_r;");
1540
1541 const std::string DS = FileSystem::DIRECTORY_SEPARATOR;
1542 const std::string templateDir = Environment::dataDirPath("ProGe");
1543
1544 instantiator.replacePlaceholder(
1545 "rv32-microcode-instruction-assign",
1546 "instruction <= instruction_in;");
1547
1548 if (hasForwarding_) {
1549 std::string forwardingPorts =
1550 " clk : in std_logic;\n"
1551 " rstx : in std_logic;\n"
1552 " glock_in : in std_logic;\n"
1553 " data_hazard_in : in std_logic;\n"
1554 " rs1_hazard_in : in std_logic;\n"
1555 " rs2_hazard_in : in std_logic;\n"
1556 " halt : in std_logic;\n";
1557
1558 std::string forwardingPortMapping =
1559 "clk => clk,\n"
1560 "rstx => rstx,\n"
1561 "glock_in => glock_in,\n"
1562 "data_hazard_in => data_hazard,\n"
1563 "rs1_hazard_in => rs1_hazard,\n"
1564 "rs2_hazard_in => rs2_hazard,\n"
1565 "halt => filling_instruction_pipeline,";
1566
1567 instantiator.replacePlaceholder("forwarding-ports", forwardingPorts);
1568 instantiator.replacePlaceholder(
1569 "forwarding-port-mapping", forwardingPortMapping);
1570 } else {
1571 instantiator.replacePlaceholder(
1572 "data-hazard-stall", "and data_hazard = '0'");
1573 instantiator.replacePlaceholder(
1574 "data-hazard-assign-conds",
1575 "elsif(data_hazard_r = '1') then\n"
1576 " data_hazard <= '0';");
1577 instantiator.replacePlaceholder(
1578 "data-hazard-detection-sensitivity-list-signals",
1579 ", data_hazard_r");
1580 }
1581 instantiator.replacePlaceholder(
1582 "rv32-microcode-op-latency-process",
1583 generateOperationLatencyLogic(instantiator));
1584 std::string otherStates;
1585
1587 otherStates += ",HANDLE_OP_LATENCY";
1588 }
1590 otherStates += ",FILL_INSTRUCTION_PIPELINE_2";
1591 }
1592 instantiator.replacePlaceholder(
1593 "rv32-microcode-other-states", otherStates);
1594 std::string executeLogic;
1595 std::string fsm_sensitivity_list_signals;
1596 executeLogic =
1597 " if(glock_in = '1') then\n"
1598 " bubble <= '1';\n"
1599 " stall_ifetch <= '0';\n"
1600 " NS <= EXECUTE;\n"
1601 " elsif (rv_jump_wire = '1' or rv_auipc_wire = '1') then\n"
1602 " rd_bus_move <= rd_move;\n"
1603 " stall_ifetch <= '0';\n"
1604 " bubble <= '1';\n"
1605 " if rv_auipc_wire = '0' then\n"
1606 " NS <= FILL_INSTRUCTION_PIPELINE;\n"
1607 " end if;\n";
1608 if (!hasForwarding_) {
1609 fsm_sensitivity_list_signals = ", data_hazard";
1611 executeLogic +=
1612 " elsif(op_latency_stall = '1' and data_hazard = '0') then\n"
1613 " bubble <= '0';\n"
1614 " NS <= HANDLE_OP_LATENCY;\n"
1615 " stall_ifetch <= '1';\n"
1616 " rd_bus_move <= rd_nop_c;\n";
1617 }
1618 executeLogic +=
1619 " elsif(data_hazard = '1') then\n"
1620 " bubble <= '1';\n"
1621 " rd_bus_move <= rd_nop_c;\n"
1622 " stall_ifetch <= '1';\n"
1623 " NS <= EXECUTE;\n"
1624 " elsif (is_control_flow_op = '1') then\n"
1625 " bubble <= '0';\n"
1626 " stall_ifetch <= '1';\n"
1627 " NS <= HANDLE_CONTROL_FLOW_OP;\n"
1628 " handle_control_flow_ns <= '1';\n"
1629 " else\n"
1630 " bubble <= '0';\n"
1631 " stall_ifetch <= '0';\n"
1632 " NS <= EXECUTE;\n"
1633 " end if;\n";
1634 } else {
1636 executeLogic +=
1637 " elsif(op_latency_stall = '1') then\n"
1638 " bubble <= '0';\n"
1639 " NS <= HANDLE_OP_LATENCY;\n"
1640 " stall_ifetch <= '1';\n"
1641 " rd_bus_move <= rd_nop_c;\n";
1642 }
1643 executeLogic +=
1644 " elsif (is_control_flow_op = '1') then\n"
1645 " bubble <= '0';\n"
1646 " stall_ifetch <= '1';\n"
1647 " NS <= HANDLE_CONTROL_FLOW_OP;\n"
1648 " handle_control_flow_ns <= '1';\n"
1649 " else\n"
1650 " bubble <= '0';\n"
1651 " stall_ifetch <= '0';\n"
1652 " NS <= EXECUTE;\n"
1653 " end if;\n";
1654 }
1656 fsm_sensitivity_list_signals += ", op_latency_stall";
1657 executeLogic +=
1658 "\n"
1659 "when HANDLE_OP_LATENCY =>\n"
1660 " bubble <= '1';\n"
1661 " stall_ifetch <= '1';\n"
1662 " rd_bus_move <= rd_nop_c;\n"
1663 " NS <= HANDLE_OP_LATENCY;\n"
1664 " if(op_latency_stall = '0') then\n"
1665 " NS <= EXECUTE;\n"
1666 " stall_ifetch <= '0';\n"
1667 " rd_bus_move <= rd_move;\n"
1668 " end if;";
1669 }
1670 std::string instructionPipelineStates;
1672 instructionPipelineStates =
1673 "when FILL_INSTRUCTION_PIPELINE =>\n"
1674 " filling_instruction_pipeline <= '1';\n"
1675 " bubble <= '1';\n"
1676 " rd_bus_move <= rd_nop_c;\n"
1677 " stall_ifetch <= '0';\n"
1678 " NS <= EXECUTE;\n";
1679 } else {
1680 instructionPipelineStates =
1681 "when FILL_INSTRUCTION_PIPELINE =>\n"
1682 " filling_instruction_pipeline <= '1';\n"
1683 " bubble <= '1';\n"
1684 " rd_bus_move <= rd_nop_c;\n"
1685 " stall_ifetch <= '0';\n"
1686 " NS <= FILL_INSTRUCTION_PIPELINE_2;\n"
1687 "\n"
1688 "\n"
1689 "when FILL_INSTRUCTION_PIPELINE_2 =>\n"
1690 " filling_instruction_pipeline <= '1';\n"
1691 " bubble <= '1';\n"
1692 " rd_bus_move <= rd_nop_c;\n"
1693 " stall_ifetch <= '0';\n"
1694 " NS <= EXECUTE;\n"
1695 "\n";
1696 }
1697 instantiator.replacePlaceholder(
1698 "rv32-microcode-instruction-pipeline-logic",
1699 instructionPipelineStates);
1700
1701 instantiator.replacePlaceholder(
1702 "rv32-microcode-fsm-sensitivity-list-signals",
1703 fsm_sensitivity_list_signals);
1704 instantiator.replacePlaceholder(
1705 "rv32-microcode-execute-logic", executeLogic);
1706
1708 instantiator.replacePlaceholder("rv32-custom0-frame-cond",
1709 "or frame_r_c(1) = opcode");
1710 }
1711 instantiator.instantiateTemplateFile(
1712 templateDir + DS + "rv32_microcode_wrapper.vhdl.tmpl",
1713 fileDst + DS + "rv32_microcode_wrapper.vhdl");
1714}
static std::string dataDirPath(const std::string &prog)
void instantiateTemplateFile(const std::string &templateFile, const std::string &dstFile)
std::string generateOperationLatencyLogic(HDLTemplateInstantiator &instantiator)

References Environment::dataDirPath(), FileSystem::DIRECTORY_SEPARATOR, DS, HDLTemplateInstantiator::instantiateTemplateFile(), and HDLTemplateInstantiator::replacePlaceholder().

Here is the call graph for this function:

◆ initializeOperations()

void ProGe::RV32MicroCodeGenerator::initializeOperations ( )
private

Definition at line 142 of file RV32MicroCodeGenerator.cc.

142 {
143 for (int i = 0; i < bem_->instructionFormatCount(); i++) {
145 for (int j = 0; j < fTemp.operationCount(); j++) {
146 std::string name = fTemp.operationAtIndex(j);
147 int encoding = fTemp.encoding(name);
148 BitVector bits = BitVector();
149 if (fTemp.name() == RISCVFields::RISCV_R_TYPE_NAME) {
150 bits.pushBack(encoding, 17);
151 std::string encBits = bits.toString();
153 const std::string tceOpName = RISCVFields::RISCVOperationNameTable.at(name);
154 rOperations_.insert({tceOpName, encBits});
155 } else {
157 rOperations_.insert({name, encBits});
158 }
159 } else if (fTemp.name() == RISCVFields::RISCV_I_TYPE_NAME) {
160 std::string encBits;
161 // Shift operations use imm bits for opcode
162 if (name == "srai" || name == "slli" || name == "srli") {
163 bits.pushBack(encoding, 17);
164 encBits = bits.toString();
165 } else {
166 bits.pushBack(encoding, 10);
167 encBits = bits.toString();
168 }
170 const std::string tceOpName = RISCVFields::RISCVOperationNameTable.at(name);
171 iOperations_.insert({tceOpName, encBits});
172 } else {
173 iOperations_.insert({name, encBits});
174 }
175 } else if (fTemp.name() == RISCVFields::RISCV_S_TYPE_NAME) {
176 bits.pushBack(encoding, 10);
177 std::string encBits = bits.toString();
179 const std::string tceOpName = RISCVFields::RISCVOperationNameTable.at(name);
180 sOperations_.insert({tceOpName, encBits});
181 } else {
182 sOperations_.insert({name, encBits});
183 }
184 } else if (fTemp.name() == RISCVFields::RISCV_B_TYPE_NAME) {
185 bits.pushBack(encoding, 10);
186 std::string encBits = bits.toString();
188 const std::string tceOpName = RISCVFields::RISCVOperationNameTable.at(name);
189 bOperations_.insert(
190 {RISCVFields::RISCVOperationNameTable.at(name), encBits});
191 } else {
192 bOperations_.insert({name, encBits});
193 }
194 } else if (fTemp.name() == RISCVFields::RISCV_U_TYPE_NAME) {
195 bits.pushBack(encoding, 7);
196 std::string encBits = bits.toString();
198 const std::string tceOpName = RISCVFields::RISCVOperationNameTable.at(name);
199 ujOperations_.insert({tceOpName, encBits});
200 } else {
201 ujOperations_.insert({name, encBits});
202 }
203 } else if (fTemp.name() == RISCVFields::RISCV_J_TYPE_NAME) {
204 bits.pushBack(encoding, 7);
205 std::string encBits = bits.toString();
207 const std::string tceOpName = RISCVFields::RISCVOperationNameTable.at(name);
208 ujOperations_.insert({tceOpName, encBits});
209 } else {
210 ujOperations_.insert({name, encBits});
211 }
212 } else if (fTemp.name() == RISCVFields::RISCV_R1R_TYPE_NAME) {
213 bits.pushBack(encoding, 17);
214 std::string encBits = bits.toString();
216 const std::string tceOpName = RISCVFields::RISCVOperationNameTable.at(name);
217 r1rOperations_.insert({tceOpName, encBits});
218 } else {
219 r1rOperations_.insert({name, encBits});
220 }
221 } else if (fTemp.name() == RISCVFields::RISCV_R1_TYPE_NAME) {
222 bits.pushBack(encoding, 17);
223 std::string encBits = bits.toString();
225 const std::string tceOpName = RISCVFields::RISCVOperationNameTable.at(name);
226 r1Operations_.insert({tceOpName, encBits});
227 } else {
228 r1Operations_.insert({name, encBits});
229 }
230 }
231 }
232 }
233}
int instructionFormatCount() const
InstructionFormat & instructionFormat(int index) const
void pushBack(long long unsigned int integer, int size)
Definition BitVector.cc:94
std::string operationAtIndex(const int index) const
int encoding(const std::string &op) const
std::string name() const
static bool containsKey(const MapType &aMap, const KeyType &aKey)
const std::string RISCV_S_TYPE_NAME
const std::string RISCV_R1R_TYPE_NAME
const std::string RISCV_B_TYPE_NAME
const std::string RISCV_J_TYPE_NAME
const std::string RISCV_R_TYPE_NAME
const std::string RISCV_R1_TYPE_NAME
const std::string RISCV_I_TYPE_NAME
const std::string RISCV_U_TYPE_NAME

References ProGe::MicroCodeGenerator::bem_, bOperations_, MapTools::containsKey(), InstructionFormat::encoding(), hasCustom0Operations_, BinaryEncoding::instructionFormat(), BinaryEncoding::instructionFormatCount(), iOperations_, InstructionFormat::name(), InstructionFormat::operationAtIndex(), InstructionFormat::operationCount(), BitVector::pushBack(), r1Operations_, r1rOperations_, RISCVFields::RISCV_B_TYPE_NAME, RISCVFields::RISCV_I_TYPE_NAME, RISCVFields::RISCV_J_TYPE_NAME, RISCVFields::RISCV_R1_TYPE_NAME, RISCVFields::RISCV_R1R_TYPE_NAME, RISCVFields::RISCV_R_TYPE_NAME, RISCVFields::RISCV_S_TYPE_NAME, RISCVFields::RISCV_U_TYPE_NAME, RISCVFields::RISCVOperationNameTable, rOperations_, sOperations_, BitVector::toString(), and ujOperations_.

Referenced by RV32MicroCodeGenerator().

Here is the call graph for this function:

◆ mapFunctionUnit()

FunctionUnit * ProGe::RV32MicroCodeGenerator::mapFunctionUnit ( const std::string &  operation) const
private

Definition at line 280 of file RV32MicroCodeGenerator.cc.

280 {
282 for (int i = 0; i < fuNav.count(); i++) {
283 FunctionUnit* fu = fuNav.item(i);
284 if (fu->hasOperation(operation)) {
285 return fu;
286 }
287 }
288 if (machine_->controlUnit()->hasOperation(operation)) {
289 return static_cast<FunctionUnit*>(machine_->controlUnit());
290 }
292 return NULL;
293}
void throwOperationNotFoundError(const std::string &op) const
virtual bool hasOperation(const std::string &name) const
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380

References TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::FunctionUnit::hasOperation(), TTAMachine::Machine::Navigator< ComponentType >::item(), ProGe::MicroCodeGenerator::machine_, and throwOperationNotFoundError().

Referenced by addBPorts(), addIPorts(), addR1Ports(), addR1RPorts(), addRPorts(), addSPorts(), addUJPorts(), constructBInstructions(), constructIInstructions(), constructR1Instructions(), constructR1RInstructions(), constructRInstructions(), constructSInstructions(), and constructUJInstructions().

Here is the call graph for this function:

◆ operationPorts()

std::set< Port * > ProGe::RV32MicroCodeGenerator::operationPorts ( const std::unordered_map< std::string, BaseFUPort * > &  ports) const
private

Definition at line 677 of file RV32MicroCodeGenerator.cc.

678 {
679 std::set<Port*> retval;
680 for (const auto& op : ports) {
681 retval.insert(static_cast<Port*>(op.second));
682 }
683 return retval;
684}

Referenced by findConnectedBusses().

◆ setBypassInstructionRegister()

void ProGe::RV32MicroCodeGenerator::setBypassInstructionRegister ( const bool &  value)

Definition at line 1724 of file RV32MicroCodeGenerator.cc.

1724 {
1726}

Referenced by DefaultICDecoderGenerator::generate().

◆ throwInputPortError()

void ProGe::RV32MicroCodeGenerator::throwInputPortError ( const BaseFUPort port,
const std::string &  type 
) const
private

Definition at line 313 of file RV32MicroCodeGenerator.cc.

314 {
315 std::string fuName = port->parentUnit()->name();
316 std::string msg = type + " operand port \'" + port->name() +
317 "\' in FU \'" + fuName + "\' not mapped as input";
318 throw InvalidData(__FILE__, __LINE__, __func__, msg);
319}
FunctionUnit * parentUnit() const
Definition BaseFUPort.cc:96
virtual std::string name() const
Definition Port.cc:141

References __func__, TTAMachine::Component::name(), TTAMachine::Port::name(), and TTAMachine::BaseFUPort::parentUnit().

Referenced by addBPorts(), addRPorts(), and addSPorts().

Here is the call graph for this function:

◆ throwOperandCountError()

void ProGe::RV32MicroCodeGenerator::throwOperandCountError ( const std::string &  op,
int  required,
int  found 
) const
private

Definition at line 331 of file RV32MicroCodeGenerator.cc.

332 {
333 std::string msg = "Operation " + op +
334 " has invalid amount of operands. " +
335 std::to_string(required) + " required, " +
336 std::to_string(found) + " found.";
337 throw InvalidData(__FILE__, __LINE__, __func__, msg);
338}

References __func__.

Referenced by addBPorts(), addIPorts(), addR1Ports(), addR1RPorts(), addRPorts(), and addSPorts().

◆ throwOperationNotFoundError()

void ProGe::RV32MicroCodeGenerator::throwOperationNotFoundError ( const std::string &  op) const
private

Definition at line 296 of file RV32MicroCodeGenerator.cc.

297 {
298 std::string msg = "Cannot find operation '" + op + "\' in machine.";
299 throw InvalidData(__FILE__, __LINE__, __func__, msg);
300}

References __func__.

Referenced by mapFunctionUnit(), and validateOperations().

◆ throwOutputPortError()

void ProGe::RV32MicroCodeGenerator::throwOutputPortError ( const BaseFUPort port,
const std::string &  type 
) const
private

Definition at line 322 of file RV32MicroCodeGenerator.cc.

323 {
324 std::string fuName = port->parentUnit()->name();
325 std::string msg = type + " operand port \'" + port->name() +
326 "\' in FU \'" + fuName + "\' not mapped as output";
327 throw InvalidData(__FILE__, __LINE__, __func__, msg);
328}

References __func__, TTAMachine::Component::name(), TTAMachine::Port::name(), and TTAMachine::BaseFUPort::parentUnit().

Referenced by addIPorts(), addR1RPorts(), addRPorts(), and addUJPorts().

Here is the call graph for this function:

◆ throwTriggeringPortError()

void ProGe::RV32MicroCodeGenerator::throwTriggeringPortError ( const BaseFUPort port,
const std::string &  type 
) const
private

Definition at line 303 of file RV32MicroCodeGenerator.cc.

304 {
305 std::string fuName = port->parentUnit()->name();
306 std::string msg = type + " operand port \'" + port->name() +
307 "\' in FU \'" + fuName +
308 "\' not mapped as triggering port";
309 throw InvalidData(__FILE__, __LINE__, __func__, msg);
310}

References __func__, TTAMachine::Component::name(), TTAMachine::Port::name(), and TTAMachine::BaseFUPort::parentUnit().

Referenced by addBPorts(), addR1Ports(), addR1RPorts(), addRPorts(), addSPorts(), and addUJPorts().

Here is the call graph for this function:

◆ validateOperations()

void ProGe::RV32MicroCodeGenerator::validateOperations ( ) const
private

Definition at line 236 of file RV32MicroCodeGenerator.cc.

236 {
237 for (const auto& op : sOperations_) {
238 const std::string opName = op.first;
239 if (!machine_->hasOperation(opName)) {
241 }
242 }
243 for (const auto& op : bOperations_) {
244 const std::string opName = op.first;
245 if (!machine_->hasOperation(opName)) {
247 }
248 }
249 for (const auto& op : ujOperations_) {
250 const std::string opName = op.first;
251 if (op.first != "move") {
252 if (!machine_->hasOperation(opName)) {
254 }
255 }
256 }
257 for (const auto& op : rOperations_) {
258 const std::string opName = op.first;
259 if (!machine_->hasOperation(opName)) {
261 }
262 }
263
264 for (const auto& op : r1rOperations_) {
265 const std::string opName = op.first;
266 if (!machine_->hasOperation(opName)) {
268 }
269 }
270
271 for (const auto& op : r1Operations_) {
272 const std::string opName = op.first;
273 if (!machine_->hasOperation(opName)) {
275 }
276 }
277}
bool hasOperation(const TCEString &opName) const
Definition Machine.cc:1042

References bOperations_, TTAMachine::Machine::hasOperation(), ProGe::MicroCodeGenerator::machine_, r1Operations_, r1rOperations_, rOperations_, sOperations_, throwOperationNotFoundError(), and ujOperations_.

Here is the call graph for this function:

Member Data Documentation

◆ bOperations_

std::map<std::string, std::string> ProGe::RV32MicroCodeGenerator::bOperations_
private

◆ busses_

std::vector<Bus*> ProGe::RV32MicroCodeGenerator::busses_
private

Definition at line 186 of file RV32MicroCodeGenerator.hh.

Referenced by findConnectedBusses(), and RV32MicroCodeGenerator().

◆ bypassInstructionRegister_

bool ProGe::RV32MicroCodeGenerator::bypassInstructionRegister_
private

Definition at line 219 of file RV32MicroCodeGenerator.hh.

◆ eVariant_

bool ProGe::RV32MicroCodeGenerator::eVariant_
private

Definition at line 222 of file RV32MicroCodeGenerator.hh.

Referenced by findRF().

◆ hasCustom0Operations_

bool ProGe::RV32MicroCodeGenerator::hasCustom0Operations_
private

Definition at line 223 of file RV32MicroCodeGenerator.hh.

Referenced by initializeOperations().

◆ hasForwarding_

bool ProGe::RV32MicroCodeGenerator::hasForwarding_
private

Definition at line 220 of file RV32MicroCodeGenerator.hh.

Referenced by connectRF(), and RV32MicroCodeGenerator().

◆ iOperations_

std::map<std::string, std::string> ProGe::RV32MicroCodeGenerator::iOperations_
private

◆ NOP_

std::string ProGe::RV32MicroCodeGenerator::NOP_
private

Definition at line 218 of file RV32MicroCodeGenerator.hh.

Referenced by generateNOP().

◆ pig_

ProgramImageGenerator* ProGe::RV32MicroCodeGenerator::pig_
private

◆ r1Operations_

std::map<std::string, std::string> ProGe::RV32MicroCodeGenerator::r1Operations_
private

◆ r1rOperations_

std::map<std::string, std::string> ProGe::RV32MicroCodeGenerator::r1rOperations_
private

◆ rdBus_

Bus* ProGe::RV32MicroCodeGenerator::rdBus_
private

◆ rdBusStart_

int ProGe::RV32MicroCodeGenerator::rdBusStart_
private

Definition at line 197 of file RV32MicroCodeGenerator.hh.

Referenced by findBusWidths().

◆ rdBusWidth_

int ProGe::RV32MicroCodeGenerator::rdBusWidth_
private

Definition at line 192 of file RV32MicroCodeGenerator.hh.

Referenced by findBusWidths().

◆ rdPorts_

std::unordered_map<std::string, BaseFUPort*> ProGe::RV32MicroCodeGenerator::rdPorts_
private

◆ rdRFPort_

RFPort* ProGe::RV32MicroCodeGenerator::rdRFPort_
private

◆ rdRFStart_

int ProGe::RV32MicroCodeGenerator::rdRFStart_
private

Definition at line 203 of file RV32MicroCodeGenerator.hh.

Referenced by findBusWidths().

◆ RF_

RegisterFile* ProGe::RV32MicroCodeGenerator::RF_
private

Definition at line 188 of file RV32MicroCodeGenerator.hh.

Referenced by connectRF(), and findRF().

◆ rOperations_

std::map<std::string, std::string> ProGe::RV32MicroCodeGenerator::rOperations_
private

◆ rs1Bus_

Bus* ProGe::RV32MicroCodeGenerator::rs1Bus_
private

◆ rs1BusStart_

int ProGe::RV32MicroCodeGenerator::rs1BusStart_
private

Definition at line 195 of file RV32MicroCodeGenerator.hh.

Referenced by findBusWidths().

◆ rs1BusWidth_

int ProGe::RV32MicroCodeGenerator::rs1BusWidth_
private

Definition at line 190 of file RV32MicroCodeGenerator.hh.

Referenced by findBusWidths().

◆ rs1Ports_

std::unordered_map<std::string, BaseFUPort*> ProGe::RV32MicroCodeGenerator::rs1Ports_
private

◆ rs1RFPort_

RFPort* ProGe::RV32MicroCodeGenerator::rs1RFPort_
private

Definition at line 212 of file RV32MicroCodeGenerator.hh.

Referenced by connectRF(), and constructUJInstructions().

◆ rs1RFStart_

int ProGe::RV32MicroCodeGenerator::rs1RFStart_
private

Definition at line 201 of file RV32MicroCodeGenerator.hh.

Referenced by findBusWidths().

◆ rs2Bus_

Bus* ProGe::RV32MicroCodeGenerator::rs2Bus_
private

◆ rs2BusStart_

int ProGe::RV32MicroCodeGenerator::rs2BusStart_
private

Definition at line 196 of file RV32MicroCodeGenerator.hh.

Referenced by findBusWidths().

◆ rs2BusWidth_

int ProGe::RV32MicroCodeGenerator::rs2BusWidth_
private

Definition at line 191 of file RV32MicroCodeGenerator.hh.

Referenced by findBusWidths().

◆ rs2Ports_

std::unordered_map<std::string, BaseFUPort*> ProGe::RV32MicroCodeGenerator::rs2Ports_
private

◆ rs2RFPort_

RFPort* ProGe::RV32MicroCodeGenerator::rs2RFPort_
private

Definition at line 213 of file RV32MicroCodeGenerator.hh.

Referenced by connectRF().

◆ rs2RFStart_

int ProGe::RV32MicroCodeGenerator::rs2RFStart_
private

Definition at line 202 of file RV32MicroCodeGenerator.hh.

Referenced by findBusWidths().

◆ simmBus_

Bus* ProGe::RV32MicroCodeGenerator::simmBus_
private

◆ simmBusStart_

int ProGe::RV32MicroCodeGenerator::simmBusStart_
private

Definition at line 198 of file RV32MicroCodeGenerator.hh.

Referenced by findBusWidths().

◆ simmBusWidth_

int ProGe::RV32MicroCodeGenerator::simmBusWidth_
private

Definition at line 193 of file RV32MicroCodeGenerator.hh.

Referenced by findBusWidths().

◆ simmPorts_

std::unordered_map<std::string, BaseFUPort*> ProGe::RV32MicroCodeGenerator::simmPorts_
private

◆ simmRFStart_

int ProGe::RV32MicroCodeGenerator::simmRFStart_
private

Definition at line 204 of file RV32MicroCodeGenerator.hh.

Referenced by findBusWidths().

◆ sOperations_

std::map<std::string, std::string> ProGe::RV32MicroCodeGenerator::sOperations_
private

◆ sourceOperationMap_

std::unordered_map<Port*, std::vector<std::string> > ProGe::RV32MicroCodeGenerator::sourceOperationMap_
private

Definition at line 91 of file RV32MicroCodeGenerator.hh.

Referenced by findOperationSources(), and generateFUTargetProcess().

◆ sourcePortID_

std::unordered_map<Port*, int> ProGe::RV32MicroCodeGenerator::sourcePortID_
private

Definition at line 88 of file RV32MicroCodeGenerator.hh.

Referenced by generateFUTargetProcess().

◆ ujOperations_

std::map<std::string, std::string> ProGe::RV32MicroCodeGenerator::ujOperations_
private

◆ variableLengthOpLatency_

bool ProGe::RV32MicroCodeGenerator::variableLengthOpLatency_
private

Definition at line 221 of file RV32MicroCodeGenerator.hh.


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