Skip to content

Commit

Permalink
complete DRV metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
abdelrahmanhosny committed Apr 9, 2020
1 parent 5b09de8 commit 3f0c124
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 10 deletions.
109 changes: 108 additions & 1 deletion edaac/metrics/parsers/innovus_drc_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,112 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''

import re
from edaac.log import get_logger


def parse_innovus_drc_report(report_file_path):
return {}
logger = get_logger()
# this could be substituted by a default dictionary
# but keeping it this way to see what metrics this function reports
metrics = {
'drv_total': None,
'drv_short_metal_total': None,
'drv_short_metal_area': None,
'drv_short_cut_total': None,
'drv_short_cut_area': None,
'drv_out_of_die_total': None,
'drv_out_of_die_area': None,
'drv_spacing_total': None,
'drv_spacing_parallel_run_length_total': None,
'drv_spacing_eol_total': None,
'drv_spacing_cut_total': None,
'drv_min_area_total': None
}

try:
with open(report_file_path, 'r') as f:
report = ''.join(f.readlines())
except Exception as e:
logger.error('Can\'t read report file: %s. Skipping ..',
report_file_path)
return

# DRV Total
regex = 'Total Violations +: +[0-9]+'
matches = re.findall(regex, report)
for match in matches:
metrics['drv_total'] = int(match.split(':')[1].strip())

# Short Violations
regex = 'SHORT: \( Metal Short \) +.*\nBounds +: +.*\n'
matches = re.findall(regex, report)
metrics['drv_short_metal_total'] = len(matches)
metrics['drv_short_metal_area'] = 0.0
for match in matches:
violation, bounds = match.strip().split('\n')
m = re.search(
'\((?P<x1>[0-9\. ]*),(?P<y1>[0-9\. ]*)\) +\((?P<x2>[0-9\. ]*),(?P<y2>[0-9\. ]*)\)', bounds)
x1, x2 = float(m.group('x1').strip()), float(m.group('x2').strip())
y1, y2 = float(m.group('y1').strip()), float(m.group('y2').strip())
area = abs(x1 - x2) * abs(y1 - y2)
metrics['drv_short_metal_area'] += area
metrics['drv_short_metal_area'] = float(
format(metrics['drv_short_metal_area'], '.8f'))

regex = 'SHORT: \( Cut Short \) +.*\nBounds +: +.*\n'
matches = re.findall(regex, report)
metrics['drv_short_cut_total'] = len(matches)
metrics['drv_short_cut_area'] = 0.0
for match in matches:
violation, bounds = match.strip().split('\n')
m = re.search(
'\((?P<x1>[0-9\. ]*),(?P<y1>[0-9\. ]*)\) +\((?P<x2>[0-9\. ]*),(?P<y2>[0-9\. ]*)\)', bounds)
x1, x2 = float(m.group('x1').strip()), float(m.group('x2').strip())
y1, y2 = float(m.group('y1').strip()), float(m.group('y2').strip())
area = abs(x1 - x2) * abs(y1 - y2)
metrics['drv_short_cut_area'] += area
metrics['drv_short_cut_area'] = float(
format(metrics['drv_short_cut_area'], '.8f'))

# Out of Die Violations
regex = 'SHORT: \( Out Of Die \) +.*\nBounds +: +.*\n'
matches = re.findall(regex, report)
metrics['drv_out_of_die_total'] = len(matches)
metrics['drv_out_of_die_area'] = 0.0
for match in matches:
violation, bounds = match.strip().split('\n')
m = re.search(
'\((?P<x1>[\-0-9\. ]*),(?P<y1>[\-0-9\. ]*)\) +\((?P<x2>[\-0-9\. ]*),(?P<y2>[\-0-9\. ]*)\)', bounds)
x1, x2 = float(m.group('x1').strip()), float(m.group('x2').strip())
y1, y2 = float(m.group('y1').strip()), float(m.group('y2').strip())
area = abs(x1 - x2) * abs(y1 - y2)
metrics['drv_out_of_die_area'] += area
metrics['drv_out_of_die_area'] = float(
format(metrics['drv_out_of_die_area'], '.8f'))

# Spacing Violations
regex = 'EndOfLine: \( EndOfLine Spacing \) +.*\nBounds +: +.*\n'
matches = re.findall(regex, report)
metrics['drv_spacing_eol_total'] = len(matches)

regex = 'SPACING: \( ParallelRunLength Spacing \) +.*\nBounds +: +.*\n'
matches = re.findall(regex, report)
metrics['drv_spacing_parallel_run_length_total'] = len(matches)

regex = 'CUTSPACING: +.*\nBounds +: +.*\n'
matches = re.findall(regex, report)
metrics['drv_spacing_cut_total'] = len(matches)

metrics['drv_spacing_total'] = metrics['drv_spacing_eol_total'] + \
metrics['drv_spacing_parallel_run_length_total'] + \
metrics['drv_spacing_cut_total']

# Minimum Area Violations
regex = 'MAR: +\( +Minimum Area +\) +.*\nBounds +: +.*\n'
matches = re.findall(regex, report)
metrics['drv_min_area_total'] = len(matches)

