数字设计实验:译码器与编码器

数字设计实验:译码器与编码器

1.实验目的

本实验旨在设计一个3-8译码器和4-2编码器,并借助vivado软件和实验开发板来进行模拟仿真和实践验证,通过实验对编码和译码原理有初步的理解和认识,同时锻炼vivado软件的使用能力和verilog语言的编写能力.

2.实验内容

  • 3-8译码器
    实验内容:
    1.写出3-8译码器真值表,通过化简写出译码器布尔表达式
    2.使用Verilog HDL实现,用vivado仿真并下载到实验板进行验证
    输入使用板上的switch拨段开关,输出使用板上的led灯。

  • 4-2编码器
    实验内容:
    1.写出4-2编码器真值表,通过化简写出编码器布尔表达式
    2.使用Verilog HDL实现,用vivado仿真并下载到实验板进行验证
    输入使用板上的switch拨段开关,输出使用板上的led灯。

3.实验设计思路

3.1 3 - 8译码器分析

3 - 8译码器有3个输入x,y,z,只取0或1;共有8种输出,每个输出代表3个输入变量的一个最小项.

3 - 8译码器的真值表如下:

xyzD0D1D2D3D4D5D6D7
00010000000
00101000000
01000100000
01100010000
10000001000
10100000100
11000000010
11100000001

不难得到:

D 0 = x ′ y ′ z ′     D 1 = x ′ y ′ z     D 2 = x ′ y z ′     D 3 = x ′ y z D 4 = x y ′ z ′     D 5 = x y ′ z     D 6 = x y z ′     D 7 = x y z D_0 = x'y'z'~~~D_1 = x'y'z~~~D_2 = x'yz'~~~D_3 = x'yz\\D_4 = xy'z'~~~D_5 = xy'z~~~D_6 = xyz'~~~D_7 = xyz D0=xyz   D1=xyz   D2=xyz   D3=xyzD4=xyz   D5=xyz   D6=xyz   D7=xyz
因此只需要根据Di的布尔表达式编写verilog代码即可.

3.2 4 - 2编码器分析

3.2.1 初始设计分析

4 - 2编码器有4个输入变量,每个输入代表一个四进制数,并初始假设在任何时候只有一个输入的值等于1;共有2个输出,每个输出对应于输入的二进制数.例如输入0,0,1,0,输出为00;输入1,0,0,0,输出为11.

4 - 2编码器的真值表如下:

D0D1D2D3xy
100000
010001
001010
000111

不难得到:
x = D 2 + D 3 y = D 1 + D 3 x=D_2+D_3\\y=D_1+D_3 x=D2+D3y=D1+D3

因此只需要根据x,y的布尔表达式编写verilog代码即可.

3.2.2 改进设计分析

在3.2.1中分析设计的编码器有两个明显的缺点:

1.由于假设的是任何时候只有一个输入是有效的,而当多个输入变量为1时,就会产生一个没有定义的输入组合,会导致与正确输入相同的输出结果;

2.当所有输入变量都为0,也即所有输入都无效时,产生的输出是00,这与D0为1时产生的输出相同.

改进方法:优先编码器

1.新增第三个输出:有效位指示符V,当四个输入均为0即均无效时,V设置为0,当有一个及以上输入为1时,V设置为1;

2.引入优先级,当有多个输入同时有效时,最高优先级的输入被视为优先,在此编码器中,定义下标数字越大的输入优先级越高.

4 - 2优先编码器真值表如下:

D0D1D2D3xyV
0000XX0
1000001
X100011
XX10101
XXX1111

容易得到:
x = D 2 + D 3 y = D 3 + D 1 D 2 ′ V = D 0 + D 1 + D 2 + D 3 x=D_2+D_3\\y=D_3+D_1D_2'\\V=D_0+D_1+D_2+D_3 x=D2+D3y=D3+D1D2V=D0+D1+D2+D3
因此只需要根据x,y,V的布尔表达式编写verilog代码即可.

4.实验过程与实验结果

4.1 3-8译码器的设计与实现

  • 设计:

1.根据3.1中的分析,可以编写decoder模块:

module decoder(x, y, z, D);
    input x, y, z;
    output [7:0] D;
    
    assign D[0] = (~x)&(~y)&(~z);
    assign D[1] = (~x)&(~y)&z;
    assign D[2] = (~x)&y&(~z);
    assign D[3] = (~x)&y&z;
    assign D[4] = x&(~y)&(~z);
    assign D[5] = x&(~y)&z;
    assign D[6] = x&y&(~z);
    assign D[7] = x&y&z;
endmodule

2.为了能在软件上虚拟仿真,写一个decoder模块的测试平台test_decoder:

//test module
module test_decoder;
    wire [7:0] out;
    reg x, y, z;
    
    decoder M1(x, y, z, out);
    
    integer i;
    
    initial begin
        $display("%4s | %1s %1s %1s | %8s", "Time", "x", "y", "z", "D");
        $display("-----------------------------");
        
        // 遍历所有 8 种输入组合
        for (i = 0; i < 8; i = i + 1) begin
            {x, y, z} = i;
            #1;
            $display("%4t | %1b %1b %1b | %08b", $time, x, y, z, out);
        end
        
        $finish;
    end
