增加控制码3个必选,3个可选
This commit is contained in:
19
doc/spec/SPI.md
Normal file
19
doc/spec/SPI.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# SPI特性
|
||||||
|
|
||||||
|
|
||||||
|
## 同步采样SPI/QSPI
|
||||||
|
|
||||||
|
同步采样SPI通过使用系统驱动的时钟,将输入的spi/QSPI信号全部当作异步数据信号,通过观测CSN,以及其余信号和SCK的关系,采样SPI/QSPI的输入,并给出输出
|
||||||
|
|
||||||
|
使用这种方法允许的QSPI传输速度会受到限制,使用慢模式时,允许的SCK速率为无穷小到1/2主时钟频率,当使用快模式时,允许的SCK速度为1/2主时钟频率到1倍主时钟频率
|
||||||
|
|
||||||
|
|
||||||
|
## 异步采样SPI/QSPI
|
||||||
|
|
||||||
|
异步采样设计的SPI/QSPI端直接使用SCK作为敏感源,因此允许更高的传输速度,但是SPI数据测和主时钟域需要精确地进行跨时钟域处理
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
113
doc/spec/SlaveParser.md
Normal file
113
doc/spec/SlaveParser.md
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# SlaveParser
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
以下为用户区域
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* 该模块例化在`MstSlvSwith`模块内,负责从站接收功能实现
|
||||||
|
* 内部例化了两个`SlaveRecParser`(`downRecParser`和`upRecParser`)和两个`SlaveSendGen`(`downSendGen`和`upSendGen`)
|
||||||
|
|
||||||
|
|
||||||
|
## 接口
|
||||||
|
|
||||||
|
* `downIn`以`Decoupled`封装的axis格式的lvds下行串行数据输入
|
||||||
|
* `downOut`以`Decoupled`封装的axis格式的lvds下行串行数据输出
|
||||||
|
* `upIn`以`Decoupled`封装的axis格式的lvds上行串行数据输入
|
||||||
|
* `upOut`以`Decoupled`封装的axis格式的lvds上行串行数据输出
|
||||||
|
* `sram_w`接入到4个`SmUnit`的SRAM写接口
|
||||||
|
* `sram_r`接入到4个`SmUnit`的SRAM读接口
|
||||||
|
* `dSMenq`接入到4个`SmUnit`的下行写入压栈Bool信号
|
||||||
|
* `uSMdeq`接入到4个`SmUnit`的上行读出弹出Bool信号
|
||||||
|
* `localDevIndex`输出本地设备的索引16bits
|
||||||
|
* `isDevOnRight`表示设备的“右边”(下行方向下一级)是否还有设备2bits,实际只使用了1bits
|
||||||
|
* `isDevOnRightModify`表示设备的“右边”(下行方向下一级)是否改变过
|
||||||
|
* `indexOfRightDev`表示设备的“右边”(下行方向下一级)设备的索引号
|
||||||
|
* `mstDeltaTimeStamp`输出32bits的时间戳信息
|
||||||
|
* `slvDeltaTime`输出32bits的时间戳信息
|
||||||
|
* `deltaFinal`输出64bits的时间戳信息
|
||||||
|
* `isLoop`是否回环Bool
|
||||||
|
* `cReg`以结构体输入通用寄存器组
|
||||||
|
* `sReg`以结构体输入从站寄存器组
|
||||||
|
* `lvds`一个类似sram的访问接口,用于允许从lvds总线的访问读写寄存器区域
|
||||||
|
* `intHWTrig`输出两个Bool硬件中断信号
|
||||||
|
* `intHWClr`输入两个Bool硬件清除中断信号
|
||||||
|
* `downRecStat`输出下行接收方向信息
|
||||||
|
* `upRecStat`输出上行接收方向信息
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------------------------
|
||||||
|
|
||||||
|
## 主报文转发处理
|
||||||
|
|
||||||
|
* 下行发送模块`downSendGen`的帧头请求`frameReq`来自于下行接收`downRecParser`的报文头同步握手,同时`frameInfo`会被更改为本地设备的索引号`lcalDevIndex`
|
||||||
|
|
||||||
|
* 上行发送模块`upSendGen`的帧头请求`frameReq`
|
||||||
|
- 上行接收`upRecParser`的报文头同步握手,此时`frameStyle`需要为普通包`FRAME_STYLE_COMMON`,转发完全相同的上行接收报文头
|
||||||
|
- 下行接收到的是嗅探包而进入`isAckProbe`状态,发送(回复)嗅探包,`frameLenAim`为0,`frameStyle`为`FRAME_STYLE_PROBE`,`frameInfo`为`localDevIndex`
|
||||||
|
|
||||||
|
## 子报文处理
|
||||||
|
|
||||||
|
* 子报文接收在上、下行各有2个位宽8bits,深度20的FIFO`downRecFifo`/`upRecFifo`,以乒乓方式工作,子报文负载信息先进入`RecFifo`,再由发送模块`SendGen`发送
|
||||||
|
* 子报文接收在上、下行各有2组寄存器分别保存子报文头,子报文尾信息,以乒乓方式工作,发送模块发送时从寄存器中提取和修改信息
|
||||||
|
|
||||||
|
|
||||||
|
## 索引特质
|
||||||
|
|
||||||
|
* 当子报文的`operator`为`SUBMSG_OPERATOR_INDEX`,为索引模式,从站按顺序更新自己的索引
|
||||||
|
* 更新索引时
|
||||||
|
- 本设备索引`localDevIndex`更新为子报文尾工作计数`workCnt`加1
|
||||||
|
- 下行转发的`workCnt`计数也加1,即`localDevIndex`
|
||||||
|
- 右边(下行方向)设备索引`indexOfRightDev`
|
||||||
|
+ 当是最后一个设备,记录为0
|
||||||
|
+ 不是最后一个设备,更新为子报文尾工作计数`workCnt`计数加2
|
||||||
|
|
||||||
|
|
||||||
|
## 读写特质
|
||||||
|
|
||||||
|
|
||||||
|
* 写操作发生在下行阶段
|
||||||
|
* 读操作发生在上行阶段
|
||||||
|
* 单独读(和/或)写操作是否执行需要根据子报文头的报文类型`style`进行判定
|
||||||
|
- 当为顺序索引`SeqIndex`,只需要子报文头的设备索引`devIndex`匹配上本设备的索引`localDevIndex`,则需要进行操作
|
||||||
|
- 当为逻辑索引`LgcIndex`, 则需要进一步根据EBMMU的配置进行判定
|
||||||
|
* 广播读(和/或)写操作则均会被执行
|
||||||
|
* 如果从站对该子报文进行了操作,则转发到下一级从站时,子报文的工作计数`workCnt`需要加1
|
||||||
|
* lvds的写操作根据地址可以访问
|
||||||
|
- 寄存器
|
||||||
|
- SMUnit0
|
||||||
|
- SMUnit2
|
||||||
|
- SMUnit4
|
||||||
|
- SMUnit6
|
||||||
|
* lvds的写操作根据地址可以访问
|
||||||
|
- 寄存器
|
||||||
|
- SMUnit1
|
||||||
|
- SMUnit3
|
||||||
|
- SMUnit5
|
||||||
|
- SMUnit7
|
||||||
|
* 当lvds的读、写操作到特定地址时,触发SMUnit对应的写压入或者读弹出操作
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### ebmmu
|
||||||
|
|
||||||
|
|
||||||
|
## 同步特质
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 嗅探特质
|
||||||
|
|
||||||
|
##
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
以下是大模型补充区域
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
147
doc/spec/SlaveRecParser.md
Normal file
147
doc/spec/SlaveRecParser.md
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
# SlaveRecParser
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
以下为用户区域
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* 从站接收解析器使用状态机,将输入的数据流解析,获取到帧头,子报文头,负载数据,子报文尾,CRC校验等部分
|
||||||
|
* `SlaveRecParser`在`SlaveParser`模块中例化2个,分别解析上行和下行方向接收到的数据
|
||||||
|
|
||||||
|
## 接口
|
||||||
|
|
||||||
|
* `rec`数据流输入接口,以axis协议传输
|
||||||
|
* `data`以`decoupledIO`握手协议下的8bits数据传输,将负载数据传输到下一级逻辑
|
||||||
|
* `stateNext` 组合逻辑输出下一拍状态机状态输出
|
||||||
|
* `stateCurr` 当前状态机状态寄存器输出
|
||||||
|
* `frameReq`以``validIO`握手协议输出帧头的信息,完整帧头信息以结构体打包
|
||||||
|
* `subMsgHeadReq`以``validIO`握手协议输出子报文头的信息,完整子报文头信息以结构体打包
|
||||||
|
* `subMsgTailReq`以``validIO`握手协议输出子报文尾的信息,完整子报文尾信息以结构体打包
|
||||||
|
* `isError` 输出Bool下的错误状态,当状态机进入错误状态,则为真
|
||||||
|
* `stat`输出传输状态
|
||||||
|
- `isHeaderError `帧头错误
|
||||||
|
- `isSubHeaderError`子报文头错误
|
||||||
|
- `isPayloadError `负载错误
|
||||||
|
- `isSubTailError `子报文尾错误
|
||||||
|
- `isCRCError `CRC错误
|
||||||
|
- `isFinish `传输正确完成
|
||||||
|
- `isRecByteAck `接收到一个字节
|
||||||
|
* `flush`软件复位
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
## 状态机
|
||||||
|
状态机有如下状态
|
||||||
|
* `STATE_IDLE`空闲
|
||||||
|
* `STATE_HEADER`解析帧头
|
||||||
|
* `STATE_SUBMSG_HEADER`解析子报文头
|
||||||
|
* `STATE_PAYLOAD_DATA`解析负载
|
||||||
|
* `STATE_SUBMSG_TAIL`解析子报文尾
|
||||||
|
* `STATE_CRC`CRC校验
|
||||||
|
* `STATE_ERROR`传输错误
|
||||||
|
|
||||||
|
* 上电复位或者软件复位后,状态机应该处在空闲状态
|
||||||
|
* 在`STATE_IDLE`
|
||||||
|
- 当输入的`rec`的`valid`从0跳1,则进入`STATE_HEADER`
|
||||||
|
- 其余状况保持
|
||||||
|
* 在`STATE_HEADER`
|
||||||
|
- 当`rec`fire时,`tlast`为1(传输结束),进入`STATE_ERROR`状态
|
||||||
|
- 当`rec`fire,`tlast`为0,接收帧头长度到达3(4byte),判断解析的帧类型
|
||||||
|
+ 如果为常规包`FRAME_STYLE_COMMON`,进入解析子报文头`STATE_SUBMSG_HEADER`,此时为***时刻1***
|
||||||
|
+ 如果为探测包`FRAME_STYLE_PROBE`,进入CRC校验`STATE_CRC`,此时为***时刻1***
|
||||||
|
+ 以上均不是则是错误,进入`STATE_ERROR`
|
||||||
|
- 其余状况保持
|
||||||
|
* 在`STATE_SUBMSG_HEADER`
|
||||||
|
- 当`rec`fire时,`tlast`为1(传输结束),进入`STATE_ERROR`状态
|
||||||
|
- 当`rec`fire,`tlast`为0,接收子报文头长度到达5(6byte),进入解析负载`STATE_PAYLOAD_DATA`,此时为***时刻2***
|
||||||
|
- 其余状况保持
|
||||||
|
* 在`STATE_PAYLOAD_DATA`
|
||||||
|
- 当`rec`fire时,`tlast`为1(传输结束)或者`data`端口上溢出`isDataRejErr`(valid为1而ready为0),进入`STATE_ERROR`状态
|
||||||
|
- 当`rec`fire,`tlast`为0,接收子报文长度到达子报文头信息标示的长度-1,进入子报文尾解析`STATE_SUBMSG_TAIL`
|
||||||
|
- 其余状况保持
|
||||||
|
* 在`STATE_SUBMSG_TAIL`
|
||||||
|
- 当`rec`fire时,`tlast`为1(传输结束),进入`STATE_ERROR`状态
|
||||||
|
- 当`rec`fire,`tlast`为0,接收子报文尾长度到达1(2byte)
|
||||||
|
+ 若已接受帧长度到达帧头标示的长度-1,进入`STATE_CRC`,此时为***时刻3***
|
||||||
|
+ 若未达到,进入`STATE_SUBMSG_HEADER`接收下一个子报文,此时为***时刻3***
|
||||||
|
- 其余状况保持
|
||||||
|
* 在`STATE_CRC`
|
||||||
|
- 当`rec`fire时,`tlast`为1(传输结束),
|
||||||
|
+ 传输长度达到3(4byte)且CRC校验通过,返回`STATE_IDLE`,解析正确完成
|
||||||
|
+ 否则,进入`STATE_ERROR`,长度不一致或者CRC校验失败
|
||||||
|
- 其余状况保持
|
||||||
|
* 在`STATE_ERROR`
|
||||||
|
- 保持`STATE_ERROR`,只能通过软复位或者全局复位清除错误
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
## 帧结构
|
||||||
|
|
||||||
|
* 帧头4byte
|
||||||
|
- frameLenAim(12bits)帧长度目标
|
||||||
|
- Null(2bits) 留空
|
||||||
|
- frameStyle (2bits) 包类型
|
||||||
|
+ `FRAME_STYLE_COMMON` 普通包 0
|
||||||
|
+ `FRAME_STYLE_PROBE` 嗅探包 1
|
||||||
|
- frameInfo (16bits)其它信息
|
||||||
|
|
||||||
|
* 子报文头 6byte
|
||||||
|
- devIndex (14bits) 子报文中设备索引
|
||||||
|
- style (2bits) 子报文类型
|
||||||
|
+ SeqIndex 0 顺序索引
|
||||||
|
+ LgcIndex 2 逻辑索引
|
||||||
|
- address (16bits) 子报文地址
|
||||||
|
- operator (4bits) 子报文命令类型
|
||||||
|
+ `SUBMSG_OPERATOR_UNIREAD ` 单独读 0
|
||||||
|
+ `SUBMSG_OPERATOR_UNIWRITE ` 单独写 1
|
||||||
|
+ `SUBMSG_OPERATOR_UNIRDWR ` 单独读写 2
|
||||||
|
+ `SUBMSG_OPERATOR_SYNCA ` 时间同步操作A 0xa
|
||||||
|
+ `SUBMSG_OPERATOR_INDEX ` 索引 0xb
|
||||||
|
+ `SUBMSG_OPERATOR_SYNCC ` 时间同步操作C 0xc
|
||||||
|
+ `SUBMSG_OPERATOR_BOARDREAD ` 广播读 0xd
|
||||||
|
+ `SUBMSG_OPERATOR_BOARDWRITE` 广播写 0xe
|
||||||
|
+ `SUBMSG_OPERATOR_BOARDRDWR ` 广播读写 0xf
|
||||||
|
- length (12bits) 子报文负载长度
|
||||||
|
|
||||||
|
* 子报文尾 2byte
|
||||||
|
- 包含`workCnt`工作计数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
## 信息交换
|
||||||
|
|
||||||
|
* 在***时刻1***,`frameReq`的`valid`为高,将帧头信息使用结构体传输到`SlaveParser`模块
|
||||||
|
* 在***时刻2***,`subMsgHeadReq`的`valid`为高,将子报文头信息使用结构体传输到`SlaveParser`模块
|
||||||
|
* 在***时刻3***,`subMsgTailReq`的`valid`为高,将子报文尾信息使用结构体传输到`SlaveParser`模块
|
||||||
|
* 在`STATE_PAYLOAD_DATA`状态,`data`的`valid`始终为高,将负载数据传输到`SlaveParser`模块
|
||||||
|
- `SlaveParser`模块需要保证`data`的`ready`在`valid`为高是也为高,否则触发上溢出`isDataRejErr`
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
## CRC
|
||||||
|
|
||||||
|
* `SlaveRecParser`内部例化一个CRC32的8比特输入模块
|
||||||
|
* 当`rec`fire时,且状态机处于`STATE_HEADER` `STATE_SUBMSG_HEADER` `STATE_PAYLOAD_DATA` `STATE_SUBMSG_TAIL`时,将数据输入模块进行计算
|
||||||
|
* 当状态机处于`STATE_IDLE`时,或者软件复位时,清空CRC模块状态
|
||||||
|
* 当接收的最后4byte和CRC模块计算值匹配时,CRC通过
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
以下是大模型补充区域
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
52
doc/spec/SmUnit.md
Normal file
52
doc/spec/SmUnit.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# SMUnit
|
||||||
|
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
以下是用户区域
|
||||||
|
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
SMUnit本质是一个SRAM队列(FIFO)的维护模块
|
||||||
|
|
||||||
|
## 接口
|
||||||
|
对外接口包括:
|
||||||
|
* sram对外写接口
|
||||||
|
* sram对外读接口
|
||||||
|
* enq 输入Bool 压栈
|
||||||
|
* deq 输入Bool 弹出
|
||||||
|
* SRAM对内接口(接入实际例化的多个SRAM)
|
||||||
|
* cnt 输出当前fifo内有多少个数据
|
||||||
|
* flush 输入软件复位整个SMUnit
|
||||||
|
* isComf 输入Bool,确认正式写入
|
||||||
|
* isAbrt 输入Bool,放弃写入
|
||||||
|
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
## 指针
|
||||||
|
* FIFO内部除了常见的读指针`rPtr`和写指针`wPtr`,额外增加了一个提交指针`cPtr`
|
||||||
|
* 提交指针是为了在系统错误写入时进行撤销而设计的,当eb01从站接收数据过程中,有可能收到了部分数据进而写入fifo并进行压栈,但是本次传输并没有完全完成,例如后续数据错误,crc校验失败。这时,我们需要回滚fifo的状态抛弃掉之前写入的数据
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
* 三个指针的位宽比fifo实际需要位宽多1bits用于指示空满`log2Ceil(depth)+1`
|
||||||
|
* 当读指针`rPtr`和提交指针`cPtr`相等时fifo为空
|
||||||
|
* 当读指针`rPtr`和写指针`wPtr`最高位不同,其余比特相同,fifo为满
|
||||||
|
* 复位或者使用`flush`软复位时,所有指针归零
|
||||||
|
* 当`enq`时且fifo不为满,写指针加1
|
||||||
|
* 当`isAbrt`了,写指针`wPtr`回退到提交指针`cPtr`的位置
|
||||||
|
* **对于写指针`wPtr`,当`enq`和`isAbrt`同时到来,`enq`的优先级更高,对整个大系统工作功能会不会产生问题需要测,或者系统正常运行时不会发生这种情况**
|
||||||
|
* 当`deq`且fifo不为空,读指针加1
|
||||||
|
* 当`isComf`时提交指针`cPtr`前进到写指针`wPtr`的位置
|
||||||
|
* 根据写指针`wPtr`的有效比特位的值,sram对外写接口连接到内部实际例化特定SRAM的写接口,其余未指向的接口保持为0不活动或者悬空
|
||||||
|
* 根据读指针`rPtr`的有效比特位的值,sram对外读接口连接到内部实际例化特定SRAM的读接口,其余未指向的接口保持为0不活动或者悬空
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
以下是大模型补充区域
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
|
||||||
44
doc/spec/物理层优化.md
Normal file
44
doc/spec/物理层优化.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# 物理层优化
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
以下为用户区域
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
## 8b10b模块
|
||||||
|
|
||||||
|
* 停用4b5b特性
|
||||||
|
- 删除选择寄存器器 h4c寄存器不再有效
|
||||||
|
* 增加部分控制码
|
||||||
|
- 所有控制码都有极性
|
||||||
|
- 控制码有对应原始码
|
||||||
|
- 额外增加一条控制线
|
||||||
|
- 控制线由发送状态机控制
|
||||||
|
- 解码不需要极性控制
|
||||||
|
|
||||||
|
* 增加6个控制码
|
||||||
|
- 同时将`in(4,0)b11100".U`在`isCtrl`时映射为 `"b001111".U(6.W), "b110000".U(6.W)`
|
||||||
|
- 3个必选 `in(7,5)`保持不变
|
||||||
|
val isK28_0 = Output(Bool()) //0x1c
|
||||||
|
val isK28_3 = Output(Bool()) //0x7c
|
||||||
|
val isK28_4 = Output(Bool()) //0x9c
|
||||||
|
- 3个备选使用宏定义控制 `in(7,5)`平衡但需要增加翻转
|
||||||
|
* val isK28_1 = Output(Bool()) //0x3c IS_ENABLE_K28_1
|
||||||
|
* val isK28_2 = Output(Bool()) //0x5c IS_ENABLE_K28_2
|
||||||
|
* val isK28_6 = Output(Bool()) //0xdc IS_ENABLE_K28_6
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
以下是大模型补充区域
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -6,15 +6,31 @@ import chisel3.util._
|
|||||||
class Encode_Bundle extends Bundle{
|
class Encode_Bundle extends Bundle{
|
||||||
val dataIn = Input(UInt(8.W))
|
val dataIn = Input(UInt(8.W))
|
||||||
val isEnable = Input(Bool())
|
val isEnable = Input(Bool())
|
||||||
|
val isCtrl = Input(Bool())
|
||||||
val dataOut = Output(UInt(10.W))
|
val dataOut = Output(UInt(10.W))
|
||||||
}
|
}
|
||||||
|
|
||||||
class Decode_Bundle extends Bundle{
|
class Decode_Bundle extends Bundle{
|
||||||
val dataIn = Input(UInt(10.W))
|
val dataIn = Input(UInt(10.W))
|
||||||
val dataOut = Output(UInt(8.W))
|
val dataOut = Output(UInt(8.W))
|
||||||
|
|
||||||
|
val isK28_0 = Output(Bool()) //0x1c
|
||||||
|
val isK28_1 = Output(Bool()) //0x3c
|
||||||
|
val isK28_2 = Output(Bool()) //0x5c
|
||||||
|
val isK28_3 = Output(Bool()) //0x7c
|
||||||
|
val isK28_4 = Output(Bool()) //0x9c
|
||||||
|
val isK28_6 = Output(Bool()) //0xdc
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class b8b10Encode extends Module with RequireAsyncReset{
|
trait b8b10Config{ this: RawModule =>
|
||||||
|
val IS_ENABLE_K28_1 = false
|
||||||
|
val IS_ENABLE_K28_2 = false
|
||||||
|
val IS_ENABLE_K28_6 = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class b8b10Encode extends Module with RequireAsyncReset with b8b10Config{
|
||||||
val io = IO(new Encode_Bundle)
|
val io = IO(new Encode_Bundle)
|
||||||
|
|
||||||
val rdTest = IO(Output(Bool())) //测试使用
|
val rdTest = IO(Output(Bool())) //测试使用
|
||||||
@@ -51,7 +67,8 @@ class b8b10Encode extends Module with RequireAsyncReset{
|
|||||||
(io.dataIn(4,0) === "b11001".U) -> "b100110".U(6.W),
|
(io.dataIn(4,0) === "b11001".U) -> "b100110".U(6.W),
|
||||||
(io.dataIn(4,0) === "b11010".U) -> "b010110".U(6.W),
|
(io.dataIn(4,0) === "b11010".U) -> "b010110".U(6.W),
|
||||||
(io.dataIn(4,0) === "b11011".U) -> Mux( ~rd, "b110110".U(6.W), "b001001".U(6.W) ),
|
(io.dataIn(4,0) === "b11011".U) -> Mux( ~rd, "b110110".U(6.W), "b001001".U(6.W) ),
|
||||||
(io.dataIn(4,0) === "b11100".U) -> "b001110".U(6.W),
|
(io.dataIn(4,0) === "b11100".U & ~io.isCtrl) -> "b001110".U(6.W),
|
||||||
|
(io.dataIn(4,0) === "b11100".U & io.isCtrl) -> Mux( ~rd, "b001111".U(6.W), "b110000".U(6.W) ),
|
||||||
(io.dataIn(4,0) === "b11101".U) -> Mux( ~rd, "b101110".U(6.W), "b010001".U(6.W) ),
|
(io.dataIn(4,0) === "b11101".U) -> Mux( ~rd, "b101110".U(6.W), "b010001".U(6.W) ),
|
||||||
(io.dataIn(4,0) === "b11110".U) -> Mux( ~rd, "b011110".U(6.W), "b100001".U(6.W) ),
|
(io.dataIn(4,0) === "b11110".U) -> Mux( ~rd, "b011110".U(6.W), "b100001".U(6.W) ),
|
||||||
(io.dataIn(4,0) === "b11111".U) -> Mux( ~rd, "b101011".U(6.W), "b010100".U(6.W) )
|
(io.dataIn(4,0) === "b11111".U) -> Mux( ~rd, "b101011".U(6.W), "b010100".U(6.W) )
|
||||||
@@ -87,20 +104,35 @@ class b8b10Encode extends Module with RequireAsyncReset{
|
|||||||
(io.dataIn(4,0) === "b11001".U) -> rd,
|
(io.dataIn(4,0) === "b11001".U) -> rd,
|
||||||
(io.dataIn(4,0) === "b11010".U) -> rd,
|
(io.dataIn(4,0) === "b11010".U) -> rd,
|
||||||
(io.dataIn(4,0) === "b11011".U) -> ~rd,
|
(io.dataIn(4,0) === "b11011".U) -> ~rd,
|
||||||
(io.dataIn(4,0) === "b11100".U) -> rd,
|
(io.dataIn(4,0) === "b11100".U & ~io.isCtrl) -> rd,
|
||||||
|
(io.dataIn(4,0) === "b11100".U & io.isCtrl) -> ~rd,
|
||||||
(io.dataIn(4,0) === "b11101".U) -> ~rd,
|
(io.dataIn(4,0) === "b11101".U) -> ~rd,
|
||||||
(io.dataIn(4,0) === "b11110".U) -> ~rd,
|
(io.dataIn(4,0) === "b11110".U) -> ~rd,
|
||||||
(io.dataIn(4,0) === "b11111".U) -> ~rd,
|
(io.dataIn(4,0) === "b11111".U) -> ~rd,
|
||||||
))
|
))
|
||||||
|
|
||||||
val b3b4LookUp = Mux1H(Seq(
|
val b3b4LookUp = Mux1H(Seq(
|
||||||
(io.dataIn(7,5) === "b000".U) -> Mux( ~b5b6RD, "b1011".U(4.W), "b0100".U(4.W) ),
|
(io.dataIn(7,5) === "b000".U) -> Mux( ~b5b6RD, "b1011".U(4.W), "b0100".U(4.W) ),//控制位与否保持相同情况
|
||||||
(io.dataIn(7,5) === "b001".U) -> "b1001".U(4.W),
|
|
||||||
(io.dataIn(7,5) === "b010".U) -> "b0101".U(4.W),
|
(io.dataIn(7,5) === "b001".U) -> Mux( (if(IS_ENABLE_K28_1) {~io.isCtrl} else { true.B }),
|
||||||
(io.dataIn(7,5) === "b011".U) -> Mux( ~b5b6RD, "b1100".U(4.W), "b0011".U(4.W) ),
|
"b1001".U(4.W),
|
||||||
(io.dataIn(7,5) === "b100".U) -> Mux( ~b5b6RD, "b1101".U(4.W), "b0010".U(4.W) ),
|
Mux( ~b5b6RD, "b0110".U(4.W), "b1001".U(4.W) ), //控制位
|
||||||
|
),
|
||||||
|
|
||||||
|
(io.dataIn(7,5) === "b010".U) -> Mux( (if(IS_ENABLE_K28_2) {~io.isCtrl} else { true.B }),
|
||||||
|
"b0101".U(4.W),
|
||||||
|
Mux( ~b5b6RD, "b1010".U(4.W), "b0101".U(4.W)), //控制位
|
||||||
|
),
|
||||||
|
|
||||||
|
(io.dataIn(7,5) === "b011".U) -> Mux( ~b5b6RD, "b1100".U(4.W), "b0011".U(4.W) ),//控制位与否保持相同情况
|
||||||
|
(io.dataIn(7,5) === "b100".U) -> Mux( ~b5b6RD, "b1101".U(4.W), "b0010".U(4.W) ),//控制位与否保持相同情况
|
||||||
(io.dataIn(7,5) === "b101".U) -> "b1010".U(4.W),
|
(io.dataIn(7,5) === "b101".U) -> "b1010".U(4.W),
|
||||||
(io.dataIn(7,5) === "b110".U) -> "b0110".U(4.W),
|
|
||||||
|
(io.dataIn(7,5) === "b110".U) -> Mux( (if(IS_ENABLE_K28_6) {~io.isCtrl} else { true.B }),
|
||||||
|
"b0110".U(4.W),
|
||||||
|
Mux( ~b5b6RD, "b1001".U(4.W), "b0110".U(4.W)), //控制位
|
||||||
|
),
|
||||||
|
|
||||||
(io.dataIn(7,5) === "b111".U) -> MuxCase( Mux( ~b5b6RD, "b1110".U(4.W), "b0001".U(4.W) ), Array(
|
(io.dataIn(7,5) === "b111".U) -> MuxCase( Mux( ~b5b6RD, "b1110".U(4.W), "b0001".U(4.W) ), Array(
|
||||||
((io.dataIn(4,0) === 17.U || io.dataIn(4,0) === 18.U || io.dataIn(4,0) === 20.U) & ~b5b6RD) -> "b0111".U(4.W), // 17, 18, 20 are special cases
|
((io.dataIn(4,0) === 17.U || io.dataIn(4,0) === 18.U || io.dataIn(4,0) === 20.U) & ~b5b6RD) -> "b0111".U(4.W), // 17, 18, 20 are special cases
|
||||||
((io.dataIn(4,0) === 11.U || io.dataIn(4,0) === 13.U || io.dataIn(4,0) === 14.U) & b5b6RD) -> "b1000".U(4.W), // 11, 13, 14 are special cases
|
((io.dataIn(4,0) === 11.U || io.dataIn(4,0) === 13.U || io.dataIn(4,0) === 14.U) & b5b6RD) -> "b1000".U(4.W), // 11, 13, 14 are special cases
|
||||||
@@ -131,10 +163,11 @@ class b8b10Encode extends Module with RequireAsyncReset{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class b8b10Decode extends Module with RequireAsyncReset{
|
class b8b10Decode extends Module with RequireAsyncReset with b8b10Config{
|
||||||
val io = IO(new Decode_Bundle)
|
val io = IO(new Decode_Bundle)
|
||||||
|
|
||||||
|
|
||||||
@@ -189,4 +222,11 @@ class b8b10Decode extends Module with RequireAsyncReset{
|
|||||||
|
|
||||||
io.dataOut := Cat(b3b4LookUp, b5b6LookUp)
|
io.dataOut := Cat(b3b4LookUp, b5b6LookUp)
|
||||||
|
|
||||||
|
io.isK28_0 := (io.dataIn === "b0011110100".U) || (io.dataIn === "b1100001011".U)
|
||||||
|
io.isK28_1 := (if(IS_ENABLE_K28_1) { (io.dataIn === "b0011111001".U) || (io.dataIn === "b1100000110".U) } else { false.B })
|
||||||
|
io.isK28_2 := (if(IS_ENABLE_K28_2) { (io.dataIn === "b0011110101".U) || (io.dataIn === "b1100001010".U) } else { false.B })
|
||||||
|
io.isK28_3 := (io.dataIn === "b0011110011".U) || (io.dataIn === "b1100001100".U)
|
||||||
|
io.isK28_4 := (io.dataIn === "b0011110010".U) || (io.dataIn === "b1100001101".U)
|
||||||
|
io.isK28_6 := (if(IS_ENABLE_K28_6) { (io.dataIn === "b0011110110".U) || (io.dataIn === "b1100001001".U) } else { false.B })
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user