FPGA 的 DSP:Verilog 中的简单 FIR 滤波器

news2024/11/24 8:45:28

本项目介绍如何用 Verilog 实现一个带有预生成系数的简单 FIR 滤波器。

在这里插入图片描述

Things used in this project 、

在这里插入图片描述

Story

简陋的 FIR 滤波器是 FPGA 数字信号处理中最基本的构建模块之一,因此了解如何利用给定的抽头数和相应的系数值组装一个基本模块非常重要。因此,在这个关于在 FPGA 上入门 DSP 基础知识的实用方法迷你系列中,我将从一个简单的 15 抽头低通滤波器 FIR 开始,先在 Matlab 中生成初始系数值,然后将这些数值转换为 Verilog 模块中的使用值。

有限脉冲响应或 FIR 滤波器的定义是,滤波器的脉冲响应在一定时间内趋于零值,因此它是有限的。脉冲响应归零所需的时间与滤波器的阶(抽头数)直接相关,而阶(抽头数)就是 FIR 底部传递函数多项式的阶数。FIR 的传递函数不包含反馈,因此如果输入一个值为 1 的脉冲,然后是一堆零值,那么输出将只是滤波器的系数值。

任何滤波器的作用都是对信号进行调节,主要侧重于选择滤除或允许哪些频率通过。最简单的例子之一就是低通滤波器,它允许低于某一阈值(截止频率)的频率通过,同时大大衰减高于该阈值的频率,如下图所示。

在这里插入图片描述
本项目的主要重点是在 HDL(特别是 Verilog,但其概念可以很容易地转换为 VHDL)中实现 FIR,可将其分解为三个主要逻辑组件:将每个采样时钟送入的循环缓冲器,该缓冲器可适当考虑串行输入的延迟;每个抽头系数值的乘法器;以及每个抽头输出相加结果的累加器寄存器。

在这里插入图片描述
由于我的重点是 FPGA 逻辑中的 FIR 机制,因此我只是使用 Simulink 和 Matlab 中的 FDA 工具为低通滤波器插入一些简单的参数,然后使用生成的系数值为 Verilog 模块计算适当的寄存器值(稍后完成)。

在这里插入图片描述
我选择实施一个简单的 15 抽头低通滤波器 FIR,采样频率为 1Ms/s,通带频率为 200 kHz,截止频率为 355kHz,从而得到以下系数:

在这里插入图片描述

Create Design File for FIR Module

在新的 Vivado 项目中从头开始,使用流程导航器窗口中的添加源选项为 FIR 模块创建新的设计源。
在这里插入图片描述

在确定了 FIR 的阶数(抽头数)和系数值之后,下一组必须定义的参数是输入采样、输出采样和系数本身的位宽。

对于这个 FIR,我选择将输入采样和系数寄存器设置为 16 位宽,输出采样寄存器设置为 32 位宽,因为两个 16 位值的乘积是一个 32 位值(两个值相乘的宽度相加得出乘积的宽度,因此如果我选择 16 位输入采样和 8 位抽头,那么输出采样的宽度将是 24 位)。

这些值也都是带符号的,因此 MSB 被用作符号位,其余较低的位数则是值必须包含的位数(在选择输入采样寄存器的初始宽度时务必牢记这一点)。要在 Verilog 中将这些值设置为有符号数据类型,需要使用关键字 signed:

reg signed [15:0] register_name;

接下来要解决的问题是如何在 Verilog 中处理系数值,需要将十进制点值转换为定点值。由于所有的系数值都小于 1,因此寄存器的全部 15 位(总共 16 位中的 MSB 为带符号位)都可以用于小数位。通常,你必须决定寄存器中的整数部分和小数部分各占多少位。因此,转换小数抽头的数学方法是:(小数系数值)*(2^(15)),如果系数值为负数,该乘积的任何十进制值都将被四舍五入,并计算该值的两位数:

