------------------------------------------------------------------------------- -- Title : Distributed Arithmetic top level -- Project : Arithmetic blocks ------------------------------------------------------------------------------- -- File : da.VHD -- Author : Jamil Khatib -- Organization: OpenIPCore Project -- Created : 2000/04/17 -- Last update : 2000/04/17 -- Platform : -- Simulators : Modelsim 5.3XE / Windows98 -- Synthesizers: Leonardo / WindowsNT -- Target : -- Dependency : dapkg ------------------------------------------------------------------------------- -- Description: Distributed Arithmetic based digital filter top level ------------------------------------------------------------------------------- -- Copyright (c) 2000 Jamil Khatib -- -- This VHDL design file is an open design; you can redistribute it and/or -- modify it and/or implement it under the terms of the Openip General Public -- License as it is going to be published by the OpenIPCore Organization and -- any coming versions of this license. -- You can check the draft license at -- http://www.openip.org/oc/license.html ------------------------------------------------------------------------------- -- Revisions : -- Revision Number : 1 -- Version : 0.1 -- Date : 17th Apr 2000 -- Modifier : Jamil Khatib (khatib@ieee.org) -- Desccription : Created -- ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Revisions : -- Revision Number : 2 -- Version : 0.2 -- Date : 30th Apr 2000 -- Modifier : Jamil Khatib (khatib@ieee.org) -- Desccription : Bug fixes and combining it with scaladder.vhd file -- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use work.dapkg.all; entity DA is generic ( NOINPUTS : integer := BUFFER_SIZE; -- number of inputs, no. of filter tabs WORD_SIZE : integer := DATA_SIZE; -- word size CONTENTS : TABLE := CONSTANTS); port ( data : in std_logic_vector(WORD_SIZE -1 downto 0); -- input data Clk : in std_logic; -- system clock Rst_n : in std_logic; -- System reset Result : out std_logic_vector(WORD_SIZE -1 downto 0); -- Result ValidOut : out std_logic; -- Output valid Overflow : out std_logic); -- Overflow signal end DA; use work.dapkg.all; architecture behavior of DA is signal address : std_logic_vector(NOINPUTS -1 downto 0); -- dalut address signal lutres : std_logic_vector(WORD_SIZE -1 downto 0); -- dalut results, partial products signal valid_l : std_logic; -- Local Valid Signal begin -- behavior ------------------------------------------------------------------------------- LUT : DALUT generic map ( ADDR_SIZE => NOINPUTS, OUTPUT_SIZE => WORD_SIZE, CONTENTS => CONSTANTS) port map ( Address => address, Result => lutres); ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- purpose: Input shift registers -- type : sequential -- inputs : clk, rst_n -- outputs: shiftinputs : process (clk, rst_n) type SHIFTREGS is array (0 to (NOINPUTS) -1) of std_logic_vector((WORD_SIZE-1 ) downto 0); variable buffer_reg_typ : SHIFTREGS; -- Internal storage buffer variable count : integer range 0 to (WORD_SIZE-1); -- counter begin -- process shiftinputs if rst_n = '0' then -- asynchronous reset (active low) Valid_l <= '0'; address <= (others => '0'); -- reset the internal buffer for i in 0 to (NOINPUTS -1) loop buffer_reg_typ(i) := (others => '0'); end loop; -- i count := 0; ------------------------------------------------------ elsif clk'event and clk = '1' then -- rising clock edge -- Do the shift for all register buffer and send it to the DALUT address for i in (NOINPUTS-1) downto 1 loop buffer_reg_typ(i) := buffer_reg_typ(i)(WORD_SIZE-2 downto 0) & buffer_reg_typ(i-1)(WORD_SIZE -1); -- -- cyclic shift register end loop; -- i buffer_reg_typ(0) := buffer_reg_typ(0)(WORD_SIZE-2 downto 0) & '0'; if count = (WORD_SIZE -1) then valid_l <= '1'; count := 0; buffer_reg_typ(0) := data; else valid_l <= '0'; count := count + 1; end if; for i in 0 to (NOINPUTS-1) loop address(i) <= buffer_reg_typ(i)(WORD_SIZE-1); end loop; -- i end if; end process shiftinputs; ------------------------------------------------------------------------------- ValidOut <= valid_l; ------------------------------------------------------------------------------- -- purpose: calculates MAC using serial approach -- type : sequential -- inputs : clk positive edge -- rst_n active low -- outputs: mac : process (clk, rst_n) variable tmpres : std_logic_vector(WORD_SIZE - 1 downto 0); -- Temporary result variable overflow_var : std_logic; -- Over Flow variable begin -- process mac if rst_n = '0' then -- asynchronous reset (active low) Result <= (others => '0'); tmpres := (others => '0'); overflow_var := '0'; elsif clk'event and clk = '1' then -- rising clock edge if valid_l = '1' then tmpres := (others => '0'); Overflow_var := '0'; end if; overflow_var := overflow_var or tmpres(WORD_SIZE-1); tmpres := tmpres(WORD_SIZE -2 downto 0 ) & '0'; tmpres := tmpres + lutres; Result <= tmpres; end if; Overflow <= overflow_var; end process mac; end behavior;