• 1-verilog的串行滤波器FIR实现


    参考文献:
    1,基于FPGA的串行FIR滤波器设计与实现
    2,FPGA实现FIR滤波器

    1,RTL代码

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date: 2023/11/21 22:55:41
    // Design Name: 
    // Module Name: fir_tops
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    module	fir_tops(
    input	i_clk,
    input	i_rst,
    input	signed	[1:0]	i_din,	//	 signed是默认的,
    						//	表示这个变量是有符号的,
    						//	可以用来存储整数和负数
    output	signed	[15:0]	o_dout
    );
    // 滤波器系数
    parameter	b0 	= 14'd82;
    parameter	b1	= 14'd317;
    parameter	b2	= 14'd788;
    parameter	b3	= 14'd1023;
    parameter	b4	= 14'd788;
    parameter	b5	= 14'd317;
    parameter	b6	= 14'd82;
    
    reg		signed	[1:0]	x0;
    reg		signed	[1:0]	x1;
    reg		signed	[1:0]	x2;
    reg		signed	[1:0]	x3;
    reg		signed	[1:0]	x4;
    reg		signed	[1:0]	x5;
    reg		signed	[1:0]	x6;
    
    //	延迟
    always@(posedge i_clk or posedge i_rst)	begin
    	if(i_rst)	begin
    		x0	<= 2'd0;
    		x1	<= 2'd0;
    		x2	<= 2'd0;
    		x3	<= 2'd0;
    		x4	<= 2'd0;
    		x5	<= 2'd0;
    		x6	<= 2'd0;
    		end
    	else	begin     // 移位
    		x0	<= i_din;
    		x1	<= x0;
    		x2	<= x1;
    		x3	<= x2;
    		x4	<= x3;
    		x5	<= x4;
    		x6	<= x5;
    		end
    end
    
    //	使用乘法器ip核计算乘法
    wire	signed	[15:0]	r0;
    multer	u0_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x0),		// input  wire [1:0]  A
    .B			(b0),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r0)		// output wire [15:0] P
    );
    
    wire	signed	[15:0]	r1;
    multer	u1_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x1),		// input  wire [1:0]  A
    .B			(b1),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r1)		// output wire [15:0] P
    );
    
    wire	signed	[15:0]	r2;
    multer	u2_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x2),		// input  wire [1:0]  A
    .B			(b2),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r2)		// output wire [15:0] P
    );
    
    wire	signed	[15:0]	r3;
    multer	u3_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x3),		// input  wire [1:0]  A
    .B			(b3),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r3)		// output wire [15:0] P
    );
    
    wire	signed	[15:0]	r4;
    multer	u4_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x4),		// input  wire [1:0]  A
    .B			(b4),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r4)		// output wire [15:0] P
    );
    
    wire	signed	[15:0]	r5;
    multer	u5_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x5),		// input  wire [1:0]  A
    .B			(b5),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r5)		// output wire [15:0] P
    );
    
    wire	signed	[15:0]	r6;
    multer	u6_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x6),		// input  wire [1:0]  A
    .B			(b6),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r6)		// output wire [15:0] P
    );
    
    assign	o_dout	= r0 + r1 + r2 + r3 + r4 + r5 + r6;
    
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136

    2,RTL原理框图

    在这里插入图片描述

    3,测试代码

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date: 2023/11/21 22:55:41
    // Design Name: 
    // Module Name: fir_tops
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    module	fir_tops(
    input	i_clk,
    input	i_rst,
    input	signed	[1:0]	i_din,	//	 signed是默认的,
    						//	表示这个变量是有符号的,
    						//	可以用来存储整数和负数
    output	signed	[15:0]	o_dout
    );
    // 滤波器系数
    parameter	b0 	= 14'd82;
    parameter	b1	= 14'd317;
    parameter	b2	= 14'd788;
    parameter	b3	= 14'd1023;
    parameter	b4	= 14'd788;
    parameter	b5	= 14'd317;
    parameter	b6	= 14'd82;
    
    reg		signed	[1:0]	x0;
    reg		signed	[1:0]	x1;
    reg		signed	[1:0]	x2;
    reg		signed	[1:0]	x3;
    reg		signed	[1:0]	x4;
    reg		signed	[1:0]	x5;
    reg		signed	[1:0]	x6;
    
    //	延迟
    always@(posedge i_clk or posedge i_rst)	begin
    	if(i_rst)	begin
    		x0	<= 2'd0;
    		x1	<= 2'd0;
    		x2	<= 2'd0;
    		x3	<= 2'd0;
    		x4	<= 2'd0;
    		x5	<= 2'd0;
    		x6	<= 2'd0;
    		end
    	else	begin     // 移位
    		x0	<= i_din;
    		x1	<= x0;
    		x2	<= x1;
    		x3	<= x2;
    		x4	<= x3;
    		x5	<= x4;
    		x6	<= x5;
    		end
    end
    
    //	使用乘法器ip核计算乘法
    wire	signed	[15:0]	r0;
    multer	u0_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x0),		// input  wire [1:0]  A
    .B			(b0),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r0)		// output wire [15:0] P
    );
    
    wire	signed	[15:0]	r1;
    multer	u1_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x1),		// input  wire [1:0]  A
    .B			(b1),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r1)		// output wire [15:0] P
    );
    
    wire	signed	[15:0]	r2;
    multer	u2_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x2),		// input  wire [1:0]  A
    .B			(b2),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r2)		// output wire [15:0] P
    );
    
    wire	signed	[15:0]	r3;
    multer	u3_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x3),		// input  wire [1:0]  A
    .B			(b3),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r3)		// output wire [15:0] P
    );
    
    wire	signed	[15:0]	r4;
    multer	u4_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x4),		// input  wire [1:0]  A
    .B			(b4),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r4)		// output wire [15:0] P
    );
    
    wire	signed	[15:0]	r5;
    multer	u5_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x5),		// input  wire [1:0]  A
    .B			(b5),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r5)		// output wire [15:0] P
    );
    
    wire	signed	[15:0]	r6;
    multer	u6_multer(
    .CLK		(i_clk),	// input  wire CLK
    .A			(x6),		// input  wire [1:0]  A
    .B			(b6),		// input  wire [13:0] B
    .SCLR		(i_rst),	// input  wire SCLR
    .P			(r6)		// output wire [15:0] P
    );
    
    assign	o_dout	= r0 + r1 + r2 + r3 + r4 + r5 + r6;
    
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136

    4,输出FIR滤波器的波形

    在这里插入图片描述

    注意:
    1,输出波形有误差,需要修改;
    2,vivado对IP catalog进行了调用;这里要注重调用的方法。
    3,测试代码结合起来理解输出波形。

    使用zynq-7000的IP核:

    在这里插入图片描述

  • 相关阅读:
    『力扣每日一题07』字符串最后一个单词的长度
    vite+vue3 + ts 项目搭建——pinia
    灰度负载均衡和普通负载均衡有什么区别
    查阅标准文档以及effective c++作者文笔 真正搞懂万能引用和引用折叠以及完美转发
    字符设备驱动框架的搭建
    JS 流行框架(二):Express
    专家特写 | 乾龙:一切都是从拆电脑开始的
    C++ 动态库热加载
    android音频学习笔记之wav文件
    内网穿透无法访问本地wordpress网站
  • 原文地址:https://blog.csdn.net/qq_21952195/article/details/134543422