这次主要学习的是数据选择器,从最简单的二选一数字选择器开始,主要是熟悉一下大致的流程,练习一下verilog语法结构
1.第一步呢首先就是分析一下数据选择器的功能,要是实现什么样的效果,对二选一数字选择器有一个大致的思路,还是从上一次的步骤开始。
首先建立一个文件夹文价夹命名为mxu2_1,在此文件夹下面建立四个文件夹,分别命名为dox、quartus_prj、rtl和sim。它们分别对应的作用是
(1)doc 主要放置一些此工程用到的一些资料或者自己绘制的波形图文件等等
(2)quartus_prj 主要放置quartus工程项目文件,如果是其他的编译软件也可以换成其他的名字
(3)rtl 主要放最后生成硬件电路的代码
(4)sim 放置波形仿真文件,如test 测试文件
接下来要做的就是画波形图,用visio绘制出二选一数字选择器的输入输出波形图,只有绘制出波形图,后续才能根据波形图进行编程序。
2.在rtl文件夹中新建一个 .v 文件,在此文件里面进行编写二选一数字选择器的代码,根据波形图很容易编写出代码,简单说一下在此次代码编写中用到的语句
(1)首先是整体的框架
module 文件名
(
输入输出,区分wire和reg型
);
always@(*) *表示所有的条件成立也可以换成其他的形式
endmodule
(2)分支语句学习
①if分支语句
if(条件)
begin
end
else if(条件)
begin
end
else
begin
end
一般if语句的分支形式都如此,其中else if()可以多次添加,但是当分支特别多的时候不建议使用此分支,用下面的case语句较好
②case分支语句
case(条件)
1’b1: 运行程序;
1‘b0: 运行程序;
default:运行程序;
endcase
3.在完成了选择器的代码编写之后,接下啦就是quartus工程的建立,包括芯片的选型、文件的添加、仿真软件的设置以及一些其余的配置。
4.接下来就是编写测试代码程序了,主要hi测试一些我们编写的选择器代码的程序出来的波形与我们想要实现的波形是否一致,如果满足要求了才能进行下一步的下载实验。
(1)整体的框架
`timescale 1ns/1ns 主要表示测试的时间时间尺度与时间精度
module 文件名();
reg 输入类型
wire 输出类型
initial
begin
初始化程序,先给输入一个初始值
end
运行程序:想要实现什么样的结果
mux2_1 mux2_1_inst
( //第一个是被实例化模块的名子,第二个是我们自己定义的在另一个模块中实例化后的名字。同一个模块可以在另一个模块中或不同的另外模块中被多次实例化,第一个名字相同,第二个名字不同
.in1(in1), //input in1,前面的“in1”表示被实例化模块中的信号,后面的“in1”表示实例化该模块并要和这个模块的该信号相连接的信号(可以取名不同,一般取名相同,方便连接和观察),“.”可以理解为将这两个信号连接在一起
.in2(in2), //input in2
.sel(sel), //input sel
.out(out) //output out
);
简单来说就是前面的是编写的模块输入输出,后面的是测试模块的输入输出
(2)打印语句
$timeformat(-9, 0, “ns”, 6); //设置显示的时间格式,此处表示的是(打印时间单位为纳秒,小数点后打印的小数位为0位,时间值后打印的字符串为“ns”,打印的最小数量字符为6个)
$monitor("@time %t: in1=%b in2=%b sel=%b out=%b", $time, in1, in2, sel, out); //只要监测的变量(时间、in1, in2, sel, out)发生变化,就会打印出相应的信息
5.最后使用quartus与modelsim进行联合仿真,观察输出结果正确下载测试,错误就返回程序进行修改。
测试代码
`timescale 1ns/1ns
module tb_mux2_1();
reg in1;
reg in2;
reg sel;
wire out;
initial
begin
in1 <= 1'b0;
in2 <= 1'b0;
sel <= 1'b0;
end
initial
begin
$timeformat(-9, 0, "ns", 6);
/*设置显示的时间格式,此处表示的是
(打印时间单位为纳秒10的-9次方,小数点后打印的小数位为0位,
时间值后打印的字符串为“ns”即10的-9次方,打印的最小数量字符为6个*/
$monitor("@time %t: in1=%b in2=%b sel=%b out=%b", $time, in1, in2, sel, out);
//只要监测的变量(时间、in1, in2, sel, out)发生变化,就会打印出相应的信息
end
always #10 in1 = {$random} % 2;//取模求余数,产生非负随机数0、1,每隔10ns产生一次随机数
always #10 in2 = {$random} % 2;
always #10 sel = {$random} % 2;
mux2_1 mux2_1_inset
(
.in1(in1),
.in2(in2),
.sel(sel),
.out(out)
);
endmodule
程序代码
module mux2_1
(
input wire [0:0] in1,
input wire in2,
input wire sel,
output reg out
);
always@(*)
begin
case(sel)
1'b1: out = in1;
1'b0: out = in2;
default:out = in1;
endcase
end
endmodule