Generate proper VHDL for top level bindings with no arguments.
authorMatthijs Kooijman <m.kooijman@student.utwente.nl>
Mon, 13 Jul 2009 09:57:25 +0000 (11:57 +0200)
committerMatthijs Kooijman <m.kooijman@student.utwente.nl>
Mon, 13 Jul 2009 09:57:25 +0000 (11:57 +0200)
Previously, a = b bindings would always generate an unconditional
assignment. Now, they use genApplication to generate VHDL, and
genApplications knows how to generate unconditional assignments when b is
a local identifier, and a component instantiation when b is a top level
binder.

Generate.hs
VHDL.hs

index e7a51983b1b9f7acb18e7a09a8a1a9eea8db5902..4f0acf319760946a632e5a5b45970164c1b8e0dc 100644 (file)
@@ -44,7 +44,7 @@ genExprArgs ::
   -> (dst -> func -> [Either CoreSyn.CoreExpr AST.Expr] -> res)
 genExprArgs ty_state wrap dst func args = wrap dst func args'
   where args' = map (either ((varToVHDLExpr ty_state).exprToVar) id) args
-  
+
 -- | A function to wrap a builder-like function that expects its arguments to
 -- be variables.
 genVarArgs ::
@@ -514,17 +514,25 @@ genApplication dst f args = do
       signatures <- getA vsSignatures
       -- This is a local id, so it should be a function whose definition we
       -- have and which can be turned into a component instantiation.
-      let  
-        signature = Maybe.fromMaybe 
-          (error $ "\nGenerate.genApplication: Using function '" ++ (varToString f) ++ "' without signature? This should not happen!") 
-          (Map.lookup f signatures)
-        entity_id = ent_id signature
-        -- TODO: Using show here isn't really pretty, but we'll need some
-        -- unique-ish value...
-        label = "comp_ins_" ++ (either show prettyShow) dst
-        portmaps = mkAssocElems (map (either (exprToVHDLExpr ty_state) id) args) ((either varToVHDLName id) dst) signature
-        in
-          return [mkComponentInst label entity_id portmaps]
+      case (Map.lookup f signatures) of
+        Just signature -> let
+          -- We have a signature, this is a top level binding. Generate a
+          -- component instantiation.
+          entity_id = ent_id signature
+          -- TODO: Using show here isn't really pretty, but we'll need some
+          -- unique-ish value...
+          label = "comp_ins_" ++ (either show prettyShow) dst
+          portmaps = mkAssocElems (map (either (exprToVHDLExpr ty_state) id) args) ((either varToVHDLName id) dst) signature
+          in
+            return [mkComponentInst label entity_id portmaps]
+        Nothing -> do
+          -- No signature, so this must be a local variable reference. It
+          -- should have a representable type (and thus, no arguments) and a
+          -- signal should be generated for it. Just generate an
+          -- unconditional assignment here.
+          ty_state <- getA vsType
+          return $ [mkUncondAssign dst ((varToVHDLExpr ty_state) f)]
+            
     IdInfo.ClassOpId cls -> do
       -- FIXME: Not looking for what instance this class op is called for
       -- Is quite stupid of course.
diff --git a/VHDL.hs b/VHDL.hs
index 6039447a55f5eb57097fa23b4fffc01d7cbee22a..2ac2a12aaffb0a74d6303053f97d871eabdd7775 100644 (file)
--- a/VHDL.hs
+++ b/VHDL.hs
@@ -254,13 +254,11 @@ mkConcSm ::
 -- the type works out.
 mkConcSm (bndr, Cast expr ty) = mkConcSm (bndr, expr)
 
--- For simple a = b assignments, just generate an unconditional signal
--- assignment. This should only happen for dataconstructors without arguments.
--- TODO: Integrate this with the below code for application (essentially this
--- is an application without arguments)
+-- Simple a = b assignments are just like applications, but without arguments.
+-- We can't just generate an unconditional assignment here, since b might be a
+-- top level binding (e.g., a function with no arguments).
 mkConcSm (bndr, Var v) = do
-  ty_state <- getA vsType
-  return $ [mkUncondAssign (Left bndr) ((varToVHDLExpr ty_state) v)]
+  genApplication (Left bndr) v []
 
 mkConcSm (bndr, app@(CoreSyn.App _ _))= do
   let (CoreSyn.Var f, args) = CoreSyn.collectArgs app