support gate arrays

This commit is contained in:
Zachary Snow 2024-12-12 09:01:20 -05:00
parent 5a636724d7
commit 12618d541e
10 changed files with 109 additions and 43 deletions

View File

@ -5,6 +5,7 @@
* Added conversion of severity system tasks and elaboration system tasks (e.g., * Added conversion of severity system tasks and elaboration system tasks (e.g.,
`$info`) into `$display` tasks that include source file and scope information; `$info`) into `$display` tasks that include source file and scope information;
pass `-E SeverityTask` to disable this new conversion pass `-E SeverityTask` to disable this new conversion
* Added support for gate arrays and conversion for multidimensional gate arrays
* Added parsing support for `not`, `strong`, `weak`, `nexttime`, and * Added parsing support for `not`, `strong`, `weak`, `nexttime`, and
`s_nexttime` in assertion property expressions `s_nexttime` in assertion property expressions
* Added `--bugpoint` utility for minimizing test cases for issue submission * Added `--bugpoint` utility for minimizing test cases for issue submission

View File

@ -54,12 +54,12 @@ traverseModuleItemM _ (Genvar x) =
traverseModuleItemM defaultNetType orig@(Assign _ x _) = do traverseModuleItemM defaultNetType orig@(Assign _ x _) = do
needsLHS defaultNetType x needsLHS defaultNetType x
return orig return orig
traverseModuleItemM defaultNetType orig@(NInputGate _ _ x lhs exprs) = do traverseModuleItemM defaultNetType orig@(NInputGate _ _ x _ lhs exprs) = do
insertElem x () insertElem x ()
needsLHS defaultNetType lhs needsLHS defaultNetType lhs
_ <- mapM (needsExpr defaultNetType) exprs _ <- mapM (needsExpr defaultNetType) exprs
return orig return orig
traverseModuleItemM defaultNetType orig@(NOutputGate _ _ x lhss expr) = do traverseModuleItemM defaultNetType orig@(NOutputGate _ _ x _ lhss expr) = do
insertElem x () insertElem x ()
_ <- mapM (needsLHS defaultNetType) lhss _ <- mapM (needsLHS defaultNetType) lhss
needsExpr defaultNetType expr needsExpr defaultNetType expr

View File

@ -89,20 +89,32 @@ flattenType t =
flattenFields :: [Field] -> [Field] flattenFields :: [Field] -> [Field]
flattenFields = map $ first flattenType flattenFields = map $ first flattenType
traverseInstanceRanges :: Identifier -> [Range] -> Scoper TypeInfo [Range]
traverseInstanceRanges x rs
| length rs <= 1 = return rs
| otherwise = do
let t = Implicit Unspecified rs
tScoped <- scopeType t
insertElem x (tScoped, [])
let r1 : r2 : rest = rs
return $ (combineRanges r1 r2) : rest
traverseModuleItemM :: ModuleItem -> Scoper TypeInfo ModuleItem traverseModuleItemM :: ModuleItem -> Scoper TypeInfo ModuleItem
traverseModuleItemM (Instance m p x rs l) = do traverseModuleItemM (Instance m p x rs l) = do
-- converts multi-dimensional instances -- converts multi-dimensional instances
rs' <- if length rs <= 1 rs' <- traverseInstanceRanges x rs
then return rs
else do
let t = Implicit Unspecified rs
tScoped <- scopeType t
insertElem x (tScoped, [])
let r1 : r2 : rest = rs
return $ (combineRanges r1 r2) : rest
traverseExprsM traverseExprM $ Instance m p x rs' l traverseExprsM traverseExprM $ Instance m p x rs' l
traverseModuleItemM item = traverseModuleItemM (NInputGate kw d x rs lhs exprs) = do
traverseLHSsM traverseLHSM item >>= rs' <- traverseInstanceRanges x rs
traverseModuleItemM' $ NInputGate kw d x rs' lhs exprs
traverseModuleItemM (NOutputGate kw d x rs lhss expr) = do
rs' <- traverseInstanceRanges x rs
traverseModuleItemM' $ NOutputGate kw d x rs' lhss expr
traverseModuleItemM item = traverseModuleItemM' item
traverseModuleItemM' :: ModuleItem -> Scoper TypeInfo ModuleItem
traverseModuleItemM' =
traverseLHSsM traverseLHSM >=>
traverseExprsM traverseExprM traverseExprsM traverseExprM
-- combines two ranges into one flattened range -- combines two ranges into one flattened range

