Simulink HDL Coder FPGA初级开发实践 按键消抖

Posted 肆拾伍

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Simulink HDL Coder FPGA初级开发实践 按键消抖相关的知识,希望对你有一定的参考价值。

前言: 本栏目除特别说明以外,均采用的黑金AX7103开发板,该开发板时钟频率为200M,并且是双端时钟,因此在每个项目中都有一段原语将双端时钟变成200MHz的单端时钟。文章仅作为学习记录,如有不足请在评论区指出,博主不会对各位的问题作出解答,请谅解。博主深知网络上关于HDL Coder的资料十分稀少,特别是中文资料几乎没有,并且官方给出的例子大多挺难不适合入门,因此将自己摸索的过程记录下来,希望给后人一些启发。

文章目录

1. Simulink 模型

key_debounce 模块内部结构

通过比较当前时刻和前一时刻的输入值判断是否发生了变化,来复位一个计数器,计时为20ms。如果成功计时到20ms则说明按键稳定,就可以取当前按键的输入值,否则保持按键的上一次的值,下面的count表示按下的次数,用于点亮LED灯。

2. 生成HDL代码

// -------------------------------------------------------------
// 
// File Name: hdlsrc\\key_debounce_mbd\\key_debounce.v
// Created: 2022-03-24 21:13:10
// 
// Generated by MATLAB 9.12 and HDL Coder 3.20
// 
// 
// -- -------------------------------------------------------------
// -- Rate and Clocking Details
// -- -------------------------------------------------------------
// Model base rate: 1
// Target subsystem base rate: 1
// 
// -------------------------------------------------------------


// -------------------------------------------------------------
// 
// Module: key_debounce
// Source Path: key_debounce_mbd/key_debounce
// Hierarchy Level: 0
// 
// -------------------------------------------------------------

`timescale 1 ns / 1 ns

module key_debounce
          (clk,
           reset,
           key_in,
           count,
           key_out);


  input   clk;
  input   reset;
  input   key_in;
  output  [3:0] count;  // ufix4
  output  key_out;


  reg  Delay_out1;
  wire [31:0] count_step;  // uint32
  wire edge_detec;
  wire [31:0] count_from;  // uint32
  wire [31:0] count_reset;  // uint32
  reg [31:0] Time_counter_out1;  // uint32
  wire [31:0] count_1;  // uint32
  wire need_to_wrap;
  wire [31:0] count_value;  // uint32
  wire [31:0] count_2;  // uint32
  wire Compare_To_Constant_out1;
  wire switch_compare_1;
  reg  Delay1_out1;
  wire Switch_out1;
  wire NOT_out1;
  wire negedge_detec;
  wire [3:0] count_step_1;  // ufix4
  wire [3:0] count_from_1;  // ufix4
  reg [3:0] LED_counter_out1;  // ufix4
  wire [3:0] count_3;  // ufix4
  wire need_to_wrap_1;
  wire [3:0] count_value_1;  // ufix4
  wire [3:0] count_4;  // ufix4


  always @(posedge clk or negedge reset)
    begin : Delay_process
      if (reset == 1'b0) begin
        Delay_out1 <= 1'b0;
      end
      else begin
        Delay_out1 <= key_in;
      end
    end


  // Count limited, Unsigned Counter
  //  initial value   = 0
  //  step value      = 1
  //  count to value  = 2000000
  assign count_step = 32'b00000000000000000000000000000001;


  assign edge_detec = Delay_out1 ^ key_in;


  assign count_from = 32'b00000000000000000000000000000000;


  assign count_reset = 32'b00000000000000000000000000000000;


  assign count_1 = Time_counter_out1 + count_step;


  assign need_to_wrap = Time_counter_out1 == 32'b00000000000111101000010010000000;


  assign count_value = (need_to_wrap == 1'b0 ? count_1 :
              count_from);


  assign count_2 = (edge_detec == 1'b0 ? count_value :
              count_reset);


  always @(posedge clk or negedge reset)
    begin : Time_counter_process
      if (reset == 1'b0) begin
        Time_counter_out1 <= 32'b00000000000000000000000000000000;
      end
      else begin
        Time_counter_out1 <= count_2;
      end
    end


  assign Compare_To_Constant_out1 = Time_counter_out1 == 32'b00000000000111101000010010000000;


  assign switch_compare_1 = Compare_To_Constant_out1 > 1'b0;



  assign Switch_out1 = (switch_compare_1 == 1'b0 ? Delay1_out1 :
              Delay_out1);


  always @(posedge clk or negedge reset)
    begin : Delay1_process
      if (reset == 1'b0) begin
        Delay1_out1 <= 1'b0;
      end
      else begin
        Delay1_out1 <= Switch_out1;
      end
    end


  assign NOT_out1 =  ~ Switch_out1;


  assign negedge_detec = Delay1_out1 & NOT_out1;


  // Count limited, Unsigned Counter
  //  initial value   = 0
  //  step value      = 1
  //  count to value  = 10
  assign count_step_1 = 4'b0001;


  assign count_from_1 = 4'b0000;


  assign count_3 = LED_counter_out1 + count_step_1;


  assign need_to_wrap_1 = LED_counter_out1 == 4'b1010;


  assign count_value_1 = (need_to_wrap_1 == 1'b0 ? count_3 :
              count_from_1);


  assign count_4 = (negedge_detec == 1'b0 ? LED_counter_out1 :
              count_value_1);


  always @(posedge clk or negedge reset)
    begin : LED_counter_process
      if (reset == 1'b0) begin
        LED_counter_out1 <= 4'b0000;
      end
      else begin
        LED_counter_out1 <= count_4;
      end
    end


  assign count = LED_counter_out1;

  assign key_out = Switch_out1;

endmodule  // key_debounce

3. 完整代码

链接:https://pan.baidu.com/s/1yFnr_PZX30wJDrBOwORPqA?pwd=1111
提取码:1111
–来自百度网盘超级会员V6的分享

4. 完整使用流程

如果对HDL Coder的使用流程不熟悉,请根据另一篇文章从头练习一边,见Simulink HDL Coder FPGA开发实践之 基本使用流程介绍

以上是关于Simulink HDL Coder FPGA初级开发实践 按键消抖的主要内容,如果未能解决你的问题,请参考以下文章

Simulink HDL Coder FPGA初级开发实践 按键消抖

Simulink HDL Coder FPGA初级开发实践 LED呼吸灯

Simulink HDL Coder FPGA初级开发实践 LED呼吸灯

Simulink HDL Coder FPGA初级开发实践 LED流水灯

Simulink HDL Coder FPGA初级开发实践 LED流水灯

Simulink HDL Coder FPGA初级开发实践 自动贩卖机建模