1 module CLasH.VHDL.Generate where
4 import qualified Data.List as List
5 import qualified Data.Map as Map
6 import qualified Control.Monad as Monad
8 import qualified Data.Either as Either
10 import Data.Accessor.MonadState as MonadState
14 import qualified Language.VHDL.AST as AST
17 import qualified CoreSyn
21 import qualified IdInfo
22 import qualified Literal
24 import qualified TyCon
27 import CLasH.Translator.TranslatorTypes
28 import CLasH.VHDL.Constants
29 import CLasH.VHDL.VHDLTypes
30 import CLasH.VHDL.VHDLTools
31 import qualified CLasH.Utils as Utils
32 import CLasH.Utils.Core.CoreTools
33 import CLasH.Utils.Pretty
34 import qualified CLasH.Normalize as Normalize
36 -----------------------------------------------------------------------------
37 -- Functions to generate VHDL for user-defined functions.
38 -----------------------------------------------------------------------------
40 -- | Create an entity for a given function
43 -> TranslatorSession Entity -- ^ The resulting entity
45 getEntity fname = Utils.makeCached fname tsEntities $ do
46 expr <- Normalize.getNormalized fname
47 -- Strip off lambda's, these will be arguments
48 let (args, letexpr) = CoreSyn.collectBinders expr
49 args' <- mapM mkMap args
50 -- There must be a let at top level
51 let (CoreSyn.Let binds (CoreSyn.Var res)) = letexpr
53 let vhdl_id = mkVHDLBasicId $ varToString fname ++ "_" ++ varToStringUniq fname
54 let ent_decl' = createEntityAST vhdl_id args' res'
55 let AST.EntityDec entity_id _ = ent_decl'
56 let signature = Entity entity_id args' res' ent_decl'
60 --[(SignalId, SignalInfo)]
62 -> TranslatorSession Port
65 --info = Maybe.fromMaybe
66 -- (error $ "Signal not found in the name map? This should not happen!")
68 -- Assume the bndr has a valid VHDL id already
71 error_msg = "\nVHDL.createEntity.mkMap: Can not create entity: " ++ pprString fname ++ "\nbecause no type can be created for port: " ++ pprString bndr
73 type_mark <- MonadState.lift tsType $ vhdl_ty error_msg ty
74 return (id, type_mark)
77 -- | Create the VHDL AST for an entity
79 AST.VHDLId -- ^ The name of the function
80 -> [Port] -- ^ The entity's arguments
81 -> Port -- ^ The entity's result
82 -> AST.EntityDec -- ^ The entity with the ent_decl filled in as well
84 createEntityAST vhdl_id args res =
85 AST.EntityDec vhdl_id ports
87 -- Create a basic Id, since VHDL doesn't grok filenames with extended Ids.
88 ports = map (mkIfaceSigDec AST.In) args
89 ++ [mkIfaceSigDec AST.Out res]
91 -- Add a clk port if we have state
92 clk_port = AST.IfaceSigDec clockId AST.In std_logicTM
94 -- | Create a port declaration
96 AST.Mode -- ^ The mode for the port (In / Out)
97 -> (AST.VHDLId, AST.TypeMark) -- ^ The id and type for the port
98 -> AST.IfaceSigDec -- ^ The resulting port declaration
100 mkIfaceSigDec mode (id, ty) = AST.IfaceSigDec id mode ty
102 -- | Create an architecture for a given function
104 CoreSyn.CoreBndr -- ^ The function to get an architecture for
105 -> TranslatorSession (Architecture, [CoreSyn.CoreBndr])
106 -- ^ The architecture for this function
108 getArchitecture fname = Utils.makeCached fname tsArchitectures $ do
109 expr <- Normalize.getNormalized fname
110 signature <- getEntity fname
111 let entity_id = ent_id signature
112 -- Strip off lambda's, these will be arguments
113 let (args, letexpr) = CoreSyn.collectBinders expr
114 -- There must be a let at top level
115 let (CoreSyn.Let (CoreSyn.Rec binds) (CoreSyn.Var res)) = letexpr
117 -- Create signal declarations for all binders in the let expression, except
118 -- for the output port (that will already have an output port declared in
120 sig_dec_maybes <- mapM (mkSigDec' . fst) (filter ((/=res).fst) binds)
121 let sig_decs = Maybe.catMaybes $ sig_dec_maybes
123 (statementss, used_entitiess) <- Monad.mapAndUnzipM mkConcSm binds
124 let statements = concat statementss
125 let used_entities = concat used_entitiess
126 let arch = AST.ArchBody (mkVHDLBasicId "structural") (AST.NSimple entity_id) (map AST.BDISD sig_decs) (statements ++ procs')
127 return (arch, used_entities)
129 procs = [] --map mkStateProcSm [] -- (makeStatePairs flatfunc)
130 procs' = map AST.CSPSm procs
131 -- mkSigDec only uses tsTypes from the state
134 -- | Transforms a core binding into a VHDL concurrent statement
136 (CoreSyn.CoreBndr, CoreSyn.CoreExpr) -- ^ The binding to process
137 -> TranslatorSession ([AST.ConcSm], [CoreSyn.CoreBndr])
138 -- ^ The corresponding VHDL concurrent statements and entities
142 -- Ignore Cast expressions, they should not longer have any meaning as long as
143 -- the type works out.
144 mkConcSm (bndr, CoreSyn.Cast expr ty) = mkConcSm (bndr, expr)
146 -- Simple a = b assignments are just like applications, but without arguments.
147 -- We can't just generate an unconditional assignment here, since b might be a
148 -- top level binding (e.g., a function with no arguments).
149 mkConcSm (bndr, CoreSyn.Var v) = do
150 genApplication (Left bndr) v []
152 mkConcSm (bndr, app@(CoreSyn.App _ _))= do
153 let (CoreSyn.Var f, args) = CoreSyn.collectArgs app
154 let valargs = get_val_args (Var.varType f) args
155 genApplication (Left bndr) f (map Left valargs)
157 -- A single alt case must be a selector. This means thee scrutinee is a simple
158 -- variable, the alternative is a dataalt with a single non-wild binder that
160 mkConcSm (bndr, expr@(CoreSyn.Case (CoreSyn.Var scrut) b ty [alt])) =
162 (CoreSyn.DataAlt dc, bndrs, (CoreSyn.Var sel_bndr)) -> do
163 case List.elemIndex sel_bndr bndrs of
165 labels <- MonadState.lift tsType $ getFieldLabels (Id.idType scrut)
166 let label = labels!!i
167 let sel_name = mkSelectedName (varToVHDLName scrut) label
168 let sel_expr = AST.PrimName sel_name
169 return ([mkUncondAssign (Left bndr) sel_expr], [])
170 Nothing -> error $ "\nVHDL.mkConcSM: Not in normal form: Not a selector case:\n" ++ (pprString expr)
172 _ -> error $ "\nVHDL.mkConcSM: Not in normal form: Not a selector case:\n" ++ (pprString expr)
174 -- Multiple case alt are be conditional assignments and have only wild
175 -- binders in the alts and only variables in the case values and a variable
176 -- for a scrutinee. We check the constructor of the second alt, since the
177 -- first is the default case, if there is any.
178 mkConcSm (bndr, (CoreSyn.Case (CoreSyn.Var scrut) b ty [(_, _, CoreSyn.Var false), (con, _, CoreSyn.Var true)])) = do
179 scrut' <- MonadState.lift tsType $ varToVHDLExpr scrut
180 let cond_expr = scrut' AST.:=: (altconToVHDLExpr con)
181 true_expr <- MonadState.lift tsType $ varToVHDLExpr true
182 false_expr <- MonadState.lift tsType $ varToVHDLExpr false
183 return ([mkCondAssign (Left bndr) cond_expr true_expr false_expr], [])
185 mkConcSm (_, (CoreSyn.Case (CoreSyn.Var _) _ _ alts)) = error "\nVHDL.mkConcSm: Not in normal form: Case statement with more than two alternatives"
186 mkConcSm (_, CoreSyn.Case _ _ _ _) = error "\nVHDL.mkConcSm: Not in normal form: Case statement has does not have a simple variable as scrutinee"
187 mkConcSm (bndr, expr) = error $ "\nVHDL.mkConcSM: Unsupported binding in let expression: " ++ pprString bndr ++ " = " ++ pprString expr
189 -----------------------------------------------------------------------------
190 -- Functions to generate VHDL for builtin functions
191 -----------------------------------------------------------------------------
193 -- | A function to wrap a builder-like function that expects its arguments to
195 genExprArgs wrap dst func args = do
196 args' <- eitherCoreOrExprArgs args
199 eitherCoreOrExprArgs :: [Either CoreSyn.CoreExpr AST.Expr] -> TranslatorSession [AST.Expr]
200 eitherCoreOrExprArgs args = mapM (Either.either ((MonadState.lift tsType) . varToVHDLExpr . exprToVar) return) args
202 -- A function to wrap a builder-like function that generates no component
205 (dst -> func -> args -> TranslatorSession [AST.ConcSm])
206 -> (dst -> func -> args -> TranslatorSession ([AST.ConcSm], [CoreSyn.CoreBndr]))
207 genNoInsts wrap dst func args = do
208 concsms <- wrap dst func args
211 -- | A function to wrap a builder-like function that expects its arguments to
214 (dst -> func -> [Var.Var] -> res)
215 -> (dst -> func -> [Either CoreSyn.CoreExpr AST.Expr] -> res)
216 genVarArgs wrap dst func args = wrap dst func args'
218 args' = map exprToVar exprargs
219 -- Check (rather crudely) that all arguments are CoreExprs
220 (exprargs, []) = Either.partitionEithers args
222 -- | A function to wrap a builder-like function that expects its arguments to
225 (dst -> func -> [Literal.Literal] -> res)
226 -> (dst -> func -> [Either CoreSyn.CoreExpr AST.Expr] -> res)
227 genLitArgs wrap dst func args = wrap dst func args'
229 args' = map exprToLit litargs
230 -- FIXME: Check if we were passed an CoreSyn.App
231 litargs = concat (map getLiterals exprargs)
232 (exprargs, []) = Either.partitionEithers args
234 -- | A function to wrap a builder-like function that produces an expression
235 -- and expects it to be assigned to the destination.
237 ((Either CoreSyn.CoreBndr AST.VHDLName) -> func -> [arg] -> TranslatorSession AST.Expr)
238 -> ((Either CoreSyn.CoreBndr AST.VHDLName) -> func -> [arg] -> TranslatorSession [AST.ConcSm])
239 genExprRes wrap dst func args = do
240 expr <- wrap dst func args
241 return $ [mkUncondAssign dst expr]
243 -- | Generate a binary operator application. The first argument should be a
244 -- constructor from the AST.Expr type, e.g. AST.And.
245 genOperator2 :: (AST.Expr -> AST.Expr -> AST.Expr) -> BuiltinBuilder
246 genOperator2 op = genNoInsts $ genExprArgs $ genExprRes (genOperator2' op)
247 genOperator2' :: (AST.Expr -> AST.Expr -> AST.Expr) -> dst -> CoreSyn.CoreBndr -> [AST.Expr] -> TranslatorSession AST.Expr
248 genOperator2' op _ f [arg1, arg2] = return $ op arg1 arg2
250 -- | Generate a unary operator application
251 genOperator1 :: (AST.Expr -> AST.Expr) -> BuiltinBuilder
252 genOperator1 op = genNoInsts $ genExprArgs $ genExprRes (genOperator1' op)
253 genOperator1' :: (AST.Expr -> AST.Expr) -> dst -> CoreSyn.CoreBndr -> [AST.Expr] -> TranslatorSession AST.Expr
254 genOperator1' op _ f [arg] = return $ op arg
256 -- | Generate a unary operator application
257 genNegation :: BuiltinBuilder
258 genNegation = genNoInsts $ genVarArgs $ genExprRes genNegation'
259 genNegation' :: dst -> CoreSyn.CoreBndr -> [Var.Var] -> TranslatorSession AST.Expr
260 genNegation' _ f [arg] = do
261 arg1 <- MonadState.lift tsType $ varToVHDLExpr arg
262 let ty = Var.varType arg
263 let (tycon, args) = Type.splitTyConApp ty
264 let name = Name.getOccString (TyCon.tyConName tycon)
266 "SizedInt" -> return $ AST.Neg arg1
267 otherwise -> error $ "\nGenerate.genNegation': Negation allowed for type: " ++ show name
269 -- | Generate a function call from the destination binder, function name and a
270 -- list of expressions (its arguments)
271 genFCall :: Bool -> BuiltinBuilder
272 genFCall switch = genNoInsts $ genExprArgs $ genExprRes (genFCall' switch)
273 genFCall' :: Bool -> Either CoreSyn.CoreBndr AST.VHDLName -> CoreSyn.CoreBndr -> [AST.Expr] -> TranslatorSession AST.Expr
274 genFCall' switch (Left res) f args = do
275 let fname = varToString f
276 let el_ty = if switch then (Var.varType res) else ((tfvec_elem . Var.varType) res)
277 id <- MonadState.lift tsType $ vectorFunId el_ty fname
278 return $ AST.PrimFCall $ AST.FCall (AST.NSimple id) $
279 map (\exp -> Nothing AST.:=>: AST.ADExpr exp) args
280 genFCall' _ (Right name) _ _ = error $ "\nGenerate.genFCall': Cannot generate builtin function call assigned to a VHDLName: " ++ show name
282 genFromSizedWord :: BuiltinBuilder
283 genFromSizedWord = genNoInsts $ genExprArgs $ genExprRes genFromSizedWord'
284 genFromSizedWord' :: Either CoreSyn.CoreBndr AST.VHDLName -> CoreSyn.CoreBndr -> [AST.Expr] -> TranslatorSession AST.Expr
285 genFromSizedWord' (Left res) f args = do
286 let fname = varToString f
287 return $ AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLBasicId toIntegerId)) $
288 map (\exp -> Nothing AST.:=>: AST.ADExpr exp) args
289 genFromSizedWord' (Right name) _ _ = error $ "\nGenerate.genFromSizedWord': Cannot generate builtin function call assigned to a VHDLName: " ++ show name
291 genResize :: BuiltinBuilder
292 genResize = genNoInsts $ genExprArgs $ genExprRes genResize'
293 genResize' :: Either CoreSyn.CoreBndr AST.VHDLName -> CoreSyn.CoreBndr -> [AST.Expr] -> TranslatorSession AST.Expr
294 genResize' (Left res) f [arg] = do {
295 ; let { ty = Var.varType res
296 ; (tycon, args) = Type.splitTyConApp ty
297 ; name = Name.getOccString (TyCon.tyConName tycon)
299 ; len <- case name of
300 "SizedInt" -> MonadState.lift tsType $ tfp_to_int (sized_int_len_ty ty)
301 "SizedWord" -> MonadState.lift tsType $ tfp_to_int (sized_word_len_ty ty)
302 ; return $ AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLBasicId resizeId))
303 [Nothing AST.:=>: AST.ADExpr arg, Nothing AST.:=>: AST.ADExpr( AST.PrimLit (show len))]
305 genResize' (Right name) _ _ = error $ "\nGenerate.genFromSizedWord': Cannot generate builtin function call assigned to a VHDLName: " ++ show name
307 -- FIXME: I'm calling genLitArgs which is very specific function,
308 -- which needs to be fixed as well
309 genFromInteger :: BuiltinBuilder
310 genFromInteger = genNoInsts $ genLitArgs $ genExprRes genFromInteger'
311 genFromInteger' :: Either CoreSyn.CoreBndr AST.VHDLName -> CoreSyn.CoreBndr -> [Literal.Literal] -> TranslatorSession AST.Expr
312 genFromInteger' (Left res) f lits = do {
313 ; let { ty = Var.varType res
314 ; (tycon, args) = Type.splitTyConApp ty
315 ; name = Name.getOccString (TyCon.tyConName tycon)
317 ; len <- case name of
318 "SizedInt" -> MonadState.lift tsType $ tfp_to_int (sized_int_len_ty ty)
319 "SizedWord" -> MonadState.lift tsType $ tfp_to_int (sized_word_len_ty ty)
320 ; let fname = case name of "SizedInt" -> toSignedId ; "SizedWord" -> toUnsignedId
321 ; return $ AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLBasicId fname))
322 [Nothing AST.:=>: AST.ADExpr (AST.PrimLit (show (last lits))), Nothing AST.:=>: AST.ADExpr( AST.PrimLit (show len))]
325 genFromInteger' (Right name) _ _ = error $ "\nGenerate.genFromInteger': Cannot generate builtin function call assigned to a VHDLName: " ++ show name
327 genSizedInt :: BuiltinBuilder
328 genSizedInt = genFromInteger
331 -- | Generate a Builder for the builtin datacon TFVec
332 genTFVec :: BuiltinBuilder
333 genTFVec (Left res) f [Left (CoreSyn.Let (CoreSyn.Rec letBinders) letRes)] = do {
334 -- Generate Assignments for all the binders
335 ; letAssigns <- mapM genBinderAssign letBinders
336 -- Generate assignments for the result (which might be another let binding)
337 ; (resBinders,resAssignments) <- genResAssign letRes
338 -- Get all the Assigned binders
339 ; let assignedBinders = Maybe.catMaybes (map fst letAssigns)
340 -- Make signal names for all the assigned binders
341 ; sigs <- mapM (\x -> MonadState.lift tsType $ varToVHDLExpr x) (assignedBinders ++ resBinders)
342 -- Assign all the signals to the resulting vector
343 ; let { vecsigns = mkAggregateSignal sigs
344 ; vecassign = mkUncondAssign (Left res) vecsigns
346 -- Generate all the signal declaration for the assigned binders
347 ; sig_dec_maybes <- mapM mkSigDec (assignedBinders ++ resBinders)
348 ; let { sig_decs = map (AST.BDISD) (Maybe.catMaybes $ sig_dec_maybes)
349 -- Setup the VHDL Block
350 ; block_label = mkVHDLExtId ("TFVec_" ++ show (varToString res))
351 ; block = AST.BlockSm block_label [] (AST.PMapAspect []) sig_decs ((concat (map snd letAssigns)) ++ resAssignments ++ [vecassign])
353 -- Return the block statement coressponding to the TFVec literal
354 ; return $ [AST.CSBSm block]
357 genBinderAssign :: (CoreSyn.CoreBndr, CoreSyn.CoreExpr) -> TranslatorSession (Maybe CoreSyn.CoreBndr, [AST.ConcSm])
358 -- For now we only translate applications
359 genBinderAssign (bndr, app@(CoreSyn.App _ _)) = do
360 let (CoreSyn.Var f, args) = CoreSyn.collectArgs app
361 let valargs = get_val_args (Var.varType f) args
362 apps <- genApplication (Left bndr) f (map Left valargs)
363 return (Just bndr, apps)
364 genBinderAssign _ = return (Nothing,[])
365 genResAssign :: CoreSyn.CoreExpr -> TranslatorSession ([CoreSyn.CoreBndr], [AST.ConcSm])
366 genResAssign app@(CoreSyn.App _ letexpr) = do
368 (CoreSyn.Let (CoreSyn.Rec letbndrs) letres) -> do
369 letapps <- mapM genBinderAssign letbndrs
370 let bndrs = Maybe.catMaybes (map fst letapps)
371 let app = (map snd letapps)
372 (vars, apps) <- genResAssign letres
373 return ((bndrs ++ vars),((concat app) ++ apps))
374 otherwise -> return ([],[])
375 genResAssign _ = return ([],[])
377 genTFVec (Left res) f [Left app@(CoreSyn.App _ _)] = do {
378 ; let { elems = reduceCoreListToHsList app
379 -- Make signal names for all the binders
380 ; binders = map (\expr -> case expr of
382 otherwise -> error $ "\nGenerate.genTFVec: Cannot generate TFVec: "
383 ++ show res ++ ", with elems:\n" ++ show elems ++ "\n" ++ pprString elems) elems
385 ; sigs <- mapM (\x -> MonadState.lift tsType $ varToVHDLExpr x) binders
386 -- Assign all the signals to the resulting vector
387 ; let { vecsigns = mkAggregateSignal sigs
388 ; vecassign = mkUncondAssign (Left res) vecsigns
389 -- Setup the VHDL Block
390 ; block_label = mkVHDLExtId ("TFVec_" ++ show (varToString res))
391 ; block = AST.BlockSm block_label [] (AST.PMapAspect []) [] [vecassign]
393 -- Return the block statement coressponding to the TFVec literal
394 ; return $ [AST.CSBSm block]
397 genTFVec (Left name) _ [Left xs] = error $ "\nGenerate.genTFVec: Cannot generate TFVec: " ++ show name ++ ", with elems:\n" ++ show xs ++ "\n" ++ pprString xs
399 genTFVec (Right name) _ _ = error $ "\nGenerate.genTFVec: Cannot generate TFVec assigned to VHDLName: " ++ show name
401 -- | Generate a generate statement for the builtin function "map"
402 genMap :: BuiltinBuilder
403 genMap (Left res) f [Left mapped_f, Left (CoreSyn.Var arg)] = do {
404 -- mapped_f must be a CoreExpr (since we can't represent functions as VHDL
405 -- expressions). arg must be a CoreExpr (and should be a CoreSyn.Var), since
406 -- we must index it (which we couldn't if it was a VHDL Expr, since only
407 -- VHDLNames can be indexed).
408 -- Setup the generate scheme
409 ; len <- MonadState.lift tsType $ tfp_to_int $ (tfvec_len_ty . Var.varType) res
410 -- TODO: Use something better than varToString
411 ; let { label = mkVHDLExtId ("mapVector" ++ (varToString res))
412 ; n_id = mkVHDLBasicId "n"
413 ; n_expr = idToVHDLExpr n_id
414 ; range = AST.ToRange (AST.PrimLit "0") (AST.PrimLit $ show (len-1))
415 ; genScheme = AST.ForGn n_id range
416 -- Create the content of the generate statement: Applying the mapped_f to
417 -- each of the elements in arg, storing to each element in res
418 ; resname = mkIndexedName (varToVHDLName res) n_expr
419 ; argexpr = vhdlNameToVHDLExpr $ mkIndexedName (varToVHDLName arg) n_expr
420 ; (CoreSyn.Var real_f, already_mapped_args) = CoreSyn.collectArgs mapped_f
421 ; valargs = get_val_args (Var.varType real_f) already_mapped_args
423 ; (app_concsms, used) <- genApplication (Right resname) real_f (map Left valargs ++ [Right argexpr])
424 -- Return the generate statement
425 ; return ([AST.CSGSm $ AST.GenerateSm label genScheme [] app_concsms], used)
428 genMap' (Right name) _ _ = error $ "\nGenerate.genMap': Cannot generate map function call assigned to a VHDLName: " ++ show name
430 genZipWith :: BuiltinBuilder
431 genZipWith = genVarArgs genZipWith'
432 genZipWith' :: (Either CoreSyn.CoreBndr AST.VHDLName) -> CoreSyn.CoreBndr -> [Var.Var] -> TranslatorSession ([AST.ConcSm], [CoreSyn.CoreBndr])
433 genZipWith' (Left res) f args@[zipped_f, arg1, arg2] = do {
434 -- Setup the generate scheme
435 ; len <- MonadState.lift tsType $ tfp_to_int $ (tfvec_len_ty . Var.varType) res
436 -- TODO: Use something better than varToString
437 ; let { label = mkVHDLExtId ("zipWithVector" ++ (varToString res))
438 ; n_id = mkVHDLBasicId "n"
439 ; n_expr = idToVHDLExpr n_id
440 ; range = AST.ToRange (AST.PrimLit "0") (AST.PrimLit $ show (len-1))
441 ; genScheme = AST.ForGn n_id range
442 -- Create the content of the generate statement: Applying the zipped_f to
443 -- each of the elements in arg1 and arg2, storing to each element in res
444 ; resname = mkIndexedName (varToVHDLName res) n_expr
445 ; argexpr1 = vhdlNameToVHDLExpr $ mkIndexedName (varToVHDLName arg1) n_expr
446 ; argexpr2 = vhdlNameToVHDLExpr $ mkIndexedName (varToVHDLName arg2) n_expr
448 ; (app_concsms, used) <- genApplication (Right resname) zipped_f [Right argexpr1, Right argexpr2]
449 -- Return the generate functions
450 ; return ([AST.CSGSm $ AST.GenerateSm label genScheme [] app_concsms], used)
453 genFoldl :: BuiltinBuilder
454 genFoldl = genFold True
456 genFoldr :: BuiltinBuilder
457 genFoldr = genFold False
459 genFold :: Bool -> BuiltinBuilder
460 genFold left = genVarArgs (genFold' left)
462 genFold' :: Bool -> (Either CoreSyn.CoreBndr AST.VHDLName) -> CoreSyn.CoreBndr -> [Var.Var] -> TranslatorSession ([AST.ConcSm], [CoreSyn.CoreBndr])
463 genFold' left res f args@[folded_f , start ,vec]= do
464 len <- MonadState.lift tsType $ tfp_to_int $ (tfvec_len_ty (Var.varType vec))
465 genFold'' len left res f args
467 genFold'' :: Int -> Bool -> (Either CoreSyn.CoreBndr AST.VHDLName) -> CoreSyn.CoreBndr -> [Var.Var] -> TranslatorSession ([AST.ConcSm], [CoreSyn.CoreBndr])
468 -- Special case for an empty input vector, just assign start to res
469 genFold'' len left (Left res) _ [_, start, vec] | len == 0 = do
470 arg <- MonadState.lift tsType $ varToVHDLExpr start
471 return ([mkUncondAssign (Left res) arg], [])
473 genFold'' len left (Left res) f [folded_f, start, vec] = do
475 --len <- MonadState.lift tsType $ tfp_to_int $ (tfvec_len_ty . Var.varType) vec
476 -- An expression for len-1
477 let len_min_expr = (AST.PrimLit $ show (len-1))
478 -- evec is (TFVec n), so it still needs an element type
479 let (nvec, _) = Type.splitAppTy (Var.varType vec)
480 -- Put the type of the start value in nvec, this will be the type of our
482 let tmp_ty = Type.mkAppTy nvec (Var.varType start)
483 let error_msg = "\nGenerate.genFold': Can not construct temp vector for element type: " ++ pprString tmp_ty
484 tmp_vhdl_ty <- MonadState.lift tsType $ vhdl_ty error_msg tmp_ty
485 -- Setup the generate scheme
486 let gen_label = mkVHDLExtId ("foldlVector" ++ (varToString vec))
487 let block_label = mkVHDLExtId ("foldlVector" ++ (varToString res))
488 let gen_range = if left then AST.ToRange (AST.PrimLit "0") len_min_expr
489 else AST.DownRange len_min_expr (AST.PrimLit "0")
490 let gen_scheme = AST.ForGn n_id gen_range
491 -- Make the intermediate vector
492 let tmp_dec = AST.BDISD $ AST.SigDec tmp_id tmp_vhdl_ty Nothing
493 -- Create the generate statement
494 cells' <- sequence [genFirstCell, genOtherCell]
495 let (cells, useds) = unzip cells'
496 let gen_sm = AST.GenerateSm gen_label gen_scheme [] (map AST.CSGSm cells)
497 -- Assign tmp[len-1] or tmp[0] to res
498 let out_assign = mkUncondAssign (Left res) $ vhdlNameToVHDLExpr (if left then
499 (mkIndexedName tmp_name (AST.PrimLit $ show (len-1))) else
500 (mkIndexedName tmp_name (AST.PrimLit "0")))
501 let block = AST.BlockSm block_label [] (AST.PMapAspect []) [tmp_dec] [AST.CSGSm gen_sm, out_assign]
502 return ([AST.CSBSm block], concat useds)
504 -- An id for the counter
505 n_id = mkVHDLBasicId "n"
506 n_cur = idToVHDLExpr n_id
507 -- An expression for previous n
508 n_prev = if left then (n_cur AST.:-: (AST.PrimLit "1"))
509 else (n_cur AST.:+: (AST.PrimLit "1"))
510 -- An id for the tmp result vector
511 tmp_id = mkVHDLBasicId "tmp"
512 tmp_name = AST.NSimple tmp_id
513 -- Generate parts of the fold
514 genFirstCell, genOtherCell :: TranslatorSession (AST.GenerateSm, [CoreSyn.CoreBndr])
516 len <- MonadState.lift tsType $ tfp_to_int $ (tfvec_len_ty . Var.varType) vec
517 let cond_label = mkVHDLExtId "firstcell"
518 -- if n == 0 or n == len-1
519 let cond_scheme = AST.IfGn $ n_cur AST.:=: (if left then (AST.PrimLit "0")
520 else (AST.PrimLit $ show (len-1)))
521 -- Output to tmp[current n]
522 let resname = mkIndexedName tmp_name n_cur
524 argexpr1 <- MonadState.lift tsType $ varToVHDLExpr start
525 -- Input from vec[current n]
526 let argexpr2 = vhdlNameToVHDLExpr $ mkIndexedName (varToVHDLName vec) n_cur
527 (app_concsms, used) <- genApplication (Right resname) folded_f ( if left then
528 [Right argexpr1, Right argexpr2]
530 [Right argexpr2, Right argexpr1]
532 -- Return the conditional generate part
533 return $ (AST.GenerateSm cond_label cond_scheme [] app_concsms, used)
536 len <- MonadState.lift tsType $ tfp_to_int $ (tfvec_len_ty . Var.varType) vec
537 let cond_label = mkVHDLExtId "othercell"
538 -- if n > 0 or n < len-1
539 let cond_scheme = AST.IfGn $ n_cur AST.:/=: (if left then (AST.PrimLit "0")
540 else (AST.PrimLit $ show (len-1)))
541 -- Output to tmp[current n]
542 let resname = mkIndexedName tmp_name n_cur
543 -- Input from tmp[previous n]
544 let argexpr1 = vhdlNameToVHDLExpr $ mkIndexedName tmp_name n_prev
545 -- Input from vec[current n]
546 let argexpr2 = vhdlNameToVHDLExpr $ mkIndexedName (varToVHDLName vec) n_cur
547 (app_concsms, used) <- genApplication (Right resname) folded_f ( if left then
548 [Right argexpr1, Right argexpr2]
550 [Right argexpr2, Right argexpr1]
552 -- Return the conditional generate part
553 return $ (AST.GenerateSm cond_label cond_scheme [] app_concsms, used)
555 -- | Generate a generate statement for the builtin function "zip"
556 genZip :: BuiltinBuilder
557 genZip = genNoInsts $ genVarArgs genZip'
558 genZip' :: (Either CoreSyn.CoreBndr AST.VHDLName) -> CoreSyn.CoreBndr -> [Var.Var] -> TranslatorSession [AST.ConcSm]
559 genZip' (Left res) f args@[arg1, arg2] = do {
560 -- Setup the generate scheme
561 ; len <- MonadState.lift tsType $ tfp_to_int $ (tfvec_len_ty . Var.varType) res
562 -- TODO: Use something better than varToString
563 ; let { label = mkVHDLExtId ("zipVector" ++ (varToString res))
564 ; n_id = mkVHDLBasicId "n"
565 ; n_expr = idToVHDLExpr n_id
566 ; range = AST.ToRange (AST.PrimLit "0") (AST.PrimLit $ show (len-1))
567 ; genScheme = AST.ForGn n_id range
568 ; resname' = mkIndexedName (varToVHDLName res) n_expr
569 ; argexpr1 = vhdlNameToVHDLExpr $ mkIndexedName (varToVHDLName arg1) n_expr
570 ; argexpr2 = vhdlNameToVHDLExpr $ mkIndexedName (varToVHDLName arg2) n_expr
572 ; labels <- MonadState.lift tsType $ getFieldLabels (tfvec_elem (Var.varType res))
573 ; let { resnameA = mkSelectedName resname' (labels!!0)
574 ; resnameB = mkSelectedName resname' (labels!!1)
575 ; resA_assign = mkUncondAssign (Right resnameA) argexpr1
576 ; resB_assign = mkUncondAssign (Right resnameB) argexpr2
578 -- Return the generate functions
579 ; return [AST.CSGSm $ AST.GenerateSm label genScheme [] [resA_assign,resB_assign]]
582 -- | Generate a generate statement for the builtin function "unzip"
583 genUnzip :: BuiltinBuilder
584 genUnzip = genNoInsts $ genVarArgs genUnzip'
585 genUnzip' :: (Either CoreSyn.CoreBndr AST.VHDLName) -> CoreSyn.CoreBndr -> [Var.Var] -> TranslatorSession [AST.ConcSm]
586 genUnzip' (Left res) f args@[arg] = do {
587 -- Setup the generate scheme
588 ; len <- MonadState.lift tsType $ tfp_to_int $ (tfvec_len_ty . Var.varType) arg
589 -- TODO: Use something better than varToString
590 ; let { label = mkVHDLExtId ("unzipVector" ++ (varToString res))
591 ; n_id = mkVHDLBasicId "n"
592 ; n_expr = idToVHDLExpr n_id
593 ; range = AST.ToRange (AST.PrimLit "0") (AST.PrimLit $ show (len-1))
594 ; genScheme = AST.ForGn n_id range
595 ; resname' = varToVHDLName res
596 ; argexpr' = mkIndexedName (varToVHDLName arg) n_expr
598 ; reslabels <- MonadState.lift tsType $ getFieldLabels (Var.varType res)
599 ; arglabels <- MonadState.lift tsType $ getFieldLabels (tfvec_elem (Var.varType arg))
600 ; let { resnameA = mkIndexedName (mkSelectedName resname' (reslabels!!0)) n_expr
601 ; resnameB = mkIndexedName (mkSelectedName resname' (reslabels!!1)) n_expr
602 ; argexprA = vhdlNameToVHDLExpr $ mkSelectedName argexpr' (arglabels!!0)
603 ; argexprB = vhdlNameToVHDLExpr $ mkSelectedName argexpr' (arglabels!!1)
604 ; resA_assign = mkUncondAssign (Right resnameA) argexprA
605 ; resB_assign = mkUncondAssign (Right resnameB) argexprB
607 -- Return the generate functions
608 ; return [AST.CSGSm $ AST.GenerateSm label genScheme [] [resA_assign,resB_assign]]
611 genCopy :: BuiltinBuilder
612 genCopy = genNoInsts $ genVarArgs genCopy'
613 genCopy' :: (Either CoreSyn.CoreBndr AST.VHDLName ) -> CoreSyn.CoreBndr -> [Var.Var] -> TranslatorSession [AST.ConcSm]
614 genCopy' (Left res) f args@[arg] =
616 resExpr = AST.Aggregate [AST.ElemAssoc (Just AST.Others)
617 (AST.PrimName $ (varToVHDLName arg))]
618 out_assign = mkUncondAssign (Left res) resExpr
622 genConcat :: BuiltinBuilder
623 genConcat = genNoInsts $ genVarArgs genConcat'
624 genConcat' :: (Either CoreSyn.CoreBndr AST.VHDLName) -> CoreSyn.CoreBndr -> [Var.Var] -> TranslatorSession [AST.ConcSm]
625 genConcat' (Left res) f args@[arg] = do {
626 -- Setup the generate scheme
627 ; len1 <- MonadState.lift tsType $ tfp_to_int $ (tfvec_len_ty . Var.varType) arg
628 ; let (_, nvec) = Type.splitAppTy (Var.varType arg)
629 ; len2 <- MonadState.lift tsType $ tfp_to_int $ tfvec_len_ty nvec
630 -- TODO: Use something better than varToString
631 ; let { label = mkVHDLExtId ("concatVector" ++ (varToString res))
632 ; n_id = mkVHDLBasicId "n"
633 ; n_expr = idToVHDLExpr n_id
634 ; fromRange = n_expr AST.:*: (AST.PrimLit $ show len2)
635 ; genScheme = AST.ForGn n_id range
636 -- Create the content of the generate statement: Applying the mapped_f to
637 -- each of the elements in arg, storing to each element in res
638 ; toRange = (n_expr AST.:*: (AST.PrimLit $ show len2)) AST.:+: (AST.PrimLit $ show (len2-1))
639 ; range = AST.ToRange (AST.PrimLit "0") (AST.PrimLit $ show (len1-1))
640 ; resname = vecSlice fromRange toRange
641 ; argexpr = vhdlNameToVHDLExpr $ mkIndexedName (varToVHDLName arg) n_expr
642 ; out_assign = mkUncondAssign (Right resname) argexpr
644 -- Return the generate statement
645 ; return [AST.CSGSm $ AST.GenerateSm label genScheme [] [out_assign]]
648 vecSlice init last = AST.NSlice (AST.SliceName (varToVHDLName res)
649 (AST.ToRange init last))
651 genIteraten :: BuiltinBuilder
652 genIteraten dst f args = genIterate dst f (tail args)
654 genIterate :: BuiltinBuilder
655 genIterate = genIterateOrGenerate True
657 genGeneraten :: BuiltinBuilder
658 genGeneraten dst f args = genGenerate dst f (tail args)
660 genGenerate :: BuiltinBuilder
661 genGenerate = genIterateOrGenerate False
663 genIterateOrGenerate :: Bool -> BuiltinBuilder
664 genIterateOrGenerate iter = genVarArgs (genIterateOrGenerate' iter)
666 genIterateOrGenerate' :: Bool -> (Either CoreSyn.CoreBndr AST.VHDLName) -> CoreSyn.CoreBndr -> [Var.Var] -> TranslatorSession ([AST.ConcSm], [CoreSyn.CoreBndr])
667 genIterateOrGenerate' iter (Left res) f args = do
668 len <- MonadState.lift tsType $ tfp_to_int ((tfvec_len_ty . Var.varType) res)
669 genIterateOrGenerate'' len iter (Left res) f args
671 genIterateOrGenerate'' :: Int -> Bool -> (Either CoreSyn.CoreBndr AST.VHDLName) -> CoreSyn.CoreBndr -> [Var.Var] -> TranslatorSession ([AST.ConcSm], [CoreSyn.CoreBndr])
672 -- Special case for an empty input vector, just assign start to res
673 genIterateOrGenerate'' len iter (Left res) _ [app_f, start] | len == 0 = return ([mkUncondAssign (Left res) (AST.PrimLit "\"\"")], [])
675 genIterateOrGenerate'' len iter (Left res) f [app_f, start] = do
677 -- len <- MonadState.lift tsType $ tfp_to_int ((tfvec_len_ty . Var.varType) res)
678 -- An expression for len-1
679 let len_min_expr = (AST.PrimLit $ show (len-1))
680 -- -- evec is (TFVec n), so it still needs an element type
681 -- let (nvec, _) = splitAppTy (Var.varType vec)
682 -- -- Put the type of the start value in nvec, this will be the type of our
683 -- -- temporary vector
684 let tmp_ty = Var.varType res
685 let error_msg = "\nGenerate.genFold': Can not construct temp vector for element type: " ++ pprString tmp_ty
686 tmp_vhdl_ty <- MonadState.lift tsType $ vhdl_ty error_msg tmp_ty
687 -- Setup the generate scheme
688 let gen_label = mkVHDLExtId ("iterateVector" ++ (varToString start))
689 let block_label = mkVHDLExtId ("iterateVector" ++ (varToString res))
690 let gen_range = AST.ToRange (AST.PrimLit "0") len_min_expr
691 let gen_scheme = AST.ForGn n_id gen_range
692 -- Make the intermediate vector
693 let tmp_dec = AST.BDISD $ AST.SigDec tmp_id tmp_vhdl_ty Nothing
694 -- Create the generate statement
695 cells' <- sequence [genFirstCell, genOtherCell]
696 let (cells, useds) = unzip cells'
697 let gen_sm = AST.GenerateSm gen_label gen_scheme [] (map AST.CSGSm cells)
698 -- Assign tmp[len-1] or tmp[0] to res
699 let out_assign = mkUncondAssign (Left res) $ vhdlNameToVHDLExpr tmp_name
700 let block = AST.BlockSm block_label [] (AST.PMapAspect []) [tmp_dec] [AST.CSGSm gen_sm, out_assign]
701 return ([AST.CSBSm block], concat useds)
703 -- An id for the counter
704 n_id = mkVHDLBasicId "n"
705 n_cur = idToVHDLExpr n_id
706 -- An expression for previous n
707 n_prev = n_cur AST.:-: (AST.PrimLit "1")
708 -- An id for the tmp result vector
709 tmp_id = mkVHDLBasicId "tmp"
710 tmp_name = AST.NSimple tmp_id
711 -- Generate parts of the fold
712 genFirstCell, genOtherCell :: TranslatorSession (AST.GenerateSm, [CoreSyn.CoreBndr])
714 let cond_label = mkVHDLExtId "firstcell"
715 -- if n == 0 or n == len-1
716 let cond_scheme = AST.IfGn $ n_cur AST.:=: (AST.PrimLit "0")
717 -- Output to tmp[current n]
718 let resname = mkIndexedName tmp_name n_cur
720 argexpr <- MonadState.lift tsType $ varToVHDLExpr start
721 let startassign = mkUncondAssign (Right resname) argexpr
722 (app_concsms, used) <- genApplication (Right resname) app_f [Right argexpr]
723 -- Return the conditional generate part
724 let gensm = AST.GenerateSm cond_label cond_scheme [] (if iter then
732 let cond_label = mkVHDLExtId "othercell"
733 -- if n > 0 or n < len-1
734 let cond_scheme = AST.IfGn $ n_cur AST.:/=: (AST.PrimLit "0")
735 -- Output to tmp[current n]
736 let resname = mkIndexedName tmp_name n_cur
737 -- Input from tmp[previous n]
738 let argexpr = vhdlNameToVHDLExpr $ mkIndexedName tmp_name n_prev
739 (app_concsms, used) <- genApplication (Right resname) app_f [Right argexpr]
740 -- Return the conditional generate part
741 return $ (AST.GenerateSm cond_label cond_scheme [] app_concsms, used)
744 -----------------------------------------------------------------------------
745 -- Function to generate VHDL for applications
746 -----------------------------------------------------------------------------
748 (Either CoreSyn.CoreBndr AST.VHDLName) -- ^ Where to store the result?
749 -> CoreSyn.CoreBndr -- ^ The function to apply
750 -> [Either CoreSyn.CoreExpr AST.Expr] -- ^ The arguments to apply
751 -> TranslatorSession ([AST.ConcSm], [CoreSyn.CoreBndr])
752 -- ^ The corresponding VHDL concurrent statements and entities
754 genApplication dst f args = do
755 case Var.isGlobalId f of
757 top <- isTopLevelBinder f
760 -- Local binder that references a top level binding. Generate a
761 -- component instantiation.
762 signature <- getEntity f
763 args' <- eitherCoreOrExprArgs args
764 let entity_id = ent_id signature
765 -- TODO: Using show here isn't really pretty, but we'll need some
766 -- unique-ish value...
767 let label = "comp_ins_" ++ (either show prettyShow) dst
768 let portmaps = mkAssocElems args' ((either varToVHDLName id) dst) signature
769 return ([mkComponentInst label entity_id portmaps], [f])
771 -- Not a top level binder, so this must be a local variable reference.
772 -- It should have a representable type (and thus, no arguments) and a
773 -- signal should be generated for it. Just generate an unconditional
775 f' <- MonadState.lift tsType $ varToVHDLExpr f
776 return $ ([mkUncondAssign dst f'], [])
778 case Var.idDetails f of
779 IdInfo.DataConWorkId dc -> case dst of
780 -- It's a datacon. Create a record from its arguments.
782 -- We have the bndr, so we can get at the type
783 labels <- MonadState.lift tsType $ getFieldLabels (Var.varType bndr)
784 args' <- eitherCoreOrExprArgs args
785 return $ (zipWith mkassign labels $ args', [])
787 mkassign :: AST.VHDLId -> AST.Expr -> AST.ConcSm
789 let sel_name = mkSelectedName ((either varToVHDLName id) dst) label in
790 mkUncondAssign (Right sel_name) arg
791 Right _ -> error $ "\nGenerate.genApplication: Can't generate dataconstructor application without an original binder"
792 IdInfo.DataConWrapId dc -> case dst of
793 -- It's a datacon. Create a record from its arguments.
795 case (Map.lookup (varToString f) globalNameTable) of
796 Just (arg_count, builder) ->
797 if length args == arg_count then
800 error $ "\nGenerate.genApplication(DataConWrapId): Incorrect number of arguments to builtin function: " ++ pprString f ++ " Args: " ++ show args
801 Nothing -> error $ "\nGenerate.genApplication: Can't generate dataconwrapper: " ++ (show dc)
802 Right _ -> error $ "\nGenerate.genApplication: Can't generate dataconwrapper application without an original binder"
803 IdInfo.VanillaId -> do
804 -- It's a global value imported from elsewhere. These can be builtin
805 -- functions. Look up the function name in the name table and execute
806 -- the associated builder if there is any and the argument count matches
807 -- (this should always be the case if it typechecks, but just to be
809 case (Map.lookup (varToString f) globalNameTable) of
810 Just (arg_count, builder) ->
811 if length args == arg_count then
814 error $ "\nGenerate.genApplication(VanillaGlobal): Incorrect number of arguments to builtin function: " ++ pprString f ++ " Args: " ++ show args
815 Nothing -> error $ ("\nGenerate.genApplication(VanillaGlobal): Using function from another module that is not a known builtin: " ++ (pprString f))
816 IdInfo.ClassOpId cls -> do
817 -- FIXME: Not looking for what instance this class op is called for
818 -- Is quite stupid of course.
819 case (Map.lookup (varToString f) globalNameTable) of
820 Just (arg_count, builder) ->
821 if length args == arg_count then
824 error $ "\nGenerate.genApplication(ClassOpId): Incorrect number of arguments to builtin function: " ++ pprString f ++ " Args: " ++ show args
825 Nothing -> error $ "\nGenerate.genApplication(ClassOpId): Using function from another module that is not a known builtin: " ++ pprString f
826 details -> error $ "\nGenerate.genApplication: Calling unsupported function " ++ pprString f ++ " with GlobalIdDetails " ++ pprString details
828 -----------------------------------------------------------------------------
829 -- Functions to generate functions dealing with vectors.
830 -----------------------------------------------------------------------------
832 -- Returns the VHDLId of the vector function with the given name for the given
833 -- element type. Generates -- this function if needed.
834 vectorFunId :: Type.Type -> String -> TypeSession AST.VHDLId
835 vectorFunId el_ty fname = do
836 let error_msg = "\nGenerate.vectorFunId: Can not construct vector function for element: " ++ pprString el_ty
837 elemTM <- vhdl_ty error_msg el_ty
838 -- TODO: This should not be duplicated from mk_vector_ty. Probably but it in
839 -- the VHDLState or something.
840 let vectorTM = mkVHDLExtId $ "vector_" ++ (AST.fromVHDLId elemTM)
841 typefuns <- getA tsTypeFuns
842 case Map.lookup (OrdType el_ty, fname) typefuns of
843 -- Function already generated, just return it
844 Just (id, _) -> return id
845 -- Function not generated yet, generate it
847 let functions = genUnconsVectorFuns elemTM vectorTM
848 case lookup fname functions of
850 modA tsTypeFuns $ Map.insert (OrdType el_ty, fname) (function_id, (fst body))
851 mapM_ (vectorFunId el_ty) (snd body)
853 Nothing -> error $ "\nGenerate.vectorFunId: I don't know how to generate vector function " ++ fname
855 function_id = mkVHDLExtId fname
857 genUnconsVectorFuns :: AST.TypeMark -- ^ type of the vector elements
858 -> AST.TypeMark -- ^ type of the vector
859 -> [(String, (AST.SubProgBody, [String]))]
860 genUnconsVectorFuns elemTM vectorTM =
861 [ (exId, (AST.SubProgBody exSpec [] [exExpr],[]))
862 , (replaceId, (AST.SubProgBody replaceSpec [AST.SPVD replaceVar] [replaceExpr,replaceRet],[]))
863 , (lastId, (AST.SubProgBody lastSpec [] [lastExpr],[]))
864 , (initId, (AST.SubProgBody initSpec [AST.SPVD initVar] [initExpr, initRet],[]))
865 , (takeId, (AST.SubProgBody takeSpec [AST.SPVD takeVar] [takeExpr, takeRet],[]))
866 , (dropId, (AST.SubProgBody dropSpec [AST.SPVD dropVar] [dropExpr, dropRet],[]))
867 , (plusgtId, (AST.SubProgBody plusgtSpec [AST.SPVD plusgtVar] [plusgtExpr, plusgtRet],[]))
868 , (emptyId, (AST.SubProgBody emptySpec [AST.SPCD emptyVar] [emptyExpr],[]))
869 , (singletonId, (AST.SubProgBody singletonSpec [AST.SPVD singletonVar] [singletonRet],[]))
870 , (copynId, (AST.SubProgBody copynSpec [AST.SPVD copynVar] [copynExpr],[]))
871 , (selId, (AST.SubProgBody selSpec [AST.SPVD selVar] [selFor, selRet],[]))
872 , (ltplusId, (AST.SubProgBody ltplusSpec [AST.SPVD ltplusVar] [ltplusExpr, ltplusRet],[]))
873 , (plusplusId, (AST.SubProgBody plusplusSpec [AST.SPVD plusplusVar] [plusplusExpr, plusplusRet],[]))
874 , (lengthTId, (AST.SubProgBody lengthTSpec [] [lengthTExpr],[]))
875 , (shiftlId, (AST.SubProgBody shiftlSpec [AST.SPVD shiftlVar] [shiftlExpr, shiftlRet], [initId]))
876 , (shiftrId, (AST.SubProgBody shiftrSpec [AST.SPVD shiftrVar] [shiftrExpr, shiftrRet], [tailId]))
877 , (nullId, (AST.SubProgBody nullSpec [] [nullExpr], []))
878 , (rotlId, (AST.SubProgBody rotlSpec [AST.SPVD rotlVar] [rotlExpr, rotlRet], [nullId, lastId, initId]))
879 , (rotrId, (AST.SubProgBody rotrSpec [AST.SPVD rotrVar] [rotrExpr, rotrRet], [nullId, tailId, headId]))
880 , (reverseId, (AST.SubProgBody reverseSpec [AST.SPVD reverseVar] [reverseFor, reverseRet], []))
883 ixPar = AST.unsafeVHDLBasicId "ix"
884 vecPar = AST.unsafeVHDLBasicId "vec"
885 vec1Par = AST.unsafeVHDLBasicId "vec1"
886 vec2Par = AST.unsafeVHDLBasicId "vec2"
887 nPar = AST.unsafeVHDLBasicId "n"
888 iId = AST.unsafeVHDLBasicId "i"
890 aPar = AST.unsafeVHDLBasicId "a"
891 fPar = AST.unsafeVHDLBasicId "f"
892 sPar = AST.unsafeVHDLBasicId "s"
893 resId = AST.unsafeVHDLBasicId "res"
894 exSpec = AST.Function (mkVHDLExtId exId) [AST.IfaceVarDec vecPar vectorTM,
895 AST.IfaceVarDec ixPar naturalTM] elemTM
896 exExpr = AST.ReturnSm (Just $ AST.PrimName $ AST.NIndexed
897 (AST.IndexedName (AST.NSimple vecPar) [AST.PrimName $
899 replaceSpec = AST.Function (mkVHDLExtId replaceId) [ AST.IfaceVarDec vecPar vectorTM
900 , AST.IfaceVarDec iPar naturalTM
901 , AST.IfaceVarDec aPar elemTM
903 -- variable res : fsvec_x (0 to vec'length-1);
906 (AST.SubtypeIn vectorTM
907 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
908 [AST.ToRange (AST.PrimLit "0")
909 (AST.PrimName (AST.NAttribute $
910 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:-:
911 (AST.PrimLit "1")) ]))
913 -- res AST.:= vec(0 to i-1) & a & vec(i+1 to length'vec-1)
914 replaceExpr = AST.NSimple resId AST.:=
915 (vecSlice (AST.PrimLit "0") (AST.PrimName (AST.NSimple iPar) AST.:-: AST.PrimLit "1") AST.:&:
916 AST.PrimName (AST.NSimple aPar) AST.:&:
917 vecSlice (AST.PrimName (AST.NSimple iPar) AST.:+: AST.PrimLit "1")
918 ((AST.PrimName (AST.NAttribute $
919 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing))
920 AST.:-: AST.PrimLit "1"))
921 replaceRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
922 vecSlice init last = AST.PrimName (AST.NSlice
925 (AST.ToRange init last)))
926 lastSpec = AST.Function (mkVHDLExtId lastId) [AST.IfaceVarDec vecPar vectorTM] elemTM
927 -- return vec(vec'length-1);
928 lastExpr = AST.ReturnSm (Just $ (AST.PrimName $ AST.NIndexed (AST.IndexedName
930 [AST.PrimName (AST.NAttribute $
931 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing)
932 AST.:-: AST.PrimLit "1"])))
933 initSpec = AST.Function (mkVHDLExtId initId) [AST.IfaceVarDec vecPar vectorTM] vectorTM
934 -- variable res : fsvec_x (0 to vec'length-2);
937 (AST.SubtypeIn vectorTM
938 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
939 [AST.ToRange (AST.PrimLit "0")
940 (AST.PrimName (AST.NAttribute $
941 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:-:
942 (AST.PrimLit "2")) ]))
944 -- resAST.:= vec(0 to vec'length-2)
945 initExpr = AST.NSimple resId AST.:= (vecSlice
947 (AST.PrimName (AST.NAttribute $
948 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing)
949 AST.:-: AST.PrimLit "2"))
950 initRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
951 takeSpec = AST.Function (mkVHDLExtId takeId) [AST.IfaceVarDec nPar naturalTM,
952 AST.IfaceVarDec vecPar vectorTM ] vectorTM
953 -- variable res : fsvec_x (0 to n-1);
956 (AST.SubtypeIn vectorTM
957 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
958 [AST.ToRange (AST.PrimLit "0")
959 ((AST.PrimName (AST.NSimple nPar)) AST.:-:
960 (AST.PrimLit "1")) ]))
962 -- res AST.:= vec(0 to n-1)
963 takeExpr = AST.NSimple resId AST.:=
964 (vecSlice (AST.PrimLit "1")
965 (AST.PrimName (AST.NSimple $ nPar) AST.:-: AST.PrimLit "1"))
966 takeRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
967 dropSpec = AST.Function (mkVHDLExtId dropId) [AST.IfaceVarDec nPar naturalTM,
968 AST.IfaceVarDec vecPar vectorTM ] vectorTM
969 -- variable res : fsvec_x (0 to vec'length-n-1);
972 (AST.SubtypeIn vectorTM
973 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
974 [AST.ToRange (AST.PrimLit "0")
975 (AST.PrimName (AST.NAttribute $
976 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:-:
977 (AST.PrimName $ AST.NSimple nPar)AST.:-: (AST.PrimLit "1")) ]))
979 -- res AST.:= vec(n to vec'length-1)
980 dropExpr = AST.NSimple resId AST.:= (vecSlice
981 (AST.PrimName $ AST.NSimple nPar)
982 (AST.PrimName (AST.NAttribute $
983 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing)
984 AST.:-: AST.PrimLit "1"))
985 dropRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
986 plusgtSpec = AST.Function (mkVHDLExtId plusgtId) [AST.IfaceVarDec aPar elemTM,
987 AST.IfaceVarDec vecPar vectorTM] vectorTM
988 -- variable res : fsvec_x (0 to vec'length);
991 (AST.SubtypeIn vectorTM
992 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
993 [AST.ToRange (AST.PrimLit "0")
994 (AST.PrimName (AST.NAttribute $
995 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing))]))
997 plusgtExpr = AST.NSimple resId AST.:=
998 ((AST.PrimName $ AST.NSimple aPar) AST.:&:
999 (AST.PrimName $ AST.NSimple vecPar))
1000 plusgtRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
1001 emptySpec = AST.Function (mkVHDLExtId emptyId) [] vectorTM
1004 (AST.SubtypeIn vectorTM Nothing)
1005 (Just $ AST.PrimLit "\"\"")
1006 emptyExpr = AST.ReturnSm (Just $ AST.PrimName (AST.NSimple resId))
1007 singletonSpec = AST.Function (mkVHDLExtId singletonId) [AST.IfaceVarDec aPar elemTM ]
1009 -- variable res : fsvec_x (0 to 0) := (others => a);
1012 (AST.SubtypeIn vectorTM
1013 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
1014 [AST.ToRange (AST.PrimLit "0") (AST.PrimLit "0")]))
1015 (Just $ AST.Aggregate [AST.ElemAssoc (Just AST.Others)
1016 (AST.PrimName $ AST.NSimple aPar)])
1017 singletonRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
1018 copynSpec = AST.Function (mkVHDLExtId copynId) [AST.IfaceVarDec nPar naturalTM,
1019 AST.IfaceVarDec aPar elemTM ] vectorTM
1020 -- variable res : fsvec_x (0 to n-1) := (others => a);
1023 (AST.SubtypeIn vectorTM
1024 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
1025 [AST.ToRange (AST.PrimLit "0")
1026 ((AST.PrimName (AST.NSimple nPar)) AST.:-:
1027 (AST.PrimLit "1")) ]))
1028 (Just $ AST.Aggregate [AST.ElemAssoc (Just AST.Others)
1029 (AST.PrimName $ AST.NSimple aPar)])
1031 copynExpr = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
1032 selSpec = AST.Function (mkVHDLExtId selId) [AST.IfaceVarDec fPar naturalTM,
1033 AST.IfaceVarDec sPar naturalTM,
1034 AST.IfaceVarDec nPar naturalTM,
1035 AST.IfaceVarDec vecPar vectorTM ] vectorTM
1036 -- variable res : fsvec_x (0 to n-1);
1039 (AST.SubtypeIn vectorTM
1040 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
1041 [AST.ToRange (AST.PrimLit "0")
1042 ((AST.PrimName (AST.NSimple nPar)) AST.:-:
1043 (AST.PrimLit "1")) ])
1046 -- for i res'range loop
1047 -- res(i) := vec(f+i*s);
1049 selFor = AST.ForSM iId (AST.AttribRange $ AST.AttribName (AST.NSimple resId) (AST.NSimple $ rangeId) Nothing) [selAssign]
1050 -- res(i) := vec(f+i*s);
1051 selAssign = let origExp = AST.PrimName (AST.NSimple fPar) AST.:+:
1052 (AST.PrimName (AST.NSimple iId) AST.:*:
1053 AST.PrimName (AST.NSimple sPar)) in
1054 AST.NIndexed (AST.IndexedName (AST.NSimple resId) [AST.PrimName (AST.NSimple iId)]) AST.:=
1055 (AST.PrimName $ AST.NIndexed (AST.IndexedName (AST.NSimple vecPar) [origExp]))
1057 selRet = AST.ReturnSm (Just $ AST.PrimName (AST.NSimple resId))
1058 ltplusSpec = AST.Function (mkVHDLExtId ltplusId) [AST.IfaceVarDec vecPar vectorTM,
1059 AST.IfaceVarDec aPar elemTM] vectorTM
1060 -- variable res : fsvec_x (0 to vec'length);
1063 (AST.SubtypeIn vectorTM
1064 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
1065 [AST.ToRange (AST.PrimLit "0")
1066 (AST.PrimName (AST.NAttribute $
1067 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing))]))
1069 ltplusExpr = AST.NSimple resId AST.:=
1070 ((AST.PrimName $ AST.NSimple vecPar) AST.:&:
1071 (AST.PrimName $ AST.NSimple aPar))
1072 ltplusRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
1073 plusplusSpec = AST.Function (mkVHDLExtId plusplusId) [AST.IfaceVarDec vec1Par vectorTM,
1074 AST.IfaceVarDec vec2Par vectorTM]
1076 -- variable res : fsvec_x (0 to vec1'length + vec2'length -1);
1079 (AST.SubtypeIn vectorTM
1080 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
1081 [AST.ToRange (AST.PrimLit "0")
1082 (AST.PrimName (AST.NAttribute $
1083 AST.AttribName (AST.NSimple vec1Par) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:+:
1084 AST.PrimName (AST.NAttribute $
1085 AST.AttribName (AST.NSimple vec2Par) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:-:
1088 plusplusExpr = AST.NSimple resId AST.:=
1089 ((AST.PrimName $ AST.NSimple vec1Par) AST.:&:
1090 (AST.PrimName $ AST.NSimple vec2Par))
1091 plusplusRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
1092 lengthTSpec = AST.Function (mkVHDLExtId lengthTId) [AST.IfaceVarDec vecPar vectorTM] naturalTM
1093 lengthTExpr = AST.ReturnSm (Just $ AST.PrimName (AST.NAttribute $
1094 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing))
1095 shiftlSpec = AST.Function (mkVHDLExtId shiftlId) [AST.IfaceVarDec vecPar vectorTM,
1096 AST.IfaceVarDec aPar elemTM ] vectorTM
1097 -- variable res : fsvec_x (0 to vec'length-1);
1100 (AST.SubtypeIn vectorTM
1101 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
1102 [AST.ToRange (AST.PrimLit "0")
1103 (AST.PrimName (AST.NAttribute $
1104 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:-:
1105 (AST.PrimLit "1")) ]))
1107 -- res := a & init(vec)
1108 shiftlExpr = AST.NSimple resId AST.:=
1109 (AST.PrimName (AST.NSimple aPar) AST.:&:
1110 (AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLExtId initId))
1111 [Nothing AST.:=>: AST.ADExpr (AST.PrimName $ AST.NSimple vecPar)]))
1112 shiftlRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
1113 shiftrSpec = AST.Function (mkVHDLExtId shiftrId) [AST.IfaceVarDec vecPar vectorTM,
1114 AST.IfaceVarDec aPar elemTM ] vectorTM
1115 -- variable res : fsvec_x (0 to vec'length-1);
1118 (AST.SubtypeIn vectorTM
1119 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
1120 [AST.ToRange (AST.PrimLit "0")
1121 (AST.PrimName (AST.NAttribute $
1122 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:-:
1123 (AST.PrimLit "1")) ]))
1125 -- res := tail(vec) & a
1126 shiftrExpr = AST.NSimple resId AST.:=
1127 ((AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLExtId tailId))
1128 [Nothing AST.:=>: AST.ADExpr (AST.PrimName $ AST.NSimple vecPar)]) AST.:&:
1129 (AST.PrimName (AST.NSimple aPar)))
1131 shiftrRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
1132 nullSpec = AST.Function (mkVHDLExtId nullId) [AST.IfaceVarDec vecPar vectorTM] booleanTM
1133 -- return vec'length = 0
1134 nullExpr = AST.ReturnSm (Just $
1135 AST.PrimName (AST.NAttribute $
1136 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:=:
1138 rotlSpec = AST.Function (mkVHDLExtId rotlId) [AST.IfaceVarDec vecPar vectorTM] vectorTM
1139 -- variable res : fsvec_x (0 to vec'length-1);
1142 (AST.SubtypeIn vectorTM
1143 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
1144 [AST.ToRange (AST.PrimLit "0")
1145 (AST.PrimName (AST.NAttribute $
1146 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:-:
1147 (AST.PrimLit "1")) ]))
1149 -- if null(vec) then res := vec else res := last(vec) & init(vec)
1150 rotlExpr = AST.IfSm (AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLExtId nullId))
1151 [Nothing AST.:=>: AST.ADExpr (AST.PrimName $ AST.NSimple vecPar)])
1152 [AST.NSimple resId AST.:= (AST.PrimName $ AST.NSimple vecPar)]
1154 (Just $ AST.Else [rotlExprRet])
1156 AST.NSimple resId AST.:=
1157 ((AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLExtId lastId))
1158 [Nothing AST.:=>: AST.ADExpr (AST.PrimName $ AST.NSimple vecPar)]) AST.:&:
1159 (AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLExtId initId))
1160 [Nothing AST.:=>: AST.ADExpr (AST.PrimName $ AST.NSimple vecPar)]))
1161 rotlRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
1162 rotrSpec = AST.Function (mkVHDLExtId rotrId) [AST.IfaceVarDec vecPar vectorTM] vectorTM
1163 -- variable res : fsvec_x (0 to vec'length-1);
1166 (AST.SubtypeIn vectorTM
1167 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
1168 [AST.ToRange (AST.PrimLit "0")
1169 (AST.PrimName (AST.NAttribute $
1170 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:-:
1171 (AST.PrimLit "1")) ]))
1173 -- if null(vec) then res := vec else res := tail(vec) & head(vec)
1174 rotrExpr = AST.IfSm (AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLExtId nullId))
1175 [Nothing AST.:=>: AST.ADExpr (AST.PrimName $ AST.NSimple vecPar)])
1176 [AST.NSimple resId AST.:= (AST.PrimName $ AST.NSimple vecPar)]
1178 (Just $ AST.Else [rotrExprRet])
1180 AST.NSimple resId AST.:=
1181 ((AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLExtId tailId))
1182 [Nothing AST.:=>: AST.ADExpr (AST.PrimName $ AST.NSimple vecPar)]) AST.:&:
1183 (AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLExtId headId))
1184 [Nothing AST.:=>: AST.ADExpr (AST.PrimName $ AST.NSimple vecPar)]))
1185 rotrRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
1186 reverseSpec = AST.Function (mkVHDLExtId reverseId) [AST.IfaceVarDec vecPar vectorTM] vectorTM
1189 (AST.SubtypeIn vectorTM
1190 (Just $ AST.ConstraintIndex $ AST.IndexConstraint
1191 [AST.ToRange (AST.PrimLit "0")
1192 (AST.PrimName (AST.NAttribute $
1193 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:-:
1194 (AST.PrimLit "1")) ]))
1196 -- for i in 0 to res'range loop
1197 -- res(vec'length-i-1) := vec(i);
1200 AST.ForSM iId (AST.AttribRange $ AST.AttribName (AST.NSimple resId) (AST.NSimple $ rangeId) Nothing) [reverseAssign]
1201 -- res(vec'length-i-1) := vec(i);
1202 reverseAssign = AST.NIndexed (AST.IndexedName (AST.NSimple resId) [destExp]) AST.:=
1203 (AST.PrimName $ AST.NIndexed (AST.IndexedName (AST.NSimple vecPar)
1204 [AST.PrimName $ AST.NSimple iId]))
1205 where destExp = AST.PrimName (AST.NAttribute $ AST.AttribName (AST.NSimple vecPar)
1206 (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:-:
1207 AST.PrimName (AST.NSimple iId) AST.:-:
1210 reverseRet = AST.ReturnSm (Just $ AST.PrimName (AST.NSimple resId))
1213 -----------------------------------------------------------------------------
1214 -- A table of builtin functions
1215 -----------------------------------------------------------------------------
1217 -- A function that generates VHDL for a builtin function
1218 type BuiltinBuilder =
1219 (Either CoreSyn.CoreBndr AST.VHDLName) -- ^ The destination signal and it's original type
1220 -> CoreSyn.CoreBndr -- ^ The function called
1221 -> [Either CoreSyn.CoreExpr AST.Expr] -- ^ The value arguments passed (excluding type and
1222 -- dictionary arguments).
1223 -> TranslatorSession ([AST.ConcSm], [CoreSyn.CoreBndr])
1224 -- ^ The corresponding VHDL concurrent statements and entities
1227 -- A map of a builtin function to VHDL function builder
1228 type NameTable = Map.Map String (Int, BuiltinBuilder )
1230 -- | The builtin functions we support. Maps a name to an argument count and a
1231 -- builder function.
1232 globalNameTable :: NameTable
1233 globalNameTable = Map.fromList
1234 [ (exId , (2, genFCall False ) )
1235 , (replaceId , (3, genFCall False ) )
1236 , (headId , (1, genFCall True ) )
1237 , (lastId , (1, genFCall True ) )
1238 , (tailId , (1, genFCall False ) )
1239 , (initId , (1, genFCall False ) )
1240 , (takeId , (2, genFCall False ) )
1241 , (dropId , (2, genFCall False ) )
1242 , (selId , (4, genFCall False ) )
1243 , (plusgtId , (2, genFCall False ) )
1244 , (ltplusId , (2, genFCall False ) )
1245 , (plusplusId , (2, genFCall False ) )
1246 , (mapId , (2, genMap ) )
1247 , (zipWithId , (3, genZipWith ) )
1248 , (foldlId , (3, genFoldl ) )
1249 , (foldrId , (3, genFoldr ) )
1250 , (zipId , (2, genZip ) )
1251 , (unzipId , (1, genUnzip ) )
1252 , (shiftlId , (2, genFCall False ) )
1253 , (shiftrId , (2, genFCall False ) )
1254 , (rotlId , (1, genFCall False ) )
1255 , (rotrId , (1, genFCall False ) )
1256 , (concatId , (1, genConcat ) )
1257 , (reverseId , (1, genFCall False ) )
1258 , (iteratenId , (3, genIteraten ) )
1259 , (iterateId , (2, genIterate ) )
1260 , (generatenId , (3, genGeneraten ) )
1261 , (generateId , (2, genGenerate ) )
1262 , (emptyId , (0, genFCall False ) )
1263 , (singletonId , (1, genFCall False ) )
1264 , (copynId , (2, genFCall False ) )
1265 , (copyId , (1, genCopy ) )
1266 , (lengthTId , (1, genFCall False ) )
1267 , (nullId , (1, genFCall False ) )
1268 , (hwxorId , (2, genOperator2 AST.Xor ) )
1269 , (hwandId , (2, genOperator2 AST.And ) )
1270 , (hworId , (2, genOperator2 AST.Or ) )
1271 , (hwnotId , (1, genOperator1 AST.Not ) )
1272 , (plusId , (2, genOperator2 (AST.:+:) ) )
1273 , (timesId , (2, genOperator2 (AST.:*:) ) )
1274 , (negateId , (1, genNegation ) )
1275 , (minusId , (2, genOperator2 (AST.:-:) ) )
1276 , (fromSizedWordId , (1, genFromSizedWord ) )
1277 , (fromIntegerId , (1, genFromInteger ) )
1278 , (resizeId , (1, genResize ) )
1279 , (sizedIntId , (1, genSizedInt ) )
1280 --, (tfvecId , (1, genTFVec ) )