-
Notifications
You must be signed in to change notification settings - Fork 746
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Martin Velay <mvelay@lowrisc.org>
- Loading branch information
1 parent
e5b2f14
commit d35f4ed
Showing
5 changed files
with
256 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/usr/bin/env python3 | ||
import sys | ||
import csv | ||
import hjson | ||
|
||
# Check if the file to be converted has been defined | ||
if len(sys.argv) > 1: | ||
# Read the CSV file | ||
csv_file = sys.argv[1] | ||
|
||
with open(csv_file, mode='r', newline='', encoding='utf-8') as file: | ||
csv_reader = csv.DictReader(file) | ||
data = [row for row in csv_reader] | ||
|
||
# Convert data into HJSON | ||
hjson_data = hjson.dumps(data, indent=2) | ||
|
||
# Write the HJSON file | ||
with open('vplan_example_converted.hjson', mode='w', encoding='utf-8') as file: | ||
file.write(hjson_data) | ||
|
||
print("Conversion successfully completed") | ||
else: | ||
print("Error: please specify the CSV file path to be converted") | ||
print(" eg.: ./csv2hjson.py dv/files/verif/my_vplan.csv") | ||
exit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#!/usr/bin/env python3 | ||
import sys | ||
import csv | ||
import hjson | ||
|
||
# Check if the file to be converted has been defined | ||
if len(sys.argv) > 1: | ||
# Load data from the HJSON file | ||
hjson_file = sys.argv[1] | ||
with open(hjson_file, 'r', encoding='utf-8') as file: | ||
data = hjson.load(file) | ||
|
||
# Check that the data is a list of objects | ||
if isinstance(data, list) and all(isinstance(item, dict) for item in data): | ||
# Extract column headers from the keys of the first object | ||
headers = data[0].keys() | ||
|
||
# Create the CSV file | ||
csv_file = 'vplan_example_converted.csv' | ||
with open(csv_file, 'w', newline='', encoding='utf-8') as file: | ||
writer = csv.DictWriter(file, fieldnames=headers) | ||
|
||
# Write headers in the CSV | ||
writer.writeheader() | ||
|
||
# Write the data rows in the CSV | ||
writer.writerows(data) | ||
|
||
print("Conversion successfully completed") | ||
else: | ||
print("HJSON data is not in the expected format") | ||
else: | ||
print("Error: please specify the HJSON file path to be converted") | ||
print(" eg.: ./hjson2csv.py dv/files/verif/my_vplan.hjson") | ||
exit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# MEM_XYZ HW IP Technical Specification | ||
|
||
[`mem_xyz`](https://reports.opentitan.org/hw/ip/mem_xyz/dv/latest/report.html): | ||
![](https://dashboards.lowrisc.org/badges/dv/mem_xyz/test.svg) | ||
![](https://dashboards.lowrisc.org/badges/dv/mem_xyz/passing.svg) | ||
![](https://dashboards.lowrisc.org/badges/dv/mem_xyz/functional.svg) | ||
![](https://dashboards.lowrisc.org/badges/dv/mem_xyz/code.svg) | ||
|
||
# Overview | ||
|
||
This document specifies MEM_XYZ hardware IP functionality. This module conforms to | ||
the [OpenTitan guideline for peripheral device functionality.](../../../doc/contributing/hw/comportability/README.md) | ||
See that document for integration overview within the broader OpenTitan top level system. | ||
|
||
|
||
## Features | ||
|
||
- Memory address space is...<!-- req_mem_xyz_162F --> | ||
- It supports read and write commands<!-- req_mem_xyz_0882 --> | ||
- All the address space is read and write accessible<!-- req_mem_xyz_24BE --> | ||
- Address width is an RTL parameter among: | ||
- 8<!-- req_mem_xyz_3A6A --> | ||
- 16<!-- req_mem_xyz_3A4E --> | ||
- 32<!-- req_mem_xyz_3637 --> | ||
- Multiple modes are available: mode_a, mode_b and mode_c<!-- req_mem_xyz_10B7 --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
#!/usr/bin/env python3 | ||
import sys | ||
import os | ||
import hjson | ||
import argparse | ||
import re | ||
|
||
def find_markdown_files(directory): | ||
"""Recursively find all Markdown files in a directory, except in 'dv' directories.""" | ||
markdown_files = [] | ||
|
||
# Walk through directory and subdirectories | ||
for root, dirs, files in os.walk(directory): | ||
# Exclude 'dv' directories | ||
dirs[:] = [d for d in dirs if d != 'dv'] | ||
|
||
# Find all .md files | ||
for file in files: | ||
if file.endswith('.md'): | ||
markdown_files.append(os.path.join(root, file)) | ||
|
||
return markdown_files | ||
|
||
def extract_tags_from_markdown(markdown_file, block_name): | ||
"""Extract tags from the Markdown file using a regex pattern based on block_name.""" | ||
try: | ||
with open(markdown_file, 'r') as md_file: | ||
content = md_file.read() | ||
except FileNotFoundError: | ||
print(f"Error: The Markdown file '{markdown_file}' was not found.") | ||
return set() | ||
|
||
# Regex pattern to find tags in the form of 'req_<block_name>_xxxx' where xxxx is 4 hexadecimal digits | ||
pattern = fr"req_{block_name}_[0-9a-fA-F]{{4}}" | ||
tags = re.findall(pattern, content) | ||
return set(tags) # Return unique tags as a set | ||
|
||
def extract_tags_from_hjson(hjson_file, block_name): | ||
"""Extract tags from the HJSON file using a regex pattern based on block_name.""" | ||
try: | ||
with open(hjson_file, 'r') as hjson_file: | ||
hjson_content = hjson.load(hjson_file) | ||
except FileNotFoundError: | ||
print(f"Error: The HJSON file '{hjson_file}' was not found.") | ||
sys.exit(1) | ||
|
||
# Convert the HJSON file to string and search for tags | ||
content = str(hjson_content) | ||
|
||
# Regex pattern to find tags in the form of 'req_<block_name>_xxxx' where xxxx is 4 hexadecimal digits | ||
pattern = fr"req_{block_name}_[0-9a-fA-F]{{4}}" | ||
tags = re.findall(pattern, content) | ||
return set(tags) # Return unique tags as a set | ||
|
||
def compare_tags(directory, hjson_file, block_name): | ||
"""Compare tags from Markdown files in a directory with those in the HJSON file.""" | ||
|
||
# Find all .md files in the directory (except 'dv') | ||
markdown_files = find_markdown_files(directory) | ||
|
||
if not markdown_files: | ||
print(f"No Markdown files found in directory '{directory}'") | ||
return | ||
|
||
# Display found Markdown files | ||
print("The following Markdown files have been found and will be analyzed:") | ||
for md_file in markdown_files: | ||
print(f" {md_file}") | ||
|
||
print() # Blank line before continuing | ||
|
||
# Collect tags from all Markdown files, and map tags to files | ||
markdown_tags = set() | ||
tags_in_files = {} # To store which tags are in which files | ||
|
||
for md_file in markdown_files: | ||
file_tags = extract_tags_from_markdown(md_file, block_name) | ||
markdown_tags.update(file_tags) | ||
|
||
# Map tags to the file they were found in | ||
for tag in file_tags: | ||
if tag not in tags_in_files: | ||
tags_in_files[tag] = [] | ||
tags_in_files[tag].append(md_file) | ||
|
||
# Extract tags from the HJSON file | ||
hjson_tags = extract_tags_from_hjson(hjson_file, block_name) | ||
|
||
# Count number of tags | ||
num_md_tags = len(markdown_tags) | ||
num_matching_tags = len(markdown_tags.intersection(hjson_tags)) | ||
|
||
# Find tags that are missing in the HJSON file | ||
missing_in_hjson = markdown_tags - hjson_tags | ||
|
||
# Find tags that are in HJSON but not in Markdown | ||
missing_in_markdown = hjson_tags - markdown_tags | ||
|
||
# Print summary | ||
print(f"Total number of tags found in Markdown files: {num_md_tags}") | ||
print(f"Number of tags found in both Markdown and HJSON: {num_matching_tags}") | ||
|
||
if missing_in_hjson: | ||
print("\nTags found in Markdown but missing in HJSON:") | ||
for tag in missing_in_hjson: | ||
print(f" {tag} (found in {', '.join(tags_in_files[tag])})") | ||
else: | ||
print("All tags in the Markdown files are present in the HJSON file.") | ||
|
||
print(f"\n") | ||
print(f"Total number of tags found in HJSON file: {len(hjson_tags)}") | ||
print(f"Number of tags found in HJSON but missing in Markdown: {len(missing_in_markdown)}") | ||
|
||
if missing_in_markdown: | ||
print("Tags found in HJSON but missing in Markdown:") | ||
for tag in missing_in_markdown: | ||
print(f" {tag}") | ||
|
||
def main(): | ||
# Set up argument parser | ||
parser = argparse.ArgumentParser( | ||
description="Compare 'req_<block_name>_xxxx' tags between Markdown specifications and the HJSON verification plan.") | ||
parser.add_argument( | ||
'block_name', | ||
type=str, | ||
help='The block name to look for in the tag format "req_<block_name>_xxxx".' | ||
) | ||
parser.add_argument( | ||
'directory', | ||
type=str, | ||
help='The path to the root directory of the block/IP. ' | ||
'The sub-directories will be automatically explored except the "dv" folder.' | ||
'Eg.: hw/ip/block_name' | ||
) | ||
parser.add_argument( | ||
'hjson_file', | ||
type=str, | ||
help='The path to the HJSON file.' | ||
) | ||
|
||
# Parse arguments | ||
args = parser.parse_args() | ||
|
||
# Call the compare function with the provided directory, HJSON file, and block name | ||
compare_tags(args.directory, args.hjson_file, args.block_name) | ||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
Name,ID,Coverage Result,Description,Depth,Node Kind,Metric Kind,Item,Owner,Priority,Milestone,Weight,Issue,Comment | ||
mem_xyz,,,A synchronous memory with a parameterizable address width and data width.,0,dut,,,,,,,, | ||
testlist,,,Testlist,1,title,,,,,,,, | ||
main_test,req_mem_xyz_1324,,Main test,2,coverage,testcase,tc_my_test,Michel,1,V1,5,#15926, | ||
bad_addr,req_mem_xyz_0E55,,Bad address,2,coverage,testcase,tc_addr_err,Andrew,2,V3,3,#15927, | ||
fcov,,,Feature coverage,1,title,,,,,,,, | ||
addr_space,req_mem_xyz_162F,,All address space,2,coverage,functional,cp_addr,Francesca,1,V1,2,#14562, | ||
rw_cmd,req_mem_xyz_0882,,Read and write commands,2,coverage,functional,cp_cmd,Michel,1,V1,2,#14562, | ||
rw_addr_space,req_mem_xyz_24BE,,Read and write to all address space,2,coverage,functional,cp_addr_x_cp_cmd,Francesca,1,V1,2,#14562, | ||
mem_full,req_mem_xyz_0F0A,,Reach memory full,2,coverage,functional,cp_full,Andrew,2,V2,3,#14562,This cannot be tested if block_abc is not ready | ||
concurrent_rw,req_mem_xyz_2730,,Read and write simultaneously,2,coverage,assertion,assert_rd_wr,Andrew,3,V3,2,#11487, | ||
addr_width_8bits,req_mem_xyz_364E,,Address 8 bits width,2,coverage,formal,fpv_addr_8bits,Andrew,1,V2,1,#2287, | ||
addr_width_16bits,req_mem_xyz_3A6A,,Address 16 bits width,2,coverage,formal,fpv_addr_16bits,Andrew,1,V2,1,#2287, | ||
addr_width_32bits,req_mem_xyz_3A4E,,Address 32 bits width,2,coverage,formal,fpv_addr_32bits,Andrew,3,V2,1,#2287, | ||
data_width_8bits,req_mem_xyz_3637,,Data width 8 bits,2,coverage,formal,fpv_data_8width,Andrew,1,V2,1,#2287, | ||
instanciate_fifo_common_lib,req_mem_xyz_9A4D,,"Uses the FIFO from the common library, test de la virgule, c'est OK ?",2,vplan,,vplan_fifo,,1,V1,10,#2145,Incorporate the sub-module verification plan | ||
...,...,,...,...,...,...,...,...,...,,,..., | ||
mem_depth,req_mem_xyz_12A4,,Memory depth,2,coverage,formal,fpv_mem_depth,Andrew,1,,1,#2287, | ||
code_cov,,,Code coverage,1,title,,,,,V3,40%,, | ||
code_cov_statement,req_mem_xyz_47D7,,Statement,2,coverage,code,s_cov(memory_xyz),,3,,,#7894,Need to run UNR before | ||
code_cov_fsm,req_mem_xyz_2047,,FSM,2,coverage,code,f_cov(memory_xyz),,3,,,#7894, | ||
code_cov_branch,req_mem_xyz_309C,,Branch...,2,coverage,code,b_cov(memory_xyz),,3,,,#7894, |