Initial import
git-svn-id: http://moon:8086/svn/vhdl/trunk@5 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
function eval_filter(N)
|
||||
omega_lp = 0.15
|
||||
omega_hp = 0.05
|
||||
|
||||
omega_bp_m = 0.02;
|
||||
bw2_bp = 0.02;
|
||||
|
||||
lp = lowpass(N, omega_lp, 1.0);
|
||||
coef_lp = hann(N)'.*lp./sum(lp.^2);
|
||||
|
||||
hp = lowpass(N, 0.5-omega_hp, 1.0).*cos(pi*(0:N-1));
|
||||
coef_hp = hp./sum(hp.^2).*hann(N)';
|
||||
|
||||
bp = lowpass(N, bw2_bp/2, 1.0).*cos(2*pi*omega_bp_m*(0:N-1));
|
||||
coef_bp = bp./sum(bp.^2).*hann(N)';
|
||||
|
||||
abs_lp = 20*log10(abs(fft(coef_lp)));
|
||||
abs_hp = 20*log10(abs(fft(coef_hp)));
|
||||
abs_bp = 20*log10(abs(fft(coef_bp)));
|
||||
|
||||
close all;
|
||||
plot((0:N/2)/N, abs_lp(1:N/2+1));grid;
|
||||
figure
|
||||
plot((0:N/2)/N, abs_hp(1:N/2+1));grid;
|
||||
figure
|
||||
plot((0:N/2)/N, abs_bp(1:N/2+1));grid;
|
||||
|
||||
figure
|
||||
plot((0:N-1), coef_lp);grid;
|
||||
figure
|
||||
plot((0:N-1), coef_hp);grid;
|
||||
figure
|
||||
plot((0:N-1), coef_bp);grid;
|
||||
|
||||
mean_lp = mean(coef_lp-mean(coef_lp))
|
||||
mean_hp = mean(coef_hp)
|
||||
mean_bp = mean(coef_bp)
|
||||
@@ -0,0 +1,20 @@
|
||||
function coef = lowpass(N, omega, scale)
|
||||
|
||||
phi = 0;
|
||||
dphi = 2*omega;
|
||||
if (mod(N, 2) == 0)
|
||||
M = N/2;
|
||||
for i=0:M-1,
|
||||
phi = phi + dphi;
|
||||
coef(M+i+1) = scale*sinc(phi);
|
||||
coef(M-i-1+1) = coef(M+i+1);
|
||||
end;
|
||||
else
|
||||
M = (N-1)/2;
|
||||
for i=1:M,
|
||||
phi = phi + dphi;
|
||||
coef(M+i+1) = scale*sinc(phi);
|
||||
coef(M-i+1) = coef(M+i+1);
|
||||
end;
|
||||
coef(M+1) = scale*Sinc(0.0);
|
||||
end;
|
||||
@@ -0,0 +1,16 @@
|
||||
vlib work
|
||||
vcom -explicit -93 "../../../lib/fixed/fixed_pkg_c.vhd"
|
||||
vcom -explicit -93 "../../../lib/PCK_FIO-2002.7/PCK_FIO_1993.vhd"
|
||||
vcom -explicit -93 "../../../lib/PCK_FIO-2002.7/PCK_FIO_1993_BODY.vhd"
|
||||
vcom -explicit -93 "../src/filter_pkg.vhd"
|
||||
vcom -explicit -93 "../src/fir_stage_pkg.vhd"
|
||||
vcom -explicit -93 "../src/fir_stage.vhd"
|
||||
vcom -explicit -93 "../src/fir_iterative_pkg.vhd"
|
||||
vcom -explicit -93 "../src/fir_iterative.vhd"
|
||||
vcom -explicit -93 "../src/tb_fir_iterative.vhd"
|
||||
vsim -t 1ps -lib work tb_fir_iterative
|
||||
do {tb_fir_iterative.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 20us
|
||||
@@ -0,0 +1,86 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/srst
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/clk
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/uut_fir_iterative/h_addr
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/ready
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/x_din
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/uut_fir_iterative/s
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/xo
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/coeffs
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/uut_fir_iterative/xtap_cnt_w
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/uut_fir_iterative/xtap_cnt_r
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/uut_fir_iterative/htap_cnt
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/xi
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/yo
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/stage_en
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/fir_stage_clr
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/fir_stage_en
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/cnt_reset
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/x_valid
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/valid
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/y_valid
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/y_dout
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/new_round
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/x_stage
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/h_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/ymem
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/uut_fir_iterative/xmem
|
||||
add wave -noupdate -divider {Xmem Dual}
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/srst
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/clk
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/uut_fir_iterative/h_addr
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/ready
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/x_din
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/uut_fir_iterative/s
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/xo
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/coeffs
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/uut_fir_iterative/xtap_cnt_w
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/uut_fir_iterative/xtap_cnt_r
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/uut_fir_iterative/htap_cnt
|
||||
add wave -noupdate -format Analog-Step -scale 10.0 /tb_fir_iterative/xi
|
||||
add wave -noupdate -format Analog-Step -scale 10.0 /tb_fir_iterative/yo
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/stage_en
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/valid
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/y_valid
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/y_valid
|
||||
add wave -noupdate -format Analog-Step -radix decimal -scale 0.00061037000000000005 /tb_fir_iterative/uut_fir_iterative/y_dout
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/x_valid
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/new_round
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/x_stage
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/h_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/y_stage
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/ymem
|
||||
add wave -noupdate -divider {FIR Stage}
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/clk
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/in_valid
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/y_out_clr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/x_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/h_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/y_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/xin
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/hin
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/yin
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/prod
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/x_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/y_out
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/valid
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/p_valid
|
||||
add wave -noupdate -format Literal /tb_fir_iterative/uut_fir_iterative/s
|
||||
add wave -noupdate -format Logic /tb_fir_iterative/uut_fir_iterative/inst_fir_stage/out_valid
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {1892287 ps} 0}
|
||||
configure wave -namecolwidth 140
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
update
|
||||
WaveRestoreZoom {1750644 ps} {2771198 ps}
|
||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
||||
vlib work
|
||||
vcom -explicit -93 "../../../lib/fixed/fixed_pkg_c.vhd"
|
||||
vcom -explicit -93 "../../../lib/PCK_FIO-2002.7/PCK_FIO_1993.vhd"
|
||||
vcom -explicit -93 "../../../lib/PCK_FIO-2002.7/PCK_FIO_1993_BODY.vhd"
|
||||
vcom -explicit -93 "../src/filter_pkg.vhd"
|
||||
vcom -explicit -93 "../src/fir_stage_pkg.vhd"
|
||||
vcom -explicit -93 "../src/fir_stage.vhd"
|
||||
vcom -explicit -93 "../src/fir_parallel_pkg.vhd"
|
||||
vcom -explicit -93 "../src/fir_parallel.vhd"
|
||||
vcom -explicit -93 "../src/tb_fir_parallel.vhd"
|
||||
vsim -t 1ps -lib work tb_fir_parallel
|
||||
do {tb_fir_parallel.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 1000us
|
||||
@@ -0,0 +1,29 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_fir_parallel/clk
|
||||
add wave -noupdate -format Logic /tb_fir_parallel/srst
|
||||
add wave -noupdate -format Logic /tb_fir_parallel/in_valid
|
||||
add wave -noupdate -format Literal -radix decimal /tb_fir_parallel/x_in
|
||||
add wave -noupdate -format Literal -radix decimal /tb_fir_parallel/y_out
|
||||
add wave -noupdate -format Logic /tb_fir_parallel/out_valid
|
||||
add wave -noupdate -format Logic /tb_fir_parallel/fileout_enable
|
||||
add wave -noupdate -format Analog-Interpolated -scale 10.0 /tb_fir_parallel/xi
|
||||
add wave -noupdate -format Analog-Interpolated -scale 10.0 /tb_fir_parallel/yo
|
||||
add wave -noupdate -format Literal -radix decimal /tb_fir_parallel/coeff_in
|
||||
add wave -noupdate -format Literal -radix decimal /tb_fir_parallel/uut_fir_parallel/h
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {19450000 ps} 0}
|
||||
configure wave -namecolwidth 140
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
update
|
||||
WaveRestoreZoom {0 ps} {25152750 ps}
|
||||
@@ -0,0 +1,10 @@
|
||||
% Read data
|
||||
function tb_fir_results()
|
||||
fir = TEXTREAD('fir.txt')';
|
||||
|
||||
N= length(fir);
|
||||
|
||||
% Output
|
||||
close all;
|
||||
plot(0:N-1, fir); grid;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
vlib work
|
||||
vcom -explicit -93 "../../../lib/fixed/fixed_pkg_c.vhd"
|
||||
vcom -explicit -93 "../../../lib/PCK_FIO-2002.7/PCK_FIO_1993.vhd"
|
||||
vcom -explicit -93 "../../../lib/PCK_FIO-2002.7/PCK_FIO_1993_BODY.vhd"
|
||||
vcom -explicit -93 "../src/filter_pkg.vhd"
|
||||
vcom -explicit -93 "../src/fir_stage_pkg.vhd"
|
||||
vcom -explicit -93 "../src/fir_stage.vhd"
|
||||
vcom -explicit -93 "../src/tb_fir_stage.vhd"
|
||||
vsim -t 1ps -lib work tb_fir_stage
|
||||
do {tb_fir_stage.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 2us
|
||||
@@ -0,0 +1,31 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_fir_stage/clk
|
||||
add wave -noupdate -format Logic /tb_fir_stage/srst
|
||||
add wave -noupdate -divider Input
|
||||
add wave -noupdate -format Logic /tb_fir_stage/in_valid
|
||||
add wave -noupdate -format Literal -radix decimal /tb_fir_stage/x_in
|
||||
add wave -noupdate -format Literal /tb_fir_stage/xi
|
||||
add wave -noupdate -divider Output
|
||||
add wave -noupdate -format Logic /tb_fir_stage/out_valid
|
||||
add wave -noupdate -format Literal -radix decimal /tb_fir_stage/y_out
|
||||
add wave -noupdate -format Analog-Step -scale 10.0 /tb_fir_stage/yo
|
||||
add wave -noupdate -divider {Stage signals}
|
||||
add wave -noupdate -format Literal -radix decimal /tb_fir_stage/x
|
||||
add wave -noupdate -format Literal -radix decimal /tb_fir_stage/y
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {1655000 ps} 0}
|
||||
configure wave -namecolwidth 140
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
update
|
||||
WaveRestoreZoom {0 ps} {2100 ns}
|
||||
@@ -0,0 +1,227 @@
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use ieee.numeric_std.all;
|
||||
use IEEE.MATH_REAL.ALL;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
package filter_pkg is
|
||||
|
||||
constant pi : real := 3.141592653589793e+000;
|
||||
type real_array_t is array (natural range <>) of real;
|
||||
|
||||
function FilterCoef_Lowpass (N : positive; omega, amp : real) return real_array_t;
|
||||
function FilterCoef_Highpass (N : positive; omega, amp : real) return real_array_t;
|
||||
function FilterCoef_Bandpass (N : positive; bw2, omega_m, amp : real) return real_array_t;
|
||||
function FilterCoef_Delta (N:positive; delay:natural; amp:real) return real_array_t;
|
||||
function Window_Hamming (x : real_array_t) return real_array_t;
|
||||
function Window_VonHann (x : real_array_t) return real_array_t;
|
||||
function Window_Blackman (x : real_array_t) return real_array_t;
|
||||
function Sinc (x : real) return real;
|
||||
function FilterEnergy (x : real_array_t) return real;
|
||||
function FilterMean (x : real_array_t) return real;
|
||||
function FilterScale (x : real_array_t; scale : real) return real_array_t;
|
||||
function FilterTestCoef (N : positive) return real_array_t;
|
||||
function NextPowerOfTwo(x : real) return natural;
|
||||
|
||||
end; -- package filter_pkg;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
package body filter_pkg is
|
||||
|
||||
function Prototype_Lowpass (N : positive; omega : real) return real_array_t is
|
||||
variable res : real_array_t(0 to N-1);
|
||||
variable M : positive;
|
||||
variable phi : real := 0.0;
|
||||
variable dphi : real := 2.0*pi*omega;
|
||||
begin
|
||||
if (N mod 2) = 0 then
|
||||
M := N/2;
|
||||
for i in 0 to M-1 loop
|
||||
phi := phi + dphi;
|
||||
res(M+i) := Sinc(phi);
|
||||
res(M-i-1) := res(M+i);
|
||||
end loop;
|
||||
else
|
||||
M := (N-1)/2;
|
||||
for i in 1 to M loop
|
||||
phi := phi + dphi;
|
||||
res(M+i) := Sinc(phi);
|
||||
res(M-i) := res(M+i);
|
||||
end loop;
|
||||
res(M) := Sinc(0.0);
|
||||
end if;
|
||||
return res;
|
||||
|
||||
end Prototype_Lowpass;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
function FilterCoef_Lowpass (N : positive; omega, amp : real) return real_array_t is
|
||||
variable lp : real_array_t(0 to N-1);
|
||||
begin
|
||||
lp := Prototype_Lowpass(N, omega);
|
||||
|
||||
return Window_VonHann(FilterScale(lp, amp/FilterEnergy(lp)));
|
||||
|
||||
end FilterCoef_Lowpass;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
function FilterCoef_Highpass (N : positive; omega, amp : real) return real_array_t is
|
||||
variable lp, res : real_array_t(0 to N-1);
|
||||
variable phi : real := 0.0;
|
||||
variable dphi : real := pi;
|
||||
begin
|
||||
lp := Prototype_Lowpass(N, 0.5-omega);
|
||||
|
||||
for i in 0 to N-1 loop
|
||||
res(i) := lp(i) * cos(phi);
|
||||
phi := phi + dphi;
|
||||
end loop;
|
||||
|
||||
return Window_VonHann(FilterScale(res, amp/FilterEnergy(lp)));
|
||||
|
||||
end FilterCoef_Highpass;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
function FilterCoef_Bandpass (N : positive; bw2, omega_m, amp : real) return real_array_t is
|
||||
variable lp, res, mean, sum : real_array_t(0 to N-1);
|
||||
variable phi : real := 0.0;
|
||||
variable dphi : real := 2.0*pi*omega_m;
|
||||
begin
|
||||
lp := Prototype_Lowpass(N, bw2/2.0);
|
||||
|
||||
for i in 0 to N-1 loop
|
||||
res(i) := lp(i) * cos(phi);
|
||||
phi := phi + dphi;
|
||||
end loop;
|
||||
|
||||
return Window_VonHann(FilterScale(res, amp/FilterEnergy(lp)));
|
||||
|
||||
end FilterCoef_Bandpass;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
function FilterCoef_Delta (N:positive; delay:natural; amp:real) return real_array_t is
|
||||
variable res : real_array_t(0 to N-1);
|
||||
begin
|
||||
for i in 0 to N-1 loop
|
||||
res(i) := 0.0;
|
||||
end loop;
|
||||
res(delay) := amp;
|
||||
|
||||
return res;
|
||||
|
||||
end FilterCoef_Delta;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
function FilterTestCoef (N : positive) return real_array_t is
|
||||
variable phi : real := 0.0;
|
||||
variable dphi : real := 1.0/real(N);
|
||||
variable res : real_array_t(0 to N-1);
|
||||
begin
|
||||
for i in 0 to N-1 loop
|
||||
res(i) := phi;
|
||||
phi := phi + dphi;
|
||||
end loop;
|
||||
return res;
|
||||
|
||||
end FilterTestCoef;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
function Window_Hamming (x : real_array_t) return real_array_t is
|
||||
variable res : real_array_t(x'range);
|
||||
variable phi : real := 0.0;
|
||||
variable dphi : real := 2.0*pi/real(x'length-1);
|
||||
begin
|
||||
for i in x'range loop
|
||||
res(i) := x(i) * (0.54 - 0.46*(cos(phi)));
|
||||
phi := phi + dphi;
|
||||
end loop;
|
||||
return res;
|
||||
|
||||
end Window_Hamming;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
function Window_VonHann (x : real_array_t) return real_array_t is
|
||||
variable res : real_array_t(x'range);
|
||||
variable phi : real := 0.0;
|
||||
variable dphi : real := 2.0*pi/real(x'length-1);
|
||||
begin
|
||||
for i in x'range loop
|
||||
res(i) := 0.5 * x(i) * (1.0 - (cos(phi)));
|
||||
phi := phi + dphi;
|
||||
end loop;
|
||||
return res;
|
||||
|
||||
end Window_VonHann;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
function Window_Blackman (x : real_array_t) return real_array_t is
|
||||
variable res : real_array_t(0 to x'length-1);
|
||||
variable phi : real := 0.0;
|
||||
variable dphi : real := 2.0*pi/real(x'length-1);
|
||||
begin
|
||||
for i in x'range loop
|
||||
res(i) := x(i) * (0.42 - 0.5*cos(phi) + 0.08*cos(2.0*phi));
|
||||
phi := phi + dphi;
|
||||
end loop;
|
||||
return res;
|
||||
|
||||
end Window_Blackman;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
function Sinc (x : real) return real is
|
||||
variable res : real := 1.0;
|
||||
begin
|
||||
if x /= 0.0 then
|
||||
res := sin(x)/x;
|
||||
end if;
|
||||
|
||||
return res;
|
||||
|
||||
end Sinc;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
function FilterScale (x : real_array_t; scale : real) return real_array_t is
|
||||
variable res : real_array_t(x'range);
|
||||
begin
|
||||
for i in x'range loop
|
||||
res(i) := scale * x(i);
|
||||
end loop;
|
||||
|
||||
return res;
|
||||
|
||||
end FilterScale;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
function FilterEnergy (x : real_array_t) return real is
|
||||
variable res : real := 0.0;
|
||||
begin
|
||||
for i in x'range loop
|
||||
res := res + x(i)*x(i);
|
||||
end loop;
|
||||
|
||||
return res;
|
||||
|
||||
end FilterEnergy;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
function FilterMean (x : real_array_t) return real is
|
||||
variable res : real := 0.0;
|
||||
begin
|
||||
for i in x'range loop
|
||||
res := res + x(i);
|
||||
end loop;
|
||||
|
||||
return res/real(x'length);
|
||||
|
||||
end FilterMean;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
function NextPowerOfTwo(x : real) return natural is
|
||||
begin
|
||||
return integer(ceil(log2(x)));
|
||||
|
||||
end NextPowerOfTwo;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
end; -- package filter_pkg;
|
||||
@@ -0,0 +1,352 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 12:16:14 10/02/05
|
||||
-- Design Name:
|
||||
-- Module Name: fir_parallel - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Device:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.MATH_REAL.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
use work.fixed_pkg.all;
|
||||
use work.fir_stage_pkg.all;
|
||||
use work.fir_iterative_pkg.all;
|
||||
|
||||
---- Uncomment the following library declaration if instantiating
|
||||
---- any Xilinx primitives in this code.
|
||||
--library UNISIM;
|
||||
--use UNISIM.VComponents.all;
|
||||
entity fir_iterative is
|
||||
Generic
|
||||
(
|
||||
ntaps : integer := 33;
|
||||
nbits_in : integer := 12;
|
||||
nbits_in_frac : integer := 11;
|
||||
nbits_stages : integer := 13;
|
||||
nbits_stages_frac : integer := 11;
|
||||
nbits_out : integer := 12;
|
||||
nbits_out_frac : integer := 11;
|
||||
fir_mode : fir_iterative_mode_t := normal;
|
||||
rounding : boolean := true;
|
||||
saturating : boolean := true
|
||||
);
|
||||
Port
|
||||
(
|
||||
srst : in std_logic;
|
||||
clk : in std_logic;
|
||||
h_din : in sfixed;
|
||||
h_addr_out : out unsigned(taps_nbits(ntaps, fir_mode)-1 downto 0);
|
||||
ready : out std_logic;
|
||||
x_valid : in std_logic;
|
||||
x_din : in sfixed;
|
||||
y_dout_valid : out std_logic;
|
||||
y_dout : out sfixed
|
||||
);
|
||||
end fir_iterative;
|
||||
|
||||
architecture Behavioral of fir_iterative is
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Component Declaration for FIR stage
|
||||
COMPONENT fir_stage
|
||||
GENERIC
|
||||
(
|
||||
nbits_in : integer;
|
||||
nbits_in_frac : integer;
|
||||
nbits_out : integer;
|
||||
nbits_out_frac : integer;
|
||||
has_in_reg : boolean;
|
||||
has_pipe_reg : boolean;
|
||||
fir_mode : fir_stage_mode_t;
|
||||
rounding : boolean;
|
||||
saturating : boolean
|
||||
);
|
||||
PORT
|
||||
(
|
||||
srst : in std_logic;
|
||||
clk : in std_logic;
|
||||
in_valid : in std_logic;
|
||||
x_in : in sfixed;
|
||||
y_in : in sfixed;
|
||||
h_in : in sfixed;
|
||||
out_valid : out std_logic;
|
||||
x_out : out sfixed;
|
||||
y_out : out sfixed;
|
||||
y_out_clr : in std_logic
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
constant fir_stage_mode : fir_stage_mode_t := transposed;
|
||||
constant ntaps_is_even : boolean := (ntaps mod 2) = 0;
|
||||
constant h_addr_bits : integer := taps_nbits(ntaps, fir_mode);
|
||||
|
||||
subtype in_t is sfixed(sproto(nbits_in, nbits_in_frac)'high downto sproto(nbits_in, nbits_in_frac)'low);
|
||||
subtype stage_t is sfixed(sproto(nbits_stages, nbits_stages_frac)'high downto sproto(nbits_stages, nbits_stages_frac)'low);
|
||||
|
||||
type state_t is (init, idle, start, proc, p1, p2, output);
|
||||
signal s, sn : state_t;
|
||||
signal x_stage, xo, y_stage : stage_t;
|
||||
signal stage_en, cnt_en, new_round : std_logic;
|
||||
|
||||
subtype tap_cnt_t is natural range 0 to ntaps-1;
|
||||
signal htap_cnt : tap_cnt_t;
|
||||
signal xtap_cnt_w : tap_cnt_t;
|
||||
signal xtap_cnt_r : tap_cnt_t;
|
||||
signal stage_valid, clr_xmem, valid, fir_stage_clr, fir_stage_en, cnt_reset : std_logic;
|
||||
subtype tap_range_t is natural range 0 to ntaps_addr(ntaps, fir_mode)-1;
|
||||
signal h_addr : tap_range_t;
|
||||
signal xmem_din, xmem_dout : in_t;
|
||||
signal xmem_we, y_valid : std_logic;
|
||||
|
||||
type xmem_t is array (0 to ntaps-1) of in_t;
|
||||
signal xmem : xmem_t;
|
||||
signal y_out_reg : stage_t;
|
||||
signal y_reg_valid : std_logic;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
h_addr_out <= to_unsigned(h_addr, h_addr_bits);
|
||||
x_stage <= resize(xmem_dout, x_stage, false, false);
|
||||
|
||||
----------------------------------------
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
y_reg_valid <= '0';
|
||||
if srst = '1' then
|
||||
y_out_reg <= to_sfixed(0, sproto(nbits_out, nbits_out_frac));
|
||||
elsif y_valid = '1' then
|
||||
y_out_reg <= y_stage;
|
||||
y_reg_valid <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
y_dout_valid <= '0';
|
||||
if srst = '1' then
|
||||
y_dout <= to_sfixed(0, sproto(nbits_out, nbits_out_frac));
|
||||
elsif y_reg_valid = '1' then
|
||||
y_dout <= resize(y_out_reg, sproto(nbits_out, nbits_out_frac), rounding, saturating);
|
||||
y_dout_valid <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
----------------------------------------
|
||||
proc_xmem_rw: process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if xmem_we = '1' then
|
||||
xmem(xtap_cnt_w) <= xmem_din;
|
||||
end if;
|
||||
xmem_dout <= xmem(xtap_cnt_r);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
----------------------------------------
|
||||
proc_xmem_dinmux: process(new_round, clr_xmem, x_din, xmem_dout)
|
||||
begin
|
||||
xmem_din <= to_sfixed(0, xmem_din);
|
||||
if new_round = '1' and clr_xmem = '0' then
|
||||
xmem_din <= sfixed(x_din);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
----------------------------------------
|
||||
proc_xmem_pointer: process(clk, new_round ,clr_xmem)
|
||||
begin
|
||||
xmem_we <= clr_xmem or new_round;
|
||||
if rising_edge(clk) then
|
||||
if srst = '1' then
|
||||
xtap_cnt_w <= tap_cnt_t'high;
|
||||
elsif xmem_we = '1' then
|
||||
if xtap_cnt_w /= tap_cnt_t'low then
|
||||
xtap_cnt_w <= xtap_cnt_w - 1;
|
||||
else
|
||||
xtap_cnt_w <= tap_cnt_t'high;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
----------------------------------------
|
||||
proc_h_addr: process(htap_cnt)
|
||||
begin
|
||||
if fir_mode = symmetric then
|
||||
if ntaps_is_even then
|
||||
if htap_cnt > ntaps/2-1 then
|
||||
h_addr <= ntaps - htap_cnt - 1;
|
||||
else
|
||||
h_addr <= htap_cnt;
|
||||
end if;
|
||||
else
|
||||
if htap_cnt > (ntaps-1)/2 then
|
||||
h_addr <= ntaps - htap_cnt - 1;
|
||||
else
|
||||
h_addr <= htap_cnt;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
h_addr <= htap_cnt;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
----------------------------------------
|
||||
proc_tap_counter: process(cnt_reset, clk, htap_cnt, xtap_cnt_r, xtap_cnt_w, cnt_en)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if cnt_reset = '1' then
|
||||
htap_cnt <= tap_cnt_t'low;
|
||||
xtap_cnt_r <= xtap_cnt_w;
|
||||
elsif cnt_en = '1' then
|
||||
if htap_cnt /= tap_cnt_t'high then
|
||||
htap_cnt <= htap_cnt + 1;
|
||||
else
|
||||
htap_cnt <= tap_cnt_t'low;
|
||||
end if;
|
||||
if xtap_cnt_r /= tap_cnt_t'high then
|
||||
xtap_cnt_r <= xtap_cnt_r + 1;
|
||||
else
|
||||
xtap_cnt_r <= tap_cnt_t'low;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
----------------------------------------
|
||||
proc_valid_out: process(srst, clk, valid, new_round)
|
||||
variable val_pipe : unsigned(4 downto 0);
|
||||
variable ctrl_pipe : unsigned(2 downto 0);
|
||||
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if srst = '1' then
|
||||
ctrl_pipe := (others => '0');
|
||||
fir_stage_en <= '0';
|
||||
fir_stage_clr <= '0';
|
||||
else
|
||||
ctrl_pipe := ctrl_pipe(ctrl_pipe'left-1 downto ctrl_pipe'right) & new_round;
|
||||
fir_stage_en <= stage_en;
|
||||
fir_stage_clr <= ctrl_pipe(2);
|
||||
end if;
|
||||
end if;
|
||||
cnt_reset <= new_round;
|
||||
end process;
|
||||
|
||||
----------------------------------------
|
||||
proc_fsm: process(s, x_valid, htap_cnt, xtap_cnt_w)
|
||||
begin
|
||||
clr_xmem <= '0';
|
||||
new_round <= '0';
|
||||
cnt_en <= '0';
|
||||
ready <= '0';
|
||||
valid <= '0';
|
||||
sn <= s;
|
||||
stage_en <= '0';
|
||||
y_valid <= '0';
|
||||
|
||||
case s is
|
||||
when init =>
|
||||
clr_xmem <= '1';
|
||||
if xtap_cnt_w = tap_cnt_t'low then
|
||||
sn <= idle;
|
||||
end if;
|
||||
|
||||
when idle =>
|
||||
ready <= '1';
|
||||
if x_valid = '1' then
|
||||
sn <= start;
|
||||
end if;
|
||||
|
||||
when start =>
|
||||
new_round <= '1';
|
||||
sn <= proc;
|
||||
|
||||
when proc =>
|
||||
stage_en <= '1';
|
||||
cnt_en <= '1';
|
||||
if htap_cnt = tap_cnt_t'high then
|
||||
sn <= p1;
|
||||
end if;
|
||||
|
||||
when p1 =>
|
||||
sn <= p2;
|
||||
|
||||
when p2 =>
|
||||
sn <= output;
|
||||
ready <= '1';
|
||||
|
||||
when output =>
|
||||
sn <= idle;
|
||||
y_valid <= '1';
|
||||
ready <= '1';
|
||||
if x_valid = '1' then
|
||||
sn <= start;
|
||||
end if;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
proc_fsm_next: process(srst, clk, sn)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if srst = '1' then
|
||||
s <= init;
|
||||
else
|
||||
s <= sn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
----------------------------------------
|
||||
inst_fir_stage: fir_stage
|
||||
GENERIC MAP
|
||||
(
|
||||
nbits_in => nbits_stages,
|
||||
nbits_in_frac => nbits_stages_frac,
|
||||
nbits_out => nbits_stages,
|
||||
nbits_out_frac => nbits_stages_frac,
|
||||
has_in_reg => true,
|
||||
has_pipe_reg => true,
|
||||
fir_mode => fir_stage_mode,
|
||||
rounding => false,
|
||||
saturating => false
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
srst => srst,
|
||||
clk => clk,
|
||||
in_valid => fir_stage_en,
|
||||
x_in => x_stage,
|
||||
y_in => y_stage,
|
||||
h_in => h_din,
|
||||
out_valid => stage_valid,
|
||||
x_out => xo,
|
||||
y_out_clr => fir_stage_clr,
|
||||
y_out => y_stage
|
||||
);
|
||||
|
||||
----------------------------------------
|
||||
-- Finished instantiation
|
||||
----------------------------------------
|
||||
|
||||
end Behavioral;
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.MATH_REAL.ALL;
|
||||
use ieee.numeric_std.all;
|
||||
use work.fixed_pkg.all;
|
||||
use work.filter_pkg.all;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
package fir_iterative_pkg is
|
||||
|
||||
type fir_iterative_mode_t is (normal, symmetric);
|
||||
|
||||
function taps_nbits(ntaps : integer; mode : fir_iterative_mode_t) return integer;
|
||||
function ntaps_addr(ntaps : integer; mode : fir_iterative_mode_t) return integer;
|
||||
|
||||
end; -- package fir_iterative_pkg;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
package body fir_iterative_pkg is
|
||||
|
||||
function taps_nbits(ntaps : integer; mode : fir_iterative_mode_t) return integer is
|
||||
variable res : integer;
|
||||
begin
|
||||
res := NextPowerOfTwo(real(ntaps_addr(ntaps, mode)));
|
||||
return res;
|
||||
end taps_nbits;
|
||||
|
||||
function ntaps_addr(ntaps : integer; mode : fir_iterative_mode_t) return integer is
|
||||
constant ntaps_is_even : boolean := (ntaps mod 2) = 0;
|
||||
variable res : integer := ntaps;
|
||||
begin
|
||||
if mode = symmetric then
|
||||
if ntaps_is_even then
|
||||
res := ntaps/2;
|
||||
else
|
||||
res := (ntaps-1)/2 + 1;
|
||||
end if;
|
||||
end if;
|
||||
return res;
|
||||
end ntaps_addr;
|
||||
|
||||
end; -- package fir_iterative_pkg;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,208 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 12:16:14 10/02/05
|
||||
-- Design Name:
|
||||
-- Module Name: fir_parallel - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Device:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.MATH_REAL.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
use work.fixed_pkg.all;
|
||||
use work.fir_stage_pkg.all;
|
||||
use work.fir_parallel_pkg.all;
|
||||
|
||||
---- Uncomment the following library declaration if instantiating
|
||||
---- any Xilinx primitives in this code.
|
||||
--library UNISIM;
|
||||
--use UNISIM.VComponents.all;
|
||||
entity fir_parallel is
|
||||
Generic
|
||||
(
|
||||
ntaps : integer := 33;
|
||||
nbits_in : integer := 12;
|
||||
nbits_in_frac : integer := 11;
|
||||
nbits_stages : integer := 13;
|
||||
nbits_stages_frac : integer := 11;
|
||||
nbits_out : integer := 12;
|
||||
nbits_out_frac : integer := 11;
|
||||
has_in_reg : boolean := false;
|
||||
has_pipe_reg : boolean := false;
|
||||
has_out_reg : boolean := false;
|
||||
fir_mode : fir_parallel_mode_t := transposed;
|
||||
rounding : boolean := true;
|
||||
saturating : boolean := true
|
||||
);
|
||||
Port
|
||||
(
|
||||
srst : in std_logic;
|
||||
clk : in std_logic;
|
||||
h_in : in sfixed_array_t;
|
||||
in_valid : in std_logic;
|
||||
d_in : in sfixed;
|
||||
out_valid : out std_logic;
|
||||
d_out : out sfixed
|
||||
);
|
||||
end fir_parallel;
|
||||
|
||||
architecture Behavioral of fir_parallel is
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Component Declaration for FIR stage
|
||||
COMPONENT fir_stage
|
||||
GENERIC
|
||||
(
|
||||
nbits_in : integer;
|
||||
nbits_in_frac : integer;
|
||||
nbits_out : integer;
|
||||
nbits_out_frac : integer;
|
||||
has_in_reg : boolean;
|
||||
has_pipe_reg : boolean;
|
||||
has_out_reg : boolean;
|
||||
fir_mode : fir_stage_mode_t;
|
||||
rounding : boolean;
|
||||
saturating : boolean
|
||||
);
|
||||
PORT
|
||||
(
|
||||
srst : in std_logic;
|
||||
clk : in std_logic;
|
||||
in_valid : in std_logic;
|
||||
x_in : in sfixed;
|
||||
y_in : in sfixed;
|
||||
h_in : in sfixed;
|
||||
out_valid : out std_logic;
|
||||
x_out : out sfixed;
|
||||
y_out : out sfixed
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
type coeff_array_t is array (natural range <>) of sfixed(SFix_high(nbits_stages, nbits_stages_frac) downto SFix_low(nbits_stages, nbits_stages_frac));
|
||||
type stages_array_t is array (natural range <>) of sfixed(SFix_high(nbits_stages, nbits_stages_frac) downto SFix_low(nbits_stages, nbits_stages_frac));
|
||||
|
||||
constant zero_in : sfixed := to_sfixed(0, nbits_in, nbits_in_frac);
|
||||
constant fir_stage_mode : fir_stage_mode_t := transposed;
|
||||
|
||||
SIGNAL x_out : sfixed(SFix_high(nbits_out, nbits_out_frac) downto SFix_low(nbits_out, nbits_out_frac));
|
||||
|
||||
SIGNAL x : stages_array_t(0 to ntaps-2);
|
||||
SIGNAL y : stages_array_t(0 to ntaps-2);
|
||||
SIGNAL h : coeff_array_t(0 to ntaps-1);
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
-- Assign coefficients
|
||||
assign_coeffs:
|
||||
for i in 0 to ntaps-1 generate
|
||||
h(i) <= to_sfixed(h_in, i);
|
||||
end generate;
|
||||
|
||||
----------------------------------------
|
||||
-- Instantiate the FIR stages
|
||||
----------------------------------------
|
||||
uut_first_stage: fir_stage
|
||||
GENERIC MAP
|
||||
(
|
||||
nbits_in => nbits_in,
|
||||
nbits_in_frac => nbits_in_frac,
|
||||
nbits_out => nbits_stages,
|
||||
nbits_out_frac => nbits_stages_frac,
|
||||
has_in_reg => has_in_reg,
|
||||
has_pipe_reg => has_pipe_reg,
|
||||
has_out_reg => has_out_reg,
|
||||
fir_mode => fir_stage_mode,
|
||||
rounding => false,
|
||||
saturating => false
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
srst => srst,
|
||||
clk => clk,
|
||||
in_valid => in_valid,
|
||||
x_in => d_in,
|
||||
y_in => zero_in,
|
||||
h_in => h(ntaps-1),
|
||||
out_valid => out_valid,
|
||||
x_out => x(0),
|
||||
y_out => y(0)
|
||||
);
|
||||
|
||||
----------------------------------------
|
||||
gen_stages:
|
||||
for i in 1 to ntaps-2 generate
|
||||
uut_stages: fir_stage
|
||||
GENERIC MAP
|
||||
(
|
||||
nbits_in => nbits_stages,
|
||||
nbits_in_frac => nbits_stages_frac,
|
||||
nbits_out => nbits_stages,
|
||||
nbits_out_frac => nbits_stages_frac,
|
||||
has_in_reg => has_in_reg,
|
||||
has_pipe_reg => has_pipe_reg,
|
||||
has_out_reg => has_out_reg,
|
||||
fir_mode => fir_stage_mode,
|
||||
rounding => false,
|
||||
saturating => false
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
srst => srst,
|
||||
clk => clk,
|
||||
in_valid => in_valid,
|
||||
x_in => x(i-1),
|
||||
y_in => y(i-1),
|
||||
h_in => h(ntaps-i-1),
|
||||
out_valid => open,
|
||||
x_out => x(i),
|
||||
y_out => y(i)
|
||||
);
|
||||
end generate;
|
||||
|
||||
----------------------------------------
|
||||
uut_last_stage: fir_stage
|
||||
GENERIC MAP
|
||||
(
|
||||
nbits_in => nbits_stages,
|
||||
nbits_in_frac => nbits_stages_frac,
|
||||
nbits_out => nbits_out,
|
||||
nbits_out_frac => nbits_out_frac,
|
||||
has_in_reg => has_in_reg,
|
||||
has_pipe_reg => has_pipe_reg,
|
||||
has_out_reg => has_out_reg,
|
||||
fir_mode => fir_stage_mode,
|
||||
rounding => rounding,
|
||||
saturating => saturating
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
srst => srst,
|
||||
clk => clk,
|
||||
in_valid => in_valid,
|
||||
x_in => x(ntaps-2),
|
||||
y_in => y(ntaps-2),
|
||||
h_in => h(0),
|
||||
out_valid => open,
|
||||
x_out => x_out,
|
||||
y_out => d_out
|
||||
);
|
||||
|
||||
----------------------------------------
|
||||
-- Finished instantiation
|
||||
----------------------------------------
|
||||
|
||||
end Behavioral;
|
||||
@@ -0,0 +1,76 @@
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use ieee.numeric_std.all;
|
||||
use work.fixed_pkg.all;
|
||||
use work.filter_pkg.all;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
package fir_parallel_pkg is
|
||||
|
||||
type ufixed_array_t is array (natural range <>, integer range <>) of STD_LOGIC;
|
||||
type sfixed_array_t is array (natural range <>, integer range <>) of STD_LOGIC;
|
||||
|
||||
type fir_parallel_mode_t is (transposed, transposed_sym, systolic, systolic_sym);
|
||||
|
||||
function to_sfixed_array(x : real_array_t; proto : sfixed) return sfixed_array_t;
|
||||
function to_sfixed_array(x : real_array_t; nbits, nbits_int : integer) return sfixed_array_t;
|
||||
|
||||
-- Slicing functions for unconstrained array types
|
||||
function to_ufixed(src : ufixed_array_t; index : integer) return ufixed;
|
||||
function to_sfixed(src : sfixed_array_t; index : integer) return sfixed;
|
||||
|
||||
end; -- package fir_parallel_pkg;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
package body fir_parallel_pkg is
|
||||
|
||||
function to_sfixed_array(x : real_array_t; proto : sfixed) return sfixed_array_t is
|
||||
variable res : sfixed_array_t(0 to x'length-1, proto'range);
|
||||
variable tt : sfixed(proto'range);
|
||||
begin
|
||||
for i in x'range loop
|
||||
tt := to_sfixed(x(i), proto);
|
||||
for j in proto'range loop
|
||||
res(i,j) := tt(j);
|
||||
end loop;
|
||||
end loop;
|
||||
return res;
|
||||
end to_sfixed_array;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
function to_sfixed_array(x : real_array_t; nbits, nbits_int : integer) return sfixed_array_t is
|
||||
variable p : sfixed(SFix_high(nbits, nbits_int) downto SFix_low(nbits, nbits_int));
|
||||
begin
|
||||
return to_sfixed_array(x, p);
|
||||
end to_sfixed_array;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- ufixed <= ufixed_array(i)
|
||||
function to_ufixed(src : ufixed_array_t; index : integer) return ufixed is
|
||||
variable dst : ufixed(src'range(2));
|
||||
begin
|
||||
for j in src'range(2) loop
|
||||
dst(j) := src(index, j);
|
||||
end loop;
|
||||
|
||||
return dst;
|
||||
|
||||
end to_ufixed;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- sfixed <= sfixed_array(i)
|
||||
function to_sfixed(src : sfixed_array_t; index : integer) return sfixed is
|
||||
variable dst : sfixed(src'range(2));
|
||||
begin
|
||||
for j in src'range(2) loop
|
||||
dst(j) := src(index, j);
|
||||
end loop;
|
||||
|
||||
return dst;
|
||||
|
||||
end to_sfixed;
|
||||
|
||||
end; -- package fir_parallel_pkg;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,150 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 12:16:14 10/02/05
|
||||
-- Design Name:
|
||||
-- Module Name: fir_stage - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Device:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.MATH_REAL.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
use work.fixed_pkg.all;
|
||||
use work.fir_stage_pkg.all;
|
||||
|
||||
---- Uncomment the following library declaration if instantiating
|
||||
---- any Xilinx primitives in this code.
|
||||
--library UNISIM;
|
||||
--use UNISIM.VComponents.all;
|
||||
entity fir_stage is
|
||||
Generic
|
||||
(
|
||||
nbits_in : integer := 12;
|
||||
nbits_in_frac : integer := 12;
|
||||
nbits_out : integer := 12;
|
||||
nbits_out_frac : integer := 12;
|
||||
has_in_reg : boolean := false;
|
||||
has_pipe_reg : boolean := false;
|
||||
has_out_reg : boolean := false;
|
||||
fir_mode : fir_stage_mode_t := transposed;
|
||||
rounding : boolean := true;
|
||||
saturating : boolean := true
|
||||
);
|
||||
Port
|
||||
(
|
||||
srst : in std_logic;
|
||||
clk : in std_logic;
|
||||
in_valid : in std_logic;
|
||||
x_in : in sfixed;
|
||||
y_in : in sfixed;
|
||||
h_in : in sfixed;
|
||||
out_valid : out std_logic;
|
||||
x_out : out sfixed;
|
||||
y_out : out sfixed;
|
||||
y_out_clr : in std_logic
|
||||
);
|
||||
end fir_stage;
|
||||
|
||||
architecture Behavioral of fir_stage is
|
||||
|
||||
signal xin : sfixed(sproto(nbits_in, nbits_in_frac)'high downto sproto(nbits_in, nbits_in_frac)'low);
|
||||
signal yin : sfixed(sproto(nbits_in, nbits_in_frac)'high downto sproto(nbits_in, nbits_in_frac)'low);
|
||||
signal hin : sfixed(sproto(nbits_in, nbits_in_frac)'high downto sproto(nbits_in, nbits_in_frac)'low);
|
||||
signal prod : sfixed(sproto(nbits_out, nbits_out_frac)'high downto sproto(nbits_out, nbits_out_frac)'low);
|
||||
signal valid, p_valid : std_logic;
|
||||
------------------------------------------------------------
|
||||
begin
|
||||
|
||||
|
||||
------------------------------------------------------------
|
||||
proc_in_reg_y: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if srst = '1' or y_out_clr = '1' then
|
||||
yin <= to_sfixed(0, yin);
|
||||
else
|
||||
yin <= resize(y_in, yin);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------
|
||||
proc_in_reg_hx: process(srst, clk, in_valid, x_in, h_in)
|
||||
variable p : sfixed(sproto(nbits_out, nbits_out_frac)'high downto sproto(nbits_out, nbits_out_frac)'low);
|
||||
begin
|
||||
if has_in_reg = true then
|
||||
if rising_edge(clk) then
|
||||
if srst = '1' then
|
||||
xin <= to_sfixed(0, xin);
|
||||
hin <= to_sfixed(0, hin);
|
||||
valid <= '0';
|
||||
else
|
||||
valid <= in_valid;
|
||||
if in_valid = '1' then
|
||||
xin <= resize(x_in, xin);
|
||||
hin <= resize(h_in, hin);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
xin <= resize(x_in, xin);
|
||||
hin <= resize(h_in, hin);
|
||||
valid <= in_valid;
|
||||
end if;
|
||||
x_out <= resize(x_in, p);
|
||||
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------
|
||||
proc_pipe_reg: process(srst, clk, valid, xin, hin)
|
||||
variable p : sfixed(sproto(nbits_out, nbits_out_frac)'high downto sproto(nbits_out, nbits_out_frac)'low);
|
||||
begin
|
||||
p := resize(xin * hin, p);
|
||||
if has_pipe_reg = true then
|
||||
if rising_edge(clk) then
|
||||
if srst = '1' then
|
||||
prod <= to_sfixed(0, prod);
|
||||
p_valid <= '0';
|
||||
else
|
||||
prod <= p;
|
||||
p_valid <= valid;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
prod <= p;
|
||||
p_valid <= valid;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------
|
||||
proc_out_reg: process(srst, clk, p_valid, prod, yin)
|
||||
variable yout : sfixed(sproto(nbits_out, nbits_out_frac)'high downto sproto(nbits_out, nbits_out_frac)'low);
|
||||
begin
|
||||
yout := resize(yin + prod, yout, rounding, saturating);
|
||||
-- if rising_edge(clk) then
|
||||
-- if srst = '1' or y_out_clr = '1' then
|
||||
-- y_out <= to_sfixed(0, yout);
|
||||
-- out_valid <= '0';
|
||||
-- else
|
||||
-- y_out <= yout;
|
||||
-- out_valid <= p_valid;
|
||||
-- end if;
|
||||
-- end if;
|
||||
out_valid <= p_valid;
|
||||
y_out <= yout;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------
|
||||
end Behavioral;
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use ieee.numeric_std.all;
|
||||
use work.fixed_pkg.all;
|
||||
|
||||
package fir_stage_pkg is
|
||||
|
||||
type fir_stage_mode_t is (transposed, systolic);
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Constructor helpers
|
||||
-- Use: variable v8u6 : ufixed_t(ufixed(8,6)'range);
|
||||
function uproto (nbits : integer; nbits_frac : integer) return ufixed;
|
||||
|
||||
-- Use: variable v8s6 : sfixed_t(sfixed(8,6)'range);
|
||||
function sproto (nbits : integer; nbits_frac : integer) return sfixed;
|
||||
|
||||
end; -- package fir_stage_pkg;
|
||||
|
||||
package body fir_stage_pkg is
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Constuctor helpers
|
||||
function uproto (nbits : integer; nbits_frac : integer) return ufixed is
|
||||
constant result : ufixed (nbits-nbits_frac-1 downto -nbits_frac) := (others => '0');
|
||||
begin
|
||||
return result(nbits-nbits_frac-1 downto -nbits_frac);
|
||||
end uproto;
|
||||
|
||||
-------------------------------------------------------------
|
||||
function sproto (nbits : integer; nbits_frac : integer) return sfixed is
|
||||
constant result : sfixed (nbits-nbits_frac downto -nbits_frac+1) := (others => '0');
|
||||
begin
|
||||
return result(nbits-nbits_frac downto -nbits_frac+1);
|
||||
end sproto;
|
||||
|
||||
end; -- package fir_stage_pkg;
|
||||
@@ -0,0 +1,231 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 17:16:42 13.05.2007
|
||||
-- Design Name: tb_fir_stage
|
||||
-- Module Name: tb_fir_stage.vhd
|
||||
-- Project Name: fir_stage
|
||||
-- Target Device:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.MATH_REAL.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
use std.textio.all; -- Imports the standard textio package.
|
||||
|
||||
library work;
|
||||
use work.fixed_pkg.all;
|
||||
use work.filter_pkg.all;
|
||||
use work.fir_stage_pkg.all;
|
||||
use work.fir_iterative_pkg.all;
|
||||
|
||||
use work.PCK_FIO.all;
|
||||
|
||||
ENTITY tb_fir_iterative IS
|
||||
Generic (
|
||||
ntaps : integer := 11;
|
||||
nbits_in : integer := 15;
|
||||
nbits_in_frac : integer := 15;
|
||||
nbits_stages : integer := 15;
|
||||
nbits_stages_frac : integer := 15;
|
||||
nbits_out : integer := 15;
|
||||
nbits_out_frac : integer := 15;
|
||||
fir_mode : fir_iterative_mode_t := symmetric;
|
||||
rounding : boolean := true;
|
||||
saturating : boolean := true
|
||||
);
|
||||
END tb_fir_iterative;
|
||||
|
||||
ARCHITECTURE behavior OF tb_fir_iterative IS
|
||||
|
||||
-- Component Declaration for the Unit Under Test (UUT)
|
||||
COMPONENT fir_iterative
|
||||
GENERIC
|
||||
(
|
||||
ntaps : integer;
|
||||
nbits_in : integer;
|
||||
nbits_in_frac : integer;
|
||||
nbits_stages : integer;
|
||||
nbits_stages_frac : integer;
|
||||
nbits_out : integer;
|
||||
nbits_out_frac : integer;
|
||||
fir_mode : fir_iterative_mode_t;
|
||||
rounding : boolean;
|
||||
saturating : boolean
|
||||
);
|
||||
PORT
|
||||
(
|
||||
srst : in std_logic;
|
||||
clk : in std_logic;
|
||||
h_din : in sfixed;
|
||||
h_addr_out : out unsigned(taps_nbits(ntaps, fir_mode)-1 downto 0);
|
||||
ready : out std_logic;
|
||||
x_valid : in std_logic;
|
||||
x_din : in sfixed;
|
||||
y_dout_valid : out std_logic;
|
||||
y_dout : out sfixed
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
--Constants
|
||||
constant nsamples : integer := 32;
|
||||
|
||||
constant PERIOD : time := 10 ns;
|
||||
constant zero_in : sfixed := to_sfixed(0, nbits_in, nbits_in_frac);
|
||||
|
||||
--Inputs
|
||||
SIGNAL clk : std_logic := '0';
|
||||
SIGNAL srst : std_logic := '1';
|
||||
SIGNAL x_valid : std_logic := '0';
|
||||
SIGNAL h_din : sfixed(sproto(nbits_stages, nbits_stages_frac)'high downto sproto(nbits_stages, nbits_stages_frac)'low);
|
||||
SIGNAL x_din : sfixed(sproto(nbits_in, nbits_in_frac)'high downto sproto(nbits_in, nbits_in_frac)'low);
|
||||
|
||||
--Outputs
|
||||
SIGNAL y_dout : sfixed(sproto(nbits_out, nbits_out_frac)'high downto sproto(nbits_out, nbits_out_frac)'low);
|
||||
SIGNAL y_valid : std_logic;
|
||||
SIGNAL ready : std_logic;
|
||||
|
||||
SIGNAL fileout_enable : std_logic := '1';
|
||||
|
||||
-- Test coefficients
|
||||
-- SIGNAL coeffs : real_array_t(0 to ntaps_addr(ntaps, fir_mode)-1) := FilterCoef_Delta(ntaps, 10, 0.999)(0 to ntaps_addr(ntaps, fir_mode)-1);
|
||||
SIGNAL coeffs : real_array_t(0 to ntaps_addr(ntaps, fir_mode)-1) := FilterCoef_Bandpass(ntaps, 0.25, 0.125, 1.0)(0 to ntaps_addr(ntaps, fir_mode)-1);
|
||||
-- SIGNAL coeffs : real_array_t(0 to ntaps-1) := FilterTestCoef(ntaps);
|
||||
signal x_input : real_array_t(0 to nsamples-1) :=
|
||||
(
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.9999,
|
||||
-0.0000,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
|
||||
);
|
||||
type ymem_t is array (0 to nsamples-1) of sfixed(sproto(nbits_out, nbits_out_frac)'high downto sproto(nbits_out, nbits_out_frac)'low);
|
||||
signal ymem : ymem_t;
|
||||
|
||||
signal y_cnt : integer ;
|
||||
SIGNAL xi, yo : real := 0.0;
|
||||
SIGNAL h_addr : unsigned(taps_nbits(ntaps, fir_mode)-1 downto 0);
|
||||
|
||||
-- file I/O
|
||||
subtype sample_t is integer range -32768 to 32767;
|
||||
type file_t is file of sample_t;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
|
||||
xi <= to_real(x_din);
|
||||
yo <= to_real(y_dout);
|
||||
|
||||
----------------------------------------
|
||||
-- Instantiate the Unit Under Test (UUT)
|
||||
----------------------------------------
|
||||
uut_fir_iterative: fir_iterative
|
||||
GENERIC MAP
|
||||
(
|
||||
ntaps => ntaps,
|
||||
nbits_in => nbits_in,
|
||||
nbits_in_frac => nbits_in_frac,
|
||||
nbits_out => nbits_out,
|
||||
nbits_out_frac => nbits_out_frac,
|
||||
nbits_stages => nbits_stages,
|
||||
nbits_stages_frac => nbits_stages_frac,
|
||||
fir_mode => fir_mode,
|
||||
rounding => rounding,
|
||||
saturating => saturating
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
srst => srst,
|
||||
clk => clk,
|
||||
h_din => h_din,
|
||||
h_addr_out => h_addr,
|
||||
ready => ready,
|
||||
x_valid => x_valid,
|
||||
x_din => x_din,
|
||||
y_dout_valid => y_valid,
|
||||
y_dout => y_dout
|
||||
);
|
||||
|
||||
----------------------------------------
|
||||
-- Finished instantiation
|
||||
----------------------------------------
|
||||
tb_clk : PROCESS
|
||||
BEGIN
|
||||
clk <= not clk;
|
||||
wait for PERIOD/2;
|
||||
END PROCESS;
|
||||
|
||||
tb : PROCESS
|
||||
BEGIN
|
||||
|
||||
-- Wait 100 ns for global reset to finish
|
||||
wait for 4*PERIOD;
|
||||
srst <= '0';
|
||||
------------------------------------------
|
||||
wait for 2*PERIOD;
|
||||
|
||||
for i in 0 to nsamples-1 loop
|
||||
if i = nsamples/2 then
|
||||
wait for 43*PERIOD;
|
||||
end if;
|
||||
------------------------------------------
|
||||
wait until rising_edge(clk) and ready = '1';
|
||||
x_din <= to_sfixed(x_input(i), x_din);
|
||||
x_valid <= '1';
|
||||
------------------------------------------
|
||||
wait until rising_edge(clk);
|
||||
x_valid <= '0';
|
||||
end loop;
|
||||
|
||||
assert false report "Test finished" severity error;
|
||||
wait;
|
||||
END PROCESS;
|
||||
|
||||
process(srst, clk, y_valid)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
h_din <= to_sfixed(coeffs(to_integer(h_addr)), h_din);
|
||||
if srst = '1' then
|
||||
y_cnt <= 0;
|
||||
|
||||
elsif y_valid = '1' then
|
||||
ymem(y_cnt) <= y_dout;
|
||||
y_cnt <= y_cnt + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
END;
|
||||
@@ -0,0 +1,189 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 17:16:42 13.05.2007
|
||||
-- Design Name: tb_fir_stage
|
||||
-- Module Name: tb_fir_stage.vhd
|
||||
-- Project Name: fir_stage
|
||||
-- Target Device:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.MATH_REAL.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
use std.textio.all; -- Imports the standard textio package.
|
||||
|
||||
library work;
|
||||
use work.fixed_pkg.all;
|
||||
use work.fir_parallel_pkg.all;
|
||||
use work.filter_pkg.all;
|
||||
|
||||
use work.PCK_FIO.all;
|
||||
|
||||
ENTITY tb_fir_parallel IS
|
||||
Generic (
|
||||
ntaps : integer := 33;
|
||||
nbits_in : integer := 15;
|
||||
nbits_in_frac : integer := 15;
|
||||
nbits_stages : integer := 16;
|
||||
nbits_stages_frac : integer := 15;
|
||||
nbits_out : integer := 15;
|
||||
nbits_out_frac : integer := 15;
|
||||
has_in_reg : boolean := false;
|
||||
has_pipe_reg : boolean := true;
|
||||
has_out_reg : boolean := false;
|
||||
fir_mode : fir_parallel_mode_t := transposed;
|
||||
rounding : boolean := true;
|
||||
saturating : boolean := true
|
||||
);
|
||||
END tb_fir_parallel;
|
||||
|
||||
ARCHITECTURE behavior OF tb_fir_parallel IS
|
||||
|
||||
-- Component Declaration for the Unit Under Test (UUT)
|
||||
COMPONENT fir_parallel
|
||||
GENERIC
|
||||
(
|
||||
ntaps : integer;
|
||||
nbits_in : integer;
|
||||
nbits_in_frac : integer;
|
||||
nbits_stages : integer;
|
||||
nbits_stages_frac : integer;
|
||||
nbits_out : integer;
|
||||
nbits_out_frac : integer;
|
||||
has_in_reg : boolean;
|
||||
has_pipe_reg : boolean;
|
||||
has_out_reg : boolean;
|
||||
fir_mode : fir_parallel_mode_t;
|
||||
rounding : boolean;
|
||||
saturating : boolean
|
||||
);
|
||||
PORT
|
||||
(
|
||||
srst : in std_logic;
|
||||
clk : in std_logic;
|
||||
h_in : in sfixed_array_t;
|
||||
in_valid : in std_logic;
|
||||
d_in : in sfixed;
|
||||
out_valid : out std_logic;
|
||||
d_out : out sfixed
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
--Constants
|
||||
constant PERIOD : time := 10 ns;
|
||||
constant zero_in : sfixed := to_sfixed(0, nbits_in, nbits_in_frac);
|
||||
|
||||
--Inputs
|
||||
SIGNAL clk : std_logic := '0';
|
||||
SIGNAL srst : std_logic := '1';
|
||||
SIGNAL in_valid : std_logic := '0';
|
||||
SIGNAL x_in : sfixed(SFix_high(nbits_in, nbits_in_frac) downto SFix_low(nbits_in, nbits_in_frac));
|
||||
|
||||
--Outputs
|
||||
SIGNAL y_out : sfixed(SFix_high(nbits_out, nbits_out_frac) downto SFix_low(nbits_out, nbits_out_frac));
|
||||
SIGNAL out_valid : std_logic := '0';
|
||||
|
||||
SIGNAL fileout_enable : std_logic := '1';
|
||||
|
||||
-- Test coefficients
|
||||
SIGNAL coeff_in : sfixed_array_t(0 to ntaps-1, SFix_high(nbits_stages, nbits_stages_frac) downto SFix_low(nbits_stages, nbits_stages_frac)) := to_sfixed_array(FilterCoef_Lowpass(ntaps, 0.125, 0.125), nbits_stages, nbits_stages_frac);
|
||||
|
||||
SIGNAL xi, yo : real := 0.0;
|
||||
|
||||
-- file I/O
|
||||
subtype sample_t is integer range -32768 to 32767;
|
||||
type file_t is file of sample_t;
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
|
||||
xi <= to_real(x_in);
|
||||
yo <= to_real(y_out);
|
||||
|
||||
----------------------------------------
|
||||
-- Instantiate the Unit Under Test (UUT)
|
||||
----------------------------------------
|
||||
uut_fir_parallel: fir_parallel
|
||||
GENERIC MAP
|
||||
(
|
||||
ntaps => ntaps,
|
||||
nbits_in => nbits_in,
|
||||
nbits_in_frac => nbits_in_frac,
|
||||
nbits_out => nbits_out,
|
||||
nbits_out_frac => nbits_out_frac,
|
||||
nbits_stages => nbits_stages,
|
||||
nbits_stages_frac => nbits_stages_frac,
|
||||
has_in_reg => has_in_reg,
|
||||
has_pipe_reg => has_pipe_reg,
|
||||
has_out_reg => has_out_reg,
|
||||
fir_mode => fir_mode,
|
||||
rounding => rounding,
|
||||
saturating => saturating
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
srst => srst,
|
||||
clk => clk,
|
||||
h_in => coeff_in,
|
||||
in_valid => in_valid,
|
||||
d_in => x_in,
|
||||
out_valid => out_valid,
|
||||
d_out => y_out
|
||||
);
|
||||
|
||||
----------------------------------------
|
||||
-- Finished instantiation
|
||||
----------------------------------------
|
||||
tb_clk : PROCESS
|
||||
BEGIN
|
||||
clk <= not clk;
|
||||
wait for PERIOD/2;
|
||||
END PROCESS;
|
||||
|
||||
tb : PROCESS
|
||||
file fi : file_t open read_mode is "wav_in.dat";
|
||||
variable si : sample_t;
|
||||
|
||||
BEGIN
|
||||
|
||||
-- Wait 100 ns for global reset to finish
|
||||
wait for 4*PERIOD;
|
||||
srst <= '0';
|
||||
------------------------------------------
|
||||
wait for 2*PERIOD;
|
||||
|
||||
while not endfile(fi) loop
|
||||
read(fi, si);
|
||||
x_in <= to_sfixed(to_signed(si, 16));
|
||||
in_valid <= '1';
|
||||
wait for PERIOD;
|
||||
wait until rising_edge(clk);
|
||||
end loop;
|
||||
------------------------------------------
|
||||
in_valid <= '0';
|
||||
|
||||
wait for 20*PERIOD;
|
||||
|
||||
assert false report "Test finished" severity error;
|
||||
wait;
|
||||
END PROCESS;
|
||||
|
||||
tb_fo : PROCESS(clk, fileout_enable, out_valid)
|
||||
file fo : file_t open write_mode is "wav_out.dat";
|
||||
variable so : sample_t;
|
||||
|
||||
BEGIN
|
||||
if rising_edge(clk) and fileout_enable = '1' and out_valid = '1' then
|
||||
so := to_integer(y_out);
|
||||
write(fo, so);
|
||||
end if;
|
||||
|
||||
END PROCESS;
|
||||
|
||||
END;
|
||||
@@ -0,0 +1,268 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 17:16:42 13.05.2007
|
||||
-- Design Name: tb_fir_stage
|
||||
-- Module Name: tb_fir_stage.vhd
|
||||
-- Project Name: fir_stage
|
||||
-- Target Device:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.MATH_REAL.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
use std.textio.all; -- Imports the standard textio package.
|
||||
|
||||
library work;
|
||||
use work.fixed_pkg.all;
|
||||
use work.fir_stage_pkg.all;
|
||||
use work.filter_pkg.all;
|
||||
|
||||
use work.PCK_FIO.all;
|
||||
|
||||
ENTITY tb_fir_stage IS
|
||||
Generic (
|
||||
ntaps : integer := 33;
|
||||
nbits_in : integer := 24;
|
||||
nbits_in_frac : integer := 23;
|
||||
nbits_stages : integer := 25;
|
||||
nbits_stages_frac : integer := 23;
|
||||
nbits_out : integer := 24;
|
||||
nbits_out_frac : integer := 22;
|
||||
has_in_reg : boolean := true;
|
||||
has_pipe_reg : boolean := true;
|
||||
has_out_reg : boolean := false;
|
||||
fir_mode : fir_stage_mode_t := transposed;
|
||||
rounding : boolean := true;
|
||||
saturating : boolean := true
|
||||
);
|
||||
END tb_fir_stage;
|
||||
|
||||
ARCHITECTURE behavior OF tb_fir_stage IS
|
||||
|
||||
-- Component Declaration for the Unit Under Test (UUT)
|
||||
COMPONENT fir_stage
|
||||
GENERIC
|
||||
(
|
||||
nbits_in : integer;
|
||||
nbits_in_frac : integer;
|
||||
nbits_out : integer;
|
||||
nbits_out_frac : integer;
|
||||
has_in_reg : boolean;
|
||||
has_pipe_reg : boolean;
|
||||
has_out_reg : boolean;
|
||||
fir_mode : fir_stage_mode_t;
|
||||
rounding : boolean;
|
||||
saturating : boolean
|
||||
);
|
||||
PORT
|
||||
(
|
||||
srst : in std_logic;
|
||||
clk : in std_logic;
|
||||
in_valid : in std_logic;
|
||||
x_in : in sfixed;
|
||||
y_in : in sfixed;
|
||||
h_in : in sfixed;
|
||||
out_valid : out std_logic;
|
||||
x_out : out sfixed;
|
||||
y_out : out sfixed
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
type stages_t is array (natural range <>) of sfixed(sproto(nbits_stages, nbits_stages_frac)'high downto sproto(nbits_stages, nbits_stages_frac)'low);
|
||||
|
||||
--Constants
|
||||
constant PERIOD : time := 10 ns;
|
||||
constant zero_in : sfixed := to_sfixed(0, nbits_in, nbits_in_frac);
|
||||
|
||||
--Inputs
|
||||
SIGNAL clk : std_logic := '0';
|
||||
SIGNAL srst : std_logic := '1';
|
||||
SIGNAL in_valid : std_logic := '0';
|
||||
SIGNAL x_in : sfixed(sproto(nbits_in, nbits_in_frac)'high downto sproto(nbits_in, nbits_in_frac)'low);
|
||||
|
||||
--Outputs
|
||||
SIGNAL x_out : sfixed(sproto(nbits_out, nbits_out_frac)'high downto sproto(nbits_out, nbits_out_frac)'low);
|
||||
SIGNAL y_out : sfixed(sproto(nbits_out, nbits_out_frac)'high downto sproto(nbits_out, nbits_out_frac)'low);
|
||||
SIGNAL out_valid : std_logic := '0';
|
||||
|
||||
SIGNAL x : stages_t(0 to ntaps-2);
|
||||
SIGNAL y : stages_t(0 to ntaps-2);
|
||||
|
||||
SIGNAL fileout_enable : std_logic := '1';
|
||||
|
||||
-- Test coefficients
|
||||
function to_sfixed(x_real : real_array_t) return stages_t is
|
||||
variable res : stages_t(x_real'range);
|
||||
begin
|
||||
for i in x_real'range loop
|
||||
res(i) := to_sfixed(x_real(i), res(i), true, true);
|
||||
end loop;
|
||||
|
||||
return res;
|
||||
end to_sfixed;
|
||||
|
||||
constant h : stages_t(0 to ntaps-1) := to_sfixed(FilterCoef_Lowpass(ntaps, 0.25, 1.0));
|
||||
|
||||
SIGNAL xi, yo : real := 0.0;
|
||||
|
||||
BEGIN
|
||||
|
||||
xi <= to_real(x_in);
|
||||
yo <= to_real(y_out);
|
||||
|
||||
----------------------------------------
|
||||
-- Instantiate the Unit Under Test (UUT)
|
||||
----------------------------------------
|
||||
uut_first_stage: fir_stage
|
||||
GENERIC MAP
|
||||
(
|
||||
nbits_in => nbits_in,
|
||||
nbits_in_frac => nbits_in_frac,
|
||||
nbits_out => nbits_stages,
|
||||
nbits_out_frac => nbits_stages_frac,
|
||||
has_in_reg => has_in_reg,
|
||||
has_pipe_reg => has_pipe_reg,
|
||||
has_out_reg => has_out_reg,
|
||||
fir_mode => fir_mode,
|
||||
rounding => false,
|
||||
saturating => false
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
srst => srst,
|
||||
clk => clk,
|
||||
in_valid => in_valid,
|
||||
x_in => x_in,
|
||||
y_in => zero_in,
|
||||
h_in => h(ntaps-1),
|
||||
out_valid => out_valid,
|
||||
x_out => x(0),
|
||||
y_out => y(0)
|
||||
);
|
||||
|
||||
----------------------------------------
|
||||
gen_stages:
|
||||
for i in 1 to ntaps-2 generate
|
||||
uut_stages: fir_stage
|
||||
GENERIC MAP
|
||||
(
|
||||
nbits_in => nbits_stages,
|
||||
nbits_in_frac => nbits_stages_frac,
|
||||
nbits_out => nbits_stages,
|
||||
nbits_out_frac => nbits_stages_frac,
|
||||
has_in_reg => has_in_reg,
|
||||
has_pipe_reg => has_pipe_reg,
|
||||
has_out_reg => has_out_reg,
|
||||
fir_mode => fir_mode,
|
||||
rounding => false,
|
||||
saturating => false
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
srst => srst,
|
||||
clk => clk,
|
||||
in_valid => in_valid,
|
||||
x_in => x(i-1),
|
||||
y_in => y(i-1),
|
||||
h_in => h(ntaps-i-1),
|
||||
out_valid => open,
|
||||
x_out => x(i),
|
||||
y_out => y(i)
|
||||
);
|
||||
end generate;
|
||||
|
||||
----------------------------------------
|
||||
uut_last_stage: fir_stage
|
||||
GENERIC MAP
|
||||
(
|
||||
nbits_in => nbits_stages,
|
||||
nbits_in_frac => nbits_stages_frac,
|
||||
nbits_out => nbits_out,
|
||||
nbits_out_frac => nbits_out_frac,
|
||||
has_in_reg => has_in_reg,
|
||||
has_pipe_reg => has_pipe_reg,
|
||||
has_out_reg => has_out_reg,
|
||||
fir_mode => fir_mode,
|
||||
rounding => rounding,
|
||||
saturating => saturating
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
srst => srst,
|
||||
clk => clk,
|
||||
in_valid => in_valid,
|
||||
x_in => x(ntaps-2),
|
||||
y_in => y(ntaps-2),
|
||||
h_in => h(0),
|
||||
out_valid => open,
|
||||
x_out => x_out,
|
||||
y_out => y_out
|
||||
);
|
||||
|
||||
----------------------------------------
|
||||
-- Finished instantiation
|
||||
----------------------------------------
|
||||
tb_clk : PROCESS
|
||||
BEGIN
|
||||
clk <= not clk;
|
||||
wait for PERIOD/2;
|
||||
END PROCESS;
|
||||
|
||||
tb : PROCESS
|
||||
|
||||
BEGIN
|
||||
|
||||
-- Wait 100 ns for global reset to finish
|
||||
wait for 4*PERIOD;
|
||||
srst <= '0';
|
||||
------------------------------------------
|
||||
wait for 2*PERIOD;
|
||||
|
||||
x_in <= to_sfixed(0.0, x_in);
|
||||
|
||||
wait until rising_edge(clk);
|
||||
in_valid <= '1';
|
||||
|
||||
wait until rising_edge(clk);
|
||||
x_in <= to_sfixed(0.0, x_in);
|
||||
|
||||
wait for 20*PERIOD;
|
||||
wait until rising_edge(clk);
|
||||
x_in <= to_sfixed(0.0, x_in);
|
||||
wait until rising_edge(clk);
|
||||
x_in <= to_sfixed(1.0, x_in);
|
||||
wait until rising_edge(clk);
|
||||
x_in <= to_sfixed(0.0, x_in);
|
||||
wait until rising_edge(clk);
|
||||
x_in <= to_sfixed(0.0, x_in);
|
||||
wait until rising_edge(clk);
|
||||
x_in <= to_sfixed(0.0, x_in);
|
||||
|
||||
wait for 150*PERIOD;
|
||||
|
||||
wait until rising_edge(clk);
|
||||
in_valid <= '0';
|
||||
|
||||
wait for 20*PERIOD;
|
||||
|
||||
assert false report "Test finished" severity error;
|
||||
wait;
|
||||
END PROCESS;
|
||||
|
||||
tb_fo : PROCESS(clk, fileout_enable, out_valid)
|
||||
file RESULT_FIR: text open write_mode is "fir.txt";
|
||||
variable L: line;
|
||||
|
||||
BEGIN
|
||||
if rising_edge(clk) and fileout_enable = '1' and out_valid = '1' then
|
||||
fprint(RESULT_FIR, L,"%s\n", REAL'image(yo));
|
||||
end if;
|
||||
|
||||
END PROCESS;
|
||||
|
||||
END;
|
||||
Reference in New Issue
Block a user