Commit b0eedfe3 by Zachary Snow

$bits conversion handles basic expressions

parent 73f83112
......@@ -6,25 +6,77 @@
module Convert.Bits (convert) where
import Control.Monad.State
import qualified Data.Map.Strict as Map
import Convert.Traverse
import Language.SystemVerilog.AST
type Info = Map.Map Identifier (Type, [Range])
convert :: AST -> AST
convert =
traverseDescriptions $
traverseModuleItems $
traverseExprs $
traverseNestedExprs $
convertExpr
convertExpr :: Expr -> Expr
convertExpr (Bits (Left (IntegerVector _ _ rs))) = size rs
convertExpr (Bits (Left (Implicit _ rs))) = size rs
convertExpr other = other
size :: [Range] -> Expr
size ranges =
simplify $
foldl (BinOp Mul) (Number "1") $
map rangeSize $
ranges
convert = traverseDescriptions convertDescription
convertDescription :: Description -> Description
convertDescription =
scopedConversion traverseDeclM traverseModuleItemM traverseStmtM Map.empty
-- collects and converts multi-dimensional packed-array declarations
traverseDeclM :: Decl -> State Info Decl
traverseDeclM (origDecl @ (Variable _ t ident a _)) = do
modify $ Map.insert ident (t, a)
return origDecl
traverseDeclM other = return other
traverseModuleItemM :: ModuleItem -> State Info ModuleItem
traverseModuleItemM item = traverseExprsM traverseExprM item
traverseStmtM :: Stmt -> State Info Stmt
traverseStmtM stmt = traverseStmtExprsM traverseExprM stmt
traverseExprM :: Expr -> State Info Expr
traverseExprM = traverseNestedExprsM $ stately convertExpr
convertExpr :: Info -> Expr -> Expr
convertExpr _ (Bits (Left t)) =
case t of
IntegerVector _ _ rs -> dimensionsSize rs
Implicit _ rs -> dimensionsSize rs
Net _ rs -> dimensionsSize rs
_ -> Bits $ Left t
convertExpr info (Bits (Right e)) =
case e of
Ident x ->
case Map.lookup x info of
Nothing -> Bits $ Right e
Just (t, rs) -> simplify $ BinOp Mul
(dimensionsSize rs)
(convertExpr info $ Bits $ Left t)
Concat exprs ->
foldl (BinOp Add) (Number "0") $
map (convertExpr info) $
map (Bits . Right) $
exprs
Range expr mode range ->
simplify $ BinOp Mul size
(convertExpr info $ Bits $ Right $ Bit expr (Number "0"))
where
size = case mode of
NonIndexed -> rangeSize range
IndexedPlus -> snd range
IndexedMinus -> snd range
Bit (Ident x) idx ->
case Map.lookup x info of
Nothing -> Bits $ Right $ Bit (Ident x) idx
Just (t, rs) ->
convertExpr info $ Bits $ Left t'
where t' = popRange t rs
_ -> Bits $ Right e
convertExpr _ other = other
popRange :: Type -> [Range] -> Type
popRange t rs =
tf $ tail rsCombined
where
(tf, trs) = typeRanges t
rsCombined = rs ++ trs
......@@ -35,19 +35,9 @@ convert :: AST -> AST
convert = traverseDescriptions convertDescription
convertDescription :: Description -> Description
convertDescription (description @ (Part _ _ _ _ _ _)) =
evalState
(initialTraverse description >>= scopedTraverse)
convertDescription =
scopedConversion traverseDeclM traverseModuleItemM traverseStmtM
(Info Map.empty)
where
initialTraverse = traverseModuleItemsM traverseMIDecl
scopedTraverse = traverseModuleItemsM $
traverseScopesM traverseDeclM traverseModuleItemM traverseStmtM
traverseMIDecl :: ModuleItem -> State Info ModuleItem
traverseMIDecl (MIDecl decl) =
traverseDeclM decl >>= return . MIDecl
traverseMIDecl other = return other
convertDescription description = description
-- collects and converts multi-dimensional packed-array declarations
traverseDeclM :: Decl -> State Info Decl
......
......@@ -217,11 +217,8 @@ convertAsgn structs types (lhs, expr) =
Pattern [(Just "default", e)]
else if null rs then
expanded
else if length rs == 1 then
Repeat (rangeSize $ head rs) [expanded]
else
error $ "default pattern for multi-dimensional struct array "
++ show structTf ++ " is not allowed"
Repeat (dimensionsSize rs) [expanded]
where
structTf = Struct (Packed sg) fields
expanded = convertExpr (structTf []) $ Pattern $
......
......@@ -71,6 +71,7 @@ module Convert.Traverse
, traverseNestedLHSs
, collectNestedLHSsM
, traverseScopesM
, scopedConversion
, stately
) where
......@@ -929,6 +930,26 @@ traverseScopesM declMapper moduleItemMapper stmtMapper =
else error $ "illegal scope state modification: "
++ show (prevState, item, currState, item')
-- applies the given decl conversion across the description, and then performs a
-- scoped traversal for each ModuleItem in the description
scopedConversion
:: (Eq s, Show s)
=> MapperM (State s) Decl
-> MapperM (State s) ModuleItem
-> MapperM (State s) Stmt
-> s
-> Description
-> Description
scopedConversion traverseDeclM traverseModuleItemM traverseStmtM s description =
evalState (initialTraverse description >>= scopedTraverse) s
where
initialTraverse = traverseModuleItemsM traverseMIDecl
scopedTraverse = traverseModuleItemsM $
traverseScopesM traverseDeclM traverseModuleItemM traverseStmtM
traverseMIDecl (MIDecl decl) =
traverseDeclM decl >>= return . MIDecl
traverseMIDecl other = return other
-- convert a basic mapper with an initial argument to a stateful mapper
stately :: (Eq s, Show s) => (s -> Mapper a) -> MapperM (State s) a
stately mapper thing = do
......
......@@ -17,6 +17,7 @@ module Language.SystemVerilog.AST.Expr
, endianCondExpr
, endianCondRange
, sizedExpr
, dimensionsSize
) where
import Data.List (intercalate)
......@@ -209,3 +210,10 @@ sizedExpr x r (Number n) =
else size ++ n
Just num -> size ++ "'d" ++ show num
sizedExpr _ _ e = e
dimensionsSize :: [Range] -> Expr
dimensionsSize ranges =
simplify $
foldl (BinOp Mul) (Number "1") $
map rangeSize $
ranges
......@@ -52,17 +52,17 @@ module top;
initial begin
foolA = 2'b10;
foolAer(4'b1001);
$display("initalA: $bits(foolA): ", $bits(foolA ));
$display("initalA: $bits(foolA[0]): ", $bits(foolA[0]));
$display("initalA: $bits(foolA): %08d", $bits(foolA ));
$display("initalA: $bits(foolA[0]): %08d", $bits(foolA[0]));
$display("initalA: foolA[0]: ", foolA[0]);
$display("initalA: foolA[1]: ", foolA[1]);
end
task foolAer;
input [1:0][1:0] foolA;
begin
$display("foolAer: $bits(foolA): ", $bits(foolA ));
$display("foolAer: $bits(foolA[0]): ", $bits(foolA[0] ));
$display("foolAer: $bits(foolA[0][0]): ", $bits(foolA[0][0]));
$display("foolAer: $bits(foolA): %08d", $bits(foolA ));
$display("foolAer: $bits(foolA[0]): %08d", $bits(foolA[0] ));
$display("foolAer: $bits(foolA[0][0]): %08d", $bits(foolA[0][0]));
$display("foolAer: foolA[0][0]: ", foolA[0][0]);
$display("foolAer: foolA[0][1]: ", foolA[0][1]);
$display("foolAer: foolA[1][0]: ", foolA[1][0]);
......@@ -74,9 +74,9 @@ module top;
task foolBer;
input [1:0][1:0] foolB;
begin
$display("foolBer: $bits(foolB): ", $bits(foolB ));
$display("foolBer: $bits(foolB[0]): ", $bits(foolB[0] ));
$display("foolBer: $bits(foolB[0][0]): ", $bits(foolB[0][0]));
$display("foolBer: $bits(foolB): %08d", $bits(foolB ));
$display("foolBer: $bits(foolB[0]): %08d", $bits(foolB[0] ));
$display("foolBer: $bits(foolB[0][0]): %08d", $bits(foolB[0][0]));
$display("foolBer: foolB[0][0]: ", foolB[0][0]);
$display("foolBer: foolB[0][1]: ", foolB[0][1]);
$display("foolBer: foolB[1][0]: ", foolB[1][0]);
......@@ -87,8 +87,8 @@ module top;
initial begin
foolB = 2'b10;
foolBer(4'b1001);
$display("initalB: $bits(foolB): ", $bits(foolB ));
$display("initalB: $bits(foolB[0]): ", $bits(foolB[0]));
$display("initalB: $bits(foolB): %08d", $bits(foolB ));
$display("initalB: $bits(foolB[0]): %08d", $bits(foolB[0]));
$display("initalB: foolB[0]: ", foolB[0]);
$display("initalB: foolB[1]: ", foolB[1]);
end
......@@ -98,9 +98,9 @@ module top;
begin : lol_block
logic [1:0][1:0] arr;
arr = 4'b1001;
$display("LOL: $bits(arr): ", $bits(arr ));
$display("LOL: $bits(arr[0]): ", $bits(arr[0] ));
$display("LOL: $bits(arr[0][0]): ", $bits(arr[0][0]));
$display("LOL: $bits(arr): %08d", $bits(arr ));
$display("LOL: $bits(arr[0]): %08d", $bits(arr[0] ));
$display("LOL: $bits(arr[0][0]): %08d", $bits(arr[0][0]));
$display("LOL: arr[0]: ", arr[0]);
$display("LOL: arr[1]: ", arr[1]);
$display("LOL: arr[0][1]: ", arr[0][1]);
......@@ -115,9 +115,9 @@ module top;
begin : magic_block1
logic [1:0][1:0] magic_arr;
magic_arr = 4'b1001;
$display("MB1: $bits(magic_arr): ", $bits(magic_arr ));
$display("MB1: $bits(magic_arr[0]): ", $bits(magic_arr[0] ));
$display("MB1: $bits(magic_arr[0][0]): ", $bits(magic_arr[0][0]));
$display("MB1: $bits(magic_arr): %08d", $bits(magic_arr ));
$display("MB1: $bits(magic_arr[0]): %08d", $bits(magic_arr[0] ));
$display("MB1: $bits(magic_arr[0][0]): %08d", $bits(magic_arr[0][0]));
$display("MB1: magic_arr[0]: ", magic_arr[0]);
$display("MB1: magic_arr[1]: ", magic_arr[1]);
$display("MB1: magic_arr[0][1]: ", magic_arr[0][1]);
......@@ -127,8 +127,8 @@ module top;
begin : magic_block2
logic [3:0] magic_arr;
magic_arr = 4'b1001;
$display("MB2: $bits(magic_arr): ", $bits(magic_arr ));
$display("MB2: $bits(magic_arr[0]): ", $bits(magic_arr[0] ));
$display("MB2: $bits(magic_arr): %08d", $bits(magic_arr ));
$display("MB2: $bits(magic_arr[0]): %08d", $bits(magic_arr[0] ));
$display("MB2: magic_arr[0]: ", magic_arr[0]);
$display("MB2: magic_arr[1]: ", magic_arr[1]);
$display("MB2: magic_arr[2]: ", magic_arr[2]);
......@@ -137,10 +137,10 @@ module top;
begin : magic_block3
logic [1:0][1:0][1:0] magic_arr;
magic_arr = 4'b1001;
$display("MB3: $bits(magic_arr): ", $bits(magic_arr ));
$display("MB3: $bits(magic_arr[0]): ", $bits(magic_arr[0] ));
$display("MB3: $bits(magic_arr[0][0]): ", $bits(magic_arr[0][0] ));
$display("MB3: $bits(magic_arr[0][0][0]): ", $bits(magic_arr[0][0][0]));
$display("MB3: $bits(magic_arr): %08d", $bits(magic_arr ));
$display("MB3: $bits(magic_arr[0]): %08d", $bits(magic_arr[0] ));
$display("MB3: $bits(magic_arr[0][0]): %08d", $bits(magic_arr[0][0] ));
$display("MB3: $bits(magic_arr[0][0][0]): %08d", $bits(magic_arr[0][0][0]));
$display("MB3: magic_arr[0]: ", magic_arr[0]);
$display("MB3: magic_arr[1]: ", magic_arr[1]);
$display("MB3: magic_arr[0][0]: ", magic_arr[0][0]);
......@@ -158,9 +158,9 @@ module top;
begin : magic_block4
logic [1:0][1:0] magic_arr;
magic_arr = 4'b1001;
$display("MB4: $bits(magic_arr): ", $bits(magic_arr ));
$display("MB4: $bits(magic_arr[0]): ", $bits(magic_arr[0] ));
$display("MB4: $bits(magic_arr[0][0]): ", $bits(magic_arr[0][0]));
$display("MB4: $bits(magic_arr): %08d", $bits(magic_arr ));
$display("MB4: $bits(magic_arr[0]): %08d", $bits(magic_arr[0] ));
$display("MB4: $bits(magic_arr[0][0]): %08d", $bits(magic_arr[0][0]));
$display("MB4: magic_arr[0]: ", magic_arr[0]);
$display("MB4: magic_arr[1]: ", magic_arr[1]);
$display("MB4: magic_arr[0][1]: ", magic_arr[0][1]);
......@@ -168,10 +168,10 @@ module top;
$display("MB4: magic_arr[1][1]: ", magic_arr[1][1]);
end
magic_arr = 4'b1001;
$display("MB3: $bits(magic_arr): ", $bits(magic_arr ));
$display("MB3: $bits(magic_arr[0]): ", $bits(magic_arr[0] ));
$display("MB3: $bits(magic_arr[0][0]): ", $bits(magic_arr[0][0] ));
$display("MB3: $bits(magic_arr[0][0][0]): ", $bits(magic_arr[0][0][0]));
$display("MB3: $bits(magic_arr): %08d", $bits(magic_arr ));
$display("MB3: $bits(magic_arr[0]): %08d", $bits(magic_arr[0] ));
$display("MB3: $bits(magic_arr[0][0]): %08d", $bits(magic_arr[0][0] ));
$display("MB3: $bits(magic_arr[0][0][0]): %08d", $bits(magic_arr[0][0][0]));
$display("MB3: magic_arr[0]: ", magic_arr[0]);
$display("MB3: magic_arr[1]: ", magic_arr[1]);
$display("MB3: magic_arr[0][0]: ", magic_arr[0][0]);
......@@ -196,9 +196,9 @@ module top;
begin : ntf_magic_block1
logic [1:0][1:0] ntf_magic_arr;
ntf_magic_arr = 4'b1001;
$display("NTFMB1: $bits(ntf_magic_arr): ", $bits(ntf_magic_arr ));
$display("NTFMB1: $bits(ntf_magic_arr[0]): ", $bits(ntf_magic_arr[0] ));
$display("NTFMB1: $bits(ntf_magic_arr[0][0]): ", $bits(ntf_magic_arr[0][0]));
$display("NTFMB1: $bits(ntf_magic_arr): %08d", $bits(ntf_magic_arr ));
$display("NTFMB1: $bits(ntf_magic_arr[0]): %08d", $bits(ntf_magic_arr[0] ));
$display("NTFMB1: $bits(ntf_magic_arr[0][0]): %08d", $bits(ntf_magic_arr[0][0]));
$display("NTFMB1: ntf_magic_arr[0]: ", ntf_magic_arr[0]);
$display("NTFMB1: ntf_magic_arr[1]: ", ntf_magic_arr[1]);
$display("NTFMB1: ntf_magic_arr[0][1]: ", ntf_magic_arr[0][1]);
......@@ -208,8 +208,8 @@ module top;
begin : ntf_magic_block2
logic [3:0] ntf_magic_arr;
ntf_magic_arr = 4'b1001;
$display("NTFMB2: $bits(ntf_magic_arr): ", $bits(ntf_magic_arr ));
$display("NTFMB2: $bits(ntf_magic_arr[0]): ", $bits(ntf_magic_arr[0] ));
$display("NTFMB2: $bits(ntf_magic_arr): %08d", $bits(ntf_magic_arr ));
$display("NTFMB2: $bits(ntf_magic_arr[0]): %08d", $bits(ntf_magic_arr[0] ));
$display("NTFMB2: ntf_magic_arr[0]: ", ntf_magic_arr[0]);
$display("NTFMB2: ntf_magic_arr[1]: ", ntf_magic_arr[1]);
$display("NTFMB2: ntf_magic_arr[2]: ", ntf_magic_arr[2]);
......@@ -218,10 +218,10 @@ module top;
begin : ntf_magic_block3
logic [1:0][1:0][1:0] ntf_magic_arr;
ntf_magic_arr = 4'b1001;
$display("NTFMB3: $bits(ntf_magic_arr): ", $bits(ntf_magic_arr ));
$display("NTFMB3: $bits(ntf_magic_arr[0]): ", $bits(ntf_magic_arr[0] ));
$display("NTFMB3: $bits(ntf_magic_arr[0][0]): ", $bits(ntf_magic_arr[0][0] ));
$display("NTFMB3: $bits(ntf_magic_arr[0][0][0]): ", $bits(ntf_magic_arr[0][0][0]));
$display("NTFMB3: $bits(ntf_magic_arr): %08d", $bits(ntf_magic_arr ));
$display("NTFMB3: $bits(ntf_magic_arr[0]): %08d", $bits(ntf_magic_arr[0] ));
$display("NTFMB3: $bits(ntf_magic_arr[0][0]): %08d", $bits(ntf_magic_arr[0][0] ));
$display("NTFMB3: $bits(ntf_magic_arr[0][0][0]): %08d", $bits(ntf_magic_arr[0][0][0]));
$display("NTFMB3: ntf_magic_arr[0]: ", ntf_magic_arr[0]);
$display("NTFMB3: ntf_magic_arr[1]: ", ntf_magic_arr[1]);
$display("NTFMB3: ntf_magic_arr[0][0]: ", ntf_magic_arr[0][0]);
......@@ -239,9 +239,9 @@ module top;
begin : ntf_magic_block4
logic [1:0][1:0] ntf_magic_arr;
ntf_magic_arr = 4'b1001;
$display("NTFMB4: $bits(ntf_magic_arr): ", $bits(ntf_magic_arr ));
$display("NTFMB4: $bits(ntf_magic_arr[0]): ", $bits(ntf_magic_arr[0] ));
$display("NTFMB4: $bits(ntf_magic_arr[0][0]): ", $bits(ntf_magic_arr[0][0]));
$display("NTFMB4: $bits(ntf_magic_arr): %08d", $bits(ntf_magic_arr ));
$display("NTFMB4: $bits(ntf_magic_arr[0]): %08d", $bits(ntf_magic_arr[0] ));
$display("NTFMB4: $bits(ntf_magic_arr[0][0]): %08d", $bits(ntf_magic_arr[0][0]));
$display("NTFMB4: ntf_magic_arr[0]: ", ntf_magic_arr[0]);
$display("NTFMB4: ntf_magic_arr[1]: ", ntf_magic_arr[1]);
$display("NTFMB4: ntf_magic_arr[0][1]: ", ntf_magic_arr[0][1]);
......@@ -249,10 +249,10 @@ module top;
$display("NTFMB4: ntf_magic_arr[1][1]: ", ntf_magic_arr[1][1]);
end
ntf_magic_arr = 4'b1001;
$display("NTFMB3: $bits(ntf_magic_arr): ", $bits(ntf_magic_arr ));
$display("NTFMB3: $bits(ntf_magic_arr[0]): ", $bits(ntf_magic_arr[0] ));
$display("NTFMB3: $bits(ntf_magic_arr[0][0]): ", $bits(ntf_magic_arr[0][0] ));
$display("NTFMB3: $bits(ntf_magic_arr[0][0][0]): ", $bits(ntf_magic_arr[0][0][0]));
$display("NTFMB3: $bits(ntf_magic_arr): %08d", $bits(ntf_magic_arr ));
$display("NTFMB3: $bits(ntf_magic_arr[0]): %08d", $bits(ntf_magic_arr[0] ));
$display("NTFMB3: $bits(ntf_magic_arr[0][0]): %08d", $bits(ntf_magic_arr[0][0] ));
$display("NTFMB3: $bits(ntf_magic_arr[0][0][0]): %08d", $bits(ntf_magic_arr[0][0][0]));
$display("NTFMB3: ntf_magic_arr[0]: ", ntf_magic_arr[0]);
$display("NTFMB3: ntf_magic_arr[1]: ", ntf_magic_arr[1]);
$display("NTFMB3: ntf_magic_arr[0][0]: ", ntf_magic_arr[0][0]);
......
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