目录
实验目的:
1、熟悉QuartusⅡ软件的使用方法,掌握EDA流程;
2、掌握基本组合逻辑电路的设计方法;
3、学会数码显示译码器设计,为复杂的数字系统设计打基础。
预习要求:
1、掌握FPGA的EDA设计流程(文本输入);
2、掌握VerilogHDL程序基本结构,always@过程语句、case语句的使用;
3、掌握数码显示译码器的设计原理。
实验讲解与练习:
1、4选1的多路选择器源程序:
module mux41_a(a,b,c,d,s0,s1,y);
input a,b,c,d,s0,s1;
output y;
reg y;
always@ (*)
begin
case ({s0,s1})
2'b00:y<=a;
2'b01:y<=b;
2'b10:y<=c;
2'b11:y<=d;
default y<=a;
endcase
end
endmodule
2、语法知识:
(1)VerilogHDL程序基本结构:
以Verilog语言的关键词module_endmodule引导的程序结构,可以完整地表达一个电路模块,或一片专用集成电路ASIC的端口结构和功能,即无论是一片74LS138还是一片CPU,都必须包含在模块描述语句module_endmodule中。
标识符:给对象(如模块名、电路的输入与输出端口、变量等)取名所用的字符串。取名时只能包含英文字母、数字、下划线和$这四种符号;注意必须以英文字母或下划线开始。如,clk、counter8、_net、bus_A 。标识符是分大小写的,即系统对大小写敏感。
建议程序的文件名应尽量与该程序的模块名一致(对于QuartusII,必须满足这一规定),文件命名时对大小写敏感,文件名不应该用中文或数字来命名,Verilog程序必须存入文件夹(要求非中文文件夹名),不要存在根目录内或桌面上。
(2)always过程语句
语法点1:由always@引导的过程语句结构是Verilog语言中最常用和最重要的语句结构之一。
语法点2:Verilog中的顺序语句和并行语句?
并行语句:无论多少行语句,都是同时执行,与语句的前后次序无关;
顺序语句:类似普通软件的程序执行方式,按照语句的前后排列方式顺序执行。
语法点3:always过程语句属于并行语句,任何顺序语句都必须放在过程语句结构中。
语法点4:always过程语句格式:
always @(敏感信号表达式)
begin
// 过程赋值语句;
// if语句,case语句;
// for语句,while语句,repeat语句;
end
语法点5:当敏感信号表达式中任何信号发生变化时,就会执行一遍块内的语句。
语法点6:敏感信号的表述方式:
(a)用文字or连接所有敏感信号,表达为always@(a or b or c or d or s0 or s1);
(b)用逗号区分和连接所有的敏感信号,表达为always@(a,b,c,d,s0,s1);
(c)省略形式,表达为always@(*)。目前的Verilog主流综合器都默认过程语句中列全了所有应该被列入的信号。always@(*)符合verilog HDL2001规范,因此试图通过选择性地列入敏感信号来改变逻辑设计无效。
(3)块语句begin_end
块语句begin_end本身没有什么功能,仅限于顺序语句结构中使用,通常用它来组合顺序语句,故称其为顺序块。块语句begin_end只相当于一个括号,在此“括号”中的语句都被认定归属于同一操作模块。
Verilog规定,若某一语句结构中仅包含一条语句且无须定义局部变量时,则块语句被默认使用,无须显式定义块;若含多条语句,则必须用begin_end的显式结构将它们“括”起来。
块语句begin_end格式:
begin [:块名]
语句1;语句2;…语句n;
end
其中[:块名] 可以省略。
(4)case语句
语法点1:是一种多分支条件选择语句,属于顺序语句,必须放在过程语句中使用。
语法点2:共有三种形式。其一般形式如下:
case (case_expr)
item_expr1: begin statement1; end
item_expr2: begin statement2; end
……
default: begin default_statement; end
endcase
语法点3:Default语句的含义?
除非所有条件语句中的选择值能完整覆盖case语句中表达式的取值,否则最后一个条件语句中的选择必须加上default语句。
建议加上default语句,因为在Verilog中,任何变量都有4种不同的逻辑状态取值——0、1、z和x,因此{S1、S0}的取值不仅仅是00,01,10和11,如果不加,有的综合器会加上不必要的时序模块。
(5)位拼接运算符{ }
作用是将两个或多个信号的某些位拼接起来成为一个新的操作数,进行运算操作。设A=1’b1,B=2’b10,C=2’b00
则{B,C}=4’b1000
{A,B[1],C[0]}=3’b110
{A,B,C,3’b101}=8’b11000101。
对同一个操作数的重复拼接还可以使用双重大括号构成的运算符{{}}
例如 {4{A}}=4’b1111,{2{A},2{B},C}=8’b11101000。
(6)Verilog中的数字表达
表示一个二进制数的一般格式
<位宽>‘<进制><数字>
位宽:表示数据的二进制的位数;
进制:表示数据的进制,其中B表示二进制,O表示八进制,D表示十进制,H表示十六进制,不区分大小写。
举例:2’b10 4’b1011 4’hA 3’D7
实验内容:数码显示译码器设计
数字系统中的数据处理和运算均为2进制,所以输出表达式均为16进制;为了满足16进制数的译码显示,最方便的方法是利用译码程序在FPGA/CPLD中实现。
一般译码电路用case语句描述。
设计要求:输入为4位二进制数(也即0~15),输出为7位二进制数,用以点亮LED灯,显示0~15的字形,当然10~15用字母A~F表示。
7段数码显示译码器源程序:
module decode_1(A, LEDS);
input[3:0] A;
output reg[6:0] LEDS;
always@ (A)
begin
case (A)
4'b0000:LEDS<=7'b0111111; //"0"
4'b0001:LEDS<=7'b0000110; //"1"
4'b0010:LEDS<=7'b1011011; //"2"
4'b0011:LEDS<=7'b1001111; //"3”
4'b0100:LEDS<=7'b1100110; //"4"
4'b0101:LEDS<=7'b1101101; //"5"
4'b0110:LEDS<=7'b1111101; //"6"
4'b0111:LEDS<=7'b0000111; //"7"
4'b1000:LEDS<=7'b1111111; //"8"
4'b1001:LEDS<=7'b1101111; //"9"
4'b1010:LEDS<=7'b1110111; //"A"
4'b1011:LEDS<=7'b1111100; //"b"
4'b1100:LEDS<=7'b0111001; //"c"
4'b1101:LEDS<=7'b1011110; //"d"
4'b1110:LEDS<=7'b1111001; //"E"
4'b1111:LEDS<=7'b1110001; //"F"
default:LEDS<=7'b0111111; //"0"
endcase
end
endmodule
7段数码显示译码器仿真波形:
7段数码显示译码器硬件验证:
- 建议选择实验模式6;【至于模式选择的方法,根据电路需要,和模式的功能】
- 引脚分配示意图【根据模式对应引脚手册锁定】,其中A[3:0]为按键输入,LEDS[6:0]为七段数码管输出。
实验总结