Commit 0d095e6a by Zachary Snow

updated case inside representation

parent 2d7dc00b
...@@ -32,8 +32,6 @@ convertModuleItem item = ...@@ -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) = ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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 } ...@@ -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 } ...@@ -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 } ...@@ -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 } ...@@ -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]) } ...@@ -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) = ...@@ -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
} }
// pattern: case has multiple defaults
module top;
initial
case (0)
0: $display("FOO");
1: $display("BAR");
default: $display("A");
default: $display("B");
endcase
endmodule
// pattern: cannot use inside with casex
module top;
initial
casex (0) inside
0: $display("FOO");
1: $display("BAR");
endcase
endmodule
// pattern: cannot use inside with casez
module top;
initial
casez (0) inside
0: $display("FOO");
1: $display("BAR");
endcase
endmodule
// pattern: case has multiple defaults
module top;
case (0)
0: wire w;
1: wire x;
default: wire y;
default: wire z;
endcase
endmodule
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