FPGA_学习_13_方差计算小模块

这篇具有很好参考价值的文章主要介绍了FPGA_学习_13_方差计算小模块。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

测距器件APD的性能与器件本身的温度、施加在APD的偏置电压息息相关。 在不同的温度下,APD的偏压对测距性能的影响非常大。 要确定一个合适的APD的偏压Vopt,首先你要知道当前温度下,APD的击穿电压Vbr,一般来讲,Vopt = Vbr – ΔV,ΔV基本是个固定的值。如果要使用算法找到Vbr,通过寻找APD采集信号的噪声方差的剧变点去寻找Vbr是一个不错的方式。 如下图所示,当方差从10以下,突然剧变到45.31,信号噪声方差剧变4倍不止。我们就可以定义此处偏压43.8V为击穿电压Vbr。 那么要在FPGA实现此功能,首先需要在FPGA中实现方差的计算,这也是本文的内容。 这算是脱离例程,第一个本人自己设计的FPGA小模块。

FPGA_学习_13_方差计算小模块,FPGA,fpga开发,学习

1 CSDN C知道

ChatGPT已经火爆的不行了,猪如何在ChatGPT的风口起飞,这个问题还真是为难。 不过使用ChatGPT倒是不难,CSDN推出了基于ChatGPT的C知道,功能还是比较强大的。我也赶一下时髦,我对C知道问了一个问题:请帮我用Verilog写一个计算方差的算法。

FPGA_学习_13_方差计算小模块,FPGA,fpga开发,学习

module VarianceCalculator (
  input clk,
  input rst,
  input [N-1:0] data_in,
  input valid_in,
  output reg [31:0] variance,
  output reg valid_out
);

  reg [N-1:0] sum;
  reg [N-1:0] square_sum;
  reg [31:0] mean;
  reg [31:0] count;

  always @(posedge clk or posedge rst) begin
    if (rst) begin
      sum <= 'b0;
      square_sum <= 'b0;
      mean <= 'b0;
      count <= 'b0;
      valid_out <= 0;
    end else if (valid_in) begin
      sum <= sum + data_in;
      square_sum <= square_sum + (data_in * data_in);
      count <= count + 1;
      if (count == N-1) begin
        mean <= sum / N;
        variance <= square_sum / N - (mean * mean);
        valid_out <= 1;
      end
    end
  end

endmodule

 从算法上来讲,计算方差倒不是一个很难的问题,比如用平方的均值减去均值的平方(平方的期望减去期望的平方)。 C知道提供的Verilog代码就是这样算的,是没有问题的。 但直接拿来用,还是存在少许问题。 不过C知道已经很强大了,是很有参考价值的。

2 V1.0 纯时序逻辑实现 

我已记不清从哪里接受了一个写Verilog代码的观念,就是:一个时序逻辑(always块),只写一个变量。这样做的好处是,修改调试非常方便,可以根据仿真结果看哪个变量有问题,然后我就专门去修改那个变量对应的时序逻辑。 不过坏处是,它不如全部变量写到一个时序逻辑里面那样,一眼看到算法的全貌。不过,我不管它的坏处是啥,总之这是我接受的观念,也是我后续编写FPGA代码的风格和态度。

下面给出,我用纯时序逻辑写的方差计算FPGA代码。

2.1 Verilog代码

