7段数码管的Verilog模型

-- TOC --

本文介绍7段数码管及其Verilog模型,展示$write函数的使用。

什么是7段数码管

它长这样:

seven_segment_decoder

英文叫 seven segment decoder,所以它是一个decoder,但是它不是二进制decoder。它的作用就是显示0-9这10个数字,以及一些其它符号。上图是1位的7段数码管,还可以多位并排在一起,用来显示多位数字。所谓7段,就是有7个条状的LED或LCD,abcdefg,控制这7个部分的亮和灭,就能显示数字。

关于二进制decoder,请参考:Decoder的Verilog实现

abcdefg

网上看到的这张图,我理解共阴即共同接了低电平,用高电平使能,即所谓的active_high,共阳就是反过来,active_low。

74LS48

74LS48是一个经典的7段数码管译码芯片,逻辑符号如下图:

74ls48

A0-A3是信号输入,使用BCD编码表示数字0-15。abcdefg就是输出了,输入和真值表如下图:

74ls48_output

查看74LS48的输入和输出对应关系,就能看出,BCD编码的输入,并没有被译码成1-out-of-16的编码,因此说,它不是二进制decoder。它的输出没有16位,只有7位。

BCD编码

BCD编码,Binary Coded Decimal,也叫8421码,是最简单的一种用4位二进制数,表示1位0-9十进制数的方式。如下表:

BCD 十进制数
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 8
1001 9

这也是8421编码名字的由来,4位二进制,从高到低,每1位分别表示十进制中的8421。

Verilog实现7段数码管的代码

下面的代码,包括7段数码管模型和测试仿真代码:

`timescale 1ns / 100ps


module seg7dec(BCD, EN, A,B,C,D,E,F,G);
    input [3:0] BCD;
    input EN;
    output A,B,C,D,E,F,G;
    reg [1:7] ATG;

    assign {A,B,C,D,E,F,G} = ATG;
    always @ (*) begin
        if (EN)
            case (BCD)
                4'd0: ATG = 7'b1111110;  // 0
                4'd1: ATG = 7'b0110000;  // 1
                4'd2: ATG = 7'b1101101;  // 2
                4'd3: ATG = 7'b1111001;  // 3
                4'd4: ATG = 7'b0110011;  // 4
                4'd5: ATG = 7'b1011011;  // 5
                4'd6: ATG = 7'b0011111;  // 6
                4'd7: ATG = 7'b1110000;  // 7
                4'd8: ATG = 7'b1111111;  // 8
                4'd9: ATG = 7'b1110011;  // 9
                default ATG = 7'b0000000;
            endcase
        else ATG = 7'b0000000;
    end
endmodule


module test_seg7dec();
    reg EN;
    reg [3:0] BCD;
    wire A,B,C,D,E,F,G;
    integer i;

    seg7dec UUT(BCD, EN, A,B,C,D,E,F,G);
    initial begin
        for (i=0; i<32; i=i+1) begin
            {EN,BCD} = i;
            #10;
            $write("iteration i=%d\n", i);
            if (EN) begin
                if (A) $write(" __\n"); else $write("\n");
                if (F) $write("|"); else $write(" ");
                if (G) $write("__"); else $write("  ");
                if (B) $write("|\n"); else $write("\n");
                if (E) $write("|"); else $write(" ");
                if (D) $write("__"); else $write("  ");
                if (C) $write("|\n"); else $write("\n");
                #10;
            end
        end
        $display("Tes Done!");
    end
endmodule

module seg7dec 只实现了0-9的显示,其它BCD输入一律输出全0,此时对应74LS48的输入15,空白,7段都不亮。测试代码使用verilog内置的$write函数,此函数与$display的区别是,$write默认不会换行,$display默认换行。

仿真结果

这次不看wave,就看测试代码的打印。测试代码有趣的地方在于,它用$write函数,将0-9个数字按照7段的方式打印了出来,如下:

# iteration i=          0
# iteration i=          1
# iteration i=          2
# iteration i=          3
# iteration i=          4
# iteration i=          5
# iteration i=          6
# iteration i=          7
# iteration i=          8
# iteration i=          9
# iteration i=         10
# iteration i=         11
# iteration i=         12
# iteration i=         13
# iteration i=         14
# iteration i=         15
# iteration i=         16
#  __
# |  |
# |__|
# iteration i=         17
# 
#    |
#    |
# iteration i=         18
#  __
#  __|
# |__
# iteration i=         19
#  __
#  __|
#  __|
# iteration i=         20
# 
# |__|
#    |
# iteration i=         21
#  __
# |__
#  __|
# iteration i=         22
# 
# |__
# |__|
# iteration i=         23
#  __
#    |
#    |
# iteration i=         24
#  __
# |__|
# |__|
# iteration i=         25
#  __
# |__|
#    |
# iteration i=         26
# 
#    
#    
# iteration i=         27
# 
#    
#    
# iteration i=         28
# 
#    
#    
# iteration i=         29
# 
#    
#    
# iteration i=         30
# 
#    
#    
# iteration i=         31
# 
#    
#    
# Tes Done!

由此可以看出,7段数码管的7个output的编码,也是有讲究的。

本文链接:https://cs.pynote.net/hd/verilog/202109305/

-- EOF --

-- MORE --