View File

@ -606,16 +606,18 @@ traverseNodesM exprMapper declMapper typeMapper lhsMapper stmtMapper =
return $ Instance m p' x rs' l' return $ Instance m p' x rs' l'
moduleItemMapper (Modport x l) = moduleItemMapper (Modport x l) =
mapM modportDeclMapper l >>= return . Modport x mapM modportDeclMapper l >>= return . Modport x
moduleItemMapper (NInputGate kw d x lhs exprs) = do moduleItemMapper (NInputGate kw d x rs lhs exprs) = do
d' <- exprMapper d d' <- exprMapper d
exprs' <- mapM exprMapper exprs exprs' <- mapM exprMapper exprs
rs' <- mapM (mapBothM exprMapper) rs
lhs' <- lhsMapper lhs lhs' <- lhsMapper lhs
return $ NInputGate kw d' x lhs' exprs' return $ NInputGate kw d' x rs' lhs' exprs'
moduleItemMapper (NOutputGate kw d x lhss expr) = do moduleItemMapper (NOutputGate kw d x rs lhss expr) = do
d' <- exprMapper d d' <- exprMapper d
rs' <- mapM (mapBothM exprMapper) rs
lhss' <- mapM lhsMapper lhss lhss' <- mapM lhsMapper lhss
expr' <- exprMapper expr expr' <- exprMapper expr
return $ NOutputGate kw d' x lhss' expr' return $ NOutputGate kw d' x rs' lhss' expr'
moduleItemMapper (Genvar x) = return $ Genvar x moduleItemMapper (Genvar x) = return $ Genvar x
moduleItemMapper (Generate items) = do moduleItemMapper (Generate items) = do
items' <- mapM (traverseNestedGenItemsM genItemMapper) items items' <- mapM (traverseNestedGenItemsM genItemMapper) items
@ -768,12 +770,12 @@ traverseLHSsM mapper =
traverseModuleItemLHSsM (Defparam lhs expr) = do traverseModuleItemLHSsM (Defparam lhs expr) = do
lhs' <- mapper lhs lhs' <- mapper lhs
return $ Defparam lhs' expr return $ Defparam lhs' expr
traverseModuleItemLHSsM (NOutputGate kw d x lhss expr) = do traverseModuleItemLHSsM (NOutputGate kw d x rs lhss expr) = do
lhss' <- mapM mapper lhss lhss' <- mapM mapper lhss
return $ NOutputGate kw d x lhss' expr return $ NOutputGate kw d x rs lhss' expr
traverseModuleItemLHSsM (NInputGate kw d x lhs exprs) = do traverseModuleItemLHSsM (NInputGate kw d x rs lhs exprs) = do
lhs' <- mapper lhs lhs' <- mapper lhs
return $ NInputGate kw d x lhs' exprs return $ NInputGate kw d x rs lhs' exprs
traverseModuleItemLHSsM (AssertionItem (MIAssertion mx a)) = do traverseModuleItemLHSsM (AssertionItem (MIAssertion mx a)) = do
converted <- converted <-
traverseNestedStmtsM (traverseStmtLHSsM mapper) (Assertion a) traverseNestedStmtsM (traverseStmtLHSsM mapper) (Assertion a)

View File

@ -33,9 +33,9 @@ initialState = ([], 1)
traverseModuleItemM :: ModuleItem -> S ModuleItem traverseModuleItemM :: ModuleItem -> S ModuleItem
traverseModuleItemM item@(Genvar x) = declaration x item traverseModuleItemM item@(Genvar x) = declaration x item
traverseModuleItemM item@(NInputGate _ _ x _ _) = declaration x item traverseModuleItemM item@(NInputGate _ _ x _ _ _) = declaration x item
traverseModuleItemM item@(NOutputGate _ _ x _ _) = declaration x item traverseModuleItemM item@(NOutputGate _ _ x _ _ _) = declaration x item
traverseModuleItemM item@(Instance _ _ x _ _) = declaration x item traverseModuleItemM item@(Instance _ _ x _ _) = declaration x item
traverseModuleItemM (MIPackageItem (Decl decl)) = traverseModuleItemM (MIPackageItem (Decl decl)) =
traverseDeclM decl >>= return . MIPackageItem . Decl traverseDeclM decl >>= return . MIPackageItem . Decl
traverseModuleItemM (MIAttr attr item) = traverseModuleItemM (MIAttr attr item) =

