------------------------------------------------------------------------------- -- Title : -- Project : Arithmetic blocks ------------------------------------------------------------------------------- -- File : arit.VHD -- Author : Jamil Khatib -- Organization: OpenIPCore Project -- Created : 2000/04/12 -- Last update : 2000/04/17 -- Platform : -- Simulators : Modelsim 5.3XE / Windows98 -- Synthesizers: Leonardo / WindowsNT -- Target : -- Dependency : ------------------------------------------------------------------------------- -- Description: Arithmetic blocks ------------------------------------------------------------------------------- -- 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 : 12th Apr 2000 -- Modifier : Jamil Khatib (khatib@ieee.org) -- Desccription : Created -- ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Revision Number : 2 -- Version : 0.2 -- Date : 17th Apr 2000 -- Modifier : Jamil Khatib (khatib@ieee.org) -- Desccription : More generic -- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity ScaleMAC is generic ( OPSIZE : integer := 8); -- Operand size port ( Op1 : in std_logic_vector(OPSIZE - 1 downto 0); -- Operand 1 Op2 : in std_logic_vector(OPSIZE - 1 downto 0); -- Operand 2 Res : out std_logic_vector(OPSIZE -1 downto 0); -- Result Overflow : out std_logic; -- Overflow ValidOut : out std_logic; -- valid output active high clk : in std_logic; -- system clock positive edge rst_n : in std_logic); -- system reset active low end ScaleMAC; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; architecture behavior of ScaleMAC is begin -- behavior -- purpose: calculates MAC using serial approach -- type : sequential -- inputs : clk positive edge -- rst_n active low -- outputs: mac : process (clk, rst_n) function BitsToSpan(num : integer) return integer is variable work : integer; begin work := num-1; for i in 1 to 32 loop work := work/2; if (work = 0) then return i; end if; end loop; -- report "BitsToSpan: Input too large" severity error; return 0; end; variable op2tmp : std_logic_vector(OPSIZE - 1 downto 0); -- Temporary store of operand 2 variable op1tmp : std_logic_vector(OPSIZE - 1 downto 0); -- Temporary store of operand 1 variable tmpres : std_logic_vector(OPSIZE - 1 downto 0); -- Temporary result variable andres : std_logic_vector(OPSIZE -1 downto 0); -- Anding result variable count : std_logic_vector(BitsToSpan(OPSIZE)-1 downto 0); -- counter variable validvar : std_logic; -- ValidOut variable begin -- process mac if rst_n = '0' then -- asynchronous reset (active low) ValidOut <= '1'; Res <= (others => '0'); validvar := '1'; op2tmp := (others => '0'); op1tmp := (others => '0'); tmpres := (others => '0'); andres := (others => '1'); count := (others => '0'); Overflow <= '0'; elsif clk'event and clk = '1' then -- rising clock edge andres := (others => '1'); if validvar = '1' then ValidOut <= '0'; validvar := '0'; tmpres := (others => '0'); op1tmp := op1; op2tmp := op2; Overflow <= '0'; end if; if count = (count'range => '1') then ValidOut <= '1'; validvar := '1'; for i in 0 to OPSIZE -1 loop andres(i) := op1tmp(i) and op2tmp(OPSIZE - 1 - conv_integer(count)); end loop; -- i tmpres := andres + tmpres; -- No shift in the last clock Res <= tmpres; count := (others => '0'); else for i in 0 to OPSIZE -1 loop andres(i) := op1tmp(i) and op2tmp(OPSIZE - 1 - conv_integer(count)); end loop; -- i tmpres := andres + tmpres; if tmpres(OPSIZE -1 ) = '1' then Overflow <= '1'; end if; tmpres := tmpres(OPSIZE -2 downto 0 ) & '0'; Res <= tmpres; end if; count := count + 1; end if; end process mac; end behavior;