fix declaration order of nested package items

This commit is contained in:
Zachary Snow 2020-06-04 21:00:17 -04:00
parent b6f4f690e7
commit ecf047e36e
3 changed files with 39 additions and 12 deletions

View File

@ -49,24 +49,33 @@ convertDescription pis (orig @ Part{}) =
Part attrs extern kw lifetime name ports items'
where
Part attrs extern kw lifetime name ports items = orig
existingPIs = execWriter $ collectModuleItemsM collectPIsM orig
runner f = execWriter $ collectModuleItemsM f orig
usedPIs = Set.unions $ map runner $
items' = addItems pis Set.empty items
convertDescription _ other = other
-- iteratively inserts missing package items exactly where they are needed
addItems :: PIs -> Idents -> [ModuleItem] -> [ModuleItem]
addItems pis existingPIs (item : items) =
if not $ Set.disjoint existingPIs thisPI then
-- this item was re-imported earlier in the module
addItems pis existingPIs items
else if null itemsToAdd then
-- this item has no additional dependencies
item : addItems pis (Set.union existingPIs thisPI) items
else
-- this item has at least one un-met dependency
addItems pis existingPIs (head itemsToAdd : item : items)
where
thisPI = execWriter $ collectPIsM item
runner f = execWriter $ collectNestedModuleItemsM f item
usedPIs = Set.unions $ map runner
[ collectStmtsM collectSubroutinesM
, collectTypesM $ collectNestedTypesM collectTypenamesM
, collectExprsM $ collectNestedExprsM collectIdentsM
]
neededPIs = Set.difference usedPIs existingPIs
newItems = map MIPackageItem $ Map.elems $
itemsToAdd = map MIPackageItem $ Map.elems $
Map.restrictKeys pis neededPIs
-- place data declarations at the beginning to obey declaration
-- ordering; everything else can go at the end
newItemsBefore = filter isDecl newItems
newItemsAfter = filter (not . isDecl) newItems
items' = newItemsBefore ++ items ++ newItemsAfter
isDecl (MIPackageItem (Decl{})) = True
isDecl _ = False
convertDescription _ other = other
addItems _ _ [] = []
-- writes down the names of package items
collectPIsM :: ModuleItem -> Writer Idents ()

11
test/basic/nest_order.sv Normal file
View File

@ -0,0 +1,11 @@
localparam Z = 1;
localparam Y = 5'(Z);
localparam X = 5'(Y);
module top;
initial begin
$display("%b", X);
$display("%b", Y);
$display("%b", Z);
end
endmodule

7
test/basic/nest_order.v Normal file
View File

@ -0,0 +1,7 @@
module top;
initial begin
$display("%b", 5'b1);
$display("%b", 5'b1);
$display("%b", 32'b1);
end
endmodule