-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathinstruction_writer.py
101 lines (75 loc) · 3.46 KB
/
instruction_writer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# SPDX-License-Identifier: Apache-2.0
#
# This file is part of the M2-ISA-R project: https://github.com/tum-ei-eda/M2-ISA-R
#
# Copyright (C) 2022
# Chair of Electrical Design Automation
# Technical University of Munich
"""Actual text output functions for functions and instructions."""
import logging
import pathlib
from contextlib import ExitStack
from mako.template import Template
from ...metamodel import arch
from . import BlockEndType
from .instruction_generator import generate_functions, generate_instructions
from .templates import template_dir
logger = logging.getLogger("instruction_writer")
def write_functions(core: arch.CoreDef, start_time: str, output_path: pathlib.Path, static_scalars: bool, generate_coverage: bool):
"""Generate and write the {CoreName}Funcs.h file for ETISS."""
fn_set_header_template = Template(filename=str(template_dir/'etiss_function_set_header.mako'))
fn_set_footer_template = Template(filename=str(template_dir/'etiss_function_set_footer.mako'))
fn_impl_template = Template(filename=str(template_dir/"etiss_functions_c.mako"))
core_name = core.name
logger.info("writing functions")
with open(output_path / f'{core_name}Funcs.h', 'w', encoding="utf-8") as funcs_f:
# generate and write file header
fn_set_str = fn_set_header_template.render(
start_time=start_time,
core_name=core_name
)
funcs_f.write(fn_set_str)
# generate and write function declarations
for fn_name, templ_str in generate_functions(core, static_scalars, True, generate_coverage):
logger.debug("writing function decl %s", fn_name)
funcs_f.write(templ_str)
fn_set_str = fn_set_footer_template.render()
funcs_f.write(fn_set_str)
with open(output_path / f'{core_name}Funcs.c', 'w', encoding="utf-8") as funcs_f:
fn_impl_str = fn_impl_template.render(
start_time=start_time,
core_name=core_name
)
funcs_f.write(fn_impl_str)
# generate and write function definitions
for fn_name, templ_str in generate_functions(core, static_scalars, False, generate_coverage):
logger.debug("writing function def %s", fn_name)
funcs_f.write(templ_str)
def write_instructions(core: arch.CoreDef, start_time: str, output_path: pathlib.Path, separate: bool, static_scalars: bool,
block_end_on: BlockEndType, generate_coverage: bool):
"""Generate and write the instruction model C++ files for ETISS."""
instr_set_template = Template(filename=str(template_dir/'etiss_instruction_set.mako'))
outfiles = {}
core_name = core.name
logger.info("writing instructions")
with ExitStack() as stack:
# if desired use one C++ file for each instruction set extension
if separate:
outfiles = {
ext_name: stack.enter_context(open(output_path / f'{core_name}_{ext_name}Instr.cpp', 'w', encoding="utf-8"))
for ext_name in core.contributing_types if len(core.instructions_by_ext[ext_name]) > 0
}
# open a default file
outfiles['default'] = stack.enter_context(open(output_path / f'{core_name}Instr.cpp', 'w', encoding="utf-8"))
# generate file headers for each file
for extension_name, out_f in outfiles.items():
instr_set_str = instr_set_template.render(
start_time=start_time,
extension_name=extension_name,
core_name=core_name
)
out_f.write(instr_set_str)
# generate instruction behavior models
for instr_name, _, ext_name, templ_str in generate_instructions(core, static_scalars, block_end_on, generate_coverage):
logger.debug("writing instruction %s", instr_name)
outfiles.get(ext_name, outfiles['default']).write(templ_str)