more documentation
This commit is contained in:
parent
122bc39d66
commit
7ca0a6209a
|
@ -164,7 +164,8 @@ struct pointerReq
|
||||||
:qpn(qpn), lock(l) {}
|
:qpn(qpn), lock(l) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//TODO maybe introduce seperate request streams
|
/*********************IMPLEMENTATION*********************/
|
||||||
|
|
||||||
template <int INSTID = 0>
|
template <int INSTID = 0>
|
||||||
void retrans_pointer_table( stream<pointerReq>& pointerReqFifo,
|
void retrans_pointer_table( stream<pointerReq>& pointerReqFifo,
|
||||||
stream<pointerUpdate>& pointerUpdFifo,
|
stream<pointerUpdate>& pointerUpdFifo,
|
||||||
|
@ -193,6 +194,7 @@ void retrans_pointer_table( stream<pointerReq>& pointerReqFifo,
|
||||||
ptr_table[upd.qpn] = upd.entry;
|
ptr_table[upd.qpn] = upd.entry;
|
||||||
if (pt_lockedQP == upd.qpn)
|
if (pt_lockedQP == upd.qpn)
|
||||||
{
|
{
|
||||||
|
// clear up lock
|
||||||
pt_isLocked = false;
|
pt_isLocked = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,6 +203,7 @@ void retrans_pointer_table( stream<pointerReq>& pointerReqFifo,
|
||||||
pointerReqFifo.read(pt_req);
|
pointerReqFifo.read(pt_req);
|
||||||
if (pt_req.lock && pt_isLocked)
|
if (pt_req.lock && pt_isLocked)
|
||||||
{
|
{
|
||||||
|
// another lock queing up, waiting for an upd to clear prev lock
|
||||||
pt_wait = true;
|
pt_wait = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -208,6 +211,7 @@ void retrans_pointer_table( stream<pointerReq>& pointerReqFifo,
|
||||||
pointerRspFifo.write(ptr_table[pt_req.qpn]);
|
pointerRspFifo.write(ptr_table[pt_req.qpn]);
|
||||||
if (pt_req.lock)
|
if (pt_req.lock)
|
||||||
{
|
{
|
||||||
|
// lock is claim, can only read, cannot write
|
||||||
pt_isLocked = true;
|
pt_isLocked = true;
|
||||||
pt_lockedQP = pt_req.qpn;
|
pt_lockedQP = pt_req.qpn;
|
||||||
}
|
}
|
||||||
|
@ -215,6 +219,7 @@ void retrans_pointer_table( stream<pointerReq>& pointerReqFifo,
|
||||||
}
|
}
|
||||||
else if (pt_wait && !pt_isLocked)
|
else if (pt_wait && !pt_isLocked)
|
||||||
{
|
{
|
||||||
|
// prev lock cleared
|
||||||
pointerRspFifo.write(ptr_table[pt_req.qpn]);
|
pointerRspFifo.write(ptr_table[pt_req.qpn]);
|
||||||
pt_isLocked = true;
|
pt_isLocked = true;
|
||||||
pt_lockedQP = pt_req.qpn;
|
pt_lockedQP = pt_req.qpn;
|
||||||
|
@ -275,7 +280,7 @@ void process_retransmissions( stream<retransRelease>& rx2retrans_release_upd,
|
||||||
#pragma HLS PIPELINE II=1
|
#pragma HLS PIPELINE II=1
|
||||||
#pragma HLS INLINE off
|
#pragma HLS INLINE off
|
||||||
|
|
||||||
enum retransStateType {MAIN, INSERT_0, INSERT_1, RELEASE_0, RELEASE_1, RETRANS_0, RETRANS_1, RETRANS_2, TIMER_RETRANS_0, TIMER_RETRANS_1};
|
enum retransStateType {MAIN, INSERT_0, INSERT_1, RELEASE_0, RELEASE_1, RETRANS_0, RETRANS_1, RETRANS_2, TIMER_RETRANS_0};
|
||||||
static retransStateType rt_state = MAIN;
|
static retransStateType rt_state = MAIN;
|
||||||
static retransRelease release;
|
static retransRelease release;
|
||||||
static ap_uint<16> curr;
|
static ap_uint<16> curr;
|
||||||
|
@ -291,7 +296,7 @@ void process_retransmissions( stream<retransRelease>& rx2retrans_release_upd,
|
||||||
if (!rx2retrans_release_upd.empty())
|
if (!rx2retrans_release_upd.empty())
|
||||||
{
|
{
|
||||||
rx2retrans_release_upd.read(release);
|
rx2retrans_release_upd.read(release);
|
||||||
pointerReqFifo.write(pointerReq(release.qpn, true));
|
pointerReqFifo.write(pointerReq(release.qpn, true)); // enquire whether we have previous req for this qpn
|
||||||
rt_state = RELEASE_0;
|
rt_state = RELEASE_0;
|
||||||
std::cout << std::hex << "[PROCESS RETRANSMISSION " << INSTID << "]: releasing " << release.latest_acked_req << std::endl;
|
std::cout << std::hex << "[PROCESS RETRANSMISSION " << INSTID << "]: releasing " << release.latest_acked_req << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -299,15 +304,15 @@ void process_retransmissions( stream<retransRelease>& rx2retrans_release_upd,
|
||||||
{
|
{
|
||||||
rx2retrans_req.read(retrans);
|
rx2retrans_req.read(retrans);
|
||||||
std::cout << "[PROCESS RETRANSMISSION " << INSTID << "]: RX Retransmit triggered!!" << std::endl;
|
std::cout << "[PROCESS RETRANSMISSION " << INSTID << "]: RX Retransmit triggered!!" << std::endl;
|
||||||
pointerReqFifo.write(pointerReq(retrans.qpn));
|
pointerReqFifo.write(pointerReq(retrans.qpn)); // enquire whether we have previous req for this qpn
|
||||||
rt_state = RETRANS_0;
|
rt_state = RETRANS_0;
|
||||||
}
|
}
|
||||||
else if (!timer2retrans_req.empty())
|
else if (!timer2retrans_req.empty())
|
||||||
{
|
{
|
||||||
std::cout << "[PROCESS RETRANSMISSION " << INSTID << "]: TIMER Retransmit triggered!!\n";
|
std::cout << "[PROCESS RETRANSMISSION " << INSTID << "]: TIMER Retransmit triggered!!" << std::endl;
|
||||||
timer2retrans_req.read(retrans);
|
timer2retrans_req.read(retrans);
|
||||||
// Uses always head psn
|
// Uses always head psn
|
||||||
pointerReqFifo.write(pointerReq(retrans.qpn)); // enquire whether we have previous req for this qpn
|
pointerReqFifo.write(pointerReq(retrans.qpn)); // enquire whether we have previous req for this qpn
|
||||||
rt_state = TIMER_RETRANS_0;
|
rt_state = TIMER_RETRANS_0;
|
||||||
}
|
}
|
||||||
else if (!tx2retrans_insertRequest.empty() && !freeListFifo.empty())
|
else if (!tx2retrans_insertRequest.empty() && !freeListFifo.empty())
|
||||||
|
@ -325,7 +330,7 @@ void process_retransmissions( stream<retransRelease>& rx2retrans_release_upd,
|
||||||
pointerRspFifo.read(ptrMeta);
|
pointerRspFifo.read(ptrMeta);
|
||||||
if (!ptrMeta.valid)
|
if (!ptrMeta.valid)
|
||||||
{
|
{
|
||||||
// first request for this qpn, write into both `retrans pointer table`, `retrans meta table`
|
// First request for this qpn, write into both `Retrans Pointer Table`, `Retrans Meta Table`
|
||||||
ptrMeta.valid = true;
|
ptrMeta.valid = true;
|
||||||
ptrMeta.head = newMetaIdx;
|
ptrMeta.head = newMetaIdx;
|
||||||
ptrMeta.tail = newMetaIdx;
|
ptrMeta.tail = newMetaIdx;
|
||||||
|
@ -336,8 +341,9 @@ void process_retransmissions( stream<retransRelease>& rx2retrans_release_upd,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Append new pointer to the tail in `Retrans Meta Table`
|
// Update the existing "tail" entry in `Retrans Meta Table` with next=newMetaIdx
|
||||||
metaReqFifo.write(retransMetaReq(ptrMeta.tail, newMetaIdx));
|
metaReqFifo.write(retransMetaReq(ptrMeta.tail, newMetaIdx));
|
||||||
|
// Update the tail pointer to the next index in `Retrans Meta Table`
|
||||||
ptrMeta.tail = newMetaIdx;
|
ptrMeta.tail = newMetaIdx;
|
||||||
rt_state = INSERT_1;
|
rt_state = INSERT_1;
|
||||||
std::cout << "[PROCESS RETRANSMISSION " << INSTID << "]: appending entry at qpn " << insert.qpn << std::endl;
|
std::cout << "[PROCESS RETRANSMISSION " << INSTID << "]: appending entry at qpn " << insert.qpn << std::endl;
|
||||||
|
@ -357,14 +363,15 @@ void process_retransmissions( stream<retransRelease>& rx2retrans_release_upd,
|
||||||
pointerRspFifo.read(ptrMeta);
|
pointerRspFifo.read(ptrMeta);
|
||||||
if (ptrMeta.valid)
|
if (ptrMeta.valid)
|
||||||
{
|
{
|
||||||
// Enquire the first uncleared index in `Retrans Meta Table`
|
// Enquire the first uncleared index (head) in `Retrans Meta Table`
|
||||||
metaReqFifo.write(retransMetaReq(ptrMeta.head));
|
metaReqFifo.write(retransMetaReq(ptrMeta.head));
|
||||||
curr = ptrMeta.head;
|
curr = ptrMeta.head;
|
||||||
rt_state = RELEASE_1;
|
rt_state = RELEASE_1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "[PROCESS RETRANSMISSION " << INSTID << "]: state RELEASE_0 invalid meta entry\n";
|
// this should not happen
|
||||||
|
std::cout << "[PROCESS RETRANSMISSION " << INSTID << "]: state RELEASE_0 invalid meta entry" << std::endl;
|
||||||
// Release lock
|
// Release lock
|
||||||
pointerUpdFifo.write(pointerUpdate(release.qpn, ptrMeta));
|
pointerUpdFifo.write(pointerUpdate(release.qpn, ptrMeta));
|
||||||
rt_state = MAIN;
|
rt_state = MAIN;
|
||||||
|
@ -386,7 +393,7 @@ void process_retransmissions( stream<retransRelease>& rx2retrans_release_upd,
|
||||||
rt_state = MAIN;
|
rt_state = MAIN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// released up till RC ACK psn
|
// released until RC ACK psn
|
||||||
else if (meta.psn == release.latest_acked_req)
|
else if (meta.psn == release.latest_acked_req)
|
||||||
{
|
{
|
||||||
// the "next" index is now the head
|
// the "next" index is now the head
|
||||||
|
@ -424,7 +431,7 @@ void process_retransmissions( stream<retransRelease>& rx2retrans_release_upd,
|
||||||
rt_state = MAIN;
|
rt_state = MAIN;
|
||||||
if (ptrMeta.valid)
|
if (ptrMeta.valid)
|
||||||
{
|
{
|
||||||
// Get continuous stream of meta entries
|
// Enquire the first uncleared index (head) in `Retrans Meta Table`
|
||||||
metaReqFifo.write(retransMetaReq(ptrMeta.head));
|
metaReqFifo.write(retransMetaReq(ptrMeta.head));
|
||||||
curr = ptrMeta.head;
|
curr = ptrMeta.head;
|
||||||
rt_state = RETRANS_1;
|
rt_state = RETRANS_1;
|
||||||
|
@ -439,19 +446,23 @@ void process_retransmissions( stream<retransRelease>& rx2retrans_release_upd,
|
||||||
rt_state = MAIN;
|
rt_state = MAIN;
|
||||||
if (meta.valid)
|
if (meta.valid)
|
||||||
{
|
{
|
||||||
if (!meta.isTail)
|
if (meta.isTail)
|
||||||
{
|
{
|
||||||
metaReqFifo.write(retransMetaReq(meta.next));
|
// this should ideally not happen
|
||||||
|
// requested retransmission psn not stored
|
||||||
|
std::cout << "[PROCESS RETRANSMISSION " << INSTID << "]: state RETRANS_1 trying to retransmit psn that is ACKed" << std::endl;
|
||||||
|
rt_state = MAIN;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rt_state = MAIN;
|
// traversing the list
|
||||||
|
metaReqFifo.write(retransMetaReq(meta.next));
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we should start retransmitting
|
// check if we should start retransmitting
|
||||||
if (meta.psn == retrans.psn)
|
if (meta.psn == retrans.psn)
|
||||||
{
|
{
|
||||||
std::cout << std::hex << "[PROCESS RETRANSMISSION " << INSTID << "]: NAK, retransmitting psn: " << meta.psn << std::endl;
|
std::cout << std::hex << "[PROCESS RETRANSMISSION " << INSTID << "]: retransmitting psn " << meta.psn << std::endl;
|
||||||
retrans2event.write(retransEvent(meta.opCode, retrans.qpn, meta.localAddr, meta.remoteAddr, meta.length, meta.psn));
|
retrans2event.write(retransEvent(meta.opCode, retrans.qpn, meta.localAddr, meta.remoteAddr, meta.length, meta.psn));
|
||||||
if (!meta.isTail)
|
if (!meta.isTail)
|
||||||
{
|
{
|
||||||
|
@ -460,14 +471,14 @@ void process_retransmissions( stream<retransRelease>& rx2retrans_release_upd,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// keep searching
|
// keep traversing
|
||||||
rt_state = RETRANS_1;
|
rt_state = RETRANS_1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RETRANS_2:
|
case RETRANS_2:
|
||||||
//Retransmit everything until we reach tail
|
// Retransmit everything until reach tail
|
||||||
if (!metaRspFifo.empty())
|
if (!metaRspFifo.empty())
|
||||||
{
|
{
|
||||||
metaRspFifo.read(meta);
|
metaRspFifo.read(meta);
|
||||||
|
@ -480,7 +491,7 @@ void process_retransmissions( stream<retransRelease>& rx2retrans_release_upd,
|
||||||
metaReqFifo.write(retransMetaReq(meta.next));
|
metaReqFifo.write(retransMetaReq(meta.next));
|
||||||
rt_state = RETRANS_2;
|
rt_state = RETRANS_2;
|
||||||
}
|
}
|
||||||
std::cout << std::hex << "[PROCESS RETRANSMISSION " << INSTID << "]: NAK, retransmitting psn: " << meta.psn << std::endl;
|
std::cout << std::hex << "[PROCESS RETRANSMISSION " << INSTID << "]: retransmitting psn " << meta.psn << std::endl;
|
||||||
retrans2event.write(retransEvent(meta.opCode, retrans.qpn, meta.localAddr, meta.remoteAddr, meta.length, meta.psn));
|
retrans2event.write(retransEvent(meta.opCode, retrans.qpn, meta.localAddr, meta.remoteAddr, meta.length, meta.psn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,7 +505,7 @@ void process_retransmissions( stream<retransRelease>& rx2retrans_release_upd,
|
||||||
{
|
{
|
||||||
// Get continuous stream of meta entries
|
// Get continuous stream of meta entries
|
||||||
metaReqFifo.write(retransMetaReq(ptrMeta.head));
|
metaReqFifo.write(retransMetaReq(ptrMeta.head));
|
||||||
rt_state = TIMER_RETRANS_1;
|
rt_state = RETRANS_2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -502,25 +513,7 @@ void process_retransmissions( stream<retransRelease>& rx2retrans_release_upd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TIMER_RETRANS_1:
|
} // switch
|
||||||
if (!metaRspFifo.empty())
|
|
||||||
{
|
|
||||||
metaRspFifo.read(meta);
|
|
||||||
rt_state = MAIN;
|
|
||||||
if (meta.valid)
|
|
||||||
{
|
|
||||||
if (!meta.isTail)
|
|
||||||
{
|
|
||||||
// keep retransmitting
|
|
||||||
metaReqFifo.write(retransMetaReq(meta.next));
|
|
||||||
rt_state = TIMER_RETRANS_1;
|
|
||||||
}
|
|
||||||
std::cout << std::hex << "[PROCESS RETRANSMISSION " << INSTID << "]: timed out, retransmitting psn " << meta.psn << std::endl;
|
|
||||||
retrans2event.write(retransEvent(meta.opCode, retrans.qpn, meta.localAddr, meta.remoteAddr, meta.length, meta.psn));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}//switch
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int INSTID = 0>
|
template <int INSTID = 0>
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
## Process Retransmission
|
||||||
|
Main state machine
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
rx2retrans_release_upd (RELEASE) | [qpn, latest_acked_req]
|
||||||
|
rx2retrans_req (RETRANS) | [qpn, psn]
|
||||||
|
timter2retrans_req (RETRANS) | [qpn]
|
||||||
|
tx2retrans_insertRequest (INSERT) | [qpn, psn, opCode, localAddr, remote Addr, length]
|
||||||
|
|
||||||
|
## Retrans Pointer Table
|
||||||
|
Indexed by `qpn`, contains the pointer to the first (`head`) and last (`tail`) entry of the qpn in `Retrans Meta Table`
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
pointerReqFifo | [qpn, lock]
|
||||||
|
pointerUdpFifo | [qpn, entry]
|
||||||
|
pointerRspFifo | [entry]
|
||||||
|
entry | [head, tail, valid]
|
||||||
|
|
||||||
|
## Retrans Meta Table
|
||||||
|
Stores the actual request if retransmission is triggered. A linked list, indexed by entries in `Retrans Pointer Table` or the "previous" entry in the table. `next` is a pointer to the table, indicating the next request of the same qpn.
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
meta_upd_req | [idx, entry, write, append]
|
||||||
|
meta_rsp | [entry]
|
||||||
|
entry | [psn, next, opCode, localAddr, remoteAddr, length]
|
||||||
|
|
||||||
|
## Freelist Handler
|
||||||
|
A FIFO that stores all available index of `Retrans Meta Table`
|
||||||
|
|
||||||
|
# Transport Timer
|
Loading…
Reference in New Issue