1、与门
1.1、符号
与门(AND gate),又称逻辑积电路。 只有当输入都为高电平(逻辑1)时,输出才为高电平(逻辑1),否则输出为低电平(逻辑0)。
1.2、与门真值表
输入 A | 输入 B | 输出 X(A & B) |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
1.3、与门波形图
1.4、与门 程序编写
我们为什么在写 FPGA 时要先进行仿真,主要原因如下:
- 验证设计正确性:仿真可以在硬件实现之前验证逻辑设计的正确性。通过模拟输入信号并观察输出,设计者可以确保设计按照预期工作,及时发现并纠正逻辑错误。
- 减少硬件调试时间:在实际硬件上测试发现问题,调试往往非常耗时且复杂。通过在仿真环境中提前发现问题,可以大幅减少在FPGA硬件上的调试时间和成本。
- 功能验证:设计过程中,仿真可以用于验证各个功能模块的交互和整体系统的功能。确保模块之间的数据传输和控制信号的正确性。
提供的仿真例程文件都在对应工程的 sim
文件夹里面,如果想跟着一起写的话,先创建一个工程,工程里面包含 doc
、 rtl
、 sim
。
注:详细的创建步骤请查看:工程创建
仿真文件 logical_and_mod.v
例程如下所示:
`timescale 1ns / 1ns // 定义时间单位为1纳秒,时间精度也为1纳秒
module logical_and_mod(); // 模块定义,名称为logical_and_mod
//reg define
reg A; // 定义A,作为输入信号
reg B; // 定义B,作为输入信号
//wire define
wire X; // 定义逻辑与运算的输出
// 初始化信号
initial begin
A = 1'b0; // 将寄存器A初始化为0
B = 1'b0; // 将寄存器B初始化为0
#200; // 等待200纳秒
A = 1'b0; // 设置A为0
B = 1'b1; // 设置B为1
#200; // 等待200纳秒
A = 1'b1; // 设置A为1
B = 1'b0; // 设置B为0
#200; // 等待200纳秒
A = 1'b1; // 设置A为1
B = 1'b1; // 设置B为1
#200; // 等待200纳秒
end
// 例化
logical_and u_logical_and(
.A(A), // 输入A
.B(B), // 输入B
.X(X) // 输出X,存储逻辑与运算结果
);
endmodule // 模块结束
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
第 1 行 :时间尺度预编译指令 时间单位/时间精度,第一个 1ns 是时间单位,第二个 1ns 是时间精度。
第 3 行:定义了仿真模块名称。
第 13 ~ 29 行:使用
initial
语句块进行输入信号的初始化,在初始化时对各输入端口数据进行固定。先将 A 和 B 赋 0,等待 200 ns后, A 保存不变 B 赋 1,等待 200 ns后,将 A 赋 1 ,B 赋 0,等待 200 ns后,将 A 和 B 赋 1 ,最后等待 200 ns。第 32 ~ 36 行:对我们的
logical_and.v
文件进行一个绑定。
logical_and.v
文件
module logical_and(
input A, //输入 A
input B, //输入 B
output X //输出 X
);
assign X = A & B; //将输入 A & B 的结果直接赋值给 输出 X
endmodule
2
3
4
5
6
7
8
9
10
11
- 第 1 行和第 11 行是
Verilog
语言中模块定义的标准语句,分别表示模块的开始和结束。第 1 行 module 后的 logical_and() 是模块名称,它应与 Verilog 工程的命名保持一致。 - 第 2 ~ 7 行:定义 输入 和 输出 端口。
- 第 9 行:将输入 A & B 的结果直接赋值给 输出 X 。
1.5、工程创建
开始使用 Gowin 创建项目工程了,芯片选型如下所示:
接着在 Gowin 的 Design 窗口空白地方右键点击选择 New Files... 添加文件。如下图所示:
会弹出新建文件的的对话框,如下图所示:
选择创建 Verilog File 文件,选择 OK 按钮,接下来该对这个新建的 Verilog 文件进行命名,工程名叫 logical_and.v(默认路径即可,例如:xx\logical\logical_and\pro\src\),命名完毕后选择 OK 按钮,如下所示:
接下来继续用 Gowin 创建仿真文件 logical_and_mod.v
(注:我们的仿真文件(xx_mod.v)是存放在 sim
文件夹中,其路径需要修改为:xx\logical\logical_and\sim\ 里面)记得改路径~,保存文件哦~,仿真文件记得失能,如下图所示:
添加完对应程序后,然后开始仿真,新建工程将 Project_Name 和 Default Library Name 都改成 logical_and 名称,如下图所示:
添加我们仿真所需的文件 logical_and.v(路径:Gowin -> logical -> logical_and -> pro -> src -> logical_and.v) 和 logical_and_mod.v (路径:Gowin -> logical -> logical_and -> sim -> logical_and_mod.v),如下图所示:
鼠标选中其中一个右击 -> 选择 Compile->Compile All ,如下图所示:
鼠标在空白地方右击 -> 选择 Add to Project -> Simulation Configuration ,如下图所示:
在 Add Simulation Configuration 配置好对应的文件(其中的 Liberies 和 Optimization Options..也别忘记修改),如下图所示:
仿真结果如下:
由上面的仿真图,可以看出与我们的真值表所列出的来结果是一致的,证明我们的程序没有问题。
1.6、上板验证
会到 Gowin 软件界面,由于我们 逻辑派 的 按键 按下为 低电平,和 RGB等 如果要点亮的话需要 低电平 与我们结果存在 差异 ,则我们得更改一下 logical_and.v (别忘记保存哦~),例程更改如下所示:
logical_and.v
文件
module logical_and(
input A, //输入 A
input B, //输入 B
output X //输出 X
);
assign X = ~((~A) & (~B)); ////将输入 A & B 的值取反,再将整体取反后结果直接赋值给 输出 X
endmodule
2
3
4
5
6
7
8
9
10
11
需要更改的地方如下图所示:
开始 Synthesize 编译判断 logical_and.v 文件是否有语法错误,如下图所示:
如果没有执行 Synthesize 编译,直接绑定引脚就无法打开,没有编译报错如下图所示:
我们该配置 I/O 引脚了,这里我们需要用到一个 LED 指示灯来表示我们的输出结果,二个 KEY 按键当我们的输入 A 和 B :
接下来就该查看 逻辑派 的原理图,看看我们的按键、LED 用到那个 I/O 口。
输入端 A 和 B ,如下所示:
输出端 X ,如下所示:
信号 | 方向 | 引脚 | 端口作用 | 电平标准 |
---|---|---|---|---|
A | input | F10 | 输入 | LVCMOS33 |
B | input | D11 | 输入 | LVCMOS33 |
X | output | R7 | 输出 | LVCMOS33 |
Gowin 的 I/O 配置如下图所示:
接下来在过程管理窗口 Process > Place & Route > Run,来对代码布局布线进行综合,如下图所示:
再点击 tools -> Shematic Viewer -> RTL Design Viewer 然后查看 RTL 电路图,如下图所示:
在软件与门(红色框)是怎样的,如下图所示:
是不是和 与门逻辑符号 一样,我们接下来,下载程序试试~:
接下来我们动手操作了,按下 A 或者 按下 B ,RGB灯 是无法点亮,我们同时按下 A 和 B ,此时 RGB 灯亮起来了,是不是和我们列的真值表一致,实际位置图如下所示:
2、或门
2.1、符号
或门(OR gate),又称逻辑和电路。只要输入中有一个为高电平(逻辑1)时,输出就为高电平(逻辑1);只有当输入都为低电平(逻辑0)时,输出才为低电平(逻辑0)。
2.2、或门真值表
输入 A | 输入 B | 输出 X(A | B) |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
2.3、或门波形图
2.4、或门 程序编写
仿真文件 logical_mod.v 例程如下所示:
`timescale 1ns / 1ns // 设置时间单位为1纳秒,时间精度为1纳秒
module logical_or_mod(); // 模块定义,名称为 logical_or_mod
//reg define
reg A; // 定义 A,作为输入信号
reg B; // 定义 B,作为输入信号
//wire define
wire X; // 定义 X,用于逻辑或运算的输出
initial begin
A = 1'b0; // 将寄存器 A 初始化为 0
B = 1'b0; // 将寄存器 B 初始化为 0
#200; // 等待 200 纳秒
A = 1'b0; // 将 A 设置为 0
B = 1'b1; // 将 B 设置为 1
#200; // 等待 200 纳秒
A = 1'b1; // 将 A 设置为 1
B = 1'b0; // 将 B 设置为 0
#200; // 等待 200 纳秒
A = 1'b1; // 将 A 设置为 1
B = 1'b1; // 将 B 设置为 1
#200; // 等待 200 纳秒
end
// 例化
logical_or u_logical_or(
.A(A), // 输入 A
.B(B), // 输入 B
.X(X) // 输出 X,逻辑或运算结果
);
endmodule // 模块结束
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
第 1 行 :时间尺度预编译指令 时间单位/时间精度,第一个 1ns 是时间单位,第二个 1ns 是时间精度。
第 3 行:定义了仿真模块名称。
第 11 ~ 27 行:使用 initial 语句块进行输入信号的初始化,在初始化时对各输入端口数据进行固定。先将 A 和 B 赋 0,等待 200 ns后, A 保存不变 B 赋 1,等待 200 ns后,将 A 赋 1 ,B 赋 0,等待 200 ns后,将 A 和 B 赋 1 ,最后等待 200 ns。
第 30 ~ 34 行:对我们的 logical_or.v 文件进行一个绑定。
logical_or.v 文件
module logical_or(
input A, //输入 A
input B, //输入 B
output X //输出 X
);
assign X = A | B; //将输入 A | B 的结果直接赋值给 输出 X
endmodule
2
3
4
5
6
7
8
9
10
11
- 第 1 行和第 11 行是 Verilog 语言中模块定义的标准语句,分别表示模块的开始和结束。第 1 行 module 后的 logical_or() 是模块名称,它应与 Verilog 工程的命名保持一致。
- 第 2 ~ 7 行:定义 输入 和 输出 端口 。
- 第 9 行:将输入 A | B 的结果直接赋值给 输出 X
2.5、工程创建
开始使用 Gowin 创建项目工程了,芯片选型如下所示:
接着在 Gowin 的 Design 窗口空白地方右键点击选择 New Files... 添加文件。如下图所示:
会弹出新建文件的的对话框,如下图所示:
选择创建 Verilog File 文件,选择 OK 按钮,接下来该对这个新建的 Verilog 文件进行命名,工程名叫 logical_or.v(默认路径即可,例如:xx\logical\logical_or\pro\src\),命名完毕后选择 OK 按钮,如下所示:
接下来继续用 Gowin 创建仿真文件 logical_or_mod.v
(注:我们的仿真文件(xx_mod.v)是存放在 sim
文件夹中,其路径需要修改为:xx\logical\logical_or\sim\ 里面)记得改路径~,保存文件哦~,仿真文件记得失能,如下图所示:
添加完对应程序后,然后开始仿真,新建工程将 Project_Name 和 Default Library Name 都改成 logical_or 名称,如下图所示:
添加我们仿真所需的文件 logical_or.v 和 logical_or_mod.v,如下图所示:
鼠标选中其中一个右击 -> 选择 Compile->Compile All ,如下图所示:
鼠标在空白地方右击 -> 选择 Add to Project -> Simulation Configuration ,如下图所示:
在 Add Simulation Configuration 配置好对应的文件,如下图所示:
仿真结果如下:
由上面的仿真图,可以看出与我们的真值表所列出的来结果是一致的,证明我们的程序没有问题
2.6、上板验证
回到 Gowin 软件,由于我们 逻辑派 的 按键 按下为 低电平,和 RGB 灯如果要电亮的话需要 低电平 与我们结果存在 差异 ,我们这里修改程序(别忘记保存哦~),例程如下所示:
module logical_or(
input A, //输入 A
input B, //输入 B
output X //输出 X
);
assign X = ~((~A) | (~B)); //将输入 A | B 的值取反,再将整体取反后结果直接赋值给 输出 X
endmodule
2
3
4
5
6
7
8
9
10
11
12
接下来我们该配置 I/O 引脚了,这里我们需要用到一个 LED 指示灯来表示我们的输出结果,二个 KEY 按键当我们的输入 A 和 B : 接下来就该查看 逻辑派 的原理图,看看我们的按键、LED 用到那个 I/O 口。
输入端 A 和 B ,如下所示:
输出端 X ,如下所示:
信号 | 方向 | 引脚 | 端口作用 | 电平标准 |
---|---|---|---|---|
A | input | F10 | 输入 | LVCMOS33 |
B | input | D11 | 输入 | LVCMOS33 |
X | output | R7 | 输出 | LVCMOS33 |
Gowin 的 I/O 配置如下图所示:
接下来在过程管理窗口 Process > Place & Route > Run,来对代码布局布线进行综合,再点击 tools -> Shematic Viewer -> RTL Design Viewer 然后查看 RTL 电路图,在软件或门(红色框)是怎样的,如下图所示:
是不是和 或门逻辑符号 一样,我们接下来,下载程序试试~:
接下来我们动手操作了,在 A 和 B 都不按下,RGB灯 是无法点亮,按下 A 或者 按下 B ,RGB灯 亮起来了,是不是和我们列的真值表一致,实际位置图如下所示:
3、非门
3.1、符号
非门(NOT gate),又称逻辑否电路。当输入为低电平(逻辑0)时,输出为高电平(逻辑1);当输入为高电平(逻辑1)时,输出为低电平(逻辑0)。
3.2、非门真值表
输入 A | 输出 X |
---|---|
0 | 1 |
1 | 0 |
3.3、非门波形图
3.4、非门 程序编写
仿真文件 logical_mod.v 例程如下所示:
`timescale 1ns / 1ns // 设置仿真时间单位和时间精度为 1 纳秒
module logical_not_mod();
//reg define
reg A; // 输入 A
//wire define
wire X; //输出 X
initial begin
A = 1'b0; // A 为 1
#200;
A = 1'b1; // A 为 0
#200;
end
logical_not u_logical_not(
.A(A), //输入 A
.X(X) //输出 X
);
endmodule
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
第 1 行 :时间尺度预编译指令 时间单位/时间精度,第一个 1ns 是时间单位,第二个 1ns 是时间精度。
第 3 行:定义了仿真模块名称。
第 10 ~ 18 行:使用 initial 语句块进行输入信号的初始化,在初始化时对各输入端口数据进行固定。先将 A 赋 0,等待 200 ns后,将 A 赋 1,等待 200 ns后。
第 21 ~ 25 行:对我们的 logical_not.v 文件进行一个绑定。
logical_not.v 文件
module logical_not(
input A, //输入 A
output X //输出 X
);
assign X = ~A ; //将输入 A 直接赋值给 输出 X
endmodule
2
3
4
5
6
7
8
9
10
- 第 1 行和第 10 行是 Verilog 语言中模块定义的标准语句,分别表示模块的开始和结束。第 1 行 module 后的 logical_not() 是模块名称,它应与 Verilog 工程的命名保持一致。
- 第 2 ~ 6 行:定义 输入 和 输出 端口。
- 第 8 行:将输入 A 的结果取反赋值给 输出 X
3.5、工程创建
开始使用 Gowin 创建项目工程了,芯片选型如下所示:
接着在 Gowin 的 Design 窗口空白地方右键点击选择 New Files... 添加文件。如下图所示:
会弹出新建文件的的对话框,如下图所示:
选择创建 Verilog File 文件,选择 OK 按钮,接下来该对这个新建的 Verilog 文件进行命名,工程名叫 logical_not.v(默认路径即可,例如:xx\logical\logical_not\pro\src\),命名完毕后选择 OK 按钮,如下所示:
接下来继续用 Gowin 创建仿真文件 logical_not_mod.v (注:我们的仿真文件(xx_mod.v)是存放在 sim 文件夹中,其路径需要修改为:xx\logical\logical_not\sim\ 里面)记得改路径~,保存文件哦~,仿真文件记得失能,如下图所示:
添加完对应程序后,然后开始仿真,新建工程将 Project_Name 和 Default Library Name 都改成 logical_not 名称,如下图所示:
添加我们仿真所需的文件 logical_not.v 和 logical_not_mod.v,如下图所示:
鼠标选中其中一个右击 -> 选择 Compile->Compile All ,如下图所示:
鼠标在空白地方右击 -> 选择 Add to Project -> Simulation Configuration ,如下图所示:
在 Add Simulation Configuration 配置好对应的文件,如下图所示:仿真结果如下:
由上面的仿真图,可以看出与我们的真值表所列出的来结果是一致的,证明我们的程序没有问题。3.6、上板验证
开始使用 Gowin 软件,这里就不在详细讲述了。 接下来我们该配置 I/O 引脚了,这里我们需要用到一个 LED 指示灯来表示我们的输出结果,一个 KEY 按键当我们的输入 A : 接下来就该查看 逻辑派 的原理图,看看我们的按键、LED 用到那个 I/O 口。
输出端 X ,如下所示:
信号 | 方向 | 引脚 | 端口作用 | 电平标准 |
---|---|---|---|---|
A | input | F10 | 输入 | LVCMOS33 |
X | output | R7 | 输出 | LVCMOS33 |
Gowin 的 I/O 配置如下图所示:
接下来在过程管理窗口 Process > Place & Route > Run,来对代码布局布线进行综合,再点击 tools -> Shematic Viewer -> RTL Design Viewer 然后查看 RTL 电路图,在软件非门(红色框)是怎样的。
一个非门 RTL 电路如下图所示:
是不是与 非门逻辑符号 一样,我们接下来,下载程序试试~:
接下来我们动手操作了,按下 A ,RGB灯 是无法点亮,按键 A 没有按下,RGB灯亮起来了,是不是和我们列的真值表一致,实际位置图如下所示:
至此,我们的基础逻辑门电路到处结束,希望大家能够多多练习,创建工程和仿真。