开发板实战篇2 6位数码管静态显示

        与"开发板实战篇1 LED点灯(开篇)" 的区别,增加模式切换

 总结:

        模块例化思想: 定时器模块 + 点灯模块

        根据自己思路编写代码,调试仿真代码,同时熟悉环境.加深细节理解 

        segled_static_driver.v 实现不够简洁,感觉还可以优化,后面有思路再搞

      

注意:

        若进行了QuartusII_13.0 和 Notepad++软件的关联,在modelsim中无法双击打开.v文件,只能通过工具栏的open文件夹图标打开, 我的电脑会打开altium designer软件 ,取消关联可恢复正常

        每次打开modelsim时需要切换工作空间,否则可能创建工程添加的源码会是上一个仿真工程的代码,导致出错 

一. 实现的功能

        6位数码管以静态方式依次显示000000、 111111、222222至FFFFFF,结束后继续从000000开始计数,每1s变化一次。
 

二. 功能框图

        定时器模块:加计数器,计数到了产生overflow信号

        segled控制模块:根据en使能信号,点亮数码管

        打开方法:  tools -> netlist viewers -> rtl viewer

三. RTL代码

        segled_static_top.v

        与led_top.v基本相同。

        COUNT_OVERFLOW = 26'd50_000_000,即闪烁周期为1S。

module segled_static_top (
    input clk,
    input reset,
    output [5:0] sel,
    output [7:0] seg_led
);

parameter COUNT_OVERFLOW = 26'd50_000_000;

wire   overflow;                 // 定时时间到

timer #(
  .COUNT_OVERFLOW (COUNT_OVERFLOW)
  )
  u_timer(
  .clk      (clk),
  .reset    (reset),
  .overflow (overflow)
);

segled_static_driver u_segled_static_driver(clk,reset,overflow,sel,seg_led);

    
endmodule

        timer.v

        除将overflow <=修改为非阻塞赋值外,其它与led点灯工程的相同。

/*
********************************************************************************
  *Copyright ©, 2018, CunXin_ All Rights Reserved
  *文 件 名: key_led.v
  *说    明: 
            程序功能无按键按下时, LED灯全灭; 
            按键1按下时, LED灯显示自右向左的流水效果;
            按键2按下时, LED灯显示自左向右的流水效果;
            按键3按下时,四个LED灯同时闪烁;
            按键4按下时, LED灯全亮
  *版    本: V000B00D00
  *创建日期: 2018年4月3日		下午12:16:49
  *创 建 人: wansaiyon
  *修改信息:  
================================================================================
  *修 改 人    		  修改日期       	  修改内容 
  *<作者/修改者>      <YYYY/MM/DD>		  <修改内容>
********************************************************************************
*/

module timer #(
    parameter COUNT_OVERFLOW = 26'd10_000_000
) (
    input clk,
    input reset,
    output reg overflow
);

localparam period = COUNT_OVERFLOW;

reg [25:0] cnt;

always @(posedge clk,negedge reset) begin
    if(!reset) begin
      cnt <= 26'd0;
      overflow <= 1'b0;
    end        
    else if(cnt < period) begin
      cnt <= cnt + 1'd1;
      overflow <= 1'b0;
    end        
    else begin
      cnt <= 26'd0;
      overflow <= 1'b1;
    end
        
end

endmodule

        segled_static_driver.v

        主要功能:定义16个字符、显示字符状态切换、、seg_led显示输出。

/*
6位数码管			
sel[0]	output	N16	第一个数码管位选信号
sel[1]	output	N15	第二个数码管位选信号
sel[2]	output	P16	第三个数码管位选信号
sel[3]	output	P15	第四个数码管位选信号
sel[4]	output	R16	第五个数码管位选信号
sel[5]	output	T15	第六个数码管位选信号
seg_led[0]	output	M11	数码管段选a
seg_led[1]	output	N12	数码管段选b
seg_led[2]	output	C9	数码管段选c
seg_led[3]	output	N13	数码管段选d
seg_led[4]	output	M10	数码管段选e
seg_led[5]	output	N11	数码管段选f
seg_led[6]	output	P11	数码管段选g
seg_led[7]	output	D9	数码管段选h
*/

module segled_static_driver (
    input clk,
    input reset,
    input en,
    output reg [5:0] sel,
    output reg [7:0] seg_led
);

// param define  
localparam CHAR_0 = 8'b0100_0000;
localparam CHAR_1 = 8'b0111_1001;
localparam CHAR_2 = 8'b0010_0100;
localparam CHAR_3 = 8'b0011_0000;
localparam CHAR_4 = 8'b0001_1001;
localparam CHAR_5 = 8'b0001_0010;
localparam CHAR_6 = 8'b0000_0010;
localparam CHAR_7 = 8'b0111_1000;
localparam CHAR_8 = 8'b0000_0000;
localparam CHAR_9 = 8'b0001_0000;
localparam CHAR_a = 8'b0000_1000;
localparam CHAR_b = 8'b0000_0011;
localparam CHAR_c = 8'b0100_0110;
localparam CHAR_d = 8'b0010_0001;
localparam CHAR_e = 8'b0000_0110;
localparam CHAR_f = 8'b0000_1110;

