module fir4_3(clk,rst_n,fir_in,fir_out)
parameter in_width=8
parameter out_width=18
parameter h0=8'd63,h1=8'd127,h2=8'd127,h3=8'd63 //系数
input clk
input rst_n
input signed [in_width-1:0] fir_in //输入数据位宽是8
output reg signed [out_width-1:0] fir_out //输出数据位宽是17
reg [out_width-1:0] fir_out_reg //输入输出寄存
reg [in_width-1:0] fir_in_reg
reg [in_width-1:0] shift[2:0] //delay模块
wire [15:0] mult[3:0] //乘法器输出
reg [16:0] adder[1:0] //加法器输出
integer i //循环计数
//**************输入输出加一拍****************
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
fir_in_reg<=8'd0
fir_out<=18'd0
end
else
begin
fir_in_reg<=fir_in
fir_out<=fir_out_reg
end
end
//*************delay模块***********************
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
for(i=2i>=0i=i-1)
shift[i]<=8'd0
else
begin
for(i=2i>0i=i-1)
shift[i]<=shift[i-1]
shift[0]<=fir_in_reg
end
end
//******************例化乘法器****************
mul mul1(.dataa(h0),.datab(fir_in_reg),.result(mult[0])),
mul2(.dataa(h1),.datab(shift[0]),.result(mult[1])),
mul3(.dataa(h2),.datab(shift[1]),.result(mult[2])),
mul4(.dataa(h3),.datab(shift[2]),.result(mult[3]))
//****************adder tree******************
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
adder[1]<=17'd0
adder[0]<=17'd0
fir_out_reg<=18'd0
end
else
begin
adder[0]<=mult[0]+mult[1]
adder[1]<=mult[2]+mult[3]
fir_out_reg<=adder[0]+adder[1]
end
end
endmodule
这是顶层模块,其中乘法器可以使用fpga的资源,也可以直接用自己优化的方式实现。我已经成功仿真过,没问题。以上,有什么问题可以追问
module INV_FIR(clk,x_in,y)input clk
input [7:0] x_in
output [10:0] y
reg [18:0] m0,m1,m2,m3,m4,m5//used for piple
reg [18:0] x40,x61,x70 //modulus of filter
reg [18:0] x32,x64,x8,x2 //medians which filter will use
reg [7:0] x
wire [18:0] x_ext
assign x_ext={{9*{x[7]}},x}// extend x
assign y=(m0>8) // output
always @ (posedge clk)
begin
x<=x_in
m0<=m1+x40
m1<=m2+x61
m2<=m3+x70
m3<=m4+x61
m4<=x40
end
always @ (posedge clk) //this modulus will multi with x
begin
x40<=x32+x8
x61<=x64-x2-x
x70<=x64+x8-x2
end
always @ (x_ext) //some medians which will be used for multiplication
begin
x2<=(x_ext<<1)
x8<=(x2<<2)
x32<=(x8<<2)
x64<=(x32<<1)
end
endmodule
这是个以前做的fir 给你参考一下吧。
<<和>>是移位运算符
,x<<y的意思就是把x按照位左移y位。比如x
=
1100
1010,
y
=
2那么x
<<
y
=
1100
1010
00.
同理>>就是右移啦,一样的。
在verilog中,因为FPGA不太好实现乘除之类的运算,所以有时会用左移右移来表示某些特殊情况的乘除法。比如这句ClkFrequency>>5就是相当于ClkFrequency/(2^5).
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)