p5图
考法一:抽象层级的排序(填空题 / 选择题)
这是最基础的考法,考查你对硬件描述“从宏观到微观”的认知。
- 考点: 图左侧那个向下的箭头“描述和抽象能力”,从高到低分别是哪五个层级?
- 答案(从高到低): 系统级 -> 算法级 -> 寄存器传输级 (RTL) -> 门级 -> 开关级。
- 典型题目: “Verilog HDL 支持不同级别的抽象描述,请按抽象级别从高到低排列:*、*、RTL级、门级、_。”
考法二:Verilog 与 VHDL 在底层的本质区别(极其爱考的判断题 / 选择题)
你看图中那条最显眼的大括号,它圈出了 Verilog HDL 的范围,并且最底部探到了“开关级”。而右侧的 VHDL 对应的框,底部只到了门级(下面是单独的 VITAL)。
- 考点: 两种语言在底层物理建模能力上的差异。
- 答案: Verilog HDL 能够进行开关级(晶体管级)的建模,而标准的 VHDL 不支持直接的开关级建模。
- 典型题目:
- (判断题)“VHDL 和 Verilog HDL 都具有开关级的描述能力。” ❌ (错,VHDL没有)
- (选择题)“下列哪种语言更适合用于底层 CMOS 晶体管开关级别的电路描述?” 👉 选 Verilog HDL。
考法三:SystemVerilog 的作用(填空题 / 简答题)
看图的最上方,SystemVerilog 补足了最顶部的空间。
- 考点: 了解 SystemVerilog 的定位。
- 答案: 它是 Verilog 的扩展,主要是为了增强 系统级(System Level) 的建模、验证和描述能力。
💡 考前冲刺复习建议
如果这道题出现在卷面上,你只需要在大脑里提取这三句话就能拿满分:
- 顺序是:系统、算法、RTL、门、开关。
- Verilog 手更长,能往下摸到“开关级”(晶体管)。
- VHDL 偏上层,底层要靠 VITAL 辅助。
考试遇到这题属于白给的分数,把这几个关键层级和“开关级”的归属看准,就没问题了!
软固硬核的概念
软核一般是指经过功能验证、5000门以上的可综合 Verilog HDL或 VHDL模型。
固核通常是指在 FPGA 器件上,经过综合验证、大于 5000 门的电路网表文件
硬核通常是指在 ASIC 器件上,经过验证、正确的、大于 5000 门的电路结构版图掩膜
ip核是具有知识产权核的集成电路芯核的总称,是经过反复验证的,具有特定功能的宏模块,且该模块与芯片制造工艺无关,可以移植到不同的半导体工艺中
verilog标准
1995年 :verilog IEEE 1364-1995
2001年:verilog IEEE 1364-2001
第二章
标识符:标识符是被用来命名信号,模块,参数等,它可以是任意一组字母,数字,下划线,美元符的组合。标识符区分大小写,开头必须是字母或者下划线。
关键字都是小写
常见表现形式示例
有位宽整数 (推荐格式)
这是最严谨的写法,可以防止在综合为底层电路时产生意想不到的位宽截断或扩展。
4'b1011:4位二进制数10118'hFA:8位十六进制数FA(二进制为11111010)16'd255:16位十进制数255
运算符优先级
为了应付考试或快速回忆,你可以记住这句顺口溜:
“单算移,关等位,逻辑三目最后拼”
- 单:单目(
!,~) - 算:算术(先乘除模,后加减)
- 移:移位(
<<,>>) - 关:关系(大小判断)
- 等:相等(是否相等)
- 位:按位操作(
&>^>|) - 逻辑:逻辑操作(
&&>||) - 三目:条件选择(
?:) - 最后拼:拼接操作(
{})
== 和 ===真值表
==
| A \ B | 0 | 1 | x | z |
|---|---|---|---|---|
0 | 1 | 0 | x | x |
1 | 0 | 1 | x | x |
x | x | x | x | x |
z | x | x | x | x |
===
| A \ B | 0 | 1 | x | z |
|---|---|---|---|---|
0 | 1 | 0 | 0 | 0 |
1 | 0 | 1 | 0 | 0 |
x | 0 | 0 | 1 | 0 |
z | 0 | 0 | 0 | 1 |

