Commit d7f641b8 by Zachary Snow

pivoted to general Verilog-2005 targeting

parent 9f0857d6
# sv2v: SystemVerilog to Verilog # sv2v: SystemVerilog to Verilog
sv2v is a tool for converting synthesizable SystemVerilog into Verilog that is sv2v is a tool for converting [SystemVerilog] into [Verilog-2005], with an
synthesizable by tools with more limited feature sets. This project is primarily emphasis on supporting synthesizable SystemVerilog features. This project was
focused on converting SystemVerilog into the subset of Verilog supported by originally developed to target [Yosys], and so allows for disabling the
[Yosys]. However, sv2v also has support for targeting the [limited subset of conversion of those [SystemVerilog features which Yosys supports].
Verilog] supported by [VTR]. In the long term, we hope for sv2v to be more
configurable and extensible so that it can be used with new and different
toolchains and as Verilog support evolves.
[SystemVerilog]: http://ecee.colorado.edu/~mathys/ecen2350/IntelSoftware/pdf/IEEE_Std1800-2017_8299595.pdf
[Verilog-2005]: https://www.eg.bucknell.edu/~csci320/2016-fall/wp-content/uploads/2015/08/verilog-std-1364-2005.pdf
[Yosys]: http://www.clifford.at/yosys/ [Yosys]: http://www.clifford.at/yosys/
[limited subset of Verilog]: https://docs.verilogtorouting.org/en/latest/odin/#verilog-synthesizable-keyword-support [SystemVerilog features which Yosys supports]: https://github.com/YosysHQ/yosys#supported-features-from-systemverilog
[VTR]: https://github.com/verilog-to-routing/vtr-verilog-to-routing
## Installation ## Installation
### Pre-built binaries ### Pre-built binaries
Given the infamy of Haskell's build system, we aim to release pre-built binaries We plan on releasing pre-built binaries in the near future.
and installation files. This has not been done yet.
### Building from source ### Building from source
...@@ -33,7 +30,8 @@ stack setup ...@@ -33,7 +30,8 @@ stack setup
make make
``` ```
This creates the executable at `./bin/sv2v` This creates the executable at `./bin/sv2v` You can install the binary by
running `stack install`.
## Usage ## Usage
...@@ -45,18 +43,14 @@ path/to/file.sv` will output the converted file to `stdout`. ...@@ -45,18 +43,14 @@ path/to/file.sv` will output the converted file to `stdout`.
sv2v [OPTIONS] [FILE] sv2v [OPTIONS] [FILE]
Common flags: Common flags:
-t --target=TARGET target sythesizer (yosys, vtr; defaults to yosys) -e --exclude=CONV conversion to exclude (always, interface, logic); can
be specified multiple times
-? --help Display help message -? --help Display help message
-V --version Print version information
--numeric-version Print just the version number
``` ```
## VTR Support
sv2v can target VTR by specifying `--target=vtr` on the command line. Note that
VTR does not support `generate` blocks, and this tool is not capable of
converting those at this time.
## SystemVerilog Parser/AST ## SystemVerilog Parser/AST
This project contains a basic preprocessor, lexer, parser, and abstract syntax This project contains a basic preprocessor, lexer, parser, and abstract syntax
...@@ -65,7 +59,7 @@ strict, and the AST allows for the representation of syntactically (and ...@@ -65,7 +59,7 @@ strict, and the AST allows for the representation of syntactically (and
semantically) invalid Verilog. The goal is to be more general in the semantically) invalid Verilog. The goal is to be more general in the
representation to enable more standardized and straightforward conversion representation to enable more standardized and straightforward conversion
procedures. This could be extended into an independent and more fully-featured procedures. This could be extended into an independent and more fully-featured
parer if there is significant interest. parser if there is significant interest.
## License ## License
......
...@@ -7,18 +7,16 @@ ...@@ -7,18 +7,16 @@
module Convert (convert) where module Convert (convert) where
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
import Job (Target(..)) import qualified Job (Exclude(..))
import qualified Convert.AlwaysKW import qualified Convert.AlwaysKW
import qualified Convert.AsgnOp import qualified Convert.AsgnOp
import qualified Convert.CaseKW
import qualified Convert.Enum import qualified Convert.Enum
import qualified Convert.FuncRet import qualified Convert.FuncRet
import qualified Convert.Interface import qualified Convert.Interface
import qualified Convert.Logic import qualified Convert.Logic
import qualified Convert.PackedArray import qualified Convert.PackedArray
import qualified Convert.Return import qualified Convert.Return
import qualified Convert.SplitPortDecl
import qualified Convert.StarPort import qualified Convert.StarPort
import qualified Convert.Struct import qualified Convert.Struct
import qualified Convert.Typedef import qualified Convert.Typedef
...@@ -26,10 +24,10 @@ import qualified Convert.Unique ...@@ -26,10 +24,10 @@ import qualified Convert.Unique
type Phase = AST -> AST type Phase = AST -> AST
phases :: Target -> [Phase] phases :: [Job.Exclude] -> [Phase]
phases YOSYS = phases excludes =
extras ++
[ Convert.AsgnOp.convert [ Convert.AsgnOp.convert
, Convert.Interface.convert
, Convert.FuncRet.convert , Convert.FuncRet.convert
, Convert.Enum.convert , Convert.Enum.convert
, Convert.PackedArray.convert , Convert.PackedArray.convert
...@@ -39,23 +37,27 @@ phases YOSYS = ...@@ -39,23 +37,27 @@ phases YOSYS =
, Convert.Typedef.convert , Convert.Typedef.convert
, Convert.Unique.convert , Convert.Unique.convert
] ]
phases VTR = where
(phases YOSYS) ++ availableExcludes =
[ Convert.AlwaysKW.convert [ (Job.Interface, Convert.Interface.convert)
, Convert.CaseKW.convert , (Job.Logic , Convert.Logic.convert)
, Convert.Logic.convert , (Job.Always , Convert.AlwaysKW.convert) ]
, Convert.SplitPortDecl.convert extras = map selectExclude availableExcludes
] selectExclude :: (Job.Exclude, Phase) -> Phase
selectExclude (exclude, phase) =
if elem exclude excludes
then id
else phase
run :: Target -> Phase run :: [Job.Exclude] -> Phase
run target = foldr (.) id $ phases target run excludes = foldr (.) id $ phases excludes
convert :: Target -> Phase convert :: [Job.Exclude] -> Phase
convert target = convert' convert excludes = convert'
where where
convert' :: Phase convert' :: Phase
convert' descriptions = convert' descriptions =
if descriptions == descriptions' if descriptions == descriptions'
then descriptions then descriptions
else convert' descriptions' else convert' descriptions'
where descriptions' = run target descriptions where descriptions' = run excludes descriptions
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Conversion for `casez` and `casex`
-
- Note that this conversion does not completely replicate the behavior of
- `casex` and `casez` in cases where that case expression itself (rather than
- just the case item patterns) contains wildcard values. This is apparently
- rarely ever intentionally done.
-}
module Convert.CaseKW (convert) where
import Convert.Traverse
import Language.SystemVerilog.AST
convert :: AST -> AST
convert = traverseDescriptions (traverseModuleItems (traverseStmts convertStmt))
-- Conversions:
-- `casez` -> `case` with wildcards (?, z) expanded
-- `casex` -> `case` with wildcards (?, z, x) expanded
-- to be either 0 or 1
wildcards :: CaseKW -> [Char]
wildcards CaseN = [] -- CaseN == `case`
wildcards CaseZ = ['?', 'z', 'Z']
wildcards CaseX = ['?', 'z', 'Z', 'x', 'X']
possibilities :: [Char]
possibilities = ['0', '1']
explodeBy :: [Char] -> String -> [String]
explodeBy _ "" = [""]
explodeBy wilds (x : xs) =
(map (:) chars) <*> (explodeBy wilds xs)
where chars = if elem x wilds then possibilities else [x]
expandExpr :: [Char] -> Expr -> [Expr]
expandExpr wilds (Number s) = map Number $ explodeBy wilds s
expandExpr [] other = [other]
-- TODO: Hopefully they only give us constant expressions...
-- TODO: We could be given a constant identifier...
expandExpr _ other = error $ "CaseKW conversion encountered case that was not a number, which is dubious..." ++ (show other)
-- Note that we don't have to convert the statements within the cases, as the
-- conversion template takes care of that for us.
convertStmt :: Stmt -> Stmt
convertStmt (Case u kw expr cases def) =
Case u CaseN expr cases' def
where
wilds = wildcards kw
cases' = map convertCase cases
convertCase :: Case -> Case
convertCase (exprs, stmt) = (exprs', stmt)
where exprs' = concat $ map (expandExpr wilds) exprs
convertStmt other = other
...@@ -13,8 +13,11 @@ convert :: AST -> AST ...@@ -13,8 +13,11 @@ convert :: AST -> AST
convert = traverseDescriptions $ traverseModuleItems convertFunction convert = traverseDescriptions $ traverseModuleItems convertFunction
convertFunction :: ModuleItem -> ModuleItem convertFunction :: ModuleItem -> ModuleItem
convertFunction (MIPackageItem (Function ml (Reg r) f decls stmts)) = convertFunction (MIPackageItem (Function ml t f decls stmts)) =
MIPackageItem $ Function ml (Implicit r) f decls stmts MIPackageItem $ Function ml t' f decls stmts
convertFunction (MIPackageItem (Function ml (Logic r) f decls stmts)) = where
MIPackageItem $ Function ml (Implicit r) f decls stmts t' = case t of
Reg rs -> Implicit rs
Logic rs -> Implicit rs
_ -> t
convertFunction other = other convertFunction other = other
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Conversion for splitting up complex port declarations. VTR doesn't support:
- `input wire foo;` but does suport: `input foo; wire foo;`.
-}
module Convert.SplitPortDecl (convert) where
import Convert.Traverse
import Language.SystemVerilog.AST
convert :: AST -> AST
convert = traverseDescriptions convertDescription
convertDescription :: Description -> Description
convertDescription (Part kw name ports items) =
Part kw name ports (concat $ map splitPortDecl items)
convertDescription other = other
splitPortDecl :: ModuleItem -> [ModuleItem]
splitPortDecl (orig @ (MIDecl (Variable Local _ _ _ _))) = [orig]
splitPortDecl (orig @ (MIDecl (Variable _ (Implicit _) _ _ _))) = [orig]
splitPortDecl (MIDecl (Variable d t x a me)) =
[ MIDecl $ Variable d (Implicit r) x a Nothing
, MIDecl $ Variable Local t x a me ]
where (_, r) = typeRanges t
splitPortDecl other = [other]
...@@ -9,18 +9,23 @@ module Job where ...@@ -9,18 +9,23 @@ module Job where
import System.Console.CmdArgs import System.Console.CmdArgs
data Target = VTR | YOSYS data Exclude
deriving (Show, Typeable, Data) = Always
| Interface
| Logic
deriving (Show, Typeable, Data, Eq)
data Job = Job data Job = Job
{ target :: Target { exclude :: [Exclude]
, file :: FilePath , file :: FilePath
} deriving (Show, Typeable, Data) } deriving (Show, Typeable, Data)
defaultJob :: Job defaultJob :: Job
defaultJob = Job defaultJob = Job
{ target = YOSYS &= typ "TARGET" { exclude = [] &= typ "CONV"
&= help "target sythesizer (yosys, vtr; defaults to yosys)" &= help
("conversion to exclude (always, interface, logic)"
++ "; can be specified multiple times")
, file = def &= args &= typFile , file = def &= args &= typFile
} }
&= program "sv2v" &= program "sv2v"
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
import System.IO import System.IO
import System.Exit import System.Exit
import Job (readJob, file, target) import Job (readJob, file, exclude)
import Convert (convert) import Convert (convert)
import Language.SystemVerilog.Parser import Language.SystemVerilog.Parser
...@@ -19,7 +19,7 @@ main = do ...@@ -19,7 +19,7 @@ main = do
content <- readFile filePath content <- readFile filePath
let ast = parseFile [] filePath content let ast = parseFile [] filePath content
-- convert the file -- convert the file
let ast' = convert (target job) ast let ast' = convert (exclude job) ast
-- print the converted file out -- print the converted file out
hPrint stdout ast' hPrint stdout ast'
exitSuccess exitSuccess
...@@ -42,14 +42,12 @@ executable sv2v ...@@ -42,14 +42,12 @@ executable sv2v
Convert Convert
Convert.AlwaysKW Convert.AlwaysKW
Convert.AsgnOp Convert.AsgnOp
Convert.CaseKW
Convert.Enum Convert.Enum
Convert.FuncRet Convert.FuncRet
Convert.Interface Convert.Interface
Convert.Logic Convert.Logic
Convert.PackedArray Convert.PackedArray
Convert.Return Convert.Return
Convert.SplitPortDecl
Convert.StarPort Convert.StarPort
Convert.Struct Convert.Struct
Convert.Typedef Convert.Typedef
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment