O HAI THIS BLOG PURPZIEZ 2 B UZED AZ MAH PLESIOUS MEM. :)

2007/10/23

xcg.fft.spec.karma--; /* fsckin' misprints */

XilinxのFast Fourier Transform v4.0のProduct specificationが低品質過ぎる.
タイミングチャートのport名が全然違うとか何考えてんだ?まじありえねー. :P
[Xilinx's Fast Fourier Transform v4.0 Product specification really suX0rz.
*STAB*. Why on the earth did dudes misprint t3h port names on timing chart?
NFC at all, KTHXBYE. :P]

で,なんとかその辺を誤魔化して,件のFFTマクロをでっち上げて,後方互換性の為に
そのまんま入出力のIFを移植した.で,予想通り,動作予定クロックで動かないと言う罠.
以下,出力IFの簡易ヴァージョンとヤル気の無いテストベンチ,さらにその手の人しか
解けないかもしれない問題っぽいモノ.
[For fsckin' backward compat, I've ported previous I/F w/o explicit changes to
t3h FFT macro by using that crap. Yup, ITDOESNTWORK(tm) w/ planning clock
ATM. These are stripped version output IF, dumb test bench, and a practical
VHDL Q.]

問題:どこがクロック高速化のボトルネックか?出来れば修正を施して示せ.
なお,OUTPUTIF.vhdlへの修正はoDATA,oOVRそれぞれのレイテンシー
は適当に増やして構わないが,修正以前と同様にアラインメントが揃っている
と好ましい.
[Q: Whre is fsckin' bottleneck to increase clock speed? Fix0rz it. You can
increase latencies of oDATA and oOVR as you like, and to sort their
alignment would be good for following ones.]

修正:typoとか.
[FIX: for typos.]
--
-- OUTPUTIF.vhdl
--
library ieee;
use ieee.std_logic_1164.all;

entity OUTPUTIF is
port (
iCLK : in std_logic;
iCLR : in std_logic;
iDATA : in std_logic_vector(22 downto 0);
iGAIN : in std_logic_vector( 3 downto 0);
oDATA : out std_logic_vector(11 downto 0);
oOVR : out std_logic
);
begin
end entity OUTPUTIF;

architecture RTL of OUTPUTIF is

begin

