FPGA基础——编码(独热码、格雷码、二进制码)

一、编码特点介绍

二进制码(Binary code):一种采用二进制格式连续编码的方法,其基本单位是二进制数(bit),由0和1组成。

独热码(One-hot code):每个状态由一个比特表示,且只有一个比特为1,其余位均为0。例如,6个状态的独热码可以表示为000001、000010、000100、001000、010000、100000。

格雷码(Gray Code):任意两个相邻状态之间只有一位二进制数不同。

 

(1)独热码(One-hot Code)

特点:

  1. 唯一性定义:每个状态仅有一位为1,其余位均为0(例如,3个状态对应编码3'b0013'b0103'b100
  2. 资源消耗:需要与状态数相等的触发器(n状态需n个触发器),但组合逻辑简化,仅需比较单个比特位即可判断状态
  3. 性能优势:
    • 速度与状态数量无关,仅取决于特定状态转移的路径复杂度
    • 减少毛刺:通过时序逻辑滤除组合逻辑输出中的瞬态干扰,适合总线信号对齐
  4. 设计友好性:
    • 易于综合、调试和静态时序分析
    • 无效状态多,需设计容错机制(如default分支强制跳转)

适用场景:

  • 大型状态机:FPGA寄存器资源丰富,独热码可显著提升速度和可靠性(如32+状态的系统)
  • 多选一逻辑:如仲裁器、优先级编码器,通过位掩码快速判断选择
  • 高时序要求场景:如流水灯控制、高速数据流调度(减少关键路径延迟)

(2)格雷码(Gray Code)

特点:

  1. 单步跳变:相邻状态仅一位变化,降低多比特跳变导致的毛刺和功耗
  2. 循环特性:首尾状态也仅相差一位,适合周期性计数
  3. 抗干扰能力:减少异步场景下的亚稳态风险,提高跨时钟域数据传输的可靠性
  4. 设计复杂度:
    • 编码规则复杂,需通过递归或异或运算生成
    • 译码需额外逻辑(如逐位异或恢复二进制值)

适用场景:

  • 跨时钟域同步:如异步FIFO的读写指针编码,确保地址变化时仅一位翻转
  • 旋转编码器:物理位置检测中避免多位跳变导致的错误解码
  • 低功耗设计:减少状态切换时的动态功耗(如电池供电设备)
  • 通信纠错:QAM调制等场景中减少单比特错误的影响

(3)二进制码(Binary Code)

特点:

  1. 资源效率:
    • 寄存器占用 log2(n)。
    • 组合逻辑复杂,易产生竞争冒险和长路径延迟
  2. 可读性:直接映射数值,便于人工理解和调试(如状态3'b011对应十进制3)
  3. 扩展性限制:状态数增加时,译码复杂度指数上升,速度显著下降

适用场景:

  • 小型状态机(状态数≤4):资源受限场景下兼顾效率和可读性
  • 数值计算电路:如二进制编码器、计数器,直接映射数学运算
  • CPLD设计:CPLD组合逻辑资源多,二进制码比独热码更高效

 


(4)特性对比

特性独热码格雷码二进制码
资源占用 多寄存器,少组合逻辑 中等寄存器,中等组合逻辑 少寄存器,多组合逻辑
速度 快(与状态数无关) 中等(依赖状态跳变复杂度) 慢(随状态数增加下降)
抗干扰能力 中(依赖时序约束) 高(单比特跳变) 低(多比特跳变)
适用规模 大型状态机(>24状态) 中等规模(4~24状态) 小型状态机(≤4状态)
典型应用 高速仲裁、多选一逻辑 异步FIFO、旋转编码器 基础计数器、数值编码器

设计建议:

  • FPGA优先独热码:利用其寄存器资源优势,简化时序收敛
  • 异步场景必选格雷码:确保跨时钟域信号稳定性
  • 小型系统或CPLD用二进制码:节省资源且易于实现

 

二、独热码占用较少的组合逻辑

  相对于格雷码,使用独热码作为状态会使用更多的触发器,但会占用较少的组合电路,即独热码相比格雷码更节省组合逻辑。

  比如说,表示4个状态,那么状态机寄存器采用格雷码编码只需要2bit:00(S0),01(S1),11(S2),10(S3);

  采用独热码需要4bit:0001(S0),0010(S1),0100(S2),1000(S3)。所以很明显采用格雷码可以省2bit寄存器。

 

例一:

假如我们要在代码中判断状态机是否处于某状态S1,

对于格雷码的状态机来说,代码是这样的:assign S1 = (STATUS==2'b01);

对于独热码来说,代码是这样的就行:assign S1=STATUS[1];

所以独热码的译码非常简单。

例二:

考虑最简单的跳变,当A为1时,状态机会从S0跳到S1。

采用格雷码写:

STATUS[1:0] <= (STATUS==2'b00) & A ? 2'b01 : 2'b00;

采用独热码写:

STATUS[1] <= STATUS[0] & A;

 

总结一下:

独热码适合写条件复杂但是状态少的状态机;

格雷码适合写条件不复杂但是状态多的状态机。

 

三、格雷码、二进制码转换

(1)二进制码转格雷码

格雷码第n位 = 二进制码第(n+1)位+二进制码第n位。不必理会进制。

Verilog 代码:

gray=(binary>>1)^binary;

(2)格雷码转二进制码

 

 二进制码第n位 = 二进制码第(n+1)位+格雷码第n位。因为二进制码和格雷码皆有相同位数,所以二进制码可从最高位的左边位元取0,以进行计算。

verilog 代码:

integer i;
for(i=0;i<=n-1;i=i+1)
binary[i]= ^(gray>>i)   //gray移位后,自身按位异或

 

posted on 2025-02-18 22:35  一曲挽歌  阅读(1169)  评论(0)    收藏  举报

导航