`timescale 1ns / 1ps

module VarCalculatorV1(
        input   wire            clk             ,
        input   wire            rst_n           ,
        input   wire    [7:0]   data_in         ,
        input   wire            valid_in        ,
        output  reg     [15:0]  variance        ,
        output  reg             valid_out
);

//==================================================================
//                        Parameter define
//==================================================================
parameter       N = 256;

//==================================================================
//                        Internal Signals
//==================================================================
reg     [31:0]  count;
reg     [15:0]  sum;
reg     [31:0]  square_sum;
reg     [7:0]   mean;

//----------------------------- valid_out -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                valid_out <= 1'b0;     
        end
        else if (count == N+1)begin
                valid_out <= 1'b1;
        end
        else begin
                valid_out <= 1'b0;
        end
end

//----------------------------- variance -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                variance <= 'd0;     
        end
        else if (valid_in==1'b1 && count >= N+1 )begin
                variance <= (square_sum >> 8) - (mean * mean);
        end
        else begin
                variance <= 'd0;
        end
end

//----------------------------- count -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                count <= 'd0;     
        end
        else if (valid_in==1'b1)begin
                if (count == N+2) begin
                        count <= 'd0;
                end
                else begin
                        count <= count + 1'b1;
                end
        end
        else begin
                count <= 'd0;
        end
end

//----------------------------- sum -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                sum <= 'd0;     
        end
        else if (valid_in==1'b1)begin
                if (count < N) begin
                        sum <= sum + data_in;
                end
                else if(count == N || count == N+1) begin
                        sum <= sum;
                end
                else if(count == N+2) begin
                        sum <= 'd0;
                end
        end
        else begin
                sum <= 'd0;
        end
end


//----------------------------- square_sum -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                square_sum <= 'd0;     
        end
        else if (valid_in==1'b1)begin
                if (count < N) begin
                        square_sum <= square_sum + data_in*data_in;
                end
                else if(count == N || count == N+1) begin
                        square_sum <= square_sum;
                end
                else if(count == N+2) begin
                        square_sum <= 'd0;
                end
        end
        else begin
                square_sum <= 'd0;
        end
end


//----------------------------- mean -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                mean <= 'd0;     
        end
        else if (valid_in==1'b1)begin
                if (count >= N) begin
                        mean <= sum >> 8;
                end
                else begin
                        mean  <= 'd0;
                end
        end
        else begin
                sum <= 'd0;
        end
end


endmodule

啰嗦几句废话哈,由于需要验证代码的准确性,因此我们对其进行了ModelSim仿真。 本来呢,由于ModelSim的仿真代码我不是很熟悉, 我还不太会使用仿真代码来创建一个我想要的data_in。所以,我在仿真的时候,在用到data_in的地方,我都是用模块内部的计数变量count来代替的。(也就是说,我们计算的是从0~255这256个数的方差)。后来仿真成功确定了代码的准确性之后,我重新去调整我的仿真代码,使得我给到这个模块的data_in变量和模块内部的count变量是一样的。

下面给出对应的ModelSim仿真代码。

2.2 ModelSim仿真代码

`timescale 1ns/1ps
module tb_VarCalculator (); /* this is automatically generated */

    // clock
    reg clk;
    reg rst_n;
    reg  [7:0] data_in;
    reg        valid_in;
    wire [15:0] variance;
    wire        valid_out;

    parameter N = 256;

    VarCalculatorV1 #(
            .N(N)
        ) inst_VarCalculator (
            .clk       (clk),
            .rst_n     (rst_n),
            .data_in   (data_in),
            .valid_in  (valid_in),
            .variance  (variance),
            .valid_out (valid_out)
        );

    initial begin
        clk <= 1'b0;
        forever #(10) clk = ~clk;
    end

    initial begin
        rst_n <= 1'b0;
        #10
        rst_n <= 1'b1;
    end

    initial begin
        valid_in <= 1'b0;
        #10
        valid_in <= 1'b1;
    end

    
    reg [15:0] tb_count;
    initial begin
        tb_count <= 'd0;
        data_in <= 'd0;
        #10
        // 仿真代码中for循环是比较值得后续学习参考的
        for(tb_count = 1; tb_count <= N+3; tb_count = tb_count + 1) begin
            #20
            if(tb_count<='d255) begin
                data_in <= tb_count; 
            end
            else begin
                if (tb_count=='d258) begin
                    tb_count <= 'd0;
                end
                data_in <= 'd0; 
            end                
        end
    end

endmodule

仿真的时候,有个小技巧,真的好方便,特别提高仿真效率。

2.3 高效仿真小技巧

首先找到如下图所示的仿真编译文件 tb_VarCalculator_compile.do。

FPGA_学习_13_方差计算小模块,FPGA,fpga开发,学习

 打开这个文件,注释最后一行。

FPGA_学习_13_方差计算小模块,FPGA,fpga开发,学习

 修改完这个编译文件后, 后续你如果你的仿真代码或者你的功能模块代码有任何的改动,你改了之后先保存。

然后在ModelSim命令行输入三个命令(第一次输入后,后面你用上键↑下键↓就能快速输入了),编译 → 重启 → 运行。

FPGA_学习_13_方差计算小模块,FPGA,fpga开发,学习

就可以实现快速修改代码仿真。

2.4 仿真结果

 FPGA_学习_13_方差计算小模块,FPGA,fpga开发,学习

分析一下仿真结果

1、可以看到仿真代码给出的data_in在0~255部分是和咱们模块内部的count变量一模一样的。仿真代码里面的for循环还是有点东西的,相信以后的仿真肯定可以借鉴。

2、仿真结果5588也是非常接近咱们用MatLAB算的0~255的方差的。 不能完全相等的原因是,我们的数据量个数是2^8,所以我们的除法是用的位移运算实现的。肯定会存在一定的误差。

3、咱们方差的计算结果延迟的3帧,

        1 首先时序逻辑肯定是要延迟1帧的,所以我在求所有数据的和、求所有数据的平方和的时候,就已经延迟了1帧。  

        2 其次,得到所有数据的和之后,我计算了所有数据的均值,这里又延迟了一帧。

        3 最后,在得到所有数据的均值之后,我又求了所有数据的平方和的均值 减去 均值的平方。

因此咱们总共延迟了三帧。 甚至我都担心最后一步在一个时钟周期内算不过来,还能再进行拆分,不过呢,这样延迟更多了,可能变成4帧或者5帧的。

这个很多帧延迟经常让人难以接受,所以我们下面用组合逻辑进行优化。

3 V2.0 时序逻辑+组合逻辑

组合逻辑是没有时钟延迟的。

当我用时序逻辑,求了所有数据的和,以及所有数据的平方和之后(延迟1帧)。

我可以用组合逻辑,就在当前时钟周期,立即得到:均值、均值的平方、平方和的均值、以及用平方和的均值减去均值的平方得到方差。

那么最终得到的方差,也只会延迟1帧。

3.1 Verilog代码

`timescale 1ns / 1ps

module VarCalculator(
        input   wire            clk      ,
        input   wire            rst_n    ,
        input   wire    [7:0]   data_in ,
        input   wire            valid_in,
        output  wire    [15:0]  variance,
        output  reg             valid_out
);

//==================================================================
//                        Parameter define
//==================================================================
parameter       N = 256;

//==================================================================
//                        Internal Signals
//==================================================================
reg     [31:0]  count;
reg     [15:0]  sum;
reg     [31:0]  square_sum;
wire    [7:0]   mean;
wire    [23:0]  square_mean;
wire    [15:0]  mean_square;

// 🔺 组合逻辑,优化延迟
assign square_mean = square_sum >> 8;
assign mean_square = mean * mean;
assign variance = ( valid_in==1'b1 && count == N ) ? (square_mean - mean_square) : 'd0;
assign mean = (valid_in==1'b1 && count == N) ? (sum >> 8) : 'd0;

//----------------------------- valid_out -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                valid_out <= 1'b0;     
        end
        else if (count == N-1)begin
                valid_out <= 1'b1;
        end
        else begin
                valid_out <= 1'b0;
        end
end

//----------------------------- count -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                count <= 'd0;     
        end
        else if (valid_in==1'b1)begin
                if (count == N) begin
                        count <= 'd0;
                end
                else begin
                        count <= count + 1'b1;
                end
        end
        else begin
                count <= 'd0;
        end
end


//----------------------------- sum -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                sum <= 'd0;     
        end
        else if (valid_in==1'b1)begin
                if (count == N) begin
                        sum <= 'd0;                       
                end
                else begin
                        sum <= sum + data_in;
                end
        end
        else begin
                sum <= 'd0;
        end
end


//----------------------------- square_sum -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                square_sum <= 'd0;     
        end
        else if (valid_in==1'b1)begin
                if (count == N) begin
                        square_sum <= 'd0;                     
                end
                else begin
                        square_sum <= square_sum + data_in*data_in;
                end
        end
        else begin
                square_sum <= 'd0;
        end
end

endmodule

3.2 仿真结果

FPGA_学习_13_方差计算小模块,FPGA,fpga开发,学习

从仿真结果可看出,方差计算仍然正确,但是延迟只有1帧。 另外,其实咱们的verilog代码也要比V1.0版本精简一些。

4 V3.0 组合逻辑部分的优化(考虑位宽对输出结果的影响)

在组合逻辑的计算部分,变量的位宽存在一些小问题,进行进一步优化。

`timescale 1ns / 1ps

module var_compute(
        input   wire            clk,
        input   wire            rst_n,
        input   wire    [7:0]   data_in,
        input   wire            valid_in,
        output  wire    [15:0]  variance,
        output  reg             valid_out
);

//==================================================================
//                        Parameter define
//==================================================================
parameter       N = 256;

//==================================================================
//                        Internal Signals
//==================================================================
reg     [31:0]  count;
reg     [15:0]  sum;
reg     [23:0]  square_sum;    // 🔺 修改
wire    [7:0]   mean;
wire    [15:0]  square_mean;    // 🔺 修改        
wire    [15:0]  mean_square;


assign square_mean = square_sum[23-:16];    // 🔺 修改
assign mean_square = mean * mean;
assign variance = ( (valid_in==1'b1) && (count == N) && (square_mean > mean_square) ) ? (square_mean - mean_square) : 'd0;    // 🔺 修改
assign mean = (valid_in==1'b1 && count == N) ? sum[15-:8] : 'd0;    // 🔺 修改

//----------------------------- valid_out -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                valid_out <= 1'b0;     
        end
        else if (count == (N-1) )begin
                valid_out <= 1'b1;
        end
        else begin
                valid_out <= 1'b0;
        end
end

//----------------------------- count -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                count <= 'd0;     
        end
        else if (valid_in==1'b1)begin
                if (count == N) begin
                        count <= 'd0;
                end
                else begin
                        count <= count + 1'b1;
                end
        end
        else begin
                count <= 'd0;
        end
end


//----------------------------- sum -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                sum <= 'd0;     
        end
        else if (valid_in==1'b1)begin
                if (count == N) begin
                        sum <= 'd0;                       
                end
                else begin
                        sum <= sum + data_in;
                end
        end
        else begin
                sum <= 'd0;
        end
end


//----------------------------- square_sum -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                square_sum <= 'd0;     
        end
        else if (valid_in==1'b1)begin
                if (count == N) begin
                        square_sum <= 'd0;                     
                end
                else begin
                        square_sum <= square_sum + data_in*data_in;
                end
        end
        else begin
                square_sum <= 'd0;
        end
end

endmodule

5 V4.0  算法精度优化

我们在求均值的时候用sum右移8位求均值,会损失一定的精度。 然后用已经损失过精度求得的均值去平方,得到期望的平方→E^2(x),再一次损失精度。   如果我先把sum平方,在除以N^2,即右移16位,以这样的方式来得到期望的平方→E^2(x),精度的损失会比以前的方式小很多。 基于此思路,我们做了进一步的优化。代码如下。

`timescale 1ns / 1ps

module var_compute(
        input   wire            clk,
        input   wire            rst_n,
        input   wire    [7:0]   data_in,
        input   wire            valid_in,
        output  wire    [15:0]  variance,
        output  reg             valid_out
);

//==================================================================
//                        Parameter define
//==================================================================
parameter       N = 256;

//==================================================================
//                        Internal Signals
//==================================================================
reg     [31:0]  count;
(* MARK_DEBUG="true" *) reg     [15:0]  sum;
(* MARK_DEBUG="true" *) reg     [23:0]  square_sum;
(* MARK_DEBUG="true" *) wire    [7:0]   mean;
(* MARK_DEBUG="true" *) wire    [15:0]  square_mean;
(* MARK_DEBUG="true" *) wire    [15:0]  mean_square;
(* MARK_DEBUG="true" *) wire    [31:0]  sum_square;    // 🔺修改

assign sum_square       = (valid_in==1'b1 && count == N) ? (sum*sum) : 'd0; // 🔺修改
assign mean_square      = sum_square[31-:16]; // 🔺修改
assign square_mean      = square_sum[23-:16];
assign variance = ( (valid_in==1'b1) && (count == N) && (square_mean > mean_square) ) ? (square_mean - mean_square) : 'd0;

//----------------------------- valid_out -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                valid_out <= 1'b0;     
        end
        else if (count == (N-1) )begin
                valid_out <= 1'b1;
        end
        else begin
                valid_out <= 1'b0;
        end
end

//----------------------------- count -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                count <= 'd0;     
        end
        else if (valid_in==1'b1)begin
                if (count == N) begin
                        count <= 'd0;
                end
                else begin
                        count <= count + 1'b1;
                end
        end
        else begin
                count <= 'd0;
        end
end


//----------------------------- sum -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                sum <= 'd0;     
        end
        else if (valid_in==1'b1)begin
                if (count == N) begin
                        sum <= 'd0;                       
                end
                else begin
                        sum <= sum + data_in;
                end
        end
        else begin
                sum <= 'd0;
        end
end


//----------------------------- square_sum -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                square_sum <= 'd0;     
        end
        else if (valid_in==1'b1)begin
                if (count == N) begin
                        square_sum <= 'd0;                     
                end
                else begin
                        square_sum <= square_sum + data_in*data_in;
                end
        end
        else begin
                square_sum <= 'd0;
        end
end

endmodule

本文之所得:

                0、C知道的代码不能是直接用的,只能参考,别想偷懒。

                1、ModelSim高效仿真小技巧(其实在前面的博文已经强调过一次,再次强调一遍,真的很高效)

                2、一个时序逻辑模块里面,尽量只给一个变量赋值。

                3、用组合逻辑可以优化时序逻辑的延迟。

                4、组合逻辑的运算一定要注意位宽匹配的问题。

                5、验证算法同时还要考虑精度问题文章来源地址https://www.toymoban.com/news/detail-657940.html

到了这里,关于FPGA_学习_13_方差计算小模块的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA学习笔记-1 FPGA原理与开发流程

    注:笔记主要参考: B站 正点原子 教学视频“正点原子手把手教你学FPGA-基于达芬奇Pro开发板 Artix-7 XC7A35T/XC7A100T”。 小梅哥爱漂流 教学视频“【零基础轻松学习FPGA】小梅哥Xilinx FPGA基础入门到项目应用培训教程”。 B站搬运 “特权同学2020版《深入浅出玩转FPGA视频教程》

    2024年02月05日
    浏览(37)
  • FPGA 开发必备:从零开始学习 FPGA 设计

    FPGA 开发必备:从零开始学习 FPGA 设计 FPGA 是一种可编程逻辑器件,可以在不用重新设计硬件电路的情况下修改其功能。它是数字电路设计中最重要的组成部分之一。FPGA 的广泛应用领域包括通信、计算机、图像处理、音频处理等。 要想成为一名合格的 FPGA 工程师,你需要了

    2024年02月07日
    浏览(45)
  • FPGA学习笔记:verilog基础代码与modelsim仿真(六)——vga显示模块

    VGA显示 目标:实现屏幕红、橙、黄、绿、青、蓝、紫、黑、白、灰条形显示 1. 模块框图与波形图 vga_colorbar是实现目标功能的总体模块框图,为了实现对应的输出,我们使用三个具体功能模块实现功能。 (1) clk_gen——使用pll锁相环实现时钟分频 (2)vga_ctrl——图像控制与输出模

    2024年02月04日
    浏览(33)
  • 【FPGA零基础学习之旅#10】按键消抖模块设计与验证(一段式状态机实现)

    🎉欢迎来到FPGA专栏~按键消抖模块设计与验证 ☆* o(≧▽≦)o *☆ 嗨 ~我是 小夏与酒 🍹 ✨ 博客主页: 小夏与酒的博客 🎈该系列 文章专栏: FPGA学习之旅 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏 📜 欢迎大家关注! ❤️ 🥝 模块设计: 🥝 按键消

    2024年02月12日
    浏览(33)
  • 概率论的学习和整理13--方差和协方差(未完成)

    一组数据的方差,没有加权信息,一般认为是 等概率的,按个数进行平均算方差 随机变量的方差,因为有概率作为权重,需要按概率算方差 常见说法,说到方差,一般把期望和方差成对出现一起说 什么是期望? 期望是一种平均值,出自赌博,是用概率做权重,随机变量的

    2024年02月03日
    浏览(28)
  • 【FPGA协议篇】UART通信及其verilog实现(代码采用传参实现模块通用性,适用于快速开发)

    ​ 即通用异步收发器(Universal Asynchronous Receiver/Transmitter),是一种 串行、异步、全双工 的通信协议。特点是通信线路简单,适用于远距离通信,但传输速度慢。 数据传输速率:波特率(单位:baud,波特) 常见波特率有:1200、2400、4800、19200、38400、57600等,最常用的是9600和11520

    2024年02月05日
    浏览(36)
  • FPGA-DFPGL22学习2-开发平台学习

    @和原子哥一起学习FPGA 开发环境:正点原子 ATK-DFPGL22G 开发板 参考书籍: 《ATK-DFPGL22G之FPGA开发指南_V1.1.pdf》 个人学习笔记,欢迎讨论 新建一个文件夹用于存放自己的 PDS 工程 新建一个 Verilog 顶层文件,然后将设计的代码输入到新建的 Verilog 顶层文件中 关联了一下打开Veri

    2024年02月07日
    浏览(31)
  • [FPGA 学习记录] 快速开发的法宝——IP核

    快速开发的法宝——IP核 在本小节当中,我们来学习一下 IP 核的相关知识。 IP 核在 FPGA 开发当中应用十分广泛,它被称为快速开发的法宝。在本小节当中,我们将和各位朋友一起来学习了解 IP 核的相关知识、理解掌握 IP 核的调用方法。 我们分为以下几个部分进行 IP 核的学

    2024年02月05日
    浏览(34)
  • 【两周学会FPGA】从0到1学习紫光同创FPGA开发|盘古PGL22G开发板学习之数码管静态显示(四)

      本原创教程由深圳市小眼睛科技有限公司创作,版权归本公司所有,如需转载,需授权并注明出处 适用于板卡型号: 紫光同创PGL22G开发平台(盘古22K) 一:盘古22K开发板(紫光同创PGL22G开发平台)简介 盘古22K开发板是基于紫光同创Logos系列PGL22G芯片设计的一款FPGA开发板

    2024年02月10日
    浏览(33)
  • 二、13【FPGA】按键消抖

    学习说明此文档为本人的学习笔记,注重实践,关于理论部分会给出相应的学习链接。 学习视频:是根据野火FPGA视频教程——第十六讲 https://www.bilibili.com/video/BV1nQ4y1Z7zN?p=3 按键常常作为系统复位信号和控制信号的外部输入,主要分为自锁按键、机械按键和薄膜按键等。开发

    2023年04月26日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包