Merge branch 'cλash' of http://git.stderr.nl/matthijs/projects/master-project
authorChristiaan Baaij <christiaan.baaij@gmail.com>
Wed, 24 Jun 2009 11:29:50 +0000 (13:29 +0200)
committerChristiaan Baaij <christiaan.baaij@gmail.com>
Wed, 24 Jun 2009 11:29:50 +0000 (13:29 +0200)
* 'cλash' of http://git.stderr.nl/matthijs/projects/master-project:
  Generate vector functions on demand.

Conflicts:
Generate.hs
GlobalNameTable.hs

1  2 
Generate.hs
GlobalNameTable.hs

diff --combined Generate.hs
index cc65979615bf67aa9a7b08e8164124e48434c909,de8c1a6604699320024636b3d5e32a5eab7c576d..cc3cb675b3a405fd7a10cb1d1d973c86195f3742
@@@ -2,13 -2,16 +2,16 @@@ module Generate wher
  
  -- Standard modules
  import qualified Control.Monad as Monad
+ import qualified Data.Map as Map
  import qualified Maybe
+ import Data.Accessor
  
  -- ForSyDe
  import qualified ForSyDe.Backend.VHDL.AST as AST
  
  -- GHC API
  import CoreSyn
+ import Type
  import qualified Var
  
  -- Local imports
@@@ -19,18 -22,20 +22,20 @@@ import CoreTool
  
  -- | Generate a binary operator application. The first argument should be a
  -- constructor from the AST.Expr type, e.g. AST.And.
- genExprOp2 :: (AST.Expr -> AST.Expr -> AST.Expr) -> [AST.Expr] -> VHDLSession AST.Expr
- genExprOp2 op [arg1, arg2] = return $ op arg1 arg2
+ genExprOp2 :: (AST.Expr -> AST.Expr -> AST.Expr) -> CoreSyn.CoreBndr -> [AST.Expr] -> VHDLSession AST.Expr
+ genExprOp2 op res [arg1, arg2] = return $ op arg1 arg2
  
  -- | Generate a unary operator application
- genExprOp1 :: (AST.Expr -> AST.Expr) -> [AST.Expr] -> VHDLSession AST.Expr
- genExprOp1 op [arg] = return $ op arg
+ genExprOp1 :: (AST.Expr -> AST.Expr) -> CoreSyn.CoreBndr -> [AST.Expr] -> VHDLSession AST.Expr
+ genExprOp1 op res [arg] = return $ op arg
  
- -- | Generate a function call from the Function Name and a list of expressions
- --   (its arguments)
- genExprFCall :: AST.VHDLId -> [AST.Expr] -> VHDLSession AST.Expr
- genExprFCall fName args = 
-    return $ AST.PrimFCall $ AST.FCall (AST.NSimple fName)  $
+ -- | Generate a function call from the destination binder, function name and a
+ -- list of expressions (its arguments)
+ genExprFCall :: String -> CoreSyn.CoreBndr -> [AST.Expr] -> VHDLSession AST.Expr
+ genExprFCall fname res args = do
+   let el_ty = (tfvec_elem . Var.varType) res
+   id <- vectorFunId el_ty fname
+   return $ AST.PrimFCall $ AST.FCall (AST.NSimple id)  $
               map (\exp -> Nothing AST.:=>: AST.ADExpr exp) args
  
  -- | Generate a generate statement for the builtin function "map"