-- Tune Gain and OVeRflow detection
P_TG_OVR : process (iCLK)
begin
if (iCLK'event and iCLK = '1') then
if (iCLR = '1') then
oDATA <= (others => '0');
oOVR <= '0';
else
case iGAIN is
when "0000" => -- 2^0
oDATA <= iDATA(22 downto 11);
oOVR <= '0';
when "0001" => -- 2^1
if (iDATA(22 downto 21) = "00" or
iDATA(22 downto 21) = "11") then
oDATA <= iDATA(21 downto 10);
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "0010" => -- 2^2
if (iDATA(22 downto 20) = "000" or
iDATA(22 downto 20) = "111") then
oDATA <= iDATA(20 downto 9);
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "0011" => -- 2^3
if (iDATA(22 downto 19) = "0000" or
iDATA(22 downto 19) = "1111") then
oDATA <= iDATA(19 downto 8);
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "0100" => -- 2^4
if (iDATA(22 downto 18) = "00000" or
iDATA(22 downto 18) = "11111") then
oDATA <= iDATA(18 downto 7);
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "0101" => -- 2^5
if (iDATA(22 downto 17) = "000000" or
iDATA(22 downto 17) = "111111") then
oDATA <= iDATA(17 downto 6);
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "0110" => -- 2^6
if (iDATA(22 downto 16) = "0000000" or
iDATA(22 downto 16) = "1111111") then
oDATA <= iDATA(16 downto 5);
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "0111" => -- 2^7
if (iDATA(22 downto 15) = "00000000" or
iDATA(22 downto 15) = "11111111") then
oDATA <= iDATA(15 downto 4);
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "1000" => -- 2^8
if (iDATA(22 downto 14) = "000000000" or
iDATA(22 downto 14) = "111111111") then
oDATA <= iDATA(14 downto 3);
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "1001" => -- 2^9
if (iDATA(22 downto 13) = "0000000000" or
iDATA(22 downto 13) = "1111111111") then
oDATA <= iDATA(13 downto 2);
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "1010" => -- 2^10
if (iDATA(22 downto 12) = "00000000000" or
iDATA(22 downto 12) = "11111111111") then
oDATA <= iDATA(12 downto 1);
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "1011" => -- 2^11
if (iDATA(22 downto 11) = "000000000000" or
iDATA(22 downto 11) = "111111111111") then
oDATA <= iDATA(11 downto 0);
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "1100" => -- 2^12
if (iDATA(22 downto 10) = "0000000000000" or
iDATA(22 downto 10) = "1111111111111") then
oDATA <= iDATA(10 downto 0) & '0';
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "1101" => -- 2^13
if (iDATA(22 downto 9) = "00000000000000" or
iDATA(22 downto 9) = "11111111111111") then
oDATA <= iDATA(9 downto 0) & "00";
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "1110" => -- 2^14
if (iDATA(22 downto 8) = "000000000000000" or
iDATA(22 downto 8) = "111111111111111") then
oDATA <= iDATA(8 downto 0) & "000";
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when "1111" => -- 2^15
if (iDATA(22 downto 7) = "0000000000000000" or
iDATA(22 downto 7) = "1111111111111111") then
oDATA <= iDATA(7 downto 0) & "0000";
oOVR <= '0';
else
oDATA(11) <= iDATA(22);
oDATA(10 downto 0) <= (others => not iDATA(22));
oOVR <= '1';
end if;
when others => -- 2^0
oDATA <= iDATA(22 downto 11);
oOVR <= '0';
end case;
end if;
end if;
end process P_TG_OVR;

end architecture RTL;

--
-- BENCH_OUTPUTIF.vhdl
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity BENCH_OUTPUTIF is
begin
end entity BENCH_OUTPUTIF;

architecture BENCH of BENCH_OUTPUTIF is

component OUTPUTIF is
port (
iCLK : in std_logic;
iCLR : in std_logic;
iDATA : in std_logic_vector(22 downto 0);
iGAIN : in std_logic_vector( 3 downto 0);
oDATA : out std_logic_vector(11 downto 0);
oOVR : out std_logic
);
end component OUTPUTIF;

signal sCLK : std_logic;
signal sCLR : std_logic;
signal sDATA : std_logic_vector(22 downto 0);
signal sGAIN : std_logic_vector( 3 downto 0);

signal sOUTPUTIF_oDATA : std_logic_vector(11 downto 0);
signal sOUTPUTIF_oOVR : std_logic;

begin

P_CLK : process
begin
sCLK <= '1'; wait for 0.5 us;
sCLK <= '0'; wait for 0.5 us;
end process P_CLK;

P_CLR : process
begin
sCLR <= '1'; wait for 10.0 us;
sCLR <= '0'; wait;
end process P_CLR;

P_DATA : process (sCLK)
begin
if (sCLK'event and sCLK = '1') then
if (sCLR = '1') then
sDATA <= (others => '0'); -- signed zero
else
sDATA <= signed(sDATA) + 1;
end if;
end if;
end process P_DATA;

P_GAIN : process (sCLK)
begin
if (sCLK'event and sCLK = '1') then
if (sCLR = '1') then
sGAIN <= (others => '0'); -- unsigned zero
else
if (signed(sDATA) = 0) then
sGAIN <= unsigned(sGAIN) + 1;
else
sGAIN <= sGAIN;
end if;
end if;
end if;
end process P_GAIN;

U_OUTPUTIF : OUTPUTIF
port map (
iCLK => sCLK,
iCLR => sCLR,
iDATA => sDATA,
iGAIN => sGAIN,
oDATA => sOUTPUTIF_oDATA,
oOVR => sOUTPUTIF_oOVR
);

end architecture BENCH;

0 件のコメント: