-------------------------------------------------------------------------------
-- 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; 


1