endmodule

作用是按照0~7的二进制编码顺序每隔1ps改变一次输入变量x,y,z,能在控制台和仿真图像上显示仿真结果.

  • 仿真结果:

1.根据所设计的程序,在vivado仿真后生成的逻辑电路图如下,符合之前的设计思路:
在这里插入图片描述

2.控制台输出结果如下,符合译码器的功能:

在这里插入图片描述

3.仿真结果时序表如下,直观呈现了输入和输出随时间的变化:

在这里插入图片描述

  • 导入实验板验证:

为了能正确接入到实验板上,需添加约束文件lab1_1_decoder.xdc如下,目的是将程序里的变量与实验板上的组件正确配对:

## Switches
set_property -dict { PACKAGE_PIN J15   IOSTANDARD LVCMOS33 } [get_ports { x }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
set_property -dict { PACKAGE_PIN L16   IOSTANDARD LVCMOS33 } [get_ports { y }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
set_property -dict { PACKAGE_PIN M13   IOSTANDARD LVCMOS33 } [get_ports { z }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]

## LEDs
set_property -dict { PACKAGE_PIN H17   IOSTANDARD LVCMOS33 } [get_ports { D[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
set_property -dict { PACKAGE_PIN K15   IOSTANDARD LVCMOS33 } [get_ports { D[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
set_property -dict { PACKAGE_PIN J13   IOSTANDARD LVCMOS33 } [get_ports { D[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
set_property -dict { PACKAGE_PIN N14   IOSTANDARD LVCMOS33 } [get_ports { D[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
set_property -dict { PACKAGE_PIN R18   IOSTANDARD LVCMOS33 } [get_ports { D[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
set_property -dict { PACKAGE_PIN V17   IOSTANDARD LVCMOS33 } [get_ports { D[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
set_property -dict { PACKAGE_PIN U17   IOSTANDARD LVCMOS33 } [get_ports { D[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
set_property -dict { PACKAGE_PIN U16   IOSTANDARD LVCMOS33 } [get_ports { D[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]

将文件下载到实验板上进行验证,得到的实拍图片如下:

在这里插入图片描述

其中,开关上拨代表对应的输入变量为1;LED灯亮代表对应的输出变量为1.

上述实验结果表明,当根据输入变量为八进制数i(i = 0,1,2,…,7)按二进制的编码来上拨开关时,i对应的LED灯亮,其他灯都不亮.这也能更直观地验证译码器设计的正确性.

4.2 4 - 2编码器的设计与实现

4.2.1 初始设计
  • 设计:

1.根据3.2.1中的分析,可以编写encoder模块:

module encoder(D, x, y);
    input [3:0] D;
    output x, y;
    
    assign x = D[2] | D[3];
    assign y = D[1] | D[3];
endmodule

2.为了能在软件上虚拟仿真,写一个encoder模块的测试平台test_encoder:

//test module
module test_encoder;
    wire x, y;
    reg [3:0] D;
    
    encoder M1(D, x, y);

    initial begin
        $display("Time\tD\t x y");

        // 输入0001
        D = 4'b0001;
        #1;
        $display("%0d\t%b\t %b %b", $time, D, x, y);

        // 输入0010
        D = 4'b0010;
        #1;
        $display("%0d\t%b\t %b %b", $time, D, x, y);

        // 输入0100
        D = 4'b0100;
        #1;
        $display("%0d\t%b\t %b %b", $time, D, x, y);

        // 输入1000
        D = 4'b1000;
        #1;
        $display("%0d\t%b\t %b %b", $time, D, x, y);

        $finish;
    end
endmodule

作用使是按照第0,1,2,3位为1的顺序每隔1ps改变一次输入向量D,能通过运行后控制台的输出和仿真时序表来观察输出变量x,y的值的变化.

  • 仿真结果:

1.根据所设计的程序,在vivado仿真后生成的逻辑电路图如下,符合之前的设计思路:

在这里插入图片描述

2.控制台输出结果如下,符合编码器的功能:

在这里插入图片描述

3.仿真结果时序表如下,直观呈现了输入和输出随时间的变化:

在这里插入图片描述

  • 导入实验板验证:

为了能正确接入到实验板上,需添加约束文件lab1_2_encoder.xdc如下,目的是将程序里的变量与实验板上的组件正确配对:

## Switches
set_property -dict { PACKAGE_PIN J15   IOSTANDARD LVCMOS33 } [get_ports { D[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
set_property -dict { PACKAGE_PIN L16   IOSTANDARD LVCMOS33 } [get_ports { D[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
set_property -dict { PACKAGE_PIN M13   IOSTANDARD LVCMOS33 } [get_ports { D[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
set_property -dict { PACKAGE_PIN R15   IOSTANDARD LVCMOS33 } [get_ports { D[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]

## LEDs
set_property -dict { PACKAGE_PIN H17   IOSTANDARD LVCMOS33 } [get_ports { x }]; #IO_L18P_T2_A24_15 Sch=led[0]
set_property -dict { PACKAGE_PIN K15   IOSTANDARD LVCMOS33 } [get_ports { y }]; #IO_L24P_T3_RS1_15 Sch=led[1]

将文件下载到实验板上进行验证,得到的实拍图片如下:

在这里插入图片描述

其中,开关上拨代表对应的输入变量为1;LED灯亮代表对应的输出变量为1.

上述实验结果表明,当输入中仅有第i(i = 0,1,2,3)个为1即对应的开关上拨时,LED灯组合xy代表了i的二进制编码(亮为1,不亮为0).这也能更直观地验证编码器设计的正确性.

4.2.2 改进设计
  • 设计:

1.根据3.2.2中的分析,可以编写encoder_plus模块:

module encoder_plus(D, x, y, V);
    input [3:0] D;
    output x, y, V;
    
    assign x = D[2] | D[3];
    assign y = (D[1] & (~D[2])) | D[3];
    assign V = D[0] | D[1] | D[2] | D[3];
endmodule

2.为了能在软件上虚拟仿真,写一个encoder_plus模块的测试平台test_encoder_plus:

//test module
module test_encoder_plus;
    wire x, y, V;
    reg [3:0] D;
    
    encoder_plus M1(D, x, y, V);

    integer i;
    
    initial begin
        $display("Time\tD\t x y V");

        // 遍历所有 16 种输入组合
        for (i = 0; i < 16; i = i + 1) begin
            D = i;
            #1;
            $display("%0d\t%b\t %b %b %b", $time, D, x, y, V);
        end
        
        $finish;
    end
endmodule
  • 仿真结果:

1.根据所设计的程序,在vivado仿真后生成的逻辑电路图如下,符合之前的设计思路:

在这里插入图片描述

2.控制台输出结果如下,符合编码器的功能:

在这里插入图片描述

3.仿真结果时序表如下,直观呈现了输入和输出随时间的变化:

在这里插入图片描述

  • 导入实验板验证:

为了能正确接入到实验板上,需添加约束文件lab1_2_encoder_plus.xdc如下,目的是将程序里的变量与实验板上的组件正确配对:

## Switches
set_property -dict { PACKAGE_PIN J15   IOSTANDARD LVCMOS33 } [get_ports { D[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
set_property -dict { PACKAGE_PIN L16   IOSTANDARD LVCMOS33 } [get_ports { D[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
set_property -dict { PACKAGE_PIN M13   IOSTANDARD LVCMOS33 } [get_ports { D[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
set_property -dict { PACKAGE_PIN R15   IOSTANDARD LVCMOS33 } [get_ports { D[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]

## LEDs
set_property -dict { PACKAGE_PIN H17   IOSTANDARD LVCMOS33 } [get_ports { x }]; #IO_L18P_T2_A24_15 Sch=led[0]
set_property -dict { PACKAGE_PIN K15   IOSTANDARD LVCMOS33 } [get_ports { y }]; #IO_L24P_T3_RS1_15 Sch=led[1]
set_property -dict { PACKAGE_PIN J13   IOSTANDARD LVCMOS33 } [get_ports { V }]; #IO_L17N_T2_A25_15 Sch=led[2]

将文件下载到实验板上进行验证,得到的实拍图片如下:

在这里插入图片描述

其中,开关上拨代表对应的输入变量为1;LED灯亮代表对应的输出变量为1.

前四张图为有效且规范的输入,后四张为对无效输入和不规范输入的处理结果(不规范输入仅3举例).

上述实验结果表明,当仅当有开关上拨时有效位指示灯才会亮;输入规范时,功能与上述初始编码器相当;而输入不规范时,优先编码器对输入进行优先处理.这也能更直观地验证优先编码器设计的正确性.

5.实验总结

5.1 实验中遇到的问题与解决方法

1.在没有实验板的情况下要想初步确定实验设计的正确性,可以在verilog文件中编写自己原先设计的模块的测试平台test_module,通过合理设置时延来改变输入进而改变输出.这样通过vivado软件自带的simulation功能便可观察仿真时序图表.同时还可借助display函数在控制台可视化呈现输出随输入的变化.

2.本实验一个主要的问题就是在编码器设计部分,初始版本有诸多欠缺,如输入的有效性判断,不规范输入等问题,然而可以通过设计一个优先编码器,并添加一个有效指示符的输出变量,便可巧妙地解决这一问题.

5.2 实验体会

本实验通过分析译码器和编码器的工作原理,使用vivado软件以verilog语言设计了一个3-8译码器和4-2编码器,同时将初始的4-2编码器改进设计成优先编码器,最后通过vivado软件仿真和实验板硬件操作,验证了译码器和编码器设计的正确性.通过本实验,加深了对译码,编码工作原理的理解,同时增强了vivado软件结合实验板的操作能力.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值