packages feed

ice40-prim-0.2.0.0: src/Ice40/Mac.hs

{-|
Module : Ice40.Mac
Description : Ice40 Multiply-Accumulate primitive wrapper
Copyright : (c) David Cox, 2021
License : BSD-3-Clause
Maintainer : standardsemiconductor@gmail.com

MAC primitive wrapper. See "Ice40.Mac.Prim" for the original primitive.
-}
module Ice40.Mac 
  ( mac
  , Input(..)
  , defaultInput
  , Parameter(..)
  , defaultParameter
  ) where

import Clash.Prelude
import Ice40.Mac.Prim

-- | MAC inputs
data Input dom = Input
  { ce        :: Signal dom Bit -- ^ clock enable input. applies to all clocked elemets, default = 1
  , c         :: Signal dom (BitVector 16) -- ^ 16-bits data of input c, default = 0
  , a         :: Signal dom (BitVector 16) -- ^ 16-bits data of input a, default = 0
  , b         :: Signal dom (BitVector 16) -- ^ 16-bits data of input b, default = 0
  , d         :: Signal dom (BitVector 16) -- ^ 16-bits data of input d, default = 0
  , irsttop   :: Signal dom Bit -- ^ reset input to registers A and C. Also reset upper 8x8 multiplier output register (8x8 MAC pipeline register) 0 = not reset (default), 1 = reset
  , irstbot   :: Signal dom Bit -- ^ reset input to registers B and D. Also reset lower 8x8 multiplier output register (8x8 MAC pipeline register) and the 16x16 multiplier output register (16x16 MAC pipeline register). 0 = not reset (default), 1 = reset
  , orsttop   :: Signal dom Bit -- ^ reset input to top accumulator register (for adder/subtractor, accumulator, and MAC functions) 0 = not reset (default), 1 = reset
  , orstbot   :: Signal dom Bit -- ^ reset input to bottom accumulator register (for adder/subtractor, accumulator, and MAC functions) 0 = not reset (default), 1 = rest
  , ahold     :: Signal dom Bit -- ^ register A hold input. Control data flow input register A. 0 = load (default), 1 = hold
  , bhold     :: Signal dom Bit -- ^ register B hold input. Control data flow input register B. 0 = load (default), 1 = hold
  , chold     :: Signal dom Bit -- ^ register C hold input. Control data flow input register C. 0 = load (default), 1 = hold
  , dhold     :: Signal dom Bit -- ^ register D hold input. Control data flow input register D. 0 = load (default), 1 = hold
  , oholdtop  :: Signal dom Bit -- ^ top accumulator output register hold input. control data flow into the register. 0 = load (default), 1 = hold
  , oholdbot  :: Signal dom Bit -- ^ bottom accumulator output register hold input. control data flow into the register. 0 = load (default), 1 = hold
  , addsubtop :: Signal dom Bit -- ^ add/subtract control input to top accumulator. 0 = add (default), 1 = subtract
  , addsubbot :: Signal dom Bit -- ^ add/subtract control input to bottom accumulator. 0 = add (default), 1 = subtract
  , oloadtop  :: Signal dom Bit -- ^ load control input to top accumulator register (initialize on MAC function). 0 = not load (default), 1 = load data from register/input C
  , oloadbot  :: Signal dom Bit -- ^ load control input to bottom accumulator register (initialize on MAC function). 0 = not load (default), 1 = load data from register/input D
  , accumci   :: Signal dom Bit -- ^ cascaded accumulator carry input from previous DSP block, default = 0
  , signextin :: Signal dom Bit -- ^ sign extension input from previous DSP block, default = 0
  , ci        :: Signal dom Bit -- ^ cascaded add/sub carry input from previous DSP block, default = 0
  }

-- | default MAC inputs
defaultInput :: Input dom
defaultInput = Input
  { ce        = 1
  , c         = 0
  , a         = 0
  , b         = 0
  , d         = 0
  , irsttop   = 0
  , irstbot   = 0
  , orsttop   = 0
  , orstbot   = 0
  , ahold     = 0
  , bhold     = 0
  , chold     = 0
  , dhold     = 0
  , oholdtop  = 0
  , oholdbot  = 0
  , addsubtop = 0
  , addsubbot = 0
  , oloadtop  = 0
  , oloadbot  = 0
  , accumci   = 0
  , signextin = 0
  , ci        = 0
  }

