一、任务要求
一. 在线Verilog编程网站学习:
https://hdlbits.01xz.net/wiki/Main_Page HDLBits — Verilog Practice 在线练习网站
(参考HDLBits 中文导学 https://zhuanlan.zhihu.com/c_1131528588117385216)
从门电路、组合电路、时序电路中各选3个以上的例题进行实践练习,并记录结果(包括初学时发生的错误)。
二.
1)首先安装Logisim软件,新建一个项目,采用门电路组合电路方式完成一个1位全加器的设计,并在Logisim中进行测试。然后封装这个1位全加器为自定义的一个子电路模块(比如名称为OneAdder),然后新建一个项目,用1位全加器串行级联方式完成一个4位全加器的设计,并进行功能测试。
2)首先基于Quartus 软件完成一个1位全加器的设计。分别采用原理图输入以及 Verilog编程 这两种设计方法。然后通过4个1位全加器的串行级联,完成一个4位全加器的 原理图设计;再改用 Verilog编程(3种模式:门电路、数据流和行为级描述),完成这个4位全加器设计,并观察Verilog代码编译综合后生成的 RTL电路,与之前电路图设计的4位全加器电路进行对比 。
二、在线Verilog编程网站学习
1、AND门
创建一个实现AND门的模块。
该电路现在有三条导线(a、b和out)。导线a和b已经具有由输入端口驱动到它们上的值。但目前的退出并不是由任何事情驱动的。写一个assign语句,用信号a和b的AND进行驱动。
请注意,这个电路与NOT门非常相似,只是多了一个输入。如果这听起来不一样,那是因为我已经开始将信号描述为被驱动的(已知值由附加的东西决定)或不被驱动的。输入线由模块外的东西驱动。assign语句将把逻辑级别驱动到连线上。正如您所料,一条线路不能有多个驱动程序(如果有,它的逻辑级别是多少?),而一条没有驱动程序的线路将有一个未定义的值(在合成硬件时通常被视为0)。
解决方案
module top_module(
input a,
input b,
output out );
assign out=a&&b;
endmodule
2、XNOR门
创建一个实现XNOR门的模块。
解决方案
module top_module(
input a,
input b,
output out );
assign out = ~(a^b);
endmodule
3、NOR门
创建一个实现NOR门的模块。NOR门是一种输出反向的OR门。用Verilog编写NOR函数时需要两个运算符。
assign语句用一个值驱动一个连接(或更正式地称为“net”)。这个值可以是一个复杂的函数,只要它是一个组合函数(即无内存、无隐藏状态)。assign语句是一个连续赋值,因为每当它的任何输入永远改变时,输出都会被“重新计算”,就像一个简单的逻辑门一样。
解决方案
module top_module(
input a,
input b,
output out );
assign out =~( a||b);
endmodule
三、Logisim 的全加器实现
3.1 1位全加器
1、打开logisim,选择需要用的各种门(异门 × 2、与门 × 2、或门 × 1)
2、按照图片连接线路
3、点击进行功能测试
3.2 4位全加器
1、封装
2、添加一个新的项目
3、直接用鼠标把1位全加器拉入新电路
4、按照图片连接
5、测试
我们运算一下0001+0001,也就是每个四位输入都点亮最下面的输入
可以看到0001+0001的运算结果是0010,正确
四、Quartus 的全加器的实现
4.1、原理图方式
1位全加器
1、创建工程
填写信息
一直next到最后点击finish
2、添加原理图
打开器件库
添加输入输出
获取所需器件并按照图示连接线路
保存
编译
等待编译完成
查看原理图
创建VWF文件
选中直线修改
开始仿真
结果正确
若仿真失败,进行仿真配置,选择tool->launch simulation library complier
4位全加器
1、封装1位全加器
可在器件库中选择使用
然后新建一个项目
按照图示选择器件和连接线路
将文件置于顶层,开始编译
查看电路图
创建波形图并验证1110+1010
结果为1000,答案正确。
4.2、Verilog编程
1、1位全加器
module Verilog2 (
input A, B, Cin,
output Sum, Cout
);
wire X1, X2, X3, X4;
// XOR gates
assign X1 = A ^ B;
assign X2 = X1 ^ Cin;
// AND gates
assign X3 = A & B;
assign X4 = X1 & Cin;
// OR gates
assign Sum = X2;
assign Cout = X3 | X4;
endmodule
开始仿真,验证一下1110+1010
结果正确
2、4位全加器
(1)行为级
module Verilog2(
input [3:0] A,
input [3:0] B,
input Cin,
output [3:0] Sum,
output Cout
);
reg [3:0] Sum_int;
reg Cout_int;
always @(A or B or Cin)
begin
Sum_int = A + B + Cin;
Cout_int = (A[3] & B[3]) | (B[3] & Cin) | (Cin & A[3]);
end
assign Sum = Sum_int;
assign Cout = Cout_int;
endmodule
查看电路图
(2)门电路
module Verilog3(
input [3:0] A,
input [3:0] B,
input Cin,
output [3:0] Sum,
output Cout
);
// Internal signals
wire [3:0] X1, X2, X3, X4, X5;
wire Cout_int;
// XOR gates for Sum bits
assign X1 = A ^ B;
assign X2 = X1 ^ Cin;
assign Sum = X2;
// AND gates for carry generation
assign X3 = A & B;
assign X4 = B & Cin;
assign X5 = Cin & A;
// OR gate for Cout generation
assign Cout_int = X3 | X4 | X5;
assign Cout = Cout_int;
endmodule
(3)数据流
module Verilog4(
input [3:0] A,
input [3:0] B,
input Cin,
output [3:0] Sum,
output Cout
);
// Dataflow-style description using assignments
assign Sum = A + B + Cin;
assign Cout = (A[3] & B[3]) | (B[3] & Cin) | (Cin & A[3]);
endmodule
五、学习心得
在1位全加器的设计中,我首先通过原理图输入方法完成了设计。这一步骤相对直观,主要是通过拖拽和连接各种逻辑门来实现全加器的功能。随后,我又采用Verilog编程方法重新实现了同样的功能。与原理图输入相比,Verilog编程更为灵活,但也更加抽象,需要对硬件描述语言有一定的了解。
进入4位全加器的设计环节,我先是通过4个1位全加器的串行级联,在原理图中完成了设计。这个过程让我对全加器的工作原理和级联方式有了更深入的理解。接着,我使用Verilog编程的三种模式:门电路、数据流和行为级描述,再次实现了4位全加器。每一种模式都有其独特的编程风格和思路,让我对Verilog的多样性和灵活性有了更深的体会。
在实验过程中,我遇到了不少挑战。例如,在编写Verilog代码时,由于语法细节和逻辑错误,导致编译失败或者功能不正确。但通过反复检查和调试,以及参考相关资料和向同学请教,我逐渐克服了这些困难。
这次实验让我深刻体会到了理论与实践相结合的重要性。通过亲手操作和实践,我不仅掌握了全加器设计的基本方法和技术,还对硬件描述语言和数字电路设计有了更深入的了解。同时,我也意识到了学习过程中的交流与合作的重要性。在遇到问题和困难时,与他人共同探讨、互相帮助,往往能够更快地找到解决问题的方法。
六、参考资料
1、https://blog.csdn.net/qq_43279579/article/details/115480406
2、https://blog.csdn.net/m0_74045503/article/details/134960936