多种基本门电路的IP核
实验目的
通过实验,进一步熟悉使用 vivado 进行可配置 IP 核设计的方法,对各种门电路的逻辑 有更加感性的认识,同时也为今后的实验以及后续的课程积累基本的门电路 IP 核。
实验内容
仿照 2.1.2 节的设计方法,使用 Verilog HDL 语言的数据流描述法设计下列各种 1~32 位 数据宽度可变的基本门电路,出了非门外,其他门电路还要求输入端口了在 2-8 之间变化, 最后将它们分别封装成IP核。一定要注意不同门电路的各个端口在disable时候的取值Driver value 的设定,要用一个合理的值。 需要完成的 IP 核及相关参数如表 2-2 所示。
表 2-2 中的各个门电路的 IP 核封装好后,统一拷贝到D:\vivado_pro \orgnization 中,并分别解压这些.zip 文件,如图 1-75 所示。
1 或门
orgate.v文件:
`timescale 1ns / 1ps
module orgate
#(parameter Port_Num = 2, // 指定缺省的输入是2个输入端口
parameter WIDTH = 8) // 指定数据宽度参数,缺省值是8
(
input [(WIDTH - 1) : 0] a,
input [(WIDTH - 1) : 0] b,
input [(WIDTH - 1) : 0] c,
input [(WIDTH - 1) : 0] d,
input [(WIDTH - 1) : 0] e,
input [(WIDTH - 1) : 0] f,
input [(WIDTH - 1) : 0] g,
input [(WIDTH - 1) : 0] h,
output [(WIDTH - 1) : 0] q
);
assign q = (a | b | c | d | e | f | g | h);
endmodule
orgate_sim.v文件:
`timescale 1ns / 1ps
module orgate_sim();
// input
reg a = 0;
reg b = 0;
reg c = 0;
reg d = 0;
reg e = 0;
reg f = 0;
reg g = 0;
reg h = 0;
// output
wire q;
// 实例化或门的时候,设定宽度为1
orgate #(8, 1) u(
.a(a),
.b(b),
.c(c),
.d(d),
.e(e),
.f(f),
.g(g),
.h(h),
.q(q)
);
initial begin
#100 a = 1;
#100 begin a = 0; b = 1; end
#100 a = 0;
#100 a = 1;
end
endmodule
orgate_sim32.v文件:
module orgate32_sim( );
// input
reg [31:0] a=32'h00000000;
reg [31:0] b=32'h00000000;
reg [31:0] c=32'h00000000;
reg [31:0] d=32'h00000000;
reg [31:0] e=32'h00000000;
reg [31:0] f=32'h00000000;
reg [31:0] g=32'h00000000;
reg [31:0] h=32'h00000000;
//outbut
wire [31:0] q;
orgate #(8,32) u(.a(a),.b(b),.c(c),.d(d),
.e(e),.f(f),.g(g),.h(h),.q(q)); // 实例化的时候,设定宽度为32
initial begin
#100 a=32'hff78dff;
#100 begin a=32'h00000000;b=32'hffff8b0;end
#100 a = 32'h007fa509;
#100 a=32'hffffffff;
end
endmodule
图 1-59 创建ordgate项目
图 1-61 32位 8 输入或门的仿真波形
2 非门
notgate.v文件:
`timescale 1ns / 1ps
module notgate
#(parameter WIDTH = 8) // 指定数据宽度参数,缺省值是8
(
input [(WIDTH - 1) : 0] a,
output [(WIDTH - 1) : 0] c
);
assign c = ~a;
endmodule
notgate_32sim.v文件:
`timescale 1ns / 1ps
module notgate32_sim();
// input
reg [31:0] a = 32'h00000000;
// output
wire [31:0] c;
// 实例化非门的时候,设定宽度为32
notgate #(32) u(
.a(a),
.c(c)
);
initial begin
#100 a = 32'hffffffff;
#100 a = 32'h00000000;
#100 a = 32'h007fa509;
#100 a = 32'hffffffff;
end
endmodule
图 1-62创建notgate项目
图 1-63 32位 8 输入非门的仿真波形
3 与非门
nandgate.v文件:
`timescale 1ns / 1ps
module nandgate
#(parameter Port_Num = 2, // 指定缺省的输入是2个输入端口
parameter WIDTH = 8) // 指定数据宽度参数,缺省值是8
(
input [(WIDTH - 1) : 0] a,
input [(WIDTH - 1) : 0] b,
input [(WIDTH - 1) : 0] c,
input [(WIDTH - 1) : 0] d,
input [(WIDTH - 1) : 0] e,
input [(WIDTH - 1) : 0] f,
input [(WIDTH - 1) : 0] g,
input [(WIDTH - 1) : 0] h,
output [(WIDTH - 1) : 0] q
);
assign q = ~(a & b & c & d & e & f & g & h);
endmodule
nandgate32_sim文件:
`timescale 1ns / 1ps
module nandgate32_sim();
// input
reg [31:0] a = 32'h00000000;
reg [31:0] b = 32'h00000000;
reg [31:0] c = 32'hffffffff;
reg [31:0] d = 32'hffffffff;
reg [31:0] e = 32'hffffffff;
reg [31:0] f = 32'hffffffff;
reg [31:0] h = 32'hffffffff;
reg [31:0] g = 32'hffffffff;
// output
wire [31:0] q;
// 实例化与非门的时候,设定宽度为32
nandgate #(8, 32) u(
.a(a),
.b(b),
.c(c),
.d(d),
.e(e),
.f(f),
.g(g),
.h(h),
.q(q)
);
initial begin
#100 a = 32'hffffffff;
#100 begin
a = 32'h00000000;
b = 32'hffffffff;
end
#100 a = 32'h007fa509;
#100 a = 32'hffffffff;
end
endmodule
图 1-64创建nandgate项目
图 1-65 1 位 8 输入与非门的仿真波形
图 1-66 32 位 8 输入与非门的仿真波形
4 或非门
norgate.v文件:
`timescale 1ns / 1ps
module norgate
#(parameter Port_Num = 2, // 指定缺省的输入是2个输入端口
parameter WIDTH = 8) // 指定数据宽度参数,缺省值是8
(
input [(WIDTH - 1) : 0] a,
input [(WIDTH - 1) : 0] b,
input [(WIDTH - 1) : 0] c,
input [(WIDTH - 1) : 0] d,
input [(WIDTH - 1) : 0] e,
input [(WIDTH - 1) : 0] f,
input [(WIDTH - 1) : 0] g,
input [(WIDTH - 1) : 0] h,
output [(WIDTH - 1) : 0] q
);
assign q = ~(a | b | c | d | e | f | g | h);
endmodule
norgate32_sim.v文件:
`timescale 1ns / 1ps
module norgate32_sim();
// input
reg [31:0] a = 32'h00000000;
reg [31:0] b = 32'h00000000;
reg [31:0] c = 32'h00000000;
reg [31:0] d = 32'h00000000;
reg [31:0] e = 32'h00000000;
reg [31:0] f = 32'h00000000;
reg [31:0] h = 32'h00000000;
reg [31:0] g = 32'h00000000;
// output
wire [31:0] q;
// 实例化或非门的时候,设定宽度为32
norgate #(8, 32) u(
.a(a),
.b(b),
.c(c),
.d(d),
.e(e),
.f(f),
.g(g),
.h(h),
.q(q)
);
initial begin
#100 a = 32'hffffffff;
#100 begin
a = 32'h00000000;
b = 32'hffffffff;
end
#100 begin
a = 32'h007fa509;
b = 32'h00000000;
end
#100 a = 32'hffffffff;
end
endmodule
图 1-67创建norgate项目
图 1-68 1 位 8 输入或非门的仿真波形
图 1-69 32位 8 输入或非门的仿真波
5 异或门
xorgate.v文件:
`timescale 1ns / 1ps
module xorgate
#(parameter Port_Num = 2, // 指定缺省的输入是2个输入端口
parameter WIDTH = 8) // 指定数据宽度参数,缺省值是8
(
input [(WIDTH - 1) : 0] a,
input [(WIDTH - 1) : 0] b,
input [(WIDTH - 1) : 0] c,
input [(WIDTH - 1) : 0] d,
input [(WIDTH - 1) : 0] e,
input [(WIDTH - 1) : 0] f,
input [(WIDTH - 1) : 0] g,
input [(WIDTH - 1) : 0] h,
output [(WIDTH - 1) : 0] q
);
assign q = (a ^ b ^ c ^ d ^ e ^ f ^ g ^ h);
endmodule
xorgate32_sim.v文件:
`timescale 1ns / 1ps
module xorgate32_sim();
// input
reg [31:0] a = 32'h00000000;
reg [31:0] b = 32'h00000000;
reg [31:0] c = 32'h00000000;
reg [31:0] d = 32'h00000000;
reg [31:0] e = 32'h00000000;
reg [31:0] f = 32'h00000000;
reg [31:0] h = 32'h00000000;
reg [31:0] g = 32'h00000000;
// output
wire [31:0] q;
// 实例化异或门的时候,设定宽度为32
xorgate #(8, 32) u(
.a(a),
.b(b),
.c(c),
.d(d),
.e(e),
.f(f),
.g(g),
.h(h),
.q(q)
);
initial begin
#100 a = 32'hffffffff;
#100 begin
a = 32'h00000000;
b = 32'hffffffff;
end
#100 a = 32'h007fa509;
#100 a = 32'hffffffff;
end
endmodule
图 1-70创建xorgate项目
图 1-71 1 位 8 输入异或门的仿真波形
图 1-72 32 位 8 输入异或门的仿真波形
6 异或非门
nxorgate.v文件:
`timescale 1ns / 1ps
module nxorgate
#(parameter Port_Num = 2, // 指定缺省的输入是2个输入端口
parameter WIDTH = 8) // 指定数据宽度参数,缺省值是8
(
input [(WIDTH - 1) : 0] a,
input [(WIDTH - 1) : 0] b,
input [(WIDTH - 1) : 0] c,
input [(WIDTH - 1) : 0] d,
input [(WIDTH - 1) : 0] e,
input [(WIDTH - 1) : 0] f,
input [(WIDTH - 1) : 0] g,
input [(WIDTH - 1) : 0] h,
output [(WIDTH - 1) : 0] q
);
assign q = ~(a ^ b ^ c ^ d ^ e ^ f ^ g ^ h);
endmodule
nxorgate32_sim.v文件:
`timescale 1ns / 1ps
module nxorgate32_sim();
// input
reg [31:0] a = 32'h00000000;
reg [31:0] b = 32'h00000000;
reg [31:0] c = 32'h00000000;
reg [31:0] d = 32'h00000000;
reg [31:0] e = 32'h00000000;
reg [31:0] f = 32'h00000000;
reg [31:0] h = 32'h00000000;
reg [31:0] g = 32'h00000000;
// output
wire [31:0] q;
// 实例化异或非门的时候,设定宽度为32
nxorgate #(8, 32) u(
.a(a),
.b(b),
.c(c),
.d(d),
.e(e),
.f(f),
.g(g),
.h(h),
.q(q)
);
initial begin
#100 a = 32'hffffffff;
#100 begin
a = 32'h00000000;
b = 32'hffffffff;
end
#100 a = 32'h007fa509;
#100 a = 32'hffffffff;
end
endmodule
图 1-73创建nxorgate项目
图 1-74 32 位 8 输入异或非门的仿真波形
7 完成结果
图 1-75封装好的 IP 核
五、实验数据记录和处理
1. LED灯仿真代码:
`timescale 1ns / 1ps
module Ex_1_sim(
);
// input
reg [23:0] sw = 24'h000000;
// output
wire [23:0] led;
// instantiate the Unit under test
Ex_1 uut(
.sw(sw),
.led(led)
);
always #10 sw = sw + 1;
endmodule
2. 1位与门仿真代码:
`timescale 1ns / 1ps
module andgate_sim();
// input
reg a = 0;
reg b = 0;
reg c = 1;
reg d = 1;
reg e = 1;
reg f = 1;
reg g = 1;
reg h = 1;
// output
wire q;
// 实例化与门的时候,设定宽度为1
andgate #(8, 1) u(
.a(a),
.b(b),
.c(c),
.d(d),
.e(e),
.f(f),
.g(g),
.h(g),
.q(q)
);
initial begin
#100 a = 1;
#100 begin a = 0; b = 1; end
#100 a = 1;
end
endmodule
3. 32位与门仿真代码:
`timescale 1ns / 1ps
module andgate32_sim();
// input
reg [31:0] a = 32'h00000000;
reg [31:0] b = 32'h00000000;
reg [31:0] c = 32'hffffffff;
reg [31:0] d = 32'hffffffff;
reg [31:0] e = 32'hffffffff;
reg [31:0] f = 32'hffffffff;
reg [31:0] h = 32'hffffffff;
reg [31:0] g = 32'hffffffff;
// output
wire [31:0] q;
// 实例化与门的时候,设定宽度为32
andgate #(8, 32) u(
.a(a),
.b(b),
.c(c),
.d(d),
.e(e),
.f(f),
.g(g),
.h(h),
.q(q)
);
initial begin
#100 a = 32'hffffffff;
#100 begin
a = 32'h00000000;
b = 32'hffffffff;
end
#100 a = 32'h007fa509;
#100 a = 32'hffffffff;
end
endmodule
六、实验结果与分析
-
LED灯仿真波形:
图 1-76 LED灯仿真波形 -
1位与门仿真波形: 图 1-77 1位与门仿真波形文章来源:https://www.toymoban.com/news/detail-764083.html
-
32位与门仿真波形: 图 1-78 32位与门仿真波形文章来源地址https://www.toymoban.com/news/detail-764083.html
七、讨论、心得
- 通过这个实验,学习了vivado软件和verilog硬件描述语言的使用,了解到了硬件程序的设计方法,巩固了设计流程。
- 封装IP核的操作其实和程序设计中的“函数”类似,通过封装IP核,我们可以在其他的工程中直接调用封装好的IP核,这样做可以大大降低我们的工作量。
- 在调用IP核时,需要注意有的没有接上的端口的值应该如何设置。这时候就要考虑我们所设计的器件的逻辑特性,例如设计andgate时,通过1 & A = A的布尔表达式得出,悬空端口设置值为1对结果不受影响,因此我们设置值为1。
- 通过本次实验,了解到封装 IP 核作用就是将一定的功能(例如加法,减法,逻辑运算等)封装起来,之后可以直接运用而不需要每次重新设计。
- 在封装的时候发现不同的 IP 核在设置端口参数时驱动值并不相同,注意到不同门电路的各个端口在 disable 时候的取值 Drivervalue 的设定,要用一个合理的值.
- vivado软件本身的学习
开发的基本流程:仿真、综合、布线、生成比特流、导出到SDK、SDK导出到开发板。想要一个程序在板子上运行,需要硬件(因为是fpga)和软件两部分。
在硬件上,如何让板子知道自己的电路被编成什么样了呢?用的就是vivado导出的比特流。比特流是根据verliog代码综合、布线得出的。其中,综合时把verliog代码转成硬件。布线,是把综合出来的电路映射到开发板上,想一下烧板子的思路。最后根据布线的结果生成比特流,硬件看见简单粗暴的比特流就知道自己应该怎么烧了。
在软件上,用到的是SDK软件编程。基本上是编写c代码的程序,然后SDK软件给你编译成mips,导出到板子上的arm的代码区。就是往内存里写汇编指令。
硬件部分称为PL部分,软件部分称为PS部分。
vivado除了verliog文件外,还有一个叫约束的东西。约束就是指定你自定义的信号对应到物理的哪个部分。比如有个信号a想控制led等亮,如何让vivado知道a控制的是led呢?就要用约束文件,将led与a信号连接起来。这部分比较偏硬件,实验中基本用不上,可以跳过去。
vivado中编写verliog的方法除了徒手编程外,还有一个拖拽连线的方法,diagram。画板就是把已经编好的模块摆到一起,然后将模块间的线连好。加入system的过程也是在画板上完成的。然后verliog可以自动根据连线生成verliog代码。
到了这里,关于VIVADO 工具与 Verilog 语言之与门IP核设计之多种基本门电路的IP核的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!