-------------------------------------------------------------------------------- -- DW2005 FM reciver for Spartan-3 RECV module -- Ver 00 -- 19 Dec. 2004 -------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY RECV is port ( CLK : in std_logic; RESET : in std_logic; FMIN : in std_logic_vector(7 downto 0 ); DMOUT : out std_logic_vector(11 downto 0 ) ); END RECV; --data format --FMIN(8,0,t) -- S.XXXXXXX -- -1 to 1-(1/2**7) --DMOUT(12,4,t) -- SXXXX.XXXXXXX -- -16 to 16-(1/2**7) ARCHITECTURE RTL of RECV is COMPONENT RAMB port ( CLK : in std_logic; DIN : in std_logic_vector(7 downto 0); DOUT : out std_logic_vector(7 downto 0); WE : in std_logic; WADR : in std_logic_vector(9 downto 0); RADR : in std_logic_vector(9 downto 0) ); END COMPONENT; ------------------------------------------------------------------------------------ -- -- Signals -- signal CUR_S : std_logic_vector(7 downto 0); --signed data signal DLY_S : std_logic_vector(7 downto 0); --current / delayed signal CUR_U : std_logic_vector(7 downto 0); --unsigned data signal DLY_U : std_logic_vector(7 downto 0); --current / delayed signal MIX : std_logic_vector(15 downto 0); --mixing signal MIX_R : std_logic_vector(8 downto 0); --round signal xMIX_R : std_logic_vector(8 downto 0); --invert signal SIGN0 : std_logic_vector(1 downto 0); --sign signal SIGN1 : std_logic_vector(1 downto 0); --1D signal R_ADR : std_logic_vector(9 downto 0); --write address signal W_ADR : std_logic_vector(9 downto 0); --read address signal DAT_R : std_logic_vector(9 downto 0); --raw data signal CNT : std_logic_vector(5 downto 0); --counter signal SUM : std_logic_vector(11 downto 0); --sum up signal REG : std_logic_vector(11 downto 0); --data register signal EN : std_logic; --enable ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -- -- Start of circuit description -- BEGIN process(RESET, CLK) begin if(RESET = '1') then CUR_S <= (others => '0'); elsif (CLK'event and CLK='1') then CUR_S <= FMIN; end if; end process; -- -- delay line -- process(RESET, CLK) begin if(RESET = '1') then R_ADR <= (others => '0'); elsif (CLK'event and CLK='1') then if(R_ADR < "1110011010") then --16000/455*26.25=923 000-39A R_ADR <= R_ADR + "0000000001"; else R_ADR <= (others => '0'); end if; end if; end process; process(RESET, CLK) begin if(RESET = '1') then W_ADR <= (others => '0'); elsif (CLK'event and CLK='1') then W_ADR <= R_ADR; end if; end process; U21 : RAMB port map ( CLK => CLK, DIN => CUR_S, DOUT => DLY_S, WE => '1', WADR => W_ADR, RADR => R_ADR ); -- -- mixer(unsigned) -- process(RESET, CLK) begin if(RESET = '1') then CUR_U <= (others => '0'); elsif (CLK'event and CLK='1') then if(CUR_S(7)='0') then CUR_U <= "0" & CUR_S(6 downto 0); else CUR_U <= "0" & (CUR_S(6 downto 0) xor "1111111"); end if; end if; end process; process(RESET, CLK) begin if(RESET = '1') then DLY_U <= (others => '0'); elsif (CLK'event and CLK='1') then if(DLY_S(7)='0') then DLY_U <= "0" & DLY_S(6 downto 0); else DLY_U <= "0" & (DLY_S(6 downto 0) xor "1111111"); end if; end if; end process; process(RESET, CLK) begin if(RESET = '1') then MIX <= (others => '0'); elsif (CLK'event and CLK='1') then MIX <= CUR_U * DLY_U; end if; end process; -- -- round(signed) -- MIX_R <= MIX(10 downto 2); xMIX_R <= MIX_R xor "111111111"; process(RESET, CLK) begin if(RESET = '1') then SIGN0<= (others => '0'); SIGN1<= (others => '0'); elsif (CLK'event and CLK='1') then SIGN0 <= CUR_S(7) & DLY_S(7); SIGN1 <= SIGN0; end if; end process; process(RESET, CLK) begin if(RESET = '1') then DAT_R <= (others => '0'); elsif (CLK'event and CLK='1') then if(MIX_R = "0000000000") then DAT_R <= (others => '0'); else case SIGN1 is when "01" => DAT_R <= "1" & xMIX_R; when "10" => DAT_R <= "1" & xMIX_R; when others => DAT_R <= "0" & MIX_R; end case; end if; end if; end process; -- -- average -- process(RESET, CLK) begin if(RESET = '1') then CNT <= (others => '0'); elsif (CLK'event and CLK='1') then if(EN = '1') then CNT <= (others => '0'); else CNT <= CNT + "000001"; end if; end if; end process; EN <= '1' when (CNT >= "100011") else '0'; --16000/455=35 00-23 process(RESET, CLK) begin if(RESET = '1') then SUM <= (others => '0'); REG <= (others => '0'); elsif (CLK'event and CLK='1') then if(EN = '1') then SUM <= (others => '0'); REG <= SUM; else SUM <= SUM + (DAT_R(9) & DAT_R(9) & DAT_R); end if; end if; end process; DMOUT <= REG; END RTL ;