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

Posted 肆拾伍

tags:

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

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

文章目录

1. Simulink 模型


HDL_DUT内部

功能简述:
2s由暗变亮,然后2s由亮变暗。
将2s分割为1000个2ms,每个2ms中有1000个基本时间单元,根据基本时间单元亮的个数决定当前2ms的亮度。

2. 生成HDL代码

要点: 在生成代码之前,需要设置好参数,我这里生成Verilog代码,并且指定复位信号reset低电平有效——这是根据各自用的板子决定的。可以根据我的另一篇文章来便捷设置,见Simulink HDL Coder FPGA开发之 脚本自动设置HDL参数

// -------------------------------------------------------------
// 
// File Name: hdlsrc\\led_breath\\HDL_DUT.v
// Created: 2022-03-28 18:28:26
// 
// Generated by MATLAB 9.12 and HDL Coder 3.20
// 
// 
// -- -------------------------------------------------------------
// -- Rate and Clocking Details
// -- -------------------------------------------------------------
// Model base rate: 1
// Target subsystem base rate: 1
// 
// -------------------------------------------------------------


// -------------------------------------------------------------
// 
// Module: HDL_DUT
// Source Path: led_breath/HDL_DUT
// Hierarchy Level: 0
// 
// -------------------------------------------------------------

