前言: 本栏目除特别说明以外,均采用的黑金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开发实践之 基本使用流程介绍。