数码管的动态显示
数码管的动态显示是利用人眼的视觉暂停效应,1ms扫描一次数码管,给不同的数码管不同的数值,最好的扫描频率是1000hz,所以需要一个分频时钟,此实验的任务是实现0-100的累加,1s加一次,废话不多说,以下是源代码:
顶层模块
例化了三个子模块:
包括分频模块,计数模块,数码管动态显示模块
> module dongtaisaomiao(clk,rst_n,seg_sel,seg_led);
> input clk,rst_n;
> output [2:0] seg_sel;
> output [7:0] seg_led;
> wire clk_1hz;
> wire [3:0] bai;
> wire [3:0] shi;
> wire [3:0] ge;
> wire [3:0] hex0;
> wire [3:0] hex1;
> wire [3:0] hex2;
> fenpin u1(
> .clk(clk),
> .rst_n(rst_n),
> .clk_1hz(clk_1hz)
> );
> jiafa u2(
> .clk_1hz(clk_1hz),
> .rst_n(rst_n),
> .bai(bai),
> .shi(shi),
> .ge(ge)
> );
>
> dongtai u3(
> .clk(clk),
> .rst_n(rst_n),
> .hex0(bai),
> .hex1(shi),
> .hex2(ge),
> .seg_sel(seg_sel),
> .seg_led(seg_led)
> );
>
> endmodule
**分频模块**
> module fenpin(clk,rst_n,clk_1hz);
> input clk,rst_n;
> output reg clk_1hz;
> parameter TIME=50000000; //50000000
> reg [25:0] cnt;
> always @(posedge clk or negedge rst_n)
> begin
> if(!rst_n)
> cnt<=0;
> else if(cnt==TIME/2-1)
> cnt<=0;
> else
> cnt<=cnt+1;
> end
> always @(posedge clk or negedge rst_n)
> begin
> if(!rst_n)
> clk_1hz<=0;
> else begin
> if(cnt==TIME/2-1)
> clk_1hz<=~clk_1hz;
> else
> clk_1hz<=clk_1hz;
> end
> end
> endmodule
计数模块 //实现0-100的累加
> module jiafa(clk_1hz,rst_n,bai,shi,ge);
> input clk_1hz;
> input rst_n;
> output reg [3:0] bai;
> output reg [3:0] shi;
> output reg [3:0] ge;
> reg [6:0] cnt; //100
> always @(posedge clk_1hz or negedge rst_n) begin
> if(!rst_n)
> cnt<=0;
> else
> begin
> if(cnt==100)
> cnt<=0;
> else
> cnt<=cnt+1;
> end
> end
>
> always @(posedge clk_1hz or negedge rst_n)
> begin if(!rst_n)
> begin
> bai<=0;
> shi<=0;
> ge<=0;
> end
> else begin
> bai<=cnt/100;
> shi=cnt/10%10;
> ge<=cnt%10;
> end
> end
> endmodule
数码管动态显示模块
> module dongtai(clk,rst_n,hex0,hex1,hex2,seg_sel,seg_led);
> input clk,rst_n;
> input [3:0] hex0;
> input [3:0] hex1;
> input [3:0] hex2;
> output reg [2:0] seg_sel;
> output reg [7:0] seg_led;
> parameter TIME_1ms=50000; //50000
> reg clk_1ms;
> reg [15:0] cnt;
> reg [3:0] data;
> reg [2:0] cnt_sel;
> always @(posedge clk or negedge rst_n)
> begin
> if(!rst_n)
> cnt<=0;
> else
> begin
> if(cnt==TIME_1ms/2-1)
> cnt<=0;
> else
> cnt<=cnt+1;
> end
> end
> //降低频率
> always @(posedge clk or negedge rst_n)
> begin
> if(!rst_n)
> clk_1ms<=0;
> else
> begin
> if(cnt==TIME_1ms/2-1)
> clk_1ms<=~clk_1ms;
> else
> clk_1ms<=clk_1ms;
> end
> end
>
> //扫描数码管
> always @(posedge clk_1ms or negedge rst_n)
> begin if(!rst_n)
> cnt_sel<=0;
> else
> begin
> if(cnt_sel==2)
> cnt_sel<=0;
> else
> cnt_sel<=cnt_sel+1;
> end
> end
> //给位选数据
> always @(posedge clk or negedge rst_n)
> begin
> if(!rst_n)
> seg_sel<=3'b111;
> else
> case(cnt_sel)
> 3'd0: seg_sel<=3'b110;
> 3'd1: seg_sel<=3'b101;
> 3'd2: seg_sel<=3'b011;
> endcase
> end
>
> //给段选数据
> always @(posedge clk or negedge rst_n)
> begin
> if(!rst_n)
> data<=4'b0000;
> else
> begin
> case(seg_sel)
> 3'b110: data<=hex0;
> 3'b101: data<=hex1;
> 3'b011: data<=hex2;
> endcase
> end
> end
>
> //译码模块
> always@(posedge clk or negedge rst_n)
> begin
> if(!rst_n)
> seg_led <= 8'd0;
> else begin
> case (data)
> 4'h0:seg_led <= 8'b11000000;
> 4'h1:seg_led <= 8'b11111001;
> 4'h2:seg_led <= 8'b10100100;
> 4'h3:seg_led <= 8'b10110000;
> 4'h4:seg_led <= 8'b10011001;
> 4'h5:seg_led <= 8'b10010010;
> 4'h6:seg_led <= 8'b10000010;
> 4'h7:seg_led <= 8'b11111000;
> 4'h8:seg_led <= 8'b10000000;
> 4'h9:seg_led <= 8'b10010000;
> 4'ha:seg_led <= 8'b10001000;
> 4'hb:seg_led <= 8'b10000011;
> 4'hc:seg_led <= 8'b11000110;
> 4'hd:seg_led <= 8'b10100001;
> 4'he:seg_led <= 8'b10000110;
> 4'hf:seg_led <= 8'b10001110;
> endcase
> end
> end
> endmodule
经过上板测试后成功。