@@@ -48,10 -53,10 +53,10 @@@ genMapCall entity [arg, res] = return 
      genScheme   = AST.ForGn nPar range
      -- Get the entity name and port names
      entity_id   = ent_id entity
 -    argport     = map (Monad.liftM fst) (ent_args entity)
 +    argports   = map (Monad.liftM fst) (ent_args entity)
      resport     = (Monad.liftM fst) (ent_res entity)
      -- Assign the ports
 -    inport      = mkAssocElemIndexed (head argport) (varToString arg) nPar
 +    inport      = mkAssocElemIndexed (argports!!0) (varToString arg) nPar
      outport     = mkAssocElemIndexed resport (varToString res) nPar
      clk_port    = mkAssocElem (Just $ mkVHDLExtId "clk") "clk"
      portassigns = Maybe.catMaybes [inport,outport,clk_port]
      compins     = mkComponentInst mapLabel entity_id portassigns
      -- Return the generate functions
      genSm       = AST.GenerateSm label genScheme [] [compins]
 +    
 +genZipWithCall ::
 +  Entity
 +  -> [CoreSyn.CoreBndr]
 +  -> VHDLSession AST.GenerateSm
 +genZipWithCall entity [arg1, arg2, res] = return $ genSm
 +  where
 +    -- Setup the generate scheme
 +    len         = (tfvec_len . Var.varType) res
 +    label       = mkVHDLExtId ("zipWithVector" ++ (varToString res))
 +    nPar        = AST.unsafeVHDLBasicId "n"
 +    range       = AST.ToRange (AST.PrimLit "0") (AST.PrimLit $ show (len-1))
 +    genScheme   = AST.ForGn nPar range
 +    -- Get the entity name and port names
 +    entity_id   = ent_id entity
 +    argports    = map (Monad.liftM fst) (ent_args entity)
 +    resport     = (Monad.liftM fst) (ent_res entity)
 +    -- Assign the ports
 +    inport1     = mkAssocElemIndexed (argports!!0) (varToString arg1) nPar
 +    inport2     = mkAssocElemIndexed (argports!!1) (varToString arg2) nPar 
 +    outport     = mkAssocElemIndexed resport (varToString res) nPar
 +    clk_port    = mkAssocElem (Just $ mkVHDLExtId "clk") "clk"
 +    portassigns = Maybe.catMaybes [inport1,inport2,outport,clk_port]
 +    -- Generate the portmap
 +    mapLabel    = "zipWith" ++ (AST.fromVHDLId entity_id)
 +    compins     = mkComponentInst mapLabel entity_id portassigns
 +    -- Return the generate functions
 +    genSm       = AST.GenerateSm label genScheme [] [compins]
  
+ -- Returns the VHDLId of the vector function with the given name for the given
+ -- element type. Generates -- this function if needed.
+ vectorFunId :: Type.Type -> String -> VHDLSession AST.VHDLId
+ vectorFunId el_ty fname = do
+   elemTM <- vhdl_ty el_ty
+   -- TODO: This should not be duplicated from mk_vector_ty. Probably but it in
+   -- the VHDLState or something.
+   let vectorTM = mkVHDLExtId $ "vector_" ++ (AST.fromVHDLId elemTM)
+   typefuns <- getA vsTypeFuns
+   case Map.lookup (OrdType el_ty, fname) typefuns of
+     -- Function already generated, just return it
+     Just (id, _) -> return id
+     -- Function not generated yet, generate it
+     Nothing -> do
+       let functions = genUnconsVectorFuns elemTM vectorTM
+       case lookup fname functions of
+         Just body -> do
+           modA vsTypeFuns $ Map.insert (OrdType el_ty, fname) (function_id, body)
+           return function_id
+         Nothing -> error $ "I don't know how to generate vector function " ++ fname
+   where
+     function_id = mkVHDLExtId fname
  genUnconsVectorFuns :: AST.TypeMark -- ^ type of the vector elements
                      -> AST.TypeMark -- ^ type of the vector
-                     -> [AST.SubProgBody]
+                     -> [(String, AST.SubProgBody)]
  genUnconsVectorFuns elemTM vectorTM  = 
