packages feed

sv2v 0.0.11 → 0.0.12

raw patch · 51 files changed

+986/−407 lines, 51 filesdep ~basedep ~hashabledep ~mtl

Dependency ranges changed: base, hashable, mtl, vector

Files

CHANGELOG.md view
@@ -1,3 +1,47 @@+## v0.0.12++### Breaking Changes++* Removed deprecated CLI flags `-d`/`-e`/`-i`, which have been aliased to+  `-D`/`-E`/`-I` with a warning since late 2019++### New Features++* `unique`, `unique0`, and `priority` case statements now produce corresponding+  `parallel_case` and `full_case` statement attributes+* Added support for attributes in unary, binary, and ternary expressions+* Added support for streaming concatenations within ternary expressions+* Added support for shadowing interface names with local typenames+* Added support for passing through `wait` statements++### Bug Fixes++* Fixed signed unsized literals with a leading 1 bit (e.g., `'sb1`, `'sh8f`)+  incorrectly sign-extending in size and type casts+* Fixed conflicting genvar names when inlining interfaces and modules that use+  them; all genvars are now given a design-wide unique name+* Fixed unconverted structs within explicit type casts+* Fixed byte order of strings in size casts+* Fixed unconverted multidimensional struct fields within dimension queries+* Fixed non-typenames (e.g., from packages or subsequent declarations)+  improperly shadowing the names of `struct` pattern fields+* Fixed shadowing of interface array indices passed to port connections+* Fixed failure to resolve typenames suffixed with dimensions in contexts+  permitting both types and expressions, e.g., `$bits(T[W-1:0])`+* Fixed an issue that prevented parsing tasks and functions with `inout` ports+* Fixed errant constant folding of shadowed non-trivial localparams+* Fixed conversion of function calls with no arguments passed to other functions+* Fixed certain non-ANSI style port declarations being incorrectly reported as+  incompatible++### Other Enhancements++* `always_comb` and `always_latch` now reliably execute at time zero+* Added error checking for unresolved typenames+* Added constant folding for `||` and `&&`+* `input reg` module ports are now converted to `input wire`+* `x | |y` and `x & &y` are now output as `x | (|y)` and `x & (&y)`+ ## v0.0.11  ### New Features
LICENSE view
@@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright 2019-2023 Zachary Snow+Copyright 2019-2024 Zachary Snow Copyright 2011-2015 Tom Hawkins  All rights reserved.
NOTICE view
@@ -1,5 +1,5 @@ ================================================================================-Dependency: alex-3.2.7.1+Dependency: alex-3.4.0.1 ================================================================================    Copyright (c) 1995-2011, Chris Dornan and Simon Marlow@@ -34,7 +34,7 @@   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  ================================================================================-Dependency: array-0.5.4.0+Dependency: array-0.5.6.0 ================================================================================    This library (libraries/base) is derived from code from several@@ -123,7 +123,7 @@   ================================================================================-Dependency: base-4.14.3.0+Dependency: base-4.18.2.0 ================================================================================    This library (libraries/base) is derived from code from several@@ -211,7 +211,7 @@   -----------------------------------------------------------------------------  ================================================================================-Dependency: binary-0.8.8.0+Dependency: binary-0.8.9.1 ================================================================================    Copyright (c) Lennart Kolmodin@@ -246,13 +246,14 @@   POSSIBILITY OF SUCH DAMAGE.  ================================================================================-Dependency: bytestring-0.10.12.0+Dependency: bytestring-0.11.5.3 ================================================================================    Copyright (c) Don Stewart 2005-2009             (c) Duncan Coutts 2006-2015             (c) David Roundy 2003-2005             (c) Simon Meier 2010-2011+            (c) Koz Ross 2021    All rights reserved. @@ -281,10 +282,10 @@   SUCH DAMAGE.  ================================================================================-Dependency: cmdargs-0.10.21+Dependency: cmdargs-0.10.22 ================================================================================ -  Copyright Neil Mitchell 2009-2021.+  Copyright Neil Mitchell 2009-2023.   All rights reserved.    Redistribution and use in source and binary forms, with or without@@ -316,7 +317,7 @@   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  ================================================================================-Dependency: containers-0.6.5.1+Dependency: containers-0.6.7 ================================================================================    The Glasgow Haskell Compiler License@@ -352,7 +353,7 @@   DAMAGE.  ================================================================================-Dependency: deepseq-1.4.4.0+Dependency: deepseq-1.4.8.1 ================================================================================    This library (deepseq) is derived from code from the GHC project which@@ -396,7 +397,7 @@   -----------------------------------------------------------------------------  ================================================================================-Dependency: directory-1.3.6.0+Dependency: directory-1.3.8.1 ================================================================================    This library (libraries/base) is derived from code from two@@ -464,13 +465,49 @@   -----------------------------------------------------------------------------  ================================================================================-Dependency: filepath-1.4.2.1+Dependency: exceptions-0.10.7 ================================================================================ -  Copyright Neil Mitchell 2005-2018.+  Copyright 2013-2015 Edward Kmett+  Copyright 2012 Google Inc.+   All rights reserved.    Redistribution and use in source and binary forms, with or without+  modification, are permitted provided that the following conditions+  are met:++  1. Redistributions of source code must retain the above copyright+     notice, this list of conditions and the following disclaimer.++  2. Redistributions in binary form must reproduce the above copyright+     notice, this list of conditions and the following disclaimer in the+     documentation and/or other materials provided with the distribution.++  3. Neither the name of the author nor the names of his contributors+     may be used to endorse or promote products derived from this software+     without specific prior written permission.++  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR+  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+  DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR+  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,+  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN+  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+  POSSIBILITY OF SUCH DAMAGE.++================================================================================+Dependency: filepath-1.4.200.1+================================================================================++  Copyright Neil Mitchell 2005-2020.+  All rights reserved.++  Redistribution and use in source and binary forms, with or without   modification, are permitted provided that the following conditions are   met: @@ -499,9 +536,45 @@   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  ================================================================================-Dependency: ghc-prim-0.6.1+Dependency: ghc-bignum-1.3 ================================================================================ +  The Glasgow Haskell Compiler License++  Copyright 2020, The University Court of the University of Glasgow.+  All rights reserved.++  Redistribution and use in source and binary forms, with or without+  modification, are permitted provided that the following conditions are met:++  - Redistributions of source code must retain the above copyright notice,+  this list of conditions and the following disclaimer.++  - Redistributions in binary form must reproduce the above copyright notice,+  this list of conditions and the following disclaimer in the documentation+  and/or other materials provided with the distribution.++  - Neither name of the University nor the names of its contributors may be+  used to endorse or promote products derived from this software without+  specific prior written permission.++  THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF+  GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,+  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND+  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+  UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE+  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH+  DAMAGE.++================================================================================+Dependency: ghc-prim-0.10.0+================================================================================+   This library (libraries/ghc-prim) is derived from code from several   sources: @@ -566,7 +639,7 @@   ================================================================================-Dependency: githash-0.1.6.2+Dependency: githash-0.1.7.0 ================================================================================    Copyright (c) 2018, Michael Snoyman, 2015, Adam C. Foltzer@@ -598,7 +671,7 @@   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  ================================================================================-Dependency: happy-1.20.0+Dependency: happy-1.20.1.1 ================================================================================    The Happy License@@ -633,7 +706,7 @@   IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  ================================================================================-Dependency: hashable-1.3.0.0+Dependency: hashable-1.4.4.0 ================================================================================    Copyright Milan Straka 2010@@ -668,42 +741,7 @@   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  ================================================================================-Dependency: integer-gmp-1.0.3.0-================================================================================--  Copyright (c) 2014, Herbert Valerio Riedel--  All rights reserved.--  Redistribution and use in source and binary forms, with or without-  modification, are permitted provided that the following conditions are met:--      * Redistributions of source code must retain the above copyright-        notice, this list of conditions and the following disclaimer.--      * Redistributions in binary form must reproduce the above-        copyright notice, this list of conditions and the following-        disclaimer in the documentation and/or other materials provided-        with the distribution.--      * Neither the name of Herbert Valerio Riedel nor the names of other-        contributors may be used to endorse or promote products derived-        from this software without specific prior written permission.--  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS-  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT-  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR-  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT-  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,-  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT-  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,-  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY-  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT-  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE-  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.--================================================================================-Dependency: mtl-2.2.2+Dependency: mtl-2.3.1 ================================================================================    The Glasgow Haskell Compiler License@@ -739,6 +777,41 @@   DAMAGE.  ================================================================================+Dependency: os-string-2.0.2.1+================================================================================++  Copyright Neil Mitchell 2005-2020.+  All rights reserved.++  Redistribution and use in source and binary forms, with or without+  modification, are permitted provided that the following conditions are+  met:++      * Redistributions of source code must retain the above copyright+        notice, this list of conditions and the following disclaimer.++      * Redistributions in binary form must reproduce the above+        copyright notice, this list of conditions and the following+        disclaimer in the documentation and/or other materials provided+        with the distribution.++      * Neither the name of Neil Mitchell nor the names of other+        contributors may be used to endorse or promote products derived+        from this software without specific prior written permission.++  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++================================================================================ Dependency: pretty-1.1.3.6 ================================================================================ @@ -783,7 +856,7 @@   -----------------------------------------------------------------------------  ================================================================================-Dependency: primitive-0.7.3.0+Dependency: primitive-0.8.0.0 ================================================================================    Copyright (c) 2008-2009, Roman Leshchinskiy@@ -818,7 +891,7 @@   ================================================================================-Dependency: process-1.6.13.2+Dependency: process-1.6.17.0 ================================================================================    This library (libraries/process) is derived from code from two@@ -886,10 +959,46 @@   -----------------------------------------------------------------------------  ================================================================================-Dependency: template-haskell-2.16.0.0+Dependency: stm-2.5.1.0 ================================================================================ +  The Glasgow Haskell Compiler License +  Copyright 2004, The University Court of the University of Glasgow.+  All rights reserved.++  Redistribution and use in source and binary forms, with or without+  modification, are permitted provided that the following conditions are met:++  - Redistributions of source code must retain the above copyright notice,+  this list of conditions and the following disclaimer.++  - Redistributions in binary form must reproduce the above copyright notice,+  this list of conditions and the following disclaimer in the documentation+  and/or other materials provided with the distribution.++  - Neither name of the University nor the names of its contributors may be+  used to endorse or promote products derived from this software without+  specific prior written permission.++  THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF+  GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,+  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND+  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+  UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE+  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH+  DAMAGE.++================================================================================+Dependency: template-haskell-2.20.0.0+================================================================================++   The Glasgow Haskell Compiler License    Copyright 2002-2007, The University Court of the University of Glasgow.@@ -924,7 +1033,7 @@   ================================================================================-Dependency: text-1.2.4.1+Dependency: text-2.0.2 ================================================================================    Copyright (c) 2008-2009, Tom Harper@@ -955,7 +1064,7 @@   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  ================================================================================-Dependency: th-compat-0.1.3+Dependency: th-compat-0.1.5 ================================================================================    Copyright (c) 2020, Ryan Scott@@ -990,10 +1099,10 @@   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  ================================================================================-Dependency: time-1.9.3+Dependency: time-1.12.2 ================================================================================ -  TimeLib is Copyright (c) Ashley Yakeley, 2004-2014. All rights reserved.+  TimeLib is Copyright (c) Ashley Yakeley and contributors, 2004-2022. All rights reserved.   Certain sections are Copyright 2004, The University Court of the University of Glasgow. All rights reserved.    Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:@@ -1005,7 +1114,7 @@   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  ================================================================================-Dependency: transformers-0.5.6.2+Dependency: transformers-0.6.1.0 ================================================================================    The Glasgow Haskell Compiler License@@ -1041,7 +1150,7 @@   DAMAGE.  ================================================================================-Dependency: unix-2.7.2.2+Dependency: unix-2.8.4.0 ================================================================================    The Glasgow Haskell Compiler License@@ -1077,10 +1186,13 @@   DAMAGE.  ================================================================================-Dependency: vector-0.12.3.1+Dependency: vector-0.13.1.0 ================================================================================    Copyright (c) 2008-2012, Roman Leshchinskiy+                2020-2022, Alexey Kuleshevich+                2020-2022, Aleksey Khudyakov+                2020-2022, Andrew Lelechenko   All rights reserved.    Redistribution and use in source and binary forms, with or without@@ -1110,4 +1222,40 @@   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH   DAMAGE. +================================================================================+Dependency: vector-stream-0.1.0.1+================================================================================++  Copyright (c) 2008-2012, Roman Leshchinskiy+                2020-2022, Alexey Kuleshevich+                2020-2022, Aleksey Khudyakov+                2020-2022, Andrew Lelechenko+  All rights reserved.++  Redistribution and use in source and binary forms, with or without+  modification, are permitted provided that the following conditions are met:++  - Redistributions of source code must retain the above copyright notice,+  this list of conditions and the following disclaimer.++  - Redistributions in binary form must reproduce the above copyright notice,+  this list of conditions and the following disclaimer in the documentation+  and/or other materials provided with the distribution.++  - Neither name of the University nor the names of its contributors may be+  used to endorse or promote products derived from this software without+  specific prior written permission.++  THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF+  GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,+  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND+  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+  UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE+  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH+  DAMAGE. 
src/Convert.hs view
@@ -27,6 +27,7 @@ import qualified Convert.Foreach import qualified Convert.FuncRet import qualified Convert.FuncRoutine+import qualified Convert.GenvarName import qualified Convert.HierConst import qualified Convert.ImplicitNet import qualified Convert.Inside@@ -114,8 +115,10 @@     , Convert.DoWhile.convert     , Convert.Foreach.convert     , Convert.FuncRoutine.convert+    , Convert.GenvarName.convert     , selectExclude Job.Assert Convert.Assertion.convert     , selectExclude Job.Always Convert.AlwaysKW.convert+    , Convert.Interface.disambiguate     , Convert.Package.convert     , Convert.StructConst.convert     , Convert.PortDecl.convert
src/Convert/AlwaysKW.hs view
@@ -5,16 +5,18 @@  -  - `always_comb` and `always_latch` become `always @*`, or produce an explicit  - sensitivity list if they need to pick up sensitivities from the functions- - they call. `always_ff` simply becomes `always`.- -- - TODO: `always_comb` blocks do not run at time zero+ - they call. These blocks are triggered at time zero by adding a no-op+ - statement reading from `_sv2v_0`, which is injected and updated in an+ - `initial` block. `always_ff` simply becomes `always`.  -}  module Convert.AlwaysKW (convert) where +import Control.Monad (when, zipWithM, (>=>)) import Control.Monad.State.Strict import Control.Monad.Writer.Strict import Data.Maybe (fromMaybe, mapMaybe)+import Data.Monoid (Any(Any), getAny)  import Convert.Scoper import Convert.Traverse@@ -24,9 +26,15 @@ convert = map $ traverseDescriptions traverseDescription  traverseDescription :: Description -> Description-traverseDescription description@Part{} =-    evalState (evalScoperT $ scopePart op description) mempty-    where op = traverseModuleItem >=> scoper+traverseDescription (Part att ext kw lif name pts items) =+    Part att ext kw lif name pts $+    if getAny anys && not (elem triggerDecl items')+        then triggerDecl : items' ++ [triggerFire]+        else items'+    where+        op = traverseModuleItem >=> scoper+        (items', (anys, _)) = flip runState mempty $ evalScoperT $+            insertElem triggerIdent Var >> scopeModuleItems op name items traverseDescription description = description  type SC = ScoperT Kind (State (Any, [Expr]))@@ -182,12 +190,13 @@ -- custom traversal which converts SystemVerilog `always` keywords and tracks -- information about task and functions traverseModuleItem :: ModuleItem -> SC ModuleItem-traverseModuleItem (AlwaysC AlwaysLatch stmt) = do-    e <- fmap toEvent $ findNonLocals $ Initial stmt-    return $ AlwaysC Always $ Timing (Event e) stmt+traverseModuleItem (AlwaysC AlwaysLatch stmt) =+    traverseModuleItem $ AlwaysC AlwaysComb stmt traverseModuleItem (AlwaysC AlwaysComb stmt) = do-    e <- fmap toEvent $ findNonLocals $ Initial stmt-    return $ AlwaysC Always $ Timing (Event e) stmt+    push (Any True, [])+    e <- fmap toEvent $ findNonLocals $ Initial stmt'+    return $ AlwaysC Always $ Timing (Event e) stmt'+    where stmt' = addTriggerStmt stmt traverseModuleItem (AlwaysC AlwaysFF stmt) =     return $ AlwaysC Always stmt traverseModuleItem item@(MIPackageItem (Function _ _ x decls _)) = do@@ -220,8 +229,28 @@ findNonLocals :: ModuleItem -> SC (Bool, [Expr]) findNonLocals item = do     scopes <- get+    prev <- lift get     lift $ put mempty     _ <- scoper item     (anys, exprs) <- lift get+    lift $ put prev     let nonLocals = mapMaybe (longestStaticPrefix scopes) exprs     return (getAny anys, nonLocals)++triggerIdent :: Identifier+triggerIdent = "_sv2v_0"++triggerDecl :: ModuleItem+triggerDecl = MIPackageItem $ Decl $ Variable Local t triggerIdent [] Nil+    where t = IntegerVector TReg Unspecified []++triggerFire :: ModuleItem+triggerFire = Initial $ Asgn AsgnOpEq Nothing (LHSIdent triggerIdent) (RawNum 0)++triggerStmt :: Stmt+triggerStmt = If NoCheck (Ident triggerIdent) Null Null++addTriggerStmt :: Stmt -> Stmt+addTriggerStmt (Block Seq name decls stmts) =+    Block Seq name decls $ triggerStmt : stmts+addTriggerStmt stmt = Block Seq "" [] [triggerStmt, stmt]
src/Convert/Cast.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -@@ -28,9 +27,11 @@  module Convert.Cast (convert) where +import Control.Monad (when) import Control.Monad.Writer.Strict import Data.List (isPrefixOf) import Data.Maybe (isJust)+import Data.Monoid (Any(Any), getAny)  import Convert.ExprUtils import Convert.Scoper
src/Convert/EmptyArgs.hs view
@@ -64,7 +64,8 @@ traverseExpr :: Expr -> SC Expr traverseExpr (Call func (Args args [])) = do     details <- lookupElemM $ Dot func dummyIdent-    let args' = if details /= Nothing+    args' <- mapM traverseExpr $+                if details /= Nothing                     then RawNum 0 : args                     else args     return $ Call func (Args args' [])
src/Convert/ExprAsgn.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -
src/Convert/ExprUtils.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -@@ -14,6 +13,8 @@     , endianCondRange     , dimensionsSize     , stringToNumber+    , simplifyRange+    , simplifyDimensions     ) where  import Data.Bits ((.&.), (.|.), shiftL, shiftR)@@ -27,15 +28,15 @@  simplifyStep :: Expr -> Expr -simplifyStep (UniOp LogNot (Number n)) =+simplifyStep (UniOpA LogNot a (Number n)) =     case numberToInteger n of         Just 0 -> bool True         Just _ -> bool False-        Nothing -> UniOp LogNot $ Number n+        Nothing -> UniOpA LogNot a $ Number n simplifyStep (UniOp LogNot (BinOp Eq a b)) = BinOp Ne a b simplifyStep (UniOp LogNot (BinOp Ne a b)) = BinOp Eq a b -simplifyStep (UniOp UniSub (UniOp UniSub e)) = e+simplifyStep (UniOpA UniSub _ (UniOpA UniSub _ e)) = e simplifyStep (UniOp UniSub (BinOp Sub e1 e2)) = BinOp Sub e2 e1  simplifyStep (Concat [Number (Decimal size _ value)]) =@@ -47,11 +48,11 @@ simplifyStep (Concat es) = Concat $ flattenConcat es simplifyStep (Repeat (Dec 0) _) = Concat [] simplifyStep (Repeat (Dec 1) es) = Concat es-simplifyStep (Mux (Number n) e1 e2) =+simplifyStep (MuxA a (Number n) e1 e2) =     case numberToInteger n of         Just 0 -> e2         Just _ -> e1-        Nothing -> Mux (Number n) e1 e2+        Nothing -> MuxA a (Number n) e1 e2  simplifyStep (Call (Ident "$clog2") (Args [SizDec k] [])) =     simplifyStep $ Call (Ident "$clog2") (Args [RawNum k] [])@@ -159,6 +160,9 @@ simplifyBinOp op (ConvertedUU sz v k) (Number n) | isCmpOp op =     simplifyBinOp op (uuExtend sz v k) (Number n) +simplifyBinOp op (Number n) e | op == LogAnd || op == LogOr =+    simplifyLogAndOr op n e+ simplifyBinOp op e1 e2 =     case (e1, e2) of         (Dec    x, Dec    y) -> constantFold orig op   x    y@@ -284,9 +288,7 @@  -- convert a string to big integer stringToInteger :: String -> Integer-stringToInteger [] = 0-stringToInteger (x : xs) =-    fromIntegral (ord x) + (256 :: Integer) * stringToInteger xs+stringToInteger = foldl ((+) . (256 *)) 0 . map (fromIntegral . ord)  -- cast string to number at least as big as the width of the given number sizeStringAs :: String -> Number -> Expr@@ -319,3 +321,28 @@ pattern ConvertedUU sz v k <- Repeat     (RawNum sz)     [Number (Based 1 True Binary v k)]++simplifyRange :: Range -> Range+simplifyRange (e1, e2) = (simplify e1, simplify e2)++simplifyDimensions :: [Range] -> [Range]+simplifyDimensions = map simplifyRange++-- TODO: extend this to other logical binary operators+simplifyLogAndOr :: BinOp -> Number -> Expr -> Expr+simplifyLogAndOr op n1 (Number n2) =+    case (numberToInteger n1, numberToInteger n2) of+        (Just v, _) | (v /= 0) == isOr -> bool isOr+        (_, Just v) | (v /= 0) == isOr -> bool isOr+        (Nothing, _) -> boolUnknown+        (_, Nothing) -> boolUnknown+        _ -> bool $ not isOr+    where+        isOr = op == LogOr+        boolUnknown = Number $ Based 1 False Binary 0 1+simplifyLogAndOr op n e =+    case numberToInteger n of+        Just v | (v /= 0) == isOr -> bool isOr+        Just _ -> UniOp LogNot $ UniOp LogNot e+        Nothing -> BinOp op (Number n) e+    where isOr = op == LogOr
+ src/Convert/GenvarName.hs view
@@ -0,0 +1,127 @@+{- sv2v+ - Author: Zachary Snow <zach@zachjs.com>+ -+ - Assign unique names to `genvar`s to avoid conflicts within explicitly-scoped+ - variables when inlining interface arrays.+ -}++module Convert.GenvarName (convert) where++import Control.Monad (when)+import Control.Monad.State.Strict+import Control.Monad.Writer.Strict+import Data.Functor ((<&>))+import Data.List (isPrefixOf)+import qualified Data.Map.Strict as Map+import qualified Data.Set as Set++import Convert.Scoper (replaceInExpr)+import Convert.Traverse+import Language.SystemVerilog.AST++convert :: [AST] -> [AST]+convert files = evalState+    (mapM (traverseDescriptionsM traverseDescription) files)+    (collectFiles files, mempty)++type IdentSet = Set.Set Identifier+type IdentMap = Map.Map Identifier Identifier+type SC = State (IdentSet, IdentMap)++-- get all of the seemingly sv2v-generated genvar names already present anywhere+-- in the sources so we can avoid generating new ones that conflict with them+collectFiles :: [AST] -> IdentSet+collectFiles = execWriter . mapM (collectDescriptionsM collectDescription)++collectDescription :: Description -> Writer IdentSet ()+collectDescription = collectModuleItemsM collectModuleItem++collectModuleItem :: ModuleItem -> Writer IdentSet ()+collectModuleItem (Genvar ident) =+    when (isGeneratedName ident) $ tell (Set.singleton ident)+collectModuleItem _ = return ()++traverseDescription :: Description -> SC Description+traverseDescription (Part att ext kw lif name ports items) =+    mapM traverseModuleItem items <&> Part att ext kw lif name ports+traverseDescription description = return description++traverseModuleItem :: ModuleItem -> SC ModuleItem+traverseModuleItem (Genvar ident) =+    renameGenvar ident <&> Genvar+traverseModuleItem (Generate genItems) =+    mapM traverseGenItem genItems <&> Generate+traverseModuleItem (MIAttr attr item) =+    traverseModuleItem item <&> MIAttr attr+traverseModuleItem item = return item++traverseGenItem :: GenItem -> SC GenItem+traverseGenItem (GenFor start@(index, _) cond incr item)+    | not (isGeneratedName index) = do+    index' <- gets $ (Map.! index) . snd+    item' <- traverseGenItem item+    return $ if index == index'+        then GenFor start cond incr item'+        else renameInLoop start cond incr index' item'+traverseGenItem (GenBlock blk items) = do+    priorMapping <- gets snd+    items' <- mapM traverseGenItem items+    -- keep all assigned names, but prefer names from the outer scope+    modify' $ (, priorMapping) . fst+    return $ GenBlock blk items'+traverseGenItem (GenModuleItem item) =+    traverseModuleItem item <&> GenModuleItem+traverseGenItem item =+    traverseSinglyNestedGenItemsM traverseGenItem item++-- rename all usages of the genvar in the initialization, guard, and+-- incrementation of a generate for loop+renameInLoop :: (Identifier, Expr) -> Expr -> (Identifier, AsgnOp, Expr)+    -> Identifier -> GenItem -> GenItem+renameInLoop (index, start) cond (dest, op, next) index' =+    GenFor (index', start') cond' (dest', op, next') . prependGenItem decl+    where+        expr = Ident index'+        replacements = Map.singleton index expr+        start' = replaceInExpr replacements start+        cond' = replaceInExpr replacements cond+        next' = replaceInExpr replacements next+        dest' = if dest == index then index' else dest+        decl = GenModuleItem $ MIPackageItem $ Decl $+                Param Localparam UnknownType index expr++-- add an item to the beginning of the given generate block+prependGenItem :: GenItem -> GenItem -> GenItem+prependGenItem item block = GenBlock blk $ item : items+    where GenBlock blk items = block++prefixIntf :: Identifier+prefixIntf = "_arr_"+prefixUniq :: Identifier+prefixUniq = "_gv_"++isGeneratedName :: Identifier -> Bool+isGeneratedName ident =+    isPrefixOf prefixIntf ident ||+    isPrefixOf prefixUniq ident++-- generate and record a unique name for the given genvar+renameGenvar :: Identifier -> SC Identifier+renameGenvar ident | isGeneratedName ident = return ident+renameGenvar ident = do+    idents <- gets fst+    let ident' = uniqueGenvarName idents prefix 1+    modify' $ (<>) (Set.singleton ident', Map.singleton ident ident')+    return ident'+    where prefix = prefixUniq ++ ident ++ "_"++-- increment the counter until it produces a unique identifier+uniqueGenvarName :: IdentSet -> Identifier -> Int -> Identifier+uniqueGenvarName idents prefix = step+    where+        step :: Int -> Identifier+        step counter =+            if Set.member candidate idents+                then step $ counter + 1+                else candidate+            where candidate = prefix ++ show counter
src/Convert/ImplicitNet.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -
src/Convert/Inside.hs view
@@ -21,6 +21,7 @@  import Control.Monad.Writer import Data.Maybe (fromMaybe)+import Data.Monoid (Any(Any), getAny)  convert :: [AST] -> [AST] convert = map $ traverseDescriptions $ traverseModuleItems convertModuleItem@@ -43,8 +44,8 @@             BinOp LogAnd                 (BinOp Le lo expr)                 (BinOp Ge hi expr)-        toCheck pattern =-            BinOp WEq expr pattern+        toCheck pat =+            BinOp WEq expr pat convertExpr other = other  convertStmt :: Stmt -> Stmt
src/Convert/Interface.hs view
@@ -1,14 +1,15 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -  - Conversion for interfaces  -} -module Convert.Interface (convert) where+module Convert.Interface (convert, disambiguate) where  import Data.List (intercalate, (\\)) import Data.Maybe (isJust, isNothing, mapMaybe)+import Data.Monoid (Any(Any), getAny)+import Control.Monad (when, (>=>)) import Control.Monad.Writer.Strict import Text.Read (readMaybe) import qualified Data.Map.Strict as Map@@ -38,11 +39,6 @@             (map . convertDescription tops)             files     where-        -- we can only collect/map non-extern interfaces and modules-        collectPart :: Description -> Writer PartInfos ()-        collectPart (Part _ False kw _ name ports items) =-            tell $ Map.singleton name $ PartInfo kw ports items-        collectPart _ = return ()         -- multidimensional instances need to be flattened before this         -- conversion can proceed         needsFlattening =@@ -55,6 +51,67 @@         checkItem (Instance _ _ _ rs _) = when (length rs > 1) $ tell $ Any True         checkItem _ = return () +-- we can only collect/map non-extern interfaces and modules+collectPart :: Description -> Writer PartInfos ()+collectPart (Part _ False kw _ name ports items) =+    tell $ Map.singleton name $ PartInfo kw ports items+collectPart _ = return ()++-- disambiguate typenames from interface names+disambiguate :: [AST] -> [AST]+disambiguate = traverseFiles+    (collectDescriptionsM collectPart)+    (map . disambiguateDescription)++-- disambiguate any typenames within a description+disambiguateDescription :: PartInfos -> Description -> Description+disambiguateDescription parts (Part att ext kw lif name ports items) =+    Part att ext kw lif name ports $ map traverseModuleItem items+    where+        typeNames = getTypeNames items++        traverseModuleItem :: ModuleItem -> ModuleItem+        traverseModuleItem (MIAttr attr item) =+            MIAttr attr $ traverseModuleItem item+        traverseModuleItem (MIPackageItem (Decl (Variable d t x a e))) =+            MIPackageItem $ Decl $ Variable d (traverseType t) x a e+        traverseModuleItem other = other++        traverseType :: Type -> Type+        traverseType (Alias interfaceName rs) =+            if isInterface interfaceName && not (elem interfaceName typeNames)+                then InterfaceT interfaceName "" rs+                else Alias interfaceName rs+        traverseType orig@(InterfaceT interfaceName _ _) =+            if null interfaceName || isInterface interfaceName+                then orig+                else error $ "declaration type " ++ show orig ++ " appears to "+                    ++ "refer to an interface that isn't defined"+        traverseType other = other++        isInterface :: Identifier -> Bool+        isInterface partName =+            fmap pKind (Map.lookup partName parts) == Just Interface++disambiguateDescription _ other = other++-- get all of the typenames declared anywhere in the top-level module items+getTypeNames :: [ModuleItem] -> [Identifier]+getTypeNames (MIAttr _ item : rest) = getTypeNames $ item : rest+getTypeNames (Generate genItems : rest) =+    getTypeNames $ genModuleItems genItems ++ rest+getTypeNames (MIPackageItem (Decl (ParamType _ name _)) : rest) =+    name : getTypeNames rest+getTypeNames (_ : rest) = getTypeNames rest+getTypeNames [] = []++-- get the top-level (i.e., un-scoped) module items within a generate block+genModuleItems :: [GenItem] -> [ModuleItem]+genModuleItems (GenModuleItem item : rest) =+    item : genModuleItems rest+genModuleItems (_ : rest) = genModuleItems rest+genModuleItems [] = []+ topInterfaceError :: String -> String -> a topInterfaceError name issue = error $     "Specified top module " ++ name ++ " " ++ issue ++ ". Please " ++@@ -167,7 +224,10 @@                 then Nothing                 else Just (portName, modportBinding)             where-                modportBinding = (substitutions, replaceBit modportE)+                modportBinding =+                    ( substitutions+                    , scopeExprWithScopes modports $ replaceBit modportE+                    )                 substitutions =                     genSubstitutions modports base instanceE modportE                 maybeInfo =@@ -307,7 +367,6 @@                     else if elem x (pPorts partInfo) then                         tell [(x, info)] >> return decl                     else-                        -- TODO: This does not handle shadowed typenames.                         scopedErrorM $                             "Modport not in port list: " ++ show t ++ " " ++ x                             ++ ". Is this an interface missing a port list?"@@ -317,22 +376,9 @@                 checkDecl decl = return decl          extractModportInfo :: Type -> Maybe (Identifier, Identifier)-        extractModportInfo (InterfaceT "" "" _) = Just ("", "")         extractModportInfo (InterfaceT interfaceName modportName _) =-            if isInterface interfaceName-                then Just (interfaceName, modportName)-                else Nothing-        extractModportInfo (Alias interfaceName _) =-            if isInterface interfaceName-                then Just (interfaceName, "")-                else Nothing+            Just (interfaceName, modportName)         extractModportInfo _ = Nothing--        isInterface :: Identifier -> Bool-        isInterface partName =-            case Map.lookup partName parts of-                Nothing -> False-                Just info -> pKind info == Interface  convertDescription _ _ other = other 
src/Convert/Jump.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -@@ -12,6 +11,7 @@  import Control.Monad.State.Strict import Control.Monad.Writer.Strict+import Data.Monoid (Any(Any), getAny)  import Convert.Traverse import Language.SystemVerilog.AST
src/Convert/Logic.hs view
@@ -25,6 +25,7 @@  module Convert.Logic (convert) where +import Control.Monad (when) import Control.Monad.Writer.Strict import qualified Data.Map.Strict as Map import qualified Data.Set as Set@@ -168,8 +169,16 @@             let t' = Implicit sg rs             insertElem accesses t'             return $ Net d TWire DefaultStrength t' x a e-rewriteDeclM _ decl@(Variable _ t x _ _) =-    insertElem x t >> return decl+rewriteDeclM locations decl@(Variable d t x a e) = do+    inProcedure <- withinProcedureM+    case (d, t, inProcedure) of+        -- Reinterpret `input reg` module ports as `input logic`. We still don't+        -- treat `logic` and `reg` as the same keyword, as specifying `reg`+        -- explicitly is typically expected to flow downstream.+        (Input, IntegerVector TReg sg rs, False) ->+            rewriteDeclM locations $ Variable Input t' x a e+            where t' = IntegerVector TLogic sg rs+        _ -> insertElem x t >> return decl rewriteDeclM _ (Net d n s (IntegerVector _ sg rs) x a e) =     insertElem x t >> return (Net d n s t x a e)     where t = Implicit sg rs
src/Convert/MultiplePacked.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE TupleSections #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -@@ -51,21 +50,22 @@ -- collects and converts declarations with multiple packed dimensions traverseDeclM :: Decl -> Scoper TypeInfo Decl traverseDeclM (Variable dir t ident a e) = do-    t' <- traverseTypeM t a ident+    recordTypeM t a ident     traverseDeclExprsM traverseExprM $ Variable dir t' ident a e+    where t' = flattenType t traverseDeclM net@Net{} =     traverseNetAsVarM traverseDeclM net traverseDeclM (Param s t ident e) = do-    t' <- traverseTypeM t [] ident+    recordTypeM t [] ident     traverseDeclExprsM traverseExprM $ Param s t' ident e+    where t' = flattenType t traverseDeclM other = traverseDeclExprsM traverseExprM other --- write down the given declaration and then flatten it-traverseTypeM :: Type -> [Range] -> Identifier -> Scoper TypeInfo Type-traverseTypeM t a ident = do+-- write down the given declaration+recordTypeM :: Type -> [Range] -> Identifier -> Scoper TypeInfo ()+recordTypeM t a ident = do     tScoped <- scopeType t     insertElem ident (tScoped, a)-    return $ flattenType t  -- flatten the innermost dimension of the given type, and any types it contains flattenType :: Type -> Type@@ -133,8 +133,21 @@     traverseStmtExprsM traverseExprM  traverseExprM :: Expr -> Scoper TypeInfo Expr-traverseExprM = traverseNestedExprsM convertExprM+traverseExprM =+    embedScopes convertExpr >=>+    traverseExprTypesM traverseTypeM >=>+    traverseSinglyNestedExprsM traverseExprM +traverseTypeM :: Type -> Scoper TypeInfo Type+traverseTypeM typ =+    traverseTypeExprsM traverseExprM >=>+    traverseSinglyNestedTypesM traverseTypeM $+    case typ of+        Struct{} -> typ'+        Union {} -> typ'+        _ -> typ+    where typ' = traverseSinglyNestedTypes flattenType typ+ traverseGenItemM :: GenItem -> Scoper TypeInfo GenItem traverseGenItemM = traverseGenItemExprsM traverseExprM @@ -148,19 +161,9 @@         traverseLHSSingleM :: LHS -> Scoper TypeInfo LHS         traverseLHSSingleM lhs = do             let expr = lhsToExpr lhs-            expr' <- convertExprM expr+            expr' <- embedScopes convertExpr expr             let Just lhs' = exprToLHS expr'             return lhs'--convertExprM :: Expr -> Scoper TypeInfo Expr-convertExprM =-    traverseExprTypesM convertTypeM >=>-    embedScopes convertExpr--convertTypeM :: Type -> Scoper TypeInfo Type-convertTypeM =-    traverseNestedTypesM $ traverseTypeExprsM $-    traverseNestedExprsM convertExprM  convertExpr :: Scopes TypeInfo -> Expr -> Expr convertExpr scopes =
src/Convert/Package.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE TupleSections #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -@@ -24,8 +23,10 @@     , prefixItems     ) where +import Control.Monad (when, (>=>)) import Control.Monad.State.Strict import Control.Monad.Writer.Strict+import Data.Functor ((<&>)) import Data.List (insert, intercalate, isPrefixOf) import Data.Maybe (mapMaybe) import qualified Data.Map.Strict as Map@@ -262,6 +263,9 @@                             ++ " conflicts with prior import of "                             ++ otherPkg ++ "::" ++ ident +pattern PatternTag :: Char+pattern PatternTag = '*'+ -- main logic responsible for translating packages, resolving imports and -- exports, and rewriting identifiers referring to package declarations processItems :: Identifier -> Identifier -> [ModuleItem]@@ -367,7 +371,10 @@                 Variable d t x a e -> declHelp x $ \x' -> Variable d t x' a e                 Net  d n s t x a e -> declHelp x $ \x' -> Net  d n s t x' a e                 Param    p t x   e -> declHelp x $ \x' -> Param    p t x'   e-                ParamType  p x   t -> declHelp x $ \x' -> ParamType  p x'   t+                ParamType  p x   t ->+                    -- make this typename available for use in patterns+                    prefixIdent (PatternTag : x) >>+                    declHelp x (\x' -> ParamType p x' t)                 CommentDecl c -> return $ CommentDecl c             where declHelp x f = prefixIdent x >>= return . f @@ -410,10 +417,25 @@             x' <- resolvePSIdent' p x             return $ Ident x'         traverseExprM (Ident x) = resolveIdent x >>= return . Ident+        traverseExprM (Pattern items) = do+            keys' <- mapM keyMapper keys+            vals' <- mapM traverseExprM vals+            return $ Pattern $ zip keys' vals'+            where (keys, vals) = unzip items         traverseExprM other =             traverseSinglyNestedExprsM traverseExprM other             >>= traverseExprTypesM traverseTypeM +        -- equivalent to the special case in traverseExprIdentsM+        keyMapper (Left t) =+            traverseTypeM t <&> Left+        keyMapper (Right (Ident x)) = do+            tagged' <- traverseExprM $ Ident $ PatternTag : x+            let Ident x' = tagged'+            return $ Right $ Ident $ filter (/= PatternTag) x'+        keyMapper (Right e) =+            traverseExprM e <&> Right+         traverseLHSM :: LHS -> Scope LHS         traverseLHSM (LHSIdent x) = resolveIdent x >>= return . LHSIdent         traverseLHSM other = traverseSinglyNestedLHSsM traverseLHSM other@@ -784,14 +806,29 @@  -- visits all identifiers in an expression traverseExprIdentsM :: Monad m => MapperM m Identifier -> MapperM m Expr-traverseExprIdentsM identMapper = fullMapper+traverseExprIdentsM identMapper = exprMapper     where-        fullMapper = exprMapper >=> traverseSinglyNestedExprsM fullMapper-        exprMapper (Call (Ident x) args) =-            identMapper x >>= \x' -> return $ Call (Ident x') args         exprMapper (Ident x) = identMapper x >>= return . Ident-        exprMapper other = return other+        exprMapper (Pattern items) = do+            keys' <- mapM keyMapper keys+            vals' <- mapM exprMapper vals+            return $ Pattern $ zip keys' vals'+            where (keys, vals) = unzip items+        exprMapper other =+            traverseExprTypesM (traverseTypeIdentsM identMapper) other >>=+            traverseSinglyNestedExprsM exprMapper +        -- Don't reorder or inject a pattern key unless it refers to a known+        -- typename. TODO: This prevents referring to expressions in packages in+        -- pattern keys, though this probably isn't common.+        keyMapper (Left t) =+            traverseTypeIdentsM identMapper t <&> Left+        keyMapper (Right (Ident x)) =+            identMapper (PatternTag : x)+                <&> filter (/= PatternTag) <&> Ident <&> Right+        keyMapper (Right e) =+            exprMapper e <&> Right+ -- visits all identifiers in a type traverseTypeIdentsM :: Monad m => MapperM m Identifier -> MapperM m Type traverseTypeIdentsM identMapper = fullMapper@@ -814,14 +851,9 @@  -- visits all identifiers in a statement traverseStmtIdentsM :: Monad m => MapperM m Identifier -> MapperM m Stmt-traverseStmtIdentsM identMapper = fullMapper-    where-        fullMapper = stmtMapper-            >=> traverseStmtExprsM (traverseExprIdentsM identMapper)-            >=> traverseStmtLHSsM  (traverseLHSIdentsM  identMapper)-        stmtMapper (Subroutine (Ident x) args) =-            identMapper x >>= \x' -> return $ Subroutine (Ident x') args-        stmtMapper other = return other+traverseStmtIdentsM identMapper =+    traverseStmtExprsM (traverseExprIdentsM identMapper) >=>+    traverseStmtLHSsM  (traverseLHSIdentsM  identMapper)  -- visits all identifiers in a declaration traverseDeclIdentsM :: Monad m => MapperM m Identifier -> MapperM m Decl@@ -838,7 +870,7 @@ piNames (Decl (Variable _ _ ident _ _)) = [ident] piNames (Decl (Net  _ _ _ _ ident _ _)) = [ident] piNames (Decl (Param    _ _ ident   _)) = [ident]-piNames (Decl (ParamType  _ ident   _)) = [ident]+piNames (Decl (ParamType  _ ident   _)) = [ident, PatternTag : ident] piNames (Decl (CommentDecl          _)) = [] piNames item@DPIImport{} = [show item] piNames item@DPIExport{} = [show item]
src/Convert/ParamNoDefault.hs view
@@ -14,6 +14,7 @@  module Convert.ParamNoDefault (convert) where +import Control.Monad (when) import Control.Monad.Writer.Strict import Data.List (intercalate) import qualified Data.Map.Strict as Map
src/Convert/ParamType.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE TupleSections #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -@@ -12,6 +10,7 @@ import Data.Either (isRight, lefts) import qualified Data.Map.Strict as Map import qualified Data.Set as Set+import Data.Monoid (Any(Any), getAny)  import Convert.Traverse import Language.SystemVerilog.AST
src/Convert/PortDecl.hs view
@@ -18,6 +18,7 @@ import Data.List (intercalate, (\\)) import Data.Maybe (mapMaybe) +import Convert.ExprUtils (simplifyDimensions) import Convert.Traverse import Language.SystemVerilog.AST @@ -34,9 +35,9 @@  convertPackageItem :: PackageItem -> PackageItem convertPackageItem (Function l t x decls stmts) =-   Function l t x (convertTFDecls decls) stmts+    Function l t x (convertTFDecls decls) stmts convertPackageItem (Task l x decls stmts) =-   Task l x (convertTFDecls decls) stmts+    Task l x (convertTFDecls decls) stmts convertPackageItem other = other  convertPorts :: Identifier -> [Identifier] -> [ModuleItem] -> [ModuleItem]@@ -102,9 +103,9 @@ combineDecls portDecl dataDecl     | eP /= Nil =         mismatch "invalid initialization at port declaration"-    | aP /= aD =+    | simplifyDimensions aP /= simplifyDimensions aD =         mismatch "different unpacked dimensions"-    | rsP /= rsD =+    | simplifyDimensions rsP /= simplifyDimensions rsD =         mismatch "different packed dimensions"     | otherwise =         base (tf rsD) ident aD Nil
src/Convert/ResolveBindings.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE TupleSections #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -
src/Convert/Scoper.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE TupleSections #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE FlexibleInstances #-} {- sv2v@@ -39,6 +38,8 @@     , replaceInExpr     , scopeExpr     , scopeType+    , scopeExprWithScopes+    , scopeTypeWithScopes     , insertElem     , removeElem     , injectItem@@ -69,6 +70,7 @@     , LookupResult     ) where +import Control.Monad (join, when) import Control.Monad.State.Strict import Data.List (findIndices, intercalate, isPrefixOf, partition) import Data.Maybe (isNothing)@@ -209,6 +211,12 @@  {-# INLINABLE scopeExpr #-} {-# INLINABLE scopeType #-}++scopeExprWithScopes :: Scopes a -> Expr -> Expr+scopeExprWithScopes scopes = flip evalState scopes . scopeExpr++scopeTypeWithScopes :: Scopes a -> Type -> Type+scopeTypeWithScopes scopes = flip evalState scopes . scopeType  class ScopePath k where     toTiers :: Scopes a -> k -> [Tier]
src/Convert/Simplify.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -@@ -17,8 +16,6 @@  module Convert.Simplify (convert) where -import Control.Monad (when)- import Convert.ExprUtils import Convert.Scoper import Convert.Traverse@@ -53,13 +50,14 @@ insertExpr :: Identifier -> Expr -> Scoper Expr () insertExpr ident expr = do     expr' <- substituteExprM expr-    case expr' of+    insertElem ident $ case expr' of         Cast (Left (SimpleVector sg l r)) (Number n) ->-            insertElem ident $ Number $ numberCast signed size n+            Number $ numberCast signed size n             where                 signed = sg == Signed                 size = fromIntegral $ abs $ l - r + 1-        _ -> when (isSimpleExpr expr') $ insertElem ident expr'+        _ | isSimpleExpr expr' -> expr'+        _ -> Nil  isSimpleExpr :: Expr -> Bool isSimpleExpr Number{}  = True@@ -84,7 +82,7 @@ traverseGenItemM = traverseGenItemExprsM traverseExprM  traverseStmtM :: Stmt -> Scoper Expr Stmt-traverseStmtM stmt = traverseStmtExprsM traverseExprM stmt+traverseStmtM = traverseStmtExprsM traverseExprM  traverseExprM :: Expr -> Scoper Expr Expr traverseExprM = embedScopes convertExpr@@ -114,27 +112,27 @@         e' = convertExpr info $ substitute info e         val = Call (Ident "$clog2") (Args [e'] [])         val' = simplifyStep val-convertExpr info (Mux cc aa bb) =+convertExpr info (MuxA a cc aa bb) =     if before == after-        then simplifyStep $ Mux cc' aa' bb'-        else simplifyStep $ Mux after aa' bb'+        then simplifyStep $ MuxA a cc' aa' bb'+        else simplifyStep $ MuxA a after aa' bb'     where         before = substitute info cc'         after = convertExpr info before         aa' = convertExpr info aa         bb' = convertExpr info bb         cc' = convertExpr info cc-convertExpr info (BinOp op e1 e2) =-    case simplifyStep $ BinOp op e1'Sub e2'Sub of+convertExpr info (BinOpA op a e1 e2) =+    case simplifyStep $ BinOpA op a e1'Sub e2'Sub of         Number n -> Number n-        _ -> simplifyStep $ BinOp op e1' e2'+        _ -> simplifyStep $ BinOpA op a e1' e2'     where         e1' = convertExpr info e1         e2' = convertExpr info e2         e1'Sub = substituteIdent info e1'         e2'Sub = substituteIdent info e2'-convertExpr info (UniOp op expr) =-    simplifyStep $ UniOp op $ convertExpr info expr+convertExpr info (UniOpA op a expr) =+    simplifyStep $ UniOpA op a $ convertExpr info expr convertExpr info (Repeat expr exprs) =     simplifyStep $ Repeat         (convertExpr info expr)
src/Convert/Stream.hs view
@@ -47,7 +47,7 @@ traverseModuleItemM (Assign opt lhs (Stream StreamL chunk exprs)) =     injectItem (MIPackageItem func) >> return (Assign opt lhs expr')     where-        fnName = streamerFuncName $ shortHash lhs+        fnName = streamerFuncName $ shortHash (lhs, chunk, exprs)         t = TypeOf $ lhsToExpr lhs         arg = Concat exprs         func = streamerFunc fnName chunk (TypeOf arg) t@@ -56,12 +56,25 @@     traverseModuleItemM $         Assign opt (LHSConcat lhss)         (Stream StreamL chunk [expr])+traverseModuleItemM (Assign opt lhs (Mux cond expr@Stream{} other)) = do+    (lhs', expr') <- indirectAssign lhs expr+    return $ Assign opt lhs' $ Mux cond expr' other+traverseModuleItemM (Assign opt lhs (Mux cond other expr@Stream{})) = do+    (lhs', expr') <- indirectAssign lhs expr+    return $ Assign opt lhs' $ Mux cond other expr' traverseModuleItemM (Assign opt lhs expr) =     traverseExprM expr' >>= return . Assign opt lhs'     where Asgn AsgnOpEq Nothing lhs' expr' =             traverseAsgn (lhs, expr) (Asgn AsgnOpEq Nothing) traverseModuleItemM item = return item +indirectAssign :: LHS -> Expr -> Scoper () (LHS, Expr)+indirectAssign lhs expr = do+    let item = Assign AssignOptionNone lhs expr+    item' <- traverseModuleItemM item+    let Assign AssignOptionNone lhs' expr' = item'+    return (lhs', expr')+ traverseStmtM :: Stmt -> Scoper () Stmt traverseStmtM (Subroutine fn (Args args [])) = do     args' <- traverseCall fn args@@ -190,6 +203,12 @@         lhs = LHSConcat lhss         lhsSize = sizeof $ lhsToExpr lhs         exprSize = sizeof expr+traverseAsgn (lhs, Mux cond e1@Stream{} e2) constructor =+    traverseAsgn (lhs, e1) constructor'+    where constructor' lhs' e1' = constructor lhs' $ Mux cond e1' e2+traverseAsgn (lhs, Mux cond e1 e2@Stream{}) constructor =+    traverseAsgn (lhs, e2) constructor'+    where constructor' lhs' e2' = constructor lhs' $ Mux cond e1 e2' traverseAsgn (lhs, expr) constructor =     constructor lhs expr 
src/Convert/StringParam.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -@@ -12,6 +11,7 @@  module Convert.StringParam (convert) where +import Control.Monad (when) import Control.Monad.Writer.Strict import Data.Maybe (mapMaybe) import qualified Data.Set as Set@@ -53,7 +53,7 @@  -- utility pattern for candidate string parameter items pattern StringParam :: Identifier -> String -> ModuleItem-pattern StringParam x s =+pattern StringParam x s <-     MIPackageItem (Decl (Param Parameter UnknownType x (String s)))  -- write down which parameters may be variable-length strings
src/Convert/Struct.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE TupleSections #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -@@ -198,8 +196,8 @@ -- try expression conversion by looking at the *outermost* type first convertExpr :: Scopes a -> Type -> Expr -> Expr convertExpr _ _ Nil = Nil-convertExpr scopes t (Mux c e1 e2) =-    Mux c e1' e2'+convertExpr scopes t (MuxA a c e1 e2) =+    MuxA a c e1' e2'     where         e1' = convertExpr scopes t e1         e2' = convertExpr scopes t e2@@ -319,8 +317,8 @@         t' = dropInnerTypeRange t         isUnsizedNumber :: Expr -> Bool         isUnsizedNumber (Number n) = not $ numberIsSized n-        isUnsizedNumber (UniOp _ e) = isUnsizedNumber e-        isUnsizedNumber (BinOp _ e1 e2) =+        isUnsizedNumber (UniOpA _ _ e) = isUnsizedNumber e+        isUnsizedNumber (BinOpA _ _ e1 e2) =             isUnsizedNumber e1 || isUnsizedNumber e2         isUnsizedNumber _ = False @@ -497,8 +495,11 @@         (retType, _) = fallbackType scopes e         args' = convertCall scopes e args convertSubExpr scopes (Cast (Left t) e) =-    (t, Cast (Left t) e')-    where (_, e') = convertSubExpr scopes e+    (t', Cast (Left t') e')+    where+        e' = convertExpr scopes t $ snd $ convertSubExpr scopes e+        t' = convertType t+ convertSubExpr scopes (Pattern items) =     if all (== Right Nil) $ map fst items'         then (UnknownType, Concat $ map snd items')@@ -507,8 +508,8 @@         items' = map mapItem items         mapItem (x, e) = (x, e')             where (_, e') = convertSubExpr scopes e-convertSubExpr scopes (Mux a b c) =-    (t, Mux a' b' c')+convertSubExpr scopes (MuxA r a b c) =+    (t, MuxA r a' b' c')     where         (_, a') = convertSubExpr scopes a         (t, b') = convertSubExpr scopes b
src/Convert/StructConst.hs view
@@ -9,6 +9,7 @@  module Convert.StructConst (convert) where +import Control.Monad (join, mplus, when) import Control.Monad.State.Strict import Data.Maybe (fromMaybe) import Data.Tuple (swap)
src/Convert/Traverse.hs view
@@ -112,6 +112,7 @@  import Data.Bitraversable (bimapM) import Data.Functor.Identity (Identity, runIdentity)+import Control.Monad ((>=>)) import Control.Monad.Writer.Strict import Language.SystemVerilog.AST @@ -256,6 +257,7 @@         cs (Subroutine expr exprs) = return $ Subroutine expr exprs         cs (Trigger blocks x) = return $ Trigger blocks x         cs stmt@Force{} = return stmt+        cs (Wait e stmt) = fullMapper stmt >>= return . Wait e         cs (Assertion a) =             traverseAssertionStmtsM fullMapper a >>= return . Assertion         cs (Continue) = return Continue@@ -448,17 +450,17 @@             pes <- mapM exprMapper $ map snd p             let p' = zip (map fst p) pes             return $ Call e' (Args l' p')-        em (UniOp      o e) =-            exprMapper e >>= return . UniOp o-        em (BinOp      o e1 e2) = do+        em (UniOpA   o a e) =+            exprMapper e >>= return . UniOpA o a+        em (BinOpA   o a e1 e2) = do             e1' <- exprMapper e1             e2' <- exprMapper e2-            return $ BinOp o e1' e2'-        em (Mux        e1 e2 e3) = do+            return $ BinOpA o a e1' e2'+        em (MuxA    a e1 e2 e3) = do             e1' <- exprMapper e1             e2' <- exprMapper e2             e3' <- exprMapper e3-            return $ Mux e1' e2' e3'+            return $ MuxA a e1' e2' e3'         em (Cast tore e) = do             tore' <- typeOrExprMapper tore             e' <- exprMapper e@@ -710,6 +712,8 @@         l' <- lhsMapper l         e' <- exprMapper e         return $ Force kw l' e'+    flatStmtMapper (Wait e stmt) =+        exprMapper e >>= \e' -> return $ Wait e' stmt     flatStmtMapper (Assertion a) =         traverseAssertionExprsM exprMapper a >>= return . Assertion     flatStmtMapper (Continue) = return Continue
src/Convert/TypeOf.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -@@ -255,9 +254,9 @@                 Just typ -> typ                 Nothing -> TypeOf orig typeof (Cast (Left t) _) = traverseTypeM t-typeof (UniOp op expr) = typeofUniOp op expr-typeof (BinOp op a b) = typeofBinOp op a b-typeof (Mux   _       a b) = largerSizeType a b+typeof (UniOpA op _  expr) = typeofUniOp op expr+typeof (BinOpA op _   a b) = typeofBinOp op a b+typeof (MuxA      _ _ a b) = largerSizeType a b typeof (Concat      exprs) = return $ typeOfSize Unsigned $ concatSize exprs typeof (Stream _ _  exprs) = return $ typeOfSize Unsigned $ concatSize exprs typeof (Repeat reps exprs) = return $ typeOfSize Unsigned size@@ -378,7 +377,7 @@ -- returns the size of an expression, with the short-circuiting sizeof :: Expr -> Expr sizeof (Number n) = RawNum $ numberBitLength n-sizeof (Mux _ a b) = largerSizeOf a b+sizeof (MuxA _ _ a b) = largerSizeOf a b sizeof expr = DimsFn FnBits $ Left $ TypeOf expr  -- returns the maximum size of the two given expressions@@ -446,8 +445,8 @@ makeExplicit :: Expr -> Expr makeExplicit (Number n) =     Number $ numberCast (numberIsSigned n) (fromIntegral $ numberBitLength n) n-makeExplicit (BinOp op e1 e2) =-    BinOp op (makeExplicit e1) (makeExplicit e2)-makeExplicit (UniOp op e) =-    UniOp op $ makeExplicit e+makeExplicit (BinOpA op a e1 e2) =+    BinOpA op a (makeExplicit e1) (makeExplicit e2)+makeExplicit (UniOpA op a e) =+    UniOpA op a $ makeExplicit e makeExplicit other = other
src/Convert/Typedef.hs view
@@ -1,7 +1,7 @@ {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -- - Conversion for `typedef`+ - Conversion for `typedef` and `localparam type`  -  - Aliased types can appear in all data declarations, including modules, blocks,  - and function parameters. They are also found in type cast expressions.@@ -20,22 +20,44 @@     where scoper = scopeModuleItem             traverseDeclM traverseModuleItemM traverseGenItemM traverseStmtM -traverseTypeOrExprM :: TypeOrExpr -> Scoper Type TypeOrExpr-traverseTypeOrExprM (Left (TypeOf (Ident x))) = do-    details <- lookupElemM x-    return $ case details of-        Nothing -> Left $ TypeOf $ Ident x-        Just (_, _, UnknownType) -> Left $ TypeOf $ Ident x-        Just (_, _, typ) -> Left typ-traverseTypeOrExprM (Right (Ident x)) = do-    details <- lookupElemM x-    return $ case details of-        Nothing -> Right $ Ident x-        Just (_, _, UnknownType) -> Right $ Ident x-        Just (_, _, typ) -> Left typ-traverseTypeOrExprM other = return other+type SC = Scoper IdentKind -traverseExprM :: Expr -> Scoper Type Expr+data IdentKind+    = Type Type -- resolved typename+    | Pending -- unresolved type parameter+    | NonType String -- anything else++traverseTypeOrExprM :: TypeOrExpr -> SC TypeOrExpr+traverseTypeOrExprM tore+    | Left (TypeOf expr) <- tore = possibleTypeName tore expr+    | Right expr <- tore = possibleTypeName tore expr+    | otherwise = return tore++possibleTypeName :: TypeOrExpr -> Expr -> SC TypeOrExpr+possibleTypeName orig expr+    | Just (x, rs1) <- maybeTypeName = do+        details <- lookupElemM x+        return $ case details of+            Just (_, _, Type typ) ->+                Left $ tf $ rs1 ++ rs2+                where (tf, rs2) = typeRanges typ+            Just (_, _, Pending) ->+                Left $ Alias x rs1+            _ -> orig+    | otherwise = return orig+    where maybeTypeName = exprToTypeName [] expr++-- aliases in type-or-expr contexts are parsed as expressions+exprToTypeName :: [Range] -> Expr -> Maybe (Identifier, [Range])+exprToTypeName rs (Ident x) = Just (x, rs)+exprToTypeName rs (Bit expr idx) =+    exprToTypeName (r : rs) expr+    where r = (RawNum 0, BinOp Sub idx (RawNum 1))+exprToTypeName rs (Range expr NonIndexed r) = do+    exprToTypeName (r : rs) expr+exprToTypeName _ _ = Nothing++traverseExprM :: Expr -> SC Expr traverseExprM (Cast v e) = do     v' <- traverseTypeOrExprM v     traverseExprM' $ Cast v' e@@ -51,68 +73,82 @@     traverseExprM' $ Pattern $ zip names exprs traverseExprM other = traverseExprM' other -traverseExprM' :: Expr -> Scoper Type Expr+traverseExprM' :: Expr -> SC Expr traverseExprM' =     traverseSinglyNestedExprsM traverseExprM     >=> traverseExprTypesM traverseTypeM -traverseModuleItemM :: ModuleItem -> Scoper Type ModuleItem+traverseModuleItemM :: ModuleItem -> SC ModuleItem traverseModuleItemM (Instance m params x rs p) = do     let mapParam (i, v) = traverseTypeOrExprM v >>= \v' -> return (i, v')     params' <- mapM mapParam params     traverseModuleItemM' $ Instance m params' x rs p traverseModuleItemM item = traverseModuleItemM' item -traverseModuleItemM' :: ModuleItem -> Scoper Type ModuleItem+traverseModuleItemM' :: ModuleItem -> SC ModuleItem traverseModuleItemM' =     traverseNodesM traverseExprM return traverseTypeM traverseLHSM return     where traverseLHSM = traverseLHSExprsM traverseExprM -traverseGenItemM :: GenItem -> Scoper Type GenItem+traverseGenItemM :: GenItem -> SC GenItem traverseGenItemM = traverseGenItemExprsM traverseExprM -traverseDeclM :: Decl -> Scoper Type Decl+traverseDeclM :: Decl -> SC Decl traverseDeclM decl = do     decl' <- traverseDeclNodesM traverseTypeM traverseExprM decl     case decl' of-        Variable{} -> return decl'-        Net{} -> return decl'+        Variable _ _ x _ _ -> insertElem x (NonType "var") >> return decl'+        Net  _ _ _ _ x _ _ -> insertElem x (NonType "net") >> return decl'         Param s (UnpackedType t rs1) x e -> do-            insertElem x UnknownType+            insertElem x (NonType $ show s)             let (tf, rs2) = typeRanges t             let t' = tf $ rs1 ++ rs2             return $ Param s t' x e-        Param _ _ x _ ->-            insertElem x UnknownType >> return decl'+        Param s _ x _ ->+            insertElem x (NonType $ show s) >> return decl'         ParamType Localparam x t -> do-            traverseTypeM t >>= scopeType >>= insertElem x+            traverseTypeM t >>= scopeType >>= insertElem x . Type             return $ case t of                 Enum{} -> ParamType Localparam tmpX t                 _ -> CommentDecl $ "removed localparam type " ++ x             where tmpX = "_sv2v_keep_enum_for_params"-        ParamType{} -> return decl'+        ParamType Parameter x _ ->+            insertElem x Pending >> return decl'         CommentDecl{} -> return decl' -traverseStmtM :: Stmt -> Scoper Type Stmt+traverseStmtM :: Stmt -> SC Stmt traverseStmtM = traverseStmtExprsM traverseExprM -traverseTypeM :: Type -> Scoper Type Type+traverseTypeM :: Type -> SC Type traverseTypeM (Alias st rs1) = do     details <- lookupElemM st     rs1' <- mapM traverseRangeM rs1-    return $ case details of-        Nothing -> Alias st rs1'-        Just (_, _, UnknownType) -> Alias st rs1'-        Just (_, _, typ) -> tf $ rs1' ++ rs2+    case details of+        Just (_, _, Type typ) ->+            return $ tf $ rs1' ++ rs2             where (tf, rs2) = typeRanges typ+        Just (_, _, Pending) ->+            return $ Alias st rs1'+        Just (_, _, NonType kind) ->+            scopedErrorM $ "expected typename, but found " ++ kind+                ++ " identifier " ++ show st+        Nothing ->+            scopedErrorM $ "couldn't resolve typename " ++ show st traverseTypeM (TypedefRef expr) = do     details <- lookupElemM expr-    return $ case details of-        Nothing -> TypedefRef expr-        Just (_, _, typ) -> typ+    case details of+        Just (_, _, Type typ) -> return typ+        Just (_, _, Pending) ->+            error "TypdefRef invariant violated! Please file an issue."+        Just (_, _, NonType kind) ->+            scopedErrorM $ "expected interface-based typename, but found "+                ++ kind ++ " " ++ show expr+        -- This can occur when the interface conversion is delayed due to+        -- multi-dimension instances.+        Nothing -> return $ TypedefRef expr traverseTypeM other =     traverseSinglyNestedTypesM traverseTypeM other     >>= traverseTypeExprsM traverseExprM -traverseRangeM :: Range -> Scoper Type Range+traverseRangeM :: Range -> SC Range traverseRangeM = mapBothM traverseExprM
src/Convert/UnbasedUnsized.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -@@ -21,6 +20,7 @@ import Data.Either (isLeft) import Data.Maybe (isNothing, mapMaybe) import qualified Data.Map.Strict as Map+import Data.Monoid (Any(Any), getAny)  import Convert.Package (inject, prefixItems) import Convert.Traverse@@ -218,48 +218,48 @@     where pnArgs' = map (convertExpr SelfDetermined) pnArgs convertExpr _ (Repeat count exprs) =     Repeat count $ map (convertExpr SelfDetermined) exprs-convertExpr SelfDetermined (Mux cond e1@UU{} e2@UU{}) =-    Mux+convertExpr SelfDetermined (MuxA a cond e1@UU{} e2@UU{}) =+    MuxA a     (convertExpr SelfDetermined cond)     (convertExpr SelfDetermined e1)     (convertExpr SelfDetermined e2)-convertExpr SelfDetermined (Mux cond e1 e2) =-    Mux+convertExpr SelfDetermined (MuxA a cond e1 e2) =+    MuxA a     (convertExpr SelfDetermined cond)     (convertExpr (ContextDetermined e2) e1)     (convertExpr (ContextDetermined e1) e2)-convertExpr (ContextDetermined expr) (Mux cond e1 e2) =-    Mux+convertExpr (ContextDetermined expr) (MuxA a cond e1 e2) =+    MuxA a     (convertExpr SelfDetermined cond)     (convertExpr context e1)     (convertExpr context e2)     where context = ContextDetermined expr-convertExpr SelfDetermined (BinOp op e1 e2) =+convertExpr SelfDetermined (BinOpA op a e1 e2) =     if isPeerSizedBinOp op || isParentSizedBinOp op-        then BinOp op+        then BinOpA op a             (convertExpr (ContextDetermined e2) e1)             (convertExpr (ContextDetermined e1) e2)-        else BinOp op+        else BinOpA op a             (convertExpr SelfDetermined e1)             (convertExpr SelfDetermined e2)-convertExpr (ContextDetermined expr) (BinOp op e1 e2) =+convertExpr (ContextDetermined expr) (BinOpA op a e1 e2) =     if isPeerSizedBinOp op then-        BinOp op+        BinOpA op a             (convertExpr (ContextDetermined e2) e1)             (convertExpr (ContextDetermined e1) e2)     else if isParentSizedBinOp op then-        BinOp op+        BinOpA op a             (convertExpr context e1)             (convertExpr context e2)     else-        BinOp op+        BinOpA op a             (convertExpr SelfDetermined e1)             (convertExpr SelfDetermined e2)     where context = ContextDetermined expr-convertExpr context (UniOp op expr) =+convertExpr context (UniOpA op a expr) =     if isSizedUniOp op-        then UniOp op (convertExpr context expr)-        else UniOp op (convertExpr SelfDetermined expr)+        then UniOpA op a (convertExpr context expr)+        else UniOpA op a (convertExpr SelfDetermined expr) convertExpr SelfDetermined (UU bit) =     literalFor bit convertExpr (ContextDetermined expr) (UU bit) =
src/Convert/Unique.hs view
@@ -3,9 +3,9 @@  -  - Conversion for `unique`, `unique0`, and `priority` (verification checks)  -- - This conversion simply drops these keywords, as they are only used for- - optimization and verification. There may be ways to communicate these- - attributes to certain downstream toolchains.+ - For `case`, these verification checks are replaced with equivalent+ - `full_case` and `parallel_case` attributes. For `if`, they are simply+ - dropped.  -}  module Convert.Unique (convert) where@@ -21,6 +21,19 @@ convertStmt :: Stmt -> Stmt convertStmt (If _ cc s1 s2) =     If NoCheck cc s1 s2-convertStmt (Case _ kw expr cases) =-    Case NoCheck kw expr cases+convertStmt (Case Priority kw expr cases) =+    StmtAttr caseAttr caseStmt+    where+        caseAttr = Attr [("full_case", Nil)]+        caseStmt = Case NoCheck kw expr cases+convertStmt (Case Unique kw expr cases) =+    StmtAttr caseAttr caseStmt+    where+        caseAttr = Attr [("full_case", Nil), ("parallel_case", Nil)]+        caseStmt = Case NoCheck kw expr cases+convertStmt (Case Unique0 kw expr cases) =+    StmtAttr caseAttr caseStmt+    where+        caseAttr = Attr [("parallel_case", Nil)]+        caseStmt = Case NoCheck kw expr cases convertStmt other = other
src/Convert/UnnamedGenBlock.hs view
@@ -10,6 +10,7 @@  module Convert.UnnamedGenBlock (convert) where +import Control.Monad (when) import Control.Monad.State.Strict import Data.List (isPrefixOf) 
src/Convert/UnpackedArray.hs view
@@ -11,6 +11,7 @@  module Convert.UnpackedArray (convert) where +import Control.Monad (when, (>=>)) import Control.Monad.State.Strict import qualified Data.Map.Strict as Map @@ -120,7 +121,7 @@     unbit (Range e _ _) = (e', n)         where (e', n) = unbit e     unbit e = (e, 0)-    split (Mux _ a b) = Just (a, b)+    split (MuxA _ _ a b) = Just (a, b)     split _ = Nothing  instance Key LHS where
src/Convert/Wildcard.hs view
@@ -76,10 +76,10 @@         BinOp BitAnd couldMatch $         BinOp BitOr  noExtraXZs $         Number (Based 1 False Binary 0 1)-    else if numberToInteger pattern /= Nothing then+    else if numberToInteger pat /= Nothing then         BinOp Eq l r     else-        BinOp Eq (BinOp BitOr l mask) pattern'+        BinOp Eq (BinOp BitOr l mask) pat'     where         lxl = BinOp BitXor l l         rxr = BinOp BitXor r r@@ -92,10 +92,10 @@         lxlxrxr = BinOp BitXor lxl rxr         -- For wildcard patterns we can find, use masking         maybePattern = lookupPattern scopes r-        Just pattern = maybePattern-        Based size signed base vals knds = pattern+        Just pat = maybePattern+        Based size signed base vals knds = pat         mask = Number $ Based size signed base knds 0-        pattern' = Number $ Based size signed base (vals .|. knds) 0+        pat' = Number $ Based size signed base (vals .|. knds) 0 convertExpr scopes (BinOp WNe l r) =     UniOp LogNot $     convertExpr scopes $
src/Job.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE TemplateHaskell #-} {- sv2v@@ -12,12 +13,13 @@ import Data.Char (toLower) import Data.List (isPrefixOf, isSuffixOf) import Data.Version (showVersion)-import GitHash (giDescribe, tGitInfoCwdTry)+#if MIN_VERSION_githash(0,1,5)+import GitHash (giTag, tGitInfoCwdTry)+#endif import qualified Paths_sv2v (version) import System.IO (stderr, hPutStr) import System.Console.CmdArgs import System.Directory (doesDirectoryExist)-import System.Environment (getArgs, withArgs) import System.Exit (exitFailure)  data Exclude@@ -54,7 +56,11 @@     } deriving (Typeable, Data)  version :: String-version = either (const backup) giDescribe $$tGitInfoCwdTry+#if MIN_VERSION_githash(0,1,5)+version = either (const backup) giTag $$tGitInfoCwdTry+#else+version = backup+#endif     where backup = showVersion Paths_sv2v.version  defaultJob :: Job@@ -100,7 +106,7 @@     &= summary ("sv2v " ++ version)     &= details [ "sv2v converts SystemVerilog to Verilog."                , "More info: https://github.com/zachjs/sv2v"-               , "(C) 2019-2023 Zachary Snow, 2011-2015 Tom Hawkins" ]+               , "(C) 2019-2024 Zachary Snow, 2011-2015 Tom Hawkins" ]     &= helpArg [explicit, name "help", help "Display this help message"]     &= versionArg [explicit, name "version"]     &= verbosityArgs [ignore] [ignore]@@ -125,32 +131,9 @@ matches :: String -> String -> Bool matches = isPrefixOf . map toLower -type DeprecationPhase = [String] -> IO [String]--flagRename :: String -> String -> DeprecationPhase-flagRename before after strs = do-    let strs' = map rename strs-    if strs == strs'-        then return strs-        else do-            hPutStr stderr $ "Deprecation warning: " ++ before ++-                " has been renamed to " ++ after ++ "\n"-            return strs'-    where-        rename :: String -> String-        rename arg =-            if before == take (length before) arg-                then after ++ drop (length before) arg-                else arg- readJob :: IO Job-readJob = do-    strs <- getArgs-    strs' <- return strs-        >>= flagRename "-i" "-I"-        >>= flagRename "-d" "-D"-        >>= flagRename "-e" "-E"-    withArgs strs' $ cmdArgs defaultJob+readJob =+    cmdArgs defaultJob         >>= setWrite . setSuccinct  setWrite :: Job -> IO Job
src/Language/SystemVerilog/AST/Attr.hs view
@@ -8,6 +8,7 @@ module Language.SystemVerilog.AST.Attr     ( Attr (..)     , AttrSpec+    , showsAttrs     ) where  import Text.Printf (printf)@@ -24,6 +25,9 @@  instance Show Attr where     show (Attr specs) = printf "(* %s *)" $ commas $ map showSpec specs++showsAttrs :: [Attr] -> ShowS+showsAttrs = foldr (\a f -> shows a . showChar ' ' . f) id  showSpec :: AttrSpec -> String showSpec (x, e) = x ++ showAssignment e
+ src/Language/SystemVerilog/AST/Attr.hs-boot view
@@ -0,0 +1,9 @@+module Language.SystemVerilog.AST.Attr+    ( Attr+    , showsAttrs+    ) where++data Attr+instance Eq Attr++showsAttrs :: [Attr] -> ShowS
src/Language/SystemVerilog/AST/Decl.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  - Initial Verilog AST Author: Tom Hawkins <tomahawkins@gmail.com>
src/Language/SystemVerilog/AST/Description.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  - Initial Verilog AST Author: Tom Hawkins <tomahawkins@gmail.com>
src/Language/SystemVerilog/AST/Expr.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  - Initial Verilog AST Author: Tom Hawkins <tomahawkins@gmail.com>@@ -20,6 +19,9 @@     , ParamBinding     , showParams     , pattern RawNum+    , pattern UniOp+    , pattern BinOp+    , pattern Mux     ) where  import Data.List (intercalate)@@ -28,6 +30,7 @@ import Language.SystemVerilog.AST.Number (Number(..)) import Language.SystemVerilog.AST.Op import Language.SystemVerilog.AST.ShowHelp+import {-# SOURCE #-} Language.SystemVerilog.AST.Attr import {-# SOURCE #-} Language.SystemVerilog.AST.Type  type Range = (Expr, Expr)@@ -37,6 +40,13 @@ pattern RawNum :: Integer -> Expr pattern RawNum n = Number (Decimal (-32) True n) +pattern UniOp :: UniOp -> Expr -> Expr+pattern UniOp op e = UniOpA op [] e+pattern BinOp :: BinOp -> Expr -> Expr -> Expr+pattern BinOp op l r = BinOpA op [] l r+pattern Mux :: Expr -> Expr -> Expr -> Expr+pattern Mux c t f = MuxA [] c t f+ data Expr     = String  String     | Real    String@@ -51,9 +61,9 @@     | Concat  [Expr]     | Stream  StreamOp Expr [Expr]     | Call    Expr Args-    | UniOp   UniOp Expr-    | BinOp   BinOp Expr Expr-    | Mux     Expr Expr Expr+    | UniOpA  UniOp [Attr] Expr+    | BinOpA  BinOp [Attr] Expr Expr+    | MuxA    [Attr] Expr Expr Expr     | Cast    TypeOrExpr Expr     | DimsFn  DimsFn TypeOrExpr     | DimFn   DimFn  TypeOrExpr Expr@@ -94,34 +104,41 @@                 where tStr = if null (show t) then "default" else show t     show (MinTypMax a b c) = printf "(%s : %s : %s)" (show a) (show b) (show c)     show (ExprAsgn l r) = printf "(%s = %s)" (show l) (show r)-    show e@UniOp{} = showsPrec 0 e ""-    show e@BinOp{} = showsPrec 0 e ""-    show e@Dot  {} = showsPrec 0 e ""-    show e@Mux  {} = showsPrec 0 e ""-    show e@Call {} = showsPrec 0 e ""+    show e@UniOpA{} = showsPrec 0 e ""+    show e@BinOpA{} = showsPrec 0 e ""+    show e@Dot   {} = showsPrec 0 e ""+    show e@MuxA  {} = showsPrec 0 e ""+    show e@Call  {} = showsPrec 0 e "" -    showsPrec _ (UniOp   o e  ) =+    showsPrec _ (UniOpA o a e  ) =         shows o .+        (if null a then id else showChar ' ') .+        showsAttrs a .         showUniOpPrec e-    showsPrec _ (BinOp   o a b) =-        showBinOpPrec a .+    showsPrec _ (BinOpA o a l r) =+        showBinOpPrec l .         showChar ' ' .         shows o .         showChar ' ' .-        showBinOpPrec b-    showsPrec _ (Dot     e n  ) =+        showsAttrs a .+        case (o, r) of+            (BitAnd, UniOp RedAnd _) -> showExprWrapped r+            (BitOr , UniOp RedOr  _) -> showExprWrapped r+            _ -> showBinOpPrec r+    showsPrec _ (Dot      e n  ) =         shows e .         showChar '.' .         showString n-    showsPrec _ (Mux     c a b) =+    showsPrec _ (MuxA   a c t f) =         showChar '(' .         shows c .         showString " ? " .-        shows a .+        showsAttrs a .+        shows t .         showString " : " .-        shows b .+        shows f .         showChar ')'-    showsPrec _ (Call    e l  ) =+    showsPrec _ (Call     e l  ) =         shows e .         shows l     showsPrec _ e = \s -> show e ++ s@@ -188,13 +205,16 @@ showRange (h, l) = '[' : show h ++ ':' : show l ++ "]"  showUniOpPrec :: Expr -> ShowS-showUniOpPrec e@UniOp{} = (showParen True . shows) e-showUniOpPrec e@BinOp{} = (showParen True . shows) e+showUniOpPrec e@UniOp{} = showExprWrapped e+showUniOpPrec e@BinOp{} = showExprWrapped e showUniOpPrec e = shows e  showBinOpPrec :: Expr -> ShowS-showBinOpPrec e@BinOp{} = (showParen True . shows) e+showBinOpPrec e@BinOp{} = showExprWrapped e showBinOpPrec e = shows e++showExprWrapped :: Expr -> ShowS+showExprWrapped = showParen True . shows  type ParamBinding = (Identifier, TypeOrExpr) 
src/Language/SystemVerilog/AST/ModuleItem.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  - Initial Verilog AST Author: Tom Hawkins <tomahawkins@gmail.com>
src/Language/SystemVerilog/AST/Number.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE TupleSections #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -@@ -154,12 +153,17 @@          -- high-order X or Z is extended up to the size of the literal         leadDigit = head digits-        numDigits = length digits+        numDigits = length digits + if isSignedUnsizedWithLeading1 then 1 else 0         leadDigitIsXZ = elem leadDigit xzDigits         digitsExtended =             if leadDigitIsXZ                 then replicate (sizeDigits - numDigits) leadDigit ++ digits                 else digits+        isSignedUnsizedWithLeading1 =+            maybeBase /= Nothing &&+            not leadDigitIsXZ &&+            signed &&+            digitToInt leadDigit >= div (baseSize base) 2          -- determine the number of digits needed based on the size         sizeDigits = ((abs size) `div` bitsPerDigit) + sizeExtraDigit
src/Language/SystemVerilog/AST/Stmt.hs view
@@ -53,6 +53,7 @@     | Trigger Bool Identifier     | Assertion Assertion     | Force Bool LHS Expr+    | Wait Expr Stmt     | Continue     | Break     | Null@@ -106,6 +107,7 @@                 (True , False) -> "release"                 (False, True ) -> "assign"                 (False, False) -> "deassign"+    show (Wait      e s) = printf "wait (%s)%s" (show e) (showShortBranch s)     show (Continue     ) = "continue;"     show (Break        ) = "break;"     show (Null         ) = ";"
src/Language/SystemVerilog/AST/Type.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  - Initial Verilog AST Author: Tom Hawkins <tomahawkins@gmail.com>@@ -62,7 +61,8 @@     show (IntegerVector kw sg rs) = printf "%s%s%s" (show kw) (showPadBefore sg) (showRanges rs)     show (IntegerAtom   kw sg   ) = printf "%s%s"   (show kw) (showPadBefore sg)     show (NonInteger    kw      ) = printf "%s"     (show kw)-    show (InterfaceT    "" "" rs) = printf "interface%s" ( showRanges rs)+    show (InterfaceT    "" "" rs) = printf "interface%s"   (showRanges rs)+    show (InterfaceT    xx "" rs) = printf "%s%s"    xx    (showRanges rs)     show (InterfaceT    xx yy rs) = printf "%s.%s%s" xx yy (showRanges rs)     show (Enum t vals r) = printf "enum %s{%s}%s" tStr (commas $ map showVal vals) (showRanges r)         where
src/Language/SystemVerilog/Parser.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE TupleSections #-} {- sv2v  - Author: Zachary Snow <zach@zachjs.com>  -}@@ -7,6 +6,8 @@     , Config(..)     ) where +import Control.Monad (when)+import Control.Monad.IO.Class (liftIO) import Control.Monad.Except import Data.List (elemIndex) import Data.Maybe (catMaybes)
src/Language/SystemVerilog/Parser/Parse.y view
@@ -13,9 +13,9 @@  -} { {-# LANGUAGE BlockArguments #-}-{-# LANGUAGE TupleSections #-} module Language.SystemVerilog.Parser.Parse (parse) where +import Control.Monad (when) import Control.Monad.Except import Control.Monad.State.Strict import Data.Maybe (catMaybes, fromMaybe)@@ -1150,6 +1150,7 @@   | "deassign" LHS          ";"                { Force False $2 Nil }   | "force"    LHS "=" Expr ";"                { Force True  $2  $4 }   | "release"  LHS          ";"                { Force True  $2 Nil }+  | "wait" "(" Expr ")" Stmt                   { Wait $3 $5 }  OptDelayOrEvent :: { Maybe Timing }   : DelayOrEvent { Just $1 }@@ -1344,7 +1345,7 @@   | Expr "[" Expr "]"           { Bit   $1 $3 }   | "{" Expr Concat "}"         { Repeat $2 $3 }   | Concat                      { Concat $1 }-  | Expr "?" Expr ":" Expr      { Mux $1 $3 $5 }+  | Expr "?" AttributeInstances Expr ":" Expr { MuxA $3 $1 $4 $6 }   | Expr "." Identifier         { Dot $1 $3 }   | "'" "{" PatternItems "}"    { Pattern $3 }   | Expr "'" "{" PatternItems "}"{ Cast (Right $1) (Pattern $4) }@@ -1358,47 +1359,47 @@   | Identifier               "::" Identifier { PSIdent $1    $3 }   | Identifier ParamBindings "::" Identifier { CSIdent $1 $2 $4 }   -- binary expressions-  | Expr "||"  Expr { BinOp LogOr  $1 $3 }-  | Expr "&&"  Expr { BinOp LogAnd $1 $3 }-  | Expr "->"  Expr { BinOp LogImp $1 $3 }-  | Expr "<->" Expr { BinOp LogEq  $1 $3 }-  | Expr "|"   Expr { BinOp BitOr  $1 $3 }-  | Expr "^"   Expr { BinOp BitXor $1 $3 }-  | Expr "&"   Expr { BinOp BitAnd $1 $3 }-  | Expr "~^"  Expr { BinOp BitXnor $1 $3 }-  | Expr "^~"  Expr { BinOp BitXnor $1 $3 }-  | Expr "+"   Expr { BinOp Add $1 $3 }-  | Expr "-"   Expr { BinOp Sub $1 $3 }-  | Expr "*"   Expr { BinOp Mul $1 $3 }-  | Expr "/"   Expr { BinOp Div $1 $3 }-  | Expr "%"   Expr { BinOp Mod $1 $3 }-  | Expr "**"  Expr { BinOp Pow $1 $3 }-  | Expr "=="  Expr { BinOp Eq $1 $3 }-  | Expr "!="  Expr { BinOp Ne $1 $3 }-  | Expr "<"   Expr { BinOp Lt $1 $3 }-  | Expr "<="  Expr { BinOp Le $1 $3 }-  | Expr ">"   Expr { BinOp Gt $1 $3 }-  | Expr ">="  Expr { BinOp Ge $1 $3 }-  | Expr "===" Expr { BinOp TEq $1 $3 }-  | Expr "!==" Expr { BinOp TNe $1 $3 }-  | Expr "==?" Expr { BinOp WEq $1 $3 }-  | Expr "!=?" Expr { BinOp WNe $1 $3 }-  | Expr "<<"  Expr { BinOp ShiftL $1 $3 }-  | Expr ">>"  Expr { BinOp ShiftR $1 $3 }-  | Expr "<<<" Expr { BinOp ShiftAL $1 $3 }-  | Expr ">>>" Expr { BinOp ShiftAR $1 $3 }+  | Expr "||"  AttributeInstances Expr { BinOpA LogOr  $3 $1 $4 }+  | Expr "&&"  AttributeInstances Expr { BinOpA LogAnd $3 $1 $4 }+  | Expr "->"  AttributeInstances Expr { BinOpA LogImp $3 $1 $4 }+  | Expr "<->" AttributeInstances Expr { BinOpA LogEq  $3 $1 $4 }+  | Expr "|"   AttributeInstances Expr { BinOpA BitOr  $3 $1 $4 }+  | Expr "^"   AttributeInstances Expr { BinOpA BitXor $3 $1 $4 }+  | Expr "&"   AttributeInstances Expr { BinOpA BitAnd $3 $1 $4 }+  | Expr "~^"  AttributeInstances Expr { BinOpA BitXnor $3 $1 $4 }+  | Expr "^~"  AttributeInstances Expr { BinOpA BitXnor $3 $1 $4 }+  | Expr "+"   AttributeInstances Expr { BinOpA Add $3 $1 $4 }+  | Expr "-"   AttributeInstances Expr { BinOpA Sub $3 $1 $4 }+  | Expr "*"   AttributeInstances Expr { BinOpA Mul $3 $1 $4 }+  | Expr "/"   AttributeInstances Expr { BinOpA Div $3 $1 $4 }+  | Expr "%"   AttributeInstances Expr { BinOpA Mod $3 $1 $4 }+  | Expr "**"  AttributeInstances Expr { BinOpA Pow $3 $1 $4 }+  | Expr "=="  AttributeInstances Expr { BinOpA Eq $3 $1 $4 }+  | Expr "!="  AttributeInstances Expr { BinOpA Ne $3 $1 $4 }+  | Expr "<"   AttributeInstances Expr { BinOpA Lt $3 $1 $4 }+  | Expr "<="  AttributeInstances Expr { BinOpA Le $3 $1 $4 }+  | Expr ">"   AttributeInstances Expr { BinOpA Gt $3 $1 $4 }+  | Expr ">="  AttributeInstances Expr { BinOpA Ge $3 $1 $4 }+  | Expr "===" AttributeInstances Expr { BinOpA TEq $3 $1 $4 }+  | Expr "!==" AttributeInstances Expr { BinOpA TNe $3 $1 $4 }+  | Expr "==?" AttributeInstances Expr { BinOpA WEq $3 $1 $4 }+  | Expr "!=?" AttributeInstances Expr { BinOpA WNe $3 $1 $4 }+  | Expr "<<"  AttributeInstances Expr { BinOpA ShiftL $3 $1 $4 }+  | Expr ">>"  AttributeInstances Expr { BinOpA ShiftR $3 $1 $4 }+  | Expr "<<<" AttributeInstances Expr { BinOpA ShiftAL $3 $1 $4 }+  | Expr ">>>" AttributeInstances Expr { BinOpA ShiftAR $3 $1 $4 }   -- unary expressions-  | "!"  Expr                 { UniOp LogNot $2 }-  | "~"  Expr                 { UniOp BitNot $2 }-  | "+"  Expr %prec REDUCE_OP { UniOp UniAdd $2 }-  | "-"  Expr %prec REDUCE_OP { UniOp UniSub $2 }-  | "&"  Expr %prec REDUCE_OP { UniOp RedAnd  $2 }-  | "~&" Expr %prec REDUCE_OP { UniOp RedNand $2 }-  | "|"  Expr %prec REDUCE_OP { UniOp RedOr   $2 }-  | "~|" Expr %prec REDUCE_OP { UniOp RedNor  $2 }-  | "^"  Expr %prec REDUCE_OP { UniOp RedXor  $2 }-  | "~^" Expr %prec REDUCE_OP { UniOp RedXnor $2 }-  | "^~" Expr %prec REDUCE_OP { UniOp RedXnor $2 }+  | "!"  AttributeInstances Expr                 { UniOpA LogNot $2 $3 }+  | "~"  AttributeInstances Expr                 { UniOpA BitNot $2 $3 }+  | "+"  AttributeInstances Expr %prec REDUCE_OP { UniOpA UniAdd $2 $3 }+  | "-"  AttributeInstances Expr %prec REDUCE_OP { UniOpA UniSub $2 $3 }+  | "&"  AttributeInstances Expr %prec REDUCE_OP { UniOpA RedAnd  $2 $3 }+  | "~&" AttributeInstances Expr %prec REDUCE_OP { UniOpA RedNand $2 $3 }+  | "|"  AttributeInstances Expr %prec REDUCE_OP { UniOpA RedOr   $2 $3 }+  | "~|" AttributeInstances Expr %prec REDUCE_OP { UniOpA RedNor  $2 $3 }+  | "^"  AttributeInstances Expr %prec REDUCE_OP { UniOpA RedXor  $2 $3 }+  | "~^" AttributeInstances Expr %prec REDUCE_OP { UniOpA RedXnor $2 $3 }+  | "^~" AttributeInstances Expr %prec REDUCE_OP { UniOpA RedXnor $2 $3 }   -- assignments within expressions   | "(" Expr "="        Expr ")" {% makeExprAsgn (tokenPosition $3, AsgnOpEq) $2 $4 }   | "(" Expr AsgnBinOpP Expr ")" {% makeExprAsgn $3                           $2 $4 }@@ -1604,9 +1605,8 @@     else return (a1 ++ a2, b1 ++ b2)  makeInput :: Decl -> Decl-makeInput (Variable Local t x a e) = Variable Input t x a e-makeInput (Variable Input t x a e) = Variable Input t x a e-makeInput (Variable Output t x a e) = Variable Output t x a e+makeInput (Variable d t x a e) = Variable d' t x a e+  where d' = if d == Local then Input else d makeInput (CommentDecl c) = CommentDecl c makeInput other =   error $ "unexpected non-var or non-port function decl: " ++ (show other)
src/Language/SystemVerilog/Parser/Preprocess.hs view
@@ -14,6 +14,7 @@     , Contents     ) where +import Control.Monad (when) import Control.Monad.Except import Control.Monad.State.Strict import Data.Char (ord)@@ -961,19 +962,19 @@ -- search for a pattern in the input and remove remove characters up to and -- including the first occurrence of the pattern removeThrough :: String -> PPS ()-removeThrough pattern = do+removeThrough pat = do     str <- getInput-    case findIndex (isPrefixOf pattern) (tails str) of+    case findIndex (isPrefixOf pat) (tails str) of         Nothing ->-            if pattern == "\n"+            if pat == "\n"                 then setInput ""                 else lexicalError $ "Reached EOF while looking for: "-                        ++ show pattern+                        ++ show pat         Just patternIdx -> do-            let chars = patternIdx + length pattern+            let chars = patternIdx + length pat             let (dropped, rest) = splitAt chars str             advancePositions dropped-            when (pattern == "\n") $ do+            when (pat == "\n") $ do                 pos <- getPosition                 pushChar '\n' pos             setInput rest
src/Language/SystemVerilog/Parser/Tokens.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE PatternSynonyms #-} {- sv2v  - Author: Tom Hawkins <tomahawkins@gmail.com>  - Modified by: Zachary Snow <zach@zachjs.com>
src/sv2v.hs view
@@ -10,37 +10,44 @@  import Control.Monad (when, zipWithM_) import Control.Monad.Except (runExceptT)+import Data.List (nub)  import Convert (convert) import Job (readJob, Job(..), Write(..)) import Language.SystemVerilog.AST import Language.SystemVerilog.Parser (parseFiles, Config(..)) -isInterface :: Description -> Bool-isInterface (Part _ _ Interface _ _ _ _ ) = True-isInterface _ = False--isPackage :: Description -> Bool-isPackage Package{} = True-isPackage _ = False- isComment :: Description -> Bool isComment (PackageItem (Decl CommentDecl{})) = True isComment _ = False +droppedKind :: Description -> Identifier+droppedKind description =+    case description of+        Part _ _ Interface _ _ _ _ -> "interface"+        Package{} -> "package"+        Class{}   -> "class"+        PackageItem Function{}     -> "function"+        PackageItem Task    {}     -> "task"+        PackageItem (Decl Param{}) -> "localparam"+        _ -> ""+ emptyWarnings :: AST -> AST -> IO () emptyWarnings before after =-    if all isComment before || not (all isComment after) then+    if all isComment before || not (all isComment after) || null kinds then         return ()-    else if any isInterface before then-        hPutStrLn stderr $ "Warning: Source includes an interface but output is"-            ++ " empty because there is no top-level module which has no ports"-            ++ " which are interfaces."-    else if any isPackage before then-        hPutStrLn stderr $ "Warning: Source includes packages but no modules."-            ++ " Please convert packages alongside the modules that use them."+    else if elem "interface" kinds then+        hPutStrLn stderr $ "Warning: Source includes an interface but the"+            ++ " output is empty because there are no modules without any"+            ++ " interface ports. Please convert interfaces alongside the"+            ++ " modules that instantiate them."     else-        return ()+        hPutStrLn stderr $ "Warning: Source includes a " ++ kind ++ " but no"+            ++ " modules. Such elements are elaborated into the modules that"+            ++ " use them. Please convert all sources in one invocation."+    where+        kinds = nub $ filter (not . null) $ map droppedKind before+        kind = head kinds  rewritePath :: FilePath -> IO FilePath rewritePath path = do
sv2v.cabal view
@@ -1,6 +1,6 @@ cabal-version:   2.4 name:            sv2v-version:         0.0.11+version:         0.0.12 license:         BSD-3-Clause license-file:    LICENSE NOTICE maintainer:      Zachary Snow <zach@zachjs.com>@@ -24,7 +24,7 @@  executable sv2v     main-is:            sv2v.hs-    build-tool-depends: alex:alex >=3.2.5 && <4, happy:happy >=1.20 && <2+    build-tool-depends: alex:alex >=3.2 && <4, happy:happy >=1.19 && <2     hs-source-dirs:     src     other-modules:         Language.SystemVerilog@@ -66,6 +66,7 @@         Convert.Foreach         Convert.FuncRet         Convert.FuncRoutine+        Convert.GenvarName         Convert.HierConst         Convert.ImplicitNet         Convert.Inside@@ -105,18 +106,19 @@      autogen-modules:    Paths_sv2v     default-language:   Haskell2010+    default-extensions: PatternSynonyms TupleSections     ghc-options:         -O3 -threaded -rtsopts "-with-rtsopts=-N -A32m"-        -funbox-strict-fields -Wall+        -funbox-strict-fields -Wall -Wno-incomplete-uni-patterns      build-depends:-        array <0.6,-        base <4.15,-        cmdargs <0.11,-        containers <0.7,-        directory <1.4,-        filepath <1.5,-        githash <0.2,-        hashable <1.4,-        mtl <2.3,-        vector <0.13+        array >=0.5.6.0 && <0.6,+        base >=4.18.2.0 && <4.19,+        cmdargs >=0.10.22 && <0.11,+        containers >=0.6.7 && <0.7,+        directory >=1.3.8.1 && <1.4,+        filepath >=1.4.200.1 && <1.5,+        githash >=0.1.7.0 && <0.2,+        hashable >=1.4.4.0 && <1.5,+        mtl >=2.3.1 && <2.4,+        vector >=0.13.1.0 && <0.14