第 2 章 · 物证登记:数据类型与参数 章节摘要:本章跟着「一件信号如何登记入册」的主线走:先分清 wire 与 reg 这两类来源不同的信号,再掌握向量、位宽与数组的记账规则,最后学会用参数把电路做成可配置的模板。类型系统是 Verilog 里最容易被轻视、也最容易出案子的地方。 一条主线 主线是登记造册:电路里的每根线、每个寄存器,都是一件证物,登记时必须写清三件事——它由谁驱动(类型)、它有多宽(位宽)、它的值是否可配置(参数)。这一章的三节正好对应这三问。登记错了的后果不会立刻显现:类型错了综合器可能直接拒收,位宽错了仿真照跑、上板出错,参数用错了则要到调参那天才爆雷。所以这一章反复强调「登记即审查」——写声明的动作,就是自查的第一步。 沿途站点 第一站 2.
章节摘要:本章跟着「一件信号如何登记入册」的主线走:先分清 wire 与 reg 这两类来源不同的信号,再掌握向量、位宽与数组的记账规则,最后学会用参数把电路做成可配置的模板。类型系统是 Verilog 里最容易被轻视、也最容易出案子的地方。
主线是登记造册:电路里的每根线、每个寄存器,都是一件证物,登记时必须写清三件事——它由谁驱动(类型)、它有多宽(位宽)、它的值是否可配置(参数)。这一章的三节正好对应这三问。登记错了的后果不会立刻显现:类型错了综合器可能直接拒收,位宽错了仿真照跑、上板出错,参数用错了则要到调参那天才爆雷。所以这一章反复强调「登记即审查」——写声明的动作,就是自查的第一步。
第一站 2.1「wire 与 reg」:net 类与 variable 类的本质差异在驱动来源——net 由持续驱动,variable 由过程赋值。这一站会破掉一个流传极广的误读:「reg 就是寄存器」。你会看到综合器真正关心的是赋值语句所在的语境,而不是关键字本身。
第二站 2.2「向量、位宽与数组」:Verilog 的加减乘除都发生在指定位宽的容器里,溢出被静默截断,这是它与软件语言最凶险的差异。这一站把位选择、部分选择、多维数组讲透,并给出一套「位宽对齐」的检查习惯。
第三站 2.3「参数与常量」:parameter、localparam 与 `define 三者的作用域与适用场合,顺带把 integer、real、time 这些辅助类型的位置摆正。参数化写得好,一份代码能顶一个产品系列;写得不好,调参就是开盲盒。
本章的拐点是把「类型声明」从样板代码变成审查动作。综合器从你的声明里读出电路形态:net 意味着持续驱动,variable 加边沿敏感过程块意味着触发器,位宽决定加法器的进位链长度。声明写得含糊,工具就替你做主,而工具做主的方向未必是你的意图。
另一个结论:位宽问题没有运行时异常帮你兜底。软件世界溢出会抛错或至少可复现,Verilog 的截断是静默的、确定性的,仿真和硬件行为一致地「错」——如果你的测试激励没覆盖到溢出场景,bug 会一路活到板上。所以本章给的纪律是:任何算术表达式,写之前先问一次「结果的正确位宽是多少」,写完再核对一遍。
类型系统还有一个容易被忽略的教学价值:它是这门语言里少数「错了立刻报」的地方。类型用错的赋值在编译期就拦下,不用等到仿真或上板。所以写代码时应当主动把类型声明写得精确——声明的精度越高,编译器能替你把的关越多。含糊的声明等于亲手关掉这层免费的检查。
`define 的适用场合。证物登记完毕,接下来是「当庭陈述」:assign 与 always 怎么把证物串成因果。第三章会直接用到本章的类型结论——比如为什么 assign 的左边必须是 net、为什么 always 里的赋值目标必须是 variable。带着「谁驱动谁」这个问题往下读,赋值语义会显得顺理成章。