在这里插入图片描述
现在,我们终于可以专注于 FIR 模块的逻辑了,首先是循环缓冲器,它引入串行输入采样流,并为滤波器的 15 个抽头创建一个包含 15 个输入采样的数组。

    always @ (posedge clk)
        begin
            if(enable_buff == 1'b1)
                begin
                    buff0 <= in_sample;
                    buff1 <= buff0;        
                    buff2 <= buff1;         
                    buff3 <= buff2;      
                    buff4 <= buff3;      
                    buff5 <= buff4;       
                    buff6 <= buff5;    
                    buff7 <= buff6;       
                    buff8 <= buff7;       
                    buff9 <= buff8;       
                    buff10 <= buff9;        
                    buff11 <= buff10;       
                    buff12 <= buff11;       
                    buff13 <= buff12;       
                    buff14 <= buff13;    
                end
        end

接下来,乘法阶段将每个样本乘以每个系数值:

always @ (posedge clk)
        begin
            if (enable_fir == 1'b1)
                begin
                    acc0 <= tap0 * buff0;
                    acc1 <= tap1 * buff1;
                    acc2 <= tap2 * buff2;
                    acc3 <= tap3 * buff3;
                    acc4 <= tap4 * buff4;
                    acc5 <= tap5 * buff5;
                    acc6 <= tap6 * buff6;
                    acc7 <= tap7 * buff7;
                    acc8 <= tap8 * buff8;
                    acc9 <= tap9 * buff9;
                    acc10 <= tap10 * buff10;
                    acc11 <= tap11 * buff11;
                    acc12 <= tap12 * buff12;
                    acc13 <= tap13 * buff13;
                    acc14 <= tap14 * buff14;
                end
        end 

乘法阶段的结果值通过加法累积到寄存器中,最终成为滤波器的输出数据流。

 /* Accumulate stage of FIR */   
    always @ (posedge clk) 
        begin
            if (enable_fir == 1'b1)
                begin
                    m_axis_fir_tdata <= acc0 + acc1 + acc2 + acc3 + acc4 + acc5 + acc6 + acc7 + acc8 + acc9 + acc10 + acc11 + acc12 + acc13 + acc14;
                end
        end 

最后,逻辑的最后一部分是 FIR 模块的数据流接口。AXI 流接口是最常见的接口之一,因此我选择了它来实现。其关键在于有效信号和就绪信号,这两个信号可以控制上下游设备之间的数据流。这意味着 FIR 模块需要向其下游设备提供一个有效信号,以表明其输出为有效数据,同时在下游设备取消就绪信号时,能够暂停(但仍保留)其输出。FIR 模块还必须能够在其主站接口上以同样的方式与上游设备进行通信。

在这里插入图片描述

以下是 FIR 模块的逻辑设计概览:
在这里插入图片描述
请注意有效信号和就绪信号是如何设置 FIR 输入循环缓冲器和乘法级的使能值的,以及数据或系数通过的每个寄存器是如何声明为带符号的。

FIR 模块 Verilog 代码:

`timescale 1ns / 1ps

module FIR(
    input clk,
    input reset,
    input signed [15:0] s_axis_fir_tdata, 
    input [3:0] s_axis_fir_tkeep,
    input s_axis_fir_tlast,
    input s_axis_fir_tvalid,
    input m_axis_fir_tready,
    output reg m_axis_fir_tvalid,
    output reg s_axis_fir_tready,
    output reg m_axis_fir_tlast,
    output reg [3:0] m_axis_fir_tkeep,
    output reg signed [31:0] m_axis_fir_tdata
    );


    always @ (posedge clk)
        begin
            m_axis_fir_tkeep <= 4'hf;
        end
        
    always @ (posedge clk)
        begin
            if (s_axis_fir_tlast == 1'b1)
                begin
                    m_axis_fir_tlast <= 1'b1;
                end
            else
                begin
                    m_axis_fir_tlast <= 1'b0;
                end
        end
    
    // 15-tap FIR 
    reg enable_fir, enable_buff;
    reg [3:0] buff_cnt;
    reg signed [15:0] in_sample; 
    reg signed [15:0] buff0, buff1, buff2, buff3, buff4, buff5, buff6, buff7, buff8, buff9, buff10, buff11, buff12, buff13, buff14; 
    wire signed [15:0] tap0, tap1, tap2, tap3, tap4, tap5, tap6, tap7, tap8, tap9, tap10, tap11, tap12, tap13, tap14; 
    reg signed [31:0] acc0, acc1, acc2, acc3, acc4, acc5, acc6, acc7, acc8, acc9, acc10, acc11, acc12, acc13, acc14; 

    
    /* Taps for LPF running @ 1MSps with a cutoff freq of 400kHz*/
    assign tap0 = 16'hFC9C;  // twos(-0.0265 * 32768) = 0xFC9C
    assign tap1 = 16'h0000;  // 0
    assign tap2 = 16'h05A5;  // 0.0441 * 32768 = 1445.0688 = 1445 = 0x05A5
    assign tap3 = 16'h0000;  // 0
    assign tap4 = 16'hF40C;  // twos(-0.0934 * 32768) = 0xF40C
    assign tap5 = 16'h0000;  // 0
    assign tap6 = 16'h282D;  // 0.3139 * 32768 = 10285.8752 = 10285 = 0x282D
    assign tap7 = 16'h4000;  // 0.5000 * 32768 = 16384 = 0x4000
    assign tap8 = 16'h282D;  // 0.3139 * 32768 = 10285.8752 = 10285 = 0x282D
    assign tap9 = 16'h0000;  // 0
    assign tap10 = 16'hF40C; // twos(-0.0934 * 32768) = 0xF40C
    assign tap11 = 16'h0000; // 0
    assign tap12 = 16'h05A5; // 0.0441 * 32768 = 1445.0688 = 1445 = 0x05A5
    assign tap13 = 16'h0000; // 0
    assign tap14 = 16'hFC9C; // twos(-0.0265 * 32768) = 0xFC9C
    
    /* This loop sets the tvalid flag on the output of the FIR high once 
     * the circular buffer has been filled with input samples for the 
     * first time after a reset condition. */
    always @ (posedge clk or negedge reset)
        begin
            if (reset == 1'b0) //if (reset == 1'b0 || tvalid_in == 1'b0)
                begin
                    buff_cnt <= 4'd0;
                    enable_fir <= 1'b0;
                    in_sample <= 8'd0;
                end
            else if (m_axis_fir_tready == 1'b0 || s_axis_fir_tvalid == 1'b0)
                begin
                    enable_fir <= 1'b0;
                    buff_cnt <= 4'd15;
                    in_sample <= in_sample;
                end
            else if (buff_cnt == 4'd15)
                begin
                    buff_cnt <= 4'd0;
                    enable_fir <= 1'b1;
                    in_sample <= s_axis_fir_tdata;
                end
            else
                begin
                    buff_cnt <= buff_cnt + 1;
                    in_sample <= s_axis_fir_tdata;
                end
        end   

    always @ (posedge clk)
        begin
            if(reset == 1'b0 || m_axis_fir_tready == 1'b0 || s_axis_fir_tvalid == 1'b0)
                begin
                    s_axis_fir_tready <= 1'b0;
                    m_axis_fir_tvalid <= 1'b0;
                    enable_buff <= 1'b0;
                end
            else
                begin
                    s_axis_fir_tready <= 1'b1;
                    m_axis_fir_tvalid <= 1'b1;
                    enable_buff <= 1'b1;
                end
        end
    
    /* Circular buffer bring in a serial input sample stream that 
     * creates an array of 15 input samples for the 15 taps of the filter. */
    always @ (posedge clk)
        begin
            if(enable_buff == 1'b1)
                begin
                    buff0 <= in_sample;
                    buff1 <= buff0;        
                    buff2 <= buff1;         
                    buff3 <= buff2;      
                    buff4 <= buff3;      
                    buff5 <= buff4;       
                    buff6 <= buff5;    
                    buff7 <= buff6;       
                    buff8 <= buff7;       
                    buff9 <= buff8;       
                    buff10 <= buff9;        
                    buff11 <= buff10;       
                    buff12 <= buff11;       
                    buff13 <= buff12;       
                    buff14 <= buff13;    
                end
            else
                begin
                    buff0 <= buff0;
                    buff1 <= buff1;        
                    buff2 <= buff2;         
                    buff3 <= buff3;      
                    buff4 <= buff4;      
                    buff5 <= buff5;       
                    buff6 <= buff6;    
                    buff7 <= buff7;       
                    buff8 <= buff8;       
                    buff9 <= buff9;       
                    buff10 <= buff10;        
                    buff11 <= buff11;       
                    buff12 <= buff12;       
                    buff13 <= buff13;       
                    buff14 <= buff14;
                end
        end
        
    /* Multiply stage of FIR */
    always @ (posedge clk)
        begin
            if (enable_fir == 1'b1)
                begin
                    acc0 <= tap0 * buff0;
                    acc1 <= tap1 * buff1;
                    acc2 <= tap2 * buff2;
                    acc3 <= tap3 * buff3;
                    acc4 <= tap4 * buff4;
                    acc5 <= tap5 * buff5;
                    acc6 <= tap6 * buff6;
                    acc7 <= tap7 * buff7;
                    acc8 <= tap8 * buff8;
                    acc9 <= tap9 * buff9;
                    acc10 <= tap10 * buff10;
                    acc11 <= tap11 * buff11;
                    acc12 <= tap12 * buff12;
                    acc13 <= tap13 * buff13;
                    acc14 <= tap14 * buff14;
                end
        end    
        
     /* Accumulate stage of FIR */   
    always @ (posedge clk) 
        begin
            if (enable_fir == 1'b1)
                begin
                    m_axis_fir_tdata <= acc0 + acc1 + acc2 + acc3 + acc4 + acc5 + acc6 + acc7 + acc8 + acc9 + acc10 + acc11 + acc12 + acc13 + acc14;
                end
        end     

    
    
endmodule

Create a Simulation Source for its Testbench

要测试 FIR 模块,需要创建一个测试平台作为新的模拟源:
在这里插入图片描述
在 FIR 模块中需要测试两个主要部分:滤波器数学和 AXI 流接口。为此,我在测试台中创建了一个状态机,用于生成一个简单的 200kHz 正弦波,同时切换 FIR 接口从属侧的有效信号和主控侧的就绪信号。

Testbench for FIR module:

`timescale 1ns / 1ps

module tb_FIR;

    reg clk, reset, s_axis_fir_tvalid, m_axis_fir_tready;
    reg signed [15:0] s_axis_fir_tdata;
    wire m_axis_fir_tvalid;
    wire [3:0] m_axis_fir_tkeep;
    wire [31:0] m_axis_fir_tdata;
    
    /*
     * 100Mhz (10ns) clock 
     */
    always begin
        clk = 1; #5;
        clk = 0; #5;
    end
    
    always begin
        reset = 1; #20;
        reset = 0; #50;
        reset = 1; #1000000;
    end
    
    always begin
        s_axis_fir_tvalid = 0; #100;
        s_axis_fir_tvalid = 1; #1000;
        s_axis_fir_tvalid = 0; #50;
        s_axis_fir_tvalid = 1; #998920;
    end
    
    always begin
        m_axis_fir_tready = 1; #1500;
        m_axis_fir_tready = 0; #100;
        m_axis_fir_tready = 1; #998400;
    end
    
    /* Instantiate FIR module to test. */
    FIR FIR_i(
        .clk(clk),
        .reset(reset),
        .s_axis_fir_tdata(s_axis_fir_tdata),   
        .s_axis_fir_tkeep(s_axis_fir_tkeep),   
        .s_axis_fir_tlast(s_axis_fir_tlast),   
        .s_axis_fir_tvalid(s_axis_fir_tvalid), 
        .m_axis_fir_tready(m_axis_fir_tready),
        .m_axis_fir_tvalid(m_axis_fir_tvalid), 
        .s_axis_fir_tready(s_axis_fir_tready), 
        .m_axis_fir_tlast(m_axis_fir_tlast),   
        .m_axis_fir_tkeep(m_axis_fir_tkeep),   
        .m_axis_fir_tdata(m_axis_fir_tdata));  
        
    reg [4:0] state_reg;
    reg [3:0] cntr;
    
    parameter wvfm_period = 4'd4;
    
    parameter init               = 5'd0;
    parameter sendSample0        = 5'd1;
    parameter sendSample1        = 5'd2;
    parameter sendSample2        = 5'd3;
    parameter sendSample3        = 5'd4;
    parameter sendSample4        = 5'd5;
    parameter sendSample5        = 5'd6;
    parameter sendSample6        = 5'd7;
    parameter sendSample7        = 5'd8;
    
    /* This state machine generates a 200kHz sinusoid. */
    always @ (posedge clk or posedge reset)
        begin
            if (reset == 1'b0)
                begin
                    cntr <= 4'd0;
                    s_axis_fir_tdata <= 16'd0;
                    state_reg <= init;
                end
            else
                begin
                    case (state_reg)
                        init : //0
                            begin
                                cntr <= 4'd0;
                                s_axis_fir_tdata <= 16'h0000;
                                state_reg <= sendSample0;
                            end
                            
                        sendSample0 : //1
                            begin
                                s_axis_fir_tdata <= 16'h0000;
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample1;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample0;
                                    end
                            end 
                        
                        sendSample1 : //2
                            begin
                                s_axis_fir_tdata <= 16'h5A7E; 
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample2;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample1;
                                    end
                            end 
                        
                        sendSample2 : //3
                            begin
                                s_axis_fir_tdata <= 16'h7FFF;
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample3;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample2;
                                    end
                            end 
                        
                        sendSample3 : //4
                            begin
                                s_axis_fir_tdata <= 16'h5A7E;
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample4;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample3;
                                    end
                            end 
                        
                        sendSample4 : //5
                            begin
                                s_axis_fir_tdata <= 16'h0000;
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample5;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample4;
                                    end
                            end 
                        
                        sendSample5 : //6
                            begin
                                s_axis_fir_tdata <= 16'hA582; 
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample6;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample5;
                                    end
                            end 
                        
                        sendSample6 : //6
                            begin
                                s_axis_fir_tdata <= 16'h8000; 
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample7;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample6;
                                    end
                            end 
                        
                        sendSample7 : //6
                            begin
                                s_axis_fir_tdata <= 16'hA582; 
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample0;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample7;
                                    end
                            end                     
                    
                    endcase
                end
        end
    
endmodule

在 "source "窗口的模拟来源下,右击测试平台模块并选择 “Set as Top”,将其设置为顶层文件。
在这里插入图片描述

Run a Behavioral Simulation

安装好 FIR 模块及其测试平台后,从 Flow Navigator 窗口启动 Vivado 中的仿真器,选择 Run Behavioral Simulation(运行行为仿真)选项(如果没有综合或实现结果,这是唯一可用的选项)。在这里插入图片描述
正如行为仿真所显示的那样,FIR 正在对信号进行正确的滤波,并对 AXI 流信号做出正确的响应。
在这里插入图片描述
许多人可能会注意到,在使用这种特定 FIR 模块的设计上运行综合和实现,会导致设计无法满足时序要求(我相信阅读此文的经验丰富的 FPGA 工程师只需查看一下 FIR 模块的 Verilog 就能知道这一点)。这将在 FPGA DSP 系列的下一篇文章中讨论,因为它为我们提供了很好的见解,让我们了解在无法满足设置时序要求时如何重新思考设计。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1493735.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学生信息管理展示-h5版(uniapp+springboot+vue)

记录一下做的第一个完整的h5业务。 一、登录 二、个人中心 三、首页&#xff08;管理员&#xff09; 四、首页&#xff08;学生&#xff09; 五、视频展示 学生信息管理展示&#xff08;h5&#xff09;完整版

算法刷题day22:双指针

目录 引言概念一、牛的学术圈I二、最长连续不重复序列三、数组元素的目标和四、判断子序列五、日志统计六、统计子矩阵 引言 关于这个双指针算法&#xff0c;主要是用来处理枚举子区间的事&#xff0c;时间复杂度从 O ( N 2 ) O(N^2) O(N2) 降为 O ( N ) O(N) O(N) &#xf…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:PanGesture)

拖动手势事件&#xff0c;当滑动的最小距离超过设定的最小值时触发拖动手势事件。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 接口 PanGesture(value?: { fingers?: number; direction?: PanDir…

进程的奥德赛:并发世界中的核心概念与动态管理

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…

Java并发编程-进程和线程

一、进程和线程 1. 进程 什么是进程&#xff1f; 简单来说&#xff0c;进程就是程序的一次启动和执行。进程是操作系统中的一个概念&#xff0c;它代表正在运行的程序的实例。每个进程都有自己的内存空间、代码和数据&#xff0c;以及其他操作系统资源&#xff0c;如文件和设备…

数据资产:隐藏在企业内部的金矿

引言 在这个数字化快速发展的时代&#xff0c;数据已成为企业的核心竞争力之一。数据资产不仅代表了企业的知识和智慧&#xff0c;还隐藏着巨大的商业价值。然而&#xff0c;许多企业对于数据资产的价值认识仍然不足&#xff0c;导致大量数据资源被埋没。本文将带您深入了解数…

游戏引擎渲染流程

一、渲染概述 我们首先看到渲染技术的发展 游戏渲染面临的挑战&#xff1a; 一个容器中同一时刻有大量的游戏对象需要进行渲染&#xff0c;并且不同对象渲染的形式、算法还有所差异&#xff0c;这些使得游戏的绘制系统变得非常复杂&#xff1b;其次&#xff0c;游戏引擎的渲染…

小白跟做江科大51单片机之DS1302可调时钟

原理部分 1.DS1302可调时钟介绍 单片机定时器主要占用CPU时间&#xff0c;掉电不能继续运行 图1 2.原理 图2 内部有寄存器&#xff0c;寄存的时候以时分秒寄存&#xff0c;以通信协议实现数据交互&#xff0c;就可以实现对数据进行访问和读写 3.主要寄存器定义 CE芯片使能…

去极值滑动平均值滤波FB(含线速度对比测试波形)

博途PLC滑动平均值滤波相关算法内容在专栏有系列文章,大家可以查看相关文章,常用链接如下: 1、滑动平均值滤波 https://rxxw-control.blog.csdn.net/article/details/124851884https://rxxw-control.blog.csdn.net/article/details/1248518842、博途PLC指数加权平均值滤波…

MATLAB环境下基于离散小波变换的体外血管图像处理

下面简要介绍小波变换的部分应用。 信号去噪。小波去噪是根据有效信号和噪声信号在小波变换后表现出的不同特性实现的&#xff0c;一般可用于去除语音、图像、视频等中的噪声信号。小波去噪方法根据对小波系数的非线性处理方式分为三类&#xff0c;分别是小波变换模极大值去噪…

数学建模【聚类模型】

一、聚类模型简介 “物以类聚&#xff0c; 人以群分”&#xff0c;所谓的聚类&#xff0c;就是将样本划分为由类似的对象组成的多个类的过程。聚类后&#xff0c;我们可以更加准确的在每个类中单独使用统计模型进行估计、分析或预测&#xff0c;也可以探究不同类之间的相关性和…

如何在控制台重新发送请求、修改请求参数

场景一&#xff1a;重新请求接口 - 鼠标右键点击请求&#xff0c;选择重放XHR - 可以看到重新发起了一次请求 注意&#xff1a;重放XHR不会重新渲染页面数据&#xff0c;只是单纯的请求接口 场景二&#xff1a;修改接口参数 - 右键鼠标右键点击接口、选择复制、选择以fetc…

【教程】无法验证app需要互联网连接以验证是否信任开发者

摘要 本文将探讨在使用苹果App时遇到无法验证开发者的情况&#xff0c;以及用户可以采取的解决方案。通过检查网络连接、重新操作、验证描述文件等方式来解决无法验证开发者的问题。同时&#xff0c;还介绍了开发者信任设置的步骤&#xff0c;以及使用appuploader工具进行安装…

Docker 部署Harbor 443端口冲突

如果Harbor的443端口和主机服务器的443端口存在冲突,那么需要修改Harbor的443 修改docker-compose中443端口,那么需要docker-compose.yml和harbor.yml保持一致配置 当修改harbor.yml重启之后不生效的,则需要进入harbor安装路径 执行 ./install.sh 命令 harbor.yml docker-…

TinyEMU编译与使用

TinyEMU编译与使用 1 介绍2 准备工作3 编译TinyEMU3.1 安装依赖库3.2 编译 4 运行TinyEMU4.1 在线运行4.2 离线运行 5 共享目录5.1 修改root_9p-riscv64.cfg5.2 启动TinyEMU5.3 执行挂载命令 6 TinyEMU命令帮助 1 介绍 原名为riscvemu&#xff0c;于2018-09-23&#xff0c;改为…

Git 进阶 高级用法,重要命令记录

本篇文章用于记录Git高级用法&#xff0c;新手可以看我的另一篇文章&#xff1a;Git基础教学。 Git git fetch 是git pull 的细分步骤&#xff0c;git pull 包含了git fetch git pull origin master 上述命令其实相当于git fetch git merge 在实际使用中&#xff0c;git fetc…

msvcr120.dll丢失怎样修复,更了解msvcr120.dll文件从而解决丢失问题

在电脑使用过程中&#xff0c;"msvcr120.dll丢失"是常见的错误提示之一。那么&#xff0c;今天就和大家聊聊msvcr120.dll文件&#xff0c;如果msvcr120.dll文件丢失的问题时什么原因导致的&#xff0c;让我们仔细来看一下msvcr120.dll是什么以及msvcr120.dll丢失怎样…

【二】【SQL Server】如何运用SQL Server中查询设计器通关数据库期末查询大题

教学管理系统201703153 教学管理系统数据库展示 成绩表展示 课程表展示 学生表展示 院系表展示 一、基本操作 设置复合主键 设置其他表的主键 设置字段取值范围 二、简单操作 第一题 第二题 第三题 第四题 结尾 最后&#xff0c;感谢您阅读我的文章&#xff0c;希望这些内容能…

2024年最受欢迎的15款缺陷管理工具

本文整理分享了15款再2024年受欢迎的bug&#xff08;缺陷&#xff09;跟踪管理工具&#xff1a;1.PingCode&#xff1b;2.Worktile&#xff1b;3.SpiraTeam&#xff1b;4. Jira Software&#xff1b;5. BugHerd&#xff1b;6. Zoho Projects&#xff1b;7.SmartSheet&#xff1…

linux实现远程文件夹共享-samba

目录 问题描述Samba如何挂载常用参数临时挂载实例一种长期挂载方法&#xff08;已失败&#xff0c;仅供参考&#xff09;查看挂载取消挂载umount失败 问题描述 我的代码需要访问存在于两个系统&#xff08;win和linux&#xff09;的文件夹&#xff0c;我不是文件夹的创建者&am…