sendgen的说明
This commit is contained in:
@@ -3,17 +3,17 @@
|
|||||||
## ShinTop 顶层模块
|
## ShinTop 顶层模块
|
||||||
|
|
||||||
### 例化模块
|
### 例化模块
|
||||||
* slaveParser 从站解析模块
|
* slaveParser 从站解析模块
|
||||||
* masterParser 主站解析模块
|
* masterParser 主站解析模块
|
||||||
|
|
||||||
* downCDRIn 下行CDR接收模块
|
* downCDRIn 下行CDR接收模块
|
||||||
* upCDRIn 上行CDR接收模块
|
* upCDRIn 上行CDR接收模块
|
||||||
* downCDROut 下行CDR发送模块
|
* downCDROut 下行CDR发送模块
|
||||||
* upCDROut 上行CDR发送模块
|
* upCDROut 上行CDR发送模块
|
||||||
|
|
||||||
* interface 寄存器逻辑控制模块
|
* interface 寄存器逻辑控制模块
|
||||||
|
|
||||||
* sram 分别为8个SM例化4个或2个2k SRAM用于sram FIFO
|
* sram 分别为8个SM例化4个或2个2k SRAM用于sram FIFO
|
||||||
|
|
||||||
```
|
```
|
||||||
val sram = Seq(
|
val sram = Seq(
|
||||||
@@ -34,20 +34,32 @@
|
|||||||
### 例化模块
|
### 例化模块
|
||||||
|
|
||||||
#### SlaveRecParser 接收解析器
|
#### SlaveRecParser 接收解析器
|
||||||
* downRecParser 下行接收解析器
|
* downRecParser 下行接收解析器
|
||||||
* upRecParser 上行接收解析器
|
* upRecParser 上行接收解析器
|
||||||
|
|
||||||
|
##### 输入输出
|
||||||
|
* rec 输入来自CDRIn模块的axis格式原始数据
|
||||||
|
* data 输出解析后的子报文负载
|
||||||
|
* stateCurr 用于辅助上级SlaveParser模块
|
||||||
|
* frameReq 输出解析的帧头给上级SlaveParser模块
|
||||||
|
* subMsgReq 输出解析的子报文头给上级SlaveParser模块
|
||||||
|
* resp 清模块的STATE_ERROR状态
|
||||||
|
* isError 输出模块的错误信息触发中断
|
||||||
|
|
||||||
##### 状态机
|
##### 状态机
|
||||||
* 0:STATE_IDLE 空闲
|
**(测试点:应该覆盖所有状态和跳转条件)**
|
||||||
* 1:STATE_HEADER 包头
|
* 0:STATE_IDLE 空闲
|
||||||
* 2:STATE_SUBMSG_HEADER 子报文头
|
* 1:STATE_HEADER 包头
|
||||||
* 3:STATE_PAYLOAD_DATA 子报文数据
|
* 2:STATE_SUBMSG_HEADER 子报文头
|
||||||
* 4:STATE_CRC CRC校验
|
* 3:STATE_PAYLOAD_DATA 子报文数据
|
||||||
* 5:STATE_ERROR 错误状态
|
* 4:STATE_CRC CRC校验
|
||||||
* 6:STATE_WAIT 等待状态
|
* 5:STATE_ERROR 错误状态
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##### 逻辑及行为
|
##### 逻辑及行为
|
||||||
* STATE_IDLE 在空闲态,等待接收CDR解析后的axis格式数据,当valid从低跳高,进入STATE_HEADER,否则一直保持在STATE_IDLE
|
* STATE_IDLE 在空闲态,等待接收CDR解析后的axis格式数据,当valid从低跳高,进入STATE_HEADER,否则一直保持在STATE_IDLE
|
||||||
* STATE_HEADER
|
* STATE_HEADER
|
||||||
- 等待axis的fire`io.rec.fire`,否则保持STATE_HEADER,无动作
|
- 等待axis的fire`io.rec.fire`,否则保持STATE_HEADER,无动作
|
||||||
- 检查tlast不应该出现`io.rec.bits.tlast`,否则进入STATE_ERROR **(测试点)**
|
- 检查tlast不应该出现`io.rec.bits.tlast`,否则进入STATE_ERROR **(测试点)**
|
||||||
- 检查长度计数到达4-1,否则保持STATE_HEADER
|
- 检查长度计数到达4-1,否则保持STATE_HEADER
|
||||||
@@ -58,7 +70,7 @@
|
|||||||
+ 其它则进入STATE_ERROR **(测试点:会不会影响xxSendGen的行为)**
|
+ 其它则进入STATE_ERROR **(测试点:会不会影响xxSendGen的行为)**
|
||||||
+ 使用`io.frameReq`通知上层模块SlaveParser接收包的到来
|
+ 使用`io.frameReq`通知上层模块SlaveParser接收包的到来
|
||||||
|
|
||||||
* STATE_SUBMSG_HEADER
|
* STATE_SUBMSG_HEADER
|
||||||
- 等待axis的fire`io.rec.fire`,否则保持STATE_SUBMSG_HEADER,无动作
|
- 等待axis的fire`io.rec.fire`,否则保持STATE_SUBMSG_HEADER,无动作
|
||||||
- 检查tlast不应该出现`io.rec.bits.tlast`,否则进入STATE_ERROR **(测试点)**
|
- 检查tlast不应该出现`io.rec.bits.tlast`,否则进入STATE_ERROR **(测试点)**
|
||||||
- 检查长度计数到达7-1,否则保持STATE_SUBMSG_HEADER
|
- 检查长度计数到达7-1,否则保持STATE_SUBMSG_HEADER
|
||||||
@@ -66,7 +78,7 @@
|
|||||||
- 长度计数到达7-1时,进入STATE_PAYLOAD_DATA
|
- 长度计数到达7-1时,进入STATE_PAYLOAD_DATA
|
||||||
+ 使用`io.subMsgReq`通知上层模块SlaveParser子报文的到来
|
+ 使用`io.subMsgReq`通知上层模块SlaveParser子报文的到来
|
||||||
|
|
||||||
* STATE_PAYLOAD_DATA
|
* STATE_PAYLOAD_DATA
|
||||||
- 等待axis的fire`io.rec.fire`,否则保持STATE_PAYLOAD_DATA,无动作
|
- 等待axis的fire`io.rec.fire`,否则保持STATE_PAYLOAD_DATA,无动作
|
||||||
- 检查tlast不应该出现`io.rec.bits.tlast`,否则进入STATE_ERROR **(测试点)**
|
- 检查tlast不应该出现`io.rec.bits.tlast`,否则进入STATE_ERROR **(测试点)**
|
||||||
- 检查io.data的数据流是否被外部fifo拒绝`isDataRejErr`,若fifo上溢出进入STATE_ERROR **(测试点)**
|
- 检查io.data的数据流是否被外部fifo拒绝`isDataRejErr`,若fifo上溢出进入STATE_ERROR **(测试点)**
|
||||||
@@ -75,17 +87,60 @@
|
|||||||
+ 已到达,进一步检查帧长度`frameLenCnt`是否达到总报文头说明长度-1 `frameHeader.frameLenAim - 1.U`
|
+ 已到达,进一步检查帧长度`frameLenCnt`是否达到总报文头说明长度-1 `frameHeader.frameLenAim - 1.U`
|
||||||
* 未到达,进入STATE_SUBMSG_HEADER处理下一个子报文
|
* 未到达,进入STATE_SUBMSG_HEADER处理下一个子报文
|
||||||
* 已到达,进入STATE_CRC做最后CRC校验
|
* 已到达,进入STATE_CRC做最后CRC校验
|
||||||
+ 将子报文负载数据通过io.data传输给上层SlaveParser存入down/up RecFifo 的pingpong缓冲区,准备用于发送转发
|
+ 将子报文负载数据通过io.data传输给上层SlaveParser存入down/up-RecFifo 的pingpong缓冲区的enq,准备用于发送转发
|
||||||
* STATE_CRC
|
* STATE_CRC
|
||||||
- 等待axis的fire`io.rec.fire`和`io.rec.bits.tlast`,否则保持STATE_CRC **(测试点:超长时间tlast不到来)**
|
- 等待axis的fire`io.rec.fire`和`io.rec.bits.tlast`,否则保持STATE_CRC **(测试点:超长时间tlast不到来)**
|
||||||
- 等待长度计数等于4-1时刻,同时检查`isCrcPass`,若检查通过,回到STATE_IDLE,否则到STATE_ERROR **(测试点:tlast在计数4-1之前到来;tlast在计数4-1之后到来)**
|
- 等待长度计数等于4-1时刻,同时检查`isCrcPass`,若检查通过,回到STATE_IDLE,否则到STATE_ERROR **(测试点:tlast在计数4-1之前到来;tlast在计数4-1之后到来)**
|
||||||
* STATE_ERROR
|
* STATE_ERROR
|
||||||
- 在该状态`io.isError`保持为高,持续触发interface中的 下行/上行 接收错误中断
|
- 在该状态`io.isError`保持为高,持续触发interface中的 下行/上行 接收错误中断
|
||||||
- 当interface写清对应中断时,通过`io.resp`让状态机回到STATE_IDLE
|
- 当interface写清对应中断时,通过`io.resp`让状态机回到STATE_IDLE
|
||||||
|
|
||||||
|
|
||||||
#### 发送生成器
|
#### 发送生成器
|
||||||
* downSendGen 下行发送生成器
|
* downSendGen 下行发送生成器
|
||||||
* upSendGen 上行发送生成器
|
* upSendGen 上行发送生成器
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### 输入输出
|
||||||
|
* data 连接上级模块SlaveParser down/up-RecFifo 的pingpong缓冲区的deq,准备用于发送转发
|
||||||
|
* frameReq 连接上级模块SlaveParser请求的帧头结构体
|
||||||
|
* subMsgReq 连接上级模块SlaveParser请求的子报文结构体
|
||||||
|
* send 输出axis格式的发送输出数据到CDRout模块
|
||||||
|
* stateCurr 输出内部状态机状态给上级模块SlaveParser辅助判断(无意义)
|
||||||
|
|
||||||
|
##### 状态机
|
||||||
|
**(测试点:应该覆盖所有状态和跳转条件)**
|
||||||
|
* 0.U: STATE_IDLE 空闲
|
||||||
|
* 1.U: STATE_FRAME_HEADER 发送帧头
|
||||||
|
* 2.U: STATE_SUBMSG_HEADER 发送子报文头
|
||||||
|
* 3.U: STATE_SUBMSG_DATA 发送子报文负载
|
||||||
|
* 4.U: STATE_CRC 发送CRC校验
|
||||||
|
* 5.U: STATE_WAIT 等待
|
||||||
|
|
||||||
|
##### 逻辑及行为
|
||||||
|
* STATE_IDLE
|
||||||
|
- 等待帧头请求和确认`io.frameReq.fire`的到来,进入STATE_FRAME_HEADER状态,否则保持STATE_IDLE等待
|
||||||
|
* STATE_FRAME_HEADER
|
||||||
|
- 等待axis的fire`io.send.fire`,否则保持STATE_FRAME_HEADER,无动作
|
||||||
|
- 等待发送计数到达4-1(帧头发送完成)
|
||||||
|
+ 如果为常规包`frameInfo.frameStyle === FRAME_STYLE_COMMON`,
|
||||||
|
* 子报文头请求已经到来,进入STATE_SUBMSG_HEADER发送子报文头
|
||||||
|
* 子报文头请求没有到来,进入STATE_WAIT等待子报文头 **(测试点:确认等待期间,CDRout数据不会下溢)**
|
||||||
|
+ 如果不为常规包(一般为嗅探包),进入STATE_CRC **(测试点: 如果既不是常规包,又不是嗅探包是否会出错)**
|
||||||
|
* STATE_SUBMSG_HEADER
|
||||||
|
- 等待axis的fire`io.send.fire`,否则保持STATE_SUBMSG_HEADER,无动作
|
||||||
|
- 等待发送计数到达8-1(子报文头发送完成),进入STATE_SUBMSG_DATA
|
||||||
|
* STATE_SUBMSG_DATA
|
||||||
|
- 等待axis的fire`io.send.fire`,否则保持STATE_SUBMSG_DATA,无动作
|
||||||
|
- 等待发送计数到达`subMsgInfoSel.length-1.U`(子报文负载发送完成)
|
||||||
|
+ 若同时总负载长度计数`frameLenCnt`到达帧头请求长度`frameInfo.frameLenAim -1.U`,进入CRC
|
||||||
|
+ 若还有子报文
|
||||||
|
* 子报文头请求已经到来,进入STATE_SUBMSG_HEADER发送子报文头
|
||||||
|
* 子报文头请求没有到来,进入STATE_WAIT等待子报文头 **(测试点:确认等待期间,CDRout数据不会下溢)**
|
||||||
|
* STATE_CRC
|
||||||
|
- 等待axis的fire`io.send.fire`,否则保持STATE_CRC,无动作
|
||||||
|
- 当计数到达4-1,进入STATE_IDLE,否则保持STATE_CRC
|
||||||
|
* STATE_WAIT
|
||||||
|
- 当子报文头请求到来`io.subMsgReq.valid`,返回STATE_SUBMSG_HEADER继续处理,否则在STATE_WAIT **(测试点:是否会产生长时间等待情形而导致流水线溢出)**
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,20 @@ import chisel3._
|
|||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param rec 输入来自CDRIn模块的axis格式原始数据
|
||||||
|
* @param data 输出解析后的子报文负载
|
||||||
|
* @param stateCurr 用于辅助上级SlaveParser模块
|
||||||
|
* @param frameReq 输出解析的帧头给上级SlaveParser模块
|
||||||
|
* @param subMsgReq 输出解析的子报文头给上级SlaveParser模块
|
||||||
|
* @param resp 清模块的STATE_ERROR状态
|
||||||
|
* @param isError 输出模块的错误信息触发中断
|
||||||
|
*/
|
||||||
class SlaveRecParserIO extends Bundle{
|
class SlaveRecParserIO extends Bundle{
|
||||||
val rec = Flipped( Decoupled(new AXIS_Bundle(8)) )
|
val rec = Flipped( Decoupled(new AXIS_Bundle(8)) )
|
||||||
|
|
||||||
val data = Decoupled(UInt(8.W))
|
val data = Decoupled(UInt(8.W))
|
||||||
|
|
||||||
val stateNext = Output(UInt(4.W))
|
|
||||||
val stateCurr = Output(UInt(4.W))
|
val stateCurr = Output(UInt(4.W))
|
||||||
|
|
||||||
val frameReq = Valid( new FrameHeader )
|
val frameReq = Valid( new FrameHeader )
|
||||||
@@ -34,7 +42,7 @@ class SlaveRecParser extends Module{
|
|||||||
val STATE_ERROR = 5.U //
|
val STATE_ERROR = 5.U //
|
||||||
|
|
||||||
|
|
||||||
val stateNext = Wire(UInt(4.W)); io.stateNext := stateNext
|
val stateNext = Wire(UInt(4.W))
|
||||||
val stateCurr = RegNext(stateNext, STATE_IDLE); io.stateCurr := stateCurr
|
val stateCurr = RegNext(stateNext, STATE_IDLE); io.stateCurr := stateCurr
|
||||||
|
|
||||||
io.isError := stateCurr === STATE_ERROR
|
io.isError := stateCurr === STATE_ERROR
|
||||||
|
|||||||
@@ -8,18 +8,21 @@ class SubMsgTxInfo extends SubMsgHeader{
|
|||||||
val source = UInt(2.W)
|
val source = UInt(2.W)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param data 连接上级模块SlaveParser down/up-RecFifo 的pingpong缓冲区的deq,准备用于发送转发
|
||||||
|
* @param frameReq 连接上级模块SlaveParser请求的帧头结构体
|
||||||
|
* @param subMsgReq 连接上级模块SlaveParser请求的子报文结构体
|
||||||
|
* @param send 输出axis格式的发送输出数据到CDRout模块
|
||||||
|
* @param stateCurr 输出内部状态机状态给上级模块SlaveParser辅助判断(无意义)
|
||||||
|
*/
|
||||||
class SlaveSendGenIO extends Bundle{
|
class SlaveSendGenIO extends Bundle{
|
||||||
val data = Vec(2, Flipped( Decoupled(UInt(8.W)) ) )
|
val data = Vec(2, Flipped( Decoupled(UInt(8.W)) ) )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val frameReq = Flipped(Decoupled( new FrameHeader ))
|
val frameReq = Flipped(Decoupled( new FrameHeader ))
|
||||||
val subMsgReq = Flipped(Decoupled( new SubMsgTxInfo ))
|
val subMsgReq = Flipped(Decoupled( new SubMsgTxInfo ))
|
||||||
|
|
||||||
val send = Decoupled(new AXIS_Bundle(8))
|
val send = Decoupled(new AXIS_Bundle(8))
|
||||||
|
|
||||||
val isError = Output(Bool())
|
|
||||||
val stateCurr = Output(UInt(3.W))
|
val stateCurr = Output(UInt(3.W))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,15 +43,12 @@ class SlaveSendGen extends Module{
|
|||||||
val STATE_SUBMSG_HEADER = 2.U
|
val STATE_SUBMSG_HEADER = 2.U
|
||||||
val STATE_SUBMSG_DATA = 3.U
|
val STATE_SUBMSG_DATA = 3.U
|
||||||
val STATE_CRC = 4.U //CRC校验
|
val STATE_CRC = 4.U //CRC校验
|
||||||
//val STATE_ERROR = 5.U
|
val STATE_WAIT = 5.U
|
||||||
val STATE_WAIT = 6.U
|
|
||||||
|
|
||||||
|
|
||||||
val stateNext = Wire(UInt(3.W))
|
val stateNext = Wire(UInt(3.W))
|
||||||
val stateCurr = RegNext(stateNext, STATE_IDLE); io.stateCurr := stateCurr
|
val stateCurr = RegNext(stateNext, STATE_IDLE); io.stateCurr := stateCurr
|
||||||
|
|
||||||
io.isError := false.B//stateCurr === STATE_ERROR
|
|
||||||
|
|
||||||
crc.io.isEnable := io.send.fire & (
|
crc.io.isEnable := io.send.fire & (
|
||||||
stateCurr === STATE_FRAME_HEADER |
|
stateCurr === STATE_FRAME_HEADER |
|
||||||
stateCurr === STATE_SUBMSG_HEADER |
|
stateCurr === STATE_SUBMSG_HEADER |
|
||||||
@@ -128,7 +128,6 @@ class SlaveSendGen extends Module{
|
|||||||
STATE_SUBMSG_DATA
|
STATE_SUBMSG_DATA
|
||||||
), STATE_SUBMSG_DATA ),
|
), STATE_SUBMSG_DATA ),
|
||||||
(stateCurr === STATE_CRC) -> Mux( io.send.fire, Mux( lengthCnt === (4-1).U, STATE_IDLE, STATE_CRC ), STATE_CRC),
|
(stateCurr === STATE_CRC) -> Mux( io.send.fire, Mux( lengthCnt === (4-1).U, STATE_IDLE, STATE_CRC ), STATE_CRC),
|
||||||
// (stateCurr === STATE_ERROR) -> Mux( io.send.fire, STATE_IDLE, STATE_ERROR),
|
|
||||||
(stateCurr === STATE_WAIT) -> Mux( io.subMsgReq.valid, STATE_SUBMSG_HEADER, STATE_WAIT),
|
(stateCurr === STATE_WAIT) -> Mux( io.subMsgReq.valid, STATE_SUBMSG_HEADER, STATE_WAIT),
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user