采用过程语句对组合电路进行描述时,需要把全部的输入信号列入敏感事件列表
采用过程语句对时序电路进行描述时,需要把时间信号和部分输入信号列入敏感事件列表
结构化建模
包括:模块级建模,门级建模,开关级建模
高频考点一:端口映射规则(必考选择/改错题)
当你调用(实例化)一个现成的模块时,如何把外部信号连到模块的端口上?这是最容易出题的地方。
- 陷阱:位置映射 vs. 名称映射
- 位置映射(Positional):严格按照原模块定义的端口顺序连线。缺点是极易连错,且一旦原模块修改,这里的代码全得改。
- 名称映射(Named,强烈推荐):使用
.端口名(连接信号)的格式。顺序可以随便打乱,非常清晰。
- 考试常见改错:题目会故意把名称映射写错,或者在同一个实例化里混用两种映射方式(语法是不允许混用的)。Verilog // 假设底层模块定义为:module D_FF (input D, input clk, output Q);
// 错误写法(混用,直接零分):
D_FF d1 (.D(data_in), clk, .Q(data_out));
// 满分写法(名称映射):
D_FF d2 (.Q(data_out), .D(data_in), .clk(clock)); // 顺序打乱完全没问题
高频考点二:内置门级原语的“暗规则”
Verilog 内置了一些基础逻辑门(如 and, or, not, nand, xor 等),被称为门级原语。调用它们时有一个极其死板的规定。
- 终极陷阱:输出必须写在第一位! 内置门的语法是:
门类型 实例名 (输出, 输入1, 输入2, ...);考试时,老师最喜欢在填空题或读图题里考这个顺序:Verilog wire out, a, b;
// 考题:请用内置与门实现 out = a & b;
and u1 (out, a, b); // 正确:输出 out 必须在最前面!
and u2 (a, b, out); // 致命错误!这会被综合成 a 作为输出
端口的对应
名称映射(Named Mapping)*是实际工程中最标准、最推荐的端口连接方式。它的核心思想是:*“指名道姓地连线,绝不依赖位置顺序。”
要彻底搞懂它,你只需要记住一个核心语法公式和一句口诀。
1. 核心语法公式
Verilog
调用的模块名 实例名 (
.底层端口名1 (当前模块的信号线A),
.底层端口名2 (当前模块的信号线B),
...
);
💡 独家记忆口诀:“点(底层),括(当前)”
.(点):代表你要“点”开那个被调用的模块,所以点后面跟着的永远是底层模块原有的端口名字。()(括号):代表你手里正拿着一根线,所以括号里面写的是当前模块中用来连接的信号线名字。
2. 来看一个超级直观的例子
假设我们有一个别人写好的半加器(Half_Adder)模块,它的代码是这样的:
Verilog
// 底层模块:半加器
module Half_Adder (
input a, // 加数1
input b, // 加数2
output sum, // 本位和
output carry // 进位
);
// (内部逻辑略)
endmodule
现在,你在写一个顶层模块(Top_Module),手里有四根线(x, y, out_sum, out_carry),你想把它们连到半加器上。使用名称映射的代码如下:
Verilog
// 顶层模块
module Top_Module (
input x,
input y,
output out_sum,
output out_carry
);
// 实例化半加器,使用名称映射
Half_Adder u1 (
.sum (out_sum), // 把底层的 sum 端口,连上我手里的 out_sum 线
.a (x), // 把底层的 a 端口,连上我手里的 x 线
.carry (out_carry), // 把底层的 carry 端口,连上我手里的 out_carry 线
.b (y) // 把底层的 b 端口,连上我手里的 y 线
);
endmodule
发现了吗? 在实例化 u1 的时候,我故意把 .sum 放到了第一行,把 .b 放到了最后一行。这就体现了名称映射的最大优势:顺序完全自由! 只要你“指名道姓”了,编译器绝对不会连错。
3. 考试与工程中的四大踩坑点
在理解了基本用法后,以下几个规则是考试最爱考、写代码最容易报错的地方:
🔴 坑点一:端口悬空(想空着不连怎么办?)
有时候我们调用一个模块,它的某个输出端口我们不需要用。在名称映射中,处理悬空非常优雅:
- 正确做法:只写点和底层端口名,括号里留空。
Verilog
Half_Adder u2 (
.a (x),
.b (y),
.sum (out_sum),
.carry () // 括号里什么都不写,代表 carry 端口悬空不连
);
(注:对于 input 端口,最好不要悬空,否则底层模块会接收到未知态 x,除非底层有默认值定义。)
🔴 坑点二:位宽不匹配
括号里的线(如 [3:0] data_in),必须和底层端口的位宽一致。如果不一致,Verilog 会默认进行截断或补零,这通常会产生一个 Warning(警告),并且极大概率导致你的逻辑出错。
🔴 坑点三:绝对不能“混搭”
在同一个实例化中,你要么全用“位置映射”,要么全用“名称映射”,严禁混用。
Verilog
// 致命错误:混用映射方式,直接编译报错!
Half_Adder u3 (
x, // 这里用的是位置映射
.b(y), // 这里用的是名称映射
.sum(out_sum),
.carry()
);
🔴 坑点四:名字拼写错误
既然是“指名道姓”,那就要求 .名字 必须和底层模块定义的端口名字一字不差(Verilog 是区分大小写的)。如果底层叫 Clk,你写成了 .clk(clock),编译器会直接报错找不到该端口。
各种门

