From: Christiaan Baaij Date: Thu, 25 Jun 2009 10:21:03 +0000 (+0200) Subject: Foldl correctly handles empty vectors X-Git-Url: https://git.stderr.nl/gitweb?a=commitdiff_plain;h=987505d217099fa2454e00f14db77d8776d9f2a5;p=matthijs%2Fmaster-project%2Fc%CE%BBash.git Foldl correctly handles empty vectors --- diff --git a/Generate.hs b/Generate.hs index 7b8dcf0..5aa5097 100644 --- a/Generate.hs +++ b/Generate.hs @@ -145,31 +145,36 @@ genFoldl' resVal f [folded_f, startVal, inVec] = do let vecty = Type.mkAppTy vec (Var.varType startVal) vecType <- vhdl_ty vecty -- Setup the generate scheme - let len = (tfvec_len . Var.varType) inVec - let genlabel = mkVHDLExtId ("foldlVector" ++ (varToString inVec)) - let blockLabel = mkVHDLExtId ("foldlVector" ++ (varToString startVal)) - let range = AST.ToRange (AST.PrimLit "0") (AST.PrimLit $ show (len-1)) - let genScheme = AST.ForGn (AST.unsafeVHDLBasicId "n") range + let len = (tfvec_len . Var.varType) inVec + let genlabel = mkVHDLExtId ("foldlVector" ++ (varToString inVec)) + let blockLabel = mkVHDLExtId ("foldlVector" ++ (varToString startVal)) + let range = AST.ToRange (AST.PrimLit "0") (AST.PrimLit $ show (len-1)) + let genScheme = AST.ForGn (AST.unsafeVHDLBasicId "n") range -- Make the intermediate vector - let tmpVec = AST.BDISD $ AST.SigDec (mkVHDLExtId "tmp") vecType Nothing + let tmpId = mkVHDLExtId "tmp" + let tmpVec = AST.BDISD $ AST.SigDec tmpId vecType Nothing -- Get the entity name and port names let entity_id = ent_id entity let argports = map (Monad.liftM fst) (ent_args entity) let resport = (Monad.liftM fst) (ent_res entity) + -- Generate the output assignment + let assign = [mkUncondAssign (Left resVal) (AST.PrimName (AST.NIndexed (AST.IndexedName + (AST.NSimple tmpId) [AST.PrimLit $ show (len-1)])))] -- Return the generate functions - let genSm = AST.GenerateSm genlabel genScheme [] + let genSm = AST.CSGSm $ AST.GenerateSm genlabel genScheme [] [ AST.CSGSm (genFirstCell (entity_id, argports, resport) [startVal, inVec, resVal]) , AST.CSGSm (genOtherCell (entity_id, argports, resport) [startVal, inVec, resVal]) - , AST.CSGSm (genLastCell (entity_id, argports, resport) - [startVal, inVec, resVal]) ] - return $ [AST.CSBSm $ AST.BlockSm blockLabel [] (AST.PMapAspect []) [tmpVec] [AST.CSGSm genSm]] + return $ if len > 0 then + [AST.CSBSm $ AST.BlockSm blockLabel [] (AST.PMapAspect []) [tmpVec] (genSm : assign)] + else + [mkUncondAssign (Left resVal) (AST.PrimName $ AST.NSimple (varToVHDLId startVal))] where genFirstCell (entity_id, argports, resport) [startVal, inVec, resVal] = cellGn where - cellLabel = mkVHDLExtId "firstcell" + cellLabel = mkVHDLExtId "firstcell" cellGenScheme = AST.IfGn ((AST.PrimName $ AST.NSimple nPar) AST.:=: (AST.PrimLit "0")) tmpId = mkVHDLExtId "tmp" nPar = AST.unsafeVHDLBasicId "n" @@ -186,9 +191,9 @@ genFoldl' resVal f [folded_f, startVal, inVec] = do genOtherCell (entity_id, argports, resport) [startVal, inVec, resVal] = cellGn where len = (tfvec_len . Var.varType) inVec - cellLabel = mkVHDLExtId "othercell" - cellGenScheme = AST.IfGn $ AST.And ((AST.PrimName $ AST.NSimple nPar) AST.:>: (AST.PrimLit "0")) - ((AST.PrimName $ AST.NSimple nPar) AST.:<: (AST.PrimLit $ show (len-1))) + cellLabel = mkVHDLExtId "othercell" + cellGenScheme = AST.IfGn ((AST.PrimName $ AST.NSimple nPar) AST.:/=: (AST.PrimLit "0")) + -- ((AST.PrimName $ AST.NSimple nPar) AST.:<: (AST.PrimLit $ show (len-1))) tmpId = mkVHDLExtId "tmp" nPar = AST.unsafeVHDLBasicId "n" -- Assign the ports @@ -201,27 +206,6 @@ genFoldl' resVal f [folded_f, startVal, inVec] = do compins = mkComponentInst mapLabel entity_id portassigns -- Return the generate functions cellGn = AST.GenerateSm cellLabel cellGenScheme [] [compins] - genLastCell (entity_id, argports, resport) [startVal, inVec, resVal] = cellGn - where - len = (tfvec_len . Var.varType) inVec - cellLabel = mkVHDLExtId "lastCell" - cellGenScheme = AST.IfGn ((AST.PrimName $ AST.NSimple nPar) AST.:=: (AST.PrimLit $ show (len-1))) - tmpId = mkVHDLExtId "tmp" - nPar = AST.unsafeVHDLBasicId "n" - -- Assign the ports - inport1 = mkAssocElemIndexed (argports!!0) tmpId (AST.unsafeVHDLBasicId "n-1") - inport2 = mkAssocElemIndexed (argports!!1) (varToVHDLId inVec) nPar - outport = mkAssocElemIndexed resport tmpId nPar - portassigns = Maybe.catMaybes [inport1,inport2,outport] - -- Generate the portmap - mapLabel = "cell" ++ (AST.fromVHDLId entity_id) - compins = mkComponentInst mapLabel entity_id portassigns - -- Generate the output assignment - assign = mkUncondAssign (Left resVal) (AST.PrimName (AST.NIndexed (AST.IndexedName - (AST.NSimple tmpId) [AST.PrimLit $ show (len-1)]))) - -- Return the generate functions - cellGn = AST.GenerateSm cellLabel cellGenScheme [] [compins,assign] - -- Returns the VHDLId of the vector function with the given name for the given -- element type. Generates -- this function if needed.