找回密码
 注册
关于网站域名变更的通知
查看: 291|回复: 1
打印 上一主题 下一主题

转——从零开始学FPGA——by ihalin——编写数码管的驱动

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-4-1 15:30 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
从零开始学FPGA我的第七个实验(记录一下)# j) c) q: p+ E/ J5 s
第七个实验是编写数码管的驱动1 W3 H1 s1 c/ q# R+ L# p
驱动数码管动态扫描显示,驱动的模型是:0 q6 v4 v: t5 t# v' u: u
" c. l6 ?/ E' b0 }( L
左上角是一个六选一的数据选择器输入的数据是24位的,分成了【3:0】【7:4】【11:8】【15:12】【19:16】【23:20】分成了8个数据长度为4的数据。: |) M, `. m+ a  d) q/ R
左下角的是分频器也就是计数器,将50MHZ的时钟分频成为1KHZ的时钟周期为1ms的时钟信号 50MHZ-----一个周期是20ns 1KHZ半个周期是0.5ms=500000ns所以计数器的计数值是500000/20=25000(为什么是用半个周期除以系统时钟周期呢?自己的理解是因为计数是沿边沿计数的)1ms产生移位欺骗人眼的时间要小于20ms
0 o  |) o+ O; o; s下面是代码:
) X8 Z- W& S( y/ U4 ?2 S# P
  • module SMG(Clk,Rst_n,En,data,sel,seg);
  •                
  •                
  •                 input Clk;
  •                 input Rst_n;
  •       input En;
  •                
  •                 input [23:0]data;
  •                
  •                 output [5:0] sel;//数码管的位选
  •                 output reg [6:0] seg;//数码管的段选(要显示的内容)
  •                
  •                 reg [14:0] div_cnt;//25000-1=24999
  •                 reg clk_1k;
  •                 reg [5:0]sel_r;
  •                 reg [3:0]data_tmp;//数据缓存
  •         //计数器从0计数到24999        
  •                 always @(posedge Clk or negedge Rst_n)
  •                 if(!Rst_n)
  •                 div_cnt <=15'd0;
  •                 else if (!En)
  •                 div_cnt <=15'd0;
  •                 else if(div_cnt == 24999)
  •            div_cnt <= 15'd0;
  •            else
  •                         div_cnt = div_cnt + 1'b1;
  • //但计数满了24999的时候clk_1k翻转一次产生1khz的clk 时钟信号
  •                 always @(posedge Clk or negedge Rst_n)
  •                 if(!Rst_n)
  •                         clk_1k <= 1'b0;
  •                 else if (div_cnt == 24999)
  •                 clk_1k <= ~clk_1k;
  •                 else
  •                    clk_1k <= clk_1k;
  •                
  • //循环移位的寄存器
  •                 always@(posedge clk_1k or negedge Rst_n)
  •                         if(!Rst_n)
  •                             sel_r <= 6'b00_0001;
  •                         else if(sel_r == 6'b10_0000)
  •                             sel_r <= 6'b00_0001;
  •                         else
  •                            sel_r <= sel_r << 1;
  • //选择显示数据
  •                 always @(*)
  •                    case (sel_r)
  •                            6'b00_0001: data_tmp = data[3:0];
  •                                 6'b00_0010: data_tmp = data[7:4];
  •                                 6'b00_0100: data_tmp = data[11:8];
  •                                 6'b00_1000: data_tmp = data[15:12];
  •                                 6'b01_0000: data_tmp = data[19:16];
  •                                 6'b10_0000: data_tmp = data[23:20];
  •                                 default :data_tmp =4'b0000;
  •                         endcase
  • //查表显示0到f的数据                        
  •                 always@(*)
  •                case(data_tmp)//查表
  •                         4'h0:seg = 7'b1000000;
  •                         4'h1:seg = 7'b1111001;
  •                         4'h2:seg = 7'b0100100;
  •                         4'h3:seg = 7'b0110000;
  •                         4'h4:seg = 7'b0011001;
  •                         4'h5:seg = 7'b0010010;
  •                         4'h6:seg = 7'b0000010;
  •                         4'h7:seg = 7'b1111000;
  •                         4'h8:seg = 7'b0000000;
  •                         4'h9:seg = 7'b0010000;
  •                         4'ha:seg = 7'b0001000;
  •                         4'hb:seg = 7'b0000011;
  •                         4'hc:seg = 7'b1000110;
  •                         4'hd:seg = 7'b0100001;
  •                         4'he:seg = 7'b0000110;
  •                         4'hf:seg = 7'b0001110;
  •                 endcase
  • //        位选的实现        
  •                         assign sel =(En)? sel_r:6'b00_0000;
  • endmodule

  • + X- L' c4 m7 a( `* l
* W+ M7 W$ N, `4 B9 `0 a
. b/ ^! J3 Y# L9 Y  W; Z. g
& s' K5 M5 i, U  h/ Q  x& w

$ v' C# P9 m4 X  f, M( E; J测试代码 testbench:& i" v3 T- ^4 w$ G2 Z4 J+ s
  • `timescale 1ns/1ns
  • `define clk_period 20
  • //20ns = 50mhz
  • module SMG_tb;
  • reg Clk;
  • reg Rst_n;
  • reg En;
  • reg [23:0] data;
  • wire [5:0]sel;//位选
  • wire [6:0]seg;//段选
  • SMG SMG0(
  •     .Clk(Clk),
  •     .Rst_n(Rst_n),
  •          .En(En),
  •          .data(data),
  •          .sel(sel),
  •          .seg(seg)
  •           );
  •    initial Clk = 1;
  •         always #(`clk_period/2) Clk = ~Clk;
  •         
  •    initial begin
  •            Rst_n = 1'b0;
  •                 En = 1;
  •                 data = 24'h123456;
  •                 #(`clk_period *30);
  •                 Rst_n =1;
  •                 #20000000;
  •                 data =24'h201607;
  •                 #20000000;
  •                 data =24'h202009;
  •                 #20000000;
  •                 $stop;
  •         end
  •         
  • endmodule
    2 q$ ~* F( Q3 s: S
5 x5 z* k) Z7 v

/ [. {, ~! b. @7 H' v3 d# @3 D
; }) h. Y3 X+ _- i& i8 Z8 J4 H

: l1 o& O) J- M9 L, ], ~+ S
& z+ c0 {. a7 ^1 j8 P8 f1 B, r& J2 O) p' O/ `
rtl波形:
( S/ J3 W6 G0 h( k  R, G1 m; ` % K) M5 @) t5 t8 N
符合对应的编码
) O$ T+ I. N, ]5 D8 m2 P1 m9 Y门级仿真:; F1 ?4 E) N4 _. `: Y0 n. M4 T* P$ q

% I4 P* F  `& O( F; L
5 Q/ C& _6 Q# p. k8 P/ N" Xquartus ii 15版本的 In system sources and probes editor (issp)还不太会使用,在板子上的仿真就明天发吧。晚安。。
  M- L1 {: R6 ?6 S
' l8 N5 g9 M0 {8 K4 U- t
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-7-29 03:47 , Processed in 0.140625 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表