-   [ AST.SubProgBody exSpec      []                  [exExpr]                    
-   , AST.SubProgBody replaceSpec [AST.SPVD replaceVar] [replaceExpr,replaceRet]   
-   , AST.SubProgBody headSpec    []                  [headExpr]                  
-   , AST.SubProgBody lastSpec    []                  [lastExpr]                  
-   , AST.SubProgBody initSpec    [AST.SPVD initVar]  [initExpr, initRet]         
-   , AST.SubProgBody tailSpec    [AST.SPVD tailVar]  [tailExpr, tailRet]         
-   , AST.SubProgBody takeSpec    [AST.SPVD takeVar]  [takeExpr, takeRet]         
-   , AST.SubProgBody dropSpec    [AST.SPVD dropVar]  [dropExpr, dropRet]    
-   , AST.SubProgBody plusgtSpec  [AST.SPVD plusgtVar] [plusgtExpr, plusgtRet]
-   , AST.SubProgBody emptySpec   [AST.SPCD emptyVar] [emptyExpr]
-   , AST.SubProgBody singletonSpec [AST.SPVD singletonVar] [singletonRet] 
-   , AST.SubProgBody copySpec    [AST.SPVD copyVar]      [copyExpr]
+   [ (exId, AST.SubProgBody exSpec      []                  [exExpr])
+   , (replaceId, AST.SubProgBody replaceSpec [AST.SPVD replaceVar] [replaceExpr,replaceRet])
+   , (headId, AST.SubProgBody headSpec    []                  [headExpr])
+   , (lastId, AST.SubProgBody lastSpec    []                  [lastExpr])
+   , (initId, AST.SubProgBody initSpec    [AST.SPVD initVar]  [initExpr, initRet])
+   , (tailId, AST.SubProgBody tailSpec    [AST.SPVD tailVar]  [tailExpr, tailRet])
+   , (takeId, AST.SubProgBody takeSpec    [AST.SPVD takeVar]  [takeExpr, takeRet])
+   , (dropId, AST.SubProgBody dropSpec    [AST.SPVD dropVar]  [dropExpr, dropRet])
+   , (plusgtId, AST.SubProgBody plusgtSpec  [AST.SPVD plusgtVar] [plusgtExpr, plusgtRet])
 -  , (emptyId, AST.SubProgBody emptySpec   [AST.SPVD emptyVar] [emptyExpr])
++  , (emptyId, AST.SubProgBody emptySpec   [AST.SPCD emptyVar] [emptyExpr])
+   , (singletonId, AST.SubProgBody singletonSpec [AST.SPVD singletonVar] [singletonRet])
+   , (copyId, AST.SubProgBody copySpec    [AST.SPVD copyVar]      [copyExpr])
    ]
    where 
      ixPar   = AST.unsafeVHDLBasicId "ix"
      iPar    = iId
      aPar    = AST.unsafeVHDLBasicId "a"
      resId   = AST.unsafeVHDLBasicId "res"
-     exSpec = AST.Function exId [AST.IfaceVarDec vecPar vectorTM,
+     exSpec = AST.Function (mkVHDLExtId exId) [AST.IfaceVarDec vecPar vectorTM,
                                 AST.IfaceVarDec ixPar  naturalTM] elemTM
      exExpr = AST.ReturnSm (Just $ AST.PrimName $ AST.NIndexed 
                (AST.IndexedName (AST.NSimple vecPar) [AST.PrimName $ 
                  AST.NSimple ixPar]))
-     replaceSpec = AST.Function replaceId  [ AST.IfaceVarDec vecPar vectorTM
+     replaceSpec = AST.Function (mkVHDLExtId replaceId)  [ AST.IfaceVarDec vecPar vectorTM
                                            , AST.IfaceVarDec iPar   naturalTM
                                            , AST.IfaceVarDec aPar   elemTM
                                            ] vectorTM 
                    (Just $ AST.ConstraintIndex $ AST.IndexConstraint 
                     [AST.ToRange (AST.PrimLit "0")
                              (AST.PrimName (AST.NAttribute $ 
-                               AST.AttribName (AST.NSimple vecPar) lengthId Nothing) AST.:-:
+                               AST.AttribName (AST.NSimple vecPar) (mkVHDLExtId lengthId) Nothing) AST.:-:
                                  (AST.PrimLit "1"))   ]))
                  Nothing
         --  res AST.:= vec(0 to i-1) & a & vec(i+1 to length'vec-1)
              AST.PrimName (AST.NSimple aPar) AST.:&: 
               vecSlice (AST.PrimName (AST.NSimple iPar) AST.:+: AST.PrimLit "1")
                        ((AST.PrimName (AST.NAttribute $ 
-                                 AST.AttribName (AST.NSimple vecPar) lengthId Nothing)) 
+                                 AST.AttribName (AST.NSimple vecPar) (mkVHDLExtId lengthId) Nothing)) 
                                                                AST.:-: AST.PrimLit "1"))
      replaceRet =  AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
      vecSlice init last =  AST.PrimName (AST.NSlice 
                                          (AST.SliceName 
                                                (AST.NSimple vecPar) 
                                                (AST.ToRange init last)))