//reg define     
reg [3:0] segled_ctrl;

// 显示状态切换
always @(posedge clk,negedge reset ) begin
    if(!reset) begin
        segled_ctrl <= 4'b0000;
    end
    else if(en) begin
        segled_ctrl <= segled_ctrl + 1'b1;
    end
    else begin
        segled_ctrl <= segled_ctrl;
    end    
end

// seg_led 输出显示
always @(posedge clk ,negedge reset) begin
    if(!reset) begin
        sel <= 6'b00_0000;
        seg_led <= CHAR_8;
    end
    else if(en) begin
        sel <= 6'b00_0000;
        casex (segled_ctrl)
            4'b0000: begin 
				seg_led <= CHAR_0;
            end
            4'b0001: begin 
				seg_led <= CHAR_1;
            end
            4'b0010: begin 
				seg_led <= CHAR_2;
            end
            4'b0011: begin 
				seg_led <= CHAR_3;
            end
            4'b0100: begin 
				seg_led <= CHAR_4;
            end
            4'b0101: begin 
				seg_led <= CHAR_5;
            end
            4'b0110: begin 
				seg_led <= CHAR_6;
            end
            4'b0111: begin 
				seg_led <= CHAR_7;
            end
            4'b1000: begin 
				seg_led <= CHAR_8;
            end
            4'b1001: begin 
				seg_led <= CHAR_9;
            end
            4'b1010: begin 
				seg_led <= CHAR_a;
            end
            4'b1011: begin 
				seg_led <= CHAR_b;
            end
            4'b1100: begin 
				seg_led <= CHAR_c;
            end
            4'b1101: begin 
				seg_led <= CHAR_d;
            end
            4'b1110: begin 
				seg_led <= CHAR_e;
            end
            4'b1111: begin 
				seg_led <= CHAR_f;
            end
            default: begin
				seg_led <= CHAR_0;
            end
        endcase
    end
    else begin
        sel <= 6'b00_0000;
        seg_led <= seg_led;
    end
end
    
endmodule

四.modelsim前仿真(功能仿真)

        每次打开modelsim时需要切换工作空间,否则可能创建工程添加的源码会是上一个仿真工程的代码,导致出错 。

        使用vscode打开segled_static_top.v, ctrl+shift+p,输入testbench,在terminal生成了segled_static_top_tb.v代码,需要安装插件verilog_testbench, 初始生成时可能提示失败,需要安装 python 库(根据错误提示自行百度)。

        生成的代码有点错误,需要自己再做点修改。

        segled_static_top_tb.v,

        为了方便减小了计数器周期为26'd10。

`timescale  1ns / 1ns

module tb_segled_static_top;

// segled_static_top Parameters
parameter PERIOD          = 10            ;     
parameter COUNT_OVERFLOW  = 26'd10;     

// segled_static_top Inputs
reg   clk                                  = 0 ;
reg   reset                                = 0 ;

// segled_static_top Outputs
wire  [5:0]  sel                           ;    
wire  [7:0]  seg_led                       ;    


initial
begin
    forever #(PERIOD/2)  clk=~clk;
end

initial
begin
    #(PERIOD*2) reset  =  1;
end

segled_static_top #(
    .COUNT_OVERFLOW ( COUNT_OVERFLOW ))
 u_segled_static_top (
    .clk                     ( clk            ),
    .reset                   ( reset          ),

    .sel                     ( sel      [5:0] ),
    .seg_led                 ( seg_led  [7:0] )
);


endmodule

        仿真波形

五.下载验证

        6位数码管以静态方式依次显示000000、 111111、222222至FFFFFF,结束后继续从000000开始计数,每1s变化一次。

        但是发现4个LED有微弱的亮度,需要配置好未使用管脚的状态为高阻输入,同时将nCEO管脚修改为Use as regular I/0,修改后LED变为熄灭状态了。

        在 Quartus 软件中默认未使用管脚的状态为弱上拉输入,所以未使用到的管脚上也是有电压的,只是驱动能力很弱,这往往会导致一些不安全的隐患,所以我们需要将未使用管脚的状态设置为三态输入。        

        在左侧Category一栏中选择Dual-Purpose Pin。对于需要使用EPCS器件的引脚时,需要将下图页面中所有的引脚都改成Use as regular IO,如果大家不确定工程中是否用到EPCS器件时,可以全部修改。本次实验只修改了nCEO一栏中, 将Use as programming pin修改为Use as regular I/0。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值