Commit 9a38225b by Zachary Snow

several major fixes surrounding packed arrays

- entirely new PackedArray conversion (always flattens)
- typedef and struct correctly order packed ranges when combining types
- Stmt LHS traversal no longer traverses nested statements to avoid double conversion
- Logic conversion applies to `initial` blocks`
- new and modified tests to cover these cases
parent fb3d68e3
...@@ -57,7 +57,7 @@ convertDescription orig = ...@@ -57,7 +57,7 @@ convertDescription orig =
regIdents :: ModuleItem -> Writer RegIdents () regIdents :: ModuleItem -> Writer RegIdents ()
regIdents (AlwaysC _ stmt) = regIdents (AlwaysC _ stmt) =
collectStmtLHSsM (collectNestedLHSsM idents) $ collectNestedStmtsM (collectStmtLHSsM (collectNestedLHSsM idents)) $
traverseNestedStmts removeTimings stmt traverseNestedStmts removeTimings stmt
where where
idents :: LHS -> Writer RegIdents () idents :: LHS -> Writer RegIdents ()
...@@ -66,4 +66,6 @@ regIdents (AlwaysC _ stmt) = ...@@ -66,4 +66,6 @@ regIdents (AlwaysC _ stmt) =
removeTimings :: Stmt -> Stmt removeTimings :: Stmt -> Stmt
removeTimings (Timing _ s) = s removeTimings (Timing _ s) = s
removeTimings other = other removeTimings other = other
regIdents (Initial stmt) =
regIdents $ AlwaysC Always stmt
regIdents _ = return () regIdents _ = return ()
...@@ -101,7 +101,7 @@ convertType :: Structs -> Type -> Type ...@@ -101,7 +101,7 @@ convertType :: Structs -> Type -> Type
convertType structs t1 = convertType structs t1 =
case Map.lookup tf1 structs of case Map.lookup tf1 structs of
Nothing -> t1 Nothing -> t1
Just (t2, _) -> tf2 (rs2 ++ rs1) Just (t2, _) -> tf2 (rs1 ++ rs2)
where (tf2, rs2) = typeRanges t2 where (tf2, rs2) = typeRanges t2
where (tf1, rs1) = typeRanges t1 where (tf1, rs1) = typeRanges t1
...@@ -141,30 +141,46 @@ convertAsgn structs types (lhs, expr) = ...@@ -141,30 +141,46 @@ convertAsgn structs types (lhs, expr) =
Nothing -> (Implicit Unspecified [], LHSIdent x) Nothing -> (Implicit Unspecified [], LHSIdent x)
Just t -> (t, LHSIdent x) Just t -> (t, LHSIdent x)
convertLHS (LHSBit l e) = convertLHS (LHSBit l e) =
if null rs case l' of
then (Implicit Unspecified [], LHSBit l' e') LHSRange lInner NonIndexed (_, loI) ->
else (tf $ tail rs, LHSBit l' e') (t', LHSBit lInner (simplify $ BinOp Add loI e'))
LHSRange lInner IndexedPlus (baseI, _) ->
(t', LHSBit lInner (simplify $ BinOp Add baseI e'))
_ -> (t', LHSBit l' e')
where where
(t, l') = convertLHS l (t, l') = convertLHS l
(tf, rs) = typeRanges t t' = case typeRanges t of
(_, []) -> Implicit Unspecified []
(tf, rs) -> tf $ tail rs
e' = snd $ convertSubExpr e e' = snd $ convertSubExpr e
convertLHS (LHSRange l m rOuterOrig) = convertLHS (LHSRange lOuter NonIndexed rOuterOrig) =
case l' of case lOuter' of
LHSRange lInner NonIndexed (_, loI) -> LHSRange lInner NonIndexed (_, loI) ->
(t, LHSRange lInner m (simplify hi, simplify lo)) (t, LHSRange lInner NonIndexed (simplify hi, simplify lo))
where where
lo = BinOp Add loI loO lo = BinOp Add loI loO
hi = BinOp Add loI hiO hi = BinOp Add loI hiO
_ -> if null rs LHSRange lInner IndexedPlus (baseI, _) ->
then (Implicit Unspecified [], LHSRange l' m rOuter) (t, LHSRange lInner IndexedPlus (simplify base, simplify len))
else (tf rs', LHSRange l' m rOuter) where
base = BinOp Add baseI loO
len = rangeSize rOuter
_ -> (t, LHSRange lOuter' NonIndexed rOuter)
where where
(t, l') = convertLHS l
(tf, rs) = typeRanges t
hiO = snd $ convertSubExpr $ fst rOuterOrig hiO = snd $ convertSubExpr $ fst rOuterOrig
loO = snd $ convertSubExpr $ snd rOuterOrig loO = snd $ convertSubExpr $ snd rOuterOrig
rOuter = (hiO, loO) rOuter = (hiO, loO)
rs' = rOuter : tail rs (t, lOuter') = convertLHS lOuter
convertLHS (LHSRange l m r) =
(t', LHSRange l' m r')
where
hi = snd $ convertSubExpr $ fst r
lo = snd $ convertSubExpr $ snd r
r' = (hi, lo)
(t, l') = convertLHS l
t' = case typeRanges t of
(_, []) -> Implicit Unspecified []
(tf, rs) -> tf $ tail rs
convertLHS (LHSDot l x ) = convertLHS (LHSDot l x ) =
case t of case t of
InterfaceT _ _ _ -> (Implicit Unspecified [], LHSDot l' x) InterfaceT _ _ _ -> (Implicit Unspecified [], LHSDot l' x)
...@@ -236,18 +252,30 @@ convertAsgn structs types (lhs, expr) = ...@@ -236,18 +252,30 @@ convertAsgn structs types (lhs, expr) =
structTf = Struct p fields structTf = Struct p fields
fieldType = lookupFieldType fields x fieldType = lookupFieldType fields x
r = lookupUnstructRange structTf x r = lookupUnstructRange structTf x
convertSubExpr (Range eOuter m (rOuter @ (hiO, loO))) = convertSubExpr (Range eOuter NonIndexed (rOuter @ (hiO, loO))) =
-- VCS doesn't allow ranges to be cascaded, so we need to combine -- VCS doesn't allow ranges to be cascaded, so we need to combine
-- nested Ranges into a single range. My understanding of the -- nested Ranges into a single range. My understanding of the
-- semantics are that a range returns a new, zero-indexed sub-range. -- semantics are that a range returns a new, zero-indexed sub-range.
case eOuter' of case eOuter' of
Range eInner NonIndexed (_, loI) -> Range eInner NonIndexed (_, loI) ->
(t, Range eInner m (simplify hi, simplify lo)) (t, Range eInner NonIndexed (simplify hi, simplify lo))
where where
lo = BinOp Add loI loO lo = BinOp Add loI loO
hi = BinOp Add loI hiO hi = BinOp Add loI hiO
_ -> (t, Range eOuter' m rOuter) Range eInner IndexedPlus (baseI, _) ->
(t, Range eInner IndexedPlus (simplify base, simplify len))
where
base = BinOp Add baseI loO
len = rangeSize rOuter
_ -> (t, Range eOuter' NonIndexed rOuter)
where (t, eOuter') = convertSubExpr eOuter where (t, eOuter') = convertSubExpr eOuter
convertSubExpr (Range e m r) =
(t', Range e' m r)
where
(t, e') = convertSubExpr e
t' = case typeRanges t of
(_, []) -> Implicit Unspecified []
(tf, rs) -> tf $ tail rs
convertSubExpr (Concat exprs) = convertSubExpr (Concat exprs) =
(Implicit Unspecified [], Concat $ map (snd . convertSubExpr) exprs) (Implicit Unspecified [], Concat $ map (snd . convertSubExpr) exprs)
convertSubExpr (BinOp op e1 e2) = convertSubExpr (BinOp op e1 e2) =
...@@ -259,6 +287,8 @@ convertAsgn structs types (lhs, expr) = ...@@ -259,6 +287,8 @@ convertAsgn structs types (lhs, expr) =
case e' of case e' of
Range eInner NonIndexed (_, loI) -> Range eInner NonIndexed (_, loI) ->
(t', Bit eInner (simplify $ BinOp Add loI i')) (t', Bit eInner (simplify $ BinOp Add loI i'))
Range eInner IndexedPlus (baseI, _) ->
(t', Bit eInner (simplify $ BinOp Add baseI i'))
_ -> (t', Bit e' i') _ -> (t', Bit e' i')
where where
(t, e') = convertSubExpr e (t, e') = convertSubExpr e
......
...@@ -60,6 +60,7 @@ module Convert.Traverse ...@@ -60,6 +60,7 @@ module Convert.Traverse
, traverseNestedModuleItems , traverseNestedModuleItems
, collectNestedModuleItemsM , collectNestedModuleItemsM
, traverseNestedStmts , traverseNestedStmts
, collectNestedStmtsM
, traverseNestedExprs , traverseNestedExprs
, collectNestedExprsM , collectNestedExprsM
, traverseNestedLHSsM , traverseNestedLHSsM
...@@ -303,7 +304,7 @@ traverseAssertionExprsM mapper = assertionMapper ...@@ -303,7 +304,7 @@ traverseAssertionExprsM mapper = assertionMapper
return $ Cover e' stmt return $ Cover e' stmt
traverseStmtLHSsM :: Monad m => MapperM m LHS -> MapperM m Stmt traverseStmtLHSsM :: Monad m => MapperM m LHS -> MapperM m Stmt
traverseStmtLHSsM mapper = traverseNestedStmtsM stmtMapper traverseStmtLHSsM mapper = stmtMapper
where where
fullMapper = mapper fullMapper = mapper
stmtMapper (Timing (Event sense) stmt) = do stmtMapper (Timing (Event sense) stmt) = do
...@@ -591,7 +592,7 @@ traverseLHSsM' strat mapper item = ...@@ -591,7 +592,7 @@ traverseLHSsM' strat mapper item =
lhs' <- mapper lhs lhs' <- mapper lhs
return $ NInputGate kw x lhs' exprs return $ NInputGate kw x lhs' exprs
traverseModuleItemLHSsM (AssertionItem (mx, a)) = do traverseModuleItemLHSsM (AssertionItem (mx, a)) = do
Assertion a' <- traverseStmtLHSsM mapper (Assertion a) Assertion a' <- traverseNestedStmtsM (traverseStmtLHSsM mapper) (Assertion a)
return $ AssertionItem (mx, a') return $ AssertionItem (mx, a')
traverseModuleItemLHSsM other = return other traverseModuleItemLHSsM other = return other
...@@ -610,7 +611,7 @@ collectLHSsM = collectLHSsM' IncludeTFs ...@@ -610,7 +611,7 @@ collectLHSsM = collectLHSsM' IncludeTFs
traverseNestedLHSsM :: Monad m => MapperM m LHS -> MapperM m LHS traverseNestedLHSsM :: Monad m => MapperM m LHS -> MapperM m LHS
traverseNestedLHSsM mapper = fullMapper traverseNestedLHSsM mapper = fullMapper
where where
fullMapper lhs = tl lhs >>= mapper fullMapper lhs = mapper lhs >>= tl
tl (LHSIdent x ) = return $ LHSIdent x tl (LHSIdent x ) = return $ LHSIdent x
tl (LHSBit l e ) = fullMapper l >>= \l' -> return $ LHSBit l' e tl (LHSBit l e ) = fullMapper l >>= \l' -> return $ LHSBit l' e
tl (LHSRange l m r) = fullMapper l >>= \l' -> return $ LHSRange l' m r tl (LHSRange l m r) = fullMapper l >>= \l' -> return $ LHSRange l' m r
...@@ -792,6 +793,8 @@ collectNestedModuleItemsM = collectify traverseNestedModuleItemsM ...@@ -792,6 +793,8 @@ collectNestedModuleItemsM = collectify traverseNestedModuleItemsM
traverseNestedStmts :: Mapper Stmt -> Mapper Stmt traverseNestedStmts :: Mapper Stmt -> Mapper Stmt
traverseNestedStmts = unmonad traverseNestedStmtsM traverseNestedStmts = unmonad traverseNestedStmtsM
collectNestedStmtsM :: Monad m => CollectorM m Stmt -> CollectorM m Stmt
collectNestedStmtsM = collectify traverseNestedStmtsM
traverseNestedExprs :: Mapper Expr -> Mapper Expr traverseNestedExprs :: Mapper Expr -> Mapper Expr
traverseNestedExprs = unmonad traverseNestedExprsM traverseNestedExprs = unmonad traverseNestedExprsM
......
...@@ -72,12 +72,12 @@ resolveType types (Alias st rs1) = ...@@ -72,12 +72,12 @@ resolveType types (Alias st rs1) =
if Map.notMember st types if Map.notMember st types
then InterfaceT st Nothing rs1 then InterfaceT st Nothing rs1
else case resolveType types $ types Map.! st of else case resolveType types $ types Map.! st of
(Net kw rs2) -> Net kw $ rs2 ++ rs1 (Net kw rs2) -> Net kw $ rs1 ++ rs2
(Implicit sg rs2) -> Implicit sg $ rs2 ++ rs1 (Implicit sg rs2) -> Implicit sg $ rs1 ++ rs2
(IntegerVector kw sg rs2) -> IntegerVector kw sg $ rs2 ++ rs1 (IntegerVector kw sg rs2) -> IntegerVector kw sg $ rs1 ++ rs2
(Enum t v rs2) -> Enum t v $ rs2 ++ rs1 (Enum t v rs2) -> Enum t v $ rs1 ++ rs2
(Struct p l rs2) -> Struct p l $ rs2 ++ rs1 (Struct p l rs2) -> Struct p l $ rs1 ++ rs2
(InterfaceT x my rs2) -> InterfaceT x my $ rs2 ++ rs1 (InterfaceT x my rs2) -> InterfaceT x my $ rs1 ++ rs2
(IntegerAtom kw _ ) -> error $ "resolveType encountered packed `" ++ (show kw) ++ "` on " ++ st (IntegerAtom kw _ ) -> error $ "resolveType encountered packed `" ++ (show kw) ++ "` on " ++ st
(NonInteger kw ) -> error $ "resolveType encountered packed `" ++ (show kw) ++ "` on " ++ st (NonInteger kw ) -> error $ "resolveType encountered packed `" ++ (show kw) ++ "` on " ++ st
(Alias _ _) -> error $ "resolveType invariant failed on " ++ st (Alias _ _) -> error $ "resolveType invariant failed on " ++ st
...@@ -145,7 +145,10 @@ simplify other = other ...@@ -145,7 +145,10 @@ simplify other = other
rangeSize :: Range -> Expr rangeSize :: Range -> Expr
rangeSize (s, e) = rangeSize (s, e) =
simplify $ BinOp Add (BinOp Sub s e) (Number "1") endianCondExpr (s, e) a b
where
a = simplify $ BinOp Add (BinOp Sub s e) (Number "1")
b = simplify $ BinOp Add (BinOp Sub e s) (Number "1")
-- chooses one or the other expression based on the endianness of the given -- chooses one or the other expression based on the endianness of the given
-- range; [hi:lo] chooses the first expression -- range; [hi:lo] chooses the first expression
......
`define CASE_A(name, dims) \ `define CASE(name, dims, a, b) \
module name(clock, in, out); \ module name(clock, in, out); \
input wire clock, in; \ input wire clock, in; \
output logic dims out; \ output logic dims out; \
initial out[0] = 0; \ initial out[0+a] = 0; \
initial out[1] = 0; \ initial out[1+a] = 0; \
initial out[2] = 0; \ initial out[2+a] = 0; \
always @(posedge clock) begin \ always @(posedge clock) begin \
\ /*$display($time, `" name ", out[0+a][1+b+:1]);*/ \
out[2][4] = out[2][3]; \ /*$display($time, `" name ", out[0+a][1+b+:1]);*/ \
out[2][3] = out[2][2]; \ /*$display($time, `" name ", out[1+a][1+b+:1]);*/ \
out[2][2] = out[2][1]; \ /*$display($time, `" name ", out[1+a][1+b+:1]);*/ \
out[2][1] = out[2][0]; \ /*$display($time, `" name ", out[2+a][1+b+:1]);*/ \
out[2][0] = out[1][4]; \ /*$display($time, `" name ", out[2+a][1+b+:1]);*/ \
\ \
out[1][4] = out[1][3]; \ out[2+a][4+b] = out[2+a][3+b]; \
out[1][3] = out[1][2]; \ out[2+a][3+b] = out[2+a][2+b]; \
out[1][2] = out[1][1]; \ out[2+a][2+b] = out[2+a][1+b]; \
out[1][1] = out[1][0]; \ out[2+a][1+b] = out[2+a][0+b]; \
out[1][0] = out[0][4]; \ out[2+a][0+b] = out[1+a][4+b]; \
\ \
out[0][4] = out[0][3]; \ out[1+a][4+b] = out[1+a][3+b]; \
out[0][3] = out[0][2]; \ out[1+a][3+b] = out[1+a][2+b]; \
out[0][2] = out[0][1]; \ out[1+a][2+b] = out[1+a][1+b]; \
out[0][1] = out[0][0]; \ out[1+a][1+b] = out[1+a][0+b]; \
out[0][0] = in; \ out[1+a][0+b] = out[0+a][4+b]; \
\
out[0+a][4+b] = out[0+a][3+b]; \
out[0+a][3+b] = out[0+a][2+b]; \
out[0+a][2+b] = out[0+a][1+b]; \
out[0+a][1+b] = out[0+a][0+b]; \
out[0+a][0+b] = in; \
\ \
end \ end \
endmodule endmodule
`CASE_A(A1, [2:0][4:0]) `CASE(A1, [2:0][4:0], 0, 0)
`CASE_A(A2, [0:2][0:4]) `CASE(A2, [0:2][0:4], 0, 0)
`CASE_A(A3, [0:2][4:0]) `CASE(A3, [0:2][4:0], 0, 0)
`CASE_A(A4, [2:0][0:4]) `CASE(A4, [2:0][0:4], 0, 0)
`define CASE_B(name, dims) \
module name(clock, in, out); \
input wire clock, in; \
output logic dims out; \
initial out[1] = 0; \
initial out[2] = 0; \
initial out[3] = 0; \
always @(posedge clock) begin \
\
out[3][5] = out[3][4]; \
out[3][4] = out[3][3]; \
out[3][3] = out[3][2]; \
out[3][2] = out[3][1]; \
out[3][1] = out[2][5]; \
\
out[2][5] = out[2][4]; \
out[2][4] = out[2][3]; \
out[2][3] = out[2][2]; \
out[2][2] = out[2][1]; \
out[2][1] = out[1][5]; \
\
out[1][5] = out[1][4]; \
out[1][4] = out[1][3]; \
out[1][3] = out[1][2]; \
out[1][2] = out[1][1]; \
out[1][1] = in; \
\
end \
endmodule
`CASE_B(B1, [3:1][5:1]) `CASE(B1, [3:1][5:1], 1, 1)
`CASE_B(B2, [1:3][1:5]) `CASE(B2, [1:3][1:5], 1, 1)
`CASE_B(B3, [1:3][5:1]) `CASE(B3, [1:3][5:1], 1, 1)
`CASE_B(B4, [3:1][1:5]) `CASE(B4, [3:1][1:5], 1, 1)
`define CASE_C(name, dims) \ `CASE(C1, [4:2][6:2], 2, 2)
module name(clock, in, out); \ `CASE(C2, [2:4][2:6], 2, 2)
input wire clock, in; \ `CASE(C3, [2:4][6:2], 2, 2)
output logic dims out; \ `CASE(C4, [4:2][2:6], 2, 2)
initial out[2] = 0; \
initial out[3] = 0; \
initial out[4] = 0; \
always @(posedge clock) begin \
\
out[4][6] = out[4][5]; \
out[4][5] = out[4][4]; \
out[4][4] = out[4][3]; \
out[4][3] = out[4][2]; \
out[4][2] = out[3][6]; \
\
out[3][6] = out[3][5]; \
out[3][5] = out[3][4]; \
out[3][4] = out[3][3]; \
out[3][3] = out[3][2]; \
out[3][2] = out[2][6]; \
\
out[2][6] = out[2][5]; \
out[2][5] = out[2][4]; \
out[2][4] = out[2][3]; \
out[2][3] = out[2][2]; \
out[2][2] = in; \
\
end \
endmodule
`CASE_C(C1, [4:2][6:2]) `CASE(D1, [5:3][6:2], 3, 2)
`CASE_C(C2, [2:4][2:6]) `CASE(D2, [3:5][2:6], 3, 2)
`CASE_C(C3, [2:4][6:2]) `CASE(D3, [3:5][6:2], 3, 2)
`CASE_C(C4, [4:2][2:6]) `CASE(D4, [5:3][2:6], 3, 2)
...@@ -4,9 +4,13 @@ ...@@ -4,9 +4,13 @@
tag``2 tag``two(.clock(clock), .in(in), .out(tag``two_out)); \ tag``2 tag``two(.clock(clock), .in(in), .out(tag``two_out)); \
tag``3 tag``thr(.clock(clock), .in(in), .out(tag``thr_out)); \ tag``3 tag``thr(.clock(clock), .in(in), .out(tag``thr_out)); \
tag``4 tag``fou(.clock(clock), .in(in), .out(tag``fou_out)); \ tag``4 tag``fou(.clock(clock), .in(in), .out(tag``fou_out)); \
integer tag``i; \
initial begin \ initial begin \
$monitor(`"tag", $time, ": %h %15b %15b %15b %15b", in, \ for (tag``i = 0; tag``i < 20; tag``i++) begin \
tag``one_out, tag``two_out, tag``thr_out, tag``fou_out); \ #2; \
$display(`"tag", $time, ": %h %15b %15b %15b %15b", in, \
tag``one_out, tag``two_out, tag``thr_out, tag``fou_out); \
end \
end end
module top; module top;
...@@ -30,5 +34,6 @@ module top; ...@@ -30,5 +34,6 @@ module top;
`FOO(A) `FOO(A)
`FOO(B) `FOO(B)
`FOO(C) `FOO(C)
`FOO(D)
endmodule endmodule
`define PRINT(arr, a, b) \
$display(arr[0+a][0+b]); \
$display(arr[0+a][1+b]); \
$display(arr[0+a][2+b]); \
$display(arr[1+a][0+b]); \
$display(arr[1+a][1+b]); \
$display(arr[1+a][2+b]); \
$display(arr[2+a][0+b]); \
$display(arr[2+a][1+b]); \
$display(arr[2+a][2+b]); \
$display(arr[3+a][0+b]); \
$display(arr[3+a][1+b]); \
$display(arr[3+a][2+b]); \
$display(arr[4+a][0+b]); \
$display(arr[4+a][1+b]); \
$display(arr[4+a][2+b]);
module Example;
typedef logic [2:0] Pack;
Pack [4:0] arr1;
Pack [4:0] arr2;
Pack [4:0] arr3;
initial begin
arr1 = 'b100101010100100;
arr1[0][1] = ~arr1[0][1];
arr1[4][2] = ~arr1[4][2];
`PRINT(arr1, 0, 0)
arr2 = 'b100101000110101;
`PRINT(arr2, 0, 0)
arr3 = 'b100100111101010;
arr3[1] = arr3[2];
`PRINT(arr3, 0, 0)
end
Pack [5:1] arr4;
Pack [5:1] arr5;
Pack [5:1] arr6;
initial begin
arr4 = 'b100101010100100;
arr4[1][1] = ~arr4[1][1];
arr4[5][2] = ~arr4[5][2];
`PRINT(arr4, 1, 0)
arr5 = 'b100101000110101;
`PRINT(arr5, 1, 0)
arr6 = 'b100100111101010;
arr6[2] = arr6[3];
`PRINT(arr6, 1, 0)
end
Pack [1:5] arr7;
Pack [1:5] arr8;
Pack [1:5] arr9;
initial begin
arr7 = 'b100101010100100;
arr7[1][1] = ~arr7[1][1];
arr7[5][2] = ~arr7[5][2];
`PRINT(arr7, 1, 0)
arr8 = 'b100101000110101;
`PRINT(arr8, 1, 0)
arr9 = 'b100100111101010;
arr9[2] = arr9[3];
`PRINT(arr9, 1, 0)
end
endmodule
`define PRINT(arr, a, b) \
$display(arr[0+a][0+b]); \
$display(arr[0+a][1+b]); \
$display(arr[0+a][2+b]); \
$display(arr[1+a][0+b]); \
$display(arr[1+a][1+b]); \
$display(arr[1+a][2+b]); \
$display(arr[2+a][0+b]); \
$display(arr[2+a][1+b]); \
$display(arr[2+a][2+b]); \
$display(arr[3+a][0+b]); \
$display(arr[3+a][1+b]); \
$display(arr[3+a][2+b]); \
$display(arr[4+a][0+b]); \
$display(arr[4+a][1+b]); \
$display(arr[4+a][2+b]);
module Example;
reg [4:0][2:0] arr1;
reg [4:0][2:0] arr2;
reg [4:0][2:0] arr3;
initial begin
arr1 = 'b100101010100100;
arr1[0][1] = ~arr1[0][1];
arr1[4][2] = ~arr1[4][2];
`PRINT(arr1, 0, 0)
arr2 = 'b100101000110101;
`PRINT(arr2, 0, 0)
arr3 = 'b100100111101010;
arr3[1] = arr3[2];
`PRINT(arr3, 0, 0)
end
reg [5:1][2:0] arr4;
reg [5:1][2:0] arr5;
reg [5:1][2:0] arr6;
initial begin
arr4 = 'b100101010100100;
arr4[1][1] = ~arr4[1][1];
arr4[5][2] = ~arr4[5][2];
`PRINT(arr4, 1, 0)
arr5 = 'b100101000110101;
`PRINT(arr5, 1, 0)
arr6 = 'b100100111101010;
arr6[2] = arr6[3];
`PRINT(arr6, 1, 0)
end
reg [1:5][2:0] arr7;
reg [1:5][2:0] arr8;
reg [1:5][2:0] arr9;
initial begin
arr7 = 'b100101010100100;
arr7[1][1] = ~arr7[1][1];
arr7[5][2] = ~arr7[5][2];
`PRINT(arr7, 1, 0)
arr8 = 'b100101000110101;
`PRINT(arr8, 1, 0)
arr9 = 'b100100111101010;
arr9[2] = arr9[3];
`PRINT(arr9, 1, 0)
end
endmodule
module top;
Example example();
endmodule
typedef struct packed {
logic x;
logic [3:0] y;
logic [1:0] z;
} Struct_t;
module Unpacker(in, select, a, b, c);
parameter WIDTH = 8;
input Struct_t [WIDTH-1:0] in;
input logic [$clog2(WIDTH)-1:0] select;
output logic a;
output logic [3:0] b;
output logic [1:0] c;
assign a = in[select].x;
assign b = in[select].y;
assign c = in[select].z;
endmodule
module Unpacker(in, select, a, b, c);
parameter WIDTH = 8;
input wire [WIDTH-1:0][6:0] in;
input wire [$clog2(WIDTH)-1:0] select;
output wire a;
output wire [3:0] b;
output wire [1:0] c;
wire [6:0] p;
assign p = in[select];
assign a = p[6:6];
assign b = p[5:2];
assign c = p[1:0];
endmodule
module top;
reg [56-1:0] in;
reg [2:0] select;
wire a;
wire [3:0] b;
wire [1:0] c;
Unpacker unpacker(in, select, a, b, c);
initial begin
$monitor("%d: %01b %04b %02b", select, a, b, c);
in = 'b01111011011011101111100111110111001010001011100110101000;
select = 0; #1;
select = 1; #1;
select = 2; #1;
select = 3; #1;
select = 4; #1;
select = 5; #1;
select = 6; #1;
select = 7; #1;
$finish;
end
// 0 1010 00
// 1 1100 11
// 0 1000 10
// 0 1110 01
// 0 0111 11
// 1 0111 11
// 1 0110 11
// 0 1111 01
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