-     headSpec = AST.Function headId [AST.IfaceVarDec vecPar vectorTM] elemTM
+     headSpec = AST.Function (mkVHDLExtId headId) [AST.IfaceVarDec vecPar vectorTM] elemTM
         -- return vec(0);
      headExpr = AST.ReturnSm (Just $ (AST.PrimName $ AST.NIndexed (AST.IndexedName 
                      (AST.NSimple vecPar) [AST.PrimLit "0"])))
-     lastSpec = AST.Function lastId [AST.IfaceVarDec vecPar vectorTM] elemTM
+     lastSpec = AST.Function (mkVHDLExtId lastId) [AST.IfaceVarDec vecPar vectorTM] elemTM
         -- return vec(vec'length-1);
      lastExpr = AST.ReturnSm (Just $ (AST.PrimName $ AST.NIndexed (AST.IndexedName 
                      (AST.NSimple vecPar) 
                      [AST.PrimName (AST.NAttribute $ 
-                                 AST.AttribName (AST.NSimple vecPar) lengthId Nothing) 
+                                 AST.AttribName (AST.NSimple vecPar) (mkVHDLExtId lengthId) Nothing) 
                                                               AST.:-: AST.PrimLit "1"])))
-     initSpec = AST.Function initId [AST.IfaceVarDec vecPar vectorTM] vectorTM 
+     initSpec = AST.Function (mkVHDLExtId initId) [AST.IfaceVarDec vecPar vectorTM] vectorTM 
         -- variable res : fsvec_x (0 to vec'length-2);
      initVar = 
           AST.VarDec resId 
                    (Just $ AST.ConstraintIndex $ AST.IndexConstraint 
                     [AST.ToRange (AST.PrimLit "0")
                              (AST.PrimName (AST.NAttribute $ 
-                               AST.AttribName (AST.NSimple vecPar) lengthId Nothing) AST.:-:
+                               AST.AttribName (AST.NSimple vecPar) (mkVHDLExtId lengthId) Nothing) AST.:-:
                                  (AST.PrimLit "2"))   ]))
                  Nothing
         -- resAST.:= vec(0 to vec'length-2)
      initExpr = AST.NSimple resId AST.:= (vecSlice 
                                 (AST.PrimLit "0") 
                                 (AST.PrimName (AST.NAttribute $ 
-                                   AST.AttribName (AST.NSimple vecPar) lengthId Nothing) 
+                                   AST.AttribName (AST.NSimple vecPar) (mkVHDLExtId lengthId) Nothing) 
                                                               AST.:-: AST.PrimLit "2"))
      initRet =  AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
-     tailSpec = AST.Function tailId [AST.IfaceVarDec vecPar vectorTM] vectorTM
+     tailSpec = AST.Function (mkVHDLExtId tailId) [AST.IfaceVarDec vecPar vectorTM] vectorTM
         -- variable res : fsvec_x (0 to vec'length-2); 
      tailVar = 
           AST.VarDec resId 
                    (Just $ AST.ConstraintIndex $ AST.IndexConstraint 
                     [AST.ToRange (AST.PrimLit "0")
                              (AST.PrimName (AST.NAttribute $ 
-                               AST.AttribName (AST.NSimple vecPar) lengthId Nothing) AST.:-:
+                               AST.AttribName (AST.NSimple vecPar) (mkVHDLExtId lengthId) Nothing) AST.:-:
                                  (AST.PrimLit "2"))   ]))
                  Nothing       
         -- res AST.:= vec(1 to vec'length-1)
      tailExpr = AST.NSimple resId AST.:= (vecSlice 
                                 (AST.PrimLit "1") 
                                 (AST.PrimName (AST.NAttribute $ 
-                                   AST.AttribName (AST.NSimple vecPar) lengthId Nothing) 
+                                   AST.AttribName (AST.NSimple vecPar) (mkVHDLExtId lengthId) Nothing) 
                                                               AST.:-: AST.PrimLit "1"))
      tailRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
