TA的每日心情 | 开心 2016-9-21 20:33 |
---|
签到天数: 29 天 连续签到: 1 天 [LV.4]偶尔看看III
|
从零开始学FPGA我的第七个实验(记录一下)
第七个实验是编写数码管的驱动
驱动数码管动态扫描显示,驱动的模型是:
实际上使用了一个六选一的数据选择器输入的数据是24位的,分成了【3:0】【7:4】【11:8】【15:12】【19:16】【23:20】分成了6个数据长度为4的数据。
左下角的是分频器也就是计数器,将50MHZ的时钟分频成为1KHZ的时钟周期为1ms的时钟信号 50MHZ-----一个周期是20ns 1KHZ半个周期是0.5ms=500000ns所以计数器的计数值是500000/20=25000(为什么是用半个周期除以系统时钟周期呢?自己的理解是因为计数是沿边沿计数的)1ms产生移位欺骗人眼的时间要小于20ms
下面是代码:- 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
复制代码 测试代码 testbench:- `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
复制代码 rtl仿真:
符合编码
门级仿真:
待续。。。
|
|