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开发实践之 基本使用流程介绍

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肆拾伍

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值