xref: /XiangShan/scripts/coverage/coverage.py (revision f320e0f01bd645f0a3045a8a740e60dd770734a9)
1d70a2272SAllen#/usr/bin/python3
2d70a2272SAllen# -*- coding: UTF-8 -*-
3c6d43980SLemover
4c6d43980SLemover#***************************************************************************************
5c6d43980SLemover# Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
6*f320e0f0SYinan Xu# Copyright (c) 2020-2021 Peng Cheng Laboratory
7c6d43980SLemover#
8c6d43980SLemover# XiangShan is licensed under Mulan PSL v2.
9c6d43980SLemover# You can use this software according to the terms and conditions of the Mulan PSL v2.
10c6d43980SLemover# You may obtain a copy of Mulan PSL v2 at:
11c6d43980SLemover#          http://license.coscl.org.cn/MulanPSL2
12c6d43980SLemover#
13c6d43980SLemover# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
14c6d43980SLemover# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
15c6d43980SLemover# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
16c6d43980SLemover#
17c6d43980SLemover# See the Mulan PSL v2 for more details.
18c6d43980SLemover#***************************************************************************************
19c6d43980SLemover
20d70a2272SAllenimport sys
21d70a2272SAllenimport re
22d70a2272SAllenimport copy
23d70a2272SAllen
24d70a2272SAllenif __name__ == "__main__":
25d70a2272SAllen    assert len(sys.argv) == 3, "Expect input_file and output_file"
26d70a2272SAllen    input_file = sys.argv[1]
27d70a2272SAllen    output_file = sys.argv[2]
28d70a2272SAllen    lines = []
29d70a2272SAllen    line_count = 0
30d70a2272SAllen    synthesis_nest_level = 0
31c8b1e4dbSAllen    reg_init_nest_level = 0
32c8b1e4dbSAllen    mem_init_nest_level = 0
33d70a2272SAllen    with open(input_file) as f:
34d70a2272SAllen        for line in f:
35d70a2272SAllen            line_count += 1
36d70a2272SAllen
37d70a2272SAllen            ifdef = re.compile('`ifdef')
38d70a2272SAllen            ifndef = re.compile('`ifndef')
39d70a2272SAllen            endif = re.compile('`endif')
40c8b1e4dbSAllen            # remove the line coverage results of not synthesizable code(mostly assert and fwrite)
41d70a2272SAllen            synthesis = re.compile('`ifndef SYNTHESIS')
42c8b1e4dbSAllen            # remove the coverage results of random init variables
43c8b1e4dbSAllen            reg_init = re.compile('`ifdef RANDOMIZE_REG_INIT')
44c8b1e4dbSAllen            mem_init = re.compile('`ifdef RANDOMIZE_MEM_INIT')
45c8b1e4dbSAllen            coverage = re.compile('^\s*(%?\d+)\s+')
46c8b1e4dbSAllen
47d70a2272SAllen
48d70a2272SAllen            ifdef_match = ifdef.search(line)
49d70a2272SAllen            ifndef_match = ifndef.search(line)
50d70a2272SAllen            endif_match = endif.search(line)
51d70a2272SAllen            synthesis_match = synthesis.search(line)
52c8b1e4dbSAllen            reg_init_match = reg_init.search(line)
53c8b1e4dbSAllen            mem_init_match = mem_init.search(line)
54c8b1e4dbSAllen            coverage_match = coverage.search(line)
55d70a2272SAllen
56d70a2272SAllen            # enter synthesis block
57d70a2272SAllen            if synthesis_match:
58d70a2272SAllen                assert synthesis_nest_level == 0, "Should not nest SYNTHESIS macro"
59d70a2272SAllen                synthesis_nest_level = 1
60d70a2272SAllen
61c8b1e4dbSAllen            if synthesis_nest_level > 0:
62d70a2272SAllen                if ifdef_match or (ifndef_match and not synthesis_match):
63d70a2272SAllen                    synthesis_nest_level += 1
64d70a2272SAllen                if endif_match:
65d70a2272SAllen                    synthesis_nest_level -= 1
66d70a2272SAllen                    assert synthesis_nest_level >= 0, "Macro nest level should be >= 0"
67d70a2272SAllen
68d70a2272SAllen                # remove line coverage results in systhesis block
69c8b1e4dbSAllen                if coverage_match:
70c8b1e4dbSAllen                    coverage_stat = coverage_match.group(1)
71c8b1e4dbSAllen                    line = line.replace(coverage_match.group(1), " " * len(coverage_stat))
72c8b1e4dbSAllen
73c8b1e4dbSAllen            # enter reg_init block
74c8b1e4dbSAllen            if reg_init_match:
75c8b1e4dbSAllen                assert reg_init_nest_level == 0, "Should not nest reg_init macro"
76c8b1e4dbSAllen                reg_init_nest_level = 1
77c8b1e4dbSAllen
78c8b1e4dbSAllen            if reg_init_nest_level > 0:
79c8b1e4dbSAllen                if (ifdef_match and not reg_init_match) or ifndef_match:
80c8b1e4dbSAllen                    reg_init_nest_level += 1
81c8b1e4dbSAllen                if endif_match:
82c8b1e4dbSAllen                    reg_init_nest_level -= 1
83c8b1e4dbSAllen                    assert reg_init_nest_level >= 0, "Macro nest level should be >= 0"
84c8b1e4dbSAllen
85c8b1e4dbSAllen                # remove line coverage results in systhesis block
86c8b1e4dbSAllen                if coverage_match:
87c8b1e4dbSAllen                    coverage_stat = coverage_match.group(1)
88c8b1e4dbSAllen                    line = line.replace(coverage_match.group(1), " " * len(coverage_stat))
89c8b1e4dbSAllen
90c8b1e4dbSAllen            # enter mem_init block
91c8b1e4dbSAllen            if mem_init_match:
92c8b1e4dbSAllen                assert mem_init_nest_level == 0, "Should not nest mem_init macro"
93c8b1e4dbSAllen                mem_init_nest_level = 1
94c8b1e4dbSAllen
95c8b1e4dbSAllen            if mem_init_nest_level > 0:
96c8b1e4dbSAllen                if (ifdef_match and not mem_init_match) or ifndef_match:
97c8b1e4dbSAllen                    mem_init_nest_level += 1
98c8b1e4dbSAllen                if endif_match:
99c8b1e4dbSAllen                    mem_init_nest_level -= 1
100c8b1e4dbSAllen                    assert mem_init_nest_level >= 0, "Macro nest level should be >= 0"
101c8b1e4dbSAllen
102c8b1e4dbSAllen                # remove line coverage results in systhesis block
103c8b1e4dbSAllen                if coverage_match:
104c8b1e4dbSAllen                    coverage_stat = coverage_match.group(1)
105c8b1e4dbSAllen                    line = line.replace(coverage_match.group(1), " " * len(coverage_stat))
106d70a2272SAllen
107d70a2272SAllen            lines += line
108d70a2272SAllen
109d70a2272SAllen    with open(output_file, "w") as f:
110d70a2272SAllen        for line in lines:
111d70a2272SAllen            f.write(line)
112