mirror of https://github.com/zachjs/sv2v.git
updated case inside representation
This commit is contained in:
parent
2d7dc00b8d
commit
0d095e6afb
|
|
@ -32,8 +32,6 @@ convertModuleItem item =
|
|||
item
|
||||
|
||||
convertExpr :: Expr -> Expr
|
||||
convertExpr (Inside Nil valueRanges) =
|
||||
Inside Nil valueRanges
|
||||
convertExpr (Inside expr valueRanges) =
|
||||
if length checks == 1
|
||||
then head checks
|
||||
|
|
@ -50,31 +48,25 @@ convertExpr (Inside expr valueRanges) =
|
|||
convertExpr other = other
|
||||
|
||||
convertStmt :: Stmt -> Stmt
|
||||
convertStmt (Case u kw expr items) =
|
||||
if not $ any isSpecialInside exprs then
|
||||
Case u kw expr items
|
||||
else if kw /= CaseN then
|
||||
error $ "cannot use inside with " ++ show kw
|
||||
else if hasSideEffects expr then
|
||||
convertStmt (Case u CaseInside expr items) =
|
||||
if hasSideEffects expr then
|
||||
Block Seq "" [decl] [stmt]
|
||||
else
|
||||
foldr ($) defaultStmt $
|
||||
map (uncurry $ If NoCheck) $
|
||||
zip comps stmts
|
||||
where
|
||||
exprs = map fst items
|
||||
-- evaluate expressions with side effects once
|
||||
tmp = "sv2v_temp_" ++ shortHash expr
|
||||
decl = Variable Local (TypeOf expr) tmp [] expr
|
||||
stmt = convertStmt (Case u kw (Ident tmp) items)
|
||||
stmt = convertStmt (Case u CaseInside (Ident tmp) items)
|
||||
-- underlying inside case elaboration
|
||||
itemsNonDefault = filter (not . null . fst) items
|
||||
isSpecialInside :: [Expr] -> Bool
|
||||
isSpecialInside [Inside Nil _] = True
|
||||
isSpecialInside _ = False
|
||||
makeComp :: [Expr] -> Expr
|
||||
makeComp [Inside Nil ovr] = Inside expr ovr
|
||||
makeComp _ = error "internal invariant violated"
|
||||
makeComp = Inside expr . map unwrap
|
||||
unwrap :: Expr -> ExprOrRange
|
||||
unwrap (Range Nil NonIndexed r) = Right r
|
||||
unwrap e = Left e
|
||||
comps = map (makeComp . fst) itemsNonDefault
|
||||
stmts = map snd itemsNonDefault
|
||||
defaultStmt = fromMaybe Null (lookup [] items)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import Text.Printf (printf)
|
|||
import Language.SystemVerilog.AST.ShowHelp (commas, indent, unlines', showPad, showBlock)
|
||||
import Language.SystemVerilog.AST.Attr (Attr)
|
||||
import Language.SystemVerilog.AST.Decl (Decl)
|
||||
import Language.SystemVerilog.AST.Expr (Expr(Inside, Nil), Args(..), showExprOrRange)
|
||||
import Language.SystemVerilog.AST.Expr (Expr(Nil), Args(..))
|
||||
import Language.SystemVerilog.AST.LHS (LHS)
|
||||
import Language.SystemVerilog.AST.Op (AsgnOp(AsgnOpEq))
|
||||
import Language.SystemVerilog.AST.Type (Identifier)
|
||||
|
|
@ -65,8 +65,11 @@ instance Show Stmt where
|
|||
header = if null name then "" else " : " ++ name
|
||||
body = showBlock decls stmts
|
||||
show (Case u kw e cs) =
|
||||
printf "%s%s (%s)\n%s\nendcase" (showPad u) (show kw) (show e) bodyStr
|
||||
where bodyStr = indent $ unlines' $ map showCase cs
|
||||
printf "%s%s (%s)%s\n%s\nendcase" (showPad u) (show kw) (show e)
|
||||
insideStr bodyStr
|
||||
where
|
||||
insideStr = if kw == CaseInside then " inside" else ""
|
||||
bodyStr = indent $ unlines' $ map showCase cs
|
||||
show (For inits cond assigns stmt) =
|
||||
printf "for (%s; %s; %s)\n%s"
|
||||
(showInits inits)
|
||||
|
|
@ -140,19 +143,20 @@ showCase (a, b) = printf "%s:%s" exprStr (showShortBranch b)
|
|||
where
|
||||
exprStr = case a of
|
||||
[] -> "default"
|
||||
[Inside Nil c] -> commas $ map showExprOrRange c
|
||||
_ -> commas $ map show a
|
||||
|
||||
data CaseKW
|
||||
= CaseN
|
||||
| CaseZ
|
||||
| CaseX
|
||||
| CaseInside
|
||||
deriving Eq
|
||||
|
||||
instance Show CaseKW where
|
||||
show CaseN = "case"
|
||||
show CaseZ = "casez"
|
||||
show CaseX = "casex"
|
||||
show CaseInside = "case"
|
||||
|
||||
type Case = ([Expr], Stmt)
|
||||
|
||||
|
|
|
|||
|
|
@ -1002,7 +1002,7 @@ StmtNonBlock :: { Stmt }
|
|||
| Unique "if" "(" Expr ")" Stmt "else" Stmt { If $1 $4 $6 $8 }
|
||||
| Unique "if" "(" Expr ")" Stmt %prec NoElse { If $1 $4 $6 Null }
|
||||
| "for" "(" ForInit ForCond ForStep ")" Stmt { For $3 $4 $5 $7 }
|
||||
| Unique CaseKW "(" Expr ")" Cases "endcase" { Case $1 $2 $4 $6 }
|
||||
| CaseStmt { $1 }
|
||||
| TimingControl Stmt { Timing $1 $2 }
|
||||
| "return" ExprOrNil ";" { Return $2 }
|
||||
| "break" ";" { Break }
|
||||
|
|
@ -1018,6 +1018,10 @@ StmtNonBlock :: { Stmt }
|
|||
| ProceduralAssertionStatement { Assertion $1 }
|
||||
| "void" "'" "(" Expr CallArgs ")" ";" { Subroutine $4 $5 }
|
||||
|
||||
CaseStmt :: { Stmt }
|
||||
: Unique CaseKW "(" Expr ")" Cases "endcase" { Case $1 $2 $4 $ validateCases $5 $6 }
|
||||
| Unique CaseKW "(" Expr ")" "inside" InsideCases "endcase" { Case $1 (caseInsideKW $3 $2) $4 $ validateCases $5 $7 }
|
||||
|
||||
BlockKWPar :: { BlockKW }
|
||||
: "fork" { Par }
|
||||
BlockKWSeq :: { BlockKW }
|
||||
|
|
@ -1127,12 +1131,16 @@ CaseKW :: { CaseKW }
|
|||
| "casez" { CaseZ }
|
||||
|
||||
Cases :: { [Case] }
|
||||
: opt("inside") InsideCases { validateCases $1 $2 }
|
||||
InsideCases :: { [([ExprOrRange], Stmt)] }
|
||||
: Case { [$1] }
|
||||
| Case Cases { $1 : $2 }
|
||||
Case :: { Case }
|
||||
: Exprs ":" Stmt { ($1, $3) }
|
||||
| "default" opt(":") Stmt { ([], $3) }
|
||||
InsideCases :: { [Case] }
|
||||
: InsideCase { [$1] }
|
||||
| InsideCases InsideCase { $1 ++ [$2] }
|
||||
InsideCase :: { ([ExprOrRange], Stmt) }
|
||||
: OpenRangeList ":" Stmt { ($1, $3) }
|
||||
| InsideCase InsideCases { $1 : $2 }
|
||||
InsideCase :: { Case }
|
||||
: OpenRangeList ":" Stmt { (map rangeAsExpr $1, $3) }
|
||||
| "default" opt(":") Stmt { ([], $3) }
|
||||
|
||||
Real :: { String }
|
||||
|
|
@ -1299,7 +1307,7 @@ GenItem :: { GenItem }
|
|||
ConditionalGenerateConstruct :: { GenItem }
|
||||
: "if" "(" Expr ")" GenItemOrNull "else" GenItemOrNull { GenIf $3 $5 $7 }
|
||||
| "if" "(" Expr ")" GenItemOrNull %prec NoElse { GenIf $3 $5 GenNull }
|
||||
| "case" "(" Expr ")" GenCases "endcase" { GenCase $3 $5 }
|
||||
| "case" "(" Expr ")" GenCases "endcase" { GenCase $3 $ validateCases $4 $5 }
|
||||
LoopGenerateConstruct :: { GenItem }
|
||||
: "for" "(" GenvarInitialization ";" Expr ";" GenvarIteration ")" GenItem { $3 $5 $7 $9 }
|
||||
|
||||
|
|
@ -1308,7 +1316,7 @@ GenBlock :: { (Identifier, [GenItem]) }
|
|||
|
||||
GenCases :: { [GenCase] }
|
||||
: GenCase { [$1] }
|
||||
| GenCases GenCase { validateGenCases $ $1 ++ [$2] }
|
||||
| GenCase GenCases { $1 : $2 }
|
||||
GenCase :: { GenCase }
|
||||
: Exprs ":" GenItemOrNull { ($1, $3) }
|
||||
| "default" opt(":") GenItemOrNull { ([], $3) }
|
||||
|
|
@ -1444,34 +1452,21 @@ fieldDecl t (x, rs2) =
|
|||
(tf $ rs2 ++ rs1, x)
|
||||
where (tf, rs1) = typeRanges t
|
||||
|
||||
validateCases :: Maybe Token -> [([ExprOrRange], Stmt)] -> [Case]
|
||||
validateCases Nothing items =
|
||||
if length (filter null exprs) <= 1
|
||||
then zip exprs' stmts
|
||||
else error $ "multiple default cases: " ++ show items
|
||||
where
|
||||
(exprs, stmts) = unzip items
|
||||
exprs' = map (map unwrap) exprs
|
||||
unwrap (Left expr) = expr
|
||||
unwrap (Right range) =
|
||||
error $ "illegal use of a range (" ++ show range
|
||||
++ ") in a non-inside case"
|
||||
validateCases (Just _) items =
|
||||
if length (filter null sets) <= 1
|
||||
then zip sets' stmts
|
||||
else error $ "multiple default cases: " ++ show items
|
||||
where
|
||||
(sets, stmts) = unzip items
|
||||
sets' = map unwrap sets
|
||||
unwrap [] = []
|
||||
unwrap ls = [Inside Nil ls]
|
||||
|
||||
validateGenCases :: [GenCase] -> [GenCase]
|
||||
validateGenCases items =
|
||||
if length (filter null exprs) <= 1
|
||||
validateCases :: Token -> [([Expr], a)] -> [([Expr], a)]
|
||||
validateCases tok items =
|
||||
if length (filter (null . fst) items) <= 1
|
||||
then items
|
||||
else error $ "multiple default generate cases: " ++ show items
|
||||
where
|
||||
(exprs, _) = unzip items
|
||||
else error $ show (tokenPosition tok)
|
||||
++ ": Parse error: case has multiple defaults"
|
||||
|
||||
caseInsideKW :: Token -> CaseKW -> CaseKW
|
||||
caseInsideKW _ CaseN = CaseInside
|
||||
caseInsideKW tok kw =
|
||||
error $ show (tokenPosition tok)
|
||||
++ ": Parse error: cannot use inside with " ++ show kw
|
||||
|
||||
rangeAsExpr :: ExprOrRange -> Expr
|
||||
rangeAsExpr (Left e) = e
|
||||
rangeAsExpr (Right r) = Range Nil NonIndexed r
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
// pattern: case has multiple defaults
|
||||
module top;
|
||||
initial
|
||||
case (0)
|
||||
0: $display("FOO");
|
||||
1: $display("BAR");
|
||||
default: $display("A");
|
||||
default: $display("B");
|
||||
endcase
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// pattern: cannot use inside with casex
|
||||
module top;
|
||||
initial
|
||||
casex (0) inside
|
||||
0: $display("FOO");
|
||||
1: $display("BAR");
|
||||
endcase
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// pattern: cannot use inside with casez
|
||||
module top;
|
||||
initial
|
||||
casez (0) inside
|
||||
0: $display("FOO");
|
||||
1: $display("BAR");
|
||||
endcase
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// pattern: case has multiple defaults
|
||||
module top;
|
||||
case (0)
|
||||
0: wire w;
|
||||
1: wire x;
|
||||
default: wire y;
|
||||
default: wire z;
|
||||
endcase
|
||||
endmodule
|
||||
Loading…
Reference in New Issue