eda复习
本文最后更新于 76 天前,其中的信息可能已经有所发展或是发生改变。

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) 的建模、验证和描述能力。

💡 考前冲刺复习建议

如果这道题出现在卷面上,你只需要在大脑里提取这三句话就能拿满分:

  1. 顺序是:系统、算法、RTL、门、开关。
  2. Verilog 手更长,能往下摸到“开关级”(晶体管)。
  3. 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位二进制数 1011
  • 8'hFA:8位十六进制数 FA (二进制为 11111010)
  • 16'd255:16位十进制数 255

运算符优先级

为了应付考试或快速回忆,你可以记住这句顺口溜:

“单算移,关等位,逻辑三目最后拼”

  • :单目(!, ~
  • :算术(先乘除模,后加减)
  • :移位(<<, >>
  • :关系(大小判断)
  • :相等(是否相等)
  • :按位操作(& > ^ > |
  • 逻辑:逻辑操作(&& > ||
  • 三目:条件选择(?:
  • 最后拼:拼接操作({}

== 和 ===真值表

==

A \ B01xz
010xx
101xx
xxxxx
zxxxx

===

A \ B01xz
01000
10100
x0010
z0001
5637cf27e2cd2fa5c9b1f776cb2d008

采用过程语句对组合电路进行描述时,需要把全部的输入信号列入敏感事件列表

采用过程语句对时序电路进行描述时,需要把时间信号和部分输入信号列入敏感事件列表

结构化建模

包括:模块级建模,门级建模,开关级建模

高频考点一:端口映射规则(必考选择/改错题)

当你调用(实例化)一个现成的模块时,如何把外部信号连到模块的端口上?这是最容易出题的地方。

  • 陷阱:位置映射 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),编译器会直接报错找不到该端口。

各种门

image-20260628210030753

第四章

数据选择器

 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触发器

image-20260702104547346

有限同步状态机有 同步异步两种

常用的编码方式:二进制编码,格雷编码和一位独热编码

第五章

timescale的语法格式:`timescale time_unit / time_precision

例如 `timescale 1ns / 1ns

大题

组合电路设计

组合电路设计大题:万能五步法

第一步:需求分析与变量定义(建立抽象模型)

  • 动作: 仔细阅读题目,找出所有的“输入条件”和“输出结果”,并给它们分配字母变量(如 A、B、C、Y)。
  • 关键点: 必须明确定义逻辑 01 的物理含义。例如:“设 A 为主裁判,A=1 表示同意,A=0 表示反对;设 Y 为最终结果,Y=1 表示通过,Y=0 表示否决。”(千万别漏写这句定义,很多老师会在这里扣过程分)。

第二步:列出真值表(最耗时,但绝对不能错)

  • 动作: 根据输入变量的个数 n,列出一个包含 2^n 行的表格。穷举从 00...011...1 的所有输入情况,并根据题意填上对应的输出 Y。
  • 避坑指南: 遇到题目中没有说明的输入组合,或者物理上不可能发生的输入(比如 BCD 码里出现了 10101111),直接在输出栏填入 无关项 d (或 x)。巧妙利用无关项,可以在下一步化简时大幅减少门电路的数量。

第三步:逻辑化简(核心拿分点:卡诺图)

  • 动作: 把真值表里的 1d 画进卡诺图(Karnaugh Map)。
  • 圈图铁律:
    1. 圈数要尽可能少。
    2. 每个圈里的方格数必须是 2^k(1, 2, 4, 8…),圈要尽可能大。
    3. 圈可以跨越边界(上下相连、左右相连,甚至是四个角相连)。
    4. 无关项 d 可以当成 1 圈进去(如果能让圈变大),也可以当成 0 不理它。

第四步:写出逻辑表达式

  • 动作: 根据卡诺图的圈,写出最简的与或式 (SOP)
  • 变形考点: 考卷有时不让你直接画与或门,而是会加限制条件:
    • “请仅用与非门 (NAND) 实现”:使用摩根定律,给整个表达式加两次非号(双重反相),然后化成全是与非的形式。
    • “请用 74LS138 (3-8译码器) 实现”:把表达式展开为标准与或式(最小项表达式),然后直接连线。

第五步:绘制逻辑电路图 / 编写 Verilog 代码

  • 动作: 根据上一步的表达式,画出逻辑门连接图,或者写出对应的 assign 数据流建模代码。

常见的三大经典考题模型

  1. “多数表决”型(含权重机制)
    • 经典题目: 三个裁判 A、B、C,A 是一票否决权,B 和 C 普通票。只有 A 同意且 B、C 中至少一人同意时才通过。
    • 破题点: 重点看特殊的那个变量,真值表中只要 A=0,输出全为 0。
  2. “数值检测/比较”型
    • 经典题目: 设计一个电路,输入为 4 位二进制数,当输入数值在 5 到 10 之间时,输出高电平。
    • 破题点: 这是典型的卡诺图无关项运用题。如果明确说输入是 BCD 码,记得把 10~15 当作无关项 d
  3. “中规模集成器件 (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 (结果)说明
0000全反对
0010一人赞成
0100一人赞成
0111B、C赞成 (2票)
1000一人赞成
1011A、C赞成 (2票)
1101A、B赞成 (2票)
1111全票赞成 (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)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