-     takeSpec = AST.Function takeId [AST.IfaceVarDec nPar   naturalTM,
+     takeSpec = AST.Function (mkVHDLExtId takeId) [AST.IfaceVarDec nPar   naturalTM,
                                     AST.IfaceVarDec vecPar vectorTM ] vectorTM
         -- variable res : fsvec_x (0 to n-1);
      takeVar = 
                      (vecSlice (AST.PrimLit "1") 
                                (AST.PrimName (AST.NSimple $ nPar) AST.:-: AST.PrimLit "1"))
      takeRet =  AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
-     dropSpec = AST.Function dropId [AST.IfaceVarDec nPar   naturalTM,
+     dropSpec = AST.Function (mkVHDLExtId dropId) [AST.IfaceVarDec nPar   naturalTM,
                                     AST.IfaceVarDec vecPar vectorTM ] vectorTM 
         -- variable res : fsvec_x (0 to vec'length-n-1);
      dropVar = 
                    (Just $ AST.ConstraintIndex $ AST.IndexConstraint 
                     [AST.ToRange (AST.PrimLit "0")
                              (AST.PrimName (AST.NAttribute $ 
-                               AST.AttribName (AST.NSimple vecPar) lengthId Nothing) AST.:-:
+                               AST.AttribName (AST.NSimple vecPar) (mkVHDLExtId lengthId) Nothing) AST.:-:
                                 (AST.PrimName $ AST.NSimple nPar)AST.:-: (AST.PrimLit "1")) ]))
                 Nothing
         -- res AST.:= vec(n to vec'length-1)
      dropExpr = AST.NSimple resId AST.:= (vecSlice 
                                 (AST.PrimName $ AST.NSimple nPar) 
                                 (AST.PrimName (AST.NAttribute $ 
-                                   AST.AttribName (AST.NSimple vecPar) lengthId Nothing) 
+                                   AST.AttribName (AST.NSimple vecPar) (mkVHDLExtId lengthId) Nothing) 
                                                               AST.:-: AST.PrimLit "1"))
      dropRet =  AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
-     plusgtSpec = AST.Function plusgtId [AST.IfaceVarDec aPar   elemTM,
+     plusgtSpec = AST.Function (mkVHDLExtId plusgtId) [AST.IfaceVarDec aPar   elemTM,
                                         AST.IfaceVarDec vecPar vectorTM] vectorTM 
      -- variable res : fsvec_x (0 to vec'length);
      plusgtVar = 
                 (Just $ AST.ConstraintIndex $ AST.IndexConstraint 
                  [AST.ToRange (AST.PrimLit "0")
                          (AST.PrimName (AST.NAttribute $ 
-                           AST.AttribName (AST.NSimple vecPar) lengthId Nothing))]))
+                           AST.AttribName (AST.NSimple vecPar) (mkVHDLExtId lengthId) Nothing))]))
               Nothing
      plusgtExpr = AST.NSimple resId AST.:= 
                     ((AST.PrimName $ AST.NSimple aPar) AST.:&: 
                      (AST.PrimName $ AST.NSimple vecPar))
      plusgtRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
-     emptySpec = AST.Function emptyId [] vectorTM
+     emptySpec = AST.Function (mkVHDLExtId emptyId) [] vectorTM
      emptyVar = 
 -          AST.VarDec resId 
 -              (AST.SubtypeIn vectorTM
 -                (Just $ AST.ConstraintIndex $ AST.IndexConstraint 
 -                 [AST.ToRange (AST.PrimLit "0")
 -                          (AST.PrimLit "-1")]))
 -              Nothing
 +          AST.ConstDec resId 
 +              (AST.SubtypeIn vectorTM Nothing)
 +              (Just $ AST.PrimLit "\"\"")
      emptyExpr = AST.ReturnSm (Just $ AST.PrimName (AST.NSimple resId))