View File

@ -43,8 +43,8 @@ data ModuleItem
| Final Stmt | Final Stmt
| ElabTask Severity [Expr] | ElabTask Severity [Expr]
| MIPackageItem PackageItem | MIPackageItem PackageItem
| NInputGate NInputGateKW Expr Identifier LHS [Expr] | NInputGate NInputGateKW Expr Identifier [Range] LHS [Expr]
| NOutputGate NOutputGateKW Expr Identifier [LHS] Expr | NOutputGate NOutputGateKW Expr Identifier [Range] [LHS] Expr
| AssertionItem AssertionItem | AssertionItem AssertionItem
deriving Eq deriving Eq
@ -60,10 +60,10 @@ instance Show ModuleItem where
show (Initial s ) = printf "initial %s" (show s) show (Initial s ) = printf "initial %s" (show s)
show (Final s ) = printf "final %s" (show s) show (Final s ) = printf "final %s" (show s)
show (ElabTask s a) = printf "%s%s;" (show s) (show $ Args a []) show (ElabTask s a) = printf "%s%s;" (show s) (show $ Args a [])
show (NInputGate kw d x lhs exprs) = show (NInputGate kw d x rs lhs exprs) =
showGate kw d x $ show lhs : map show exprs showGate kw d x rs $ show lhs : map show exprs
show (NOutputGate kw d x lhss expr) = show (NOutputGate kw d x rs lhss expr) =
showGate kw d x $ (map show lhss) ++ [show expr] showGate kw d x rs $ (map show lhss) ++ [show expr]
show (AssertionItem i) = show i show (AssertionItem i) = show i
show (Instance m params i rs ports) = show (Instance m params i rs ports) =
if null params if null params
@ -81,12 +81,13 @@ showPort (i, arg) =
then show arg then show arg
else printf ".%s(%s)" i (show arg) else printf ".%s(%s)" i (show arg)
showGate :: Show k => k -> Expr -> Identifier -> [String] -> String showGate :: Show k => k -> Expr -> Identifier -> [Range] -> [String] -> String
showGate kw d x args = showGate kw d x rs args =
printf "%s %s%s(%s);" (show kw) delayStr nameStr (commas args) printf "%s %s%s%s(%s);" (show kw) delayStr nameStr rsStr (commas args)
where where
delayStr = if d == Nil then "" else showPad $ Delay d delayStr = if d == Nil then "" else showPad $ Delay d
nameStr = showPad $ Ident x nameStr = showPad $ Ident x
rsStr = if null rs then "" else tail $ showRanges rs
showModportDecl :: ModportDecl -> String showModportDecl :: ModportDecl -> String
showModportDecl (dir, ident, e) = showModportDecl (dir, ident, e) =

View File