logger.info('Successfully extracted metrics from %s', report_file_path)

return metrics
8 changes: 4 additions & 4 deletions edaac/metrics/parsers/innovus_timing_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@
from edaac.log import get_logger
import re

def parse_innovus_timing_report(log_file_name):
def parse_innovus_timing_report(report_file_path):
logger = get_logger()
metrics = {}

try:
with open(log_file_name, 'r') as f:
with open(report_file_path, 'r') as f:
lines = f.readlines()
arrival_time_lines = list(filter(lambda l: '- Arrival Time' in l, lines))
arrival_time = re.findall(r'-?\d+\.?\d*', arrival_time_lines[0])[0]
metrics['arrival_time'] = float(arrival_time)

logger.info('Successfully extracted metrics from %s', log_file_name)
logger.info('Successfully extracted metrics from %s', report_file_path)

except Exception as e:
logger.error('Can\'t read log file: %s. Skipping ..', log_file_name)
logger.error('Can\'t read report file: %s. Skipping ..', report_file_path)

return metrics
Empty file added test/data/.keep
Empty file.
84 changes: 81 additions & 3 deletions test/test_innovus_drc.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,87 @@
from edaac.metrics.parsers import parse_innovus_drc_report


class TestInnovusDRC(unittest.TestCase):
class TestInnovusDRC1(unittest.TestCase):
def test(self):
metrics = {}
result = parse_innovus_drc_report(os.path.join(pathlib.Path(__file__).parent.absolute(), 'test_project', 'route', 'drc.rpt'))
metrics = {
'drv_total': 22,
'drv_short_metal_total': 3,
'drv_short_metal_area': 0.03220000,
'drv_short_cut_total': 0,
'drv_short_cut_area': 0.0,
'drv_out_of_die_total': 0,
'drv_out_of_die_area': 0.0,
'drv_spacing_total': 9,
'drv_spacing_parallel_run_length_total': 5,
'drv_spacing_eol_total': 4,
'drv_spacing_cut_total': 0,
'drv_min_area_total': 10
}
result = parse_innovus_drc_report(os.path.join(pathlib.Path(
__file__).parent.absolute(), 'data', 'drc1.rpt'))
self.assertDictEqual(metrics, result)


class TestInnovusDRC2(unittest.TestCase):
def test(self):
metrics = {
'drv_total': 76,
'drv_short_metal_total': 30,
'drv_short_metal_area': 0.06930000,
'drv_short_cut_total': 0,
'drv_short_cut_area': 0.0,
'drv_out_of_die_total': 0,
'drv_out_of_die_area': 0.0,
'drv_spacing_total': 32,
'drv_spacing_parallel_run_length_total': 19,
'drv_spacing_eol_total': 13,
'drv_spacing_cut_total': 0,
'drv_min_area_total': 14
}
result = parse_innovus_drc_report(os.path.join(pathlib.Path(
__file__).parent.absolute(), 'data', 'drc2.rpt'))
self.assertDictEqual(metrics, result)


class TestInnovusDRC3(unittest.TestCase):
def test(self):
metrics = {
'drv_total': 333,
'drv_short_metal_total': 300,
'drv_short_metal_area': 130.68,
'drv_short_cut_total': 0,
'drv_short_cut_area': 0.0,
'drv_out_of_die_total': 8,
'drv_out_of_die_area': 0.03050500,
'drv_spacing_total': 6,
'drv_spacing_parallel_run_length_total': 5,
'drv_spacing_eol_total': 1,
'drv_spacing_cut_total': 0,
'drv_min_area_total': 19
}
result = parse_innovus_drc_report(os.path.join(pathlib.Path(
__file__).parent.absolute(), 'data', 'drc3.rpt'))
self.assertDictEqual(metrics, result)



class TestInnovusDRC4(unittest.TestCase):
def test(self):
metrics = {
'drv_total': 101,
'drv_short_metal_total': 2,
'drv_short_metal_area': 0.02382500,
'drv_short_cut_total': 1,
'drv_short_cut_area': 0.0012500,
'drv_out_of_die_total': 0,
'drv_out_of_die_area': 0.0,
'drv_spacing_total': 41,
'drv_spacing_parallel_run_length_total': 7,
'drv_spacing_eol_total': 9,
'drv_spacing_cut_total': 25,
'drv_min_area_total': 57
}
result = parse_innovus_drc_report(os.path.join(pathlib.Path(
__file__).parent.absolute(), 'data', 'drc4.rpt'))
self.assertDictEqual(metrics, result)

4 changes: 2 additions & 2 deletions test/test_innovus_timing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

class TestInnovusTiming(unittest.TestCase):
def test(self):
metrics = {'arrival_time': 1625.8}
result = parse_innovus_timing_report(os.path.join(pathlib.Path(__file__).parent.absolute(), 'test_project', 'route', 'timing.rpt'))
metrics = {'arrival_time': 1598.2}
result = parse_innovus_timing_report(os.path.join(pathlib.Path(__file__).parent.absolute(), 'data', 'timing1.rpt'))
self.assertDictEqual(metrics, result)

0 comments on commit 3f0c124

Please sign in to comment.