-- | MAC parameters
data Parameter = Parameter
  { negTrigger :: Bit -- ^ input clock polarity, 0 = rising edge (default), 1 = falling edge
  , aReg :: Bit -- ^ input A register control, 0 = not registered (default), 1 = registered
  , bReg :: Bit -- ^ input B register control, 0 = not registered (default), 1 = registered
  , cReg :: Bit -- ^ input C register control, 0 = not registered (default), 1 = registered
  , dReg :: Bit -- ^ input D register control, 0 = not registered (default), 1 = registered
  , top8x8MultReg :: Bit -- ^ top 8x8 multiplier output register control (pipeline register for MAC). 0 = not registered (default), 1 = registered
  , bot8x8MultReg :: Bit -- ^ bottom 8x8 multiplier output register control (pipeline register for MAC). 0 = not registered (default), 1 = registered
  , pipeline16x16MultReg1 :: Bit -- ^ 16x16 multiplier pipeline register control. 0 = not registered (default), 1 = registered
  , pipeline16x16MultReg2 :: Bit -- ^ 16x16 multiplier output register control (pipeline register for MAC). 0 = not registered (default), 1 = registered
  , topOutputSelect      :: BitVector 2 -- ^ top output select. 00 = adder-subtractor not registered (default), 01 = adder-subtractor registered, 10 = 8x8 multiplier, 11 = 16x16 multiplier
  , topAddSubLowerInput  :: BitVector 2 -- ^ input X of upper adder-subtractor. 00 = input A (default), 01 = 8x8 multiplier output at top, 10 = 16x16 multiplier upper 16-bit outputs, 11 = sign extension from Z15 (lower adder-subtractor input)
  , topAddSubUpperInput  :: Bit -- ^ input W of upper adder-subtractor. 0 = output of adder-subtractor register (accumulation function) (default), 1 = input C
  , topAddSubCarrySelect :: BitVector 2 -- ^ carry input select top adder-subtractor, 00 = constant 0 (default), 01 = constant 1, 10 = cascade ACCUMOUT from lower adder-subtractor, 11 = cascade CO from lower adder-subtractor
  , botOutputSelect      :: BitVector 2 -- ^ bottom output select. 00 = adder-subtractor not registered (default), 01 = adder-subtractor registered, 10 = 8x8 multiplier, 16x16 multiplier
  , botAddSubLowerInput  :: BitVector 2 -- ^ input Z of upper adder-subtractor. 00 = input B (default), 01 = 8x8 multiplier output at top, 10 = 16x16 multiplier upper 16-bit outputs, 11 = sign extension from SIGNEXTIN
  , botAddSubUpperInput  :: Bit -- ^ input Y of upper adder-subtractor. 0 = output of adder-subtractor output register (accumulation function) (default), 1 = input D
  , botAddSubCarrySelect :: BitVector 2 -- ^ carry input select bottom adder-subtractor. 00 = constant 0 (default), 01 = constant 1, 10 = cascade ACCUMOUT from lower DSP block, 11 = cascade CO from lower DSP block
  , mode8x8 :: Bit -- ^ select 8x8 multiplier mode (power saving. 0 = not selected (default), 1 = selected
  , aSigned :: Bit -- ^ input A sign. 0 = input A is unsigned (default), 1 = input A is signed
  , bSigned :: Bit -- ^ input B sign. 0 = input B is unsigned (default), 1 = input B is signed
  }

-- | default MAC parameters
defaultParameter :: Parameter
defaultParameter = Parameter
  { negTrigger = 0
  , aReg = 0
  , bReg = 0
  , cReg = 0
  , dReg = 0
  , top8x8MultReg = 0
  , bot8x8MultReg = 0
  , pipeline16x16MultReg1 = 0
  , pipeline16x16MultReg2 = 0
  , topOutputSelect = 0
  , topAddSubLowerInput = 0
  , topAddSubUpperInput = 0
  , topAddSubCarrySelect = 0
  , botOutputSelect = 0
  , botAddSubLowerInput = 0
  , botAddSubUpperInput = 0
  , botAddSubCarrySelect = 0
  , mode8x8 = 0
  , aSigned = 0
  , bSigned = 0
  }

-- | MAC primitive wrapper
mac
  :: HiddenClock dom
  => Parameter
  -> Input dom
  -> ( Signal dom (BitVector 32)
     , Signal dom Bit
     , Signal dom Bit
     , Signal dom Bit
     )
mac Parameter{..} Input{..}
  = macPrim negTrigger
            aReg
            bReg
            cReg
            dReg
            top8x8MultReg
            bot8x8MultReg
            pipeline16x16MultReg1
            pipeline16x16MultReg2
            topOutputSelect
            topAddSubLowerInput
            topAddSubUpperInput
            topAddSubCarrySelect
            botOutputSelect
            botAddSubLowerInput
            botAddSubUpperInput
            botAddSubCarrySelect
            mode8x8
            aSigned
            bSigned
            hasClock
            ce
            c
            a
            b
            d
            irsttop
            irstbot
            orsttop
            orstbot
            ahold
            bhold
            chold
            dhold
            oholdtop
            oholdbot
            addsubtop
            addsubbot
            oloadtop
            oloadbot
            accumci
            signextin
            ci