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