@ -719,8 +719,8 @@ NonGenerateModuleItem :: { [ModuleItem] }
| "modport" ModportItems ";" { map (uncurry Modport) $2 } | "modport" ModportItems ";" { map (uncurry Modport) $2 }
| NonDeclPackageItem { map MIPackageItem $1 } | NonDeclPackageItem { map MIPackageItem $1 }
| TaskOrFunction { [MIPackageItem $1] } | TaskOrFunction { [MIPackageItem $1] }
| NInputGateKW NInputGates ";" { map (\(a, b, c, d) -> NInputGate $1 a b c d) $2 } | NInputGateKW NInputGates ";" { map (\(a, b, c, d, e) -> NInputGate $1 a b c d e) $2 }
| NOutputGateKW NOutputGates ";" { map (\(a, b, c, d) -> NOutputGate $1 a b c d) $2 } | NOutputGateKW NOutputGates ";" { map (\(a, b, c, d, e) -> NOutputGate $1 a b c d e) $2 }
| AttributeInstance ModuleItem { map (addMIAttr $1) $2 } | AttributeInstance ModuleItem { map (addMIAttr $1) $2 }
| AssertionItem { [AssertionItem $1] } | AssertionItem { [AssertionItem $1] }
@ -852,23 +852,23 @@ AttrSpecs :: { [AttrSpec] }
AttrSpec :: { AttrSpec } AttrSpec :: { AttrSpec }
: Identifier OptAsgn { ($1, $2) } : Identifier OptAsgn { ($1, $2) }
NInputGates :: { [(Expr, Identifier, LHS, [Expr])] } NInputGates :: { [(Expr, Identifier, [Range], LHS, [Expr])] }
: NInputGate { [$1] } : NInputGate { [$1] }
| NInputGates "," NInputGate { $1 ++ [$3]} | NInputGates "," NInputGate { $1 ++ [$3]}
NOutputGates :: { [(Expr, Identifier, [LHS], Expr)] } NOutputGates :: { [(Expr, Identifier, [Range], [LHS], Expr)] }
: NOutputGate { [$1] } : NOutputGate { [$1] }
| NOutputGates "," NOutputGate { $1 ++ [$3]} | NOutputGates "," NOutputGate { $1 ++ [$3]}
NInputGate :: { (Expr, Identifier, LHS, [Expr]) } NInputGate :: { (Expr, Identifier, [Range], LHS, [Expr]) }
: DelayControlOrNil OptIdentifier "(" LHS "," Exprs ")" { ($1, $2, $4, $6) } : DelayControlOrNil OptGateName "(" LHS "," Exprs ")" { ($1, fst $2, snd $2, $4, $6) }
NOutputGate :: { (Expr, Identifier, [LHS], Expr) } NOutputGate :: { (Expr, Identifier, [Range], [LHS], Expr) }
: DelayControlOrNil OptIdentifier "(" Exprs "," Expr ")" { ($1, $2, map toLHS $4, $6) } : DelayControlOrNil OptGateName "(" Exprs "," Expr ")" { ($1, fst $2, snd $2, map toLHS $4, $6) }
DelayControlOrNil :: { Expr } DelayControlOrNil :: { Expr }
: DelayControl { $1 } : DelayControl { $1 }
| {- empty -} { Nil } | {- empty -} { Nil }
OptIdentifier :: { Identifier } OptGateName :: { (Identifier, [Range]) }
: Identifier { $1 } : Identifier Dimensions { ($1, $2) }
| {- empty -} { "" } | {- empty -} { ("", []) }
NInputGateKW :: { NInputGateKW } NInputGateKW :: { NInputGateKW }
: "and" { GateAnd } : "and" { GateAnd }

13
test/core/gate_array.sv Normal file
View File

@ -0,0 +1,13 @@
module mod(
input logic input_a, input_b,
input logic [1:0] input_c,
input logic [1:0][2:0] input_d,
output logic [1:0] output_a, output_b,
output logic [1:0][2:0] output_c,
output logic [0:1][2:0] output_d
);
and gate_a[1:0] (output_a, input_a, input_c);
and gate_b[1:0] (output_b, input_a, input_b);
and gate_c[1:0][2:0] (output_c, input_a, input_d);
and gate_d[1:0][0:2] (output_d, input_b, input_d);
endmodule

12
test/core/gate_array.v Normal file
View File

@ -0,0 +1,12 @@
module mod(
input input_a, input_b,
input [1:0] input_c,
input [5:0] input_d,
output [1:0] output_a, output_b,
output [5:0] output_c, output_d
);
and gate_a[1:0] (output_a, input_a, input_c);
and gate_b[1:0] (output_b, input_a, input_b);
and gate_c[5:0] (output_c, input_a, input_d);
and gate_d[5:0] (output_d, input_b, input_d);
endmodule

25
test/core/gate_array_tb.v Normal file
View File

@ -0,0 +1,25 @@
module top;
wire input_a, input_b;
wire [1:0] input_c;
wire [5:0] input_d;
wire [1:0] output_a, output_b;
wire [5:0] output_c, output_d;
mod m(
input_a, input_b, input_c, input_d,
output_a, output_b, output_c, output_d
);
integer i;
localparam bits = $bits({input_a, input_b, input_c, input_d });
assign {input_a, input_b, input_c, input_d} = i;
initial begin
$monitor(
"%03d (%b, %b, %b, %b) -> (%b, %b, %b, %b)",
$time,
input_a, input_b, input_c, input_d,
output_a, output_b, output_c, output_d
);
repeat(3)
for (i = 0; i < 2 ** bits; i = i + 1)
#1;
end
endmodule