-     singletonSpec = AST.Function singletonId [AST.IfaceVarDec aPar elemTM ] 
+     singletonSpec = AST.Function (mkVHDLExtId singletonId) [AST.IfaceVarDec aPar elemTM ] 
                                           vectorTM
      -- variable res : fsvec_x (0 to 0) := (others => a);
      singletonVar = 
               (Just $ AST.Aggregate [AST.ElemAssoc (Just AST.Others) 
                                            (AST.PrimName $ AST.NSimple aPar)])
      singletonRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
-     copySpec = AST.Function copyId [AST.IfaceVarDec nPar   naturalTM,
+     copySpec = AST.Function (mkVHDLExtId copyId) [AST.IfaceVarDec nPar   naturalTM,
                                     AST.IfaceVarDec aPar   elemTM   ] vectorTM 
      -- variable res : fsvec_x (0 to n-1) := (others => a);
      copyVar = 
diff --combined GlobalNameTable.hs
index aa7462890e94b15885a2fb3588b87894a96ff98b,dda018c7fc1a41a7dcba431e6e7805f865d24965..feea40170e750e69ec32390abda99bbaa33ed68d
@@@ -17,22 -17,21 +17,22 @@@ mkGlobalNameTable = Map.fromLis
  
  globalNameTable :: NameTable
  globalNameTable = mkGlobalNameTable
-   [ ("!"              , (2, Left $ genExprFCall exId                      ) )
-   , ("replace"        , (3, Left $ genExprFCall replaceId                 ) )
-   , ("head"           , (1, Left $ genExprFCall headId                    ) )
-   , ("last"           , (1, Left $ genExprFCall lastId                    ) )
-   , ("tail"           , (1, Left $ genExprFCall tailId                    ) )
-   , ("init"           , (1, Left $ genExprFCall initId                    ) )
-   , ("take"           , (2, Left $ genExprFCall takeId                    ) )
-   , ("drop"           , (2, Left $ genExprFCall dropId                    ) )
-   , ("+>"             , (2, Left $ genExprFCall plusgtId                  ) )
-   , ("map"            , (2, Right $ genMapCall                            ) )
-   , ("zipWith"        , (3, Right $ genZipWithCall                        ) )
-   , ("empty"          , (0, Left $ genExprFCall emptyId                   ) )
-   , ("singleton"      , (1, Left $ genExprFCall singletonId               ) )
-   , ("copy"           , (2, Left $ genExprFCall copyId                    ) )
-   , ("hwxor"          , (2, Left $ genExprOp2 AST.Xor                     ) )
-   , ("hwand"          , (2, Left $ genExprOp2 AST.And                     ) )
-   , ("hwor"           , (2, Left $ genExprOp2 AST.Or                      ) )
-   , ("hwnot"          , (1, Left $ genExprOp1 AST.Not                     ) )
+   [ (exId             , (2, Left $ genExprFCall exId                      ) )
+   , (replaceId        , (3, Left $ genExprFCall replaceId                 ) )
+   , (headId           , (1, Left $ genExprFCall headId                    ) )
+   , (lastId           , (1, Left $ genExprFCall lastId                    ) )
+   , (tailId           , (1, Left $ genExprFCall tailId                    ) )
+   , (initId           , (1, Left $ genExprFCall initId                    ) )
+   , (takeId           , (2, Left $ genExprFCall takeId                    ) )
+   , (dropId           , (2, Left $ genExprFCall dropId                    ) )
+   , (plusgtId         , (2, Left $ genExprFCall plusgtId                  ) )
+   , (mapId            , (2, Right $ genMapCall                            ) )
++  , (zipWithId        , (3, Right $ genZipWithCall                        ) )
+   , (emptyId          , (0, Left $ genExprFCall emptyId                   ) )
+   , (singletonId      , (1, Left $ genExprFCall singletonId               ) )
+   , (copyId           , (2, Left $ genExprFCall copyId                    ) )
+   , (hwxorId          , (2, Left $ genExprOp2 AST.Xor                     ) )
+   , (hwandId          , (2, Left $ genExprOp2 AST.And                     ) )
+   , (hworId           , (2, Left $ genExprOp2 AST.Or                      ) )
+   , (hwnotId          , (1, Left $ genExprOp1 AST.Not                     ) )
    ]