StrongWong

从计数器开始,看数字 IC 设计

计数器设计

之前有实验室的学长去参加海思、中芯国际、瑞芯微、…… 数字 IC 前端方向的面试,几乎都问到了同一系列问题——设计一个计数器及相关问题。这里很多朋友就会觉得很有意思了,为什么一个简单的计数器能有这么多东西,那我们就『简单』的东西简单看。

0x00 请你设计一个 10 进制的异步复位无限循环计数器(0-9)

首先,第一个问题,请你设计一个 10 进制的异步复位无限循环计数器(0-9),你会怎么做?

相信到这很多朋友就开始洋洋洒洒地写道:

module counter10(
                input clk,
                input rst_n,
                output wire cnt_flag
                );
reg[3:0] cnt_reg;

always @(posedge clk or negedge rst) begin
    if( ~rst_n) begin
        cnt_reg <= 4'b0;
    end
    else begin
        if(cnt_reg == 4'd9)
            cnt_reg <= 4'b0;
        else
            cnt_reg <= cnt_reg + 4'b1;
        end
    end

assign cnt_flag = (cnt_reg == 4'd9) ? 1'b1 : 1'b0;

endmodule

0x01 请画出对应的电路图

Bravo! 没有任何问题!接下来开始有分水岭了,请画出对应的电路图 ,有的朋友可能会抓脑袋了:

这里给一点提示,看你能想起什么,确定状态 —— 确定激励方程 —— 逻辑图 —— 自启动检查 —— 状态表。这是什么?数字电路基础,为什么?我们这是数字集成电路设计啊!最终还是要回归到数字电路上来啊!

好,那我们先用 D 触发器来做(不经过编码优化,只是还原最简单的设计步骤),回忆一下最初我们大一大二时怎么弄的。

状态表:

计数顺序现状态次状态
-Q3 Q2 Q1 Q0D3 D2 D1 D0
00 0 0 00 0 0 1
10 0 0 10 0 1 0
20 0 1 00 0 1 1
30 0 1 10 1 0 0
40 1 0 00 1 0 1
50 1 0 10 1 1 0
60 1 1 00 1 1 1
70 1 1 11 0 0 0
81 0 0 01 0 0 1
91 0 0 10 0 0 0

激励方程:

逻辑图:

…… 剩下的估计大家都能回忆起来了

以上就是我们之前数字电路设计流程,我们回过头来看我们的硬件描述过程,有 if 判断值,那少不了比较器,有 + 运算,自然也有一个加法器 …… 当然我们真正的设计应该是先想好了有比较器和其他逻辑电路才有对应的硬件描述,但我们不妨来看一下我们设计的电路,不正是如下图所示:

0x02 上图中的关键路径是哪一条?

Ok~ 解决了电路图,下一个问题又来了,上图中的关键路径是哪一条?

要知道关键路径就需要时序分析啦,这里为接下来的另一个数字 IC 的小专栏———时序分析与约束挖下第一坑。

关键路径应该是:Q > + > MUX > D (具体分析将在后面填坑,大家也可以先想想为什么不是 Q > CMP > MUX > D)

0x03 上面图中 CMP = 9 即原描述中 cnt_reg == 4’d9 的电路是什么?

接下来的问题,上面图中 CMP = 9 即原描述中 cnt_reg == 4’d9 的电路是什么? 其实答案就在我们的触发器版原理图对应的组合电路中,精简后如下图所示:

0x04 cnt_reg == 4’d9 和 cnt_reg > 8 有什么区别?

功能上确实是一样的,但是如果是一个把 Verilog 当编程玩的朋友对于接下来的东就蛮有意义的了,cnt_reg == 4’d9 实现的电路如上图所示,是一个相对简单的组合逻辑电路。如果是 cnt_reg > 8,对于我们 4 位数据来说可能的范围为 9~15,则综合工具会把所有的情况都列出,cnt_reg == 9,10,11 …… 这样在无形中就浪费了资源。若位宽更大则会被综合为cnt_reg - 8 > 0,由此便会引入一个加法器 ……

0x05 加法器对应的电路是什么?如何验证这个计数器?……

一系列的问题,我们可以发现并非那么简单的。要知道直到现在优化加法器的文章依然不时可以出现在 sci 检索期刊中,这另外说明为什么上一问引入加法器后带来的浪费用省略号来表示,为什么关键路径是到 + 而不是比较器 ……

小结

引用《手把手教你设计 CPU——RISC-V 处理器篇》作者胡振波老师的一段话,当年第一次 Verilog 课时我的授课老师董乾博士也强调过类似的话。

先定义电路微架构而后编写代码。 谨记 Verilog 只是一种硬件描述语言,IC 设计的本质是对于电路的设计,虽然现在Verilog Coding 采用 RTL 级别的抽象描述,但是必须清楚所描述的代码能够映射出的电路结构,其面积和时序的影响都了然于胸,只有如此才能够成为一名优秀的 IC 设计工程师。 不要纠结 Verilog 的语法,而应立足实战。 Verilog 的设计语法子集非常精简简单,很快就可以上手入门。入门之后最好的学习方法是进行设计实战(实战是最好的老师),而不是进一步纠结 Verilog 的语法(不要浪费脑力试图记住大多数高级的 Verilog 语法,而是在需要使用的时候查阅即可)。

By Ricky