数字系统设计实验六:用verilog实现4位led译码器电路

1.问题重述:
用Verilog HDL设计一个4位LED显示器的动态扫描译码电路。要求:4个七段显示器共用一个译码驱动电路。

2.问题分析:
a.首先是,我们需要明确的是什么是动态扫描译码电路。译码器即是输入数字,将对应的数字显示在led灯上,一个数字对应一种led点亮的灯序号。那么要想进行扫描,可以静态扫描,每次接受一个数字,都更新一次led的点亮序号,对应led灯同时点亮。而动态扫描就是每次扫描只点亮一盏灯,利用人的视觉暂留效果,达到数字显示的功能。这个视觉暂留时间是大约0.1s,那么我们进行扫描的时间不能大于0.1s。
b.其次是,led灯的点亮方式分共阴极和共阳极。共阴极即led二极管的阴极共同接在gnd上,另外的引脚有信号控制,信号接高电平,则点亮;共阳极即led二极管的阳极共同接在vdd上,另外的引脚有信号控制,信号接低电平,则点亮。
在这里插入图片描述

c.对控制信号的分析:按照下面的图示进行编号,一个数字的显示需要七位的数据进行控制,具体的对应关系如下(暂时忽略顿号)。
4’d0: segment=7’b1111110;
4’d1: segment=7’b0110000;
4’d2: segment=7’b1101101;
4’d3: segment=7’b1111001;
4’d4: segment=7’b0110011;
4’d5: segment=7’b1011011;
4’d6: segment=7’b1011111;
4’d7: segment=7’b1110000;
4’d8: segment=7’b1111111;
4’d9: segment=7’b1111011;
题目要求四位的led显示,采用静态译码则需要4*7=28个输出控制位,采用动态译码则需要4位选位和7个数字译码信号。很显然,动态译码在这方面具有很大的优势。

按下图的方式进行选位编码:
在这里插入图片描述

d.程序设计如下:将通过一个模块来实现这个功能。输入4个10进制数(16位二进制数字),通过case语句译码为4位选通信号,通过另一个case语句译码为数字显示信号。另外有rst信号进行归零操作。

3.代码详细:
.v文件:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: jeffery

module led(number,segment,chip,clk,rst);

input [15:0] number;
input clk,rst;
output reg [6:0] segment;
output reg [3:0] chip;


//这个always语句是完成了选通信号的逐个开启,0,1,2,3四个状态
reg [1:0] cnt;
always @(posedge clk or negedge rst)//rst信号的下降沿将触发这个模块,是他们在任何条件都进行复位操作
    begin
    if(!rst)
        cnt=0;
    else
        cnt=cnt+1;
    end

    
    
//这个部分是对每次选择的数字,以及对应显示的片进行了选择
reg [3:0] number_reading;//number_reading是用来表示通过片选信号按顺序显示数字,这时正在读取的数字
always @(posedge clk or negedge rst)
    begin
if(!rst)
  begin
        number_reading=1'd0;
        end
    else
        begin
            case(cnt)
            2'b11: 
                begin
                number_reading=number[3:0];
                chip=4'b0001;
                end
            2'b10: 
                begin
                number_reading=number[7:4];
                chip=4'b0010;
                end
            2'b01: 
                begin
                number_reading=number[11:8];
                chip=4'b0100;
                end
            2'b00: 
                begin
                number_reading=number[15:12];//从左边的数开始输出
                chip=4'b1000;
                end
            default: 
                begin
                number_reading=1'd0;
                chip=4'b0000;
                end
            endcase
        end
    end
    
//这个always语句是对segment进行了数字编码
always @(posedge clk or negedge rst)
    begin
    if(!rst)
        segment=7'b0;
    else
        begin
            case(number_reading)
            4'd0: segment=7'b1111110;
            4'd1: segment=7'b0110000;
            4'd2: segment=7'b1101101;
            4'd3: segment=7'b1111001;
            4'd4: segment=7'b0110011;
            4'd5: segment=7'b1011011;
            4'd6: segment=7'b1011111;
            4'd7: segment=7'b1110000;
            4'd8: segment=7'b1111111;
            4'd9: segment=7'b1111011;
            default: segment=7'b0;
            endcase
        end
    
    end
    
endmodule

Tb文件:

`timescale 1ns / 1ps


module tb();

reg [15:0] number;
reg clk,rst;

wire [6:0] segment;
wire [3:0] chip;

led my_led(.number(number),.segment(segment),.chip(chip),.clk(clk),.rst(rst));

initial
    begin 
    clk=0;
    rst=0;
 #2 rst=1;number=0;
#8 number[15:12]=4'd5;number[11:8]=4'd4;number[7:4]=4'd3;number[3:0]=4'd2;//测试信号为5432
    #8 number[15:12]=4'd9;number[11:8]=4'd9;number[7:4]=4'd9;number[3:0]=4'd9;//测试信号为9999
    #8 number[15:12]=4'd2;number[11:8]=4'd0;number[7:4]=4'd2;number[3:0]=4'd2;//测试信号为2022
    #8 number[15:12]=4'd0;number[11:8]=4'd9;number[7:4]=4'd1;number[3:0]=4'd3;//测试信号为0913
    #8 rst=0;
    #8 rst=1;
    #8 number[15:12]=4'd10;number[11:8]=4'd11;number[7:4]=4'd12;number[3:0]=4'd13;//测试信号溢出
    #8 rst=0;
    end


//生成clk信号,周期和系统最小时钟周期的两倍
always 
    begin
    #1 clk=~clk;
    end
    
endmodule 

4.测试结果

在这里插入图片描述

在这里插入图片描述
1)通过观察测试信号发现,由于cnt的起始数字由于测试发生变化而不同,即显示数字的顺序不是从左往右显示,而是3—2—1—4的顺序,但选片信号与数字信号的对应关系没有改变,这部分在代码内是由同一个begin_end块实现的,所以对功能没有影响。
2)对给定的输入测试,其输出满足下列对应关系:
4’d0: segment=7’b1111110;
4’d1: segment=7’b0110000;
4’d2: segment=7’b1101101;
4’d3: segment=7’b1111001;
4’d4: segment=7’b0110011;
4’d5: segment=7’b1011011;
4’d6: segment=7’b1011111;
4’d7: segment=7’b1110000;
4’d8: segment=7’b1111111;
4’d9: segment=7’b1111011;
3)复位信号可以顺利的使输出为0,并且当输入数字超过范围时,也不会进行输出。
经过测试,以上代码的功能正常。

  • 2
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值