用Verilog HDL的三种建模方式描述——2选1数据选择器
1,数据选择器的定义和功能
数据选择是指经过选择,把多路数据中的某一路传送到公共数据线上,实现数据选择功能的逻辑电路称为数据选择器。它的作用相当于多输入的单刀多掷开关。
2,集成电路数据选择器
常用的集成电路数据选择器有许多种类,并且有COMS和TTL产品。例如,四2选1数据选择器74x157、双4选1数据选择器74x153、8选1数据选择器74x151等。
还有一些数据选择器具有三态输出功能,例如以上述产品相对应具有三态输出功能的有74x257、74x253、74x251。除了正常的0或1输出外,当低电平使能输入端/E为1时,输出为高阻状态。利用这一特点,可以将多个芯片的输出端线与在一起,共用一根数据传输线,而不会存在负载效应问题。
3,实例练习(2选1数据选择器)
该数据选择器有两个输入信号(a和b)和一个控制输入(sel),一个输出(out)。当sel为1的时候out选择a,当sel为0的时候out选择b。首先列出真值表。
简单的表达:
图(1)
具体化:
图(2)
根据真值表写出逻辑函数表达式:
图(3)
化简后:
图(4)
根据逻辑表达式画出电路图:
图(5)
3.1 用门级原语描述。
1 //Gate-level description of 2-to-1-line multiplexer
2 module mux2to1_GL(
3 a,b,sel,
4 out
5 );
6
7 input a,b,sel;
8 output out;
9
10 wire nsel,a1,b1; //定义中间变量
11
12 not U1(nsel,sel);
13 and U2(b1,b,nsel);
14 and U3(a1,a,sel);
15 or U4(out,a1,b1);
16
17 endmodule
18
第12~15行采用了门级原语,用到了最基础的与、或、非门。
编译后,看一下它综合之后的RTL视图:
图(6)
可以跟之前画的比较一下,看是不是一样的。
编写testbench,验证其功能是否正确,或则用其自带的仿真工具也行。
我用的是QII 9.1,在源代码编写完以后,写testbench和仿真的步骤大概是这样的:
Processing > Start > Start Test Bench Template Writer,它就会自动生成一个模板并且自动的将顶层的.V文件进行例化
图(7)
点击打开文件的图标,在工程存放的目标文件夹下的modelsim文件夹里打开.VT文件。
图(8)
在.VT下可以看到一些它跟你做好的东西,删除一些你不要的东西,编写你的测试代码。
1 `timescale 1 ps/ 1 ps
2 module mux2to1_GL_vlg_tst();
3
4 reg a;
5 reg b;
6 reg sel;
7 // wires
8 wire out;
9
10 // assign statements (if any)
11 mux2to1_GL i1 (
12 // port map - connection between master ports and signals/registers
13 .a(a),
14 .b(b),
15 .out(out),
16 .sel(sel)
17 );
18
19 initial
20 begin
21 a = 0;
22 b = 0;
23 sel = 0;
24 end
25
26 always
27 begin
28 #40 a = 1;
29 #40 a = 0;
30 end
31
32 always
33 begin
34 #20 b = 1;
35 #20 b = 0;
36 #20 b = 1;
37 #20 b = 0;
38 end
39
40 always
41 begin
42 #80 sel = 1;
43 #80 sel = 0;
44 end
45
46 endmodule
保存,编译。在仿真之前先要设置一下,Assignment > EDA Tool Settings
图(9)
在弹出的窗口下点击Simulation,在NativeLink setting下,选择Compile test bench标签,单击Test Benches按钮
图(10)
这几个名字分清楚,Test Bench Name 就是测试脚本的名字在这里是:mux2to1_GL,Top Level Module in text bench 是在测试脚本中顶层模块的名字在这里是mux2to1_GL_vlg_tst,Design instance name in text bench 就是在测试脚本中例化的名字在本例中是:i1。然后添加文件,再直接点击3个OK,
图(11)
仿真,Tools -> Run EDA Simulation -> EDA RTL Simulatiom。
图(12)
可以看到仿真波形和我们设计的是一样的,当sel为0时,输出out的波形跟b的波形一致,当sel为1时,输出out的波形跟a的一致。
图(13)
下面就可以分配引脚,下载到板子上。
在仿真之前还有一个ModelSim-Altera路径的设置,选择Tools>Options>General>EDA Tool Options,看你的Modelsim安装在哪里,你就改在哪里。
3.2 用数据流来描述
1 //Dataflow description of 2-to-1-line multiplexer
2 module Mux2to1_DF(
3 a,b,sel,
4 out
5 );
6
7 input a,b,sel;
8 output out;
9
10 assign out = (a&sel) |(b&(~sel)); //out = sel ? a : b;
11
12 endmodule
13
我觉得assign后面的两种写法都行,当然仿真的结果是一样的。但是写out = (a&sel) |(b&(~sel));时综合后生成的RTL和前面一样,而用out = sel ? a : b; 时综合后生成的RTL的视图:
图(14)
它直接就是一数据选择器,而没有综合成最基本的门电路,还得想一下这是什么原因。
3.3 用行为级描述
1 //Behavioral description of 2-to-1-line multiplexer
2 module Mux2to1_BH(
3 a,b,sel,
4 out
5 );
6
7 input a,b,sel;
8 output out;
9 reg out;
10
11 always @ (*)
12 begin
13 if(sel == 1'b1)
14 out = a;
15 else
16 out = b;
17 end
18
19 endmodule
综合之后的RTL视图如图(14).
功能仿真的效果跟前面一样,RTL却出现了两种电路图,内部应该是一样的,但为什么就以两种形式表示出来呢?不是太清楚。