|
发表于 2004-6-21 14:17:17
|
显示全部楼层
谁会?
--testbench:fft_tb.vhd,我的ise前一阵卸载了,所带的Modelsim也卸了,所以没法验证,凑合着看吧。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use std.textio.all;
use ieee.std_logic_textio.all;
use ieee.numeric_std.all;
entity fft_tb is
end;
architecture bench of fft_tb is
component fft
generic(
coeff_width : integer := 16;
data_width : integer := 16;
fft_length : integer := 4);
port (
reset : in std_logic; -- Power on reset (Active Low)
clk : in std_logic; -- Input clock
data_rd : in std_logic; -- New Sample Read (Active High Sampling Clock)
data_in_r : in std_logic_vector(Data_width-1 downto 0); -- Input real data
data_in_i : in std_logic_vector(Data_width-1 downto 0); -- Input imaginary data
address : in std_logic_vector(2 downto 0); -- Address bus for accessing output results array
data_out_r : out std_logic_vector(Data_width-1 downto 0); -- Output real data
data_out_i : out std_logic_vector(Data_width-1 downto 0); -- Output imaginary data
res_valid : out std_logic -- Indicates that results are now valid
);
end component;
component RMS
generic(
data_width : integer := 16);
port (
reset : in std_logic; -- power on reset
clk : in std_logic; -- Input clock
load : in std_logic; -- New Sample Read (Active High Sampling Clock)
input_data_real : in std_logic_vector(data_width-1 downto 0); -- Input Data Real
input_data_imag : in std_logic_vector(data_width-1 downto 0); -- Input Data Imag
rms_result : out std_logic_vector(data_width-1 downto 0) -- RMS result
);
end component;
--------------------------------------------------------------------------------
subtype data_value is std_logic_vector(15 downto 0);
type Cartesian_results_array is array (0 to 7) of data_value;
type FFT_Magnitude_Array is array (0 to 3) of data_value;
signal reset_low, clk, sample_clk : std_logic; -- Testbench signals
signal data_sample_real : std_logic_vector(15 downto 0);
signal data_sample_imag : std_logic_vector(15 downto 0);
signal count1 : integer range 0 to 14;
signal address : std_logic_vector(2 downto 0);
signal fft_data_real_result : std_logic_vector(15 downto 0);
signal fft_data_imag_result : std_logic_vector(15 downto 0);
signal data_out : std_logic_vector(15 downto 0);
signal res_valid : std_logic;
signal Cartesian_results : Cartesian_results_array;
signal results_out_count : integer range 0 to 4;
signal Magn_Result : FFT_Magnitude_Array;
begin
test_fft: fft
generic map(
coeff_width => 16,
data_width => 16,
fft_length => 4
)
port map(
reset => reset_low, -- Power on reset active low
clk => clk, -- Main clock
data_rd => sample_clk, -- Data Sampling Clock
data_in_r => data_sample_real, -- Input Data Real
data_in_i => data_sample_imag, -- Input Data Imag
address => address, -- Input Address
data_out_r => fft_data_real_result, -- FFT Output Real
data_out_i => fft_data_imag_result, -- FFT Output Imag
res_valid => res_valid -- Results valid indicator
);
cartesian_values: process(address)
-- Insert the real and imaginary results into array to calculate
-- their RMS magnitude values
begin
if ((unsigned(address) rem 2) = 0) or (To_Integer(unsigned(address)) = 0) then
Cartesian_results(To_Integer(unsigned(address))) <= fft_data_real_result;
Cartesian_results(To_Integer(unsigned(address))+1) <= fft_data_imag_result;
end if;
end process cartesian_values;
-- Instantiate the RMS component here for each real and imaginary value and output the results
Mag_Calc: for I in 0 to 3 generate
Magn: RMS
-- Calculate the RMS result for each real and imaginary output values
generic map (16)
port map (
reset => reset_low,
clk => clk,
load => sample_clk,
input_data_real => Cartesian_results(2*I)(15 downto 0),
input_data_imag => Cartesian_results((2*I)+1)(15 downto 0),
rms_result => Magn_Result(I)
);
end generate Mag_Calc;
results_address: process(reset_low, clk)
-- Process generates the input address for the completed results
begin
if reset_low = '0' then
address <= (others => '0');
elsif Rising_Edge(clk) then
if res_valid = '1' then
if To_Integer(unsigned(address)) <= 4 then
address <= address + "010";
end if;
else
address <= (others => '0');
end if;
end if;
end process results_address;
results_out: process(reset_low, clk)
begin
if reset_low = '0' then
results_out_count <= 0;
Data_out <= (others => '0');
elsif Rising_Edge(clk) then
Data_out <= Magn_Result(results_out_count);
results_out_count <= results_out_count + 1;
if results_out_count = 3 then
results_out_count <= 0;
end if;
end if;
end process results_out;
System_reset: process
-- This generates the active low system reset
begin
reset_low <= '1';
wait for 15 ns;
reset_low <= '0';
wait for 100 ns;
reset_low <= '1';
wait;
end process;
clock: process
-- 5MHz Clock pulse (50% low / 50% high)
begin
while now <= 2048000 ns loop
clk <= '1';
wait for 100 ns;
clk <= '0';
wait for 100 ns;
end loop;
wait;
end process;
Stimulus: process
file F: TEXT open READ_MODE is "fft_input_binary.dat";
file G: TEXT open WRITE_MODE is "fft_output_binary.dat";
variable L: LINE;
variable M: LINE;
variable Rvalue: BIT_VECTOR(15 downto 0);
variable Ivalue: BIT_VECTOR(15 downto 0);
begin
while not ENDFILE(F) loop
wait until sample_clk = '1';
READLINE (F, L);
READ (L, Rvalue); -- read real data from input file
READ (L, Ivalue); -- read imaginary data from input file
data_sample_real <= To_StdLogicVector(Rvalue);
data_sample_imag <= To_StdLogicVector(Ivalue);
WRITE (M, (To_bitvector(fft_data_real_result)), Right, 16);
WRITE (M, (To_bitvector(fft_data_real_result)), Right, 17);
WRITELINE (G, M);
end loop;
wait;
end process;
Counter: process(reset_low, clk)
begin
if reset_low = '0' then
count1 <= 0;
sample_clk <= '0';
elsif clk'event and clk = '1' then
count1 <= count1 + 1;
if count1 = 5 then
sample_clk <= '1';
end if;
if count1 = 10 then
sample_clk <= '0';
count1 <= 0;
end if;
end if;
end process Counter;
end;
|
|