FPGA数码管显示自动计数+按键计数+蜂鸣器
生活随笔
收集整理的這篇文章主要介紹了
FPGA数码管显示自动计数+按键计数+蜂鸣器
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在文章下評論郵箱直接發工程
?top頂層文件
module seg_test(input clk,input rst_n,input key1,input key2,output buzzer,output [5:0] seg_sel,output [7:0] seg_data ); wire button_negedge; ax_debounce ax_debounce_m0 (.clk (clk),.rst (~rst_n),.button_in (key1),.button_posedge (),.button_negedge (button_negedge),.button_out () ); wire[3:0] count; wire t0; count_m10 count10_m0(.clk (clk),.rst_n (rst_n),.en (button_negedge),.clr (1'b0),.data (count),.t (t0) ); wire[3:0] count1; wire t1; count_m10 count10_m1(.clk (clk),.rst_n (rst_n),.en (t0),.clr (1'b0),.data (count1),.t (t1) ); wire[3:0] count2; wire t2; count_m10 count10_m2(.clk (clk),.rst_n (rst_n),.en (t1),.clr (1'b0),.data (count2),.t (t2) ); reg[31:0] timer_cnt; reg en_1hz; always@(posedge clk or negedge rst_n) beginif(rst_n == 1'b0)beginen_1hz <= 1'b0;timer_cnt <= 32'd0;endelse if(timer_cnt >= 32'd49_999_999)beginen_1hz <= 1'b1;timer_cnt <= 32'd0;endelsebeginen_1hz <= 1'b0;timer_cnt <= timer_cnt + 32'd1; end end wire[3:0] count3; wire t3; count_m10 count10_m3(.clk (clk),.rst_n (rst_n),.en (en_1hz),.clr (1'b0),.data (count3),.t (t3) ); wire[3:0] count4; wire t4; count_m10 count10_m4(.clk (clk),.rst_n (rst_n),.en (t3),.clr (1'b0),.data (count4),.t (t4) ); wire[3:0] count5; wire t5; count_m10 count10_m5(.clk (clk),.rst_n (rst_n),.en (t4),.clr (1'b0),.data (count5),.t (t5) ); wire[6:0] seg_data_3; seg_decoder seg_decoder_m3(.bin_data (count3),.seg_data (seg_data_3) );wire[6:0] seg_data_4; seg_decoder seg_decoder_m4(.bin_data (count4),.seg_data (seg_data_4) ); wire[6:0] seg_data_5; seg_decoder seg_decoder_m(.bin_data (count5),.seg_data (seg_data_5) ); wire[6:0] seg_data_0; seg_decoder seg_decoder_m0(.bin_data (count),.seg_data (seg_data_0) );wire[6:0] seg_data_1; seg_decoder seg_decoder_m1(.bin_data (count1),.seg_data (seg_data_1) ); wire[6:0] seg_data_2; seg_decoder seg_decoder_m2(.bin_data (count2),.seg_data (seg_data_2) ); seg_scan seg_scan_m0(.clk (clk),.rst_n (rst_n),.seg_sel (seg_sel),.seg_data (seg_data),.seg_data_0 ({1'b1,seg_data_5}),.seg_data_1 ({1'b1,seg_data_4}),.seg_data_2 ({1'b1,seg_data_3}),.seg_data_3 ({1'b1,seg_data_2}),.seg_data_4 ({1'b1,seg_data_1}),.seg_data_5 ({1'b1,seg_data_0}) ); buzzer_pwm_test buzzer_pwm_test_m0(. clk(clk),.rst_n(rst_n),.key2(key2),.buzzer(buzzer) ); endmodule按鍵key消抖
`timescale 1 ns / 100 ps module ax_debounce (input clk, input rst, input button_in,output reg button_posedge,output reg button_negedge,output reg button_out );---------------- internal constants -------------- parameter N = 32 ; // debounce timer bitwidth parameter FREQ = 50; //model clock :Mhz parameter MAX_TIME = 20; //ms localparam TIMER_MAX_VAL = MAX_TIME * 1000 * FREQ; ---------------- internal variables --------------- reg [N-1 : 0] q_reg; // timing regs reg [N-1 : 0] q_next; reg DFF1, DFF2; // input flip-flops wire q_add; // control flags wire q_reset; reg button_out_d0;------------------------------------------------------contenious assignment for counter control assign q_reset = (DFF1 ^ DFF2); // xor input flip flops to look for level chage to reset counter assign q_add = ~(q_reg == TIMER_MAX_VAL); // add to counter when q_reg msb is equal to 0combo counter to manage q_next always @ ( q_reset, q_add, q_reg) begincase( {q_reset , q_add})2'b00 :q_next <= q_reg;2'b01 :q_next <= q_reg + 1;default :q_next <= { N {1'b0} };endcase endFlip flop inputs and q_reg update always @ ( posedge clk or posedge rst) beginif(rst == 1'b1)beginDFF1 <= 1'b0;DFF2 <= 1'b0;q_reg <= { N {1'b0} };endelsebeginDFF1 <= button_in;DFF2 <= DFF1;q_reg <= q_next;end endcounter control always @ ( posedge clk or posedge rst) beginif(rst == 1'b1)button_out <= 1'b1;else if(q_reg == TIMER_MAX_VAL)button_out <= DFF2;elsebutton_out <= button_out; endalways @ ( posedge clk or posedge rst) beginif(rst == 1'b1)beginbutton_out_d0 <= 1'b1;button_posedge <= 1'b0;button_negedge <= 1'b0;endelsebeginbutton_out_d0 <= button_out;button_posedge <= ~button_out_d0 & button_out;button_negedge <= button_out_d0 & ~button_out;end end endmoduleseg_scan
module seg_scan(input clk,input rst_n,output reg[5:0] seg_sel, //digital led chip selectoutput reg[7:0] seg_data, //eight segment digital tube output,MSB is the decimal pointinput[7:0] seg_data_0,input[7:0] seg_data_1,input[7:0] seg_data_2,input[7:0] seg_data_3,input[7:0] seg_data_4,input[7:0] seg_data_5 ); parameter SCAN_FREQ = 200; //scan frequency parameter CLK_FREQ = 50000000; //clock frequencyparameter SCAN_COUNT = CLK_FREQ /(SCAN_FREQ * 6) - 1;reg[31:0] scan_timer; //scan time counter reg[3:0] scan_sel; //Scan select counter always@(posedge clk or negedge rst_n) beginif(rst_n == 1'b0)beginscan_timer <= 32'd0;scan_sel <= 4'd0;endelse if(scan_timer >= SCAN_COUNT)beginscan_timer <= 32'd0;if(scan_sel == 4'd5)scan_sel <= 4'd0;elsescan_sel <= scan_sel + 4'd1;endelsebeginscan_timer <= scan_timer + 32'd1;end end always@(posedge clk or negedge rst_n) beginif(rst_n == 1'b0)beginseg_sel <= 6'b111111;seg_data <= 8'hff;endelsebegincase(scan_sel)//first digital led4'd0:beginseg_sel <= 6'b11_1110;seg_data <= seg_data_0;end//second digital led4'd1:beginseg_sel <= 6'b11_1101;seg_data <= seg_data_1;end//...4'd2:beginseg_sel <= 6'b11_1011;seg_data <= seg_data_2;end4'd3:beginseg_sel <= 6'b11_0111;seg_data <= seg_data_3;end4'd4:beginseg_sel <= 6'b10_1111;seg_data <= seg_data_4;end4'd5:beginseg_sel <= 6'b01_1111;seg_data <= seg_data_5;enddefault:beginseg_sel <= 6'b11_1111;seg_data <= 8'hff;endendcaseend endendmoduleseg_decoder
module seg_decoder (input[3:0] bin_data, // bin data inputoutput reg[6:0] seg_data // seven segments LED output );always@(*) begincase(bin_data)4'd0:seg_data <= 7'b100_0000;4'd1:seg_data <= 7'b111_1001;4'd2:seg_data <= 7'b010_0100;4'd3:seg_data <= 7'b011_0000;4'd4:seg_data <= 7'b001_1001;4'd5:seg_data <= 7'b001_0010;4'd6:seg_data <= 7'b000_0010;4'd7:seg_data <= 7'b111_1000;4'd8:seg_data <= 7'b000_0000;4'd9:seg_data <= 7'b001_0000;4'ha:seg_data <= 7'b000_1000;4'hb:seg_data <= 7'b000_0011;4'hc:seg_data <= 7'b100_0110;4'hd:seg_data <= 7'b010_0001;4'he:seg_data <= 7'b000_0110;4'hf:seg_data <= 7'b000_1110;default:seg_data <= 7'b111_1111;endcase end endmodulecount_m10
module count_m10(input clk,input rst_n,input en, //Counter enableinput clr, //Counter synchronous reset output reg[3:0]data, //counter valueoutput reg t // carry enable signal); always@(posedge clk or negedge rst_n) beginif(rst_n==0)begindata <= 4'd0;t <= 1'd0;endelse if(clr)begindata <= 4'd0;t <= 1'd0; endelse if(en)beginif(data==4'd9)begint<= 1'b1; //Counter to 9 to generate carrydata <= 4'd0;//Counter to 9 resetendelsebegint <= 1'b0;data <= data + 4'd1;endendelset <= 1'b0; endendmoduleax_pwm
`timescale 1ns / 1ps module ax_pwm #(parameter N = 16 //pwm bit width ) (input clk,input rst,input[N - 1:0]period,input[N - 1:0]duty,output pwm_out );reg[N - 1:0] period_r; reg[N - 1:0] duty_r; reg[N - 1:0] period_cnt; reg pwm_r; assign pwm_out = pwm_r; always@(posedge clk or posedge rst) beginif(rst==1)beginperiod_r <= { N {1'b0} };duty_r <= { N {1'b0} };endelsebeginperiod_r <= period;duty_r <= duty;end endalways@(posedge clk or posedge rst) beginif(rst==1)period_cnt <= { N {1'b0} };elseperiod_cnt <= period_cnt + period_r; endalways@(posedge clk or posedge rst) beginif(rst==1)beginpwm_r <= 1'b0;endelsebeginif(period_cnt >= duty_r)pwm_r <= 1'b1;elsepwm_r <= 1'b0;end endendmodulebuzzer_pwm_test
module buzzer_pwm_test(input clk,input rst_n,input key2,output buzzer); parameter IDLE = 0; parameter BUZZER = 1; wire button_negedge; wire pwm_out; reg[31:0] period; reg[31:0] duty;reg[3:0] state; reg[31:0] timer; assign buzzer = ~(pwm_out & (state == BUZZER));//buzzer low activealways@(posedge clk or negedge rst_n) beginif(rst_n == 1'b0)beginperiod <= 32'd0;timer <= 32'd0;duty <= 32'd429496729;state <= IDLE;endelsecase(state)IDLE:beginif(button_negedge)beginperiod <= 32'd8590; //The pwm step valuestate <= BUZZER;duty <= duty + 32'd429496729;endendBUZZER:beginif(timer >= 32'd12_499_999) //buzzer effictive time 250msbeginstate <= IDLE;timer <= 32'd0;endelsebegintimer <= timer + 32'd1;endenddefault:beginstate <= IDLE; end endcase endax_debounce ax_debounce_m0 (.clk (clk),.rst (~rst_n),.button_in (key2),.button_posedge (),.button_negedge (button_negedge),.button_out () );ax_pwm# (.N(32) ) ax_pwm_m0(.clk (clk),.rst (~rst_n),.period (period),.duty (duty),.pwm_out (pwm_out));endmodule總結
以上是生活随笔為你收集整理的FPGA数码管显示自动计数+按键计数+蜂鸣器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新疆维吾尔自治区坡度数据
- 下一篇: 如何快速安装PR