Altifigence Academy

40 / 63 · 实验

实验:串行数据移动与位顺序验证

结合位串与整数参考模型,验证方向、被丢弃的比特以及复位后的延迟。

实验对象与观察条件

每个上升沿上升沿 时钟从 0 变为 1 的瞬间。它不同于表示整个 CLK=1 区间的电平。了解更多将旧 q 的低两位向左移动,并将 din 放入 bit 0。依次输入 1、0、1、1,比较移动过程。

开始之前

准备 Digital Design Studio 的 Desktop 项目,并确保具备运行权限。将各示例分别保存到独立文件夹中的 rtl/top.sv。

SystemVerilog 源码

SystemVerilog
module top (
    input logic clk,
    input logic rst,
    input logic din,
    output logic [2:0] q
);
    // Old q[1:0] and din are captured together at each rising edge.
    always_ff @(posedge clk)
        if (rst) q <= 3'b000;
        else q <= {q[1:0], din};
endmodule

运行方法

在 New analysis 中选择 Two-state single-clock v1。Clock port 设为 clk,周期为 1000ps。使用以下设置完成 Preflight,再执行 Run RTL simulation 并比较结果。

设置值
初始寄存器值(从 LSB 开始)[false,false,false]
Reset portrst · Active high · 1 cycle
Maximum cycles / time5 / 5000ps

输入激励

json
[
  {
    "inputs": {
      "din": [
        false
      ]
    }
  },
  {
    "inputs": {
      "din": [
        true
      ]
    }
  },
  {
    "inputs": {
      "din": [
        false
      ]
    }
  },
  {
    "inputs": {
      "din": [
        true
      ]
    }
  },
  {
    "inputs": {
      "din": [
        true
      ]
    }
  }
]

每列记录一个上升沿的观察结果。输入取自边沿前,名称带 after 的状态取自更新后。列的排列表示采样顺序,并非描绘物理传播延迟传播延迟 从输入变化到输出稳定为正确值所需的时间。逻辑表达式等价与时间特性是两回事。了解更多。第一列是复位复位 将状态恢复为规定初值的控制。必须同时规定其同步或异步性质,以及相对于其他控制的优先级。了解更多边沿,din=0 不计为存储数据。将随后四次输入与下方 JSON 顺序比较。

输入激励与三位状态的移动
查看波形数据
波形数据:每个字符表示一个区间,点表示保持前一状态,p 表示一个时钟周期。
信号波形总线值
edge23452E0 → E1 → E2 → E3 → E4
reset10...
din0101.
q after23452000 → 001 → 010 → 101 → 011

比较结果

5 cycles · q=011。各上升沿的状态依次为 000 → 001 → 010 → 101 → 011。

本实验使用 0/1 单时钟 RTL,不包含 #delay、initial 或 X/Z 测试平台。学习完成标记只记录学习进度,不代表实际仿真结果。

用独立公式检查拼接运算

若把与 RTL 完全相同的拼接运算拼接运算 将多个位串并排连接的运算。结果位宽是操作数位宽之和,与数值加法不同。了解更多复制成测试答案,可能把同一错误放进两个地方。尝试使用按 unsignedunsigned 将位串解释为非负整数的规则。n 位范围为 0 到 2^n−1,可能与同一位串的 signed 解释不同。了解更多 整数解释的参考模型。

Qk+1=(2Qk+dk) mod 8Q_{k+1}=(2Q_k+d_k)\bmod 8

复位后,对输入 1、0、1、1 的计算是 0→1→2→5→30\to1\to2\to5\to3。将其写成三位二进制,应与实验波形相同。最后一步 2⋅5+1=112\cdot5+1=11,只保留低三位,因此结果为 3。

已接收比特数输入边沿后 q整数值
0复位0000
110011
200102
311015
410113

在 reset=0、enable=1 时,依次选择 din=1、0、1、1,每次都点击时钟。q 将依次为 001、010、101、011。先用这个单步实验预测,再与实际 RTL 结果比较。加入 enable 控制,是为了同时测试下方扩展任务中的暂停行为。

运行 RTL 前,亲自预测位顺序

同步 reset 优先于 enable。enable=0 时保持当前存储值。 q=000; q_next = (2q + din) mod 8

跟踪单个比特来验证方向

复位后输入一次 1,再输入三次 0,状态应为 001 → 010 → 100 → 000。最初的 1 应依次经过 bit 0、bit 1、bit 2,最后消失。只使用全 0 或全 1 模式,可能漏掉移位方向错误。

在三级寄存器寄存器 存储多位状态的电路。本课程中的同步寄存器在时钟边沿存储指定输入。了解更多中,若输入首次存储的边沿为 kk,它会在 k+2k+2 边沿后到达最高位 bit 2。若从外部发送寄存器发出数据的边沿计延迟,基准会不同,因此报告中应明确起点与终点。

扩展任务:只移动有效输入

假设给输入加入 valid。valid=0 时保持 q 的设计,与每周期移动数据并同时传递独立 valid 位的流水线不同。前者按接收比特数移动,后者按实际时钟周期移动,不能用同一预期状态序列验证这两种设计。

自己试试

复位后的 valid=1 比特依次为 1、0、1。第二个比特前后各有一个 valid=0 周期,invalid 周期保持 q。说明最终 q 及最初的 1 到达 bit 2 的时刻。

阅读解释

只有三次有效输入改变状态,因此最终 q=101。最初的 1 在第三个有效输入被存储的边沿到达 bit 2。从首次存储起还需要两次额外移动;其中两个 invalid 周期使实际经过时间增加。

Lesson files

shift-top.sv ↓shift-inputs.json ↓

你的选择适用于此浏览器,可随时在页脚更改。