Skip to content

Commit

Permalink
Merge pull request #200 from zjcurtis/master
Browse files Browse the repository at this point in the history
pre-commit with ruff initial set up
  • Loading branch information
JulianKemmerer authored Jul 2, 2024
2 parents d9a6d92 + a465697 commit bf7e57f
Show file tree
Hide file tree
Showing 23 changed files with 2,732 additions and 1,584 deletions.
10 changes: 4 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,13 @@ But nothing was ever good enough for anyone (including myself) it seems. And now

See the [How does the compiler work?](https://github.com/JulianKemmerer/PipelineC/wiki/How-does-the-compiler-work%3F) page.

# Tests
# Pre-Commit

We use hypothesis (property testing) mutmut (mutation testing) and pytest (general unit tests).
Please add tests when you submit a PR.
To ensure that your PR doesn't break anything, use the command `poetry run pytest`
We use ruff for formatting and linting (currently most lint rules are disabled, we are enabling them incrementally as the codebase is cleaned up). To ensure this is done, we use a pre-commit hook.

# Formatting/Style Guide
You can install Poetry (for dev dependency management) via https://python-poetry.org/docs/#installation. Once you have poetry installed, you can run 'poetry install' to get the dev dependencies installed. From there, you must run 'poetry run pre-commit install' once before making a commit. This will ensure that the pre-commit hook gets run when you make any commit. If the lint fails, follow the guidance given by Ruff (you can look up the name of the error, such as E721, online, if necessary to understand) to fix the lint error.

We use black for formatting. Before you submit a PR do `poetry run black src`
Cheers!

# Future Goals

Expand Down
11 changes: 3 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,9 @@ readme = "README.md"
python = "^3.10"

[tool.poetry.group.dev.dependencies]
black = ">=22.12.0"
pytest = ">=7.2.1"
hypothesis = ">=6.65.2"
py-spy = ">=0.3.14"
ruff = ">=0.0.237"
refurb = ">=1.10.0"
pytest-cov = "^4.0.0"
cosmic-ray = "^8.3.5"
ruff = "^0.5.0"
pre-commit = "^3.7.1"


[build-system]
requires = ["poetry-core"]
Expand Down
818 changes: 596 additions & 222 deletions src/C_TO_FSM.py

Large diffs are not rendered by default.

761 changes: 395 additions & 366 deletions src/C_TO_LOGIC.py

Large diffs are not rendered by default.

127 changes: 72 additions & 55 deletions src/DEVICE_MODELS.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,70 +7,87 @@
# https://github.com/JulianKemmerer/PipelineC/issues/48
# https://github.com/JulianKemmerer/PipelineC/issues/64

#(C) 2022 Victor Surez Rovere <[email protected]>
#NOTE: only for integer operations (not floats)
# (C) 2022 Victor Surez Rovere <[email protected]>
# NOTE: only for integer operations (not floats)

import os, re, math

ops = {}


def part_supported(part_str):
return part_str=="xc7a35ticsg324-1l"
return part_str == "xc7a35ticsg324-1l"


def estimate_int_timing(integer_op, widths_vector):
timing_model= { #category, origin, slope
"arith": (1.92, .04),
"comp": (2.49, .0),
"equal": (1.72, .04),
"logical": (1.28, .0),
"shift": (3.42, .0),
}

categ = ""
if integer_op in ["PLUS", "MINUS", "NEGATE"]: categ = "arith"
if integer_op in ["GT", "GTE", "LT", "LTE"]: categ = "comp"
if integer_op in ["EQ", "NEQ"]: categ = "equal"
if integer_op in ["AND", "OR", "XOR", "NOT"]: categ = "logical"
if integer_op in ["SL", "SR"]: categ = "shift"
if categ not in timing_model:
return None #unknown operation

bits = max(widths_vector)
origin, slope = timing_model[categ]
return origin + bits*slope
timing_model = { # category, origin, slope
"arith": (1.92, 0.04),
"comp": (2.49, 0.0),
"equal": (1.72, 0.04),
"logical": (1.28, 0.0),
"shift": (3.42, 0.0),
}

categ = ""
if integer_op in ["PLUS", "MINUS", "NEGATE"]:
categ = "arith"
if integer_op in ["GT", "GTE", "LT", "LTE"]:
categ = "comp"
if integer_op in ["EQ", "NEQ"]:
categ = "equal"
if integer_op in ["AND", "OR", "XOR", "NOT"]:
categ = "logical"
if integer_op in ["SL", "SR"]:
categ = "shift"
if categ not in timing_model:
return None # unknown operation

bits = max(widths_vector)
origin, slope = timing_model[categ]
return origin + bits * slope


def func_name_to_op_and_widths(func_name):
p = func_name.find("_OP_")
if p >= 0:
optyp = func_name[:p]
_ = func_name.find("_", p+4)
op = func_name[p+4:_]
widths = re.findall(r'int[0-9]+', func_name[4:])
if not len(widths):
return None
widths = [int(w[3:]) for w in widths] #cut 'int'
return op, widths
return None
p = func_name.find("_OP_")
if p >= 0:
optyp = func_name[:p]
_ = func_name.find("_", p + 4)
op = func_name[p + 4 : _]
widths = re.findall(r"int[0-9]+", func_name[4:])
if not len(widths):
return None
widths = [int(w[3:]) for w in widths] # cut 'int'
return op, widths
return None


def process_delays(dir_path):
print("real\top\testimation\twidths")
mindelay = 1e6
total = count = 0
for path in os.listdir(dir_path):
full = os.path.join(dir_path, path)
if os.path.isfile(full):
op_and_widths = func_name_to_op_and_widths(path)
if op_and_widths is not None:
op, widths = op_and_widths
estim_ns = estimate_int_timing(op, widths)
with open(full, 'r') as file:
time_ns = float(file.read())

if estim_ns is not None:
if time_ns < mindelay: mindelay = time_ns
total += (time_ns - estim_ns)**2
count += 1
print(str(time_ns) + "\t" + op + "\t" + str(estim_ns) + "\t".join([str(w) for w in widths]))

rms = math.sqrt(total/count)
print("Count:", count, ", minimum delay (ns):", mindelay, ", RMS error (ns):", rms)
print("real\top\testimation\twidths")
mindelay = 1e6
total = count = 0
for path in os.listdir(dir_path):
full = os.path.join(dir_path, path)
if os.path.isfile(full):
op_and_widths = func_name_to_op_and_widths(path)
if op_and_widths is not None:
op, widths = op_and_widths
estim_ns = estimate_int_timing(op, widths)
with open(full, "r") as file:
time_ns = float(file.read())

if estim_ns is not None:
if time_ns < mindelay:
mindelay = time_ns
total += (time_ns - estim_ns) ** 2
count += 1
print(
str(time_ns)
+ "\t"
+ op
+ "\t"
+ str(estim_ns)
+ "\t".join([str(w) for w in widths])
)

rms = math.sqrt(total / count)
print("Count:", count, ", minimum delay (ns):", mindelay, ", RMS error (ns):", rms)
13 changes: 7 additions & 6 deletions src/DIAMOND.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ def SYN_AND_REPORT_TIMING_NEW(
log_text = f.read()
f.close()
else:

# Write top level vhdl for this module/multimain
if inst_name:
VHDL.WRITE_LOGIC_ENTITY(
Expand Down Expand Up @@ -221,7 +220,7 @@ def init_synplify(self, syn_output):
# WTF is system clock that shows up with zero delay?
# Skip it?
if path_report.path_delay_ns == 0.0:
continue
continue
# Only save the worst delay per path group
do_add = False
if path_report.path_group in self.path_reports:
Expand Down Expand Up @@ -317,7 +316,7 @@ def init_synplify(self, path_report_text):
toks = list(filter(None, line.split(" ")))
tok = toks[6].strip()
self.path_group = tok
#print("path_group",self.path_group)
# print("path_group",self.path_group)
tok1 = "The end point is clocked by"
if tok1 in line:
toks = list(filter(None, line.split(" ")))
Expand Down Expand Up @@ -351,7 +350,7 @@ def init_synplify(self, path_report_text):
prev_line = line

self.path_delay_ns = self.source_ns_per_clock - self.slack_ns
#print("path_delay_ns",self.path_delay_ns)
# print("path_delay_ns",self.path_delay_ns)

def init_lse(self, path_report_text):
# print("path_report_text",path_report_text)
Expand All @@ -366,7 +365,6 @@ def init_lse(self, path_report_text):

prev_line = None
for line in path_report_text.split("\n"):

# DELAY
tok1 = "Delay:"
if tok1 in line:
Expand Down Expand Up @@ -453,5 +451,8 @@ def init_lse(self, path_report_text):
def FUNC_IS_PRIMITIVE(func_name):
return OPEN_TOOLS.FUNC_IS_PRIMITIVE(func_name)


def GET_PRIMITIVE_MODULE_TEXT(inst_name, Logic, parser_state, TimingParamsLookupTable):
return OPEN_TOOLS.GET_PRIMITIVE_MODULE_TEXT(inst_name, Logic, parser_state, TimingParamsLookupTable)
return OPEN_TOOLS.GET_PRIMITIVE_MODULE_TEXT(
inst_name, Logic, parser_state, TimingParamsLookupTable
)
Loading

0 comments on commit bf7e57f

Please sign in to comment.