Skip to content

Commit

Permalink
Implement iterator interface for stages in ProcessorStructure #203
Browse files Browse the repository at this point in the history
  • Loading branch information
mortbopet committed Mar 26, 2022
1 parent 2048c66 commit dd70bcd
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 113 deletions.
44 changes: 20 additions & 24 deletions src/editor/codeeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,31 +445,27 @@ void CodeEditor::updateHighlighting() {
const unsigned stages = proc->structure().numStages();
auto colorGenerator = Colors::incrementalRedGenerator(stages);

for (auto laneIt : proc->structure()) {
for (unsigned stageIdx = 0; stageIdx < laneIt.second; stageIdx++) {
StageIndex sid = StageIndex{laneIt.first, stageIdx};
const auto stageInfo = proc->stageInfo(sid);
QColor stageColor = colorGenerator();
if (stageInfo.stage_valid) {
auto mappingIt = sourceMapping.find(stageInfo.pc);
if (mappingIt == sourceMapping.end()) {
// No source line registerred for this PC.
for (auto sid : proc->structure().stageIt()) {
const auto stageInfo = proc->stageInfo(sid);
QColor stageColor = colorGenerator();
if (stageInfo.stage_valid) {
auto mappingIt = sourceMapping.find(stageInfo.pc);
if (mappingIt == sourceMapping.end()) {
// No source line registerred for this PC.
continue;
}

for (auto sourceLine : mappingIt->second) {
// Find block
QTextBlock block = document()->findBlockByLineNumber(sourceLine);
if (!block.isValid())
continue;
}

for (auto sourceLine : mappingIt->second) {
// Find block
QTextBlock block = document()->findBlockByLineNumber(sourceLine);
if (!block.isValid())
continue;

// Record the stage name for the highlighted block for later painting
QString stageString =
ProcessorHandler::getProcessor()->stageName(sid);
if (!stageInfo.namedState.isEmpty())
stageString += " (" + stageInfo.namedState + ")";
highlightBlock(block, stageColor, stageString);
}

// Record the stage name for the highlighted block for later painting
QString stageString = ProcessorHandler::getProcessor()->stageName(sid);
if (!stageInfo.namedState.isEmpty())
stageString += " (" + stageInfo.namedState + ")";
highlightBlock(block, stageColor, stageString);
}
}
}
Expand Down
58 changes: 26 additions & 32 deletions src/instructionmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,9 @@ int InstructionModel::addressToRow(AInt addr) const {

InstructionModel::InstructionModel(QObject *parent)
: QAbstractTableModel(parent) {
for (auto laneIt : ProcessorHandler::getProcessor()->structure()) {
for (unsigned stageIdx = 0; stageIdx < laneIt.second; stageIdx++) {
StageIndex idx = {laneIt.first, stageIdx};
m_stageNames[idx] = ProcessorHandler::getProcessor()->stageName(idx);
m_stageInfos[idx] = ProcessorHandler::getProcessor()->stageInfo(idx);
}
for (auto idx : ProcessorHandler::getProcessor()->structure().stageIt()) {
m_stageNames[idx] = ProcessorHandler::getProcessor()->stageName(idx);
m_stageInfos[idx] = ProcessorHandler::getProcessor()->stageInfo(idx);
}
connect(ProcessorHandler::get(), &ProcessorHandler::procStateChangedNonRun,
this, &InstructionModel::updateStageInfo);
Expand Down Expand Up @@ -67,34 +64,31 @@ int InstructionModel::rowCount(const QModelIndex &) const { return m_rowCount; }

void InstructionModel::updateStageInfo() {
bool firstStageChanged = false;
for (auto laneIt : ProcessorHandler::getProcessor()->structure()) {
for (unsigned stageIdx = 0; stageIdx < laneIt.second; stageIdx++) {
StageIndex idx = {laneIt.first, stageIdx};
auto stageInfoIt = m_stageInfos.find(idx);
if (stageInfoIt != m_stageInfos.end()) {
auto &oldStageInfo = m_stageInfos.at(idx);
if (idx == StageIndex(0, 0)) {
if (oldStageInfo.pc !=
ProcessorHandler::getProcessor()->stageInfo(idx).pc) {
firstStageChanged = true;
}
}
const auto stageInfo = ProcessorHandler::getProcessor()->stageInfo(idx);
const AInt oldAddress = oldStageInfo.pc;
if (oldStageInfo != stageInfo) {
oldStageInfo = stageInfo;
const int oldRow = addressToRow(oldAddress);
const int newRow = addressToRow(stageInfo.pc);
const QModelIndex oldIdx = index(oldRow, Stage);
const QModelIndex newIdx = index(newRow, Stage);
emit dataChanged(oldIdx, oldIdx, {Qt::DisplayRole});
emit dataChanged(newIdx, newIdx, {Qt::DisplayRole});
}
if (firstStageChanged) {
emit firstStageInstrChanged(addressToRow(m_stageInfos.at({0, 0}).pc));
firstStageChanged = false;
for (auto idx : ProcessorHandler::getProcessor()->structure().stageIt()) {
auto stageInfoIt = m_stageInfos.find(idx);
if (stageInfoIt != m_stageInfos.end()) {
auto &oldStageInfo = m_stageInfos.at(idx);
if (idx == StageIndex(0, 0)) {
if (oldStageInfo.pc !=
ProcessorHandler::getProcessor()->stageInfo(idx).pc) {
firstStageChanged = true;
}
}
const auto stageInfo = ProcessorHandler::getProcessor()->stageInfo(idx);
const AInt oldAddress = oldStageInfo.pc;
if (oldStageInfo != stageInfo) {
oldStageInfo = stageInfo;
const int oldRow = addressToRow(oldAddress);
const int newRow = addressToRow(stageInfo.pc);
const QModelIndex oldIdx = index(oldRow, Stage);
const QModelIndex newIdx = index(newRow, Stage);
emit dataChanged(oldIdx, oldIdx, {Qt::DisplayRole});
emit dataChanged(newIdx, newIdx, {Qt::DisplayRole});
}
if (firstStageChanged) {
emit firstStageInstrChanged(addressToRow(m_stageInfos.at({0, 0}).pc));
firstStageChanged = false;
}
}
}
}
Expand Down
10 changes: 3 additions & 7 deletions src/pipelinediagrammodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,9 @@ void PipelineDiagramModel::gatherStageInfo() {
if (stageInfoForCycle == m_cycleStageInfos.end()) {
return;
}
for (auto laneIt : ProcessorHandler::getProcessor()->structure()) {
for (unsigned stageIdx = 0; stageIdx < laneIt.second; stageIdx++) {
StageIndex idx = {laneIt.first, stageIdx};
stageInfoForCycle->second[idx] =
ProcessorHandler::getProcessor()->stageInfo(idx);
}
}
for (auto idx : ProcessorHandler::getProcessor()->structure().stageIt())
stageInfoForCycle->second[idx] =
ProcessorHandler::getProcessor()->stageInfo(idx);
}

QVariant PipelineDiagramModel::data(const QModelIndex &index, int role) const {
Expand Down
64 changes: 55 additions & 9 deletions src/processors/interface/ripesprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,68 @@ struct MemoryAccess {

struct StageIndex : public std::pair<unsigned, unsigned> {
using std::pair<unsigned, unsigned>::pair;
unsigned lane() const {return this->first;}
unsigned index() const {return this->second;}
unsigned lane() const { return this->first; }
unsigned index() const { return this->second; }
};


/// Structural description of the processor model. Currently this is a map of {# of lanes, # of stages}.
/// @todo: add an iterator over all stages.
/// Structural description of the processor model. Currently this is a map of {#
/// of lanes, # of stages}.
struct ProcessorStructure : public std::map<unsigned, unsigned> {
using std::map<unsigned, unsigned>::map;

struct StageIterator {
StageIterator(const ProcessorStructure &structure)
: m_structure(structure) {}

struct Iterator {
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = StageIndex;
using pointer = value_type *;
using reference = value_type &;

Iterator(unsigned lane, unsigned index,
const ProcessorStructure &structure)
: m_lane(lane), m_index(index), m_structure(structure) {}
StageIndex operator*() const { return {m_lane, m_index}; }
StageIndex operator->() const { return {m_lane, m_index}; }
Iterator &operator++() {
++m_index;
if (m_index == m_structure.at(m_lane)) {
m_index = 0;
++m_lane;
}
return *this;
}
Iterator operator++(int) {
Iterator tmp = *this;
++(*this);
return tmp;
}
bool operator==(const Iterator &other) const {
return m_lane == other.m_lane && m_index == other.m_index;
}
bool operator!=(const Iterator &other) const { return !(*this == other); }

unsigned m_lane = 0;
unsigned m_index = 0;
const ProcessorStructure &m_structure;
};

Iterator begin() const { return Iterator(0, 0, m_structure); }
Iterator end() const {
return Iterator(m_structure.size(), 0, m_structure);
}
const ProcessorStructure &m_structure;
};

// Returns an iterator over all stages.
StageIterator stageIt() const { return {*this}; }

// Returns the total number of stages of this processor.
unsigned numStages() const {
unsigned count = 0;
for(auto it : *this)
for (auto it : *this)
count += it.second;
return count;
}
Expand Down Expand Up @@ -129,9 +177,7 @@ class RipesProcessor {
* @brief stageCount
* @return number of stages for the processor
*/
virtual const ProcessorStructure& structure() const = 0;


virtual const ProcessorStructure &structure() const = 0;

/**
* @brief getPcForStage
Expand Down
46 changes: 20 additions & 26 deletions src/processortab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,12 @@ void ProcessorTab::loadLayout(const Layout &layout) {

// Adjust stage label positions
const auto &parent = m_stageInstructionLabels.at({0, 0})->parentItem();
for (auto laneIt : ProcessorHandler::getProcessor()->structure()) {
for (unsigned stageIdx = 0; stageIdx < laneIt.second; stageIdx++) {
StageIndex sid = {laneIt.first, stageIdx};
auto &label = m_stageInstructionLabels.at(sid);
QFontMetrics metrics(label->font());
label->setPos(parent->boundingRect().width() *
layout.stageLabelPositions.at(sid).x(),
metrics.height() * layout.stageLabelPositions.at(sid).y());
}
for (auto sid : ProcessorHandler::getProcessor()->structure().stageIt()) {
auto &label = m_stageInstructionLabels.at(sid);
QFontMetrics metrics(label->font());
label->setPos(parent->boundingRect().width() *
layout.stageLabelPositions.at(sid).x(),
metrics.height() * layout.stageLabelPositions.at(sid).y());
}
}

Expand Down Expand Up @@ -473,31 +470,28 @@ void ProcessorTab::enableSimulatorControls() {

void ProcessorTab::updateInstructionLabels() {
const auto &proc = ProcessorHandler::getProcessor();
for (auto laneIt : ProcessorHandler::getProcessor()->structure()) {
for (unsigned stageIdx = 0; stageIdx < laneIt.second; stageIdx++) {
StageIndex sid = {laneIt.first, stageIdx};
if (!m_stageInstructionLabels.count(sid))
continue;
const auto stageInfo = proc->stageInfo(sid);
auto &instrLabel = m_stageInstructionLabels.at(sid);
QString instrString;
if (stageInfo.state != StageInfo::State::None) {
/* clang-format off */
for (auto sid : ProcessorHandler::getProcessor()->structure().stageIt()) {
if (!m_stageInstructionLabels.count(sid))
continue;
const auto stageInfo = proc->stageInfo(sid);
auto &instrLabel = m_stageInstructionLabels.at(sid);
QString instrString;
if (stageInfo.state != StageInfo::State::None) {
/* clang-format off */
switch (stageInfo.state) {
case StageInfo::State::Flushed: instrString = "nop (flush)"; break;
case StageInfo::State::Stalled: instrString = "nop (stall)"; break;
case StageInfo::State::WayHazard: if(stageInfo.stage_valid) {instrString = "nop (way hazard)";} break;
case StageInfo::State::Unused: instrString = "nop (unused)"; break;
case StageInfo::State::None: Q_UNREACHABLE();
}
/* clang-format on */
instrLabel->forceDefaultTextColor(Qt::red);
} else if (stageInfo.stage_valid) {
instrString = ProcessorHandler::disassembleInstr(stageInfo.pc);
instrLabel->clearForcedDefaultTextColor();
}
instrLabel->setText(instrString);
/* clang-format on */
instrLabel->forceDefaultTextColor(Qt::red);
} else if (stageInfo.stage_valid) {
instrString = ProcessorHandler::disassembleInstr(stageInfo.pc);
instrLabel->clearForcedDefaultTextColor();
}
instrLabel->setText(instrString);
}
}

Expand Down
27 changes: 12 additions & 15 deletions src/programviewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,21 +105,18 @@ void ProgramViewer::updateHighlightedAddresses() {
ProcessorHandler::getProcessor()->structure().numStages();
auto colorGenerator = Colors::incrementalRedGenerator(stages);

for (auto laneIt : ProcessorHandler::getProcessor()->structure()) {
for (unsigned stageIdx = 0; stageIdx < laneIt.second; stageIdx++) {
StageIndex sid = {laneIt.first, stageIdx};
const auto stageInfo = ProcessorHandler::getProcessor()->stageInfo(sid);
if (stageInfo.stage_valid) {
auto block = blockForAddress(stageInfo.pc);
if (!block.isValid())
continue;

// Record the stage name for the highlighted block for later painting
QString stageString = ProcessorHandler::getProcessor()->stageName(sid);
if (!stageInfo.namedState.isEmpty())
stageString += " (" + stageInfo.namedState + ")";
highlightBlock(block, colorGenerator(), stageString);
}
for (auto sid : ProcessorHandler::getProcessor()->structure().stageIt()) {
const auto stageInfo = ProcessorHandler::getProcessor()->stageInfo(sid);
if (stageInfo.stage_valid) {
auto block = blockForAddress(stageInfo.pc);
if (!block.isValid())
continue;

// Record the stage name for the highlighted block for later painting
QString stageString = ProcessorHandler::getProcessor()->stageName(sid);
if (!stageInfo.namedState.isEmpty())
stageString += " (" + stageInfo.namedState + ")";
highlightBlock(block, colorGenerator(), stageString);
}
}

Expand Down

0 comments on commit dd70bcd

Please sign in to comment.