FPGA硬件编程EP4CE6F17C8

/*********

*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 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值