HDLBits刷题笔记
最近试了一下Verilog刷题网站HDLBits,感觉还是蛮有意思的。这里记录一下刷题的一些收获。
Bit slicing的简化语法
Bit slicing ("Indexed vector part select", since Verilog-2001) has an even more compact syntax.
来源:Circuits-Multiplexers-Mux256to1v
1 |
|
in[sel*4 +: 4]
是 Verilog-2001 中引入的 “indexed part
select” 语法:
sel*4
表示选择从哪个位开始(包含该位)。
+: 4
表示从 sel*4 开始,选择 4 位宽的数据。
这个语法非常简洁,并且可以避免合成工具无法推断切片宽度为常数的问题。
类似的还有assign out = in[sel*4+3 -: 4];
加法器
Create a 100-bit binary adder. The adder adds two 100-bit numbers and a carry-in to produce a 100-bit sum and carry out.
正解:没有必要重新构造全加器模块了,直接使用现有的运算符号。
1
2
3
4
5
6
7
8
9
10
11
12module top_module (
input [99:0] a,
input [99:0] b,
input cin,
output cout,
output [99:0] sum
);
// The concatenation {cout, sum} is a 101-bit vector.
assign {cout, sum} = a+b+cin;
endmodule
卡诺图的两种形式
77.A single-output digital system with four inputs (a,b,c,d) generates a logic-1 when 2, 7, or 15 appears on the inputs, and a logic-0 when 0, 1, 4, 5, 6, 9, 10, 13, or 14 appears. The input conditions for the numbers 3, 8, 11, and 12 never occur in this system. For example, 7 corresponds to a,b,c,d being set to 0,1,1,1, respectively.
Determine the output out_sop in minimum SOP form, and the output out_pos in minimum POS form.
1 |
|
Dff8
Create 8 D flip-flops. All DFFs should be triggered by the positive edge of clk.
1 |
|
因为q在这里是一个向量,所以可以一次性创建出8个D触发器。
异步复位
异步复位和同步复位相比,唯一的区别在于always的敏感列表中包含了复位信号reset。
1 |
|
Problem 85 : DFF with byte enable(Dff16e)
Create 16 D flip-flops. It's sometimes useful to only modify parts of a group of flip-flops. The byte-enable inputs control whether each byte of the 16 registers should be written to on that cycle. byteena[1] controls the upper byte d[15:8], while byteena[0] controls the lower byte d[7:0].
resetn is a synchronous, active-low reset.
All DFFs should be triggered by the positive edge of clk.
这道题的要求是创建一个 16 路 D触发器。部分情况下,只需要多路触发器中的一部分触发器工作,此时可以通过 ena 使能端进行控制。使能端 ena 信号有效时,触发器在时钟上升沿工作。
注意:当byteena=2'b11时,两个部分均可被写入,因此要慎重选择if~else的结构
1 |
|
边沿捕获
96.当reset信号为高时,强制输出为低电平;当输入信号in出现下降沿时,输出out保持为1,也就是说只有reset能将out拉低。
1 |
|
双边沿触发器
Verilog的always语句块的敏感变量列表不能同时支持posedge和negedge,自己单独搭建电路实现双边沿触发的功能。
时序图如下:
利用二选一数据选择器的实现思路:
1 |
|
暂停计数器
Problem 101 Slow decade counter
在时钟上升沿对0~9递增计数,高电平复位,当slowena为低时暂停计数。
1 |
|
Problem 104 4-digit decimal counter
Build a 4-digit BCD (binary-coded decimal) counter. Each decimal digit is encoded using 4 bits: q[3:0] is the ones digit, q[7:4] is the tens digit, etc. For digits [3:1], also output an enable signal indicating when each of the upper three digits should be incremented.
You may want to instantiate or modify some one-digit decade counters.
这道题要求我们设计一个四位BCD码计数器。由于每一位BCD码要用4位二进制数表示,因此输出为16位二进制数。基本思路是先建立一个一位BCD码计数器的基本单元,再实例化得到4位的。
个人觉得这里比较难搞的地方是怎么处理进位。在组合逻辑电路中,4位BCD码加法器的进位只需要把低位端的进位输出连接到高位的进位输入即可。对于时序逻辑来说,进位也可以理解为使能,计数可以理解为翻转,只有当计数溢出时才使能一次高位,使高位在时钟信号到来的时候翻转一次。
以T触发器构成的计数器为例,T触发器有以下特征:
- 当使能信号T=1时,每次触发会使输出翻转;
- 当使能信号T=0时,输出保持不变;
计数器在递增计数的过程中,计数值的变化体现为位的翻转,低位对高位的影响体现在只有当低位全为1时高位才可翻转(进位),用激励方程来描述就是
对应的硬件电路为
对于BCD计数器来说也是一样的道理。4位BCD计数器由4个BCD技术单元组成,每一个单元都有使能端,以最高位为例,只有当四位BCD的低三位全为4'b1001
时,最高位才被使能,这只需要用与门就可以实现,类似上图中的G1,G2,G3。用Verilog来描述的话,可以是.ena(q[11:8] == 4'd9 && q[7:4] == 4'd9 && q[3:0] == 4'd9),
或者直接写为.ena(q[11:0] == 12'h999),
,二者是等价的。
1 |
|
LFSR
Linear-feedback shift register,线性反馈移位寄存器 未完待续
1 |
|
Rule 90
Rule90是一种一维“元胞自动机”(cellular automaton),在每个时间步骤,每个细胞的下一个状态是它两个当前邻居的异或(XOR)值。
In this circuit, create a 512-cell system (q[511:0]), and advance by one time step each clock cycle. The load input indicates the state of the system should be loaded with data[511:0]. Assume the boundaries (q[-1] and q[512]) are both zero (off).
官方解答:
1 |
|
0 | q[511] | q[510] | … | q[2] | q[1] |
---|---|---|---|---|---|
q[510] | q[509] | q[508] | … | q[0] | 0 |
可以看出每来一个时钟沿,q的每一位都会变成相邻两位的异或。