第四章
数据选择器
module mux8to1(out, sel, data_in);
output out;
input [7:0] data_in;
input [3:0] sel;
reg out;
always @(data_in or sel)
case (sel)
3'b000 : out = data_in[0];
3'b001 : out = data_in[1];
3'b010 : out = data_in[2];
3'b011 : out = data_in[3];
3'b100 : out = data_in[4];
3'b101 : out = data_in[5];
3'b110 : out = data_in[6];
3'b111 : out = data_in[7];
endcase
endmodule
移位寄存器
module shiftregist1 (D, clk, reset);
parameter shiftregist_width = 4;
output [shiftregist_width-1:0] D;
input clk, reset;
reg [shiftregist_width-1:0] D;
always @(posedge clk)
if (!reset)
D <= 4'b0001;
else
D <= {D[shiftregist_width-2:0], D[shiftregist_width-1]};
endmodule
计数器
module comp2bit (Q, clk, reset);
output Q;
input clk, reset;
reg Q;
always @ (posedge clk or negedge reset)
if (!reset)
Q <= 1'b0;
else
Q <= ~Q;
endmodule
D触发器

有限同步状态机有 同步 和 异步两种
常用的编码方式:二进制编码,格雷编码和一位独热编码
第五章
timescale的语法格式:`timescale time_unit / time_precision
例如 `timescale 1ns / 1ns
大题
组合电路设计
组合电路设计大题:万能五步法
第一步:需求分析与变量定义(建立抽象模型)
- 动作: 仔细阅读题目,找出所有的“输入条件”和“输出结果”,并给它们分配字母变量(如 A、B、C、Y)。
- 关键点: 必须明确定义逻辑
0和1的物理含义。例如:“设 A 为主裁判,A=1 表示同意,A=0 表示反对;设 Y 为最终结果,Y=1 表示通过,Y=0 表示否决。”(千万别漏写这句定义,很多老师会在这里扣过程分)。
第二步:列出真值表(最耗时,但绝对不能错)
- 动作: 根据输入变量的个数 n,列出一个包含 2^n 行的表格。穷举从
00...0到11...1的所有输入情况,并根据题意填上对应的输出 Y。 - 避坑指南: 遇到题目中没有说明的输入组合,或者物理上不可能发生的输入(比如 BCD 码里出现了
1010到1111),直接在输出栏填入 无关项d(或x)。巧妙利用无关项,可以在下一步化简时大幅减少门电路的数量。
第三步:逻辑化简(核心拿分点:卡诺图)
- 动作: 把真值表里的
1和d画进卡诺图(Karnaugh Map)。 - 圈图铁律:
- 圈数要尽可能少。
- 每个圈里的方格数必须是 2^k(1, 2, 4, 8…),圈要尽可能大。
- 圈可以跨越边界(上下相连、左右相连,甚至是四个角相连)。
- 无关项
d可以当成1圈进去(如果能让圈变大),也可以当成0不理它。
第四步:写出逻辑表达式
- 动作: 根据卡诺图的圈,写出最简的与或式 (SOP)。
- 变形考点: 考卷有时不让你直接画与或门,而是会加限制条件:
- “请仅用与非门 (NAND) 实现”:使用摩根定律,给整个表达式加两次非号(双重反相),然后化成全是与非的形式。
- “请用 74LS138 (3-8译码器) 实现”:把表达式展开为标准与或式(最小项表达式),然后直接连线。
第五步:绘制逻辑电路图 / 编写 Verilog 代码
- 动作: 根据上一步的表达式,画出逻辑门连接图,或者写出对应的
assign数据流建模代码。
常见的三大经典考题模型
- “多数表决”型(含权重机制)
- 经典题目: 三个裁判 A、B、C,A 是一票否决权,B 和 C 普通票。只有 A 同意且 B、C 中至少一人同意时才通过。
- 破题点: 重点看特殊的那个变量,真值表中只要 A=0,输出全为 0。
- “数值检测/比较”型
- 经典题目: 设计一个电路,输入为 4 位二进制数,当输入数值在 5 到 10 之间时,输出高电平。
- 破题点: 这是典型的卡诺图无关项运用题。如果明确说输入是 BCD 码,记得把 10~15 当作无关项
d。
- “中规模集成器件 (MSI)”搭积木型
- 经典题目: 请用一个 8 选 1 数据选择器 (74LS151) 或者 3-8 译码器 (74LS138) 实现特定的逻辑函数。
- 破题点: 不需要画复杂的卡诺图。把函数化为最小项之和,最小项的编号(如 m_3, m_5, m_7)直接对应芯片引脚的连线。
没问题,我们来实战演练一道数字逻辑考试中最经典、最常考的入门级大题:“三人表决器”。
掌握了这道题,你就彻底打通了“从文字需求到物理硬件”的任督二脉。
经典例题:三人表决器设计 书p75
【题目描述】
有 A、B、C 三名评委对一个项目进行投票表决。只有当两名或两名以上的评委投“赞成”票时,项目才算通过。请设计该表决器的逻辑电路,并写出对应的 Verilog 数据流建模代码。
第一步:需求分析与变量定义(建立模型)
- 输入变量: 设 A、B、C 为三名评委的投票状态。
- 逻辑
1表示“赞成”。 - 逻辑
0表示“反对”。
- 逻辑
- 输出变量: 设 Y 为最终表决结果。
- 逻辑
1表示“项目通过”。 - 逻辑
0表示“项目否决”。
- 逻辑
第二步:列出真值表(穷举所有可能)
三个输入,总共有 2^3 = 8 种情况。规则是“至少两个 1,输出才是 1”。
| A (评委1) | B (评委2) | C (评委3) | Y (结果) | 说明 |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 全反对 |
| 0 | 0 | 1 | 0 | 一人赞成 |
| 0 | 1 | 0 | 0 | 一人赞成 |
| 0 | 1 | 1 | 1 | B、C赞成 (2票) |
| 1 | 0 | 0 | 0 | 一人赞成 |
| 1 | 0 | 1 | 1 | A、C赞成 (2票) |
| 1 | 1 | 0 | 1 | A、B赞成 (2票) |
| 1 | 1 | 1 | 1 | 全票赞成 (3票) |
第三步:逻辑化简(卡诺图推导)
我们将真值表中 Y=1 的位置(也就是 011, 101, 110, 111)填入卡诺图。
- 相邻的 1 可以圈在一起(两个一圈)。
- 最终可以画出三个圈,分别覆盖:(A,B)、(A,C)、(B,C)。
第四步:写出逻辑表达式
根据卡诺图的三个圈,我们可以得出最简的与或式 (SOP):
Y = AB + AC + BC
(这就是这个电路的核心灵魂:A和B同意、或者A和C同意、或者B和C同意)
第五步:编写 Verilog 代码 (数据流建模)
有了表达式,写代码就是一秒钟的事,直接把数学符号翻译成 Verilog 的按位运算符(& 和 |):
Verilog
module Majority_Voter (
input A,
input B,
input C,
output Y
);
// 数据流建模:用 assign 直接映射逻辑表达式
assign Y = (A & B) | (A & C) | (B & C);
endmodule
(注意:在工程习惯中,虽然 & 优先级高于 |,但加上括号 () 会让代码可读性大大增强,考试时这样写绝对满分。)
复位 (rst_n=0)din = 1din = 0din = 1din = 0din = 1din = 0din = 1din = 0din = 1din = 0S0 / 0 (未检测到1)S1 / 0 (连续1个1)S2 / 0 (连续2个1)S3 / 0 (连续3个1)S4 / 1 (4个或以上1)