/*********
*author: Gibson
*date : 2019/5/28
*********/
//只展示部分自己写的代码,有意者可评论给打包
//实现功能就是FPGA开发板上初始化时数码管作时钟显示
//蜂鸣器不同频率响,LED不同频率闪烁,按键控制数码管加减
module key_debounce(
input clk,
input rst_n,
input key2,
input key3,
input key4,
output [3:0] led,
output buzzer,
output [5:0] seg_sel,
output [6:0] seg_data
);
reg k;//默认是0
//initial k=1'b1;
wire button_negedge; //Key falling edge
ax_debounce ax_debounce_m0
(
.clk (clk),
.rst (~rst_n),
.button_in0 (key2),//key1键
.button_posedge (),
.button_negedge (button_negedge),//按键下降沿触发,count0 count1同种触发情况button_negedge
.button_out ()
);
//添加
wire button_negedge1;
ax_debounce ax_debounce_m1
(
.clk (clk),
.rst (~rst_n),
.button_in0 (key3),//例化key2键
.button_posedge (),
.button_negedge (button_negedge1),//按键下降沿触发,count2 count3同种触发情况button_negedge1
.button_out ()
);
wire button_negedge2;
ax_debounce ax_debounce_m2
(
.clk (clk),
.rst (~rst_n),
.button_in0 (key4),//例化key2键
.button_posedge (),
.button_negedge (button_negedge2),//按键下降沿触发,count2 count3同种触发情况button_negedge1
.button_out ()
);
wire [3:0] counts;
wire[3:0] count;
count_m10 count10_m0( //数码管位选择
.clk (clk),
.rst_n (rst_n),
.en (button_negedge),//同步key1按键
.clr (1'b0),
.t (1'b0),
.t0 (),
.counts (),
.data (),//按键次数
.data0 (count)
);
wire[3:0] count1;
count_m10 count10_m1(
.clk (clk),
.rst_n (rst_n),
.en (button_negedge1),
.clr (1'b0),
.t (1'b1),
.t0 (1'b1),//加
.counts (counts),
.data (count1),
.data0 ()
);
//添加
wire[3:0] count2;
count_m10 count10_m2(
.clk (clk),
.rst_n (rst_n),
.en (button_negedge2),//同步key2按键
.clr (1'b0),
.t (1'b1),
.t0 (1'b0),//减
.counts (counts),
.data (count2),
.data0 ()
);
reg y;//用于判断该加还是该减
always@(button_negedge1 or button_negedge2)
begin
if(button_negedge1)
begin
y<=1'b0;
end
else if(button_negedge2)
begin
y<=1'b1;
end
end
always@(button_negedge or rst_n)
begin
if(rst_n==0) //复位时显示时钟
begin
k<=1'b0;
end
else if(button_negedge)
begin
k<=1'b1;
end
end
wire[6:0] seg_data10;
seg_decoder seg_decoder_m1(
.bin_data (count1), //加
.seg_data (seg_data10)
);
//添加
wire[6:0] seg_data20;
seg_decoder seg_decoder_m2(
.bin_data (count2), //减
.seg_data (seg_data20)
);
wire[3:0] d1;
wire[3:0] d2;
wire[3:0] d3;
wire[3:0] d4;
wire[3:0] d5;
wire[3:0] d6;
reg[6:0] seg_data_5;
reg[6:0] seg_data_4;
reg[6:0] seg_data_3;
reg[6:0] seg_data_2;
reg[6:0] seg_data_1;
reg[6:0] seg_data_0;
showTime showTime_0(
.clk (clk),
.rst_n (rst_n),
.d1 (d1),
.d2 (d2),
.d3 (d3),
.d4 (d4),
.d5 (d5),
.d6 (d6)
);
wire[6:0] seg_data0;
seg_decoder seg_decoder_m3(
.bin_data (d6),
.seg_data (seg_data0)
);
wire[6:0] seg_data1;
seg_decoder seg_decoder_m4(
.bin_data (d5),
.seg_data (seg_data1)
);
wire[6:0] seg_data2;
seg_decoder seg_decoder_m5(
.bin_data (d4),
.seg_data (seg_data2)
);
wire[6:0] seg_data3;
seg_decoder seg_decoder_m6(
.bin_data (d3),
.seg_data (seg_data3)
);
wire[6:0] seg_data4;
seg_decoder seg_decoder_m7(
.bin_data (d2),
.seg_data (seg_data4)
);
wire[6:0] seg_data5;
seg_decoder seg_decoder_m8(
.bin_data (d1),
.seg_data (seg_data5)
);
reg [3:0] div;
reg [3:0] div2;
always@(posedge clk)
begin
if(k==1'b0)
begin
seg_data_5<=seg_data5;
seg_data_4<=seg_data4;
seg_data_3<=seg_data3;
seg_data_2<=seg_data2;
seg_data_1<=seg_data1;
seg_data_0<=seg_data0;
end
else if(k==1'b1)
begin
if(!y)
begin
div<=count1;
div2<=count1;
case(count)
4'd0: begin seg_data_5<=7'h7f;seg_data_4<=7'h7f;seg_data_3<=7'h7f;seg_data_2<=7'h7f;seg_data_1<=7'h7f;seg_data_0<=seg_data10; end
4'd1: begin seg_data_5<=7'h7f;seg_data_4<=7'h7f;seg_data_3<=7'h7f;seg_data_2<=7'h7f;seg_data_1<=seg_data10;seg_data_0<=7'h7f; end
4'd2: begin seg_data_5<=7'h7f;seg_data_4<=7'h7f;seg_data_3<=7'h7f;seg_data_2<=seg_data10;seg_data_1<=7'h7f;seg_data_0<=7'h7f; end
4'd3: begin seg_data_5<=7'h7f;seg_data_4<=7'h7f;seg_data_3<=seg_data10;seg_data_2<=7'h7f;seg_data_1<=7'h7f;seg_data_0<=7'h7f; end
4'd4: begin seg_data_5<=7'h7f;seg_data_4<=seg_data10;seg_data_3<=7'h7f;seg_data_2<=7'h7f;seg_data_1<=7'h7f;seg_data_0<=7'h7f; end
4'd5: begin seg_data_5<=seg_data10;seg_data_4<=7'h7f;seg_data_3<=7'h7f;seg_data_2<=7'h7f;seg_data_1<=7'h7f;seg_data_0<=7'h7f; end
default: begin seg_data_5<=7'h7f;seg_data_4<=7'h7f;seg_data_3<=7'h7f;seg_data_2<=7'h7f;seg_data_1<=7'h7f;seg_data_0<=7'h7f; end
endcase
end
else if(y)
begin
div<=count2;
div2<=count2;
case(count)
4'd0: begin seg_data_5<=7'h7f;seg_data_4<=7'h7f;seg_data_3<=7'h7f;seg_data_2<=7'h7f;seg_data_1<=7'h7f;seg_data_0<=seg_data20; end
4'd1: begin seg_data_5<=7'h7f;seg_data_4<=7'h7f;seg_data_3<=7'h7f;seg_data_2<=7'h7f;seg_data_1<=seg_data20;seg_data_0<=7'h7f; end
4'd2: begin seg_data_5<=7'h7f;seg_data_4<=7'h7f;seg_data_3<=7'h7f;seg_data_2<=seg_data20;seg_data_1<=7'h7f;seg_data_0<=7'h7f; end
4'd3: begin seg_data_5<=7'h7f;seg_data_4<=7'h7f;seg_data_3<=seg_data20;seg_data_2<=7'h7f;seg_data_1<=7'h7f;seg_data_0<=7'h7f; end
4'd4: begin seg_data_5<=7'h7f;seg_data_4<=seg_data20;seg_data_3<=7'h7f;seg_data_2<=7'h7f;seg_data_1<=7'h7f;seg_data_0<=7'h7f; end
4'd5: begin seg_data_5<=seg_data20;seg_data_4<=7'h7f;seg_data_3<=7'h7f;seg_data_2<=7'h7f;seg_data_1<=7'h7f;seg_data_0<=7'h7f; end
default: begin seg_data_5<=7'h7f;seg_data_4<=7'h7f;seg_data_3<=7'h7f;seg_data_2<=7'h7f;seg_data_1<=7'h7f;seg_data_0<=7'h7f; end
endcase
end
end
end
seg_scan seg_scan_m0(
.clk (clk),
.rst_n (rst_n),
// .scan_sel (count),
.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}), //最高位1'b1是数码管的小数点。数码管实时显示变量seg_data_3的数据
.seg_data_3 ({1'b1,seg_data_2}), //拼接 seg_data_2 7位数据加1'b1 共8位赋值给seg_data,具体看seg_scan.v
.seg_data_4 ({1'b1,seg_data_1}),
.seg_data_5 ({1'b1,seg_data_0})
);
ledFM led0(
.clk (clk),
.rst_n (rst_n),
.div (div),
.led (led)
// .buzzer (buzzer)
);
wire[3:0]count3;
assign count3=div2;
FM FM_0(
.key (key2),
.clk (clk),
.rst_n(rst_n),
.count (count3),
.beep (buzzer)
);
endmodule
/********************
频率越高,FM音调越尖
********************/
module FM(
input key,
input clk,
input rst_n,
input[3:0] count,
output reg beep
);
wire button_negedge; //Key falling edge
ax_debounce ax_debounce_m0
(
.clk (clk),
.rst (~rst_n),
.button_in0 (key),//key1键
.button_posedge (),
.button_negedge (button_negedge),//按键下降沿触发,count0 count1同种触发情况button_negedge
.button_out ()
);
reg [16:0] cnt;
reg [16:0] prediv;
reg [11:0] delay;
reg [3:0] sel;
reg i;
initial beep=1'b1;
/*begin
cnt = 16'd0;
prediv = 16'hBA9E;
delay = 13'd0;
end*/
always @(posedge clk)
begin
if(button_negedge)i<=1;
else if(rst_n==0)i<=0;
case(count)
4'd0:prediv <= 17'h17629; //分频系数=>时钟频率/(音频频率*2)
4'd1:prediv <= 17'h14d4c;
4'd2:prediv <= 17'h128d3;
4'd3:prediv <= 17'h117d1;
4'd4:prediv <= 17'h0f91f;
4'd5:prediv <= 17'h0ddf2;
4'd6:prediv <= 17'h0c3b4;
4'd7:prediv <= 17'h0bab9;//中音1
4'd8:prediv <= 17'h0532e;//高音2
4'd9:prediv <= 17'h02508;//超高音3
default : prediv <= prediv;
endcase
end
always @(posedge clk or negedge rst_n)
begin
if(rst_n==0)
begin
// sel<=4'd0;
beep <= 1'b1;
delay <= 12'd0;
cnt <= 17'd0;
// count<=4'd0;
//i<=1'b0;
// prediv <= 17'h0c3b4;
end
else if(i)
begin
cnt <= cnt + 1'b1;
if (cnt == prediv)
begin
beep <= ~beep; //当prediv <= 17'h17629即95785,261Hz时0/1转换1000次,响1000/2=500次【响的间隔为95785个计数值
//即(1/50M)*95785ns约1.9157ms/一响
cnt <= 17'd0; //同理,prediv <= 17'h14d4c约85324,1.70648ms/一响】
if(delay==12'd1000)
begin
delay<=12'd0;
end
else delay <= delay +1'b1;
end
end
end
endmodule
//LED灯
module ledFM(
input clk,
input rst_n,
input [3:0] div,//分频
output [3:0] led
// output buzzer //硬件蜂鸣器
);
/*******************************
50MHZ的晶振下计数值为12_500_000即0.25s
现倍频到125M,8ns每次,即每250ms计数31.25M次*/
//parameter COUNT_37_5Mx250ms = 27'd150_000_000;
reg [26:0] COUNT_37_5Mx250ms;
reg [26:0]count;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
count <= 27'd0;
else if(count == (COUNT_37_5Mx250ms-1))
begin
count <= 27'd0;
end
else
count <= count + 27'd1;
end
reg [3:0] LEDs;
reg [3:0] led_num;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
LEDs = 4'd0;
else if(count >= 27'd0 && count <= (COUNT_37_5Mx250ms/4))//12.5M频率下每执行一条语句5ns,计数12500000次0.25s,即每0.25s亮一次
LEDs <= 4'd1;
else if(count > (COUNT_37_5Mx250ms/4) && count <= (COUNT_37_5Mx250ms/3))
LEDs <= 4'd2;
else if(count > (COUNT_37_5Mx250ms/3) && count <= (COUNT_37_5Mx250ms/2))
LEDs <= 4'd3;
else if(count >(COUNT_37_5Mx250ms/2) && count <= (COUNT_37_5Mx250ms-1))
LEDs <= 4'd4;
else
LEDs <= 4'd0;
end
always @(*) //一直执行,不用触发
begin
case(LEDs)
4'd1:led_num=4'b0001; //LED灯高电平亮
4'd2:led_num=4'b0010;
4'd3:led_num=4'b0100;
4'd4:led_num=4'b1000;
default:led_num=4'b0000;
endcase
case(div)
4'd0:begin COUNT_37_5Mx250ms = 27'd50_000_000;end
4'd1:begin COUNT_37_5Mx250ms = 27'd45_000_000;end
4'd2:begin COUNT_37_5Mx250ms = 27'd40_000_000;end
4'd3:begin COUNT_37_5Mx250ms = 27'd35_000_000;end
4'd4:begin COUNT_37_5Mx250ms = 27'd30_000_000;end
4'd5:begin COUNT_37_5Mx250ms = 27'd25_000_000;end
4'd6:begin COUNT_37_5Mx250ms = 27'd20_000_000;end
4'd7:begin COUNT_37_5Mx250ms = 27'd15_000_000;end
4'd8:begin COUNT_37_5Mx250ms = 27'd10_000_000;end
4'd9:begin COUNT_37_5Mx250ms = 27'd5_000_000;end
default:COUNT_37_5Mx250ms = 27'd50_000_000;
endcase
end
assign led = led_num;
endmodule
//数码管作时钟显示
module showTime(
input clk,
input rst_n,
input k,
output reg[3:0] d1,
output reg[3:0] d2,
output reg[3:0] d3,
output reg[3:0] d4,
output reg[3:0] d5,
output reg[3:0] d6
);
parameter Counter50M=26'd50_000_000;
reg [26:0] count;
always@(posedge clk)
begin
if(count==Counter50M-1)
begin
count<=26'd0;
end
else
begin
count<=count+26'd1;
end
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n==0)
begin
d1<=4'd1;
d2<=4'd4;
d3<=4'd3;
d4<=4'd5;
d5<=4'd0;
d6<=4'd0;
end
else if(count==Counter50M-1)//每秒加一
begin
if(d6==4'd9)
begin
d6<=4'd0;
if(d5==4'd5)
begin
d5<=4'd0;
if(d4==4'd9)
begin
d4<=4'd0;
if(d3==4'd5)
begin
d3<=4'd0;
if(d2<=4'd9)
begin
d2<=4'd0;
if(d1==4'd5)
begin
d1<=4'd0;
end
else d1<=d1+4'd1;
end
else d2<=d2+4'd1;
end
else d3<=d3+4'd1;
end
else d4<=d4+4'd1;
end
else d5<=d5+4'd1;
end
else d6<=d6+4'd1;
end
end
endmodule
//计数规则
module count_m10(
input clk,
input rst_n,
input en, //Counter enable
input clr, //Counter synchronous reset
input t,
input t0,
inout reg[3:0]counts,
output reg[3:0]data, //counter value
output reg[3:0]data0
//output reg[3:0]data1
);
//reg [3:0] counts;//同步加减数值
always@(posedge clk or negedge rst_n)
begin
if(rst_n==0)
begin
data0<= 4'd0;
data <= 4'd0;
end
else if(clr)
begin
data0<= 4'd0;
data <= 4'd0;
end
else if(en)
begin
if(t==1'b1)
begin
if(t0==1'b1)//加
begin
data<=counts;
if(data==4'd9)
begin
data <= 4'd0;//Counter to 9 reset
end
else
begin
data <= data + 4'd1;
end
counts<=data;
end
else if(t0==1'b0)//减
begin
data<=counts;
if(data==4'd0)
begin
data <= 4'd9;//Counter to 9 reset
end
else
begin
data <= data - 4'd1;
end
counts<=data;
end
end
else if(t==1'b0)//数码管位选择
begin
if(data0>=4'd5)
begin
data0<=4'd0;
end
else
begin
data0<=data0+4'd1;
end
end
end
end
endmodule
FPGA硬件编程EP4CE6F17C8
最新推荐文章于 2024-03-26 10:00:00 发布