Commit 81f5fb50 by Zachary Snow

added conversion for packed unions

parent 8a67a911
{- sv2v {- sv2v
- Author: Zachary Snow <zach@zachjs.com> - Author: Zachary Snow <zach@zachjs.com>
- -
- Conversion for `struct packed` - Conversion for `struct packed` and `union packed`
-} -}
module Convert.Struct (convert) where module Convert.Struct (convert) where
...@@ -70,10 +70,19 @@ convertDescription other = other ...@@ -70,10 +70,19 @@ convertDescription other = other
-- write down unstructured versions of packed struct types -- write down unstructured versions of packed struct types
collectStructM :: Type -> Writer Structs () collectStructM :: Type -> Writer Structs ()
collectStructM (Struct (Packed sg) fields _) = do collectStructM (Struct (Packed sg) fields _) =
collectStructM' Struct True sg fields
collectStructM (Union (Packed sg) fields _) =
collectStructM' Union False sg fields
collectStructM _ = return ()
collectStructM'
:: (Packing -> [Field] -> [Range] -> Type)
-> Bool -> Signing -> [Field] -> Writer Structs ()
collectStructM' constructor isStruct sg fields = do
if canUnstructure if canUnstructure
then tell $ Map.singleton then tell $ Map.singleton
(Struct (Packed sg) fields) (constructor (Packed sg) fields)
(unstructType, unstructFields) (unstructType, unstructFields)
else return () else return ()
where where
...@@ -90,8 +99,14 @@ collectStructM (Struct (Packed sg) fields _) = do ...@@ -90,8 +99,14 @@ collectStructM (Struct (Packed sg) fields _) = do
-- layout the fields into the unstructured type; note that `scanr` is -- layout the fields into the unstructured type; note that `scanr` is
-- used here because SystemVerilog structs are laid out backwards -- used here because SystemVerilog structs are laid out backwards
fieldLos = map simplify $ tail $ scanr (BinOp Add) (Number "0") fieldSizes fieldLos =
fieldHis = map simplify $ init $ scanr (BinOp Add) (Number "-1") fieldSizes if isStruct
then map simplify $ tail $ scanr (BinOp Add) (Number "0") fieldSizes
else map simplify $ repeat (Number "0")
fieldHis =
if isStruct
then map simplify $ init $ scanr (BinOp Add) (Number "-1") fieldSizes
else map simplify $ map (BinOp Add (Number "-1")) fieldSizes
-- create the mapping structure for the unstructured fields -- create the mapping structure for the unstructured fields
unstructOffsets = map simplify $ map snd fieldRanges unstructOffsets = map simplify $ map snd fieldRanges
...@@ -102,7 +117,10 @@ collectStructM (Struct (Packed sg) fields _) = do ...@@ -102,7 +117,10 @@ collectStructM (Struct (Packed sg) fields _) = do
-- create the unstructured type; result type takes on the signing of the -- create the unstructured type; result type takes on the signing of the
-- struct itself to preserve behavior of operations on the whole struct -- struct itself to preserve behavior of operations on the whole struct
structSize = foldl1 (BinOp Add) fieldSizes structSize =
if isStruct
then foldl1 (BinOp Add) fieldSizes
else head fieldSizes
packedRange = (simplify $ BinOp Sub structSize (Number "1"), zero) packedRange = (simplify $ BinOp Sub structSize (Number "1"), zero)
unstructType = IntegerVector TLogic sg [packedRange] unstructType = IntegerVector TLogic sg [packedRange]
...@@ -114,7 +132,6 @@ collectStructM (Struct (Packed sg) fields _) = do ...@@ -114,7 +132,6 @@ collectStructM (Struct (Packed sg) fields _) = do
isIntVec _ = False isIntVec _ = False
canUnstructure = all isIntVec fieldTypes canUnstructure = all isIntVec fieldTypes
collectStructM _ = return ()
-- convert a struct type to its unstructured equivalent -- convert a struct type to its unstructured equivalent
convertType :: Structs -> Type -> Type convertType :: Structs -> Type -> Type
...@@ -252,7 +269,13 @@ convertAsgn structs types (lhs, expr) = ...@@ -252,7 +269,13 @@ convertAsgn structs types (lhs, expr) =
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)
Struct _ _ _ -> case Map.lookup structTf structs of Struct p fields [] -> undot (Struct p fields) fields
Union p fields [] -> undot (Union p fields) fields
Implicit sg _ -> (Implicit sg [], LHSDot l' x)
_ -> error $ "convertLHS encountered dot for bad type: " ++ show (t, l, x)
where
(t, l') = convertLHS l
undot structTf fields = case Map.lookup structTf structs of
Nothing -> (fieldType, LHSDot l' x) Nothing -> (fieldType, LHSDot l' x)
Just (structT, m) -> (tf [tr], LHSRange l' NonIndexed r) Just (structT, m) -> (tf [tr], LHSRange l' NonIndexed r)
where where
...@@ -261,12 +284,7 @@ convertAsgn structs types (lhs, expr) = ...@@ -261,12 +284,7 @@ convertAsgn structs types (lhs, expr) =
hi' = BinOp Add base $ BinOp Sub hi lo hi' = BinOp Add base $ BinOp Sub hi lo
lo' = base lo' = base
tr = (simplify hi', simplify lo') tr = (simplify hi', simplify lo')
Implicit sg _ -> (Implicit sg [], LHSDot l' x)
_ -> error $ "convertLHS encountered dot for bad type: " ++ show (t, l, x)
where where
(t, l') = convertLHS l
Struct p fields [] = t
structTf = Struct p fields
fieldType = lookupFieldType fields x fieldType = lookupFieldType fields x
convertLHS (LHSConcat lhss) = convertLHS (LHSConcat lhss) =
(Implicit Unspecified [], LHSConcat $ map (snd . convertLHS) lhss) (Implicit Unspecified [], LHSConcat $ map (snd . convertLHS) lhss)
...@@ -330,15 +348,16 @@ convertAsgn structs types (lhs, expr) = ...@@ -330,15 +348,16 @@ convertAsgn structs types (lhs, expr) =
Just t -> (t, Ident x) Just t -> (t, Ident x)
convertSubExpr (Dot e x) = convertSubExpr (Dot e x) =
case subExprType of case subExprType of
Struct _ _ _ -> Struct p fields [] -> undot (Struct p fields) fields
Union p fields [] -> undot (Union p fields) fields
_ -> (Implicit Unspecified [], Dot e' x)
where
(subExprType, e') = convertSubExpr e
undot structTf fields =
if Map.notMember structTf structs if Map.notMember structTf structs
then (fieldType, Dot e' x) then (fieldType, Dot e' x)
else (fieldType, Range e' NonIndexed r) else (fieldType, Range e' NonIndexed r)
_ -> (Implicit Unspecified [], Dot e' x)
where where
(subExprType, e') = convertSubExpr e
Struct p fields [] = subExprType
structTf = Struct p fields
fieldType = lookupFieldType fields x fieldType = lookupFieldType fields x
r = lookupUnstructRange structTf x r = lookupUnstructRange structTf x
convertSubExpr (Range eOuter NonIndexed (rOuter @ (hiO, loO))) = convertSubExpr (Range eOuter NonIndexed (rOuter @ (hiO, loO))) =
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
module Language.SystemVerilog.AST.Type module Language.SystemVerilog.AST.Type
( Identifier ( Identifier
, Field
, Type (..) , Type (..)
, Signing (..) , Signing (..)
, Packing (..) , Packing (..)
......
typedef union packed {
logic [4:0] x;
logic [4:0] y;
} A;
typedef union packed {
logic [4:0] x;
logic [0:4] y;
} B;
typedef union packed {
logic [4:0] x;
logic [1:5] y;
} C;
typedef union packed {
logic [4:0] x;
struct packed {
logic [2:0] a;
logic [1:0] b;
} y;
struct packed {
logic [1:0] a;
logic [0:2] b;
} z;
} D;
module wrap;
A a;
B b;
C c;
D d;
initial begin
$monitor($time, " %b %b", a.x, a.y);
a.x = 5'b01101; #10;
a.y = 5'b11101; #10;
$monitor($time, " %b %b", b.x, b.y);
b.x = 5'b01101; #10;
b.y = 5'b11101; #10;
$monitor($time, " %b %b", c.x, c.y);
c.x = 5'b01101; #10;
c.y = 5'b11101; #10;
$monitor($time, " %b %b {%b %b} %b {%b %b}", d.x, d.y, d.y.a, d.y.b,
d.z, d.z.a, d.z.b);
d.x = 5'b01101; #10;
d.y = '{ a: 3'b110, b: 2'b01 }; #10;
d.z = '{ b: 3'b110, a: 2'b01 }; #10;
d.y.a = 3'b010; #10;
d.y.b = 2'b10; #10;
d.z.a = 2'b11; #10;
d.z.b = 3'b101; #10;
end
endmodule
module wrap;
initial begin
// This was generated by running the original through VCS.
$display(" 0 01101 01101");
$display(" 10 11101 11101");
$display(" 20 01101 01101");
$display(" 30 11101 11101");
$display(" 40 01101 01101");
$display(" 50 11101 11101");
$display(" 60 01101 01101 {011 01} 01101 {01 101}");
$display(" 70 11001 11001 {110 01} 11001 {11 001}");
$display(" 80 01110 01110 {011 10} 01110 {01 110}");
$display(" 90 01010 01010 {010 10} 01010 {01 010}");
$display(" 110 11010 11010 {110 10} 11010 {11 010}");
$display(" 120 11101 11101 {111 01} 11101 {11 101}");
#130;
end
endmodule
module top;
wrap wrap();
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