`timescale 1 ns / 1 ns

module HDL_DUT
          (clk,
           reset,
           led,
           led1,
           led2,
           led3);


  input   clk;
  input   reset;
  output  led;
  output  led1;
  output  led2;
  output  led3;


  wire [15:0] count_step;  // uint16
  wire [15:0] count_from;  // uint16
  reg [15:0] alpha2us_Counter_out1;  // uint16
  wire [15:0] count;  // uint16
  wire need_to_wrap;
  wire [15:0] count_value;  // uint16
  wire Compare_To_Constant_out1;
  wire [9:0] count_step_1;  // ufix10
  wire [9:0] count_from_1;  // ufix10
  reg [9:0] alpha2ms_Counter_out1;  // ufix10
  wire [9:0] count_1;  // ufix10
  wire need_to_wrap_1;
  wire [9:0] count_value_1;  // ufix10
  wire [9:0] count_2;  // ufix10
  wire Compare_To_Constant1_out1;
  wire AND_out1;
  wire [10:0] count_step_2;  // ufix11
  wire [10:0] count_from_2;  // ufix11
  reg [10:0] alpha2s_Counter1_out1;  // ufix11
  wire [10:0] count_3;  // ufix11
  wire need_to_wrap_2;
  wire [10:0] count_value_2;  // ufix11
  wire [10:0] count_4;  // ufix11
  wire Compare_To_Constant2_out1;
  wire switch_compare_1;
  wire [10:0] Constant_out1;  // ufix11
  wire signed [11:0] Subtract_1;  // sfix12
  wire signed [11:0] Subtract_2;  // sfix12
  wire signed [11:0] Subtract_out1;  // sfix12
  wire signed [11:0] GreaterThan1_1_1;  // sfix12
  wire GreaterThan1_relop1;
  wire [10:0] GreaterThan_1_1;  // ufix11
  wire GreaterThan_relop1;
  wire Switch_out1;


  // Count limited, Unsigned Counter
  //  initial value   = 0
  //  step value      = 1
  //  count to value  = 399
  assign count_step = 16'b0000000000000001;


  assign count_from = 16'b0000000000000000;


  assign count = alpha2us_Counter_out1 + count_step;


  assign need_to_wrap = alpha2us_Counter_out1 == 16'b0000000110001111;


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


  always @(posedge clk or negedge reset)
    begin : alpha2us_Counter_process
      if (reset == 1'b0) begin
        alpha2us_Counter_out1 <= 16'b0000000000000000;
      end
      else begin
        alpha2us_Counter_out1 <= count_value;
      end
    end


  assign Compare_To_Constant_out1 = alpha2us_Counter_out1 == 16'b0000000110001111;


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


  assign count_from_1 = 10'b0000000000;


  assign count_1 = alpha2ms_Counter_out1 + count_step_1;


  assign need_to_wrap_1 = alpha2ms_Counter_out1 == 10'b1111100111;


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


  assign count_2 = (Compare_To_Constant_out1 == 1'b0 ? alpha2ms_Counter_out1 :
              count_value_1);


  always @(posedge clk or negedge reset)
    begin : alpha2ms_Counter_process
      if (reset == 1'b0) begin
        alpha2ms_Counter_out1 <= 10'b0000000000;
      end
      else begin
        alpha2ms_Counter_out1 <= count_2;
      end
    end


  assign Compare_To_Constant1_out1 = alpha2ms_Counter_out1 == 10'b1111100111;


  assign AND_out1 = Compare_To_Constant1_out1 & Compare_To_Constant_out1;


  // Count limited, Unsigned Counter
  //  initial value   = 0
  //  step value      = 1
  //  count to value  = 1999
  assign count_step_2 = 11'b00000000001;


  assign count_from_2 = 11'b00000000000;


  assign count_3 = alpha2s_Counter1_out1 + count_step_2;


  assign need_to_wrap_2 = alpha2s_Counter1_out1 == 11'b11111001111;


  assign count_value_2 = (need_to_wrap_2 == 1'b0 ? count_3 :
              count_from_2);


  assign count_4 = (AND_out1 == 1'b0 ? alpha2s_Counter1_out1 :
              count_value_2);


  always @(posedge clk or negedge reset)
    begin : alpha2s_Counter1_process
      if (reset == 1'b0) begin
        alpha2s_Counter1_out1 <= 11'b00000000000;
      end
      else begin
        alpha2s_Counter1_out1 <= count_4;
      end
    end


  assign Compare_To_Constant2_out1 = alpha2s_Counter1_out1 <= 11'b01111100111;


  assign switch_compare_1 = Compare_To_Constant2_out1 > 1'b0;



  assign Constant_out1 = 11'b11111001111;


  assign Subtract_1 = 1'b0, Constant_out1;
  assign Subtract_2 = 1'b0, alpha2s_Counter1_out1;
  assign Subtract_out1 = Subtract_1 - Subtract_2;


  assign GreaterThan1_1_1 = 2'b0, alpha2ms_Counter_out1;
  assign GreaterThan1_relop1 = GreaterThan1_1_1 > Subtract_out1;


  assign GreaterThan_1_1 = 1'b0, alpha2ms_Counter_out1;
  assign GreaterThan_relop1 = GreaterThan_1_1 > alpha2s_Counter1_out1;


  assign Switch_out1 = (switch_compare_1 == 1'b0 ? GreaterThan1_relop1 :
              GreaterThan_relop1);


  assign led = Switch_out1;

  assign led1 = Switch_out1;

  assign led2 = Switch_out1;

  assign led3 = Switch_out1;

endmodule  // HDL_DUT

上面的代码可以作为一个模块来调用,我们还需要一个代码来实例化,如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/03/28 17:36:10
// Design Name: 
// Module Name: led_breath
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module led_breath(
input  wire clk_n,
input  wire clk_p,
input  wire rstn,
output wire[3:0] led
    );

wire  clk;
IBUFDS sys_clk_ibufgds  // 这里就是将双端时钟变为单端
       (
         .O              (clk                  ),
         .I              (clk_p                ),
         .IB             (clk_n                )
       );

HDL_DUT l(
.clk(clk),
.reset(rstn),
.led(led[0]),
.led1(led[1]),
.led2(led[2]),
.led3(led[3])
);
endmodule

3. 管脚图

4. simulink文件以及 HDL文件

所用到的代码下载链接:
链接:https://pan.baidu.com/s/15KzIP4BU7mWleyaWGg39UQ?pwd=1111
提取码:1111
–来自百度网盘超级会员V6的分享

5. 完整使用流程

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

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

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初级开发实践 自动贩卖机建模