Skip to content

Commit

Permalink
fixed issue with pipeline stage 'ready' trigger
Browse files Browse the repository at this point in the history
  • Loading branch information
sylefeb committed Dec 6, 2023
1 parent 08c80a6 commit e7e0891
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 23 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Silice
*A language for hardcoding algorithms into FPGA hardware*
*A language for hardcoding algorithms with pipelines and parallelism into FPGA hardware*

---
**Quick links:**
Expand Down
30 changes: 22 additions & 8 deletions src/Algorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4263,11 +4263,16 @@ std::string Algorithm::fsmPipelineStageStall(const t_fsm_nfo *fsm) const
return "_stall_" + fsm->name;
}

std::string Algorithm::fsmPipelineFirstStageDisable(const t_fsm_nfo *fsm) const
std::string Algorithm::fsmPipelineFirstStateDisable(const t_fsm_nfo *fsm) const
{
return "_1stdisable_" + fsm->name;
}

std::string Algorithm::fsmPipelineStageReachedEnd(const t_fsm_nfo* fsm) const
{
return "_reachedend_" + fsm->name;
}

// -------------------------------------------------

std::string Algorithm::fsmNextState(std::string prefix,const t_fsm_nfo *fsm) const
Expand Down Expand Up @@ -7479,12 +7484,16 @@ void Algorithm::writeFlipFlopDeclarations(std::string prefix, std::ostream& out,
out << "reg [" << stateWidth(fsm) - 1 << ":0] " FF_D << prefix << fsmIndex(fsm)
<< "," FF_Q << prefix << fsmIndex(fsm) << ';' << nxl;
out << "wire " << fsmPipelineStageReady(fsm) << " = "
<< "(" << FF_Q << prefix << fsmIndex(fsm) << " == " << toFSMState(fsm, lastPipelineStageState(fsm)) << ')'
// this condition allows to trigger the stage immediately after it reached its end state
<< "(" << FF_Q << prefix << fsmIndex(fsm) << " == " << toFSMState(fsm, lastPipelineStageState(fsm)) << " && " << FF_Q << prefix << fsmPipelineStageReachedEnd(fsm) << ')'
// this condition allows to trigger the stage when idle (becomes idle one cycle after it reached end)
<< " || (" << FF_Q << prefix << fsmIndex(fsm) << " == " << toFSMState(fsm, terminationState(fsm)) << ");" << nxl;
out << "reg [0:0] " FF_D << prefix << fsmPipelineStageFull(fsm) << " = 0"
<< "," FF_Q << prefix << fsmPipelineStageFull(fsm) << " = 0;" << nxl;
out << "reg [0:0] " FF_TMP << prefix << fsmPipelineStageStall(fsm) << " = 0;" << nxl;
out << "reg [0:0] " FF_TMP << prefix << fsmPipelineFirstStageDisable(fsm) << " = 0;" << nxl;
out << "reg [0:0] " FF_TMP << prefix << fsmPipelineFirstStateDisable(fsm) << " = 0;" << nxl;
out << "reg [0:0] " FF_D << prefix << fsmPipelineStageReachedEnd(fsm) << " = 0"
<< "," FF_Q << prefix << fsmPipelineStageReachedEnd(fsm) << " = 0;" << nxl;
}
}
// state machine caller id (subroutines)
Expand Down Expand Up @@ -7765,7 +7774,8 @@ void Algorithm::writeCombinationalAlwaysPre(
w.out << FF_D << "_" << fsmIndex(fsm) << " = " << FF_Q << "_" << fsmIndex(fsm) << ';' << nxl;
w.out << FF_D << "_" << fsmPipelineStageFull(fsm) << " = " << FF_Q << "_" << fsmPipelineStageFull(fsm) << ';' << nxl;
w.out << FF_TMP << "_" << fsmPipelineStageStall(fsm) << " = 0;" << nxl;
w.out << FF_TMP << "_" << fsmPipelineFirstStageDisable(fsm) << " = 0;" << nxl;
w.out << FF_TMP << "_" << fsmPipelineFirstStateDisable(fsm) << " = 0;" << nxl;
w.out << FF_D << "_" << fsmPipelineStageReachedEnd(fsm) << " = 0;" << nxl;
}
// instanced algorithms run, maintain high
for (const auto& iaiordr : m_InstancedBlueprintsInDeclOrder) {
Expand Down Expand Up @@ -8317,7 +8327,7 @@ void Algorithm::disableStartingPipelines(std::string prefix, t_writer_context &w
findAllStartingPipelines(block, pipelines);
for (auto pip : pipelines) {
if (!fsmIsEmpty(pip->stages.front()->fsm)) {
w.out << FF_TMP << '_' << fsmPipelineFirstStageDisable(pip->stages.front()->fsm) << " = 1;" << nxl;
w.out << FF_TMP << '_' << fsmPipelineFirstStateDisable(pip->stages.front()->fsm) << " = 1;" << nxl;
}
}
}
Expand Down Expand Up @@ -8348,11 +8358,11 @@ void Algorithm::writeStatelessBlockGraph(
return;
}
} else {
// first state of pipeline first stage?
// first state of first pipeline stage?
if (block->context.pipeline_stage) {
if (block->context.pipeline_stage->stage_id == 0 && !fsmIsEmpty(fsm)) {
// add conditional on first stage disabled (in case the pipeline is enclosed in a conditional)
w.out << "if (~" << FF_TMP << prefix << fsmPipelineFirstStageDisable(fsm) << ") begin " << nxl;
w.out << "if (~" << FF_TMP << prefix << fsmPipelineFirstStateDisable(fsm) << ") begin " << nxl;
enclosed_in_conditional = true;
}
}
Expand All @@ -8370,6 +8380,8 @@ void Algorithm::writeStatelessBlockGraph(
if (!fsmIsEmpty(fsm)) {
// stage full
w.out << FF_D << '_' << fsmPipelineStageFull(fsm) << " = 1;" << nxl;
// reached end
w.out << FF_D << "_" << fsmPipelineStageReachedEnd(fsm) << " = 1;" << nxl;
// first state of pipeline first stage?
sl_assert(block->context.pipeline_stage);
if (enclosed_in_conditional) { w.out << "end // 0" << nxl; } // end conditional
Expand Down Expand Up @@ -8658,6 +8670,8 @@ void Algorithm::writeStatelessBlockGraph(
if (!fsmIsEmpty(fsm)) {
// stage full
w.out << FF_D << '_' << fsmPipelineStageFull(fsm) << " = 1;" << nxl;
// reached end
w.out << FF_D << "_" << fsmPipelineStageReachedEnd(fsm) << " = 1;" << nxl;
// first state of pipeline first stage?
sl_assert(block->context.pipeline_stage);
if (enclosed_in_conditional) { w.out << "end // 7" << nxl; } // end conditional
Expand All @@ -8679,7 +8693,7 @@ void Algorithm::writeStatelessBlockGraph(
// in a recursion, pipeline might have been disabled so we re-enable it
// (otherwise we are sure it was not disabled, no need to manipulate the signal and risk adding logic)
if (!fsmIsEmpty(current->pipeline_next()->next->context.pipeline_stage->fsm)) {
w.out << FF_TMP << '_' << fsmPipelineFirstStageDisable(current->pipeline_next()->next->context.pipeline_stage->fsm) << " = 0;" << nxl;
w.out << FF_TMP << '_' << fsmPipelineFirstStateDisable(current->pipeline_next()->next->context.pipeline_stage->fsm) << " = 0;" << nxl;
}
}
// write pipeline
Expand Down
13 changes: 8 additions & 5 deletions src/Algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -896,14 +896,17 @@ namespace Silice
void fsmGetBlocks(t_fsm_nfo *fsm, std::unordered_set<t_combinational_block *>& _blocks) const;
/// \brief returns the index name of the fsm
std::string fsmIndex(const t_fsm_nfo *) const;
/// \brief returns the 'ready' signal name of the fsm
/// \brief returns the 'ready' signal name of the pipeline stage fsm
std::string fsmPipelineStageReady(const t_fsm_nfo *) const;
/// \brief returns the 'full' signal name of the fsm
/// \brief returns the 'full' signal name of the pipeline stage fsm
std::string fsmPipelineStageFull(const t_fsm_nfo *) const;
/// \brief returns the 'stall' signal name of the fsm
/// \brief returns the 'stall' signal name of the pipeline stage fsm
std::string fsmPipelineStageStall(const t_fsm_nfo *) const;
/// \brief returns the 'first stage disable' signal name of the fsm
std::string fsmPipelineFirstStageDisable(const t_fsm_nfo *) const;
/// \brief returns the 'first state disable' signal name of the pipeline stage fsm
std::string fsmPipelineFirstStateDisable(const t_fsm_nfo *) const;
/// \brief returns the 'end of pipeline stage' signal name of the pipeline stage fsm
/// (signals the stage just passed the end of the last state, pulses once)
std::string fsmPipelineStageReachedEnd(const t_fsm_nfo* fsm) const;
/// \brief returns an expression that evaluates to the fsm next state
std::string fsmNextState(std::string prefix, const t_fsm_nfo *) const;
/// \brief returns whether the fsm is empty (no state)
Expand Down
15 changes: 6 additions & 9 deletions tests/pipeline29.si
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ algorithm main(output uint8 leds)
{

uint5 i = 0;
while (i!=5)
while (i!=4)
{

// stage 0
Expand All @@ -18,8 +18,7 @@ algorithm main(output uint8 leds)
__display("[B] before (%d)",n);
// stage 1
uint5 j = 0;
uint1 done = 0;
while (~done) {
while (j != 3) {
// nested pipeline
__display("[B,A] %d,%d",n,j);
uint8 q = j + 10;
Expand All @@ -29,15 +28,13 @@ algorithm main(output uint8 leds)
q = q + 100;
->
__display("[B,C] %d,%d",n,q);
if (j == 3) { done = 1; }
}
++: ////////////////////////////// breaks without, why?
__display("[B] after (%d)",n);

->

__display("[C] (%d)",n);

}

}

/*

*/

0 comments on commit e7e0891

Please sign in to comment.