|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
两个信号发生器分别产生200Hz和800Hz的信号,最后用加法得到的结果输入到低通滤波器,用signaltapii进行的板极调试,问题是结果仅仅是输入的幅值增大,没有产生滤波效果。FIR低通滤波器的功能模块用modelsim仿真正确,激励的产生是用matlab。如何才能让信号发生器和FIR低通滤波器有正确的数据传输,或者如何才能在板极调试的过程中FIR低通滤波器的激励如何提供?本人小白,有什么没有描述清楚的,可以具体讨论呐~谢谢大家的帮忙啦,纠结好久了
FIR源程序
- module FirFullSerial (
- rst,clk,Xin,Yout);
-
- input rst; //复位信号,高电平有效
- input clk; //FPGA系统时钟,频率为16kHz
- input signed [11:0] Xin; //数据输入频率为2khZ
- output signed [28:0] Yout; //滤波后的输出数据
- //实例化有符号数乘法器IP核mult
- reg signed [11:0] coe; //滤波器为12比特量化数据
- wire signed [12:0] add_s; //输入为12比特量化数据,两个对称系数相加需要13比特存储
- wire signed [24:0] Mout;
- mult Umult (
- .clock (clk),
- .dataa (coe),
- .datab (add_s),
- .result (Mout));
- //实例化有符号数加法器IP核,对输入数据进行1位符号位扩展,输出结果为13比特数据
- reg signed [12:0] add_a;
- reg signed [12:0] add_b;
- adder Uadder (
- .dataa (add_a),
- .datab (add_b),
- .result (add_s));
-
- //3位计数器,计数周期为8,为输入数据速率
- reg [2:0] count;
- always @(posedge clk or posedge rst)
- if (rst)
- count = 3'd0;
- else
- count = count + 1;
-
- //将数据存入移位寄存器Xin_Reg中
- reg [11:0] Xin_Reg[15:0];
- reg [3:0] i,j;
- always @(posedge clk or posedge rst)
- if (rst)
- //初始化寄存器值为0
- begin
- for (i=0; i<15; i=i+1)
- Xin_Reg[i]=12'd0;
- end
- else
- begin
- if (count==7)
- begin
- for (j=0; j<15; j=j+1)
- Xin_Reg[j+1] <= Xin_Reg[j];
- Xin_Reg[0] <= Xin;
- end
- end
-
- //将对称系数的输入数据相加,同时将对应的滤波器系数送入乘法器
- //需要注意的是,下面程序只使用了一个加法器及一个乘法器资源
- //以8倍数据速率调用乘法器IP核,由于滤波器长度为16,系数具有对称性,故可在一个数据
- //周期内完成所有8个滤波器系数与数据的乘法运算
- //为了保证加法运算不溢出,输入输出数据均扩展为13比特。
- always @(posedge clk or posedge rst)
- if (rst)
- begin
- add_a <= 13'd0;
- add_b <= 13'd0;
- coe <= 12'd0;
- end
- else
- begin
- if (count==3'd0)
- begin
- add_a <= {Xin_Reg[0][11],Xin_Reg[0]};
- add_b <= {Xin_Reg[15][11],Xin_Reg[15]};
- coe <= 12'h000;//c0
- end
- else if (count==3'd1)
- begin
- add_a <= {Xin_Reg[1][11],Xin_Reg[1]};
- add_b <= {Xin_Reg[14][11],Xin_Reg[14]};
- coe <= 12'hffd; //c1
- end
- else if (count==3'd2)
- begin
- add_a <= {Xin_Reg[2][11],Xin_Reg[2]};
- add_b <= {Xin_Reg[13][11],Xin_Reg[13]};
- coe <= 12'h00f; //c2
- end
- else if (count==3'd3)
- begin
- add_a <= {Xin_Reg[3][11],Xin_Reg[3]};
- add_b <= {Xin_Reg[12][11],Xin_Reg[12]};
- coe <= 12'h02e; //c3
- end
- else if (count==3'd4)
- begin
- add_a <= {Xin_Reg[4][11],Xin_Reg[4]};
- add_b <= {Xin_Reg[11][11],Xin_Reg[11]};
- coe <= 12'hf8b; //c4
- end
- else if (count==3'd5)
- begin
- add_a <= {Xin_Reg[5][11],Xin_Reg[5]};
- add_b <= {Xin_Reg[10][11],Xin_Reg[10]};
- coe <= 12'hef9; //c5
- end
- else if (count==3'd6)
- begin
- add_a <= {Xin_Reg[6][11],Xin_Reg[6]};
- add_b <= {Xin_Reg[9][11],Xin_Reg[9]};
- coe <= 12'h24e; //c6
- end
- else
- begin
- add_a <= {Xin_Reg[7][11],Xin_Reg[7]};
- add_b <= {Xin_Reg[8][11],Xin_Reg[8]};
- coe <= 12'h7ff; //c7
- end
- end
- //对滤波器系数与输入数据的乘法结果进行累加,并输出滤波后的数据
- //考虑到乘法器及累加器的延时,需要计数器为2时对累加器清零,同时输出滤波器结果数据。
- //类似的时延长度一方面可通过精确计算获取,但更好的方法是通过行为仿真查看
- reg signed [28:0] sum;
- reg signed [28:0] yout;
- always @(posedge clk or posedge rst)
- if (rst)
- begin
- sum = 29'd0;
- yout <= 29'd0;
- end
- else
- begin
- if (count==2)
- begin
- yout <= sum;
- sum = 29'd0;
- sum =sum + Mout;
- end
- else
- sum = sum + Mout;
- end
-
- assign Yout = yout;
-
- endmodule
复制代码
testbench仿真程序
- `timescale 1 ns/ 1 ns //设置仿真时间单位:ns
- module FirFullSerial_vlg_tst();
- // constants
- // general purpose registers
- reg eachvec;
- // test vector input registers
- reg [11:0] Xin;
- reg clk;
- reg rst;
- reg clk_data; //数据时钟,速率为系统时钟clk的1/8;
- // wires
- wire [28:0] Yout;
- // assign statements (if any)
- FirFullSerial i1 (
- // port map - connection between master ports and signals/registers
- .Xin(Xin),
- .Yout(Yout),
- .clk(clk),
- .rst(rst)
- );
- parameter clk_period=625; //设置时钟信号周期(频率):1.6MHz
- parameter clk_period_data=clk_period*8;
- parameter clk_half_period=clk_period/2;
- parameter clk_half_period_data=clk_half_period*8;
- parameter data_num=2000; //仿真数据长度
- parameter time_sim=data_num*clk_period; //仿真时间
- initial
- begin
- //设置时钟信号初值
- clk=1;
- clk_data=1;
- //设置复位信号
- rst=1;
- #1000 rst=0;
- //设置仿真时间
- #time_sim $finish;
- //设置输入信号初值
- Xin=12'd10;
- end
- //产生时钟信号
- always
- #clk_half_period clk=~clk;
- always
- #clk_half_period_data clk_data=~clk_data;
- //从外部TX文件(SinIn.txt)读入数据作为测试激励
- integer Pattern;
- reg [11:0] stimulus[1:data_num];
- initial
- begin
- $readmemb("E4_7_Bin_noise.txt",stimulus);
- //$readmemb("E4_7_Bin_s.txt",stimulus);
- Pattern=0;
- repeat(data_num)
- begin
- Pattern=Pattern+1;
- Xin=stimulus[Pattern];
- #clk_period_data;//数据周期为时钟周期的8倍
- end
- end
- //将仿真数据dout写入外部TXT文件中(out.txt)
- integer file_out;
- initial
- begin
- //文件放置在"工程目录\simulation\modelsim"路径下
- file_out = $fopen("E4_7_Noiseout.txt");
- //file_out = $fopen("E4_7_Sout.txt");
- if(!file_out)
- begin
- $display("could not open file!");
- $finish;
- end
- end
- wire rst_write;
- wire signed [28:0] dout_s;
- assign dout_s = Yout; //将dout转换成有符号数据
- assign rst_write = clk_data & (!rst);//产生写入时钟信号,复位状态时不写入数据
- always @(posedge rst_write )
- $fdisplay(file_out,"%d",dout_s);
-
- endmodule
复制代码
|
|