实验练习
说明
- 每一次实验我们会为大家准备若干练习题目。不同的题目有着不同的难度,请大家量力而行;
- 你可以查阅任何开源资料完成实验练习,但不能直接抄袭。一经发现,我们将取消所有抄袭参与者本次的实验成绩。情节特别严重的,我们将按照学校的有关规定进行处理。
- 部分题目我们提供了代码框架,你需要在框架指定的位置完成代码内容。你也可以自由修改框架代码,但需要根据题目要求完成练习。
必做内容
每一名同学都需要完成必做部分的内容。
题目 1:if 语句与锁存器(1 分)
本题来自于 Digital Lab2 Avoid Latch If。你可以在该平台上验证自己的设计。
有时候,语法正确的代码并不一定能产生功能正常的电路,一般来说都是因为不小心引入了锁存器造成的。例如下面的 Verilog 语句:
1 2 3 4 5 6 7 8 9 | |
为消除锁存器,我们应当使组合逻辑过程块中的条件完备,即 if 语句后应加上 else 语句。试修改上述两段代码,以消除锁存器。
输入格式
- 输入信号 cpu_overheated, 位宽 1bit,控制 shut_off_computer 信号。
- 输入信号 arrived, 位宽 1bit,控制 keep_driving 信号。
- 输入信号 gas_tank_empty,位宽 1bit, 作为 keep_driving 的输入信号之一。
输出格式
- 输出信号 shut_off_computer,位宽 1bit,要求 cpu_overheated 为真时输出 1'b1,反之输出 1'b0。
- 输出信号 keep_driving,位宽 1bit,要求 arrived 为假时输出 ~gas_tank_empty,反之输出 1'b0。
代码框架如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
题目 2:case 语句与锁存器(1 分)
本题来自于 Digital Lab2 PS2 Arrow Decode。你可以在该平台上验证自己的设计。
假设您正在构建一个电路来处理游戏中 PS/2 键盘上的扫描码。现在给定接收到的扫描码的最后两个字节,您需要指示是否按下了键盘上的一个箭头键。这涉及到一个相当简单的映射,包含五种可能的情况:上、下、左、右,以及不属于任何一种。
您的电路有一个 16bits 输入和四个 1bit 输出,该电路识别这四个扫描码并确认正确的输出。为避免产生锁存,必须在所有情况下为四个输出指定一个值。这可能涉及许多不必要的输入。解决这个问题的一个简单方法是在 case 语句之前为输出分配一个『默认值』:
1 2 3 4 5 6 | |
这种类型的代码确保在所有可能的情况下为输出赋值(0),除非 case 语句重写赋值。这也意味着 default 项变得不必要。请试着将上述代码补充完整,以实现期望的电路功能。
代码框架如下:
1 2 3 4 5 6 7 8 9 | |
题目 3:计数器 Pro(3 分)
本题来自于 Digital Lab2 Counter Pro。你可以在该平台上验证自己的设计。
这是我们在实验教程中展示的计数器代码:
| Counter.v | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
现在,我们需要对其进行一点改进。
-
现在的计数器复位值是 0,最小值是 0,最大值是 MAX_VALUE。请修改代码,使得计数器的最小值也可以由模块参数 MIN_VALUE 指定。
-
在 1 的基础上,增加一个 1bit 输入信号
enable用于控制计数器的工作状态。要求:enable为高电平时,计数器在 MIN_VALUE 至 MAX_VALUE 之间正常工作;enable为低电平时,counter变量复位并保持在 0。从enable变为低电平开始到counter复位并保持在 0 的间隔不超过三个时钟周期。此外,rst信号的优先级应当高于enable信号。你需要结合仿真波形证明自己设计的正确性。例如:下面是助教的仿真文件与结果:
q3_tb.v 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
module q3_tb(); reg clk, rst, en; wire out_TA; initial begin clk = 0; rst = 1; en = 0; #10; rst = 0; #10; en = 1; #20; en = 0; #20; en = 1; #20; rst = 1; #20; rst = 0; #200; en = 0; end always #5 clk = ~clk; Counter #( .MIN_VALUE(8'd10), .MAX_VALUE(8'd13) ) counter ( .clk(clk), .rst(rst), .enable(en), .out(out_TA) ); endmodule
题目 4:1的个数pro(2 分)
本题来自于 Digital Lab2 Count Ones Range 32-bit。你可以在该平台上验证自己的设计。
设计一个Verilog模块,统计32位输入数据 a 中从第 b 位到第 c 位(包含两端)这个区间内1的个数。其中 b 和 c 都是5位无符号数,且保证 b < c。
注意:位索引从0开始,即第0位是最低位(LSB),第31位是最高位(MSB)。
模块接口
| CountOnes.v | |
|---|---|
1 2 3 4 5 6 | |
输入输出样例: 例:a = 32'b1010_1100_0011_1100_1010_1100_0011_1100 b = 5'd2, c = 5'd7 a[2:7] = 6'b001111 out = 5'd4 下面是供大家检查使用的testbench(测试平台已经为大家提供了测试用的testbench,但还是希望大家对testbench的书写方式和原理有充分的了解,以便于后续实验中的使用)
| CountOnes_tb.v | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | |
`
选择性必做内容
选择性必做内容是针对不同层次学生设计的分层内容。不同难度的题目对应不同的分值,请大家根据自身实际情况进行选择。
请在下面的题目中任选一题完成。多选按选择的第一题计分。
题目 1:奇怪的代码(2 分)
下面是一段被加密的代码。请自行编写仿真文件,设计特定的输入,测试该模块的功能。
| Foo.v | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
请在实验报告中指出该模块每个输入、输出端口的功能,并附上一些你的推理过程。
提示:位宽为 8bits 的信号为数据信号,其余为控制信号。
题目 2:计数器 天上天下天地无双版(2分)
本题来自于 Digital Lab2 Gray Counter 4-bit。你可以在该平台上验证自己的设计。
格雷码是一种编码系统,相邻两位之间只有1个比特的区别,相较于普通的二进制编码,格雷码能避免出现竞争-冒险现象,更加稳定。格雷码甚至能在解决汉诺塔问题、遗传算法理论等地方得到应用。
请设计一个计数器模块,以 4 位格雷码计数,每个时钟周期增加 1 ,到达最大值后归零,并在这个周期内给out信号置1,长度为1个周期,不断循环。
模块的部分信息如下:
| GrayCounter.v | |
|---|---|
1 2 3 4 5 6 7 8 | |
需要提示?
可以对4个比特一个一个分析,不一定要找出通用的规律。
题目 3:『众数』统计(3 分)
本题来自于 Digital Lab2 Find Mode Stream。你可以在该平台上验证自己的设计。
请设计一个模块,实时输出对于任意给定数目 8bits 无符号整数中出现次数超过一半的数(如果不存在则可以输出序列中任意一个数)。请结合 Vivado 仿真验证自己设计的正确性。方便起见,我们假定输入的数个数不超过 100。
模块的部分信息如下:
| FindMode | |
|---|---|
1 2 3 4 5 6 7 8 9 | |
其中:
- rst 有效时会清除先前的记录,视作从下一个数开始为第一个数;
- next 有效时代表此时通过 number 输入了一个数。输入过程是时钟同步的;
- out 输出截至目前输入的结果。
例如:对于输入序列,
10, 20, 30, 10, 10, 20, 30, 30, 30, 10, 10, 10
一个可接受的输出序列如下:
10, 20, 30, 10, 10, 10, 30, 30, 30, 30, 30, 10
对应的仿真波形如下: