- Intital revision

git-svn-id: http://moon:8086/svn/vhdl/trunk@192 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2009-01-03 20:06:07 +00:00
parent 690c6c24f6
commit fcdbc0e601
6 changed files with 700 additions and 0 deletions
+19
View File
@@ -0,0 +1,19 @@
vmap ieee_proposed ../../../Common/sim/ieee_proposed
vlib work
vcom -explicit -93 "../../../lib/misc/utils_pkg.vhd"
vcom -explicit -93 "../../../lib/fixed/fixed_util_pkg.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_pkg.vhd"
vcom -explicit -93 "../src/fir_stage_sys.vhd"
vcom -explicit -93 "../src/delay_line.vhd"
vcom -explicit -93 "../src/fir_semi_parallel.vhd"
vcom -explicit -93 "../src/tb_fir_semi_parallel.vhd"
vsim -t 1ps -lib work tb_fir_semi_parallel
do {tb_fir_semi_parallel.wdo}
view wave
view structure
view signals
run 400us
+58
View File
@@ -0,0 +1,58 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic /tb_fir_semi_parallel/uut/rst
add wave -noupdate -format Logic /tb_fir_semi_parallel/uut/clk
add wave -noupdate -format Literal /tb_fir_semi_parallel/uut/h_addr
add wave -noupdate -format Logic /tb_fir_semi_parallel/uut/h_we
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/h_in
add wave -noupdate -format Logic /tb_fir_semi_parallel/din_vld
add wave -noupdate -format Logic /tb_fir_semi_parallel/dout_vld
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/d_in
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/d_out
add wave -noupdate -format Literal /tb_fir_semi_parallel/uut/vld_pipe
add wave -noupdate -format Logic /tb_fir_semi_parallel/rdy
add wave -noupdate -divider {Real out}
add wave -noupdate -format Analog-Step -height 50 -scale 50.0 /tb_fir_semi_parallel/xi
add wave -noupdate -format Analog-Step -height 50 -scale 50.0 /tb_fir_semi_parallel/yo
add wave -noupdate -divider -height 50 <NULL>
add wave -noupdate -format Literal /tb_fir_semi_parallel/uut/count_array
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/coef_array
add wave -noupdate -format Literal -expand /tb_fir_semi_parallel/uut/ce_array
add wave -noupdate -format Literal /tb_fir_semi_parallel/uut/h_addr
add wave -noupdate -format Logic /tb_fir_semi_parallel/uut/h_we
add wave -noupdate -format Literal -radix decimal -expand /tb_fir_semi_parallel/uut/x
add wave -noupdate -format Logic /tb_fir_semi_parallel/uut/accu_load
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/accu
add wave -noupdate -format Literal -radix decimal -expand /tb_fir_semi_parallel/uut/y
add wave -noupdate -divider {stage 1}
add wave -noupdate -format Logic /tb_fir_semi_parallel/uut/gen_stages__0/inst_fir_stage/clk
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__0/inst_fir_stage/xin
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__0/inst_fir_stage/yin
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__0/inst_fir_stage/hin
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__0/inst_fir_stage/prod
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__0/inst_fir_stage/x_out
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__0/inst_fir_stage/y_out
add wave -noupdate -divider {stage 2}
add wave -noupdate -format Logic /tb_fir_semi_parallel/uut/gen_stages__1/inst_fir_stage/clk
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__1/inst_fir_stage/xin
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__1/inst_fir_stage/yin
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__1/inst_fir_stage/hin
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__1/inst_fir_stage/prod
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__1/inst_fir_stage/x_out
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__1/inst_fir_stage/y_out
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {126110000 ps} 0}
configure wave -namecolwidth 150
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 100
configure wave -griddelta 40
configure wave -timeline 1
update
WaveRestoreZoom {0 ps} {420 us}
+79
View File
@@ -0,0 +1,79 @@
--------------------------------------------------------------------------------
-- 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;
library ieee_proposed;
use ieee_proposed.math_utility_pkg.all;
use ieee_proposed.fixed_pkg.all;
library work;
use work.utils_pkg.all;
use work.fixed_util_pkg.all;
entity delay_line is
Generic
(
nbits : integer := 12;
nbits_frac : integer := 11;
ntaps : integer := 4;
delay_fix : integer := 1
);
Port
(
clk : in std_logic;
ce : in std_logic;
delay : in natural range 0 to ntaps-1;
din : in sfixed;
dout : out sfixed
);
end delay_line;
architecture Behavioral of delay_line is
-------------------------------------------------------------------------------
subtype word_t is sfixed(shi(nbits, nbits_frac) downto slo(nbits, nbits_frac));
type delay_pipe_t is array (ntaps-1 downto 0) of word_t;
type delay_fix_pipe_t is array (delay_fix downto 0) of word_t;
-------------------------------------------------------------------------------
begin
--- assert delay_fix >= 1 report "fix delay must be greater than 1!" severity failure;
shift_register:
process(clk)
variable delay_pipe : delay_pipe_t;
begin
if rising_edge(clk) then
dout <= delay_pipe(delay);
if ce = '1' then
delay_pipe := delay_pipe(delay_pipe'left-1 downto 0) & din;
end if;
end if;
end process;
----------------------------------------
-- Finished instantiation
----------------------------------------
end Behavioral;
+54
View File
@@ -0,0 +1,54 @@
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.MATH_REAL.ALL;
use ieee.numeric_std.all;
library ieee_proposed;
use ieee_proposed.math_utility_pkg.all;
use ieee_proposed.fixed_pkg.all;
library work;
use work.utils_pkg.all;
use work.fixed_util_pkg.all;
use work.filter_pkg.all;
-------------------------------------------------------------------------------
package fir_pkg is
type fir_stage_mode_t is (transposed, systolic);
type fir_iterative_mode_t is (normal, symmetric);
type fir_parallel_mode_t is (transposed, transposed_sym, systolic, systolic_sym);
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_pkg;
-------------------------------------------------------------------------------
package body fir_pkg is
function taps_nbits(ntaps : integer; mode : fir_iterative_mode_t) return integer is
variable res : integer;
begin
res := integer(NextExpBaseTwo(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_pkg;
-------------------------------------------------------------------------------
+283
View File
@@ -0,0 +1,283 @@
--------------------------------------------------------------------------------
-- 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;
library ieee_proposed;
use ieee_proposed.math_utility_pkg.all;
use ieee_proposed.fixed_pkg.all;
library work;
use work.utils_pkg.all;
use work.fixed_util_pkg.all;
use work.fir_pkg.all;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity fir_semi_parallel is
Generic
(
ntaps_per_stage : integer := 32;
nstages : integer := 2;
mul_latency : integer := 1;
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
);
Port
(
rst : in std_logic;
clk : in std_logic;
h_addr : in natural range 0 to nstages*ntaps_per_stage-1;
h_we : in std_logic;
h_in : in sfixed;
din_vld : in std_logic;
din : in sfixed;
dout_vld : out std_logic;
rdy : out std_logic;
dout : out sfixed
);
end fir_semi_parallel;
architecture Behavioral of fir_semi_parallel is
-------------------------------------------------------------------------------
constant coef_addr_nbits : natural := NextExpBaseTwo(ntaps_per_stage) + NextExpBaseTwo(nstages);
constant input_latency : natural := 1;
constant coef_latency : natural := 1;
constant pipe_latency : natural := mul_latency + 1;
subtype coef_t is sfixed(shi(nbits_stages, nbits_stages_frac) downto slo(nbits_stages, nbits_stages_frac));
type coef_stage_t is array (0 to nstages-1) of coef_t;
type coef_stage_array_t is array (0 to ntaps_per_stage-1) of coef_t;
type coef_array_t is array (0 to nstages-1) of coef_stage_array_t;
subtype count_t is natural range 0 to ntaps_per_stage-1;
type count_array_t is array (0 to nstages-1) of count_t;
subtype stage_t is sfixed(shi(nbits_stages, nbits_stages_frac) downto slo(nbits_stages, nbits_stages_frac));
type stage_array_t is array (0 to nstages) of stage_t;
signal count_array : count_array_t;
signal coef_array : coef_array_t;
signal coef_stage : coef_stage_t;
signal count0 : count_t;
signal ce0 : std_logic;
signal ce_array : unsigned(0 to nstages);
signal coef_addr : unsigned(coef_addr_nbits-1 downto 0);
signal stage_addr : unsigned(NextExpBaseTwo(nstages)-1 downto 0);
SIGNAL x : stage_array_t;
SIGNAL xo : stage_array_t;
SIGNAL y : stage_array_t;
SIGNAL accu : sfixed(shi(nbits_stages, nbits_stages_frac) downto slo(nbits_stages, nbits_stages_frac));
signal accu_load : std_logic;
signal accu_ld_pipe : unsigned(nstages+input_latency+coef_latency+pipe_latency downto 0);
signal vld_pipe : unsigned((1+ntaps_per_stage)*nstages downto 0);
-------------------------------------------------------------------------------
begin
assert ntaps_per_stage = NextPowerOfTwo(ntaps_per_stage) report "ntaps_per_stage must be of form 2**R!" severity failure;
coef_addr <= to_unsigned(h_addr, coef_addr_nbits);
stage_addr <= coef_addr(coef_addr'left downto NextExpBaseTwo(ntaps_per_stage));
x(0) <= resize(din, x(0));
y(0) <= to_sfixed(0.0, y(0));
accu_load <= accu_ld_pipe(accu_ld_pipe'left);
dout_vld <= vld_pipe(vld_pipe'left) and ce0;
rdy <= ce0;
valid_pipe:
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
vld_pipe <= (others => '0');
elsif ce0 = '1' then
vld_pipe <= vld_pipe(vld_pipe'left-1 downto 0) & din_vld;
end if;
end if;
end process;
accu_load_pipe:
process(clk)
begin
if rising_edge(clk) then
accu_ld_pipe(0) <= ce0;
for i in 1 to accu_ld_pipe'length-1 loop
if rst = '1' then
accu_ld_pipe(i) <= '0';
else
accu_ld_pipe(i) <= accu_ld_pipe(i-1);
end if;
end loop;
end if;
end process;
coef_write:
process(clk)
variable i : natural range 0 to nstages-1;
variable j : natural range 0 to ntaps_per_stage-1;
begin
if rising_edge(clk) then
i := to_integer(stage_addr);
j := to_integer(coef_addr(NextExpBaseTwo(ntaps_per_stage)-1 downto 0));
if h_we = '1' then
coef_array(i)(j) <= h_in;
end if;
end if;
end process;
coef_read:
process(clk)
variable i : natural range 0 to nstages-1;
begin
if rising_edge(clk) then
for i in 0 to nstages-1 loop
coef_stage(i) <= coef_array(i)(count_array(i));
end loop;
end if;
end process;
counter:
process(clk)
variable cnt : count_t;
begin
if rising_edge(clk) then
ce0 <= '0';
count0 <= cnt;
if rst = '1' then
cnt := 0;
else
if cnt /= count_t'high then
cnt := cnt + 1;
else
cnt := 0;
ce0 <= '1';
end if;
end if;
end if;
end process;
cnt_pipe:
process(clk)
begin
if rising_edge(clk) then
count_array(0) <= count0;
for i in 1 to nstages-1 loop
if rst = '0' then
count_array(i) <= count_array(i-1);
end if;
end loop;
end if;
end process;
ce_pipe:
process(clk)
begin
if rising_edge(clk) then
ce_array(0) <= ce0;
for i in 1 to nstages loop
if rst = '1' then
ce_array(i) <= '0';
else
ce_array(i) <= ce_array(i-1);
end if;
end loop;
end if;
end process;
gen_stages:
for i in 0 to nstages-1 generate
begin
inst_fir_stage: entity work.fir_stage_sys
GENERIC MAP
(
nbits_in => nbits_stages,
nbits_in_frac => nbits_stages_frac,
nbits_out => nbits_stages,
nbits_out_frac => nbits_stages_frac,
input_latency => input_latency,
coef_latency => coef_latency,
pipe_latency => pipe_latency
)
PORT MAP
(
rst => rst,
clk => clk,
x_in => x(i+1),
y_in => y(i),
h_in => coef_stage(i),
x_out => xo(i+1),
y_out => y(i+1)
);
end generate;
gen_delays:
for i in 0 to nstages-1 generate
begin
inst_delay_line : entity work.delay_line
GENERIC MAP
(
nbits => nbits_stages,
nbits_frac => nbits_stages_frac,
ntaps => ntaps_per_stage,
delay_fix => 0
)
PORT MAP
(
clk => clk,
ce => ce_array(i),
delay => count_array(i),
din => x(i),
dout => x(i+1)
);
end generate;
acumulator:
process(clk)
begin
if rising_edge(clk) then
if accu_load = '1' then
dout <= resize(accu, shi(nbits_out, nbits_out_frac), slo(nbits_out, nbits_out_frac));
end if;
if accu_load = '1' then
accu <= y(nstages);
else
accu <= resize(accu + y(nstages), accu);
end if;
end if;
end process;
end Behavioral;
+207
View File
@@ -0,0 +1,207 @@
--------------------------------------------------------------------------------
-- 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 ieee_proposed;
use ieee_proposed.math_utility_pkg.all;
use ieee_proposed.fixed_pkg.all;
library work;
use work.fixed_util_pkg.all;
use work.filter_pkg.all;
use work.fir_pkg.all;
use work.PCK_FIO.all;
ENTITY tb_fir_semi_parallel IS
Generic
(
ntaps_per_stage : integer := 64;
nstages : integer := 2;
nbits_in : integer := 32;
nbits_in_frac : integer := 30;
nbits_stages : integer := 32;
nbits_stages_frac : integer := 30;
nbits_out : integer := 32;
nbits_out_frac : integer := 30
);
END tb_fir_semi_parallel;
ARCHITECTURE behavior OF tb_fir_semi_parallel IS
-------------------------------------------------------------------------------
--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 rst : std_logic := '1';
SIGNAL din_vld : std_logic := '0';
SIGNAL d_in : sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac));
signal h_addr : natural := 0;
SIGNAL h_we : std_logic := '0';
SIGNAL h_in : sfixed(shi(nbits_stages, nbits_stages_frac) downto slo(nbits_stages, nbits_stages_frac));
--Outputs
SIGNAL d_out : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac));
SIGNAL dout_vld : std_logic;
SIGNAL rdy : std_logic;
SIGNAL fileout_enable : std_logic := '1';
SIGNAL xi, yo : real := 0.0;
CONSTANT ntaps : natural := nstages*ntaps_per_stage;
type h_mem_t is array (0 to ntaps-1) of sfixed(shi(nbits_stages, nbits_stages_frac) downto slo(nbits_stages, nbits_stages_frac));
function to_h_mem(coef_real : real_array_t; ntaps : integer; proto : sfixed) return h_mem_t is
variable res : h_mem_t;
begin
for i in 0 to ntaps-1 loop
res(i) := to_sfixed(coef_real(i), proto, fixed_wrap, fixed_round);
end loop;
return res;
end to_h_mem;
CONSTANT coeffs : real_array_t(0 to ntaps-1) := FilterCoef_Lowpass(ntaps, 0.1, 4.0);
CONSTANT h_mem : h_mem_t := to_h_mem(coeffs, ntaps, h_in);
-- file I/O
subtype sample_t is integer range -32768 to 32767;
type file_t is file of sample_t;
-------------------------------------------------------------------------------
BEGIN
xi <= to_real(d_in);
yo <= to_real(d_out);
----------------------------------------
-- Instantiate the Unit Under Test (UUT)
----------------------------------------
uut : entity work.fir_semi_parallel
GENERIC MAP
(
ntaps_per_stage => ntaps_per_stage,
nstages => nstages,
mul_latency => 2,
nbits_in => nbits_in,
nbits_in_frac => nbits_in_frac,
nbits_stages => nbits_stages,
nbits_stages_frac => nbits_stages_frac,
nbits_out => nbits_out,
nbits_out_frac => nbits_out_frac
)
PORT MAP
(
rst => rst,
clk => clk,
h_addr => h_addr,
h_we => h_we,
h_in => h_in,
din_vld => din_vld,
din => d_in,
dout_vld => dout_vld,
rdy => rdy,
dout => d_out
);
----------------------------------------
-- Finished instantiation
----------------------------------------
tb_clk : PROCESS
BEGIN
clk <= not clk;
wait for PERIOD/2;
END PROCESS;
din_vld <= rdy;
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;
rst <= '0';
------------------------------------------
wait for 2*PERIOD;
-- write coeffs
for i in 0 to ntaps-1 loop
wait until rising_edge(clk);
h_addr <= i;
h_in <= h_mem(i);
h_we <= '1';
end loop;
wait until rising_edge(clk);
h_we <= '0';
d_in <= to_sfixed(0.0, d_in);
wait for 64*ntaps*PERIOD;
wait until rising_edge(clk);
for i in 0 to 19 loop
wait until rising_edge(clk);
-- din_vld <= rdy;
d_in <= to_sfixed(real(i)*0.01, d_in);
wait until rising_edge(clk);
-- din_vld <= '0';
wait for (ntaps_per_stage-1)*PERIOD;
end loop;
wait until rising_edge(clk);
------------------------------------------
-- din_vld <= '0';
d_in <= to_sfixed(0.0, d_in);
wait for 64*ntaps*PERIOD;
wait until rising_edge(clk);
-- din_vld <= '1';
d_in <= to_sfixed(1.0, d_in);
wait until rising_edge(clk);
-- din_vld <= '0';
wait for (ntaps_per_stage-1)*PERIOD;
d_in <= to_sfixed(0.0, d_in);
wait for 40*PERIOD;
assert false report "Test finished" severity error;
wait;
END PROCESS;
tb_fo : PROCESS(clk, fileout_enable)
file fo : file_t open write_mode is "wav_out.dat";
variable so : sample_t;
BEGIN
if rising_edge(clk) and fileout_enable = '1' then
if dout_vld = '1' then
so := to_integer(d_out);
write(fo, so);
end if;
end if;
END PROCESS;
END;