Elastic Pipeline
From Lyra
This is the elastic pipeline example in the Introduction.
The pipeline stage is modeled using the following Lyra module.
module ep_stage(in<int> enq, out<int> deq)
{
reg int myreg;
init
{
myreg = 0;
}
fsm my_fsm
{
init E: // start state
/* enque */
when (enq)
{
/* enq is input, it receives a value, and assign it to myreg */
myreg = enq.read();
goto F;
}
state F:
/* dequeue */
when (deq)
{
/* deq is output, it transmits the value in myreg */
/*common activities for every condition below*/
deq.write(myreg);
myreg = 0;
goto E;
}
when (enq, deq)
{
/* enqueue and dequeue occurs simultaneously
=> pipelined transfer */
/* assignment to a state variable (reg) is non-blocking,
* so the deq uses the old value of myreg, not the
* new one received by enq
*/
deq.write(myreg);
myreg = enq.read();
goto F;
}
}
}
To test it, one can use the following toplevel module and producer/consumer pair.
module toplevel
{
/* two rendezvous, point to point */
rendv p1, p2, p3, p4, p5;
/* instantiation of modules */
ep_stage s1(p1, p2);
ep_stage s2(p2, p3);
ep_stage s3(p3, p4);
ep_stage s4(p4, p5);
producer pro(p1);
consumer con(p5);
}
module producer(out<int> produce)
{
reg int myreg;
init
{
myreg = 1;
}
fsm my_fsm
{
init U: // start state
when (produce)
{
// rendezvous to synchronize with and forward data to buffer
produce.write(myreg);
goto W;
}
state W:
myreg = myreg + 1;
goto U;
}
}
module consumer(in<int> consume)
{
reg int myreg;
init
{
myreg = 0;
}
fsm my_fsm
{
init X: // start state
when (consume)
{
// rendezvous to synchronize with and receive data from buffer
myreg = consume.read();
goto Y;
}
state Y: goto X;
}
}

