实验三 编码器和译码器
3.1 实验目的
上一章节我们学习了简单组合逻辑电路——多路数据选择器,在本章节我们将学习另外一种数字系统中常见的简单组合逻辑电路——编码器和译码器。然后通过一个设计一个简易的计算器让大家进一步巩固FPGA开发的流程和方法。
本节您将掌握的内容如下:
-
理解编码器和解码器的概念,并用 Verilog HDL 实现编码器和译码器;
-
用Verilog HDL 实现7段数码管的显示控制;
-
熟悉数字电路的设计、仿真流程,最后在DE1-SOC开发板上验证设计 。
3.2 原理介绍
在数字系统中一般采用二进制运算处理数据,因此通常需要将输入的信息转变成若干位二进制代码,或者是将二进制代码转变成输出信息。而这些转换会用到数字系统里面常见的编码器和译码器。
3.2.1 编码器
在逻辑电路中,信号都是以高,低电平的形式输入。把每次输入的高低电平信号按一定的规律编成一组对应的二进制代码称为编码。在编码时,每一种二进制代码都赋予了特定的含义,即都表示了一个确定的信号或者对象。具有编码功能的逻辑电路称为编码器。编码器有若干个输入,在某一时刻只有一个输入被转换为二进制码。例如8线-3线编码器则有8个输入,在某一时刻只有8个输入中的某一个输入被转换为3位二进制码输出。
8-3普通编码器
8-3编码器的功能框图如下:
图3.1 8-3编码器功能框图
8-3普通编码器的真值表如下所示:
表3.1 8-3普通编码器真值表
输入 | 输出 | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
in7 | in6 | in5 | in4 | in3 | in2 | in1 | in0 | out2 | out1 | out0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 |
0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
根据表3.1 我们可以自己手绘出8-3普通编码器波形图:
图3.2 8-3普通编码器波形图
根据图3.2的波形图,我们可以用case语句实现8-3普通编码器,其代码如下:
module encoder8x3(input [7:0] in, //8个信号输入output reg[2:0] out //3位信号输出);always @ (*) begincase(in)8'b0000_0001: out = 3'b000 ;8'b0000_0010: out = 3'b001 ;8'b0000_0100: out = 3'b010 ;8'b0000_1000: out = 3'b011 ;8'b0001_0000: out = 3'b100 ;8'b0010_0000: out = 3'b101 ;8'b0100_0000: out = 3'b110 ;8'b1000_0000: out = 3'b111 ;default: out = 3'b000 ;//其他输入组合情况都输出000endcaseendendmodule
代码3.1 case语句实现8-3普通编码器代码
代码3.1的case语句只列了8种输入情况,没有全部列举 in 的所有输入组合情况(总共可能出现2^8即256种情况),当出现某种没有被列举出来的组合输入时,如果没有代码行16的default语句,电路输出将出现错乱。所以这里加上default语句,并任意指定一种确定的输出情况。
代码3.1对应的8-3普通编码器RTL Viewer图如下:
图3.3 代码3.1对应的8-3编码器的RTL Viewer图
在实验二中,我们设计实现数据选择器时,既可以用case语句也可以用if-else语句来实现相同功能的电路,那有的读者可能会问在这里我们是否也能用if-else描述同样功能的8-3编码器?答案是肯定的,代码实现如下:
module encoder8x3(input [7:0] in, //8个信号输入output reg[2:0] out //3位信号输出);always @ (*) beginif(in==8'b0000_0001)out = 3'b000 ;else if(in==8'b0000_0010)out = 3'b001 ;else if(in==8'b0000_0100)out = 3'b010 ;else if(in==8'b0000_1000)out = 3'b011 ;else if(in==8'b0001_0000)out = 3'b100 ;else if(in==8'b0010_0000)out = 3'b101 ;else if(in==8'b0100_0000) out = 3'b110 ;else if(in==8'b1000_0000) out = 3'b111 ;else out = 3'b000 ;endendmodule
代码3.2 if-else语句实现8-3编码器代码
代码3.2对应的8-3编码器RTL Viewer图如下:
图3.4 代码3.2对应的8-3编码器的RTL Viewer图
代码3.1和代码3.2 两种电路描述虽然最后实现的功能是一样的,但比较图3.3和图3.4大家会发现case语句实现的8-3编码器和if-else语句实现的8-3编码器的 RTL 视图差别较大。 通过 RTL 视图3.3和图3.4我们也能够发现 if 括号里面的条件会生成名为“EQUAL”的比较器单元,而 case 则会生成名为“DECODER”的译码器单元,这些单元并不是 FPGA 硬件底层中最小单元,而只是一种用于 RTL 视图中易于表达的抽象后的图形,使之更易于我们观察、理解其代码所实现功能的硬件结构的大致样子,也符合了“HDL(硬件描述语言)”所表述的含义。
8-3优先编码器
从RTL视图分析可以发现,使用if-else 写法实现的编码器是存在优先级的,即第一个 if 中的条件的优先级最高,后面的else if 中的条件的优先级依次递减,好在该 if 中的条件只有一个,也只会产生一种情况,并不会产生优先级的冲突,所以这里优先级的高低关系并不会对最后的功能产生任何影响。而 case 在任何时候都不存在优先级的问题,而是通过判断case 中的条件来选择对应的输出。
我们可以稍微调整下代码3.2,描述出一个8-3优先编码器。首先来看8-3优先编码器真值表:
表3.2 8-3优先编码器真值表
输入 | 输出 | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
in7 | in6 | in5 | in4 | in3 | in2 | in1 | in0 | out2 | out1 | out0 |
x | x | x | x | x | x | x | 1 | 0 | 0 | 0 |
x | x | x | x | x | x | 1 | 0 | 0 | 0 | 1 |
x | x | x | x | x | 1 | 0 | 0 | 0 | 1 | 0 |
x | x | x | x | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
x | x | x | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
x | x | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
x | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
表3.1中,普通编码器一次只能输入一个信号,而表3.2中,优先编码器(Priority Encoder)将各输入信号的优先顺序排好,当几个信号同时输入时,优先级最高的信号优先编码。优先级低的信号则不起作用。
根据真值表我们可以描述出8-3优先编码器的Verilog HDL 代码如下:
module encoder8x3 ( input [7:0] in,output reg [2:0] out
);always @( * )beginif (in[0]) out=3'b000;else if (in[1]) out=3'b100;else if (in[2]) out=3'b010;else if (in[3]) out=3'b110;else if (in[4]) out=3'b001;else if (in[5]) out=3'b101;else if (in[6]) out=3'b011;else if (in[7]) out=3'b111;else out=3'b000;endendmodule
代码3.3 if-else语句实现8-3优先编码器代码
图3.5 代码3.3对应的8-3编码器的RTL Viewer图
3.2.2 3-8译码器
译码是编码的逆过程。其功能是将具有特定含义的二进制码转换成信号输出,具有译码功能的逻辑电路称为译码器。如果有n个二进制选择线,则最多可译码转换成2^n个数据输出。
在数字系统当中,常见的译码器有 2-4译码器,3-8译码器等。3-8译码器的功能框图如下图3.6所示:
图3.6 3-8译码器功能框图
如下表3.3是3-8译码器真值表:
表3.3 3-8译码器真值表
输入 | 输出 | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
in2 | in1 | in0 | out7 | out6 | out5 | out4 | out3 | out2 | out1 | out0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
3-8译码器波形图:
图3.7 3-8译码器波形图
根据图 3.7所示的3-8译码器波形图,用case语句描述3-8译码器的代码如下:
module decoder3x8(input [2:0] in,output reg[7:0] out);always @ (*) begincase(in)3'b000 : out <= 8'b0111_1111 ;3'b001 : out <= 8'b1011_1111 ;3'b010 : out <= 8'b1101_1111 ;3'b011 : out <= 8'b1110_1111 ;3'b100 : out <= 8'b1111_0111 ;3'b101 : out <= 8'b1111_1011 ;3'b110 : out <= 8'b1111_1101 ;3'b111 : out <= 8'b1111_1110 ;endcaseend
endmodule
代码3.4 3-8译码器的Verilog HDL 代码
3-8译码器的TRL Viewer图:
图3.8 3-8译码器的RTL Viewer图
译码器在数字系统中有广泛的应用,不仅用于代码的转换,终端的数字显示,还用于数据分配,存储器寻址和组合控制信号等。
下面章节我们将描述如何用译码器实现数码管的显示控制。
3.2.3 7段数码管显示
数码管是一种半导体发光器件,其基本单元是发光二极管,常见的数码管有7段数码管、8段数码管(比7段数码管多一个小数点)和其他类型数码管(如“米”字管),如下图3.9所示。
图3.9 数码管器件
在数字电路中,7段数码管是一个应用非常广泛的显示器件,它有7个可独立点亮的线段(LED灯),如图3.10(a)所示。用户可以通过控制点亮7个线段中某些线段来拼成10个数字和某些字母,从而完成显示任务。目前有两种类型的7段数码管显示器件:共阴极数码管(如图 3.10(b)所示)和共阳极数码管(如图 3.10(c)所示)。
共阴极数码管是7个LED的阴极端一起接地,每个阳极端单独连接到控制端(比如接到FPGA的GPIO pin)。共阴极数码管器件是高电平有效。
共阳极数码管是7个LED的阳极端一起连接VCC,每个阴极端单独接控制端(比如接到FPGA的GPIO pin)。 共阳极数码管器件是低电平有效。
图3.10 七段数码管结构图
我们以共阳极数码管为例,共阳极七段数码管显示数字0-9,字母A-F的示意图如下3.11图所示。比如我们想要显示数字0,我们需要点亮第0、1、2、3、4、5段,第6段不需要点亮。因为共阳极数码管其阳极都是连接到公共的VCC,所以只要在每段对应的端口输入低电平即可点亮对应的二极管,就能显示出数字0。
图3.11 七段数码管显示数字和字母
根据图3.11可以得到下面表3.4,表的第三列是共阳极数码管显示内容所对应的译码输出。
表3.4 七段数码管真值表
显示的内容 | 二进制码 | 输出到数码管 |
---|---|---|
0 | 0000 | 1000000 |
1 | 0001 | 1111001 |
2 | 0010 | 0100100 |
3 | 0011 | 0110000 |
4 | 0100 | 0011001 |
5 | 0101 | 0010010 |
6 | 0110 | 0000010 |
7 | 0111 | 1111000 |
8 | 1000 | 0000000 |
9 | 1001 | 0010000 |
A | 1010 | 0001000 |
B | 1011 | 0000011 |
C | 1100 | 1000110 |
D | 1101 | 0100001 |
E | 1110 | 0000110 |
F | 1111 | 0001110 |
如果需要七段数码管显示数字0-9,字母A-F共16种字符,则需要4位(2^4为16)二进制数编码。 将二进制数在数码管上显示,需要先将二进制数转换为适合7段数码管显示的代码。因此得到七段数码管显示功能框图如下:
图3.12 七段数码管显示功能框图
根据表3.4可以写出七段数码管共阳极显示功能的代码如下:
module decod7seg(input [3:0] hex,output reg [6:0] display
);always @(hex)begincase(hex)4'h1: display = 7'b1111001; // ---0----4'h2: display = 7'b0100100; // | |4'h3: display = 7'b0110000; // 5 14'h4: display = 7'b0011001; // | |4'h5: display = 7'b0010010; // ---6----4'h6: display = 7'b0000010; // | |4'h7: display = 7'b1111000; // 4 24'h8: display = 7'b0000000; // | |4'h9: display = 7'b0011000; // ---3----4'ha: display = 7'b0001000;4'hb: display = 7'b0000011;4'hc: display = 7'b1000110;4'hd: display = 7'b0100001;4'he: display = 7'b0000110;4'hf: display = 7'b0001110;4'h0: display = 7'b1000000;default: display = 7'b1111111;endcaseend
endmodule
代码3.5 七段数码管显示代码
代码3.5的七段数码管显示对应的RTL Viewer图如下:
图3.13 代码3.5 对应的RTL Viewer图
3.3 实验目标
设计一个简易计算器,能够实现4位的 and、 or、 xor、 not 逻辑运算,通过控制信号对这四种运算进行四选一,并将运算的结果同时显示在7段数码管和LED灯 上 。
3.4 设计实现
3.4.1 硬件介绍
我们使用DE1-SOC平台上的SW开关、7段数码管和 LED 灯等硬件进行简易计算器的验证,选取 SW[3:0],SW[7:4]分别作为待算量a和b信号的输入端,选取SW[9:8] 作为功能选择信号 sel 的信号输入;选取HEX0和 LEDR[3:0] 作为结果输出信号out的显示,具体的硬件映射关系如图 3.14所示 :
图3.14 实验3的硬件映射关系图
3.4.2 设计思路
这个简易计算器的功能框图可以继续参考图3.14,它总共有7个子模块,分别是与(and)逻辑运算模块、 或(or)逻辑运算模块、异或(xor)逻辑运算模块、非(not)逻辑运算模块、4位四选一数据选择器模块和7段数码管译码器模块以及计算器系统模块。
and、 or、 xor、 not四种逻辑运算在本书实验一章节已经讲解过,后面将在代码小节中直接给出描述的代码; 4位四选一模块在实验二中也已经讲解过;7段数码管译码器模块则在本实验的3.13章节讲解过,在此都不再赘述。
如下表3.5 是简易计算器的输入输出信号描述。
表3.5 顶层模块输入输出信号描述
信号 | 位宽 | 类型 | 功能描述 |
---|---|---|---|
a | 4-bit | input | 输入信号1 |
b | 4-bit | input | 输入信号2 |
sel | 2-bit | Input | 选通信号 |
hex0_out | 8-bit | output | 输出信号 |
ledr_out | 4-bit | output | 输出信号 |
3.4.3 代码
下面将实验三的7个模块的代码展示如下:
与(and)逻辑运算模块代码:
module c1(input [3:0] a, //数据输入信号ainput [3:0] b, //数据输入信号boutput [3:0] f //数据输出信号f
);assign f = a & b; //执行逻辑与运算endmodule
代码3.6 and逻辑运算模块代码
或(or)逻辑运算模块代码:
module c2(input [3:0] a, //数据输入信号ainput [3:0] b, //数据输入信号boutput [3:0] f //数据输出信号f
);
assign f = a | b;
endmodule
代码3.7 or逻辑运算模块代码
异或(xor)逻辑运算模块代码:
module c3(input [3:0] a, //数据输入信号ainput [3:0] b, //数据输入信号boutput [3:0] f //数据输出信号f
);
assign f = a ^ b;
endmodule
代码3.8 xor逻辑运算模块代码
非(not)逻辑运算模块代码:
module c4(input [3:0] a, //数据输入信号aoutput [3:0] f //数据输出信号f
);assign f = ~ a;endmodule
代码3.9 not逻辑运算模块代码
4位四选一的数据选择器模块代码参考:
module mux4x1(input [3:0] in1, //数据输入信号in1input [3:0] in2, //数据输入信号in2input [3:0] in3, //数据输入信号in3input [3:0] in4, //数据输入信号in4input [1:0] sel, //选通信号output reg [3:0] out //输出信号
);always @ ( * ) begincase (sel) 2'b00 : out = in1;2'b01 : out = in2;2'b10 : out = in3;2'b11 : out = in4;default : out = in1;endcaseendendmodule
代码3.10 mux4x1.v
7段数码管解码器代码参考代码3.5。
calculator计算器系统模块:完成以上6个模块后,我们需要将它们都集成到计算器系统模块中,所以我们需要创建calculator.v文件,然后将前面的6个子模块进行例化和信号连接。
module calculator(input [3:0] a, // 计算器的第一个操作数input [3:0] b, // 计算器的第二个操作数input [1:0] sel, // 计算器的功能选择信号output [3:0] ledr_out, // 寄存器的数据输出output [6:0] hex0_out // 七段数码管译码器的输出
);// 变量声明
wire [3:0] operator_a;
wire [3:0] operator_b;
wire [1:0] operation_s;// 输入信号赋值
assign operator_a = a;
assign operator_b = b;
assign operation_s = sel;wire [3:0] f1;
wire [3:0] f2;
wire [3:0] f3;
wire [3:0] f4;
wire [3:0] f;
wire [6:0] hex0dec_output;// 与运算
c1 c1_inst(.a (operator_a),.b (operator_b),.f (f1)
);
// 或运算
c2 c2_inst(.a (operator_a),.b (operator_b),.f (f2)
);
// 异或运算
c3 c3_inst(.a (operator_a),.b (operator_b),.f (f3)
);
// 非运算
c4 c4_inst(.a (operator_a),.f (f4)
);
// 在f1,f2,f3,f4四种运算结果中,选择一个运算结果f
mux4x1 mux4x1_inst(.in1 (f1),.in2 (f2),.in3 (f3),.in4 (f4),.sel (operation_s),.out (f)
);// 寄存器的输出数据f输入至数码管译码器,经译码后显示至七段数码管上
decod7seg decod7seg_inst(.hex (f),.display (hex0dec_output)
);
// 寄存器的输出数据g直接显示在LED上
assign ledr_out = f;
assign hex0_out = hex0dec_output;endmodule
代码3.11 calculator.v
calculator模块综合出来的RTL Viewer如图3.15所示,可以看出这和我们的系统框图是一致的。
图3.15 calculator模块RTL Viewer
3.5 实验步骤
执行以下步骤,构造一个包含与、或、异或和非逻辑运算的简易计算器,并对该计算器进行仿真,最后在DE1-SOC上观察实验现象。
3.5.1 创建工程和代码输入
1. 点击电脑右下角的开始菜单找到Quartus软件,双击Quartus (Quartus Prime 17.1)打开Quartus Prime软件。
2. 点击菜单File-->New Project Wizard弹出工程创建的对话框。在弹出的对话框中点击Next。
3. 在您的DE1-SOC 工作文件夹下创建一个lab3的文件夹,并将工程路径指向该文件夹,且工程的名称也命名lab3。如图3.16所示。
图3.16 创建lab3
4. 连续点击3次Next得到如下界面,通过器件过滤器筛选选中DE1-SoC的Cyclone V 5CSEMA5F31C6器件,点击Next两次后得到工程的生成报告窗口,检查无误后点击Finish完成工程创建。
图3.17 lab3实验操作窗口
5. 完成创建工程后,打开后的工程Quartus Prime工程界面如图3.18所示。
图3.18 创建lab3工程
6. 在Quartus工具栏依次点击File-->New,在New窗口中选择Verilog HDL File后点击OK按钮新建7个空白Verilog HDL文件,分别命名为c1.v、c2.v、c3.v、c4.v、mux4x1.v、decod7seg.v和calculator.v,并新建名为v的文件夹,将该7个空白Verilog HDL文件保存在v文件夹中。将代码3.6、代码3.7、代码3.8、代码3.9、代码2.6、代码3.5和代码3.10分别复制添加到c1.v、c2.v、c3.v、c4.v、mux4x1.v、decod7seg.v和calculator.v文件中。
图3.19 Quartus中的c1.v文件
图3.20 Quartus中的c2.v文件
图3.21 Quartus中的c3.v文件
图3.22 Quartus中的c4.v文件
图3.23 Quartus中的mux4x1.v文件
图3.24 Quartus中的decod7seg.v文件
图3.25 Quartus中的calculator.v文件
7. 点击Quartus软件工具栏的Processing --> Start --> Start Analysis & Synthesis或点击按钮对Verilog HDL代码执行语法检查和综合。如果在该过程中提示有错误,请检查Verilog HDL代码语法,确保与上述代码块完全一致。
图3.26 对Verilog HDL代码执行语法检查和综合
3.5.2 仿真
1. 点击Quartus软件工具栏的File --> New --> Verilog HDL File,点击OK,新建一个空白Verilog HDL文件,然后将如下代码复制进去:
`timescale 1ns/1ps
module calculator_tb;
reg [3:0] a;reg [3:0] b;
reg [1:0] sel;wire [6:0] hex0_out;wire [3:0] ledr_out;
wire [3:0] f1;wire [3:0] f2;wire [3:0] f3;wire [3:0] f4;wire [3:0] out;
calculator calculator_inst( //例化与(and)逻辑运算c1.a(a),.b(b),.sel(sel),hex0_out(hex0_out),ledr_out(ledr_out)
);initialbeginrepeat(2) begina = {$random} % 16; //产生输入随机数,模拟输入端ab = {$random} % 16; //产生输入随机数,模拟输入端b
sel = 2'b00; //00模式,选择逻辑与运算模块# 10;endrepeat(2) begina = {$random} % 16;b = {$random} % 16;
sel = 2'b01; //01模式,选择逻辑或运算模块# 10;endrepeat(2) begina = {$random} % 16;b = {$random} % 16;
sel = 2'b10; //10模式,选择逻辑异或运算模块# 10;endrepeat(2) begina = {$random} % 16;
b = {$random} % 16;
sel = 2'b11;//11模式,选择逻辑非运算模块
# 10;
end
end
endmodule
代码3.12 calculator_tb.v文件代码
2. 再点击File --> Save As ...保存,命名为calculator_tb.v,保存在v文件夹中,如图3.27所示。
图3.27 保存test bench文件
图3.28 Quartus软件中的calculator_tb.v文件
3. 点击Assignments --> Settings,然后选中Simulation栏,Tool name选择ModelSim-Altera,然后选择新建Test Bench文件,如图3.29、图3.30所示的步骤。
图3.29
图3.30
4. 按照图3.31所示的步骤选择calculator_tb.v文件,点击Add进行添加,然后点击OK。
图3.31 添加Test Bench文件calculator_tb.v
5. 这样就可以在Test Bench看到添加的calculator_tb.v文件,点击OK ,如图3.32-1所示。添加完成后,在Settings窗口点击Apply和OK,然后将其关闭,如图3.32-2所示。
图3.32-1Test Bench文件添加完成
图3.32-2
6. 在Quartus Prime中选择菜单项Tools --> Run Simulation Tool --> RTL Simulation,即可调用ModelSim工具进行仿真,如图3.33所示。
图3.33 运行Simulation Tool
7. 运仿真结果如图3.34所示。
图3.34 ModelSim 仿真结果
8. 从波形图3.34可以看出:
a. 当选择信号sel=00时,计算器将a和b的与逻辑运算结果输出到ledr_out,同时该结果也被译码输出到hex0_out。
b. 当选择信号sel=01时,计算器将a和b的或逻辑运算结果输出到ledr_out,同时该结果也被译码输出到hex0_out。
c. 当选择信号sel=10时,计算器将a和b的异或逻辑运算结果输出到ledr_out,同时该结果也被译码输出到hex0_out。
d. 当选择信号sel=11时,计算器将a和b的非逻辑运算结果输出到ledr_out,同时该结果也被译码输出到hex0_out。
结果与预期一致,说明本实验要求的简易计算器电路已实现。
3.5.3 引脚分配、全编译与烧录
1. 点击Quartus菜单Assignments——Pin Planner。
关于引脚分配信息可以查看DE1-SoC_v.5.1.3_HWrevF.revG_SystemCD\UserManual\DE1-SoC_User_manual.pdf第 25、26、28页或者E:\CD_Package\01-DE1-SoC\DE1-SoC_v.5.1.3_HWrevF.revG_SystemCD\Schematic\DE1-SoC.pdf的第3页。
这里,a到b以及sel可以通过拨码开关SW0到SW9来控制,out信号分别输出到LEDR0到LEDR3,hex0_out输出到数码管0。
1. 点击Quartus软件工具栏的Processing --> Start Compilation或点击
按钮编译工程。
图3.35 编译Verilog HDL代码
2. 编译完成后,如图3.36所示,此外还可以看到在output_files文件夹中生成了calculator.sof文件,如图3.35所示。
图3.36 calculator.sof文件
3. 用DE1-SOC开发板自带的白色USB type B线缆连接DE1-SOC和PC,给开发板接上电源,按下SW11开机。
4. 点击Quartus软件工具栏的Tools --> Programmer或
按钮打开Programmer窗口,点击Hardware Setup选择USB-Blaster[USB-0],点击Auto Detect选择5CSEBA6器件,左键单击选中5CSEBA6器件再点击Change File,选择calculator.sof,勾选program/configure,点击Start下载calculator.sof。
图3.37-1
图3.37-2
图3.37-3
图3.37-4
图3.37-5
图3.37-6烧录完成
3.5.4 实验现象观察
1. 在lab3中,使用的SW、LEDR和HEX如下图所示。
图3.38 lab3中SW、HEX、LEDR对应关系
2. 通过切换滑动开关SW9-0到 up 或 down位置,观察LEDR3-0的状态以及HEX0的显示来测试设计的功能。
a. 拨动SW9~SW8为“down、down”,拨动SW7~SW4为“down、down、down、up”、SW3~SW0为“down、up、down、down”时,LEDR3~LEDR0的状态为“熄灭、熄灭、熄灭、熄灭”,HEX0上显示“0”;
b. 拨动SW9~SW8为“down、up”,拨动SW7~SW4为“down、down、up、down”、SW3~SW0为“down、up、down、up”时,LEDR3~LEDR0的状态为“熄灭、点亮、点亮、点亮”,HEX0上显示“7”;
c. 拨动SW9~SW8为“up、down”,拨动SW7~SW4为“up、up、down、up”、SW3~SW0为“down、up、up、down”时,LEDR3~LEDR0的状态为“点亮、熄灭、点亮、点亮”,HEX0上显示“b”;
d. 拨动SW9~SW8为“up、up”,拨动SW7~SW4为“down、up、up、down”、SW3~SW0为“up、down、down、up”时,LEDR3~LEDR0的状态为“熄灭、点亮、点亮、熄灭”,HEX0上显示“6”;
3.6 实验小结
本章主要讲解了数字电路中的经典组合逻辑 3-8 译码器如何用 Verilog 代码去实现,并对比了 if-else 语句和 case 语句所表达的逻辑的异同,希望大家在以后的应用中能够合理、熟练的使用这两种语法。