-------------------------------------------------------------------------------
--- $Id: PrimitiveGates.hs#2 2010/09/21 13:51:11 REDMOND\\satnams $
-------------------------------------------------------------------------------

module Lava.PrimitiveGates (module Lava.PrimitiveGates)
where
import Control.Monad.State
import Lava.Netlist

-- * Adding new primitive gates to the Lava system

-------------------------------------------------------------------------------
-- | 'primitiveGate' adds a primitive gate 

primitiveGate :: String -- ^ The name of the component
                 -> [(String, Bit)] -- ^ name of input ports with argument nets
                 -> [String]  -- ^ name of output ports
                 -> Maybe (Int, Int) -- ^ optional size information for layout
                 -> Out [Bit] -- ^ a list of output nets from this component
primitiveGate gateName inputPorts outputNames maybeSize
  = do state <- get
       let insts = instances state
           oNet = netCount state
           instNr = instCount state
           placement = if maybeSize /= Nothing && layoutNesting state > 0 then
                         At (0, 0)
                       else
                         Unplaced
           outputs = zip outputNames [oNet..]
           newInst = Instance 
                       (PrimitiveGate inputPorts outputs) 
                       gateName instNr placement maybeSize
       put (state{instances = newInst:insts, 
                  netCount = oNet + length outputNames, 
                  instCount = instNr +1})
       return [oNet..oNet+length outputNames-1]
    where
    Just (w, h) = maybeSize

-------------------------------------------------------------------------------