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