Verilog-HDL与CPLD/FPGA设计应用讲座
第 7 讲 用Verilog-HDL做CPLD设计
组合逻辑电路的实现
7.1 与非门的实现
7.2 2-1数据选择器的实现
7.3 2位二进制编码器的实现
7.4 1位数据比较器的实现
本讲中,我们通过由浅入深的实例来介绍组合逻辑电路在目标板上是如何实现的。
7.1 与非门的实现
首先,来实现一个用两个开关控制一个灯的设计。期望达到的目的如表1所示。
表1 两个开关控制一个灯的真值表
分析表1可以得到下述结论:如果两个开关S1和S2中,任意有一个为低电平,灯都不亮;只有当两个开关S1和S2同时为高电平时,灯才亮。因此,我们考虑采用与非门来实现设计。图1示出了符合表1的逻辑功能框图。
其中,S1_1和S1_2表示开关,对应表1中的S1和S2,打开时为高电平,闭合时为低电平,作为输入;LED0表示发光二级管,对应表1中的 LED,作为输出;33、34和44为上述变量对应芯片XC9536的引脚;33和34旁边的三角形表示上拉电阻(下文同)。虚线框中的部分是CPLD设计,实现与非门的功能。
根据图1,可以对该电路进行Verilog-HDL描述。
/* 与非门的Verilog-HDL描述*/
module S2_D1 ( S1_1, S1_2, LED0 ); // 模块名及端口定义,范围至endmodule
input S1_1, S1_2; // 输入端口定义,S1_1和S1_2分别对应XC9536的第34和33脚
output LED0; // 输出端口定义,对应XC9536的第44脚
nand U1 ( LED0, S1_1, S1_2 ); // 门级描述语句,实现与非门的功能
endmodule // 模块结束
把以上与非门的Verilog-HDL描述,用Webpack Project Navigator软件,生成目标文件,并通过下载电缆写入芯片XC9536中。然后,将芯片插到目标板上,即可实现用两个开关通过与非门控制一个灯的功能。图2示出了下载过程中出现的引脚配置画面。
图2 两个开关通过与非门控制一个灯的引脚配置画面
7.2 2-1数据选择器的实现
在第五讲中,已经详细地介绍过2-1数据选择器的Verilog-HDL描述方法,并且对其进行了仿真。这里,我们来看一下它是如何在目标板上实现的。
2-1数据选择器的真值表如表2所示。
由表2可以得到下述结论:当SEL=0时,F=A;当SEL=1时,F=B。因此,我们考虑采用如图3所示的逻辑功能框图来实现。
其中,S1_1、S1_2和S1_3表示开关,对应表2中的A、B和SEL,打开时为高电平,闭合时为低电平,作为2-1数据选择器的输入;LED0表示发光二级管,对应表2中的F,作为其输出。29、33、34和44是上述变量对应芯片XC9536的引脚。虚线框中的部分是CPLD设计,实现2-1数据选择器的功能。
根据图3,对该电路进行Verilog-HDL描述。
/* 2-1数据选择器的Verilog-HDL描述*/
module SEL (S1_1, S1_2, S1_3, LED0 ); // 模块名及端口定义,范围至endmodule
input S1_1, S1_2, S1_3; // 输入端口定义,S1_1、S1_2和S1_3分别对应XC9536的第34、33和29脚
output LED0; // 输出端口定义,对应第44脚
assign LED0= ( S1_3 ==0 ) ? S1_1 : S1_2;
// 条件表达式,实现2-1数据选择器的功能。
// 如果S1_3 =0,则LED0= S1_1;否则,LED0= S1_2
endmodule // 模块结束
把以上2-1数据选择器的Verilog-HDL描述,用Webpack Project Navigator软件,生成目标文件,并通过下载电缆写入芯片XC9536中。然后,将芯片放到目标板上,即可实现2-1数据选择器。图4示出了下载过程中出现的引脚配置画面。
7.3 2位二进制编码器的实现
同样,在第五讲中,也已经详细地介绍了2位二进制编码器的Verilog-HDL描述方法,并且对其进行了仿真。这里,也来看一下它是如何在目标板上实现的。
2位二进制编码器的真值表如表3所示。
表3 2位二进制编码器的真值表
分析表3可以得到下述结论:4个输入IN0-IN3在同一时刻只有一个为高电平,而输出Y0-Y1根据不同的状态分别进行编码。因此,可以采用如图5所示的逻辑功能框图来实现。
图5 2位二进制编码器的逻辑功能框图
其中,S1_1、S1_2、S1_3和S1_4表示开关,对应表3中的IN0、IN1、IN2、IN3,打开时为高电平,闭合时为低电平,作为2位二进制编码器的输入;LED0和LED1表示发光二级管,对应表3中的Y0和Y1,作为其输出。28、29、33、34、43和44是上述变量对应芯片 XC9536的引脚。虚线框中的部分是CPLD设计,实现2位二进制编码器的功能。
根据图5,可以对该电路进行Verilog-HDL描述。
/* 2位二进制编码器的Verilog-HDL描述*/
/* Data Definision */ // 数据定义
`define SW_IN0 4'b0001 // 编译时,将SW_IN0转换为4bit的二进制数0001
`define SW_IN1 4'b0010 // 编译时,将SW_IN1转换为4bit的二进制数0010
`define SW_IN2 4'b0100 // 编译时,将SW_IN2转换为4bit的二进制数0100
`define SW_IN3 4'b1000 // 编译时,将SW_IN3转换为4bit的二进制数1000
/* ENCORDER */ // 主模块
module ENC ( S1, LED ); // 模块名及参数定义,范围至endmodule
input [3:0] S1; // 输入端口定义,S1[0]-S1[3]分别对应第34、33、29和28脚
output [1:0] LED; // 输出端口定义,LED[0]-LED[1] 分别对应第44和43脚
assign LED = FUNC_ENC ( S1 ); // 用assign语句实现function函数调用
function [1:0] FUNC_ENC; // function函数及函数名,至endfunction为止
input [3:0] S1; // 输入端口定义
case ( S1 ) // case语句,至endcase为止
`SW_IN0 : FUNC_ENC = 0; // 当S1= SW_IN0时,返回0
`SW_IN1 : FUNC_ENC = 1; // 当S1= SW_IN1时,返回1
`SW_IN2 : FUNC_ENC = 2; // 当S1= SW_IN2时,返回2
`SW_IN3 : FUNC_ENC = 3; // 当S1= SW_IN3时,返回3
endcase // case语句结束
endfunction // function函数结束
endmodule // 模块结束
把以上2位二进制编码器的Verilog-HDL描述,用Webpack Project Navigator软件,生成目标文件,并通过下载电缆写入芯片XC9536中。然后,将芯片插到目标板上,即可实现2位二进制编码器。图6示出了下载过程中出现的引脚配置画面。
7.4 1位数据比较器的实现
数据比较器是用来对两个二进制数的大小进行比较或检测是否相等的逻辑电路,在数字逻辑的设计中占有重要的位置。
1位数据比较器应有两个宽度为1的数据输入端口。设其输入分别为A和B,输出分别为A=B、A>B和A<B。可列出真值表,如表4所示。
表4 1位数据比较器的真值表
分析表4可以得出如下结论:
A=B的逻辑表达式为:/A·/B+A·B;
A>B的逻辑表达式为:A·/B
A<B的逻辑表达式为:/A·B
因此,可以采用如图7所示的逻辑功能框图来实现。
图7 1位数据比较器的逻辑功能框图
其中,S1_1和S1_2表示开关,对应表4中的A和B,打开时为高电平,闭合时为低电平,作为1位数据比较器的输入;LED0、LED1和LED2 表示发光二级管,对应表4中的A=B、A<B和A>B,作为其输出。33、34、38、43和44是上述变量对应芯片XC9536的引脚。虚线框中的部分是CPLD设计,实现1位数据比较器的功能。
根据图7,可以对该电路进行Verilog-HDL描述。
/* 1位数据比较器的Verilog-HDL描述*/
module COMPARATOR ( S1_1, S1_2, LED0, LED1, LED2 );
// 模块名及端口参数,范围至endmodule
input S1_1, S1_2; // 输入端口定义,S1_1和S1_2分别对应第34和33脚
output LED0, LED1, LED2; // 输出端口定义,LED0、 LED1和LED2分别对应第44、43和38脚
assign { LED0, LED1, LED2 } = FUNC_COMP ( S1_1, S1_2 );
// 用assign语句实现function函数调用
function [2:0] FUNC_COMP; // function函数及函数名,至endmodule为止
input S1_1, S1_2; // 输入端口定义,S1_1和S1_2分别对应第34和33脚
if (S1_1 > S1_2 ) // if语句,与else配合
FUNC_COMP = 3'b001; // 如果S1_1 > S1_2,则返回3bit二进制数001
else if (S1_1 < S1_2 ) // 与if相呼应
FUNC_COMP = 3'b010; // 如果S1_1 <S1_2,则返回3bit二进制数010
else // 与if相呼应
FUNC_COMP = 3'b100; // 如果S1_1 =S1_2,则返回3bit二进制数100
endfunction // function函数结束
endmodule // 模块结束
下面是1位数据比较器的测试模块。
/* 1位数据比较器的测试模块 */
`timescale 1ns/1ns // 将仿真的单位设定为1ns
module COMPARATOR_TEST; // 测试模块名及参数定义,范围至endmodule
reg S1_1, S1_2; // 寄存器定义,输入端口
wire LED0, LED1, LED2; // 线网定义,输出端口
parameter STEP="50"; // 定义STEP为50,下面的程序中,STEP都视为50
COMPARATOR COMPARATOR (S1_1, S1_2, LED0, LED1, LED2);
// 底层模块、实例名及参数
initial begin // 从initial开始,输入信号变化。begin与end相呼应
S1_1=0; S1_2=0; // 参数初始化
# (STEP/2) S1_1=1; // 经过(STEP/2)后,S1_1=1; S1_2不变
# (STEP/2) S1_1=0; S1_2=1; // 经过(STEP/2)后,S1_1=0; S1_2=1
# (STEP/2) S1_1=1; // 经过(STEP/2)后,S1_1=1; S1_2不变
# (STEP/2) S1_1=0; S1_2=0; // 经过(STEP/2)后,S1_1=0; S1_2=0
# (STEP/2) S1_1=1; // 经过(STEP/2)后,S1_1=1; S1_2不变
# (STEP/2) S1_1=0; S1_2=1; // 经过(STEP/2)后,S1_1=0; S1_2=1
# (STEP/2) S1_1=1; // 经过(STEP/2)后,S1_1=0; S1_2不变
# (STEP/10) $finish; // 经过(STEP/10)后,程序停止运行
end // 与begin相呼应
endmodule // 模块结束
图8为1位数据比较器的逻辑仿真结果。在图中,数据S1_1和数据S1_2都是按照"0、1"这两种状态做着周期性地变化。数据S1_1每隔25ns 改变一次状态,而数据S1_2每隔50ns才改变一次状态。通过观察,可得逻辑仿真结果与设计所期望的结果完全相同,即:当S1_1= S1_2时,LED0=1,LED1=0,LED2=0;当S1_1> S1_2时,LED0=0,LED1=0,LED2=1;S1_1<S1_2时,LED0=0,LED1=1,LED2=0。
图8 1位数据比较器的逻辑仿真结果
把以上1位数据比较器的Verilog-HDL描述,用Webpack Project Navigator软件,生成目标文件,并通过下载电缆写入芯片XC9536中。然后,将芯片插到目标板上,即可实现1位数据比较器。图9示出了下载过程中出现的引脚配置画面。
参考文献:
(1) 夏宇闻:复杂数字电路与系统的Verilog HDL设计技术,北京航空航天大学出版社,1998.
(2) John M. Yarbrough著,李书浩等译:数字逻辑应用与设计, 机械工业出版社,北京,2000.4.
(3) 常晓明:Verilog-HDL实践与应用系统设计,北京航空航天大学出版社, 2003.1.
文章评论(0条评论)
登录后参与讨论