diff --git a/.gitignore b/.gitignore index a01f1c07d0..2acbd1f2aa 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ tests/linux-testgen/buildroot-image-output tests/linux-testgen/buildroot-config-src/main.config.old tests/linux-testgen/buildroot-config-src/linux.config.old tests/linux-testgen/buildroot-config-src/busybox.config.old +linux/buildroot linux/testvector-generation/boottrace.S linux/testvector-generation/boottrace_disasm.log sim/slack-notifier/slack-webhook-url.txt diff --git a/Makefile b/Makefile index 2c445fc464..877e69e52a 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ imperasdv: iter-elf.bash --search ${WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m coverage: - cd ${WALLY}/sim; ./regresssion-wally -coverage -fp + cd ${WALLY}/sim; ./regression-wally -coverage -fp benchmarks: make coremark diff --git a/README.md b/README.md index f0b1a9f4b9..d75e8fb986 100644 --- a/README.md +++ b/README.md @@ -128,4 +128,12 @@ If you want to implement your own version of the chip, your tool and license com Startups can expect to spend more than $1 million on CAD tools to get a chip to market. Commercial CAD tools are not realistically available to individuals without a university or company connection. +## Adding Cron Job for nightly builds + +If you want to add a cronjob you can do the following: +1) `crontab -e` +2) add this code: +``` +0 3 * * * BASH_ENV=~/.bashrc bash -l -c "PATH_TO_CVW/cvw/bin/wrapper_nightly_runs.sh > PATH_TO_LOG_FOLDER/cron.log" +``` diff --git a/bin/nightly_build.py b/bin/nightly_build.py index 21d0ce0252..8f806d1193 100755 --- a/bin/nightly_build.py +++ b/bin/nightly_build.py @@ -54,6 +54,8 @@ - re - markdown - subprocess + - argparse + - logging Bash: - mutt (email sender) @@ -69,6 +71,31 @@ import re import markdown import subprocess +import argparse +import logging + +# Logger + +# Set up the logger +logger = logging.getLogger(__name__) +logger.setLevel(logging.DEBUG) + +# Create a file handler +file_handler = logging.FileHandler('../../logs/nightly_build.log') +file_handler.setLevel(logging.DEBUG) + +# Create a console handler +console_handler = logging.StreamHandler() +console_handler.setLevel(logging.INFO) + +# Create a formatter and add it to the handlers +formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') +file_handler.setFormatter(formatter) +console_handler.setFormatter(formatter) + +# Add the handlers to the logger +logger.addHandler(file_handler) +logger.addHandler(console_handler) @@ -83,21 +110,21 @@ def __init__(self): base_dir (str): The base directory where folders will be managed and repository will be cloned. """ env_extract_var = 'WALLY' - print(f"The environemntal variable is {env_extract_var}") self.base_dir = os.environ.get(env_extract_var) - print(f"The base directory is: {self.base_dir}") self.base_parent_dir = os.path.dirname(self.base_dir) - # print(f"The new WALLY vairable is: {os.environ.get('WALLY')}") - # print(f"The Base Directory is now : {self.base_dir}") - # print(f"The Base Parent Directory is now : {self.base_parent_dir}") + logger.info(f"Base directory: {self.base_dir}") + logger.info(f"Parent Base directory: {self.base_parent_dir}") + def create_preliminary_folders(self, folders): """ Create preliminary folders if they do not exist. These folders are: - nightly_runs/repos/ - nightly_runs/results/ + nightly-runs/repos/ + nightly-runs/results/ + nightly-runs/repos/ + nightly-runs/results/ Args: folders (list): A list of folder names to be created. @@ -110,6 +137,7 @@ def create_preliminary_folders(self, folders): folder_path = os.path.join(self.base_parent_dir, folder) if not os.path.exists(folder_path): os.makedirs(folder_path) + logger.info(f"Preliminary folders created: {folders}") def create_new_folder(self, folders): """ @@ -131,7 +159,7 @@ def create_new_folder(self, folders): return_folder_path.append(folder_path) else: return_folder_path.append(None) # Folder already exists - + logger.info(f"New folder created. Path: {folder_path}") return return_folder_path def clone_repository(self, folder, repo_url): @@ -152,7 +180,8 @@ def clone_repository(self, folder, repo_url): os.makedirs(repo_folder) os.system(f"git clone --recurse-submodules {repo_url} {repo_folder}") os.makedirs(tmp_folder) - + + logger.info(f"Repository cloned: {repo_url}") class TestRunner: """A class for making, running, and formatting test results.""" @@ -161,8 +190,9 @@ def __init__(self): self.base_dir = os.environ.get('WALLY') self.base_parent_dir = os.path.dirname(self.base_dir) self.current_datetime = datetime.now() - #self.temp_dir = self.base_parent_dir - #print(f"Base Directory: {self.base_parent_dir}") + + logger.info("Test runner object is initialized") + def copy_setup_script(self, folder): """ @@ -171,10 +201,11 @@ def copy_setup_script(self, folder): The setup script will be copied from the base directory to a specific folder structure inside the base directory. Args: - folder: the "nightly_runs/repos/" + folder: the "nightly-runs/repos/" + folder: the "nightly-runs/repos/" Returns: - bool: True if the script is copied successfully, False otherwise. + bool: True if the script is copied successfuly, False otherwise. """ # Get today's date in YYYY-MM-DD format todays_date = datetime.now().strftime("%Y-%m-%d") @@ -185,22 +216,22 @@ def copy_setup_script(self, folder): # Check if the source script exists if not os.path.exists(source_script): - print(f"Error: Source script '{source_script}' not found.") + logger.error(f"Error: Source script '{source_script}' not found.") return False # Check if the destination folder exists, create it if necessary if not os.path.exists(destination_folder): - print(f"Error: Destination folder '{destination_folder}' not found.") + logger.error(f"Error: Destination folder '{destination_folder}' not found.") return False # Copy the script to the destination folder try: shutil.copy(source_script, destination_folder) - #print(f"Setup script copied to: {destination_folder}") + logger.info(f"Setup script copied to: {destination_folder}") return True except Exception as e: - print(f"Error copying setup script: {e}") + logger.error(f"Error copying setup script: {e}") return False @@ -225,10 +256,37 @@ def set_env_var(self, folder): self.base_parent_dir = os.path.dirname(self.base_dir) self.temp_dir = self.base_parent_dir - # print(f"The new WALLY vairable is: {os.environ.get('WALLY')}") - # print(f"The Base Directory is now : {self.base_dir}") - # print(f"The Base Parent Directory is now : {self.base_parent_dir}") - + logger.info(f"Tests are going to be ran from: {self.base_dir}") + logger.info(f"WALLY environmental variable is: {os.environ.get('WALLY')}") + + + def change_time_dur(self, time_duriation=1): + + # Prepare the command to execute the Makefile + make_file_path = os.path.join(self.base_dir, "sim") + logger.info(f"Make file path is set to: {make_file_path}") + try: + os.chdir(make_file_path) + except Exception as e: + logger.error(f"Error nagivating to the make file path. Error: {e}") + file_path = "regression-wally" + line_number = 450 # TIMEOUT_DUR = 1 day at this line in regression-wally + new_line = f" TIMEOUT_DUR = {60*time_duriation}" + + with open(file_path, 'r') as file: + lines = file.readlines() + + if line_number < 1 or line_number > len(lines): + logger.error("Error: Line number out of range.") + return False + + lines[line_number - 1] = new_line + '\n' + + with open(file_path, 'w') as file: + file.writelines(lines) + logger.info(f"Timeduration in ./regression-wally has been changed to: {time_duriation*60} seconds") + return True + def execute_makefile(self, target=None): """ Execute a Makefile with optional target. @@ -252,7 +310,9 @@ def execute_makefile(self, target=None): # Add target to the command if specified if target: command.append(target) - #print(f"The command is: {command}") + logger.info(f"Command used: {command[0]} {command[1]}") + else: + logger.info(f"Command used: {command[0]}") # Execute the command using subprocess and save the output into a file with open(output_file, "w") as f: @@ -266,10 +326,10 @@ def execute_makefile(self, target=None): # Check the result if result.returncode == 0: - #print(f"Makefile executed successfully{' with target ' + target if target else ''}.") + logger.info(f"Tests have been made with tag target: {target}") return True else: - #print("Error executing Makefile.") + logger.error(f"Error making the tests. Target: {target}") return False def run_tests(self, test_type=None, test_name=None, test_exctention=None): @@ -291,21 +351,27 @@ def run_tests(self, test_type=None, test_name=None, test_exctention=None): if test_exctention: command = [test_type, test_name, test_exctention] + logger.info(f"Command used to run tests: {test_type} {test_name} {test_exctention}") else: command = [test_type, test_name] + logger.info(f"Command used to run tests: {test_type} {test_name}") + # Execute the command using subprocess and save the output into a file - with open(output_file, "w") as f: - formatted_datetime = self.current_datetime.strftime("%Y-%m-%d %H:%M:%S") - f.write(formatted_datetime) - f.write("\n\n") - result = subprocess.run(command, stdout=f, stderr=subprocess.STDOUT, text=True) - - # Check if the command executed successfully + try: + with open(output_file, "w") as f: + formatted_datetime = self.current_datetime.strftime("%Y-%m-%d %H:%M:%S") + f.write(formatted_datetime) + f.write("\n\n") + result = subprocess.run(command, stdout=f, stderr=subprocess.STDOUT, text=True) + except Exception as e: + logger.error("There was an error in running the tests in the run_tests function: {e}") + # Check if the command executed successfuly if result.returncode or result.returncode == 0: + logger.info(f"Test ran successfuly. Test type: {test_type}, test name: {test_name}, test extention: {test_exctention}") return True, output_file else: - print("Error:", result.returncode) + logger.error(f"Error making test. Test type: {test_type}, test name: {test_name}, test extention: {test_exctention}") return False, output_file @@ -336,11 +402,10 @@ def clean_format_output(self, input_file, output_file=None): while index < len(lines): # Remove ANSI escape codes line = re.sub(r'\x1b\[[0-9;]*[mGK]', '', lines[index]) - #print(line) + if "Success" in line: passed_configs.append(line.split(':')[0].strip()) elif "passed lint" in line: - #print(line) passed_configs.append(line.split(' ')[0].strip()) #passed_configs.append(line) # potentially use a space elif "failed lint" in line: @@ -351,7 +416,6 @@ def clean_format_output(self, input_file, output_file=None): try: config_name = line.split(':')[0].strip() log_file = os.path.abspath("logs/"+config_name+".log") - #print(f"The log file saving to: {log_file} in the current working directory: {os.getcwd()}") failed_configs.append((config_name, log_file)) except: failed_configs.append((config_name, "Log file not found")) @@ -365,8 +429,7 @@ def clean_format_output(self, input_file, output_file=None): if len(failed_configs) != 0: failed_configs.sort() - #print(f"The passed configs are: {passed_configs}") - #print(f"The failed configs are {failed_configs}") + logger.info(f"Cleaned test results. Passed configs {passed_configs}. Failed configs: {failed_configs}") return passed_configs, failed_configs def rewrite_to_markdown(self, test_name, passed_configs, failed_configs): @@ -387,8 +450,7 @@ def rewrite_to_markdown(self, test_name, passed_configs, failed_configs): os.chdir(output_directory) current_directory = os.getcwd() output_file = os.path.join(current_directory, f"{test_name}.md") - #print("Current directory:", current_directory) - #print("Output File:", output_file) + with open(output_file, 'w') as md_file: @@ -412,7 +474,9 @@ def rewrite_to_markdown(self, test_name, passed_configs, failed_configs): for config in passed_configs: md_file.write(f"- {config}\n") - def combine_markdown_files(self, passed_tests, failed_tests, test_list, total_number_failures, total_number_success, test_type="default", markdown_file=None): + logger.info("writing test outputs to markdown") + + def combine_markdown_files(self, passed_tests, failed_tests, test_list, total_number_failures, total_number_success, test_type="default", markdown_file=None, args=None): """ First we want to display the server properties like: - Server full name @@ -451,6 +515,9 @@ def combine_markdown_files(self, passed_tests, failed_tests, test_list, total_nu os_info = subprocess.check_output(['uname', '-a']).strip().decode('utf-8') md_file.write(f"\n**Operating System Information:** {os_info}") md_file.write("\n") + + md_file.write(f"\n**Command used to execute test:** python nightly_build.py --path {args.path} --repository {args.repository} --target {args.target} --send_email {args.send_email}") + md_file.write("\n") except subprocess.CalledProcessError as e: # Handle if the command fails md_file.write(f"Failed to identify host and Operating System information: {str(e)}") @@ -465,13 +532,10 @@ def combine_markdown_files(self, passed_tests, failed_tests, test_list, total_nu # Failed Tests md_file.write(f"\n\n## Failed Tests") - md_file.write(f"\nTotal failed tests: {total_number_failures}") + md_file.write(f"\n**Total failed tests: {total_number_failures}**") for (test_item, item) in zip(test_list, failed_tests): md_file.write(f"\n\n### {test_item[1]} test") - md_file.write(f"\n**General Information**\n") - md_file.write(f"\n* Test type: {test_item[0]}\n") - md_file.write(f"\n* Test name: {test_item[1]}\n") - md_file.write(f"\n* Test extension: {test_item[2]}\n\n") + md_file.write(f"\n**Command used:** {test_item[0]} {test_item[1]} {test_item[2]}\n\n") md_file.write(f"**Failed Tests:**\n") @@ -488,17 +552,14 @@ def combine_markdown_files(self, passed_tests, failed_tests, test_list, total_nu md_file.write("\n") md_file.write(f"* {config} ({log_file})\n") md_file.write("\n") - # Successfull Tests + # Successful Tests - md_file.write(f"\n\n## Successfull Tests") - md_file.write(f"\n**Total successfull tests: {total_number_success}**") + md_file.write(f"\n\n## Successful Tests") + md_file.write(f"\n**Total successful tests: {total_number_success}**") for (test_item, item) in zip(test_list, passed_tests): md_file.write(f"\n\n### {test_item[1]} test") - md_file.write(f"\n**General Information**\n") - md_file.write(f"\n* Test type: {test_item[0]}") - md_file.write(f"\n* Test name: {test_item[1]}") - md_file.write(f"\n* Test extension: {test_item[2]}\n\n") - md_file.write(f"\n**Successfull Tests:**\n") + md_file.write(f"\n**Command used:** {test_item[0]} {test_item[1]} {test_item[2]}\n\n") + md_file.write(f"\n**Successful Tests:**\n") @@ -514,7 +575,8 @@ def combine_markdown_files(self, passed_tests, failed_tests, test_list, total_nu md_file.write(f"* {config}\n") md_file.write("\n") - + logger.info("Combining markdown files") + def convert_to_html(self, markdown_file="results.md", html_file="results.html"): """ @@ -539,7 +601,7 @@ def convert_to_html(self, markdown_file="results.md", html_file="results.html"): with open(html_file, 'w') as html_file: html_file.write(html_content) - + logger.info("Converting markdown file to html file.") def send_email(self, sender_email=None, receiver_emails=None, subject="Nightly Regression Test"): """ @@ -557,7 +619,7 @@ def send_email(self, sender_email=None, receiver_emails=None, subject="Nightly R # check if there are any emails if not receiver_emails: - print("No receiver emails provided.") + logger.ERROR("No receiver emails provided.") return # grab thge html file todays_date = self.current_datetime.strftime("%Y-%m-%d") @@ -570,124 +632,167 @@ def send_email(self, sender_email=None, receiver_emails=None, subject="Nightly R + try: + for receiver_email in receiver_emails: + # Compose the mutt command for each receiver email + command = [ + '/usr/bin/mutt', + '-s', subject, + '-e', 'set content_type=text/html', + '-e', 'my_hdr From: James Stine ', + '--', receiver_email + ] + try: + # Open a subprocess to run the mutt command + process = subprocess.Popen(command, stdin=subprocess.PIPE) + # Write the email body to the subprocess + process.communicate(body.encode('utf-8')) + logger.info("Sent email") + except expression as identifier: + logger.error(f"Error sending email with error: {identifier}") + except expression as identifier: + logger.error(f"Error sending email with error: {identifier}") - for receiver_email in receiver_emails: - # Compose the mutt command for each receiver email - command = [ - 'mutt', - '-s', subject, - '-e', 'set content_type=text/html', - '-e', 'my_hdr From: James Stine ', - '--', receiver_email - ] - - # Open a subprocess to run the mutt command - process = subprocess.Popen(command, stdin=subprocess.PIPE) - - # Write the email body to the subprocess - process.communicate(body.encode('utf-8')) -############################################# -# SETUP # -############################################# -folder_manager = FolderManager() # creates the object +def main(): + ############################################# + # ARG PARSER # + ############################################# -# setting the path on where to clone new repositories of cvw -path = folder_manager.create_preliminary_folders(["nightly_runs/repos/", "nightly_runs/results/"]) -new_folder = folder_manager.create_new_folder(["nightly_runs/repos/", "nightly_runs/results/"]) + parser = argparse.ArgumentParser(description='Nightly Verification Testing for WALLY.') -# clone the cvw repo -folder_manager.clone_repository("nightly_runs/repos/", "https://github.com/openhwgroup/cvw.git") + parser.add_argument('--path', help='specify the path for where the nightly repositories will be cloned ex: "nightly-runs') + parser.add_argument('--repository', help='specify which github repository you want to clone') + parser.add_argument('--target', help='types of tests you can make are: all, wally-riscv-arch-test') + parser.add_argument('--send_email', help='do you want to send emails: "yes" or "y"') + + args = parser.parse_args() + + logger.info(f"path: {args.path}") + logger.info(f"repository: {args.repository}") + logger.info(f"target: {args.target}") + logger.info(f"send_email: {args.send_email}") + + # file paths for where the results and repos will be saved: repos and results can be changed to whatever + repos_path = f"{args.path}/repos/" + results_path = f"{args.path}/results/" + ############################################# + # SETUP # + ############################################# + folder_manager = FolderManager() # creates the object + + # setting the path on where to clone new repositories of cvw + folder_manager.create_preliminary_folders([repos_path, results_path]) + new_folder = folder_manager.create_new_folder([repos_path, results_path]) + + # clone the cvw repo + folder_manager.clone_repository(repos_path, args.repository) + - -############################################# -# SETUP # -############################################# + test_runner = TestRunner() # creates the object + test_runner.set_env_var(repos_path) # ensures that the new WALLY environmental variable is set correctly -test_runner = TestRunner() # creates the object -test_runner.set_env_var("nightly_runs/repos/") # ensures that the new WALLY environmental variable is set correctly + ############################################# + # TMP SETUP # + ############################################# -############################################# -# MAKE TESTS # -############################################# + """ + The goal of this section is to replace the TIMEOUT_DUR for regression tests. + """ + if test_runner.change_time_dur(time_duriation=1): + pass + else: + logger.error("Error occured changing the TIMEOUT duration in './regression-wally'") -# target = "wally-riscv-arch-test" -target = "all" -if test_runner.execute_makefile(target = target): - print(f"The {target} tests were made successfully") + ############################################# + # MAKE TESTS # + ############################################# -############################################# -# RUN TESTS # -############################################# + if args.target != "no": + # test_runner.execute_makefile(target = "deriv") + test_runner.execute_makefile(target = args.target) + ############################################# + # RUN TESTS # + ############################################# -test_list = [["python", "regression-wally", "-nightly"], ["bash", "lint-wally", "-nightly"], ["bash", "coverage", "--search"]] -output_log_list = [] # a list where the output markdown file lcoations will be saved to -total_number_failures = 0 # an integer where the total number failures from all of the tests will be collected -total_number_success = 0 # an integer where the total number of sucess will be collected -total_failures = [] -total_success = [] + test_list = [["python", "regression-wally", "-nightly"], ["bash", "lint-wally", "-nightly"], ["bash", "coverage", "--search"]] + output_log_list = [] # a list where the output markdown file lcoations will be saved to + total_number_failures = 0 # an integer where the total number failures from all of the tests will be collected + total_number_success = 0 # an integer where the total number of sucess will be collected -for test_type, test_name, test_exctention in test_list: - print("--------------------------------------------------------------") - print(f"Test type: {test_type}") - print(f"Test name: {test_name}") - print(f"Test extenction: {test_exctention}") + total_failures = [] + total_success = [] - check, output_location = test_runner.run_tests(test_type=test_type, test_name=test_name, test_exctention=test_exctention) - print(check) - print(output_location) - if check: # this checks if the test actually ran successfully - output_log_list.append(output_location) + for test_type, test_name, test_exctention in test_list: - # format tests to markdown + check, output_location = test_runner.run_tests(test_type=test_type, test_name=test_name, test_exctention=test_exctention) try: - passed, failed = test_runner.clean_format_output(input_file = output_location) - except: - print("There was an error cleaning the data") + if check: # this checks if the test actually ran successfuly + output_log_list.append(output_location) + logger.info(f"{test_name} ran successfuly. Output location: {output_location}") + # format tests to markdown + try: + passed, failed = test_runner.clean_format_output(input_file = output_location) + logger.info(f"{test_name} has been formatted to markdown") + except: + logger.ERROR(f"Error occured with formatting {test_name}") - print(f"The # of failures are for {test_name}: {len(failed)}") - total_number_failures+= len(failed) - total_failures.append(failed) + logger.info(f"The # of failures are for {test_name}: {len(failed)}") + total_number_failures+= len(failed) + total_failures.append(failed) - print(f"The # of sucesses are for {test_name}: {len(passed)}") - total_number_success += len(passed) - total_success.append(passed) - test_runner.rewrite_to_markdown(test_name, passed, failed) + logger.info(f"The # of sucesses are for {test_name}: {len(passed)}") + total_number_success += len(passed) + total_success.append(passed) + test_runner.rewrite_to_markdown(test_name, passed, failed) + + except Exception as e: + logger.error("There was an error in running the tests: {e}") -print(f"The total sucesses are: {total_number_success}") -print(f"The total failures are: {total_number_failures}") + logger.info(f"The total sucesses for all tests ran are: {total_number_success}") + logger.info(f"The total failures for all tests ran are: {total_number_failures}") - + -############################################# -# FORMAT TESTS # -############################################# + ############################################# + # FORMAT TESTS # + ############################################# -# Combine multiple markdown files into one file + # Combine multiple markdown files into one file + try: + test_runner.combine_markdown_files(passed_tests = total_success, failed_tests = total_failures, test_list = test_list, total_number_failures = total_number_failures, total_number_success = total_number_success, test_type=args.target, markdown_file=None, args=args) + except Exception as e: + logger.error(f"Error combining the markdown tests called from main: {e}") -test_runner.combine_markdown_files(passed_tests = total_success, failed_tests = total_failures, test_list = test_list, total_number_failures = total_number_failures, total_number_success = total_number_success, test_type=target, markdown_file=None) + ############################################# + # WRITE MD TESTS # + ############################################# + test_runner.convert_to_html() -############################################# -# WRITE MD TESTS # -############################################# -test_runner.convert_to_html() + ############################################# + # SEND EMAIL # + ############################################# + sender_email = 'james.stine@okstate.edu' -############################################# -# SEND EMAIL # -############################################# + receiver_emails = ['thomas.kidd@okstate.edu', 'james.stine@okstate.edu', 'harris@g.hmc.edu', 'rose.thompson10@okstate.edu', 'sarah.harris@unlv.edu', 'nlucio@hmc.edu'] + testing_emails = ['thomas.kidd@okstate.edu'] + + if (args.send_email == "yes" or args.send_email == "y"): + test_runner.send_email(sender_email=sender_email, receiver_emails=receiver_emails) + if (args.send_email == "test"): + test_runner.send_email(sender_email=sender_email, receiver_emails=testing_emails) -sender_email = 'james.stine@okstate.edu' -receiver_emails = ['thomas.kidd@okstate.edu', 'james.stine@okstate.edu', 'harris@g.hmc.edu', 'rose.thompson10@okstate.edu'] -test_runner.send_email(sender_email=sender_email, receiver_emails=receiver_emails) \ No newline at end of file +if __name__ == "__main__": + main() diff --git a/bin/wrapper_nightly_runs.sh b/bin/wrapper_nightly_runs.sh index 219e765df6..91e57d091b 100755 --- a/bin/wrapper_nightly_runs.sh +++ b/bin/wrapper_nightly_runs.sh @@ -3,9 +3,9 @@ date # Variables -LOG=$HOME/nightly_runs/logs/from_wrapper.log # you can store your log file where you would like -PYTHON_SCRIPT=$HOME/nightly_runs/cvw/bin/ # cvw can be anywhere you would like it. Make sure to point your variable there -SETUP_SCRIPT=$HOME/nightly_runs/cvw/ # cvw can be anywhere you would like it. Make sure to point your variable there +LOG=$HOME/nightly-runs/logs/from_wrapper.log # you can store your log file where you would like +PYTHON_SCRIPT=$HOME/nightly-runs/cvw/bin/ # cvw can be anywhere you would like it. Make sure to point your variable there +SETUP_SCRIPT=$HOME/nightly-runs/cvw/ # cvw can be anywhere you would like it. Make sure to point your variable there @@ -20,9 +20,9 @@ pwd echo "Sourcing setup_host" source ./setup_host.sh >> $LOG 2>&1 -echo "Sourcing setup_tools" cd $PYTHON_SCRIPT pwd echo "Running python file" -python nightly_build.py >> $LOG 2>&1 +python nightly_build.py --path "nightly-runs" --repository "https://github.com/openhwgroup/cvw" --target "all" --send_email "yes" >> $LOG 2>&1 +echo "Finished" diff --git a/config/derivlist.txt b/config/derivlist.txt index 279fbd3c5e..6851278b3e 100644 --- a/config/derivlist.txt +++ b/config/derivlist.txt @@ -546,6 +546,10 @@ deriv fd_rv64gc rv64gc MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) ZFH_SUPPORTED 0 +deriv fdh_rv64gc rv64gc +MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) +ZFH_SUPPORTED 1 + deriv fdq_rv64gc rv64gc MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 16 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) ZFH_SUPPORTED 0 diff --git a/config/rv32e/config.vh b/config/rv32e/config.vh index 9f0056fad7..5e1f883d4e 100644 --- a/config/rv32e/config.vh +++ b/config/rv32e/config.vh @@ -179,6 +179,15 @@ localparam ZCA_SUPPORTED = 0; localparam ZCF_SUPPORTED = 0; localparam ZCD_SUPPORTED = 0; +// K extension instructions +localparam ZBKB_SUPPORTED = 0; +localparam ZBKC_SUPPORTED = 0; +localparam ZBKX_SUPPORTED = 0; +localparam ZKNE_SUPPORTED = 0; +localparam ZKND_SUPPORTED = 0; +localparam ZK_SUPPORTED = 0; +localparam ZKNH_SUPPORTED = 0; + // Memory synthesis configuration localparam USE_SRAM = 0; diff --git a/config/rv32gc/config.vh b/config/rv32gc/config.vh index 843f55530b..d6fb995b12 100644 --- a/config/rv32gc/config.vh +++ b/config/rv32gc/config.vh @@ -180,6 +180,15 @@ localparam ZCA_SUPPORTED = 0; localparam ZCF_SUPPORTED = 0; localparam ZCD_SUPPORTED = 0; +// K extension instructions +localparam ZBKB_SUPPORTED = 1; +localparam ZBKC_SUPPORTED = 1; +localparam ZBKX_SUPPORTED = 1; +localparam ZKND_SUPPORTED = 1; +localparam ZKNE_SUPPORTED = 1; +localparam ZKNH_SUPPORTED = 1; +localparam ZK_SUPPORTED = 1; + // Memory synthesis configuration localparam USE_SRAM = 0; diff --git a/config/rv32i/config.vh b/config/rv32i/config.vh index 81b25bc2b7..490937558a 100644 --- a/config/rv32i/config.vh +++ b/config/rv32i/config.vh @@ -180,6 +180,15 @@ localparam ZCA_SUPPORTED = 0; localparam ZCF_SUPPORTED = 0; localparam ZCD_SUPPORTED = 0; +// K extension instructions +localparam ZBKB_SUPPORTED = 0; +localparam ZBKC_SUPPORTED = 0; +localparam ZBKX_SUPPORTED = 0; +localparam ZKNE_SUPPORTED = 0; +localparam ZKND_SUPPORTED = 0; +localparam ZK_SUPPORTED = 0; +localparam ZKNH_SUPPORTED = 0; + // Memory synthesis configuration localparam USE_SRAM = 0; diff --git a/config/rv32imc/config.vh b/config/rv32imc/config.vh index 931725cc42..357eba840d 100644 --- a/config/rv32imc/config.vh +++ b/config/rv32imc/config.vh @@ -178,6 +178,15 @@ localparam ZCA_SUPPORTED = 0; localparam ZCF_SUPPORTED = 0; localparam ZCD_SUPPORTED = 0; +// K extension instructions +localparam ZBKB_SUPPORTED = 0; +localparam ZBKC_SUPPORTED = 0; +localparam ZBKX_SUPPORTED = 0; +localparam ZKNE_SUPPORTED = 0; +localparam ZKND_SUPPORTED = 0; +localparam ZK_SUPPORTED = 0; +localparam ZKNH_SUPPORTED = 0; + // Memory synthesis configuration localparam USE_SRAM = 0; diff --git a/config/rv64gc/config.vh b/config/rv64gc/config.vh index 7f038d87ec..1d6c5e9f45 100644 --- a/config/rv64gc/config.vh +++ b/config/rv64gc/config.vh @@ -181,6 +181,15 @@ localparam ZCA_SUPPORTED = 0; localparam ZCF_SUPPORTED = 0; localparam ZCD_SUPPORTED = 0; +// K extension instructions +localparam ZBKB_SUPPORTED = 1; +localparam ZBKC_SUPPORTED = 1; +localparam ZBKX_SUPPORTED = 1; +localparam ZKND_SUPPORTED = 1; +localparam ZKNE_SUPPORTED = 1; +localparam ZKNH_SUPPORTED = 1; +localparam ZK_SUPPORTED = 1; + // Memory synthesis configuration localparam USE_SRAM = 0; diff --git a/config/rv64i/config.vh b/config/rv64i/config.vh index 4dd540a9f9..a289003cc0 100644 --- a/config/rv64i/config.vh +++ b/config/rv64i/config.vh @@ -181,6 +181,15 @@ localparam ZCA_SUPPORTED = 0; localparam ZCF_SUPPORTED = 0; localparam ZCD_SUPPORTED = 0; +// K extension instructions +localparam ZBKB_SUPPORTED = 0; +localparam ZBKC_SUPPORTED = 0; +localparam ZBKX_SUPPORTED = 0; +localparam ZKNE_SUPPORTED = 0; +localparam ZKND_SUPPORTED = 0; +localparam ZK_SUPPORTED = 0; +localparam ZKNH_SUPPORTED = 0; + // Memory synthesis configuration localparam USE_SRAM = 0; diff --git a/config/shared/config-shared.vh b/config/shared/config-shared.vh index dd766f2fd9..481247eaec 100644 --- a/config/shared/config-shared.vh +++ b/config/shared/config-shared.vh @@ -1,3 +1,6 @@ +//max function +`define max(a,b) (((a) > (b)) ? (a) : (b)) + // constants defining different privilege modes // defined in Table 1.1 of the privileged spec localparam M_MODE = (2'b11); @@ -29,6 +32,7 @@ localparam D_SUPPORTED = ((MISA >> 3) % 2 == 1); localparam E_SUPPORTED = ((MISA >> 4) % 2 == 1); localparam F_SUPPORTED = ((MISA >> 5) % 2 == 1); localparam I_SUPPORTED = ((MISA >> 8) % 2 == 1); +localparam K_SUPPORTED = ((ZBKB_SUPPORTED | ZBKC_SUPPORTED | ZBKX_SUPPORTED | ZKND_SUPPORTED | ZKNE_SUPPORTED | ZKNH_SUPPORTED)); localparam M_SUPPORTED = ((MISA >> 12) % 2 == 1); localparam Q_SUPPORTED = ((MISA >> 16) % 2 == 1); localparam S_SUPPORTED = ((MISA >> 18) % 2 == 1); @@ -106,12 +110,13 @@ localparam DURLEN = $clog2(FPDUR); // enough bi localparam DIVBLEN = $clog2(DIVb+1); // enough bits to count number of fractional bits + 1 integer bit // largest length in IEU/FPU -localparam CVTLEN = ((NF(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVb + 1 +NF+1) > (3*NF+6) ? (DIVb + 1 +NF+1) : (3*NF+6))); // max(CVTLEN+NF+1, DIVb + 1 + NF + 1, 3*NF+6) +localparam NORMSHIFTSZ = `max(`max((CVTLEN+NF+1), (DIVb + 1 + NF + 1)), (3*NF+6)); localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ)); -localparam CORRSHIFTSZ = (NORMSHIFTSZ-2 > (DIVMINb + 1 + NF)) ? NORMSHIFTSZ-2 : (DIVMINb+1+NF); // max(NORMSHIFTSZ-2, DIVMINb + 1 + NF) +localparam CORRSHIFTSZ = `max((NORMSHIFTSZ-2), (DIVMINb + 1 + NF)); // Disable spurious Verilator warnings diff --git a/config/shared/parameter-defs.vh b/config/shared/parameter-defs.vh index 464e3c0f92..5635b286c1 100644 --- a/config/shared/parameter-defs.vh +++ b/config/shared/parameter-defs.vh @@ -113,6 +113,13 @@ localparam cvw_t P = '{ ZCB_SUPPORTED : ZCB_SUPPORTED, ZCD_SUPPORTED : ZCD_SUPPORTED, ZCF_SUPPORTED : ZCF_SUPPORTED, + ZBKB_SUPPORTED: ZBKB_SUPPORTED, + ZBKC_SUPPORTED: ZBKC_SUPPORTED, + ZBKX_SUPPORTED: ZBKX_SUPPORTED, + ZKND_SUPPORTED: ZKND_SUPPORTED, + ZKNE_SUPPORTED: ZKNE_SUPPORTED, + ZKNH_SUPPORTED: ZKNH_SUPPORTED, + ZK_SUPPORTED : ZK_SUPPORTED, USE_SRAM : USE_SRAM, M_MODE : M_MODE, S_MODE : S_MODE, @@ -136,6 +143,7 @@ localparam cvw_t P = '{ E_SUPPORTED : E_SUPPORTED, F_SUPPORTED : F_SUPPORTED, I_SUPPORTED : I_SUPPORTED, + K_SUPPORTED : K_SUPPORTED, M_SUPPORTED : M_SUPPORTED, Q_SUPPORTED : Q_SUPPORTED, S_SUPPORTED : S_SUPPORTED, diff --git a/setup.csh b/setup.csh index 82728f57c5..62a99f376e 100755 --- a/setup.csh +++ b/setup.csh @@ -5,48 +5,20 @@ echo "Executing Wally setup.csh" -# Path to Wally repository -setenv WALLY $PWD -echo '$WALLY set to ' ${WALLY} # Extend alias which makes extending PATH much easier. alias extend 'if (-d \!:2) if ("$\!:1" \!~ *"\!:2"*) setenv \!:1 ${\!:1}:\!:2;echo Added \!:2 to \!:1' alias prepend 'if (-d \!:2) if ("$\!:1" \!~ *"\!:2"*) setenv \!:1 "\!:2":${\!:1};echo Added \!:2 to \!:1' -# License servers and commercial CAD tool paths -# Must edit these based on your local environment. Ask your sysadmin. -setenv MGLS_LICENSE_FILE 27002@zircon.eng.hmc.edu # Change this to your Siemens license server -setenv SNPSLMD_LICENSE_FILE 27020@zircon.eng.hmc.edu # Change this to your Synopsys license server -setenv QUESTAPATH /cad/mentor/questa_sim-2022.4_2/questasim/bin # Change this for your path to Questa -setenv SNPSPATH /cad/synopsys/SYN/bin # Change this for your path to Design Compiler - # Path to RISC-V Tools setenv RISCV /opt/riscv # change this if you installed the tools in a different location -# Tools -# Questa and Synopsys -extend PATH $QUESTAPATH -extend PATH $SNPSPATH -# GCC -prepend LD_LIBRARY_PATH $RISCV/riscv-gnu-toolchain/lib -prepend LD_LIBRARY_PATH $RISCV/riscv-gnu-toolchain/riscv64-unknown-elf/lib -extend PATH $RISCV/riscv-gnu-toolchain/bin # GCC tools -extend PATH $RISCV/riscv-gnu-toolchain/riscv64-unknown-elf/bin # GCC tools -# Spike -extend LD_LIBRARY_PATH $RISCV/lib -extend PATH $RISCV/bin +# Path to Wally repository +setenv WALLY $PWD +echo '$WALLY set to ' ${WALLY} # utility functions in Wally repository extend PATH $WALLY/bin -# Verilator -extend PATH /usr/local/bin/verilator # Change this for your path to Verilator -# ModelSim/Questa (vsim) -# Note: 2022.1 complains on cache/sram1p1r1w about StoredData cannot be driven by multiple always_ff blocks. Ues 2021.2 for now - -# Imperas; put this in if you are using it -#set path = ($RISCV/imperas-riscv-tests/riscv-ovpsim-plus/bin/Linux64 $path) -#setenv LD_LIBRARY_PATH $RISCV/imperas_riscv_tests/riscv-ovpsim-plus/bin/Linux64:$LD_LIBRARY_PATH # remove if no imperas -# Verilator needs a larger stack to simulate CORE-V Wally -limit stacksize unlimited +source $RISCV/site-setup.csh echo "setup done" diff --git a/setup.sh b/setup.sh old mode 100755 new mode 100644 index e1d4e6cd37..f609c1e3df --- a/setup.sh +++ b/setup.sh @@ -2,58 +2,31 @@ # setup.sh # David_Harris@hmc.edu and kekim@hmc.edu 1 December 2021 -# Set up tools for rvw +# Set up tools for cvw + +# optionally have .bashrc or .bash_profile source this file with +#if [ -f ~/cvw/setup.sh ]; then +# source ~/cvw/setup.sh +#fi + # SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 echo "Executing Wally setup.sh" +# Path to RISC-V Tools +export RISCV=/opt/riscv # change this if you installed the tools in a different location + # Path to Wally repository WALLY=$(dirname ${BASH_SOURCE[0]:-$0}) export WALLY=$(cd "$WALLY" && pwd) echo \$WALLY set to ${WALLY} - -# License servers and commercial CAD tool paths -# Must edit these based on your local environment. Ask your sysadmin. -export MGLS_LICENSE_FILE=27002@zircon.eng.hmc.edu # Change this to your Siemens license server -export SNPSLMD_LICENSE_FILE=27020@zircon.eng.hmc.edu # Change this to your Synopsys license server -export QUESTA_HOME=/cad/mentor/questa_sim-2023.4/questasim # Change this for your path to Questa, excluding bin -export SNPS_HOME=/cad/synopsys/SYN # Change this for your path to Design Compiler, excluding bin - -# Path to RISC-V Tools -export RISCV=/opt/riscv # change this if you installed the tools in a different location - -# Tools -# Questa and Synopsys -export PATH=$QUESTA_HOME/bin:$SNPS_HOME/bin:$PATH -# GCC -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RISCV/riscv-gnu-toolchain/lib:$RISCV/riscv-gnu-toolchain/riscv64-unknown-elf/lib -export PATH=$PATH:$RISCV/riscv-gnu-toolchain/bin:$RISCV/riscv-gnu-toolchain/riscv64-unknown-elf/bin # GCC tools -# Spike -export LD_LIBRARY_PATH=$RISCV/lib:$LD_LIBRARY_PATH -export PATH=$PATH:$RISCV/bin # utility functions in Wally repository export PATH=$WALLY/bin:$PATH -# Verilator -export PATH=/usr/local/bin/verilator:$PATH # Change this for your path to Verilator -# ModelSim/Questa (vsim) -# Note: 2022.1 complains on cache/sram1p1r1w about StoredData cannot be driven by multiple always_ff blocks. Ues 2021.2 for now - -# Imperas; put this in if you are using it -#export PATH=$RISCV/imperas-riscv-tests/riscv-ovpsim-plus/bin/Linux64:$PATH -#export LD_LIBRARY_PATH=$RISCV/imperas_riscv_tests/riscv-ovpsim-plus/bin/Linux64:$LD_LIBRARY_PATH # remove if no imperas - -export IDV=$RISCV/ImperasDV-OpenHW -if [ -e "$IDV" ]; then -# echo "Imperas exists" - export IMPERAS_HOME=$IDV/Imperas - export IMPERAS_PERSONALITY=CPUMAN_DV_ASYNC - export ROOTDIR=~/ - source ${IMPERAS_HOME}/bin/setup.sh - setupImperas ${IMPERAS_HOME} - export PATH=$IDV/scripts/cvw:$PATH -fi # Verilator needs a larger stack to simulate CORE-V Wally ulimit -s 100000 -echo "setup done" \ No newline at end of file +# load site licenses and tool locations +source $RISCV/site-setup.sh + +echo "setup done" diff --git a/sim/Makefile b/sim/Makefile index b23d1cb47f..6a2558f0c3 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -1,72 +1,60 @@ - -all: riscoftests memfiles coveragetests deriv benchmarks - # *** Build old tests/imperas-riscv-tests for now; - # Delete this part when the privileged tests transition over to tests/wally-riscv-arch-test - # DH: 2/27/22 temporarily commented out imperas-riscv-tests because license expired - #make -C ../tests/imperas-riscv-tests --jobs - #make -C ../tests/imperas-riscv-tests XLEN=64 --jobs - # Only compile Imperas tests if they are installed locally. - # They are usually a symlink to $RISCV/imperas-riscv-tests and only - # get compiled there manually during installation - #make -C ../addins/imperas-riscv-tests - #make -C ../addins/imperas-riscv-tests XLEN=64 - #cd ../addins/imperas-riscv-tests; elf2hex.sh - #cd ../addins/imperas-riscv-tests; extractFunctionRadix.sh work/*/*/*.elf.objdump - # Link Linux test vectors - #cd ../tests/linux-testgen/linux-testvectors/;./tvLinker.sh - -wally-riscv-arch-test: wallyriscoftests memfiles - -coverage: cov/rv64gc_arch64i.ucdb - #iter-elf.bash --cover --search ../tests/coverage - vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb -logfile cov/log -# vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb cov/buildroot_buildroot.ucdb riscv.ucdb -logfile cov/log - vcover report -details cov/cov.ucdb > cov/rv64gc_coverage_details.rpt - vcover report cov/cov.ucdb -details -instance=/core/ebu. > cov/rv64gc_coverage_ebu.rpt - vcover report cov/cov.ucdb -details -instance=/core/priv. > cov/rv64gc_coverage_priv.rpt - vcover report cov/cov.ucdb -details -instance=/core/ifu. > cov/rv64gc_coverage_ifu.rpt - vcover report cov/cov.ucdb -details -instance=/core/lsu. > cov/rv64gc_coverage_lsu.rpt - vcover report cov/cov.ucdb -details -instance=/core/fpu. > cov/rv64gc_coverage_fpu.rpt - vcover report cov/cov.ucdb -details -instance=/core/ieu. > cov/rv64gc_coverage_ieu.rpt - vcover report cov/cov.ucdb -below 100 -details -instance=/core/ebu. > cov/rv64gc_uncovered_ebu.rpt - vcover report cov/cov.ucdb -below 100 -details -instance=/core/priv. > cov/rv64gc_uncovered_priv.rpt - vcover report cov/cov.ucdb -below 100 -details -instance=/core/ifu. > cov/rv64gc_uncovered_ifu.rpt - vcover report cov/cov.ucdb -below 100 -details -instance=/core/lsu. > cov/rv64gc_uncovered_lsu.rpt - vcover report cov/cov.ucdb -below 100 -details -instance=/core/fpu. > cov/rv64gc_uncovered_fpu.rpt - vcover report cov/cov.ucdb -below 100 -details -instance=/core/ieu. > cov/rv64gc_uncovered_ieu.rpt - vcover report -hierarchical cov/cov.ucdb > cov/rv64gc_coverage_hierarchical.rpt - vcover report -below 100 -hierarchical cov/cov.ucdb > cov/rv64gc_uncovered_hierarchical.rpt -# vcover report -below 100 cov/cov.ucdb > cov/rv64gc_coverage.rpt -# vcover report -recursive cov/cov.ucdb > cov/rv64gc_recursive.rpt - vcover report -details -threshH 100 -html cov/cov.ucdb - -allclean: clean all - +# Common Variables +ifndef IMPERAS_HOME +$(error IMPERAS_HOME is not set) +endif + +IMPERAS_HOME := $(IMPERAS_HOME) +LIB = +CONFIG_VARIANT ?= rv64i +SOURCE_PATH =+incdir+../config/$(CONFIG_VARIANT) +incdir+../config/deriv/$(CONFIG_VARIANT) +incdir+../config/shared +incdir+../testbench +incdir+/$(IMPERAS_HOME)/ImpProprietary/include/host +incdir+/$(IMPERAS_HOME)/ImpPublic/source/host/rvvi +incdir+$(IMPERAS_HOME)/ImpPublic/include/host +incdir+$(IMPERAS_HOME)/ImpProprietary/include/host +SIMFILES := $(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviApiPkg.sv \ + $(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviTrace.sv \ + $(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvApiPkg.sv \ + $(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvPkg.sv \ + $(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvApiPkg.sv \ + $(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2api.sv \ + $(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2log.sv \ + $(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2bin.sv \ + ../src/cvw.sv ../testbench/testbench.sv ../src/*/*.sv ../src/*/*/*.sv ../testbench/common/*.sv +OUTPUT = sim_out + +# VCS specific +#VCS = vcs +v2k +lint=all,noGCWM -simprofile -sverilog +vc -Mupdate -line -full64 -kdb -lca -debug_access+all+reverse +define+FPGA=$(FPGA) +define+P=$(P) +define+USE_IMPERAS_DV=$(USE_IMPERAS_DV) +define+RVVI_API_VERSION=$(RVVI_API_VERSION) +define+IDV_MAX_ERRORS=$(RVVI_API_VERSION) +VCS = vcs +v2k +lint=all,noGCWM -simprofile -sverilog +vc -Mupdate -line -full64 -kdb -lca -debug_access+all+reverse +define+USE_IMPERAS_DV -v2k_generate +define+P.ZICSR_SUPPORTED=1 + +# Cadence Xcelium (xrun) specific +XRUN = xrun -sv -uvm -access +rwc -timescale 1ns/1ns + +# QuestaSim specific +QUESTASIM = vsim -c -do "run -all; quit" -voptargs+acc + +# Verilator specific +VERILATOR = verilator -Wall --cc --trace --build -Wno-ASSIGNDLY -Wno-WIDTHTRUNC -Wno-WIDTHEXPAND -Wno-ENUMVALUE + +# Target for compiling and running with VCS +vcs: clean + $(VCS) $(SOURCE_PATH) $(SIMFILES) -o $(OUTPUT) + ./$(OUTPUT) | tee program.out + +# Target for compiling and running with Xcelium (xrun) +xrun: clean + $(XRUN) $(SOURCE_PATH) $(SIMFILES) -R | tee program.out + +# Target for compiling and running with QuestaSim +questasim: clean + vlib work + vlog $(SOURCE_PATH) $(SIMFILES) + $(QUESTASIM) work.$(TOP_MODULE) + +# Target for compiling and running with Verilator for rv32i +verilate: clean + $(VERILATOR) $(SIMFILES) --exe --top-module testbench -CFLAGS "-DTEST_CONFIG=\\\"$(CONFIG_VARIANT)\\\"" -I../config/shared -I../config/$(CONFIG_VARIANT) ../testbench/common/*.sv --relative-includes ../testbench/testbench.sv + ./obj_dir/Vtop + +# Clean up generated files clean: - make clean -C ../tests/riscof -# make clean -C ../../tests/wally-riscv-arch-test -# make allclean -C ../../tests/imperas-riscv-tests - -riscoftests: -# Builds riscv-arch-test 64 and 32-bit versions and builds wally-riscv-arch-test 64 and 32-bit versions - make -C ../tests/riscof/ - -wallyriscoftests: -# Builds riscv-arch-test 64 and 32-bit versions and builds wally-riscv-arch-test 64 and 32-bit versions - make -C ../tests/riscof/ wally-riscv-arch-test - -memfiles: - make -f makefile-memfile wally-sim-files --jobs - -coveragetests: - make -C ../tests/coverage/ --jobs - -deriv: - derivgen.pl + rm -rf obj_dir work transcript vsim.wlf $(OUTPUT) *.vcd csrc ucli.key vc_hdrs.h program.out + rm -rf simv* *.daidir dve *.vpd *.dump DVEfiles/ verdi* novas* *fsdb* *.vg *.rep *.db *.chk *.log *.out profileReport* simprofile_dir* -benchmarks: - $(MAKE) -C ../benchmarks/embench build - $(MAKE) -C ../benchmarks/embench size - $(MAKE) -C ../benchmarks/embench modelsim_build_memfile - $(MAKE) -C ../benchmarks/coremark +.PHONY: vcs xrun questasim verilate clean diff --git a/sim/regression-wally b/sim/regression-wally index ea855b358f..42c54d0160 100755 --- a/sim/regression-wally +++ b/sim/regression-wally @@ -89,7 +89,7 @@ for test in tests64i: configs.append(tc) tests32gcimperas = ["imperas32i", "imperas32f", "imperas32m", "imperas32c"] # unused -tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32f_divsqrt", "arch32d_divsqrt", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zicond", "arch32zba", "arch32zbb", "arch32zbs", "arch32zfh", "arch32zfh_fma", "arch32zfh_divsqrt", "arch32zfaf", "wally32a", "wally32priv", "wally32periph"] # "arch32zbc", "arch32zfad", +tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32f_divsqrt", "arch32d_divsqrt", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zicond", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "arch32zfh", "arch32zfh_fma", "arch32zfh_divsqrt", "arch32zfaf", "wally32a", "wally32priv", "wally32periph", "arch32zbkb", "arch32zbkc", "arch32zbkx", "arch32zknd", "arch32zkne", "arch32zknh"] # "arch32zbc", "arch32zfad", #tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "arch32zicboz", "arch32zcb", "wally32a", "wally32priv", "wally32periph"] for test in tests32gc: tc = TestCase( @@ -128,7 +128,7 @@ for test in tests32e: grepstr="All tests ran without failures") configs.append(tc) -tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64f_divsqrt", "arch64d_divsqrt", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", "arch64zfh", "arch64zfh_divsqrt", "arch64zfh_fma", "arch64zfaf", "arch64zfad", +tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64f_divsqrt", "arch64d_divsqrt", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", "arch64zfh", "arch64zfh_divsqrt", "arch64zfh_fma", "arch64zfaf", "arch64zfad", "arch64zbkb", "arch64zbkc", "arch64zbkx", "arch64zknd", "arch64zkne", "arch64zknh", "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "arch64zicond", "wally64a", "wally64periph", "wally64priv"] # add arch64zfh_fma when available; arch64zicobz, arch64zcb when working #tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", # "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "wally64a", "wally64periph", "wally64priv", "arch64zicboz", "arch64zcb"] @@ -272,13 +272,13 @@ if (nightly): ["f_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma"]], ["fh_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32zfh", "arch32zfh_divsqrt"]], ["fdh_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma", "arch32zfh", "arch32zfh_divsqrt"]], - ["fdq_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma"]], - ["fdqh_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma", "arch32zfh", "arch32zfh_divsqrt"]], + ["fdq_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma", "arch32i"]], + ["fdqh_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma", "arch32zfh", "arch32zfh_divsqrt", "arch32i"]], ["f_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma"]], ["fh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64zfh", "arch64zfh_divsqrt"]], # hanging 1/31/24 dh; try again when lint is fixed ["fdh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt"]], - ["fdq_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma"]], - ["fdqh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt"]], + ["fdq_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64i"]], + ["fdqh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt", "arch64i", "wally64q"]], ] diff --git a/sim/run_vcs.sh b/sim/run_vcs.sh new file mode 100755 index 0000000000..65f1a2c761 --- /dev/null +++ b/sim/run_vcs.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Ensure IMPERAS_HOME is set +if [ -z "$IMPERAS_HOME" ]; then + echo "IMPERAS_HOME is not set" + exit 1 +fi + +# Set CONFIG_VARIANT from the first script argument +#CONFIG_VARIANT=${1:-rv64i} +CONFIG_VARIANT=${1} +# Set TESTSUITE from the second script argument +TESTSUITE=$2 + +SOURCE_PATH="+incdir+../config/${CONFIG_VARIANT} +incdir+../config/deriv/${CONFIG_VARIANT} +incdir+../config/shared +incdir+../testbench +incdir+/${IMPERAS_HOME}/ImpProprietary/include/host +incdir+/${IMPERAS_HOME}/ImpPublic/source/host/rvvi +incdir+${IMPERAS_HOME}/ImpPublic/include/host +define+INCLUDE_TRACE2COV +define+COVER_BASE_RV64I +define+COVER_LEVEL_DV_PR_EXT +define+COVER_RV64I +define+COVER_RV64C +define+COVER_RV64M +incdir+${IMPERAS_HOME}/ImpProprietary/include/host +incdir+${IMPERAS_HOME}/ImpProprietary/source/host/riscvISACOV/source" +SIMFILES="${IMPERAS_HOME}/ImpPublic/source/host/rvvi/rvviApiPkg.sv ${IMPERAS_HOME}/ImpPublic/source/host/rvvi/rvviTrace.sv ${IMPERAS_HOME}/ImpProprietary/source/host/idv/idvApiPkg.sv ${IMPERAS_HOME}/ImpProprietary/source/host/idv/idvPkg.sv ${IMPERAS_HOME}/ImpProprietary/source/host/idv/idvApiPkg.sv ${IMPERAS_HOME}/ImpProprietary/source/host/idv/trace2api.sv ${IMPERAS_HOME}/ImpProprietary/source/host/idv/trace2log.sv ${IMPERAS_HOME}/ImpProprietary/source/host/idv/trace2bin.sv ../src/cvw.sv ../testbench/testbench.sv ../src/*/*.sv ../src/*/*/*.sv ../testbench/common/*.sv" +OUTPUT="sim_out" + +clean() { + rm -rf obj_dir work transcript vsim.wlf $OUTPUT *.vcd csrc ucli.key vc_hdrs.h program.out + rm -rf simv* *.daidir dve *.vpd *.dump DVEfiles/ verdi* novas* *fsdb* *.vg *.rep *.db *.chk *.log *.out profileReport* simprofile_dir* +} + +# Clean and run simulation with VCS +clean +vcs +v2k +lint=all,noGCWM -simprofile -sverilog +vc -Mupdate -line -full64 -kdb -lca -debug_access+all+reverse +define+USE_IMPERAS_DV=1 -v2k_generate +define+P.ZICSR_SUPPORTED=1 +define+P.XLEN +define+P.ILEN +define+P.FLEN +define+P.VLEN +define+TEST=$TESTSUITE $SOURCE_PATH $SIMFILES -o $OUTPUT +./$OUTPUT | tee program.out + diff --git a/sim/run_xcellium.sh b/sim/run_xcellium.sh new file mode 100755 index 0000000000..811eeab67e --- /dev/null +++ b/sim/run_xcellium.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Ensure IMPERAS_HOME is set +if [ -z "$IMPERAS_HOME" ]; then + echo "IMPERAS_HOME is not set" + exit 1 +fi + +# Set CONFIG_VARIANT from the first script argument +CONFIG_VARIANT="$1" +# Set TESTSUITE from the second script argument +TESTSUITE="$2" + +# Define source and simulation files paths +SOURCE_PATH="+incdir+../config/${CONFIG_VARIANT} +incdir+../config/deriv/${CONFIG_VARIANT} +incdir+../config/shared +incdir+../testbench +incdir+/${IMPERAS_HOME}/ImpProprietary/include/host +incdir+/${IMPERAS_HOME}/ImpPublic/source/host/rvvi +incdir+${IMPERAS_HOME}/ImpPublic/include/host +define+INCLUDE_TRACE2COV +define+COVER_BASE_RV64I +define+COVER_LEVEL_DV_PR_EXT +define+COVER_RV64I +define+COVER_RV64C +define+COVER_RV64M +incdir+${IMPERAS_HOME}/ImpProprietary/include/host +incdir+${IMPERAS_HOME}/ImpProprietary/source/host/riscvISACOV/source" +SIMFILES="${IMPERAS_HOME}/ImpPublic/source/host/rvvi/rvviApiPkg.sv ${IMPERAS_HOME}/ImpPublic/source/host/rvvi/rvviTrace.sv ${IMPERAS_HOME}/ImpProprietary/source/host/idv/idvApiPkg.sv ${IMPERAS_HOME}/ImpProprietary/source/host/idv/idvPkg.sv ${IMPERAS_HOME}/ImpProprietary/source/host/idv/idvApiPkg.sv ${IMPERAS_HOME}/ImpProprietary/source/host/idv/trace2api.sv ${IMPERAS_HOME}/ImpProprietary/source/host/idv/trace2log.sv ${IMPERAS_HOME}/ImpProprietary/source/host/idv/trace2bin.sv ../src/cvw.sv ../testbench/testbench.sv ../src/*/*.sv ../src/*/*/*.sv ../testbench/common/*.sv" + +# Function to clean up generated files +clean() { + rm -rf obj_dir work transcript vsim.wlf *.vcd csrc ucli.key vc_hdrs.h program.out + rm -rf simv* *.daidir dve *.vpd *.dump DVEfiles/ verdi* novas* *fsdb* *.vg *.rep *.db *.chk *.log *.out profileReport* simprofile_dir* +} + +# Clean up before running +clean + +# Command to run Xcelium (xrun) simulation +xrun -sv -uvm -access +rwc -timescale 1ns/1ns +define+TEST=$TESTSUITE $SOURCE_PATH $SIMFILES -R | tee program.out + +# Check for errors in command execution +if [ $? -ne 0 ]; then + echo "Error: Xcelium (xrun) simulation failed." + exit 1 +else + echo "Xcelium (xrun) simulation completed successfully." +fi + diff --git a/sim/wally.do b/sim/wally.do index 4c1a22074e..430146d395 100644 --- a/sim/wally.do +++ b/sim/wally.do @@ -33,7 +33,7 @@ vlib work # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { - vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 + vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/deriv/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 # start and run simulation vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -G NO_SPOOFING=0 -o testbenchopt vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7 @@ -47,7 +47,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { exec ./slack-notifier/slack-notifier.py } elseif {$2 eq "buildroot-no-trace"} { - vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 + vlog -lint -work work_${1}_${2} +incdir+../config/deriv/$1 +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 # start and run simulation vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=0 -G INSTR_WAVEON=0 -G CHECKPOINT=0 -G NO_SPOOFING=1 -o testbenchopt vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7 @@ -68,7 +68,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { } elseif {$2 eq "fpga"} { echo "hello" - vlog -work work +incdir+../config/fpga +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/sdc/*.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv ../../fpga/sim/*.sv -suppress 8852,12070,3084,3829,2583,7063,13286 + vlog -work work +incdir+../config/fpga +incdir+../config/deriv/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/sdc/*.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv ../../fpga/sim/*.sv -suppress 8852,12070,3084,3829,2583,7063,13286 vopt +acc work.testbench -G TEST=$2 -G DEBUG=0 -o workopt vsim workopt +nowarn3829 -fatal 7 @@ -77,7 +77,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { run 20 ms } else { - vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063 + vlog +incdir+../config/$1 +incdir+../config/deriv/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063 vopt +acc work.testbench -G TEST=$2 -G DEBUG=1 -o workopt vsim workopt +nowarn3829 -fatal 7 @@ -103,7 +103,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { #elseif {$2 eq "buildroot-no-trace""} { -# vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 +# vlog -lint -work work_${1}_${2} +incdir+../config/deriv/$1 +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 # start and run simulation # vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=470350800 -G INSTR_WAVEON=470350800 -G CHECKPOINT=470350800 -G DEBUG_TRACE=0 -o testbenchopt # vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829 diff --git a/site-setup.csh b/site-setup.csh new file mode 100644 index 0000000000..d2a52e7201 --- /dev/null +++ b/site-setup.csh @@ -0,0 +1,46 @@ +#!/bin/csh + +# site-setup.csh + +# License servers and commercial CAD tool paths +# Must edit these based on your local environment. Ask your sysadmin. +setenv MGLS_LICENSE_FILE 27002@zircon.eng.hmc.edu # Change this to your Siemens license server +setenv SNPSLMD_LICENSE_FILE 27020@zircon.eng.hmc.edu # Change this to your Synopsys license server +setenv QUESTAPATH /cad/mentor/questa_sim-2022.4_2/questasim/bin # Change this for your path to Questa +setenv SNPSPATH /cad/synopsys/SYN/bin # Change this for your path to Design Compiler + +# Tools +# Questa and Synopsys +extend PATH $QUESTAPATH +extend PATH $SNPSPATH + +# GCC +prepend LD_LIBRARY_PATH $RISCV/riscv-gnu-toolchain/lib +prepend LD_LIBRARY_PATH $RISCV/riscv-gnu-toolchain/riscv64-unknown-elf/lib +extend PATH $RISCV/riscv-gnu-toolchain/bin # GCC tools +extend PATH $RISCV/riscv-gnu-toolchain/riscv64-unknown-elf/bin # GCC tools + +# Spike +extend LD_LIBRARY_PATH $RISCV/lib +extend PATH $RISCV/bin + +# Verilator +extend PATH /usr/local/bin/verilator # Change this for your path to Verilator +# Verilator needs a larger stack to simulate CORE-V Wally +limit stacksize unlimited + +# Imperas; put this in if you are using it +#set path = ($RISCV/imperas-riscv-tests/riscv-ovpsim-plus/bin/Linux64 $path) +#setenv LD_LIBRARY_PATH $RISCV/imperas_riscv_tests/riscv-ovpsim-plus/bin/Linux64:$LD_LIBRARY_PATH # remove if no imperas + +setenv IDV $RISCV/ImperasDV-OpenHW +if ($?IDV) then +# echo "Imperas exists" + setenv IMPERAS_HOME $IDV/Imperas + setenv IMPERAS_PERSONALITY CPUMAN_DV_ASYNC + setenv ROOTDIR ~/ + source ${IMPERAS_HOME}/bin/setup.sh + setupImperas ${IMPERAS_HOME} + extend PATH $IDV/scripts/cvw +endfi + diff --git a/site-setup.sh b/site-setup.sh new file mode 100755 index 0000000000..cf28a93f1f --- /dev/null +++ b/site-setup.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# site-setup.sh +# David_Harris@hmc.edu and kekim@hmc.edu 1 December 2021 +# System Admin should install this into $RISCV/site-setup.sh +# $RISCV is typically /opt/riscv +# System Admin must update the licenses and paths for localization. +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +# license servers and commercial CAD tool paths +# Must edit these based on your local environment. +export MGLS_LICENSE_FILE=27002@zircon.eng.hmc.edu # Change this to your Siemens license server for Questa +export SNPSLMD_LICENSE_FILE=27020@zircon.eng.hmc.edu # Change this to your Synopsys license server for Design Compiler +export QUESTA_HOME=/cad/mentor/questa_sim-2023.4/questasim # Change this for your path to Questa, excluding bin +export SNPS_HOME=/cad/synopsys/SYN # Change this for your path to Design Compiler, excluding bin + +# Tools +# Questa and Synopsys +export PATH=$QUESTA_HOME/bin:$SNPS_HOME/bin:$PATH + +# GCC +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RISCV/riscv-gnu-toolchain/lib:$RISCV/riscv-gnu-toolchain/riscv64-unknown-elf/lib +export PATH=$PATH:$RISCV/riscv-gnu-toolchain/bin:$RISCV/riscv-gnu-toolchain/riscv64-unknown-elf/bin # GCC tools + +# Spike +export LD_LIBRARY_PATH=$RISCV/lib:$LD_LIBRARY_PATH +export PATH=$PATH:$RISCV/bin + +# Verilator +export PATH=/usr/local/bin/verilator:$PATH # Change this for your path to Verilator + +# Imperas OVPsim; put this in if you are using it +#export PATH=$RISCV/imperas-riscv-tests/riscv-ovpsim-plus/bin/Linux64:$PATH +#export LD_LIBRARY_PATH=$RISCV/imperas_riscv_tests/riscv-ovpsim-plus/bin/Linux64:$LD_LIBRARY_PATH + +export IDV=$RISCV/ImperasDV-OpenHW +if [ -e "$IDV" ]; then +# echo "Imperas exists" + export IMPERAS_HOME=$IDV/Imperas + export IMPERAS_PERSONALITY=CPUMAN_DV_ASYNC + export ROOTDIR=~/ + source ${IMPERAS_HOME}/bin/setup.sh + setupImperas ${IMPERAS_HOME} + export PATH=$IDV/scripts/cvw:$PATH +fi + diff --git a/src/cvw.sv b/src/cvw.sv index 75f83f68b8..21b55c55e5 100644 --- a/src/cvw.sv +++ b/src/cvw.sv @@ -180,6 +180,15 @@ typedef struct packed { logic ZCD_SUPPORTED; logic ZCF_SUPPORTED; +// Cryptography + logic ZBKB_SUPPORTED; + logic ZBKC_SUPPORTED; + logic ZBKX_SUPPORTED; + logic ZKND_SUPPORTED; + logic ZKNE_SUPPORTED; + logic ZKNH_SUPPORTED; + logic ZK_SUPPORTED; + // Memory synthesis configuration logic USE_SRAM; @@ -214,6 +223,7 @@ typedef struct packed { logic E_SUPPORTED; logic F_SUPPORTED; logic I_SUPPORTED; + logic K_SUPPORTED; logic M_SUPPORTED; logic Q_SUPPORTED; logic S_SUPPORTED; diff --git a/src/fpu/fdivsqrt/fdivsqrt.sv b/src/fpu/fdivsqrt/fdivsqrt.sv index 85a1a54942..1d44cef5d3 100644 --- a/src/fpu/fdivsqrt/fdivsqrt.sv +++ b/src/fpu/fdivsqrt/fdivsqrt.sv @@ -41,14 +41,14 @@ module fdivsqrt import cvw::*; #(parameter cvw_t P) ( input logic StallM, input logic FlushE, input logic SqrtE, SqrtM, - input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // these are the src outputs before the mux choosing between them and PCE to put in srcA/B + input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // these are the src A/B outputs before the mux choosing between them and PCE to put in srcA/B input logic [2:0] Funct3E, Funct3M, input logic IntDivE, W64E, output logic DivStickyM, output logic FDivBusyE, IFDivStartE, FDivDoneE, output logic [P.NE+1:0] UeM, // Exponent result output logic [P.DIVb:0] UmM, // Significand result - output logic [P.XLEN-1:0] FIntDivResultM + output logic [P.XLEN-1:0] FIntDivResultM // Integer division result (IntDivResult in figure) ); // Floating-point division and square root module, with optional integer division and remainder diff --git a/src/fpu/fdivsqrt/fdivsqrtuotfc2.sv b/src/fpu/fdivsqrt/fdivsqrtuotfc2.sv index 032bb700eb..55810665b8 100644 --- a/src/fpu/fdivsqrt/fdivsqrtuotfc2.sv +++ b/src/fpu/fdivsqrt/fdivsqrtuotfc2.sv @@ -33,7 +33,7 @@ module fdivsqrtuotfc2 import cvw::*; #(parameter cvw_t P) ( input logic up, un, input logic [P.DIVb+1:0] C, // Q2.DIVb - input logic [P.DIVb:0] U, UM, // U1.DIVb + input logic [P.DIVb:0] U, UM, // U1.DIVb UM is actually U - 1 ulp and starts negative, but this representation still produces the right answer output logic [P.DIVb:0] UNext, UMNext // U1.DIVb ); // The on-the-fly converter transfers the divsqrt diff --git a/src/fpu/fdivsqrt/fdivsqrtuotfc4.sv b/src/fpu/fdivsqrt/fdivsqrtuotfc4.sv index 19e322013e..5a802934eb 100644 --- a/src/fpu/fdivsqrt/fdivsqrtuotfc4.sv +++ b/src/fpu/fdivsqrt/fdivsqrtuotfc4.sv @@ -29,7 +29,7 @@ module fdivsqrtuotfc4 import cvw::*; #(parameter cvw_t P) ( input logic [3:0] udigit, - input logic [P.DIVb:0] U, UM, // U1.DIVb + input logic [P.DIVb:0] U, UM, // U1.DIVb UM is actually U - 1 ulp and starts negative, but this representation still produces the right answer input logic [P.DIVb:0] C, // Q1.DIVb output logic [P.DIVb:0] UNext, UMNext // U1.DIVb ); diff --git a/src/fpu/fdivsqrt/fdivsqrtuslc4cmp.sv b/src/fpu/fdivsqrt/fdivsqrtuslc4cmp.sv index fef26668c3..fd1092497e 100644 --- a/src/fpu/fdivsqrt/fdivsqrtuslc4cmp.sv +++ b/src/fpu/fdivsqrt/fdivsqrtuslc4cmp.sv @@ -48,10 +48,10 @@ module fdivsqrtuslc4cmp ( logic [6:0] mk2, mk1, mk0, mkm1; logic [6:0] mkj2, mkj1, mkj0, mkjm1; - logic [6:0] mks2[7:0], mks1[7:0]; + logic [6:0] mks2[7:0], mks1[7:0], mks0[7:0], mksm1[7:0]; logic sqrtspecial; - // Prepopulate table of mks0 + // Prepopulate table of mks for comparison assign mks2[0] = 12; assign mks2[1] = 14; assign mks2[2] = 16; @@ -68,6 +68,24 @@ module fdivsqrtuslc4cmp ( assign mks1[5] = 8; // is the logic any cheaper if this is a 6? assign mks1[6] = 8; assign mks1[7] = 8; + + assign mks0[0] = -4; + assign mks0[1] = -4; + assign mks0[2] = -6; + assign mks0[3] = -6; + assign mks0[4] = -6; + assign mks0[5] = -8; + assign mks0[6] = -8; + assign mks0[7] = -8; + assign mksm1[0] = -13; + assign mksm1[1] = -14; + assign mksm1[2] = -16; + assign mksm1[3] = -17; + assign mksm1[4] = -18; + assign mksm1[5] = -20; + assign mksm1[6] = -22; + assign mksm1[7] = -23; + // handles special case when j = 0 or j = 1 for sqrt assign mkj2 = 20; // when j = 1 use mk2[101] when j = 0 use anything bigger than 7. @@ -85,8 +103,13 @@ module fdivsqrtuslc4cmp ( assign mk2 = sqrtspecial ? mkj2 : mks2[A]; assign mk1 = sqrtspecial ? mkj1 : mks1[A]; + assign mk0 = sqrtspecial ? -mkj1 : mks0[A]; + assign mkm1 = sqrtspecial ? -mkj2 : mksm1[A]; + +/* Nannarelli12 design to exploit symmetry is slower because of negation and mux for special case of A = 000 assign mk0 = -mk1; assign mkm1 = (A == 3'b000) ? -13 : -mk2; // asymmetry in table *** can we hide from critical path + */ // Compare residual W to selection constants to choose digit always_comb diff --git a/src/fpu/postproc/specialcase.sv b/src/fpu/postproc/specialcase.sv index e3a1466feb..e9ba573e1a 100644 --- a/src/fpu/postproc/specialcase.sv +++ b/src/fpu/postproc/specialcase.sv @@ -305,7 +305,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) ( // signed | 2^31-1 | 2^63-1 | // unsigned | 2^32-1 | 2^64-1 | // - // other: 32 bit unsinged res should be sign extended as if it were a signed number + // other: 32 bit unsigned res should be sign extended as if it were a signed number if(P.IEEE754) begin always_comb @@ -343,7 +343,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) ( else OfIntRes2 = OfIntRes; if (Zfa) Int64Res = {{(P.XLEN-32){CvtNegRes[P.XLEN-1]}}, CvtNegRes[31:0]}; else Int64Res = CvtNegRes[P.XLEN-1:0]; - if (Zfa) SelCvtOfRes = InfIn | NaNIn | (CvtCe > 32 + 52); // fcvtmod.w.d only overflows to 0 on NaN or Infinity, or if the shift is so large that only zeros are left + if (Zfa) SelCvtOfRes = InfIn | NaNIn | (CvtCe > 32 + 52); // fcvtmod.w.d only overflows to 0 on NaN or Infinity, or if the shift is so large that only zeros are left else SelCvtOfRes = IntInvalid; // regular fcvt gives an overflow if out of range end else diff --git a/src/generic/mux.sv b/src/generic/mux.sv index 5a4767c87e..f07efeb5ca 100644 --- a/src/generic/mux.sv +++ b/src/generic/mux.sv @@ -65,6 +65,15 @@ module mux6 #(parameter WIDTH = 8) ( output logic [WIDTH-1:0] y); assign y = s[2] ? (s[0] ? d5 : d4) : (s[1] ? (s[0] ? d3 : d2) : (s[0] ? d1 : d0)); +endmodule // mux6 + +module mux7 #(parameter WIDTH = 8) ( + input logic [WIDTH-1:0] d0, d1, d2, d3, d4, d5, d6, + input logic [2:0] s, + output logic [WIDTH-1:0] y); + + assign y = s[2] ? (s[1] ? d6 : (s[0] ? d5 : d4)) : (s[1] ? (s[0] ? d3 : d2) : (s[0] ? d1 : d0)); + endmodule /* verilator lint_on DECLFILENAME */ diff --git a/src/ieu/aes/aes32d.sv b/src/ieu/aes/aes32d.sv new file mode 100644 index 0000000000..95b75fc80f --- /dev/null +++ b/src/ieu/aes/aes32d.sv @@ -0,0 +1,41 @@ +/////////////////////////////////////////// +// aes32d.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: aes32dsmi and aes32dsi instruction: RV32 middle and final round AES decryption +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module aes32d( + input logic [7:0] SboxIn, + input logic finalround, + output logic [31:0] result +); + + logic [7:0] SboxOut; + logic [31:0] so, mixed; + + aesinvsbox inv_sbox(SboxIn, SboxOut); // Apply inverse sbox to si + assign so = {24'h0, SboxOut}; // Pad output of inverse substitution box + aesinvmixcolumns mix(so, mixed); // Run so through the mixword AES function + mux2 #(32) rmux(mixed, so, finalround, result); // on final round, skip mixcolumns +endmodule diff --git a/src/ieu/aes/aes32e.sv b/src/ieu/aes/aes32e.sv new file mode 100644 index 0000000000..969f8a25fc --- /dev/null +++ b/src/ieu/aes/aes32e.sv @@ -0,0 +1,41 @@ +/////////////////////////////////////////// +// aes32e.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: aes32esmi and aes32esi instruction: RV32 middle and final round AES encryption +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module aes32e( + input logic [7:0] SboxIn, + input logic finalround, + output logic [31:0] result +); + + logic [7:0] SboxOut; + logic [31:0] so, mixed; + + aessbox sbox(SboxIn, SboxOut); // Substitute + assign so = {24'h0, SboxOut}; // Pad sbox output + aesmixcolumns mwd(so, mixed); // Mix Word using aesmixword component + mux2 #(32) rmux(mixed, so, finalround, result); // on final round, skip mixcolumns +endmodule diff --git a/src/ieu/aes/aes64d.sv b/src/ieu/aes/aes64d.sv new file mode 100644 index 0000000000..6f6fc172f2 --- /dev/null +++ b/src/ieu/aes/aes64d.sv @@ -0,0 +1,53 @@ +/////////////////////////////////////////// +// aes64d.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: aes64dsm and aes64ds instruction: RV64 middle and final round AES decryption +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module aes64d( + input logic [63:0] rs1, + input logic [63:0] rs2, + input logic finalround, aes64im, + output logic [63:0] result +); + + logic [127:0] ShiftRowOut; + logic [63:0] SboxOut, MixcolIn, MixcolOut; + + // Apply inverse shiftrows to rs2 and rs1 + aesinvshiftrow srow({rs2, rs1}, ShiftRowOut); + + // Apply full word inverse substitution to lower 2 words of shiftrow out + aesinvsboxword invsbox0(ShiftRowOut[31:0], SboxOut[31:0]); + aesinvsboxword invsbox1(ShiftRowOut[63:32], SboxOut[63:32]); + + mux2 #(64) mixcolmux(SboxOut, rs1, aes64im, MixcolIn); + + // Apply inverse mixword to sbox outputs + aesinvmixcolumns invmw0(MixcolIn[31:0], MixcolOut[31:0]); + aesinvmixcolumns invmw1(MixcolIn[63:32], MixcolOut[63:32]); + + // Final round skips mixcolumns. + mux2 #(64) resultmux(MixcolOut, SboxOut, finalround, result); +endmodule diff --git a/src/ieu/aes/aes64e.sv b/src/ieu/aes/aes64e.sv new file mode 100644 index 0000000000..98a18fa235 --- /dev/null +++ b/src/ieu/aes/aes64e.sv @@ -0,0 +1,56 @@ +/////////////////////////////////////////// +// aes64e.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: aes64esm and aes64es instruction: RV64 middle and final round AES encryption +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module aes64e( + input logic [63:0] rs1, + input logic [63:0] rs2, + input logic finalround, + input logic [31:0] Sbox0Out, + output logic [31:0] SboxEIn, + output logic [63:0] result +); + + logic [127:0] ShiftRowOut; + logic [63:0] SboxOut, MixcolOut; + + // AES shiftrow unit + aesshiftrow srow({rs2,rs1}, ShiftRowOut); + + // Apply substitution box to 2 lower words + // Use the shared sbox in zknde64.sv for the first sbox + assign SboxEIn = ShiftRowOut[31:0]; + assign SboxOut[31:0] = Sbox0Out; + + aessboxword sbox1(ShiftRowOut[63:32], SboxOut[63:32]); // instantiate second sbox + + // Apply mix columns operations + aesmixcolumns mw0(SboxOut[31:0], MixcolOut[31:0]); + aesmixcolumns mw1(SboxOut[63:32], MixcolOut[63:32]); + + // Skip mixcolumns on last round + mux2 #(64) resultmux(MixcolOut, SboxOut, finalround, result); +endmodule diff --git a/src/ieu/aes/aes64ks1i.sv b/src/ieu/aes/aes64ks1i.sv new file mode 100644 index 0000000000..ef36e1cc69 --- /dev/null +++ b/src/ieu/aes/aes64ks1i.sv @@ -0,0 +1,52 @@ +/////////////////////////////////////////// +// aes64ks1i.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: aes64ks1i instruction: part of AES keyschedule with involving sbox +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module aes64ks1i( + input logic [3:0] round, + input logic [63:0] rs1, + input logic [31:0] Sbox0Out, + output logic [31:0] SboxKIn, + output logic [63:0] result +); + + logic finalround; + logic [7:0] rcon8; + logic [31:0] rcon, rs1Rotate; + + rconlut128 rc(round, rcon8); // Get rcon value from lookup table + assign rcon = {24'b0, rcon8}; // Zero-pad RCON + assign rs1Rotate = {rs1[39:32], rs1[63:40]}; // Get rotated value fo ruse in tmp2 + assign finalround = (round == 4'b1010); // round 10 is the last one + assign SboxKIn = finalround ? rs1[63:32] : rs1Rotate; // Don't rotate on the last round + + // Share sbox with encryption in zknde64. This module just sends value to shared sbox and gets result back + // send out value as SboxKIn, get back subsittuted result as Sbox0Out + + assign result[31:0] = Sbox0Out ^ rcon; + assign result[63:32] = Sbox0Out ^ rcon; +endmodule + diff --git a/src/ieu/aes/aes64ks2.sv b/src/ieu/aes/aes64ks2.sv new file mode 100644 index 0000000000..dac9ed50df --- /dev/null +++ b/src/ieu/aes/aes64ks2.sv @@ -0,0 +1,39 @@ +/////////////////////////////////////////// +// aes64ks2.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: aes64ks2 instruction: part of AES keyschedule +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module aes64ks2( + input logic [63:0] rs2, + input logic [63:0] rs1, + output logic [63:0] result +); + + logic [31:0] w0, w1; + + assign w0 = rs1[63:32] ^ rs2[31:0]; + assign w1 = w0 ^ rs2[63:32]; + assign result = {w1, w0}; +endmodule diff --git a/src/ieu/aes/aesinvmixcolumns.sv b/src/ieu/aes/aesinvmixcolumns.sv new file mode 100644 index 0000000000..5ef6b2e9c1 --- /dev/null +++ b/src/ieu/aes/aesinvmixcolumns.sv @@ -0,0 +1,48 @@ +/////////////////////////////////////////// +// aesinvmixcolumns.sv +// +// Written: kelvin.tran@okstate.edu, james.stine@okstate.edu +// Created: 05 March 2024 +// +// Purpose: AES Inverted Mix Column Function for use with AES +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module aesinvmixcolumns( + input logic [31:0] a, + output logic [31:0] y +); + + logic [7:0] a0, a1, a2, a3, temp; + logic [10:0] xor0, xor1, xor2, xor3; + + assign {a0, a1, a2, a3} = a; + assign temp = a0 ^ a1 ^ a2 ^ a3; + + assign xor0 = {temp, 3'b0} ^ {1'b0, a3^a1, 2'b0} ^ {2'b0, a3^a2, 1'b0} ^ {3'b0, temp} ^ {3'b0, a3}; + assign xor1 = {temp, 3'b0} ^ {1'b0, a2^a0, 2'b0} ^ {2'b0, a2^a1, 1'b0} ^ {3'b0, temp} ^ {3'b0, a2}; + assign xor2 = {temp, 3'b0} ^ {1'b0, a1^a3, 2'b0} ^ {2'b0, a1^a0, 1'b0} ^ {3'b0, temp} ^ {3'b0, a1}; + assign xor3 = {temp, 3'b0} ^ {1'b0, a0^a2, 2'b0} ^ {2'b0, a0^a3, 1'b0} ^ {3'b0, temp} ^ {3'b0, a0}; + + galoismultinverse gm0 (xor0, y[7:0]); + galoismultinverse gm1 (xor1, y[15:8]); + galoismultinverse gm2 (xor2, y[23:16]); + galoismultinverse gm3 (xor3, y[31:24]); +endmodule diff --git a/src/ieu/aes/aesinvsbox.sv b/src/ieu/aes/aesinvsbox.sv new file mode 100644 index 0000000000..3d62e30f2f --- /dev/null +++ b/src/ieu/aes/aesinvsbox.sv @@ -0,0 +1,292 @@ +/////////////////////////////////////////// +// aesinvsbox.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: Rinjdael Inverted S-BOX in form of a LUT +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module aesinvsbox( + input logic [7:0] a, + output logic [7:0] y +); + + always_comb + case(a) + 8'h00 : y = 8'h52; + 8'h01 : y = 8'h09; + 8'h02 : y = 8'h6A; + 8'h03 : y = 8'hD5; + 8'h04 : y = 8'h30; + 8'h05 : y = 8'h36; + 8'h06 : y = 8'hA5; + 8'h07 : y = 8'h38; + 8'h08 : y = 8'hBF; + 8'h09 : y = 8'h40; + 8'h0A : y = 8'hA3; + 8'h0B : y = 8'h9E; + 8'h0C : y = 8'h81; + 8'h0D : y = 8'hF3; + 8'h0E : y = 8'hD7; + 8'h0F : y = 8'hFB; + 8'h10 : y = 8'h7C; + 8'h11 : y = 8'hE3; + 8'h12 : y = 8'h39; + 8'h13 : y = 8'h82; + 8'h14 : y = 8'h9B; + 8'h15 : y = 8'h2F; + 8'h16 : y = 8'hFF; + 8'h17 : y = 8'h87; + 8'h18 : y = 8'h34; + 8'h19 : y = 8'h8E; + 8'h1A : y = 8'h43; + 8'h1B : y = 8'h44; + 8'h1C : y = 8'hC4; + 8'h1D : y = 8'hDE; + 8'h1E : y = 8'hE9; + 8'h1F : y = 8'hCB; + 8'h20 : y = 8'h54; + 8'h21 : y = 8'h7B; + 8'h22 : y = 8'h94; + 8'h23 : y = 8'h32; + 8'h24 : y = 8'hA6; + 8'h25 : y = 8'hC2; + 8'h26 : y = 8'h23; + 8'h27 : y = 8'h3D; + 8'h28 : y = 8'hEE; + 8'h29 : y = 8'h4C; + 8'h2A : y = 8'h95; + 8'h2B : y = 8'h0B; + 8'h2C : y = 8'h42; + 8'h2D : y = 8'hFA; + 8'h2E : y = 8'hC3; + 8'h2F : y = 8'h4E; + 8'h30 : y = 8'h08; + 8'h31 : y = 8'h2E; + 8'h32 : y = 8'hA1; + 8'h33 : y = 8'h66; + 8'h34 : y = 8'h28; + 8'h35 : y = 8'hD9; + 8'h36 : y = 8'h24; + 8'h37 : y = 8'hB2; + 8'h38 : y = 8'h76; + 8'h39 : y = 8'h5B; + 8'h3A : y = 8'hA2; + 8'h3B : y = 8'h49; + 8'h3C : y = 8'h6D; + 8'h3D : y = 8'h8B; + 8'h3E : y = 8'hD1; + 8'h3F : y = 8'h25; + 8'h40 : y = 8'h72; + 8'h41 : y = 8'hF8; + 8'h42 : y = 8'hF6; + 8'h43 : y = 8'h64; + 8'h44 : y = 8'h86; + 8'h45 : y = 8'h68; + 8'h46 : y = 8'h98; + 8'h47 : y = 8'h16; + 8'h48 : y = 8'hD4; + 8'h49 : y = 8'hA4; + 8'h4A : y = 8'h5C; + 8'h4B : y = 8'hCC; + 8'h4C : y = 8'h5D; + 8'h4D : y = 8'h65; + 8'h4E : y = 8'hB6; + 8'h4F : y = 8'h92; + 8'h50 : y = 8'h6C; + 8'h51 : y = 8'h70; + 8'h52 : y = 8'h48; + 8'h53 : y = 8'h50; + 8'h54 : y = 8'hFD; + 8'h55 : y = 8'hED; + 8'h56 : y = 8'hB9; + 8'h57 : y = 8'hDA; + 8'h58 : y = 8'h5E; + 8'h59 : y = 8'h15; + 8'h5A : y = 8'h46; + 8'h5B : y = 8'h57; + 8'h5C : y = 8'hA7; + 8'h5D : y = 8'h8D; + 8'h5E : y = 8'h9D; + 8'h5F : y = 8'h84; + 8'h60 : y = 8'h90; + 8'h61 : y = 8'hD8; + 8'h62 : y = 8'hAB; + 8'h63 : y = 8'h00; + 8'h64 : y = 8'h8C; + 8'h65 : y = 8'hBC; + 8'h66 : y = 8'hD3; + 8'h67 : y = 8'h0A; + 8'h68 : y = 8'hF7; + 8'h69 : y = 8'hE4; + 8'h6A : y = 8'h58; + 8'h6B : y = 8'h05; + 8'h6C : y = 8'hB8; + 8'h6D : y = 8'hB3; + 8'h6E : y = 8'h45; + 8'h6F : y = 8'h06; + 8'h70 : y = 8'hD0; + 8'h71 : y = 8'h2C; + 8'h72 : y = 8'h1E; + 8'h73 : y = 8'h8F; + 8'h74 : y = 8'hCA; + 8'h75 : y = 8'h3F; + 8'h76 : y = 8'h0F; + 8'h77 : y = 8'h02; + 8'h78 : y = 8'hC1; + 8'h79 : y = 8'hAF; + 8'h7A : y = 8'hBD; + 8'h7B : y = 8'h03; + 8'h7C : y = 8'h01; + 8'h7D : y = 8'h13; + 8'h7E : y = 8'h8A; + 8'h7F : y = 8'h6B; + 8'h80 : y = 8'h3A; + 8'h81 : y = 8'h91; + 8'h82 : y = 8'h11; + 8'h83 : y = 8'h41; + 8'h84 : y = 8'h4F; + 8'h85 : y = 8'h67; + 8'h86 : y = 8'hDC; + 8'h87 : y = 8'hEA; + 8'h88 : y = 8'h97; + 8'h89 : y = 8'hF2; + 8'h8A : y = 8'hCF; + 8'h8B : y = 8'hCE; + 8'h8C : y = 8'hF0; + 8'h8D : y = 8'hB4; + 8'h8E : y = 8'hE6; + 8'h8F : y = 8'h73; + 8'h90 : y = 8'h96; + 8'h91 : y = 8'hAC; + 8'h92 : y = 8'h74; + 8'h93 : y = 8'h22; + 8'h94 : y = 8'hE7; + 8'h95 : y = 8'hAD; + 8'h96 : y = 8'h35; + 8'h97 : y = 8'h85; + 8'h98 : y = 8'hE2; + 8'h99 : y = 8'hF9; + 8'h9A : y = 8'h37; + 8'h9B : y = 8'hE8; + 8'h9C : y = 8'h1C; + 8'h9D : y = 8'h75; + 8'h9E : y = 8'hDF; + 8'h9F : y = 8'h6E; + 8'hA0 : y = 8'h47; + 8'hA1 : y = 8'hF1; + 8'hA2 : y = 8'h1A; + 8'hA3 : y = 8'h71; + 8'hA4 : y = 8'h1D; + 8'hA5 : y = 8'h29; + 8'hA6 : y = 8'hC5; + 8'hA7 : y = 8'h89; + 8'hA8 : y = 8'h6F; + 8'hA9 : y = 8'hB7; + 8'hAA : y = 8'h62; + 8'hAB : y = 8'h0E; + 8'hAC : y = 8'hAA; + 8'hAD : y = 8'h18; + 8'hAE : y = 8'hBE; + 8'hAF : y = 8'h1B; + 8'hB0 : y = 8'hFC; + 8'hB1 : y = 8'h56; + 8'hB2 : y = 8'h3E; + 8'hB3 : y = 8'h4B; + 8'hB4 : y = 8'hC6; + 8'hB5 : y = 8'hD2; + 8'hB6 : y = 8'h79; + 8'hB7 : y = 8'h20; + 8'hB8 : y = 8'h9A; + 8'hB9 : y = 8'hDB; + 8'hBA : y = 8'hC0; + 8'hBB : y = 8'hFE; + 8'hBC : y = 8'h78; + 8'hBD : y = 8'hCD; + 8'hBE : y = 8'h5A; + 8'hBF : y = 8'hF4; + 8'hC0 : y = 8'h1F; + 8'hC1 : y = 8'hDD; + 8'hC2 : y = 8'hA8; + 8'hC3 : y = 8'h33; + 8'hC4 : y = 8'h88; + 8'hC5 : y = 8'h07; + 8'hC6 : y = 8'hC7; + 8'hC7 : y = 8'h31; + 8'hC8 : y = 8'hB1; + 8'hC9 : y = 8'h12; + 8'hCA : y = 8'h10; + 8'hCB : y = 8'h59; + 8'hCC : y = 8'h27; + 8'hCD : y = 8'h80; + 8'hCE : y = 8'hEC; + 8'hCF : y = 8'h5F; + 8'hD0 : y = 8'h60; + 8'hD1 : y = 8'h51; + 8'hD2 : y = 8'h7F; + 8'hD3 : y = 8'hA9; + 8'hD4 : y = 8'h19; + 8'hD5 : y = 8'hB5; + 8'hD6 : y = 8'h4A; + 8'hD7 : y = 8'h0D; + 8'hD8 : y = 8'h2D; + 8'hD9 : y = 8'hE5; + 8'hDA : y = 8'h7A; + 8'hDB : y = 8'h9F; + 8'hDC : y = 8'h93; + 8'hDD : y = 8'hC9; + 8'hDE : y = 8'h9C; + 8'hDF : y = 8'hEF; + 8'hE0 : y = 8'hA0; + 8'hE1 : y = 8'hE0; + 8'hE2 : y = 8'h3B; + 8'hE3 : y = 8'h4D; + 8'hE4 : y = 8'hAE; + 8'hE5 : y = 8'h2A; + 8'hE6 : y = 8'hF5; + 8'hE7 : y = 8'hB0; + 8'hE8 : y = 8'hC8; + 8'hE9 : y = 8'hEB; + 8'hEA : y = 8'hBB; + 8'hEB : y = 8'h3C; + 8'hEC : y = 8'h83; + 8'hED : y = 8'h53; + 8'hEE : y = 8'h99; + 8'hEF : y = 8'h61; + 8'hF0 : y = 8'h17; + 8'hF1 : y = 8'h2B; + 8'hF2 : y = 8'h04; + 8'hF3 : y = 8'h7E; + 8'hF4 : y = 8'hBA; + 8'hF5 : y = 8'h77; + 8'hF6 : y = 8'hD6; + 8'hF7 : y = 8'h26; + 8'hF8 : y = 8'hE1; + 8'hF9 : y = 8'h69; + 8'hFA : y = 8'h14; + 8'hFB : y = 8'h63; + 8'hFC : y = 8'h55; + 8'hFD : y = 8'h21; + 8'hFE : y = 8'h0C; + 8'hFF : y = 8'h7D; + endcase +endmodule diff --git a/src/ieu/aes/aesinvsboxword.sv b/src/ieu/aes/aesinvsboxword.sv new file mode 100644 index 0000000000..62b969852b --- /dev/null +++ b/src/ieu/aes/aesinvsboxword.sv @@ -0,0 +1,38 @@ +/////////////////////////////////////////// +// aesinvsboxword.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: 4 sets of Rinjdael Inverse S-BOX for whole word look up +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module aesinvsboxword( + input logic [31:0] a, + output logic [31:0] y +); + + // inverse substitutions boxes for each byte of the word + aesinvsbox sboxb0(a[7:0], y[7:0]); + aesinvsbox sboxb1(a[15:8], y[15:8]); + aesinvsbox sboxb2(a[23:16], y[23:16]); + aesinvsbox sboxb3(a[31:24], y[31:24]); +endmodule diff --git a/src/generic/mem/empty.sv b/src/ieu/aes/aesinvshiftrow.sv similarity index 57% rename from src/generic/mem/empty.sv rename to src/ieu/aes/aesinvshiftrow.sv index b6f5c801e4..54b11c82a4 100644 --- a/src/generic/mem/empty.sv +++ b/src/ieu/aes/aesinvshiftrow.sv @@ -1,15 +1,15 @@ /////////////////////////////////////////// -// ram2p1rwbe_128x64.sv +// aesinvshiftrow.sv // -// Written: Rose Thompon ross1728@gmail.com 06 March 2024 -// Modified: +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: AES Shiftrow // -// Purpose: Empty wrapper for VCS to work. Would really like to not have any of these. -// // A component of the CORE-V-WALLY configurable RISC-V project. // https://github.com/openhwgroup/cvw // -// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University // // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // @@ -25,21 +25,13 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -module TSDN28HPCPA128X64M4FW( - input logic CLKA, - input logic CLKB, - input logic CEBA, - input logic CEBB, - input logic WEBA, - input logic WEBB, - input logic [6:0] AA, - input logic [6:0] AB, - input logic [63:0] DA, - input logic [63:0] DB, - input logic [63:0] BWEBA, - input logic [63:0] BWEBB, - output logic [63:0] QA, - output logic [63:0] QB +module aesinvshiftrow( + input logic [127:0] a, + output logic [127:0] y ); + assign y = {a[31:24], a[55:48], a[79:72], a[103:96], + a[127:120], a[23:16], a[47:40], a[71:64], + a[95:88], a[119:112], a[15:8], a[39:32], + a[63:56], a[87:80], a[111:104], a[7:0]}; endmodule diff --git a/src/ieu/aes/aesmixcolumns.sv b/src/ieu/aes/aesmixcolumns.sv new file mode 100644 index 0000000000..517533f635 --- /dev/null +++ b/src/ieu/aes/aesmixcolumns.sv @@ -0,0 +1,50 @@ +/////////////////////////////////////////// +// aesmixcolumns.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu, David_Harris@hmc.edu +// Created: 20 February 2024 +// +// Purpose: Galois field operation to an individual 32-bit word +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + + +module aesmixcolumns( + input logic [31:0] a, + output logic [31:0] y +); + + logic [7:0] a0, a1, a2, a3, y0, y1, y2, y3, t0, t1, t2, t3, temp; + + assign {a0, a1, a2, a3} = a; + assign temp = a0 ^ a1 ^ a2 ^ a3; + + galoismultforward gm0 (a0^a1, t0); + galoismultforward gm1 (a1^a2, t1); + galoismultforward gm2 (a2^a3, t2); + galoismultforward gm3 (a3^a0, t3); + + assign y0 = a0 ^ temp ^ t3; + assign y1 = a1 ^ temp ^ t0; + assign y2 = a2 ^ temp ^ t1; + assign y3 = a3 ^ temp ^ t2; + + assign y = {y0, y1, y2, y3}; +endmodule diff --git a/src/ieu/aes/aessbox.sv b/src/ieu/aes/aessbox.sv new file mode 100644 index 0000000000..84eb61c4d4 --- /dev/null +++ b/src/ieu/aes/aessbox.sv @@ -0,0 +1,293 @@ +/////////////////////////////////////////// +// aessbox.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: Rinjdael forward S-BOX in the form of a LUT +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module aessbox( + input logic [7:0] a, + output logic [7:0] y +); + + // case statement to lookup the value in the rijndael table + always_comb + case(a) + 8'h00 : y = 8'h63; + 8'h01 : y = 8'h7C; + 8'h02 : y = 8'h77; + 8'h03 : y = 8'h7B; + 8'h04 : y = 8'hF2; + 8'h05 : y = 8'h6B; + 8'h06 : y = 8'h6F; + 8'h07 : y = 8'hC5; + 8'h08 : y = 8'h30; + 8'h09 : y = 8'h01; + 8'h0A : y = 8'h67; + 8'h0B : y = 8'h2B; + 8'h0C : y = 8'hFE; + 8'h0D : y = 8'hD7; + 8'h0E : y = 8'hAB; + 8'h0F : y = 8'h76; + 8'h10 : y = 8'hCA; + 8'h11 : y = 8'h82; + 8'h12 : y = 8'hC9; + 8'h13 : y = 8'h7D; + 8'h14 : y = 8'hFA; + 8'h15 : y = 8'h59; + 8'h16 : y = 8'h47; + 8'h17 : y = 8'hF0; + 8'h18 : y = 8'hAD; + 8'h19 : y = 8'hD4; + 8'h1A : y = 8'hA2; + 8'h1B : y = 8'hAF; + 8'h1C : y = 8'h9C; + 8'h1D : y = 8'hA4; + 8'h1E : y = 8'h72; + 8'h1F : y = 8'hC0; + 8'h20 : y = 8'hB7; + 8'h21 : y = 8'hFD; + 8'h22 : y = 8'h93; + 8'h23 : y = 8'h26; + 8'h24 : y = 8'h36; + 8'h25 : y = 8'h3F; + 8'h26 : y = 8'hF7; + 8'h27 : y = 8'hCC; + 8'h28 : y = 8'h34; + 8'h29 : y = 8'hA5; + 8'h2A : y = 8'hE5; + 8'h2B : y = 8'hF1; + 8'h2C : y = 8'h71; + 8'h2D : y = 8'hD8; + 8'h2E : y = 8'h31; + 8'h2F : y = 8'h15; + 8'h30 : y = 8'h04; + 8'h31 : y = 8'hC7; + 8'h32 : y = 8'h23; + 8'h33 : y = 8'hC3; + 8'h34 : y = 8'h18; + 8'h35 : y = 8'h96; + 8'h36 : y = 8'h05; + 8'h37 : y = 8'h9A; + 8'h38 : y = 8'h07; + 8'h39 : y = 8'h12; + 8'h3A : y = 8'h80; + 8'h3B : y = 8'hE2; + 8'h3C : y = 8'hEB; + 8'h3D : y = 8'h27; + 8'h3E : y = 8'hB2; + 8'h3F : y = 8'h75; + 8'h40 : y = 8'h09; + 8'h41 : y = 8'h83; + 8'h42 : y = 8'h2C; + 8'h43 : y = 8'h1A; + 8'h44 : y = 8'h1B; + 8'h45 : y = 8'h6E; + 8'h46 : y = 8'h5A; + 8'h47 : y = 8'hA0; + 8'h48 : y = 8'h52; + 8'h49 : y = 8'h3B; + 8'h4A : y = 8'hD6; + 8'h4B : y = 8'hB3; + 8'h4C : y = 8'h29; + 8'h4D : y = 8'hE3; + 8'h4E : y = 8'h2F; + 8'h4F : y = 8'h84; + 8'h50 : y = 8'h53; + 8'h51 : y = 8'hD1; + 8'h52 : y = 8'h00; + 8'h53 : y = 8'hED; + 8'h54 : y = 8'h20; + 8'h55 : y = 8'hFC; + 8'h56 : y = 8'hB1; + 8'h57 : y = 8'h5B; + 8'h58 : y = 8'h6A; + 8'h59 : y = 8'hCB; + 8'h5A : y = 8'hBE; + 8'h5B : y = 8'h39; + 8'h5C : y = 8'h4A; + 8'h5D : y = 8'h4C; + 8'h5E : y = 8'h58; + 8'h5F : y = 8'hCF; + 8'h60 : y = 8'hD0; + 8'h61 : y = 8'hEF; + 8'h62 : y = 8'hAA; + 8'h63 : y = 8'hFB; + 8'h64 : y = 8'h43; + 8'h65 : y = 8'h4D; + 8'h66 : y = 8'h33; + 8'h67 : y = 8'h85; + 8'h68 : y = 8'h45; + 8'h69 : y = 8'hF9; + 8'h6A : y = 8'h02; + 8'h6B : y = 8'h7F; + 8'h6C : y = 8'h50; + 8'h6D : y = 8'h3C; + 8'h6E : y = 8'h9F; + 8'h6F : y = 8'hA8; + 8'h70 : y = 8'h51; + 8'h71 : y = 8'hA3; + 8'h72 : y = 8'h40; + 8'h73 : y = 8'h8F; + 8'h74 : y = 8'h92; + 8'h75 : y = 8'h9D; + 8'h76 : y = 8'h38; + 8'h77 : y = 8'hF5; + 8'h78 : y = 8'hBC; + 8'h79 : y = 8'hB6; + 8'h7A : y = 8'hDA; + 8'h7B : y = 8'h21; + 8'h7C : y = 8'h10; + 8'h7D : y = 8'hFF; + 8'h7E : y = 8'hF3; + 8'h7F : y = 8'hD2; + 8'h80 : y = 8'hCD; + 8'h81 : y = 8'h0C; + 8'h82 : y = 8'h13; + 8'h83 : y = 8'hEC; + 8'h84 : y = 8'h5F; + 8'h85 : y = 8'h97; + 8'h86 : y = 8'h44; + 8'h87 : y = 8'h17; + 8'h88 : y = 8'hC4; + 8'h89 : y = 8'hA7; + 8'h8A : y = 8'h7E; + 8'h8B : y = 8'h3D; + 8'h8C : y = 8'h64; + 8'h8D : y = 8'h5D; + 8'h8E : y = 8'h19; + 8'h8F : y = 8'h73; + 8'h90 : y = 8'h60; + 8'h91 : y = 8'h81; + 8'h92 : y = 8'h4F; + 8'h93 : y = 8'hDC; + 8'h94 : y = 8'h22; + 8'h95 : y = 8'h2A; + 8'h96 : y = 8'h90; + 8'h97 : y = 8'h88; + 8'h98 : y = 8'h46; + 8'h99 : y = 8'hEE; + 8'h9A : y = 8'hB8; + 8'h9B : y = 8'h14; + 8'h9C : y = 8'hDE; + 8'h9D : y = 8'h5E; + 8'h9E : y = 8'h0B; + 8'h9F : y = 8'hDB; + 8'hA0 : y = 8'hE0; + 8'hA1 : y = 8'h32; + 8'hA2 : y = 8'h3A; + 8'hA3 : y = 8'h0A; + 8'hA4 : y = 8'h49; + 8'hA5 : y = 8'h06; + 8'hA6 : y = 8'h24; + 8'hA7 : y = 8'h5C; + 8'hA8 : y = 8'hC2; + 8'hA9 : y = 8'hD3; + 8'hAA : y = 8'hAC; + 8'hAB : y = 8'h62; + 8'hAC : y = 8'h91; + 8'hAD : y = 8'h95; + 8'hAE : y = 8'hE4; + 8'hAF : y = 8'h79; + 8'hB0 : y = 8'hE7; + 8'hB1 : y = 8'hC8; + 8'hB2 : y = 8'h37; + 8'hB3 : y = 8'h6D; + 8'hB4 : y = 8'h8D; + 8'hB5 : y = 8'hD5; + 8'hB6 : y = 8'h4E; + 8'hB7 : y = 8'hA9; + 8'hB8 : y = 8'h6C; + 8'hB9 : y = 8'h56; + 8'hBA : y = 8'hF4; + 8'hBB : y = 8'hEA; + 8'hBC : y = 8'h65; + 8'hBD : y = 8'h7A; + 8'hBE : y = 8'hAE; + 8'hBF : y = 8'h08; + 8'hC0 : y = 8'hBA; + 8'hC1 : y = 8'h78; + 8'hC2 : y = 8'h25; + 8'hC3 : y = 8'h2E; + 8'hC4 : y = 8'h1C; + 8'hC5 : y = 8'hA6; + 8'hC6 : y = 8'hB4; + 8'hC7 : y = 8'hC6; + 8'hC8 : y = 8'hE8; + 8'hC9 : y = 8'hDD; + 8'hCA : y = 8'h74; + 8'hCB : y = 8'h1F; + 8'hCC : y = 8'h4B; + 8'hCD : y = 8'hBD; + 8'hCE : y = 8'h8B; + 8'hCF : y = 8'h8A; + 8'hD0 : y = 8'h70; + 8'hD1 : y = 8'h3E; + 8'hD2 : y = 8'hB5; + 8'hD3 : y = 8'h66; + 8'hD4 : y = 8'h48; + 8'hD5 : y = 8'h03; + 8'hD6 : y = 8'hF6; + 8'hD7 : y = 8'h0E; + 8'hD8 : y = 8'h61; + 8'hD9 : y = 8'h35; + 8'hDA : y = 8'h57; + 8'hDB : y = 8'hB9; + 8'hDC : y = 8'h86; + 8'hDD : y = 8'hC1; + 8'hDE : y = 8'h1D; + 8'hDF : y = 8'h9E; + 8'hE0 : y = 8'hE1; + 8'hE1 : y = 8'hF8; + 8'hE2 : y = 8'h98; + 8'hE3 : y = 8'h11; + 8'hE4 : y = 8'h69; + 8'hE5 : y = 8'hD9; + 8'hE6 : y = 8'h8E; + 8'hE7 : y = 8'h94; + 8'hE8 : y = 8'h9B; + 8'hE9 : y = 8'h1E; + 8'hEA : y = 8'h87; + 8'hEB : y = 8'hE9; + 8'hEC : y = 8'hCE; + 8'hED : y = 8'h55; + 8'hEE : y = 8'h28; + 8'hEF : y = 8'hDF; + 8'hF0 : y = 8'h8C; + 8'hF1 : y = 8'hA1; + 8'hF2 : y = 8'h89; + 8'hF3 : y = 8'h0D; + 8'hF4 : y = 8'hBF; + 8'hF5 : y = 8'hE6; + 8'hF6 : y = 8'h42; + 8'hF7 : y = 8'h68; + 8'hF8 : y = 8'h41; + 8'hF9 : y = 8'h99; + 8'hFA : y = 8'h2D; + 8'hFB : y = 8'h0F; + 8'hFC : y = 8'hB0; + 8'hFD : y = 8'h54; + 8'hFE : y = 8'hBB; + 8'hFF : y = 8'h16; + endcase +endmodule diff --git a/src/ieu/aes/aessboxword.sv b/src/ieu/aes/aessboxword.sv new file mode 100644 index 0000000000..55bf1bb997 --- /dev/null +++ b/src/ieu/aes/aessboxword.sv @@ -0,0 +1,38 @@ +/////////////////////////////////////////// +// aessboxword.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: 4 sets of Rijndael S-BOX so whole word can be looked up simultaneously. +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module aessboxword( + input logic [31:0] a, + output logic [31:0] y +); + + // substitutions boxes for each byte of the word + aessbox sboxb0(a[7:0], y[7:0]); + aessbox sboxb1(a[15:8], y[15:8]); + aessbox sboxb2(a[23:16], y[23:16]); + aessbox sboxb3(a[31:24], y[31:24]); +endmodule diff --git a/src/ieu/aes/aesshiftrow.sv b/src/ieu/aes/aesshiftrow.sv new file mode 100644 index 0000000000..fa355458b3 --- /dev/null +++ b/src/ieu/aes/aesshiftrow.sv @@ -0,0 +1,37 @@ +/////////////////////////////////////////// +// aesshiftrow.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: aesshiftrow for taking in first Data line +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module aesshiftrow( + input logic [127:0] a, + output logic [127:0] y +); + + assign y = {a[95:88], a[55:48], a[15:8], a[103:96], + a[63:56], a[23:16], a[111:104], a[71:64], + a[31:24], a[119:112], a[79:72], a[39:32], + a[127:120], a[87:80], a[47:40], a[7:0]}; +endmodule diff --git a/src/ieu/aes/galoismultforward.sv b/src/ieu/aes/galoismultforward.sv new file mode 100644 index 0000000000..0816056823 --- /dev/null +++ b/src/ieu/aes/galoismultforward.sv @@ -0,0 +1,37 @@ +/////////////////////////////////////////// +// galoismultforward.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu, David_Harris@hmc.edu +// Created: 20 February 2024 +// +// Purpose: Galois field operations for mix columns operation +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module galoismultforward( + input logic [7:0] a, + output logic [7:0] y +); + + logic [7:0] leftshift; + + assign leftshift = {a[6:0], 1'b0}; + assign y = a[7] ? (leftshift ^ 8'b00011011) : leftshift; +endmodule diff --git a/src/ieu/aes/galoismultinverse.sv b/src/ieu/aes/galoismultinverse.sv new file mode 100644 index 0000000000..89c6975841 --- /dev/null +++ b/src/ieu/aes/galoismultinverse.sv @@ -0,0 +1,38 @@ +/////////////////////////////////////////// +// galoismultinverse.sv +// +// Written: kelvin.tran@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: Galois field operations for mix columns operation +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module galoismultinverse( + input logic [10:0] a, + output logic [7:0] y +); + + logic [7:0] temp0, temp1; + + assign temp0 = a[8] ? (a[7:0] ^ 8'b00011011) : a[7:0]; + assign temp1 = a[9] ? (temp0 ^ 8'b00110110) : temp0; + assign y = a[10] ? (temp1 ^ 8'b01101100) : temp1; +endmodule diff --git a/src/ieu/aes/rconlut128.sv b/src/ieu/aes/rconlut128.sv new file mode 100644 index 0000000000..3360b9b514 --- /dev/null +++ b/src/ieu/aes/rconlut128.sv @@ -0,0 +1,48 @@ +/////////////////////////////////////////// +// rconlut128.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: rcon lookup for aes64ks1i instruction +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module rconlut128( + input logic [3:0] rd, + output logic [7:0] rconOut +); + + always_comb + case(rd) + 4'h0 : rconOut = 8'h01; + 4'h1 : rconOut = 8'h02; + 4'h2 : rconOut = 8'h04; + 4'h3 : rconOut = 8'h08; + 4'h4 : rconOut = 8'h10; + 4'h5 : rconOut = 8'h20; + 4'h6 : rconOut = 8'h40; + 4'h7 : rconOut = 8'h80; + 4'h8 : rconOut = 8'h1b; + 4'h9 : rconOut = 8'h36; + 4'hA : rconOut = 8'h00; + default : rconOut = 8'h00; + endcase +endmodule diff --git a/src/ieu/aes/rotate.sv b/src/ieu/aes/rotate.sv new file mode 100644 index 0000000000..7f44f95f43 --- /dev/null +++ b/src/ieu/aes/rotate.sv @@ -0,0 +1,35 @@ +/////////////////////////////////////////// +// rotate.sv +// +// Written: ryan.swann@okstate.edu, james.stine@okstate.edu +// Created: 20 February 2024 +// +// Purpose: rotate a by shamt +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module rotate #(parameter WIDTH=32) ( + input logic [WIDTH-1:0] a, + input logic [$clog2(WIDTH)-1:0] shamt, + output logic [WIDTH-1:0] y +); + + assign y = (a << shamt) | (a >> (WIDTH-shamt)); +endmodule diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index 51cf00b975..ae573ca70e 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -33,9 +33,11 @@ module alu import cvw::*; #(parameter cvw_t P) ( input logic W64, // W64-type instruction input logic SubArith, // Subtraction or arithmetic shift input logic [2:0] ALUSelect, // ALU mux select signal - input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction - input logic [2:0] ZBBSelect, // ZBB mux select signal + input logic [3:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction + input logic [3:0] ZBBSelect, // ZBB mux select signal input logic [2:0] Funct3, // For BMU decoding + input logic [6:0] Funct7, // For ZKNE and ZKND computation + input logic [4:0] Rs2E, // For ZKNE and ZKND computation input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage input logic BMUActive, // Bit manipulation instruction being executed input logic [1:0] CZero, // {czero.nez, czero.eqz} instructions active @@ -89,10 +91,10 @@ module alu import cvw::*; #(parameter cvw_t P) ( else assign PreALUResult = FullResult; // Bit manipulation muxing - if (P.ZBC_SUPPORTED | P.ZBS_SUPPORTED | P.ZBA_SUPPORTED | P.ZBB_SUPPORTED) begin : bitmanipalu + if (P.ZBC_SUPPORTED | P.ZBS_SUPPORTED | P.ZBA_SUPPORTED | P.ZBB_SUPPORTED | P.ZBKB_SUPPORTED | P.ZBKC_SUPPORTED | P.ZBKX_SUPPORTED | P.ZKND_SUPPORTED | P.ZKNE_SUPPORTED | P.ZKNH_SUPPORTED) begin : bitmanipalu bitmanipalu #(P) balu( .A, .B, .W64, .BSelect, .ZBBSelect, .BMUActive, - .Funct3, .LT,.LTU, .BALUControl, .PreALUResult, .FullResult, + .Funct3, .Funct7, .Rs2E, .LT,.LTU, .BALUControl, .PreALUResult, .FullResult, .CondMaskB, .CondShiftA, .ALUResult); end else begin assign ALUResult = PreALUResult; diff --git a/src/ieu/bmu/bitmanipalu.sv b/src/ieu/bmu/bitmanipalu.sv index 3f7d0ae7a8..244a5b4463 100644 --- a/src/ieu/bmu/bitmanipalu.sv +++ b/src/ieu/bmu/bitmanipalu.sv @@ -1,18 +1,18 @@ /////////////////////////////////////////// // bitmanipalu.sv // -// Written: Kevin Kim +// Written: Kevin Kim , kelvin.tran@okstate.edu // Created: 23 March 2023 -// Modified: 23 March 2023 +// Modified: 9 March 2024 // -// Purpose: RISC-V Arithmetic/Logic Unit Bit-Manipulation Extension +// Purpose: RISC-V Arithmetic/Logic Unit Bit-Manipulation Extension and K extension // // Documentation: RISC-V System on Chip Design Chapter 15 // // A component of the CORE-V-WALLY configurable RISC-V project. // https://github.com/openhwgroup/cvw // -// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University // // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // @@ -29,29 +29,37 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module bitmanipalu import cvw::*; #(parameter cvw_t P) ( - input logic [P.XLEN-1:0] A, B, // Operands - input logic W64, // W64-type instruction - input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction - input logic [2:0] ZBBSelect, // ZBB mux select signal - input logic [2:0] Funct3, // Funct3 field of opcode indicates operation to perform - input logic LT, // less than flag - input logic LTU, // less than unsigned flag - input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage - input logic BMUActive, // Bit manipulation instruction being executed - input logic [P.XLEN-1:0] PreALUResult, FullResult,// PreALUResult, FullResult signals + input logic [P.XLEN-1:0] A, B, // Operands + input logic W64, // W64-type instruction + input logic [3:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction + input logic [3:0] ZBBSelect, // ZBB mux select signal + input logic [2:0] Funct3, // Funct3 field of opcode indicates operation to perform + input logic [6:0] Funct7, // Funct7 field for ZKND and ZKNE operations + input logic [4:0] Rs2E, // Register source2 for RNUM of ZKNE/ZKND + input logic LT, // less than flag + input logic LTU, // less than unsigned flag + input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage + input logic BMUActive, // Bit manipulation instruction being executed + input logic [P.XLEN-1:0] PreALUResult, // PreALUResult signals + input logic [P.XLEN-1:0] FullResult, // FullResult signals output logic [P.XLEN-1:0] CondMaskB, // B is conditionally masked for ZBS instructions output logic [P.XLEN-1:0] CondShiftA, // A is conditionally shifted for ShAdd instructions output logic [P.XLEN-1:0] ALUResult); // Result - logic [P.XLEN-1:0] ZBBResult, ZBCResult; // ZBB, ZBC Result - logic [P.XLEN-1:0] MaskB; // BitMask of B - logic [P.XLEN-1:0] RevA; // Bit-reversed A - logic Rotate; // Indicates if it is Rotate instruction - logic Mask; // Indicates if it is ZBS instruction - logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction - logic [1:0] PreShiftAmt; // Amount to Pre-Shift A - logic [P.XLEN-1:0] CondZextA; // A Conditional Extend Intermediary Signal - logic [P.XLEN-1:0] ABMU, BBMU; // Gated data inputs to reduce BMU activity + logic [P.XLEN-1:0] ZBBResult; // ZBB Result + logic [P.XLEN-1:0] ZBCResult; // ZBC Result + logic [P.XLEN-1:0] ZBKBResult; // ZBKB Result + logic [P.XLEN-1:0] ZBKCResult; // ZBKC Result + logic [P.XLEN-1:0] ZBKXResult; // ZBKX Result + logic [P.XLEN-1:0] ZKNHResult; // ZKNH Result + logic [P.XLEN-1:0] ZKNDEResult; // ZKNE or ZKND Result + logic [P.XLEN-1:0] MaskB; // BitMask of B + logic [P.XLEN-1:0] RevA; // Bit-reversed A + logic Mask; // Indicates if it is ZBS instruction + logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction + logic [1:0] PreShiftAmt; // Amount to Pre-Shift A + logic [P.XLEN-1:0] CondZextA; // A Conditional Extend Intermediary Signal + logic [P.XLEN-1:0] ABMU, BBMU; // Gated data inputs to reduce BMU activity // gate data inputs to BMU to only operate when BMU is active assign ABMU = A & {P.XLEN{BMUActive}}; @@ -83,23 +91,50 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P) ( bitreverse #(P.XLEN) brA(.A(ABMU), .RevA); end - // ZBC Unit - if (P.ZBC_SUPPORTED) begin: zbc + // ZBC and ZBKCUnit + if (P.ZBC_SUPPORTED | P.ZBKC_SUPPORTED) begin: zbc zbc #(P.XLEN) ZBC(.A(ABMU), .RevA, .B(BBMU), .Funct3, .ZBCResult); end else assign ZBCResult = 0; // ZBB Unit if (P.ZBB_SUPPORTED) begin: zbb - zbb #(P.XLEN) ZBB(.A(ABMU), .RevA, .B(BBMU), .W64, .LT, .LTU, .BUnsigned(Funct3[0]), .ZBBSelect, .ZBBResult); + zbb #(P.XLEN) ZBB(.A(ABMU), .RevA, .B(BBMU), .W64, .LT, .LTU, .BUnsigned(Funct3[0]), .ZBBSelect(ZBBSelect[2:0]), .ZBBResult); end else assign ZBBResult = 0; + // ZBKB Unit + if (P.ZBKB_SUPPORTED) begin: zbkb + zbkb #(P.XLEN) ZBKB(.A(ABMU), .B(BBMU), .RevA, .W64, .Funct3, .ZBKBSelect(ZBBSelect[2:0]), .ZBKBResult); + end else assign ZBKBResult = 0; + + // ZBKX Unit + if (P.ZBKX_SUPPORTED) begin: zbkx + zbkx #(P.XLEN) ZBKX(.A(ABMU), .B(BBMU), .ZBKXSelect(ZBBSelect[2:0]), .ZBKXResult); + end else assign ZBKXResult = 0; + + // ZKND and ZKNE AES decryption and encryption + if (P.ZKND_SUPPORTED | P.ZKNE_SUPPORTED) + if (P.XLEN == 32) zknde32 #(P) ZKN32(.A(ABMU), .B(BBMU), .Funct7, .round(Rs2E[3:0]), .ZKNSelect(ZBBSelect[3:0]), .ZKNDEResult); + else zknde64 #(P) ZKN64(.A(ABMU), .B(BBMU), .Funct7, .round(Rs2E[3:0]), .ZKNSelect(ZBBSelect[3:0]), .ZKNDEResult); + + // ZKNH Unit + if (P.ZKNH_SUPPORTED) begin: zknh + if (P.XLEN == 32) zknh32 ZKNH32(.A(ABMU), .B(BBMU), .ZKNHSelect(ZBBSelect), .ZKNHResult(ZKNHResult)); + else zknh64 ZKNH64(.A(ABMU), .B(BBMU), .ZKNHSelect(ZBBSelect), .ZKNHResult(ZKNHResult)); + end else assign ZKNHResult = 0; + // Result Select Mux always_comb case (BSelect) - // 00: ALU, 01: ZBA/ZBS, 10: ZBB, 11: ZBC - 2'b00: ALUResult = PreALUResult; - 2'b01: ALUResult = FullResult; // NOTE: We don't use ALUResult because ZBA/ZBS instructions don't sign extend the MSB of the right-hand word. - 2'b10: ALUResult = ZBBResult; - 2'b11: ALUResult = ZBCResult; + // 0000: ALU, 0001: ZBA/ZBS, 0010: ZBB, 0011: ZBC/ZBKC, 0100: ZBKB, 0110: ZBKX + // 0111: ZKND, 1000: ZKNE, 1001: ZKNH, 1010: ZKSED, 1011: ZKSH... + 4'b0000: ALUResult = PreALUResult; + 4'b0001: ALUResult = FullResult; // NOTE: don't use ALUResult since ZBA/ZBS doesnt sext the MSB of RH word + 4'b0010: ALUResult = ZBBResult; + 4'b0011: ALUResult = ZBCResult; + 4'b0100: ALUResult = ZBKBResult; + 4'b0110: ALUResult = ZBKXResult; + 4'b0111: ALUResult = ZKNDEResult; + 4'b1000: ALUResult = ZKNHResult; + default: ALUResult = PreALUResult; endcase endmodule diff --git a/src/ieu/bmu/bitreverse.sv b/src/ieu/bmu/bitreverse.sv index 3876c31e45..083033d530 100644 --- a/src/ieu/bmu/bitreverse.sv +++ b/src/ieu/bmu/bitreverse.sv @@ -1,4 +1,3 @@ - /////////////////////////////////////////// // bitreverse.sv // diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index 5b758f123b..887ac00653 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -1,9 +1,9 @@ /////////////////////////////////////////// // bmuctrl.sv // -// Written: Kevin Kim +// Written: Kevin Kim , kelvin.tran@okstate.edu // Created: 16 February 2023 -// Modified: 6 March 2023 +// Modified: 6 March 2023, 9 March 2024 // // Purpose: Top level bit manipulation instruction decoder // @@ -12,7 +12,7 @@ // A component of the CORE-V-WALLY configurable RISC-V project. // https://github.com/openhwgroup/cvw // -// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University // // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // @@ -34,8 +34,8 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) ( input logic StallD, FlushD, // Stall, flush Decode stage input logic [31:0] InstrD, // Instruction in Decode stage input logic ALUOpD, // Regular ALU Operation - output logic [1:0] BSelectD, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding in Decode stage - output logic [2:0] ZBBSelectD, // ZBB mux select signal in Decode stage NOTE: do we need this in decode? + output logic [3:0] BSelectD, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding in Decode stage + output logic [3:0] ZBBSelectD, // ZBB mux select signal in Decode stage NOTE: do we need this in decode? output logic BRegWriteD, // Indicates if it is a R type B instruction in Decode Stage output logic BALUSrcBD, // Indicates if it is an I/IW (non auipc) type B instruction in Decode Stage output logic BW64D, // Indiciates if it is a W type B instruction in Decode Stage @@ -44,8 +44,8 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) ( // Execute stage control signals input logic StallE, FlushE, // Stall, flush Execute stage output logic [2:0] ALUSelectD, // ALU select - output logic [1:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding - output logic [2:0] ZBBSelectE, // ZBB mux select signal + output logic [3:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding + output logic [3:0] ZBBSelectE, // ZBB mux select signal output logic BRegWriteE, // Indicates if it is a R type B instruction in Execute output logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage output logic BMUActiveE // Bit manipulation instruction being executed @@ -62,7 +62,7 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) ( logic [2:0] BALUSelectD; // ALU Mux select signal in Decode Stage for BMU operations logic BALUOpD; // Indicates if it is an ALU B instruction in Decode Stage - `define BMUCTRLW 17 + `define BMUCTRLW 20 logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals @@ -78,92 +78,204 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) ( BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_0_1; // default: Illegal bmu instruction; if (P.ZBA_SUPPORTED) begin casez({OpD, Funct7D, Funct3D}) - 17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh1add - 17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh2add - 17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh3add + 17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_0_1_0_0_0_1_0; // sh1add + 17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_0_1_0_0_0_1_0; // sh2add + 17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_0_1_0_0_0_1_0; // sh3add endcase if (P.XLEN==64) casez({OpD, Funct7D, Funct3D}) - 17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh1add.uw - 17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh2add.uw - 17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh3add.uw - 17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_0_0; // add.uw - 17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_01_000_1_1_1_1_0_0_0_0_0; // slli.uw + 17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_1_1_0_0_0_1_0; // sh1add.uw + 17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_1_1_0_0_0_1_0; // sh2add.uw + 17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_1_1_0_0_0_1_0; // sh3add.uw + 17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_1_1_0_0_0_0_0; // add.uw + 17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_0001_0000_1_1_1_1_0_0_0_0_0; // slli.uw endcase end + if (P.ZBB_SUPPORTED) begin casez({OpD, Funct7D, Funct3D}) - 17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_0_1_0_1_0_0_0; // rol - 17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_0_1_0_1_0_0_0; // ror 17'b0010011_0110000_001: if ((Rs2D[4:1] == 4'b0010)) - BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // sign extend instruction + BMUControlsD = `BMUCTRLW'b000_0010_0001_1_1_0_1_0_0_0_0_0; // sign extend instruction else if ((Rs2D[4:2]==3'b000) & ~(Rs2D[1] & Rs2D[0])) - BMUControlsD = `BMUCTRLW'b000_10_000_1_1_0_1_0_0_0_0_0; // count instruction + BMUControlsD = `BMUCTRLW'b000_0010_0000_1_1_0_1_0_0_0_0_0; // count instruction // // coverage off: This case can't occur in RV64 // 17'b0110011_0000100_100: if (P.XLEN == 32) // BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32) // // coverage on - 17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_01_111_1_0_0_1_1_0_0_0_0; // andn - 17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_01_111_1_0_0_1_1_0_0_0_0; // orn - 17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_01_111_1_0_0_1_1_0_0_0_0; // xnor - 17'b0010011_011010?_101: if ((P.XLEN == 32 ^ Funct7D[0]) & (Rs2D == 5'b11000)) - BMUControlsD = `BMUCTRLW'b000_10_010_1_1_0_1_0_0_0_0_0; // rev8 17'b0010011_0010100_101: if (Rs2D[4:0] == 5'b00111) - BMUControlsD = `BMUCTRLW'b000_10_010_1_1_0_1_0_0_0_0_0; // orc.b - 17'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_10_111_1_0_0_1_1_0_0_0_0; // max - 17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_10_111_1_0_0_1_1_0_0_0_0; // maxu - 17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_1_0_0_0_0; // min - 17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_1_0_0_0_0; // minu + BMUControlsD = `BMUCTRLW'b000_0010_0010_1_1_0_1_0_0_0_0_0; // orc.b + 17'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_0010_0111_1_0_0_1_1_0_0_0_0; // max + 17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_0010_0111_1_0_0_1_1_0_0_0_0; // maxu + 17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_0010_0011_1_0_0_1_1_0_0_0_0; // min + 17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_0010_0011_1_0_0_1_1_0_0_0_0; // minu endcase if (P.XLEN==32) casez({OpD, Funct7D, Funct3D}) - 17'b0110011_0000100_100: BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32) - 17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_0_1_0_1_0_0_0; // rori (rv32) + 17'b0110011_0000100_100: BMUControlsD = `BMUCTRLW'b000_0010_0001_1_1_0_1_0_0_0_0_0; // zexth (rv32) endcase else if (P.XLEN==64) casez({OpD, Funct7D, Funct3D}) - 17'b0111011_0000100_100: BMUControlsD = `BMUCTRLW'b000_10_001_1_0_0_1_0_0_0_0_0; // zexth (rv64) - 17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rolw - 17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rorw - 17'b0010011_011000?_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_0_1_0_1_0_0_0; // rori (rv64) - 17'b0011011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_1_1_0_1_0_0_0; // roriw + 17'b0111011_0000100_100: BMUControlsD = `BMUCTRLW'b000_0010_0001_1_0_0_1_0_0_0_0_0; // zexth (rv64) 17'b0011011_0110000_001: if ((Rs2D[4:2]==3'b000) & ~(Rs2D[1] & Rs2D[0])) - BMUControlsD = `BMUCTRLW'b000_10_000_1_1_1_1_0_0_0_0_0; // count word instruction + BMUControlsD = `BMUCTRLW'b000_0010_0000_1_1_1_1_0_0_0_0_0; // count word instruction endcase end + if (P.ZBC_SUPPORTED) casez({OpD, Funct7D, Funct3D}) - 17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_11_000_1_0_0_1_0_0_0_0_0; // ZBC instruction + 17'b0110011_0000101_010: BMUControlsD = `BMUCTRLW'b000_0011_0001_1_0_0_1_0_0_0_0_0; // clmulr + 17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_1_0_0_0_0_0; // ZBC instruction + endcase + if (P.ZBKC_SUPPORTED | P.ZBC_SUPPORTED) begin + casez({OpD, Funct7D, Funct3D}) + 17'b0110011_0000101_001: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_1_0_0_0_0_0; // clmul + 17'b0110011_0000101_011: BMUControlsD = `BMUCTRLW'b000_0011_0001_1_0_0_1_0_0_0_0_0; // clmulh endcase + end + if (P.ZBS_SUPPORTED) begin // ZBS casez({OpD, Funct7D, Funct3D}) - 17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_0_0_1_1_0_1_0_0; // bclr - 17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_0_0_1_1_0_1_0_0; // bext - 17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_0_0_1_0_0_1_0_0; // binv - 17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_0_0_1_0_0_1_0_0; // bset + 17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_0000_1_0_0_1_1_0_1_0_0; // bclr + 17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_0000_1_0_0_1_1_0_1_0_0; // bext + 17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_0000_1_0_0_1_0_0_1_0_0; // binv + 17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_0000_1_0_0_1_0_0_1_0_0; // bset endcase if (P.XLEN==32) // ZBS 64-bit casez({OpD, Funct7D, Funct3D}) - 17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri - 17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti - 17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_1_0_1_0_0_1_0_0; // binvi - 17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti + 17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_0000_1_1_0_1_1_0_1_0_0; // bclri + 17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_0000_1_1_0_1_1_0_1_0_0; // bexti + 17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_0000_1_1_0_1_0_0_1_0_0; // binvi + 17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_0000_1_1_0_1_0_0_1_0_0; // bseti endcase else if (P.XLEN==64) // ZBS 64-bit casez({OpD, Funct7D, Funct3D}) - 17'b0010011_010010?_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri (rv64) - 17'b0010011_010010?_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti (rv64) - 17'b0010011_011010?_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_1_0_1_0_0_1_0_0; // binvi (rv64) - 17'b0010011_001010?_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti (rv64) + 17'b0010011_010010?_001: BMUControlsD = `BMUCTRLW'b111_0001_0000_1_1_0_1_1_0_1_0_0; // bclri (rv64) + 17'b0010011_010010?_101: BMUControlsD = `BMUCTRLW'b101_0001_0000_1_1_0_1_1_0_1_0_0; // bexti (rv64) + 17'b0010011_011010?_001: BMUControlsD = `BMUCTRLW'b100_0001_0000_1_1_0_1_0_0_1_0_0; // binvi (rv64) + 17'b0010011_001010?_001: BMUControlsD = `BMUCTRLW'b110_0001_0000_1_1_0_1_0_0_1_0_0; // bseti (rv64) endcase end if (P.ZBB_SUPPORTED | P.ZBS_SUPPORTED) // rv32i/64i shift instructions need BMU ALUSelect when BMU shifter is used casez({OpD, Funct7D, Funct3D}) - 17'b0110011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_0_0_1_0_0_0_0_0; // sra, srl, sll - 17'b0010011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_1_0_1_0_0_0_0_0; // srai, srli, slli - 17'b0111011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_0_1_1_0_0_0_0_0; // sraw, srlw, sllw - 17'b0011011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_1_1_1_0_0_0_0_0; // sraiw, srliw, slliw + 17'b0110011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_0_1_0_0_0_0_0; // sra, srl, sll + 17'b0010011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_0_1_0_0_0_0_0; // srai, srli, slli + 17'b0111011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_1_1_0_0_0_0_0; // sraw, srlw, sllw + 17'b0011011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_1_1_0_0_0_0_0; // sraiw, srliw, slliw + endcase + + if (P.ZBKB_SUPPORTED) begin // ZBKB Bitmanip + casez({OpD,Funct7D, Funct3D}) + 17'b0110011_0000100_100: BMUControlsD = `BMUCTRLW'b000_0100_0001_1_0_0_1_0_0_0_0_0; // pack + 17'b0110011_0000100_111: BMUControlsD = `BMUCTRLW'b000_0100_0001_1_0_0_1_0_0_0_0_0; // packh + 17'b0010011_0110100_101: if (Rs2D == 5'b00111) + BMUControlsD = `BMUCTRLW'b000_0100_0000_1_1_0_1_0_0_0_0_0; // brev8 + endcase + if (P.XLEN==32) + casez({OpD, Funct7D, Funct3D}) + 17'b0010011_0000100_001: if (Rs2D == 5'b01111) + BMUControlsD = `BMUCTRLW'b000_0100_0011_1_1_0_1_0_0_0_0_0; //zip + 17'b0010011_0000100_101: if (Rs2D == 5'b01111) + BMUControlsD = `BMUCTRLW'b000_0100_0011_1_1_0_1_0_0_0_0_0; //unzip + endcase + else if (P.XLEN==64) + casez({OpD,Funct7D, Funct3D}) + 17'b0111011_0000100_100: BMUControlsD = `BMUCTRLW'b000_0100_0101_1_0_1_1_0_0_0_0_0; //packw + endcase + end + if (P.ZBB_SUPPORTED | P.ZBKB_SUPPORTED) begin // ZBB and ZBKB shared instructions + casez({OpD, Funct7D, Funct3D}) + 17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0001_0111_1_0_0_1_0_1_0_0_0; // rol + 17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0001_0111_1_0_0_1_0_1_0_0_0; // ror + 17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_0001_0111_1_0_0_1_1_0_0_0_0; // andn + 17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_0001_0111_1_0_0_1_1_0_0_0_0; // orn + 17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_0001_0111_1_0_0_1_1_0_0_0_0; // xnor + 17'b0010011_011010?_101: if ((P.XLEN == 32 ^ Funct7D[0]) & (Rs2D == 5'b11000)) + BMUControlsD = `BMUCTRLW'b000_0010_0010_1_1_0_1_0_0_0_0_0; // rev8 + endcase + if (P.XLEN==32) + casez({OpD, Funct7D, Funct3D}) + 17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_1_0_1_0_1_0_0_0; // rori (rv32) + endcase + else if (P.XLEN==64) + casez({OpD, Funct7D, Funct3D}) + 17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_0_1_1_0_1_0_0_0; // rolw + 17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_0_1_1_0_1_0_0_0; // rorw + 17'b0010011_011000?_101: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_1_0_1_0_1_0_0_0; // rori (rv64) + 17'b0011011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_1_1_1_0_1_0_0_0; // roriw + endcase + end + + if (P.ZBKX_SUPPORTED) begin //ZBKX + casez({OpD, Funct7D, Funct3D}) + 17'b0110011_0010100_100: BMUControlsD = `BMUCTRLW'b000_0110_0000_1_0_0_1_0_0_0_0_0; // xperm8 + 17'b0110011_0010100_010: BMUControlsD = `BMUCTRLW'b000_0110_0001_1_0_0_1_0_0_0_0_0; // xperm4 + endcase + end + + if (P.ZKND_SUPPORTED) begin //ZKND + if (P.XLEN==32) + casez({OpD, Funct7D, Funct3D}) + 17'b0110011_??10101_000: BMUControlsD = `BMUCTRLW'b000_0111_0100_1_0_0_1_0_0_0_0_0; // aes32dsi - final round decrypt + 17'b0110011_??10111_000: BMUControlsD = `BMUCTRLW'b000_0111_0000_1_0_0_1_0_0_0_0_0; // aes32dsmi - mid round decrypt + endcase + else if (P.XLEN==64) + casez({OpD, Funct7D, Funct3D}) + 17'b0110011_0011101_000: BMUControlsD = `BMUCTRLW'b000_0111_0100_1_0_0_1_0_0_0_0_0; // aes64ds - decrypt final round + 17'b0110011_0011111_000: BMUControlsD = `BMUCTRLW'b000_0111_0000_1_0_0_1_0_0_0_0_0; // aes64dsm - decrypt mid round + 17'b0010011_0011000_001: if (Rs2D == 5'b00000) + BMUControlsD = `BMUCTRLW'b000_0111_1000_1_1_0_1_0_0_0_0_0; // aes64im - decrypt keyschdule mixcolumns + endcase + end + + if (P.ZKNE_SUPPORTED) begin //ZKNE + if (P.XLEN==32) + casez({OpD, Funct7D, Funct3D}) + 17'b0110011_??10001_000: BMUControlsD = `BMUCTRLW'b000_0111_0101_1_0_0_1_0_0_0_0_0; // aes32esi - final round encrypt + 17'b0110011_??10011_000: BMUControlsD = `BMUCTRLW'b000_0111_0001_1_0_0_1_0_0_0_0_0; // aes32esmi - mid round encrypt + endcase + else if (P.XLEN==64) + casez({OpD, Funct7D, Funct3D}) + 17'b0110011_0011001_000: BMUControlsD = `BMUCTRLW'b000_0111_0101_1_0_0_1_0_0_0_0_0; // aes64es - encrypt final round + 17'b0110011_0011011_000: BMUControlsD = `BMUCTRLW'b000_0111_0001_1_0_0_1_0_0_0_0_0; // aes64esm - encrypt mid round + endcase + end + + if ((P.ZKND_SUPPORTED | P.ZKNE_SUPPORTED) & P.XLEN == 64) begin // ZKND and ZKNE shared instructions + casez({OpD, Funct7D, Funct3D}) + 17'b0010011_0011000_001: if (Rs2D[4] == 1'b1) + BMUControlsD = `BMUCTRLW'b000_0111_0010_1_0_0_1_0_0_0_0_0; // aes64ks1i - key schedule istr1 + 17'b0110011_0111111_000: BMUControlsD = `BMUCTRLW'b000_0111_0011_1_0_0_1_0_0_0_0_0; // aes64ks2 - key schedule istr2 endcase + end + + if (P.ZKNH_SUPPORTED) begin // ZKNH + casez({OpD, Funct7D, Funct3D}) + 17'b0010011_0001000_001: + if (Rs2D == 5'b00010) BMUControlsD = `BMUCTRLW'b000_1000_0000_1_0_0_1_0_0_0_0_0; // sha256sig0 + else if (Rs2D == 5'b00011) BMUControlsD = `BMUCTRLW'b000_1000_0001_1_0_0_1_0_0_0_0_0; // sha256sig1 + else if (Rs2D == 5'b00000) BMUControlsD = `BMUCTRLW'b000_1000_0010_1_0_0_1_0_0_0_0_0; // sha256sum0 + else if (Rs2D == 5'b00001) BMUControlsD = `BMUCTRLW'b000_1000_0011_1_0_0_1_0_0_0_0_0; // sha256sum1 + endcase + + if (P.XLEN==32) + casez({OpD, Funct7D, Funct3D}) + 17'b0110011_0101110_000: BMUControlsD = `BMUCTRLW'b000_1000_1000_1_0_0_1_0_0_0_0_0; // sha512sig0h + 17'b0110011_0101010_000: BMUControlsD = `BMUCTRLW'b000_1000_1001_1_0_0_1_0_0_0_0_0; // sha512sig0l + 17'b0110011_0101111_000: BMUControlsD = `BMUCTRLW'b000_1000_1010_1_0_0_1_0_0_0_0_0; // sha512sig1h + 17'b0110011_0101011_000: BMUControlsD = `BMUCTRLW'b000_1000_1011_1_0_0_1_0_0_0_0_0; // sha512sig1l + 17'b0110011_0101000_000: BMUControlsD = `BMUCTRLW'b000_1000_1100_1_0_0_1_0_0_0_0_0; // sha512sum0r + 17'b0110011_0101001_000: BMUControlsD = `BMUCTRLW'b000_1000_1101_1_0_0_1_0_0_0_0_0; // sha512sum1r + endcase + + else if (P.XLEN==64) + casez({OpD, Funct7D, Funct3D}) + 17'b0010011_0001000_001: + if (Rs2D == 5'b00110) BMUControlsD = `BMUCTRLW'b000_1000_1000_1_0_0_1_0_0_0_0_0; // sha512sig0 + else if (Rs2D == 5'b00111) BMUControlsD = `BMUCTRLW'b000_1000_1001_1_0_0_1_0_0_0_0_0; // sha512sig1 + else if (Rs2D == 5'b00100) BMUControlsD = `BMUCTRLW'b000_1000_1010_1_0_0_1_0_0_0_0_0; // sha512sum0 + else if (Rs2D == 5'b00101) BMUControlsD = `BMUCTRLW'b000_1000_1011_1_0_0_1_0_0_0_0_0; // sha512sum1 + endcase + end end // Unpack Control Signals @@ -176,5 +288,5 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) ( assign ALUSelectD = BALUOpD ? BALUSelectD : (ALUOpD ? Funct3D : 3'b000); // BMU Execute stage pipieline control register - flopenrc #(10) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BALUControlD, ~IllegalBitmanipInstrD}, {BSelectE, ZBBSelectE, BRegWriteE, BALUControlE, BMUActiveE}); + flopenrc #(13) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BALUControlD, ~IllegalBitmanipInstrD}, {BSelectE, ZBBSelectE, BRegWriteE, BALUControlE, BMUActiveE}); endmodule diff --git a/src/ieu/bmu/byteop.sv b/src/ieu/bmu/byteop.sv index 191919ecc6..980c6d5862 100644 --- a/src/ieu/bmu/byteop.sv +++ b/src/ieu/bmu/byteop.sv @@ -1,9 +1,9 @@ /////////////////////////////////////////// // byteop.sv // -// Written: Kevin Kim +// Written: Kevin Kim , kelvin.tran@okstate.edu // Created: 1 February 2023 -// Modified: 6 March 2023 +// Modified: 29 February 2024 // // Purpose: RISCV bitmanip byte-wise operation unit // @@ -12,7 +12,7 @@ // A component of the CORE-V-WALLY configurable RISC-V project. // https://github.com/openhwgroup/cvw // -// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University // // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // @@ -30,16 +30,24 @@ module byteop #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, // Operands - input logic ByteSelect, // LSB of Immediate + input logic [WIDTH-1:0] RevA, // Reversed A + input logic [1:0] ByteSelect, // LSB of Immediate output logic [WIDTH-1:0] ByteResult); // rev8, orcb result - logic [WIDTH-1:0] OrcBResult, Rev8Result; + logic [WIDTH-1:0] OrcBResult, Rev8Result, Brev8Result; genvar i; for (i=0;i diff --git a/src/ieu/bmu/zbb.sv b/src/ieu/bmu/zbb.sv index 52ed8ef348..e96ed7acd7 100644 --- a/src/ieu/bmu/zbb.sv +++ b/src/ieu/bmu/zbb.sv @@ -1,4 +1,3 @@ - /////////////////////////////////////////// // zbb.sv // @@ -46,7 +45,7 @@ module zbb #(parameter WIDTH=32) ( mux2 #(1) ltmux(LT, LTU, BUnsigned , lt); cnt #(WIDTH) cnt(.A, .RevA, .B(B[1:0]), .W64, .CntResult); - byteop #(WIDTH) bu(.A, .ByteSelect(B[0]), .ByteResult); + byteop #(WIDTH) bu(.A, .RevA, .ByteSelect({B[10], B[0]}), .ByteResult); ext #(WIDTH) ext(.A, .ExtSelect({~B[2], {B[2] & B[0]}}), .ExtResult); // ZBBSelect[2] differentiates between min(u) vs max(u) instruction diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index d9c076dbd9..9bb40af120 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -43,7 +43,7 @@ module controller import cvw::*; #(parameter cvw_t P) ( output logic StructuralStallD, // Structural stalls detected by controller output logic LoadStallD, // Structural stalls for load, sent to performance counters output logic StoreStallD, // load after store hazard - output logic [4:0] Rs1D, Rs2D, // Register sources to read in Decode or Execute stage + output logic [4:0] Rs1D, Rs2D, Rs2E, // Register sources to read in Decode or Execute stage // Execute stage control signals input logic StallE, FlushE, // Stall, flush Execute stage input logic [1:0] FlagsE, // Comparison flags ({eq, lt}) @@ -55,6 +55,7 @@ module controller import cvw::*; #(parameter cvw_t P) ( output logic [2:0] ALUSelectE, // ALU mux select signal output logic MemReadE, CSRReadE, // Instruction reads memory, reads a CSR (needed for Hazard unit) output logic [2:0] Funct3E, // Instruction's funct3 field + output logic [6:0] Funct7E, // Instruction's funct7 field output logic IntDivE, // Integer divide output logic MDUE, // MDU (multiply/divide) operatio output logic W64E, // RV64 W-type operation @@ -63,8 +64,8 @@ module controller import cvw::*; #(parameter cvw_t P) ( output logic BranchE, // Branch instruction output logic SCE, // Store Conditional instruction output logic BranchSignedE, // Branch comparison operands are signed (if it's a branch) - output logic [1:0] BSelectE, // One-Hot encoding of if it's ZBA_ZBB_ZBC_ZBS instruction - output logic [2:0] ZBBSelectE, // ZBB mux select signal in Execute stage + output logic [3:0] BSelectE, // One-Hot encoding of if it's ZBA_ZBB_ZBC_ZBS instruction + output logic [3:0] ZBBSelectE, // ZBB mux select signal in Execute stage output logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage output logic BMUActiveE, // Bit manipulation instruction being executed output logic [1:0] CZeroE, // {czero.nez, czero.eqz} instructions active @@ -95,7 +96,7 @@ module controller import cvw::*; #(parameter cvw_t P) ( output logic [4:0] RdW // Register destinations in Execute, Memory, or Writeback stage ); - logic [4:0] Rs1E, Rs2E; // pipelined register sources + logic [4:0] Rs1E; // pipelined register sources logic [6:0] OpD; // Opcode in Decode stage logic [2:0] Funct3D; // Funct3 field in Decode stage logic [6:0] Funct7D; // Funct7 field in Decode stage @@ -138,8 +139,8 @@ module controller import cvw::*; #(parameter cvw_t P) ( logic FenceD, FenceE; // Fence instruction logic SFenceVmaD; // sfence.vma instruction logic IntDivM; // Integer divide instruction - logic [1:0] BSelectD; // One-Hot encoding if it's ZBA_ZBB_ZBC_ZBS instruction in decode stage - logic [2:0] ZBBSelectD; // ZBB Mux Select Signal + logic [3:0] BSelectD; // One-Hot encoding if it's ZBA_ZBB_ZBC_ZBS instruction in decode stage + logic [3:0] ZBBSelectD; // ZBB Mux Select Signal logic [1:0] CZeroD; logic IFunctD, RFunctD, MFunctD; // Detect I, R, and M-type RV32IM/Rv64IM instructions logic LFunctD, SFunctD, BFunctD; // Detect load, store, branch instructions @@ -351,9 +352,9 @@ module controller import cvw::*; #(parameter cvw_t P) ( assign SubArithD = BaseSubArithD; // TRUE If B-type or R-type instruction involves inverted operand // tie off unused bit manipulation signals - assign BSelectE = 2'b00; - assign BSelectD = 2'b00; - assign ZBBSelectE = 3'b000; + assign BSelectE = 4'b0000; + assign BSelectD = 4'b0000; + assign ZBBSelectE = 4'b0000; assign BALUControlE = 3'b0; assign BMUActiveE = 1'b0; end @@ -417,9 +418,9 @@ module controller import cvw::*; #(parameter cvw_t P) ( flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD); // Execute stage pipeline control register and logic - flopenrc #(37) controlregE(clk, reset, FlushE, ~StallE, - {ALUSelectD, RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, SubArithD, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, CMOpD, IFUPrefetchD, LSUPrefetchD, CZeroD, InstrValidD}, - {ALUSelectE, IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, SubArithE, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, CMOpE, IFUPrefetchE, LSUPrefetchE, CZeroE, InstrValidE}); + flopenrc #(44) controlregE(clk, reset, FlushE, ~StallE, + {ALUSelectD, RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, Funct7D, W64D, SubArithD, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, CMOpD, IFUPrefetchD, LSUPrefetchD, CZeroD, InstrValidD}, + {ALUSelectE, IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, Funct7E, W64E, SubArithE, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, CMOpE, IFUPrefetchE, LSUPrefetchE, CZeroE, InstrValidE}); flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E); flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E); flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE); diff --git a/src/ieu/datapath.sv b/src/ieu/datapath.sv index eb6fd1d811..49da4e0cb0 100644 --- a/src/ieu/datapath.sv +++ b/src/ieu/datapath.sv @@ -33,11 +33,12 @@ module datapath import cvw::*; #(parameter cvw_t P) ( // Decode stage signals input logic [2:0] ImmSrcD, // Selects type of immediate extension input logic [31:0] InstrD, // Instruction in Decode stage - input logic [4:0] Rs1D, Rs2D, // Source registers + input logic [4:0] Rs1D, Rs2D, Rs2E, // Source registers // Execute stage signals input logic [P.XLEN-1:0] PCE, // PC in Execute stage input logic [P.XLEN-1:0] PCLinkE, // PC + 4 (of instruction in Execute stage) input logic [2:0] Funct3E, // Funct3 field of instruction in Execute stage + input logic [6:0] Funct7E, // Funct7 field of instruction in Execute stage input logic StallE, FlushE, // Stall, flush Execute stage input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages input logic W64E, // W64-type instruction @@ -47,8 +48,8 @@ module datapath import cvw::*; #(parameter cvw_t P) ( input logic [2:0] ALUSelectE, // ALU mux select signal input logic JumpE, // Is a jump (j) instruction input logic BranchSignedE, // Branch comparison operands are signed (if it's a branch) - input logic [1:0] BSelectE, // One hot encoding of ZBA_ZBB_ZBC_ZBS instruction - input logic [2:0] ZBBSelectE, // ZBB mux select signal + input logic [3:0] BSelectE, // One hot encoding of ZBA_ZBB_ZBC_ZBS instruction + input logic [3:0] ZBBSelectE, // ZBB mux select signal input logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage input logic BMUActiveE, // Bit manipulation instruction being executed input logic [1:0] CZeroE, // {czero.nez, czero.eqz} instructions active @@ -109,7 +110,7 @@ module datapath import cvw::*; #(parameter cvw_t P) ( comparator #(P.XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE); mux2 #(P.XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE); mux2 #(P.XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE); - alu #(P) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, BALUControlE, BMUActiveE, CZeroE, ALUResultE, IEUAdrE); + alu #(P) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, Funct7E, Rs2E, BALUControlE, BMUActiveE, CZeroE, ALUResultE, IEUAdrE); mux2 #(P.XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); mux2 #(P.XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE); diff --git a/src/ieu/ieu.sv b/src/ieu/ieu.sv index 438ca75346..38d50e3c3f 100644 --- a/src/ieu/ieu.sv +++ b/src/ieu/ieu.sv @@ -90,13 +90,16 @@ module ieu import cvw::*; #(parameter cvw_t P) ( logic SCE; // Store Conditional instruction logic FWriteIntM; // FPU writing to integer register file logic IntDivW; // Integer divide instruction - logic [1:0] BSelectE; // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding - logic [2:0] ZBBSelectE; // ZBB Result Select Signal in Execute Stage + logic [3:0] BSelectE; // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding + logic [3:0] ZBBSelectE; // ZBB Result Select Signal in Execute Stage logic [2:0] BALUControlE; // ALU Control signals for B instructions in Execute Stage logic SubArithE; // Subtraction or arithmetic shift + logic [6:0] Funct7E; + // Forwarding signals - logic [4:0] Rs1D, Rs2D; // Source registers + logic [4:0] Rs1D, Rs2D; + logic [4:0] Rs2E; // Source registers logic [1:0] ForwardAE, ForwardBE; // Select signals for forwarding multiplexers logic RegWriteM, RegWriteW; // Register will be written in Memory, Writeback stages logic MemReadE, CSRReadE; // Load, CSRRead instruction @@ -108,10 +111,10 @@ module ieu import cvw::*; #(parameter cvw_t P) ( controller #(P) c( .clk, .reset, .StallD, .FlushD, .InstrD, .STATUS_FS, .ENVCFG_CBE, .ImmSrcD, .IllegalIEUFPUInstrD, .IllegalBaseInstrD, - .StructuralStallD, .LoadStallD, .StoreStallD, .Rs1D, .Rs2D, + .StructuralStallD, .LoadStallD, .StoreStallD, .Rs1D, .Rs2D, .Rs2E, .StallE, .FlushE, .FlagsE, .FWriteIntE, .PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE, - .Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, + .Funct3E, .Funct7E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .CZeroE, .MDUActiveE, .FCvtIntE, .ForwardAE, .ForwardBE, .CMOpM, .IFUPrefetchE, .LSUPrefetchM, .StallM, .FlushM, .MemRWE, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, @@ -120,8 +123,8 @@ module ieu import cvw::*; #(parameter cvw_t P) ( .RdW, .RdE, .RdM); datapath #(P) dp( - .clk, .reset, .ImmSrcD, .InstrD, .Rs1D, .Rs2D, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE, - .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE, + .clk, .reset, .ImmSrcD, .InstrD, .Rs1D, .Rs2D, .Rs2E, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE, + .Funct3E, .Funct7E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .CZeroE, .StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW, .StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW, diff --git a/src/ieu/kmu/packer.sv b/src/ieu/kmu/packer.sv new file mode 100644 index 0000000000..fcf2f9eef5 --- /dev/null +++ b/src/ieu/kmu/packer.sv @@ -0,0 +1,54 @@ +/////////////////////////////////////////// +// packer.sv +// +// Written: kelvin.tran@okstate.edu, james.stine@okstate.edu +// Created: 5 October 2023 +// +// Purpose: RISCV kbitmanip pack operation unit +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module packer #(parameter WIDTH=32) ( + input logic [WIDTH-1:0] A, B, + input logic [2:0] PackSelect, + output logic [WIDTH-1:0] PackResult +); + + logic [WIDTH/2-1:0] lowhalf, highhalf; + logic [7:0] lowhalfh, highhalfh; + logic [15:0] lowhalfw, highhalfw; + logic [WIDTH-1:0] Pack, PackH, PackW; + + assign lowhalf = A[WIDTH/2-1:0]; + assign highhalf = B[WIDTH/2-1:0]; + assign lowhalfh = A[7:0]; + assign highhalfh = B[7:0]; + assign lowhalfw = A[15:0]; + assign highhalfw = B[15:0]; + + assign Pack = {highhalf, lowhalf}; + assign PackH = {{(WIDTH-16){1'b0}}, highhalfh, lowhalfh}; + assign PackW = (WIDTH == 64) ? {{(WIDTH-32){highhalfw[15]}}, highhalfw, lowhalfw} : Pack; // not implemented for RV32; treat as Pack to simplify logic in result mux + + always_comb + if (PackSelect[1:0] == 2'b11) PackResult = PackH; + else if (PackSelect[2] == 1'b0) PackResult = Pack; + else PackResult = PackW; +endmodule diff --git a/src/ieu/kmu/zbkb.sv b/src/ieu/kmu/zbkb.sv new file mode 100644 index 0000000000..90b7740420 --- /dev/null +++ b/src/ieu/kmu/zbkb.sv @@ -0,0 +1,46 @@ +/////////////////////////////////////////// +// zbkb.sv +// +// Written: kelvin.tran@okstate.edu, james.stine@okstate.edu +// Created: 4 October 2023 +// +// Purpose: RISC-V ZBKB top level unit: bit manipulation instructions for crypto +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module zbkb #(parameter WIDTH=32) ( + input logic [WIDTH-1:0] A, B, RevA, + input logic W64, + input logic [2:0] Funct3, + input logic [2:0] ZBKBSelect, + output logic [WIDTH-1:0] ZBKBResult +); + + logic [WIDTH-1:0] ByteResult; // rev8, brev8 + logic [WIDTH-1:0] PackResult; // pack, packh, packw (RB64 only) + logic [WIDTH-1:0] ZipResult; // zip, unzip + + byteop #(WIDTH) rev(.A, .RevA, .ByteSelect({B[10], B[0]}), .ByteResult); + packer #(WIDTH) pack(.A, .B, .PackSelect({ZBKBSelect[2], Funct3[1:0]}), .PackResult); + zipper #(WIDTH) zip(.A, .ZipSelect(Funct3[2]), .ZipResult); + + // ZBKB Result Select Mux + mux3 #(WIDTH) zbkbresultmux(ByteResult, PackResult, ZipResult, ZBKBSelect[1:0], ZBKBResult); +endmodule diff --git a/src/ieu/kmu/zbkx.sv b/src/ieu/kmu/zbkx.sv new file mode 100644 index 0000000000..dbbaf3d2d8 --- /dev/null +++ b/src/ieu/kmu/zbkx.sv @@ -0,0 +1,50 @@ +/////////////////////////////////////////// +// zbkx.sv +// +// Written: kelvin.tran@okstate.edu, james.stine@okstate.edu +// Created: 1 February 2024 +// +// Purpose: RISC-V ZBKX top level unit: crossbar permutation instructions for crypto +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module zbkx #(parameter WIDTH=32) ( + input logic [WIDTH-1:0] A, B, + input logic [2:0] ZBKXSelect, + output logic [WIDTH-1:0] ZBKXResult +); + + logic [WIDTH-1:0] xperm4, xperm4lookup; + logic [WIDTH-1:0] xperm8, xperm8lookup; + int i; + + always_comb begin + for(i=0; i> {B[i+:4], 2'b0}; + xperm4[i+:4] = xperm4lookup[3:0]; + end + for(i=0; i> {B[i+:8], 3'b0}; + xperm8[i+:8] = xperm8lookup[7:0]; + end + end + + assign ZBKXResult = ZBKXSelect[0] ? xperm4 : xperm8; +endmodule diff --git a/src/ieu/kmu/zipper.sv b/src/ieu/kmu/zipper.sv new file mode 100644 index 0000000000..2cc0a3a185 --- /dev/null +++ b/src/ieu/kmu/zipper.sv @@ -0,0 +1,45 @@ +/////////////////////////////////////////// +// zipper.sv +// +// Written: kelvin.tran@okstate.edu, james.stine@okstate.edu +// Created: 9 October 2023 +// +// Purpose: RISCV kbitmanip zip operation unit +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module zipper #(parameter WIDTH=64) ( + input logic [WIDTH-1:0] A, + input logic ZipSelect, + output logic [WIDTH-1:0] ZipResult +); + + logic [WIDTH-1:0] zip, unzip; + genvar i; + + for (i=0; i> 1; + assign x[0][1] = A >> 7; + assign x[0][2] = A >> 8; + assign x[0][3] = B << 31; + assign x[0][4] = B << 24; + assign x[0][5] = 0; + + // sha512sig0l + assign x[1][0] = A >> 1; + assign x[1][1] = A >> 7; + assign x[1][2] = A >> 8; + assign x[1][3] = B << 31; + assign x[1][4] = B << 25; + assign x[1][5] = B << 24; + + // sha512sig1h + assign x[2][0] = A << 3; + assign x[2][1] = A >> 6; + assign x[2][2] = A >> 19; + assign x[2][3] = B >> 29; + assign x[2][4] = B << 13; + assign x[2][5] = 0; + + // sha512sig1l + assign x[3][0] = A << 3; + assign x[3][1] = A >> 6; + assign x[3][2] = A >> 19; + assign x[3][3] = B >> 29; + assign x[3][4] = B << 26; + assign x[3][5] = B << 13; + + // sha512sum0r + assign x[4][0] = A << 25; + assign x[4][1] = A << 30; + assign x[4][2] = A >> 28; + assign x[4][3] = B >> 7; + assign x[4][4] = B >> 2; + assign x[4][5] = B << 4; + + // sha512sum1r + assign x[5][0] = A << 23; + assign x[5][1] = A >> 14; + assign x[5][2] = A >> 18; + assign x[5][3] = B >> 9; + assign x[5][4] = B << 18; + assign x[5][5] = B << 14; + + // 32-bit muxes to select inputs to xor6 for sha512 + assign y[0] = x[ZKNHSelect[2:0]][0]; + assign y[1] = x[ZKNHSelect[2:0]][1]; + assign y[2] = x[ZKNHSelect[2:0]][2]; + assign y[3] = x[ZKNHSelect[2:0]][3]; + assign y[4] = x[ZKNHSelect[2:0]][4]; + assign y[5] = x[ZKNHSelect[2:0]][5]; + + // sha512 32-bit xor6 + assign result = y[0] ^ y[1] ^ y[2] ^ y[3] ^ y[4] ^ y[5]; +endmodule diff --git a/src/ieu/sha/sha512_64.sv b/src/ieu/sha/sha512_64.sv new file mode 100644 index 0000000000..8707311e81 --- /dev/null +++ b/src/ieu/sha/sha512_64.sv @@ -0,0 +1,66 @@ +/////////////////////////////////////////// +// sha512_64.sv +// +// Written: kelvin.tran@okstate.edu, james.stine@okstate.edu +// Created: 13 February 2024 +// +// Purpose: RISC-V (RV64) ZKNH 512-bit SHA: select shifted inputs and XOR3 +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module sha512_64 ( + input logic [63:0] A, + input logic [1:0] ZKNHSelect, + output logic [63:0] result +); + + logic [63:0] x[4][3]; + logic [63:0] y[3]; + + // sha512{sig0/sig1/sum0/sum1} select shifted operands for 64-bit xor3 + + // sha512sig0 + assign x[0][0] = {A[0], A[63:1]}; + assign x[0][1] = {A[7:0], A[63:8]}; + assign x[0][2] = A >> 7; + + // sha512sig1 + assign x[1][0] = {A[18:0], A[63:19]}; + assign x[1][1] = {A[60:0], A[63:61]}; + assign x[1][2] = A >> 6; + + // sha512sum0 + assign x[2][0] = {A[27:0], A[63:28]}; + assign x[2][1] = {A[33:0], A[63:34]}; + assign x[2][2] = {A[38:0], A[63:39]}; + + // sha512sum1 + assign x[3][0] = {A[13:0], A[63:14]}; + assign x[3][1] = {A[17:0], A[63:18]}; + assign x[3][2] = {A[40:0], A[63:41]}; + + // 64-bit muxes to select inputs to xor3 for sha512 + assign y[0] = x[ZKNHSelect[1:0]][0]; + assign y[1] = x[ZKNHSelect[1:0]][1]; + assign y[2] = x[ZKNHSelect[1:0]][2]; + + // sha512 64-bit xor3 + assign result = y[0] ^ y[1] ^ y[2]; +endmodule diff --git a/testbench/common/instrNameDecTB.sv b/testbench/common/instrNameDecTB.sv index ee6cd6900c..b433b2ed83 100644 --- a/testbench/common/instrNameDecTB.sv +++ b/testbench/common/instrNameDecTB.sv @@ -58,6 +58,17 @@ module instrNameDecTB( else if (funct7[6:1] == 6'b010010) name = "BCLRI"; else if (funct7[6:1] == 6'b011010) name = "BINVI"; else if (funct7[6:1] == 6'b001010) name = "BSETI"; + else if (funct7 == 7'b0000100 && rs2 == 5'b01111) name = "ZIP"; + else if (funct7 == 7'b0011000 && rs2 == 5'b00000) name = "AES64IM"; + else if (funct7 == 7'b0011000 && rs2[4] == 1'b1) name = "AES64KS1I"; + else if (funct7 == 7'b0001000 && rs2 == 5'b00010) name = "SHA256SIG0"; + else if (funct7 == 7'b0001000 && rs2 == 5'b00011) name = "SHA256SIG1"; + else if (funct7 == 7'b0001000 && rs2 == 5'b00000) name = "SHA256SUM0"; + else if (funct7 == 7'b0001000 && rs2 == 5'b00001) name = "SHA256SUM1"; + else if (funct7 == 7'b0001000 && rs2 == 5'b00110) name = "SHA512SIG0"; + else if (funct7 == 7'b0001000 && rs2 == 5'b00111) name = "SHA512SIG1"; + else if (funct7 == 7'b0001000 && rs2 == 5'b00100) name = "SHA512SUM0"; + else if (funct7 == 7'b0001000 && rs2 == 5'b00101) name = "SHA512SUM1"; else if (funct7 == 7'b0110000) begin case (rs2) 5'b00000: name = "CLZ"; @@ -77,6 +88,8 @@ module instrNameDecTB( else if (funct7[6:1] == 6'b011000) name = "RORI"; else if (funct7[6:1] == 6'b010010) name = "BEXTI"; else if (funct7 == 7'b0010100 & rs2 == 5'b00111) name = "ORC.B"; + else if (imm == 12'b011010000111) name = "BREV8"; + else if (funct7 == 7'b0000100 && rs2 == 5'b01111) name = "UNZIP"; else name = "ILLEGAL"; 10'b0010011_110: if (rd == 0 & rs2 == 0) name = "PREFETCH.I"; else if (rd == 0 & rs2 == 1) name = "PREFETCH.R"; @@ -130,6 +143,21 @@ module instrNameDecTB( 10'b0110011_000: if (funct7 == 7'b0000000) name = "ADD"; else if (funct7 == 7'b0000001) name = "MUL"; else if (funct7 == 7'b0100000) name = "SUB"; + else if (funct7[4:0] == 5'b10101) name = "AES32DSI"; + else if (funct7[4:0] == 5'b10111) name = "AES32DSMI"; + else if (funct7 == 7'b0011101) name = "AES64DS"; + else if (funct7 == 7'b0011111) name = "AES64DSM"; + else if (funct7[4:0] == 5'b10001) name = "AES32ESI"; + else if (funct7[4:0] == 5'b10011) name = "AES32ESMI"; + else if (funct7 == 7'b0011001) name = "AES64ES"; + else if (funct7 == 7'b0011011) name = "AES64ESM"; + else if (funct7 == 7'b0111111) name = "AES64KS2"; + else if (funct7 == 7'b0101110) name = "SHA512SIG0H"; + else if (funct7 == 7'b0101010) name = "SHA512SIG0L"; + else if (funct7 == 7'b0101111) name = "SHA512SIG1H"; + else if (funct7 == 7'b0101011) name = "SHA512SIG1L"; + else if (funct7 == 7'b0101000) name = "SHA512SUM0R"; + else if (funct7 == 7'b0101001) name = "SHA512SUM1R"; else name = "ILLEGAL"; 10'b0110011_001: if (funct7 == 7'b0000000) name = "SLL"; else if (funct7 == 7'b0000001) name = "MULH"; @@ -153,7 +181,9 @@ module instrNameDecTB( else if (funct7 == 7'b0010000) name = "SH2ADD"; else if (funct7 == 7'b0000101) name = "MIN"; else if (funct7 == 7'b0100000) name = "ORN"; - else if (funct7 == 7'b0000100) name = "ZEXT.H"; + else if (funct7 == 7'b0000100 && rs2 == 5'b00000) name = "ZEXT.H"; + else if (funct7 == 7'b0000100 && op == 7'b0110011) name = "PACK"; + else if (funct7 == 7'b0000100 && op == 7'b0111011) name = "PACKW"; else name = "ILLEGAL"; 10'b0110011_101: if (funct7 == 7'b0000000) name = "SRL"; else if (funct7 == 7'b0000001) name = "DIVU"; @@ -311,10 +341,14 @@ module instrNameDecTB( else if (funct7 == 7'b1011011 & funct3 == 3'b000) name = "FMVP.Q.X"; else if (funct7 == 7'b1100001 & funct3 == 3'b001 & rs2 == 5'b01000) name = "FCVTMOD.W.D"; else name = "ILLEGAL"; + 10'b0000111_001: name = "FLH"; 10'b0000111_010: name = "FLW"; - 10'b0100111_010: name = "FSW"; 10'b0000111_011: name = "FLD"; + 10'b0000111_100: name = "FLQ"; + 10'b0100111_001: name = "FSH"; + 10'b0100111_010: name = "FSW"; 10'b0100111_011: name = "FSD"; + 10'b0100111_100: name = "FSQ"; default: name = "ILLEGAL"; endcase endmodule diff --git a/testbench/common/riscvassertions.sv b/testbench/common/riscvassertions.sv index b439b3d75a..3f50d3f7c6 100644 --- a/testbench/common/riscvassertions.sv +++ b/testbench/common/riscvassertions.sv @@ -66,6 +66,7 @@ module riscvassertions import cvw::*; #(parameter cvw_t P); assert ((P.ZCA_SUPPORTED == 1) || (P.ZCD_SUPPORTED == 0 && P.ZCF_SUPPORTED == 0)) else $fatal(1, "ZCF or ZCD requires ZCA"); assert ((P.ZCF_SUPPORTED == 0) || (P.F_SUPPORTED == 1)) else $fatal(1, "ZCF requires F"); assert ((P.ZCD_SUPPORTED == 0) || (P.D_SUPPORTED == 1)) else $fatal(1, "ZCD requires D"); + assert ((P.LLEN == P.XLEN) || (P.DCACHE_SUPPORTED)) else $fatal(1, "LLEN > XLEN (D on RV32 or Q on RV64) requires data cache"); end endmodule diff --git a/testbench/common/wallyTracer.sv b/testbench/common/wallyTracer.sv index 309b390276..554ebc5d7f 100644 --- a/testbench/common/wallyTracer.sv +++ b/testbench/common/wallyTracer.sv @@ -63,7 +63,7 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi); logic CSRWriteM, CSRWriteW; logic [11:0] CSRAdrM, CSRAdrW; logic wfiM; - logic InterruptM; + logic InterruptM, InterruptW; assign clk = testbench.dut.clk; // assign InstrValidF = testbench.dut.core.ieu.InstrValidF; // not needed yet @@ -266,6 +266,7 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi); flopenrc #(P.XLEN)PCWReg (clk, reset, FlushW, ~StallW, PCM, PCW); flopenrc #(1) InstrValidMReg (clk, reset, FlushW, ~StallW, InstrValidM, InstrValidW); flopenrc #(1) TrapWReg (clk, reset, 1'b0, ~StallW, TrapM, TrapW); + flopenrc #(1) InterruptWReg (clk, reset, 1'b0, ~StallW, InterruptM, InterruptW); flopenrc #(1) HaltWReg (clk, reset, 1'b0, ~StallW, HaltM, HaltW); // **** remove? are these used? @@ -287,9 +288,9 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi); assign rvvi.order[0][0] = CSRArray[12'hB02]; // TODO: IMPERAS Should be event order assign rvvi.insn[0][0] = InstrRawW; assign rvvi.pc_rdata[0][0] = PCW; - assign rvvi.trap[0][0] = 0; + assign rvvi.trap[0][0] = TrapW; assign rvvi.halt[0][0] = HaltW; - assign rvvi.intr[0][0] = 0; + assign rvvi.intr[0][0] = InterruptW; assign rvvi.mode[0][0] = PrivilegeModeW; assign rvvi.ixl[0][0] = PrivilegeModeW == 2'b11 ? 2'b10 : PrivilegeModeW == 2'b01 ? STATUS_SXL : STATUS_UXL; diff --git a/testbench/testbench-xcelium.sv b/testbench/testbench-xcelium.sv index 85b39e766f..2e7db3d6e9 100644 --- a/testbench/testbench-xcelium.sv +++ b/testbench/testbench-xcelium.sv @@ -129,6 +129,12 @@ module testbench; "arch64zbb": if (P.ZBB_SUPPORTED) tests = arch64zbb; "arch64zbc": if (P.ZBC_SUPPORTED) tests = arch64zbc; "arch64zbs": if (P.ZBS_SUPPORTED) tests = arch64zbs; + "arch64zbkb": if (P.ZBKB_SUPPORTED) tests = arch64zbkb; + "arch64zbkc": if (P.ZBKC_SUPPORTED) tests = arch64zbkc; + "arch64zbkx": if (P.ZBKX_SUPPORTED) tests = arch64zbkx; + "arch64zknd": if (P.ZKND_SUPPORTED) tests = arch64zknd; + "arch64zkne": if (P.ZKNE_SUPPORTED) tests = arch64zkne; + "arch64zknh": if (P.ZKNH_SUPPORTED) tests = arch64zknh; endcase end else begin // RV32 case (TEST) @@ -159,6 +165,12 @@ module testbench; "arch32zbb": if (P.ZBB_SUPPORTED) tests = arch32zbb; "arch32zbc": if (P.ZBC_SUPPORTED) tests = arch32zbc; "arch32zbs": if (P.ZBS_SUPPORTED) tests = arch32zbs; + "arch32zbkb": if (P.ZBKB_SUPPORTED) tests = arch32zbkb; + "arch32zbkc": if (P.ZBKC_SUPPORTED) tests = arch32zbkc; + "arch32zbkx": if (P.ZBKX_SUPPORTED) tests = arch32zbkx; + "arch32zknd": if (P.ZKND_SUPPORTED) tests = arch32zknd; + "arch32zkne": if (P.ZKNE_SUPPORTED) tests = arch32zkne; + "arch32zknh": if (P.ZKNH_SUPPORTED) tests = arch32zknh; endcase end if (tests.size() == 0) begin diff --git a/testbench/testbench.sv b/testbench/testbench.sv index cfcf812372..4c7bfac1c4 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -124,6 +124,7 @@ module testbench; "imperas64f": if (P.F_SUPPORTED) tests = imperas64f; "imperas64d": if (P.D_SUPPORTED) tests = imperas64d; "imperas64m": if (P.M_SUPPORTED) tests = imperas64m; + "wally64q": if (P.Q_SUPPORTED) tests = wally64q; "wally64a": if (P.A_SUPPORTED) tests = wally64a; "imperas64c": if (P.C_SUPPORTED) tests = imperas64c; else tests = imperas64iNOc; @@ -147,6 +148,12 @@ module testbench; "arch64zfaf": if (P.ZFA_SUPPORTED) tests = arch64zfaf; "arch64zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch64zfad; "buildroot": tests = buildroot; + "arch64zbkb": if (P.ZBKB_SUPPORTED) tests = arch64zbkb; + "arch64zbkc": if (P.ZBKC_SUPPORTED) tests = arch64zbkc; + "arch64zbkx": if (P.ZBKX_SUPPORTED) tests = arch64zbkx; + "arch64zknd": if (P.ZKND_SUPPORTED) tests = arch64zknd; + "arch64zkne": if (P.ZKNE_SUPPORTED) tests = arch64zkne; + "arch64zknh": if (P.ZKNH_SUPPORTED) tests = arch64zknh; endcase end else begin // RV32 case (TEST) @@ -189,6 +196,12 @@ module testbench; "arch32zfh_divsqrt": if (P.ZFH_SUPPORTED) tests = arch32zfh_divsqrt; "arch32zfaf": if (P.ZFA_SUPPORTED) tests = arch32zfaf; "arch32zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch32zfad; + "arch32zbkb": if (P.ZBKB_SUPPORTED) tests = arch32zbkb; + "arch32zbkc": if (P.ZBKC_SUPPORTED) tests = arch32zbkc; + "arch32zbkx": if (P.ZBKX_SUPPORTED) tests = arch32zbkx; + "arch32zknd": if (P.ZKND_SUPPORTED) tests = arch32zknd; + "arch32zkne": if (P.ZKNE_SUPPORTED) tests = arch32zkne; + "arch32zknh": if (P.ZKNH_SUPPORTED) tests = arch32zknh; endcase end if (tests.size() == 0) begin diff --git a/testbench/tests.vh b/testbench/tests.vh index 95ebb74b3c..1e676b8cb6 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -869,6 +869,10 @@ string imperas32f[] = '{ "rv32i_m/I/XORI-01" }; + string wally64q[] = '{ + `WALLYTEST, + "rv64i_m/Q/src/WALLY-q-01.S" + }; string wally64a[] = '{ `WALLYTEST, @@ -990,6 +994,78 @@ string imperas32f[] = '{ "rv32i_m/B/src/bseti-01.S" }; + string arch32zbkc[] = '{ + `RISCVARCHTEST, + "rv32i_m/B/src/clmul-01.S", + "rv32i_m/B/src/clmulh-01.S" + }; + + string arch32zbkx[] = '{ + `RISCVARCHTEST, + "rv32i_m/K/src/xperm8-01.S", + "rv32i_m/K/src/xperm4-01.S" + }; + + string arch32zknd[] = '{ + `RISCVARCHTEST, + "rv32i_m/K/src/aes32dsi-01.S", + "rv32i_m/K/src/aes32dsmi-01.S" + }; + + string arch32zkne[] = '{ + `RISCVARCHTEST, + "rv32i_m/K/src/aes32esi-01.S", + "rv32i_m/K/src/aes32esmi-01.S" + }; + + string arch32zknh[] = '{ + `RISCVARCHTEST, + "rv32i_m/K/src/sha256sig0-01.S", + "rv32i_m/K/src/sha256sig1-01.S", + "rv32i_m/K/src/sha256sum0-01.S", + "rv32i_m/K/src/sha256sum1-01.S", + "rv32i_m/K/src/sha512sig0h-01.S", + "rv32i_m/K/src/sha512sig0l-01.S", + "rv32i_m/K/src/sha512sig1h-01.S", + "rv32i_m/K/src/sha512sig1l-01.S", + "rv32i_m/K/src/sha512sum0r-01.S", + "rv32i_m/K/src/sha512sum1r-01.S" + }; + + string arch32zbkb[] = '{ + `RISCVARCHTEST, + "rv32i_m/B/src/ror-01.S", + "rv32i_m/B/src/rol-01.S", + "rv32i_m/B/src/rori-01.S", + "rv32i_m/B/src/andn-01.S", + "rv32i_m/B/src/orn-01.S", + "rv32i_m/B/src/xnor-01.S", + "rv32i_m/B/src/rev8_32-01.S", + "rv32i_m/K/src/pack-01.S", + "rv32i_m/K/src/packh-01.S", + "rv32i_m/K/src/brev8_32-01.S", + "rv32i_m/K/src/zip-01.S", + "rv32i_m/K/src/unzip-01.S" + }; + + string arch64zbkb[] = '{ + `RISCVARCHTEST, + "rv64i_m/B/src/ror-01.S", + "rv64i_m/B/src/rol-01.S", + "rv64i_m/B/src/rori-01.S", + "rv64i_m/B/src/rorw-01.S", + "rv64i_m/B/src/rolw-01.S", + "rv64i_m/B/src/roriw-01.S", + "rv64i_m/B/src/andn-01.S", + "rv64i_m/B/src/orn-01.S", + "rv64i_m/B/src/xnor-01.S", + "rv64i_m/B/src/rev8-01.S", + "rv64i_m/K/src/pack-01.S", + "rv64i_m/K/src/packh-01.S", + "rv64i_m/K/src/packw-01.S", + "rv64i_m/K/src/brev8-01.S" + }; + string arch64m[] = '{ `RISCVARCHTEST, "rv64i_m/M/src/div-01.S", @@ -1748,6 +1824,47 @@ string arch64zbs[] = '{ "rv64i_m/B/src/bseti-01.S" }; +string arch64zbkc[] = '{ + `RISCVARCHTEST, + "rv64i_m/B/src/clmul-01.S", + "rv64i_m/B/src/clmulh-01.S" +}; + +string arch64zbkx[] = '{ + `RISCVARCHTEST, + "rv64i_m/K/src/xperm8-01.S", + "rv64i_m/K/src/xperm4-01.S" +}; + +string arch64zknd[] = '{ + `RISCVARCHTEST, + "rv64i_m/K/src/aes64ds-01.S", + "rv64i_m/K/src/aes64dsm-01.S", + "rv64i_m/K/src/aes64im-01.S", + "rv64i_m/K/src/aes64ks1i-01.S", + "rv64i_m/K/src/aes64ks2-01.S" +}; + +string arch64zkne[] = '{ + `RISCVARCHTEST, + "rv64i_m/K/src/aes64es-01.S", + "rv64i_m/K/src/aes64esm-01.S", + "rv64i_m/K/src/aes64ks1i-01.S", + "rv64i_m/K/src/aes64ks2-01.S" +}; + +string arch64zknh[] = '{ + `RISCVARCHTEST, + "rv64i_m/K/src/sha256sig0-01.S", + "rv64i_m/K/src/sha256sig1-01.S", + "rv64i_m/K/src/sha256sum0-01.S", + "rv64i_m/K/src/sha256sum1-01.S", + "rv64i_m/K/src/sha512sig0-01.S", + "rv64i_m/K/src/sha512sig1-01.S", + "rv64i_m/K/src/sha512sum0-01.S", + "rv64i_m/K/src/sha512sum1-01.S" +}; + string arch32priv[] = '{ `RISCVARCHTEST, "rv32i_m/privilege/src/ebreak.S", diff --git a/tests/riscof/config.ini b/tests/riscof/config.ini index ae5a2f13b3..9611574607 100644 --- a/tests/riscof/config.ini +++ b/tests/riscof/config.ini @@ -9,6 +9,9 @@ pluginpath={0}/spike ispec={0}/spike/spike_rv{1}_isa.yaml pspec={0}/spike/spike_platform.yaml target_run=1 +# Optional as mentioned in https://riscof.readthedocs.io/en/latest/inputs.html#config-ini-syntax +jobs=4 [sail_cSim] pluginpath={0}/sail_cSim +jobs=4 \ No newline at end of file diff --git a/tests/riscof/spike/riscof_spike.py b/tests/riscof/spike/riscof_spike.py index 5450f64df9..f5b8ea3173 100644 --- a/tests/riscof/spike/riscof_spike.py +++ b/tests/riscof/spike/riscof_spike.py @@ -131,6 +131,18 @@ def build(self, isa_yaml, platform_yaml): self.isa += '_Zbc' if "Zbs" in ispec["ISA"]: self.isa += '_Zbs' + if "Zbkb" in ispec["ISA"]: + self.isa += '_Zbkb' + if "Zbkc" in ispec["ISA"]: + self.isa += '_Zbkc' + if "Zknd" in ispec["ISA"]: + self.isa += '_Zknd' + if "Zkne" in ispec["ISA"]: + self.isa += '_Zkne' + if "Zbkx" in ispec["ISA"]: + self.isa += '_Zbkx' + if "Zknh" in ispec["ISA"]: + self.isa += '_Zknh' #TODO: The following assumes you are using the riscv-gcc toolchain. If # not please change appropriately diff --git a/tests/riscof/spike/spike_rv32e_isa.yaml b/tests/riscof/spike/spike_rv32e_isa.yaml index 9e9775a9bf..ee0aeec112 100644 --- a/tests/riscof/spike/spike_rv32e_isa.yaml +++ b/tests/riscof/spike/spike_rv32e_isa.yaml @@ -1,6 +1,6 @@ hart_ids: [0] hart0: - ISA: RV32EMCZicsr_Zifencei + ISA: RV32EMCZicsr_Zifencei_Zbkc physical_addr_sz: 32 User_Spec_Version: '2.3' supported_xlen: [32] diff --git a/tests/riscof/spike/spike_rv32gc_isa.yaml b/tests/riscof/spike/spike_rv32gc_isa.yaml index c2c95fbf41..1879440ed2 100644 --- a/tests/riscof/spike/spike_rv32gc_isa.yaml +++ b/tests/riscof/spike/spike_rv32gc_isa.yaml @@ -1,6 +1,7 @@ hart_ids: [0] hart0: - ISA: RV32IMAFDCZicsr_Zicond_Zifencei_Zfa_Zfh_Zba_Zbb_Zbc_Zbs + ISA: RV32IMAFDCZicsr_Zicond_Zifencei_Zfa_Zfh_Zba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh +# ISA: RV32IMAFDCZicsr_Zicond_Zifencei_Zfa_Zfh_Zba_Zbb_Zbc_Zbs # ISA: RV32IMAFDCZicsr_Zicboz_Zifencei_Zca_Zba_Zbb_Zbc_Zbs # _Zbkb_Zcb physical_addr_sz: 32 User_Spec_Version: '2.3' diff --git a/tests/riscof/spike/spike_rv64gc_isa.yaml b/tests/riscof/spike/spike_rv64gc_isa.yaml index 4374ad07c3..f7e6b8c73c 100644 --- a/tests/riscof/spike/spike_rv64gc_isa.yaml +++ b/tests/riscof/spike/spike_rv64gc_isa.yaml @@ -2,12 +2,12 @@ hart_ids: [0] hart0: # ISA: RV64IMAFDCSUZicsr_Zicboz_Zifencei_Zba_Zbb_Zbc_Zbs # Zkbs_Zcb # ISA: RV64IMAFDCSUZicsr_Zifencei_Zca_Zcb_Zba_Zbb_Zbc_Zbs # Zkbs_Zcb - ISA: RV64IMAFDCSUZicsr_Zicond_Zifencei_Zfa_Zfh_Zba_Zbb_Zbc_Zbs # Zkbs_Zcb + ISA: RV64IMAFDQCSUZicsr_Zicond_Zifencei_Zfa_Zfh_Zba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh physical_addr_sz: 56 User_Spec_Version: '2.3' supported_xlen: [64] misa: - reset-val: 0x800000000014112D + reset-val: 0x800000000015112D rv32: accessible: false rv64: diff --git a/tests/vcs_examples/README.md b/tests/vcs_examples/README.md new file mode 100644 index 0000000000..6337401f9f --- /dev/null +++ b/tests/vcs_examples/README.md @@ -0,0 +1,27 @@ +# VCS Testbench Setup +Steps to configure and run the testbench using Synopsys VCS. Follow these instructions to Synopsys VCS simulation. + +## Dependencies +- Verilator (tested with Verilator 5.021 devel rev v5.020-16-g7507c5f56) +- Synopsys VCS + +## Running Simulations +```bash +cd cvw/tests/vcs_examples +cd /block_level_tests/generic ##select specific test directory +cd flop or cd flop_empty +``` +### Verilator +To simulate with Verilator, follow these steps: + ```bash + make verilate + ``` +### VCS + ```bash + make vcs + ``` +## Cleaning Build Artifacts +To clean up all generated files and prepare for a fresh simulation, run: +```bash +make clean +``` diff --git a/tests/vcs_examples/block_level_tests/generic/flop/.fsm.sch.verilog.xml b/tests/vcs_examples/block_level_tests/generic/flop/.fsm.sch.verilog.xml new file mode 100644 index 0000000000..ae8416a81d --- /dev/null +++ b/tests/vcs_examples/block_level_tests/generic/flop/.fsm.sch.verilog.xml @@ -0,0 +1,2 @@ + + diff --git a/tests/vcs_examples/block_level_tests/generic/flop/Makefile b/tests/vcs_examples/block_level_tests/generic/flop/Makefile new file mode 100644 index 0000000000..b131cde678 --- /dev/null +++ b/tests/vcs_examples/block_level_tests/generic/flop/Makefile @@ -0,0 +1,61 @@ +# Makefile for running a design with Verilator and VCS + +# Variables +DESIGN_FILE = top_flop.sv +VERILATOR_TESTBENCH = tb_flop.cpp +VCS_TESTBENCH = tb_flop.sv +TOP_MODULE = top_flop # Specify your top-level module name here +BUILD_DIR = obj_dir +SOURCE_PATH = +incdir+../../../../../src/generic/flop/ +SIMFILES = ../../../../../src/generic/flop/*.sv + +# Verilator specific +VERILATOR = verilator +VERILATOR_FLAGS = -Wall --cc --exe --trace --timing -Wno-SYMRSVDWORD + +# VCS specific +VCS = vcs +# Enable code coverage and specify the directory for coverage results +VCS_FLAGS = -full64 -sverilog +v2k -debug_acc+all+dmptf -debug_region+cell+encrypt +CODE_COV_FLAGS= -cm line+cond+fsm+tgl+branch -cm_dir COVERAGE +# To handle the ASLR-related behavior/message +SIM_FLAGS = -no_save + +# Default target +all: + @echo "Specify 'make verilate' for Verilator or 'make vcs' for VCS." + + +# Verilate and run with Verilator +verilate: clean_verilate + $(VERILATOR) $(VERILATOR_FLAGS) $(SIMFILES) --top-module $(TOP_MODULE) --relative-includes $(DESIGN_FILE) + + +# Compile and run with VCS with code coverage +vcs: clean_vcs + mkdir -p $(BUILD_DIR) # Ensure the build directory exists + mkdir -p $(BUILD_DIR)/coverage # Ensure the coverage directory exists as well + # To specify a different top-level module, replace $(TOP_MODULE) with your module name in the VCS command below + # $(VCS) $(VCS_FLAGS) $(SOURCE_PATH) $(SIMFILES) $(CODE_COV_FLAGS) $(DESIGN_FILE) $(VCS_TESTBENCH) -o $(BUILD_DIR)/vcs_simv + $(VCS) $(VCS_FLAGS) $(SOURCE_PATH) $(SIMFILES) $(DESIGN_FILE) $(VCS_TESTBENCH) -o $(BUILD_DIR)/vcs_simv + ./$(BUILD_DIR)/vcs_simv $(SIM_FLAGS) + # Generate and view the coverage report + #urg -lca -dir COVERAGE.vdb + +# To pass parameters to your simulation, you can use the +define+NAME=VALUE syntax with VCS. +# For example, to define a parameter named PARAM with a value of 10, add '+define+PARAM=10' to the VCS_FLAGS variable. + +# Clean up Verilator generated files +clean_verilate: + rm -rf $(BUILD_DIR) + +# Clean up VCS generated files and coverage reports +clean_vcs: + rm -rf csrc $(BUILD_DIR)/vcs_simv.daidir $(BUILD_DIR)/vcs_simv ucli.key vc_hdrs.h $(BUILD_DIR)/coverage + +# Clean up all generated files +clean: clean_verilate clean_vcs + rm -rf *.vcd + +.PHONY: all verilate vcs clean clean_verilate clean_vcs + diff --git a/tests/vcs_examples/block_level_tests/generic/flop/tb_flop.cpp b/tests/vcs_examples/block_level_tests/generic/flop/tb_flop.cpp new file mode 100644 index 0000000000..02365e2d39 --- /dev/null +++ b/tests/vcs_examples/block_level_tests/generic/flop/tb_flop.cpp @@ -0,0 +1,54 @@ +#include +#include "Vtop_flop.h" // Generated model header for top_flop +#include // Header for VCD tracing + +vluint64_t main_time = 0; // Current simulation time + +// Called by $time in Verilog +double sc_time_stamp() { + return main_time; // Note does conversion to real, to match SystemC +} + +int main(int argc, char** argv, char** env) { + Verilated::commandArgs(argc, argv); // Initialize Verilator's variables + Vtop_flop* top = new Vtop_flop; // Create an instance of our module under test + + Verilated::traceEverOn(true); // Enable waveform generation + VerilatedVcdC* tfp = new VerilatedVcdC; + top->trace(tfp, 99); // Trace 99 levels of hierarchy + tfp->open("top_flop.vcd"); // Open the waveform output + + top->reset = 1; // Start in reset + + while (main_time < 1000 && !Verilated::gotFinish()) { + if (main_time % 10 == 0) { + top->clk = !top->clk; // Toggle clock every 10 simulation cycles + } + if (main_time == 15) { + top->reset = 0; // Release reset + } + + // Randomly manipulate inputs every cycle after reset + if (main_time > 15) { + top->set = rand() % 2; + top->clear = rand() % 2; + top->en = rand() % 2; + top->load = rand() % 2; + top->d = rand() % 256; + top->val = rand() % 256; + top->d_sync = rand() % 2; + } + + top->eval(); // Evaluate model + tfp->dump(main_time); // Dump trace data for this cycle + + main_time++; // Time passes... + } + + top->final(); // Done simulating + tfp->close(); // Close the waveform + delete top; + delete tfp; + return 0; +} + diff --git a/tests/vcs_examples/block_level_tests/generic/flop/tb_flop.sv b/tests/vcs_examples/block_level_tests/generic/flop/tb_flop.sv new file mode 100644 index 0000000000..07462bf6ba --- /dev/null +++ b/tests/vcs_examples/block_level_tests/generic/flop/tb_flop.sv @@ -0,0 +1,40 @@ +module tb_flop; + + logic clk, reset, clear, en, load, set; + logic [7:0] d, val; + logic d_sync; + logic [7:0] q_flop, q_flopenl, q_flopenrc, q_flopenr, q_flopens, q_flopen, q_flopr; + logic q_sync; + + // Instantiate the top module + top_flop dut( + .clk(clk), .reset(reset), .clear(clear), .en(en), .load(load), .set(set), + .d(d), .val(val), + .q_flop(q_flop), .q_flopenl(q_flopenl), .q_flopenrc(q_flopenrc), .q_flopenr(q_flopenr), .q_flopens(q_flopens), .q_flopen(q_flopen), .q_flopr(q_flopr), + .d_sync(d_sync), .q_sync(q_sync) + ); + + // Clock generation + initial begin + clk = 0; + forever #5 clk = ~clk; // Generate a clock with 100MHz frequency + end + + // Apply random inputs and dump VCD + initial begin + $dumpfile("tb_flop.vcd"); + $dumpvars(0, tb_flop); + + reset = 1; clear = 0; en = 0; load = 0; set = 0; d = 0; val = 0; d_sync = 0; + #10 reset = 0; // Release reset after 10ns + + repeat (100) begin + #10; // Every 10ns, apply new random inputs + reset = $random; clear = $random; en = $random; load = $random; set = $random; + d = $urandom%256; val = $urandom%256; d_sync = $urandom%2; + end + + $finish; + end +endmodule + diff --git a/tests/vcs_examples/block_level_tests/generic/flop/tb_flop.vcd b/tests/vcs_examples/block_level_tests/generic/flop/tb_flop.vcd new file mode 100644 index 0000000000..7779b8ebb1 --- /dev/null +++ b/tests/vcs_examples/block_level_tests/generic/flop/tb_flop.vcd @@ -0,0 +1,6165 @@ +$date + Fri Mar 15 08:44:48 2024 +$end + +$version + Synopsys VCS version U-2023.03-SP2-4_Full64 +$end + +$timescale + 1s +$end + +$comment Csum: 1 b8c1dc1d2724083a $end + + +$scope module tb_flop $end +$var reg 1 ! clk $end +$var reg 1 " reset $end +$var reg 1 # clear $end +$var reg 1 $ en $end +$var reg 1 % load $end +$var reg 1 & set $end +$var reg 8 ' d [7:0] $end +$var reg 8 ( val [7:0] $end +$var reg 1 ) d_sync $end +$var reg 8 * q_flop [7:0] $end +$var reg 8 + q_flopenl [7:0] $end +$var reg 8 , q_flopenrc [7:0] $end +$var reg 8 - q_flopenr [7:0] $end +$var reg 8 . q_flopens [7:0] $end +$var reg 8 / q_flopen [7:0] $end +$var reg 8 0 q_flopr [7:0] $end +$var reg 1 1 q_sync $end + +$scope begin unnamed$$_vcs_0 $end +$upscope $end + + +$scope module dut $end +$var reg 1 2 clk $end +$var reg 1 3 reset $end +$var reg 1 4 clear $end +$var reg 1 5 en $end +$var reg 1 6 load $end +$var reg 1 7 set $end +$var reg 8 8 d [7:0] $end +$var reg 8 9 val [7:0] $end +$var reg 8 : q_flop [7:0] $end +$var reg 8 ; q_flopenl [7:0] $end +$var reg 8 < q_flopenrc [7:0] $end +$var reg 8 = q_flopenr [7:0] $end +$var reg 8 > q_flopens [7:0] $end +$var reg 8 ? q_flopen [7:0] $end +$var reg 8 @ q_flopr [7:0] $end +$var reg 1 A d_sync $end +$var reg 1 B q_sync $end + +$scope module flop_inst $end +$var reg 1 C clk $end +$var reg 8 D d [7:0] $end +$var reg 8 E q [7:0] $end +$upscope $end + + +$scope module flopenl_inst $end +$var reg 1 F clk $end +$var reg 1 G load $end +$var reg 1 H en $end +$var reg 8 I d [7:0] $end +$var reg 8 J val [7:0] $end +$var reg 8 K q [7:0] $end +$upscope $end + + +$scope module flopenrc_inst $end +$var reg 1 L clk $end +$var reg 1 M reset $end +$var reg 1 N clear $end +$var reg 1 O en $end +$var reg 8 P d [7:0] $end +$var reg 8 Q q [7:0] $end +$upscope $end + + +$scope module flopenr_inst $end +$var reg 1 R clk $end +$var reg 1 S reset $end +$var reg 1 T en $end +$var reg 8 U d [7:0] $end +$var reg 8 V q [7:0] $end +$upscope $end + + +$scope module flopens_inst $end +$var reg 1 W clk $end +$var reg 1 X set $end +$var reg 1 Y en $end +$var reg 8 Z d [7:0] $end +$var reg 8 [ q [7:0] $end +$upscope $end + + +$scope module flopen_inst $end +$var reg 1 \ clk $end +$var reg 1 ] en $end +$var reg 8 ^ d [7:0] $end +$var reg 8 _ q [7:0] $end +$upscope $end + + +$scope module flopr_inst $end +$var reg 1 ` clk $end +$var reg 1 a reset $end +$var reg 8 b d [7:0] $end +$var reg 8 c q [7:0] $end +$upscope $end + + +$scope module synchronizer_inst $end +$var reg 1 d clk $end +$var reg 1 e d $end +$var reg 1 f q $end +$var reg 1 g mid $end +$upscope $end + +$upscope $end + +$upscope $end + +$enddefinitions $end + +#0 +$dumpvars +0# +0! +0) +04 +0A +05 +06 +xB +13 +07 +0$ +0] +0H +0G +0T +1S +0N +0O +1M +0Y +0X +1a +0% +xg +x1 +1" +0& +0e +xf +b00000000 I +bxxxxxxxx K +b00000000 J +b00000000 ' +b00000000 8 +bxxxxxxxx : +bxxxxxxxx ? +bxxxxxxxx ; +bxxxxxxxx = +bxxxxxxxx < +bxxxxxxxx > +bxxxxxxxx @ +b00000000 9 +b00000000 D +b00000000 ^ +bxxxxxxxx _ +b00000000 U +bxxxxxxxx V +b00000000 P +bxxxxxxxx Q +b00000000 Z +bxxxxxxxx [ +b00000000 b +bxxxxxxxx c +bxxxxxxxx E +bxxxxxxxx * +bxxxxxxxx / +bxxxxxxxx + +bxxxxxxxx - +bxxxxxxxx , +bxxxxxxxx . +bxxxxxxxx 0 +b00000000 ( +02 +0C +0F +0L +0R +0W +0\ +0` +0d +$end +#5 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#6 +b00000000 E +b00000000 : +b00000000 * +b00000000 Q +b00000000 < +b00000000 , +b00000000 V +b00000000 = +b00000000 - +b00000000 c +b00000000 @ +b00000000 0 +0g +#10 +0" +03 +0a +0S +0M +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#15 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#16 +0f +0B +01 +#20 +1# +14 +1N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b00010011 ' +b00010011 8 +b00010011 b +b00010011 ^ +b00010011 Z +b00010011 U +b00010011 P +b00010011 I +b00010011 D +b01110000 ( +b01110000 9 +b01110000 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#25 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#26 +b00010011 E +b00010011 : +b00010011 * +b01110000 K +b01110000 ; +b01110000 + +b00010011 V +b00010011 = +b00010011 - +b00000001 [ +b00000001 > +b00000001 . +b00010011 _ +b00010011 ? +b00010011 / +b00010011 c +b00010011 @ +b00010011 0 +1g +#30 +1" +13 +1a +1S +1M +0$ +05 +0] +0Y +0T +0O +0H +b11100010 ' +b11100010 8 +b11100010 b +b11100010 ^ +b11100010 Z +b11100010 U +b11100010 P +b11100010 I +b11100010 D +b10010111 ( +b10010111 9 +b10010111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#35 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#36 +b11100010 E +b11100010 : +b11100010 * +b10010111 K +b10010111 ; +b10010111 + +b00000000 V +b00000000 = +b00000000 - +b00000000 c +b00000000 @ +b00000000 0 +1f +1B +11 +#40 +0" +03 +0a +0S +0M +1$ +15 +1] +1Y +1T +1O +1H +0% +06 +0G +b11000101 ' +b11000101 8 +b11000101 b +b11000101 ^ +b11000101 Z +b11000101 U +b11000101 P +b11000101 I +b11000101 D +b11101100 ( +b11101100 9 +b11101100 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#45 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#46 +b11000101 E +b11000101 : +b11000101 * +b11000101 K +b11000101 ; +b11000101 + +b11000101 V +b11000101 = +b11000101 - +b11000101 _ +b11000101 ? +b11000101 / +b11000101 c +b11000101 @ +b11000101 0 +0g +#50 +0$ +05 +0] +0Y +0T +0O +0H +1% +16 +1G +b00001100 ' +b00001100 8 +b00001100 b +b00001100 ^ +b00001100 Z +b00001100 U +b00001100 P +b00001100 I +b00001100 D +b00101100 ( +b00101100 9 +b00101100 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#55 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#56 +b00001100 E +b00001100 : +b00001100 * +b00101100 K +b00101100 ; +b00101100 + +b00001100 c +b00001100 @ +b00001100 0 +1g +0f +0B +01 +#60 +0% +06 +0G +0& +07 +0X +b00011011 ' +b00011011 8 +b00011011 b +b00011011 ^ +b00011011 Z +b00011011 U +b00011011 P +b00011011 I +b00011011 D +b01000101 ( +b01000101 9 +b01000101 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#65 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#66 +b00011011 E +b00011011 : +b00011011 * +b00011011 c +b00011011 @ +b00011011 0 +0g +1f +1B +11 +#70 +1" +13 +1a +1S +1M +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b01101100 ' +b01101100 8 +b01101100 b +b01101100 ^ +b01101100 Z +b01101100 U +b01101100 P +b01101100 I +b01101100 D +b01100111 ( +b01100111 9 +b01100111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#75 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#76 +b01101100 E +b01101100 : +b01101100 * +b01100111 K +b01100111 ; +b01100111 + +b00000000 V +b00000000 = +b00000000 - +b01101100 _ +b01101100 ? +b01101100 / +b00000000 c +b00000000 @ +b00000000 0 +0f +0B +01 +#80 +0$ +05 +0] +0Y +0T +0O +0H +0% +06 +0G +0& +07 +0X +b01001010 ' +b01001010 8 +b01001010 b +b01001010 ^ +b01001010 Z +b01001010 U +b01001010 P +b01001010 I +b01001010 D +b10100110 ( +b10100110 9 +b10100110 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#85 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#86 +b01001010 E +b01001010 : +b01001010 * +1g +#90 +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b10011101 ' +b10011101 8 +b10011101 b +b10011101 ^ +b10011101 Z +b10011101 U +b10011101 P +b10011101 I +b10011101 D +b01111100 ( +b01111100 9 +b01111100 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#95 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#96 +b10011101 E +b10011101 : +b10011101 * +b01111100 K +b01111100 ; +b01111100 + +b10011101 _ +b10011101 ? +b10011101 / +0g +1f +1B +11 +#100 +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +0% +06 +0G +b11101011 ' +b11101011 8 +b11101011 b +b11101011 ^ +b11101011 Z +b11101011 U +b11101011 P +b11101011 I +b11101011 D +b01011011 ( +b01011011 9 +b01011011 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#105 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#106 +b11101011 E +b11101011 : +b11101011 * +1g +0f +0B +01 +#110 +0& +07 +0X +b01001101 ' +b01001101 8 +b01001101 b +b01001101 ^ +b01001101 Z +b01001101 U +b01001101 P +b01001101 I +b01001101 D +b01011100 ( +b01011100 9 +b01011100 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#115 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#116 +b01001101 E +b01001101 : +b01001101 * +0g +1f +1B +11 +#120 +0" +03 +0a +0S +0M +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +b11011001 ' +b11011001 8 +b11011001 b +b11011001 ^ +b11011001 Z +b11011001 U +b11011001 P +b11011001 I +b11011001 D +b10101001 ( +b10101001 9 +b10101001 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#125 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#126 +b11011001 E +b11011001 : +b11011001 * +b11011001 K +b11011001 ; +b11011001 + +b11011001 Q +b11011001 < +b11011001 , +b11011001 V +b11011001 = +b11011001 - +b11011001 [ +b11011001 > +b11011001 . +b11011001 _ +b11011001 ? +b11011001 / +b11011001 c +b11011001 @ +b11011001 0 +0f +0B +01 +#130 +1" +13 +1a +1S +1M +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +b10011110 ' +b10011110 8 +b10011110 b +b10011110 ^ +b10011110 Z +b10011110 U +b10011110 P +b10011110 I +b10011110 D +b11001000 ( +b11001000 9 +b11001000 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#135 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#136 +b10011110 E +b10011110 : +b10011110 * +b00000000 Q +b00000000 < +b00000000 , +b00000000 V +b00000000 = +b00000000 - +b00000000 c +b00000000 @ +b00000000 0 +1g +#140 +0" +03 +0a +0S +0M +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b00100110 ' +b00100110 8 +b00100110 b +b00100110 ^ +b00100110 Z +b00100110 U +b00100110 P +b00100110 I +b00100110 D +b11110110 ( +b11110110 9 +b11110110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#145 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#146 +b00100110 E +b00100110 : +b00100110 * +b11110110 K +b11110110 ; +b11110110 + +b00100110 Q +b00100110 < +b00100110 , +b00100110 V +b00100110 = +b00100110 - +b00000001 [ +b00000001 > +b00000001 . +b00100110 _ +b00100110 ? +b00100110 / +b00100110 c +b00100110 @ +b00100110 0 +0g +1f +1B +11 +#150 +1" +13 +1a +1S +1M +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +0% +06 +0G +b01011011 ' +b01011011 8 +b01011011 b +b01011011 ^ +b01011011 Z +b01011011 U +b01011011 P +b01011011 I +b01011011 D +b01000010 ( +b01000010 9 +b01000010 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#155 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#156 +b01011011 E +b01011011 : +b01011011 * +b00000000 Q +b00000000 < +b00000000 , +b00000000 V +b00000000 = +b00000000 - +b00000000 c +b00000000 @ +b00000000 0 +1g +0f +0B +01 +#160 +b10010001 ' +b10010001 8 +b10010001 b +b10010001 ^ +b10010001 Z +b10010001 U +b10010001 P +b10010001 I +b10010001 D +b00111000 ( +b00111000 9 +b00111000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#165 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#166 +b10010001 E +b10010001 : +b10010001 * +1f +1B +11 +#170 +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +0& +07 +0X +b01101101 ' +b01101101 8 +b01101101 b +b01101101 ^ +b01101101 Z +b01101101 U +b01101101 P +b01101101 I +b01101101 D +b11000010 ( +b11000010 9 +b11000010 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#175 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#176 +b01101101 E +b01101101 : +b01101101 * +b11000010 K +b11000010 ; +b11000010 + +b01101101 [ +b01101101 > +b01101101 . +b01101101 _ +b01101101 ? +b01101101 / +#180 +1# +14 +1N +0% +06 +0G +1& +17 +1X +b01111100 ' +b01111100 8 +b01111100 b +b01111100 ^ +b01111100 Z +b01111100 U +b01111100 P +b01111100 I +b01111100 D +b00101110 ( +b00101110 9 +b00101110 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#185 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#186 +b01111100 E +b01111100 : +b01111100 * +b01111100 K +b01111100 ; +b01111100 + +b00000001 [ +b00000001 > +b00000001 . +b01111100 _ +b01111100 ? +b01111100 / +#190 +0# +04 +0N +0$ +05 +0] +0Y +0T +0O +0H +0& +07 +0X +b00011101 ' +b00011101 8 +b00011101 b +b00011101 ^ +b00011101 Z +b00011101 U +b00011101 P +b00011101 I +b00011101 D +b11100011 ( +b11100011 9 +b11100011 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#195 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#196 +b00011101 E +b00011101 : +b00011101 * +0g +#200 +1# +14 +1N +1& +17 +1X +b00001010 ' +b00001010 8 +b00001010 b +b00001010 ^ +b00001010 Z +b00001010 U +b00001010 P +b00001010 I +b00001010 D +b00010011 ( +b00010011 9 +b00010011 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#205 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#206 +b00001010 E +b00001010 : +b00001010 * +0f +0B +01 +#210 +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +0& +07 +0X +b00111100 ' +b00111100 8 +b00111100 b +b00111100 ^ +b00111100 Z +b00111100 U +b00111100 P +b00111100 I +b00111100 D +b00111010 ( +b00111010 9 +b00111010 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#215 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#216 +b00111100 E +b00111100 : +b00111100 * +b00111010 K +b00111010 ; +b00111010 + +b00111100 [ +b00111100 > +b00111100 . +b00111100 _ +b00111100 ? +b00111100 / +#220 +0% +06 +0G +b11100111 ' +b11100111 8 +b11100111 b +b11100111 ^ +b11100111 Z +b11100111 U +b11100111 P +b11100111 I +b11100111 D +b10010111 ( +b10010111 9 +b10010111 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#225 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#226 +b11100111 E +b11100111 : +b11100111 * +b11100111 K +b11100111 ; +b11100111 + +b11100111 [ +b11100111 > +b11100111 . +b11100111 _ +b11100111 ? +b11100111 / +1g +#230 +0" +03 +0a +0S +0M +0# +04 +0N +0$ +05 +0] +0Y +0T +0O +0H +b11100011 ' +b11100011 8 +b11100011 b +b11100011 ^ +b11100011 Z +b11100011 U +b11100011 P +b11100011 I +b11100011 D +b00100000 ( +b00100000 9 +b00100000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#235 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#236 +b11100011 E +b11100011 : +b11100011 * +b11100011 c +b11100011 @ +b11100011 0 +1f +1B +11 +#240 +1" +13 +1a +1S +1M +1# +14 +1N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b10111111 ' +b10111111 8 +b10111111 b +b10111111 ^ +b10111111 Z +b10111111 U +b10111111 P +b10111111 I +b10111111 D +b10010001 ( +b10010001 9 +b10010001 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#245 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#246 +b10111111 E +b10111111 : +b10111111 * +b10010001 K +b10010001 ; +b10010001 + +b00000001 [ +b00000001 > +b00000001 . +b10111111 _ +b10111111 ? +b10111111 / +b00000000 c +b00000000 @ +b00000000 0 +#250 +0" +03 +0a +0S +0M +0% +06 +0G +0& +07 +0X +b01001100 ' +b01001100 8 +b01001100 b +b01001100 ^ +b01001100 Z +b01001100 U +b01001100 P +b01001100 I +b01001100 D +b01110110 ( +b01110110 9 +b01110110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#255 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#256 +b01001100 E +b01001100 : +b01001100 * +b01001100 K +b01001100 ; +b01001100 + +b01001100 V +b01001100 = +b01001100 - +b01001100 [ +b01001100 > +b01001100 . +b01001100 _ +b01001100 ? +b01001100 / +b01001100 c +b01001100 @ +b01001100 0 +0g +#260 +1" +13 +1a +1S +1M +0$ +05 +0] +0Y +0T +0O +0H +1% +16 +1G +1& +17 +1X +b00001100 ( +b00001100 9 +b00001100 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#265 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#266 +b00001100 K +b00001100 ; +b00001100 + +b00000000 V +b00000000 = +b00000000 - +b00000001 [ +b00000001 > +b00000001 . +b00000000 c +b00000000 @ +b00000000 0 +1g +0f +0B +01 +#270 +0% +06 +0G +0& +07 +0X +b11001000 ' +b11001000 8 +b11001000 b +b11001000 ^ +b11001000 Z +b11001000 U +b11001000 P +b11001000 I +b11001000 D +b00011111 ( +b00011111 9 +b00011111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#275 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#276 +b11001000 E +b11001000 : +b11001000 * +1f +1B +11 +#280 +0# +04 +0N +1& +17 +1X +b00100011 ' +b00100011 8 +b00100011 b +b00100011 ^ +b00100011 Z +b00100011 U +b00100011 P +b00100011 I +b00100011 D +b10011001 ( +b10011001 9 +b10011001 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#285 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#286 +b00100011 E +b00100011 : +b00100011 * +0g +#290 +1% +16 +1G +0& +07 +0X +b10001111 ' +b10001111 8 +b10001111 b +b10001111 ^ +b10001111 Z +b10001111 U +b10001111 P +b10001111 I +b10001111 D +b11110110 ( +b11110110 9 +b11110110 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#295 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#296 +b10001111 E +b10001111 : +b10001111 * +b11110110 K +b11110110 ; +b11110110 + +1g +0f +0B +01 +#300 +0" +03 +0a +0S +0M +1$ +15 +1] +1Y +1T +1O +1H +0% +06 +0G +b11110111 ' +b11110111 8 +b11110111 b +b11110111 ^ +b11110111 Z +b11110111 U +b11110111 P +b11110111 I +b11110111 D +b00001110 ( +b00001110 9 +b00001110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#305 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#306 +b11110111 E +b11110111 : +b11110111 * +b11110111 K +b11110111 ; +b11110111 + +b11110111 Q +b11110111 < +b11110111 , +b11110111 V +b11110111 = +b11110111 - +b11110111 [ +b11110111 > +b11110111 . +b11110111 _ +b11110111 ? +b11110111 / +b11110111 c +b11110111 @ +b11110111 0 +0g +1f +1B +11 +#310 +1" +13 +1a +1S +1M +1% +16 +1G +1& +17 +1X +b01101101 ' +b01101101 8 +b01101101 b +b01101101 ^ +b01101101 Z +b01101101 U +b01101101 P +b01101101 I +b01101101 D +b00000110 ( +b00000110 9 +b00000110 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#315 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#316 +b01101101 E +b01101101 : +b01101101 * +b00000110 K +b00000110 ; +b00000110 + +b00000000 Q +b00000000 < +b00000000 , +b00000000 V +b00000000 = +b00000000 - +b00000001 [ +b00000001 > +b00000001 . +b01101101 _ +b01101101 ? +b01101101 / +b00000000 c +b00000000 @ +b00000000 0 +0f +0B +01 +#320 +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +0% +06 +0G +0& +07 +0X +b00011010 ' +b00011010 8 +b00011010 b +b00011010 ^ +b00011010 Z +b00011010 U +b00011010 P +b00011010 I +b00011010 D +b10001111 ( +b10001111 9 +b10001111 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#325 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#326 +b00011010 E +b00011010 : +b00011010 * +1g +#330 +0# +04 +0N +1% +16 +1G +1& +17 +1X +b00101111 ' +b00101111 8 +b00101111 b +b00101111 ^ +b00101111 Z +b00101111 U +b00101111 P +b00101111 I +b00101111 D +b00100001 ( +b00100001 9 +b00100001 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#335 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#336 +b00101111 E +b00101111 : +b00101111 * +b00100001 K +b00100001 ; +b00100001 + +0g +1f +1B +11 +#340 +0" +03 +0a +0S +0M +b00001111 ' +b00001111 8 +b00001111 b +b00001111 ^ +b00001111 Z +b00001111 U +b00001111 P +b00001111 I +b00001111 D +b01110100 ( +b01110100 9 +b01110100 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#345 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#346 +b00001111 E +b00001111 : +b00001111 * +b01110100 K +b01110100 ; +b01110100 + +b00001111 c +b00001111 @ +b00001111 0 +0f +0B +01 +#350 +b01000111 ' +b01000111 8 +b01000111 b +b01000111 ^ +b01000111 Z +b01000111 U +b01000111 P +b01000111 I +b01000111 D +b00111101 ( +b00111101 9 +b00111101 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#355 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#356 +b01000111 E +b01000111 : +b01000111 * +b00111101 K +b00111101 ; +b00111101 + +b01000111 c +b01000111 @ +b01000111 0 +#360 +0& +07 +0X +b10011100 ' +b10011100 8 +b10011100 b +b10011100 ^ +b10011100 Z +b10011100 U +b10011100 P +b10011100 I +b10011100 D +b00111110 ( +b00111110 9 +b00111110 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#365 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#366 +b10011100 E +b10011100 : +b10011100 * +b00111110 K +b00111110 ; +b00111110 + +b10011100 c +b10011100 @ +b10011100 0 +#370 +1# +14 +1N +0% +06 +0G +b10010100 ' +b10010100 8 +b10010100 b +b10010100 ^ +b10010100 Z +b10010100 U +b10010100 P +b10010100 I +b10010100 D +b10100101 ( +b10100101 9 +b10100101 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#375 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#376 +b10010100 E +b10010100 : +b10010100 * +b10010100 c +b10010100 @ +b10010100 0 +1g +#380 +1" +13 +1a +1S +1M +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +b11100010 ' +b11100010 8 +b11100010 b +b11100010 ^ +b11100010 Z +b11100010 U +b11100010 P +b11100010 I +b11100010 D +b01000001 ( +b01000001 9 +b01000001 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#385 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#386 +b11100010 E +b11100010 : +b11100010 * +b01000001 K +b01000001 ; +b01000001 + +b11100010 [ +b11100010 > +b11100010 . +b11100010 _ +b11100010 ? +b11100010 / +b00000000 c +b00000000 @ +b00000000 0 +1f +1B +11 +#390 +0" +03 +0a +0S +0M +0$ +05 +0] +0Y +0T +0O +0H +b00110101 ' +b00110101 8 +b00110101 b +b00110101 ^ +b00110101 Z +b00110101 U +b00110101 P +b00110101 I +b00110101 D +b00011101 ( +b00011101 9 +b00011101 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#395 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#396 +b00110101 E +b00110101 : +b00110101 * +b00011101 K +b00011101 ; +b00011101 + +b00110101 c +b00110101 @ +b00110101 0 +0g +#400 +1& +17 +1X +b11000011 ' +b11000011 8 +b11000011 b +b11000011 ^ +b11000011 Z +b11000011 U +b11000011 P +b11000011 I +b11000011 D +b00111101 ( +b00111101 9 +b00111101 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#405 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#406 +b11000011 E +b11000011 : +b11000011 * +b00111101 K +b00111101 ; +b00111101 + +b00000001 [ +b00000001 > +b00000001 . +b11000011 c +b11000011 @ +b11000011 0 +1g +0f +0B +01 +#410 +1" +13 +1a +1S +1M +1$ +15 +1] +1Y +1T +1O +1H +b10111110 ' +b10111110 8 +b10111110 b +b10111110 ^ +b10111110 Z +b10111110 U +b10111110 P +b10111110 I +b10111110 D +b10001100 ( +b10001100 9 +b10001100 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#415 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#416 +b10111110 E +b10111110 : +b10111110 * +b10001100 K +b10001100 ; +b10001100 + +b10111110 _ +b10111110 ? +b10111110 / +b00000000 c +b00000000 @ +b00000000 0 +1f +1B +11 +#420 +0" +03 +0a +0S +0M +b00111000 ' +b00111000 8 +b00111000 b +b00111000 ^ +b00111000 Z +b00111000 U +b00111000 P +b00111000 I +b00111000 D +b11001110 ( +b11001110 9 +b11001110 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#425 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#426 +b00111000 E +b00111000 : +b00111000 * +b11001110 K +b11001110 ; +b11001110 + +b00111000 Q +b00111000 < +b00111000 , +b00111000 V +b00111000 = +b00111000 - +b00111000 _ +b00111000 ? +b00111000 / +b00111000 c +b00111000 @ +b00111000 0 +#430 +1" +13 +1a +1S +1M +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +b01100101 ' +b01100101 8 +b01100101 b +b01100101 ^ +b01100101 Z +b01100101 U +b01100101 P +b01100101 I +b01100101 D +b00001100 ( +b00001100 9 +b00001100 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#435 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#436 +b01100101 E +b01100101 : +b01100101 * +b00001100 K +b00001100 ; +b00001100 + +b00000000 Q +b00000000 < +b00000000 , +b00000000 V +b00000000 = +b00000000 - +b00000000 c +b00000000 @ +b00000000 0 +#440 +0" +03 +0a +0S +0M +0# +04 +0N +0% +06 +0G +b11110010 ' +b11110010 8 +b11110010 b +b11110010 ^ +b11110010 Z +b11110010 U +b11110010 P +b11110010 I +b11110010 D +b10000000 ( +b10000000 9 +b10000000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#445 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#446 +b11110010 E +b11110010 : +b11110010 * +b11110010 c +b11110010 @ +b11110010 0 +#450 +1" +13 +1a +1S +1M +1% +16 +1G +0& +07 +0X +b00010000 ' +b00010000 8 +b00010000 b +b00010000 ^ +b00010000 Z +b00010000 U +b00010000 P +b00010000 I +b00010000 D +b01100110 ( +b01100110 9 +b01100110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#455 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#456 +b00010000 E +b00010000 : +b00010000 * +b01100110 K +b01100110 ; +b01100110 + +b00000000 c +b00000000 @ +b00000000 0 +0g +#460 +0" +03 +0a +0S +0M +1# +14 +1N +0% +06 +0G +1& +17 +1X +b01010110 ' +b01010110 8 +b01010110 b +b01010110 ^ +b01010110 Z +b01010110 U +b01010110 P +b01010110 I +b01010110 D +b10110011 ( +b10110011 9 +b10110011 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#465 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#466 +b01010110 E +b01010110 : +b01010110 * +b01010110 c +b01010110 @ +b01010110 0 +0f +0B +01 +#470 +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +b01000110 ' +b01000110 8 +b01000110 b +b01000110 ^ +b01000110 Z +b01000110 U +b01000110 P +b01000110 I +b01000110 D +b01110100 ( +b01110100 9 +b01110100 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#475 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#476 +b01000110 E +b01000110 : +b01000110 * +b01110100 K +b01110100 ; +b01110100 + +b01000110 Q +b01000110 < +b01000110 , +b01000110 V +b01000110 = +b01000110 - +b01000110 _ +b01000110 ? +b01000110 / +b01000110 c +b01000110 @ +b01000110 0 +#480 +0$ +05 +0] +0Y +0T +0O +0H +0& +07 +0X +b00100100 ' +b00100100 8 +b00100100 b +b00100100 ^ +b00100100 Z +b00100100 U +b00100100 P +b00100100 I +b00100100 D +b00001111 ( +b00001111 9 +b00001111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#485 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#486 +b00100100 E +b00100100 : +b00100100 * +b00001111 K +b00001111 ; +b00001111 + +b00100100 c +b00100100 @ +b00100100 0 +#490 +1# +14 +1N +0% +06 +0G +b10100111 ' +b10100111 8 +b10100111 b +b10100111 ^ +b10100111 Z +b10100111 U +b10100111 P +b10100111 I +b10100111 D +b10111111 ( +b10111111 9 +b10111111 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#495 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#496 +b10100111 E +b10100111 : +b10100111 * +b10100111 c +b10100111 @ +b10100111 0 +1g +#500 +b00010010 ' +b00010010 8 +b00010010 b +b00010010 ^ +b00010010 Z +b00010010 U +b00010010 P +b00010010 I +b00010010 D +b00111010 ( +b00111010 9 +b00111010 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#505 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#506 +b00010010 E +b00010010 : +b00010010 * +b00010010 c +b00010010 @ +b00010010 0 +1f +1B +11 +#510 +1" +13 +1a +1S +1M +1% +16 +1G +1& +17 +1X +b01101101 ' +b01101101 8 +b01101101 b +b01101101 ^ +b01101101 Z +b01101101 U +b01101101 P +b01101101 I +b01101101 D +b10111110 ( +b10111110 9 +b10111110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#515 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#516 +b01101101 E +b01101101 : +b01101101 * +b10111110 K +b10111110 ; +b10111110 + +b00000000 Q +b00000000 < +b00000000 , +b00000000 V +b00000000 = +b00000000 - +b00000000 c +b00000000 @ +b00000000 0 +0g +#520 +b11010001 ' +b11010001 8 +b11010001 b +b11010001 ^ +b11010001 Z +b11010001 U +b11010001 P +b11010001 I +b11010001 D +b01110000 ( +b01110000 9 +b01110000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#525 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#526 +b11010001 E +b11010001 : +b11010001 * +b01110000 K +b01110000 ; +b01110000 + +0f +0B +01 +#530 +0# +04 +0N +0& +07 +0X +b10110100 ' +b10110100 8 +b10110100 b +b10110100 ^ +b10110100 Z +b10110100 U +b10110100 P +b10110100 I +b10110100 D +b10010101 ( +b10010101 9 +b10010101 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#535 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#536 +b10110100 E +b10110100 : +b10110100 * +b10010101 K +b10010101 ; +b10010101 + +1g +#540 +0" +03 +0a +0S +0M +1# +14 +1N +1$ +15 +1] +1Y +1T +1O +1H +0% +06 +0G +b00011010 ' +b00011010 8 +b00011010 b +b00011010 ^ +b00011010 Z +b00011010 U +b00011010 P +b00011010 I +b00011010 D +b10111000 ( +b10111000 9 +b10111000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#545 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#546 +b00011010 E +b00011010 : +b00011010 * +b00011010 K +b00011010 ; +b00011010 + +b00011010 V +b00011010 = +b00011010 - +b00011010 [ +b00011010 > +b00011010 . +b00011010 _ +b00011010 ? +b00011010 / +b00011010 c +b00011010 @ +b00011010 0 +1f +1B +11 +#550 +1" +13 +1a +1S +1M +0# +04 +0N +0$ +05 +0] +0Y +0T +0O +0H +1% +16 +1G +b10011101 ' +b10011101 8 +b10011101 b +b10011101 ^ +b10011101 Z +b10011101 U +b10011101 P +b10011101 I +b10011101 D +b00101010 ( +b00101010 9 +b00101010 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#555 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#556 +b10011101 E +b10011101 : +b10011101 * +b00101010 K +b00101010 ; +b00101010 + +b00000000 V +b00000000 = +b00000000 - +b00000000 c +b00000000 @ +b00000000 0 +#560 +1# +14 +1N +b11001100 ' +b11001100 8 +b11001100 b +b11001100 ^ +b11001100 Z +b11001100 U +b11001100 P +b11001100 I +b11001100 D +b00100011 ( +b00100011 9 +b00100011 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#565 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#566 +b11001100 E +b11001100 : +b11001100 * +b00100011 K +b00100011 ; +b00100011 + +#570 +0# +04 +0N +b11010001 ' +b11010001 8 +b11010001 b +b11010001 ^ +b11010001 Z +b11010001 U +b11010001 P +b11010001 I +b11010001 D +b01001010 ( +b01001010 9 +b01001010 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#575 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#576 +b11010001 E +b11010001 : +b11010001 * +b01001010 K +b01001010 ; +b01001010 + +0g +#580 +0" +03 +0a +0S +0M +1$ +15 +1] +1Y +1T +1O +1H +1& +17 +1X +b11010100 ' +b11010100 8 +b11010100 b +b11010100 ^ +b11010100 Z +b11010100 U +b11010100 P +b11010100 I +b11010100 D +b01000000 ( +b01000000 9 +b01000000 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#585 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#586 +b11010100 E +b11010100 : +b11010100 * +b01000000 K +b01000000 ; +b01000000 + +b11010100 Q +b11010100 < +b11010100 , +b11010100 V +b11010100 = +b11010100 - +b00000001 [ +b00000001 > +b00000001 . +b11010100 _ +b11010100 ? +b11010100 / +b11010100 c +b11010100 @ +b11010100 0 +1g +0f +0B +01 +#590 +1" +13 +1a +1S +1M +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +b10100011 ' +b10100011 8 +b10100011 b +b10100011 ^ +b10100011 Z +b10100011 U +b10100011 P +b10100011 I +b10100011 D +b01111101 ( +b01111101 9 +b01111101 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#595 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#596 +b10100011 E +b10100011 : +b10100011 * +b01111101 K +b01111101 ; +b01111101 + +b00000000 Q +b00000000 < +b00000000 , +b00000000 V +b00000000 = +b00000000 - +b00000000 c +b00000000 @ +b00000000 0 +1f +1B +11 +#600 +0# +04 +0N +0% +06 +0G +0& +07 +0X +b10111011 ' +b10111011 8 +b10111011 b +b10111011 ^ +b10111011 Z +b10111011 U +b10111011 P +b10111011 I +b10111011 D +b01110010 ( +b01110010 9 +b01110010 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#605 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#606 +b10111011 E +b10111011 : +b10111011 * +#610 +0" +03 +0a +0S +0M +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b10101000 ' +b10101000 8 +b10101000 b +b10101000 ^ +b10101000 Z +b10101000 U +b10101000 P +b10101000 I +b10101000 D +b01101001 ( +b01101001 9 +b01101001 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#615 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#616 +b10101000 E +b10101000 : +b10101000 * +b01101001 K +b01101001 ; +b01101001 + +b10101000 Q +b10101000 < +b10101000 , +b10101000 V +b10101000 = +b10101000 - +b10101000 _ +b10101000 ? +b10101000 / +b10101000 c +b10101000 @ +b10101000 0 +#620 +1" +13 +1a +1S +1M +1# +14 +1N +0& +07 +0X +b11001101 ' +b11001101 8 +b11001101 b +b11001101 ^ +b11001101 Z +b11001101 U +b11001101 P +b11001101 I +b11001101 D +b10001011 ( +b10001011 9 +b10001011 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#625 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#626 +b11001101 E +b11001101 : +b11001101 * +b10001011 K +b10001011 ; +b10001011 + +b00000000 Q +b00000000 < +b00000000 , +b00000000 V +b00000000 = +b00000000 - +b11001101 [ +b11001101 > +b11001101 . +b11001101 _ +b11001101 ? +b11001101 / +b00000000 c +b00000000 @ +b00000000 0 +#630 +1& +17 +1X +b01101100 ' +b01101100 8 +b01101100 b +b01101100 ^ +b01101100 Z +b01101100 U +b01101100 P +b01101100 I +b01101100 D +b01011011 ( +b01011011 9 +b01011011 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#635 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#636 +b01101100 E +b01101100 : +b01101100 * +b01011011 K +b01011011 ; +b01011011 + +b00000001 [ +b00000001 > +b00000001 . +b01101100 _ +b01101100 ? +b01101100 / +#640 +0% +06 +0G +0& +07 +0X +b11101010 ' +b11101010 8 +b11101010 b +b11101010 ^ +b11101010 Z +b11101010 U +b11101010 P +b11101010 I +b11101010 D +b10011001 ( +b10011001 9 +b10011001 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#645 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#646 +b11101010 E +b11101010 : +b11101010 * +b11101010 K +b11101010 ; +b11101010 + +b11101010 [ +b11101010 > +b11101010 . +b11101010 _ +b11101010 ? +b11101010 / +#650 +0$ +05 +0] +0Y +0T +0O +0H +b10111100 ' +b10111100 8 +b10111100 b +b10111100 ^ +b10111100 Z +b10111100 U +b10111100 P +b10111100 I +b10111100 D +b00101101 ( +b00101101 9 +b00101101 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#655 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#656 +b10111100 E +b10111100 : +b10111100 * +#660 +0" +03 +0a +0S +0M +b10100111 ' +b10100111 8 +b10100111 b +b10100111 ^ +b10100111 Z +b10100111 U +b10100111 P +b10100111 I +b10100111 D +b00110011 ( +b00110011 9 +b00110011 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#665 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#666 +b10100111 E +b10100111 : +b10100111 * +b10100111 c +b10100111 @ +b10100111 0 +0g +#670 +0# +04 +0N +1% +16 +1G +b11101000 ' +b11101000 8 +b11101000 b +b11101000 ^ +b11101000 Z +b11101000 U +b11101000 P +b11101000 I +b11101000 D +b10001001 ( +b10001001 9 +b10001001 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#675 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#676 +b11101000 E +b11101000 : +b11101000 * +b10001001 K +b10001001 ; +b10001001 + +b11101000 c +b11101000 @ +b11101000 0 +0f +0B +01 +#680 +1# +14 +1N +0% +06 +0G +b00101010 ' +b00101010 8 +b00101010 b +b00101010 ^ +b00101010 Z +b00101010 U +b00101010 P +b00101010 I +b00101010 D +b10101100 ( +b10101100 9 +b10101100 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#685 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#686 +b00101010 E +b00101010 : +b00101010 * +b00101010 c +b00101010 @ +b00101010 0 +#690 +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b10001111 ' +b10001111 8 +b10001111 b +b10001111 ^ +b10001111 Z +b10001111 U +b10001111 P +b10001111 I +b10001111 D +b11010011 ( +b11010011 9 +b11010011 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#695 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#696 +b10001111 E +b10001111 : +b10001111 * +b11010011 K +b11010011 ; +b11010011 + +b10001111 V +b10001111 = +b10001111 - +b00000001 [ +b00000001 > +b00000001 . +b10001111 _ +b10001111 ? +b10001111 / +b10001111 c +b10001111 @ +b10001111 0 +#700 +1" +13 +1a +1S +1M +0# +04 +0N +b11101100 ' +b11101100 8 +b11101100 b +b11101100 ^ +b11101100 Z +b11101100 U +b11101100 P +b11101100 I +b11101100 D +b10010010 ( +b10010010 9 +b10010010 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#705 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#706 +b11101100 E +b11101100 : +b11101100 * +b10010010 K +b10010010 ; +b10010010 + +b00000000 V +b00000000 = +b00000000 - +b11101100 _ +b11101100 ? +b11101100 / +b00000000 c +b00000000 @ +b00000000 0 +#710 +0" +03 +0a +0S +0M +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +0% +06 +0G +b01101101 ' +b01101101 8 +b01101101 b +b01101101 ^ +b01101101 Z +b01101101 U +b01101101 P +b01101101 I +b01101101 D +b01101000 ( +b01101000 9 +b01101000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#715 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#716 +b01101101 E +b01101101 : +b01101101 * +b01101101 c +b01101101 @ +b01101101 0 +#720 +1" +13 +1a +1S +1M +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +0& +07 +0X +b10100000 ' +b10100000 8 +b10100000 b +b10100000 ^ +b10100000 Z +b10100000 U +b10100000 P +b10100000 I +b10100000 D +b01100110 ( +b01100110 9 +b01100110 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#725 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#726 +b10100000 E +b10100000 : +b10100000 * +b10100000 K +b10100000 ; +b10100000 + +b10100000 [ +b10100000 > +b10100000 . +b10100000 _ +b10100000 ? +b10100000 / +b00000000 c +b00000000 @ +b00000000 0 +1g +#730 +0$ +05 +0] +0Y +0T +0O +0H +b01111110 ' +b01111110 8 +b01111110 b +b01111110 ^ +b01111110 Z +b01111110 U +b01111110 P +b01111110 I +b01111110 D +b10001000 ( +b10001000 9 +b10001000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#735 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#736 +b01111110 E +b01111110 : +b01111110 * +1f +1B +11 +#740 +1# +14 +1N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +b00101100 ' +b00101100 8 +b00101100 b +b00101100 ^ +b00101100 Z +b00101100 U +b00101100 P +b00101100 I +b00101100 D +b00010110 ( +b00010110 9 +b00010110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#745 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#746 +b00101100 E +b00101100 : +b00101100 * +b00010110 K +b00010110 ; +b00010110 + +b00101100 [ +b00101100 > +b00101100 . +b00101100 _ +b00101100 ? +b00101100 / +0g +#750 +1& +17 +1X +b01110001 ' +b01110001 8 +b01110001 b +b01110001 ^ +b01110001 Z +b01110001 U +b01110001 P +b01110001 I +b01110001 D +b11110111 ( +b11110111 9 +b11110111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#755 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#756 +b01110001 E +b01110001 : +b01110001 * +b11110111 K +b11110111 ; +b11110111 + +b00000001 [ +b00000001 > +b00000001 . +b01110001 _ +b01110001 ? +b01110001 / +0f +0B +01 +#760 +0$ +05 +0] +0Y +0T +0O +0H +0& +07 +0X +b00011100 ' +b00011100 8 +b00011100 b +b00011100 ^ +b00011100 Z +b00011100 U +b00011100 P +b00011100 I +b00011100 D +b00001111 ( +b00001111 9 +b00001111 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#765 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#766 +b00011100 E +b00011100 : +b00011100 * +b00001111 K +b00001111 ; +b00001111 + +1g +#770 +0# +04 +0N +b01111100 ' +b01111100 8 +b01111100 b +b01111100 ^ +b01111100 Z +b01111100 U +b01111100 P +b01111100 I +b01111100 D +b00110100 ( +b00110100 9 +b00110100 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#775 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#776 +b01111100 E +b01111100 : +b01111100 * +b00110100 K +b00110100 ; +b00110100 + +0g +1f +1B +11 +#780 +0" +03 +0a +0S +0M +0% +06 +0G +1& +17 +1X +b00100011 ' +b00100011 8 +b00100011 b +b00100011 ^ +b00100011 Z +b00100011 U +b00100011 P +b00100011 I +b00100011 D +b11010010 ( +b11010010 9 +b11010010 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#785 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#786 +b00100011 E +b00100011 : +b00100011 * +b00100011 c +b00100011 @ +b00100011 0 +1g +0f +0B +01 +#790 +0& +07 +0X +b00111010 ' +b00111010 8 +b00111010 b +b00111010 ^ +b00111010 Z +b00111010 U +b00111010 P +b00111010 I +b00111010 D +b00010000 ( +b00010000 9 +b00010000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#795 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#796 +b00111010 E +b00111010 : +b00111010 * +b00111010 c +b00111010 @ +b00111010 0 +1f +1B +11 +#800 +1# +14 +1N +1% +16 +1G +b11110001 ' +b11110001 8 +b11110001 b +b11110001 ^ +b11110001 Z +b11110001 U +b11110001 P +b11110001 I +b11110001 D +b01100111 ( +b01100111 9 +b01100111 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#805 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#806 +b11110001 E +b11110001 : +b11110001 * +b01100111 K +b01100111 ; +b01100111 + +b11110001 c +b11110001 @ +b11110001 0 +0g +#810 +1& +17 +1X +b01011011 ' +b01011011 8 +b01011011 b +b01011011 ^ +b01011011 Z +b01011011 U +b01011011 P +b01011011 I +b01011011 D +b01101101 ( +b01101101 9 +b01101101 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#815 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#816 +b01011011 E +b01011011 : +b01011011 * +b01101101 K +b01101101 ; +b01101101 + +b01011011 c +b01011011 @ +b01011011 0 +1g +0f +0B +01 +#820 +0& +07 +0X +b10000101 ' +b10000101 8 +b10000101 b +b10000101 ^ +b10000101 Z +b10000101 U +b10000101 P +b10000101 I +b10000101 D +b00000111 ( +b00000111 9 +b00000111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#825 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#826 +b10000101 E +b10000101 : +b10000101 * +b00000111 K +b00000111 ; +b00000111 + +b10000101 c +b10000101 @ +b10000101 0 +1f +1B +11 +#830 +0# +04 +0N +b01110110 ' +b01110110 8 +b01110110 b +b01110110 ^ +b01110110 Z +b01110110 U +b01110110 P +b01110110 I +b01110110 D +b10011111 ( +b10011111 9 +b10011111 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#835 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#836 +b01110110 E +b01110110 : +b01110110 * +b10011111 K +b10011111 ; +b10011111 + +b01110110 c +b01110110 @ +b01110110 0 +0g +#840 +1" +13 +1a +1S +1M +1$ +15 +1] +1Y +1T +1O +1H +b11011011 ' +b11011011 8 +b11011011 b +b11011011 ^ +b11011011 Z +b11011011 U +b11011011 P +b11011011 I +b11011011 D +b10101111 ( +b10101111 9 +b10101111 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#845 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#846 +b11011011 E +b11011011 : +b11011011 * +b10101111 K +b10101111 ; +b10101111 + +b11011011 [ +b11011011 > +b11011011 . +b11011011 _ +b11011011 ? +b11011011 / +b00000000 c +b00000000 @ +b00000000 0 +1g +0f +0B +01 +#850 +1& +17 +1X +b10001100 ' +b10001100 8 +b10001100 b +b10001100 ^ +b10001100 Z +b10001100 U +b10001100 P +b10001100 I +b10001100 D +b01011110 ( +b01011110 9 +b01011110 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#855 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#856 +b10001100 E +b10001100 : +b10001100 * +b01011110 K +b01011110 ; +b01011110 + +b00000001 [ +b00000001 > +b00000001 . +b10001100 _ +b10001100 ? +b10001100 / +1f +1B +11 +#860 +0" +03 +0a +0S +0M +1# +14 +1N +0% +06 +0G +0& +07 +0X +b11001101 ' +b11001101 8 +b11001101 b +b11001101 ^ +b11001101 Z +b11001101 U +b11001101 P +b11001101 I +b11001101 D +b10111100 ( +b10111100 9 +b10111100 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#865 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#866 +b11001101 E +b11001101 : +b11001101 * +b11001101 K +b11001101 ; +b11001101 + +b11001101 V +b11001101 = +b11001101 - +b11001101 [ +b11001101 > +b11001101 . +b11001101 _ +b11001101 ? +b11001101 / +b11001101 c +b11001101 @ +b11001101 0 +0g +#870 +1" +13 +1a +1S +1M +0$ +05 +0] +0Y +0T +0O +0H +1& +17 +1X +b00010010 ' +b00010010 8 +b00010010 b +b00010010 ^ +b00010010 Z +b00010010 U +b00010010 P +b00010010 I +b00010010 D +b00110101 ( +b00110101 9 +b00110101 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#875 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#876 +b00010010 E +b00010010 : +b00010010 * +b00000000 V +b00000000 = +b00000000 - +b00000001 [ +b00000001 > +b00000001 . +b00000000 c +b00000000 @ +b00000000 0 +0f +0B +01 +#880 +0# +04 +0N +1% +16 +1G +0& +07 +0X +b10001110 ' +b10001110 8 +b10001110 b +b10001110 ^ +b10001110 Z +b10001110 U +b10001110 P +b10001110 I +b10001110 D +b10110111 ( +b10110111 9 +b10110111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#885 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#886 +b10001110 E +b10001110 : +b10001110 * +b10110111 K +b10110111 ; +b10110111 + +#890 +0" +03 +0a +0S +0M +1# +14 +1N +1$ +15 +1] +1Y +1T +1O +1H +0% +06 +0G +b11011111 ' +b11011111 8 +b11011111 b +b11011111 ^ +b11011111 Z +b11011111 U +b11011111 P +b11011111 I +b11011111 D +b10000000 ( +b10000000 9 +b10000000 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#895 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#896 +b11011111 E +b11011111 : +b11011111 * +b11011111 K +b11011111 ; +b11011111 + +b11011111 V +b11011111 = +b11011111 - +b11011111 [ +b11011111 > +b11011111 . +b11011111 _ +b11011111 ? +b11011111 / +b11011111 c +b11011111 @ +b11011111 0 +1g +#900 +1" +13 +1a +1S +1M +0# +04 +0N +0$ +05 +0] +0Y +0T +0O +0H +1% +16 +1G +1& +17 +1X +b00001011 ' +b00001011 8 +b00001011 b +b00001011 ^ +b00001011 Z +b00001011 U +b00001011 P +b00001011 I +b00001011 D +b00001000 ( +b00001000 9 +b00001000 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#905 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#906 +b00001011 E +b00001011 : +b00001011 * +b00001000 K +b00001000 ; +b00001000 + +b00000000 V +b00000000 = +b00000000 - +b00000001 [ +b00000001 > +b00000001 . +b00000000 c +b00000000 @ +b00000000 0 +0g +1f +1B +11 +#910 +0" +03 +0a +0S +0M +1# +14 +1N +b00000101 ' +b00000101 8 +b00000101 b +b00000101 ^ +b00000101 Z +b00000101 U +b00000101 P +b00000101 I +b00000101 D +b10000111 ( +b10000111 9 +b10000111 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#915 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#916 +b00000101 E +b00000101 : +b00000101 * +b10000111 K +b10000111 ; +b10000111 + +b00000101 c +b00000101 @ +b00000101 0 +1g +0f +0B +01 +#920 +1$ +15 +1] +1Y +1T +1O +1H +0& +07 +0X +b11000001 ' +b11000001 8 +b11000001 b +b11000001 ^ +b11000001 Z +b11000001 U +b11000001 P +b11000001 I +b11000001 D +b10111011 ( +b10111011 9 +b10111011 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#925 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#926 +b11000001 E +b11000001 : +b11000001 * +b10111011 K +b10111011 ; +b10111011 + +b11000001 V +b11000001 = +b11000001 - +b11000001 [ +b11000001 > +b11000001 . +b11000001 _ +b11000001 ? +b11000001 / +b11000001 c +b11000001 @ +b11000001 0 +0g +1f +1B +11 +#930 +1" +13 +1a +1S +1M +0% +06 +0G +b11001100 ' +b11001100 8 +b11001100 b +b11001100 ^ +b11001100 Z +b11001100 U +b11001100 P +b11001100 I +b11001100 D +b00110101 ( +b00110101 9 +b00110101 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#935 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#936 +b11001100 E +b11001100 : +b11001100 * +b11001100 K +b11001100 ; +b11001100 + +b00000000 V +b00000000 = +b00000000 - +b11001100 [ +b11001100 > +b11001100 . +b11001100 _ +b11001100 ? +b11001100 / +b00000000 c +b00000000 @ +b00000000 0 +1g +0f +0B +01 +#940 +0# +04 +0N +0$ +05 +0] +0Y +0T +0O +0H +1% +16 +1G +b11011100 ' +b11011100 8 +b11011100 b +b11011100 ^ +b11011100 Z +b11011100 U +b11011100 P +b11011100 I +b11011100 D +b11110110 ( +b11110110 9 +b11110110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#945 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#946 +b11011100 E +b11011100 : +b11011100 * +b11110110 K +b11110110 ; +b11110110 + +0g +1f +1B +11 +#950 +0" +03 +0a +0S +0M +1# +14 +1N +1$ +15 +1] +1Y +1T +1O +1H +0% +06 +0G +1& +17 +1X +b01000011 ' +b01000011 8 +b01000011 b +b01000011 ^ +b01000011 Z +b01000011 U +b01000011 P +b01000011 I +b01000011 D +b00110000 ( +b00110000 9 +b00110000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#955 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#956 +b01000011 E +b01000011 : +b01000011 * +b01000011 K +b01000011 ; +b01000011 + +b01000011 V +b01000011 = +b01000011 - +b00000001 [ +b00000001 > +b00000001 . +b01000011 _ +b01000011 ? +b01000011 / +b01000011 c +b01000011 @ +b01000011 0 +0f +0B +01 +#960 +1% +16 +1G +b01111101 ' +b01111101 8 +b01111101 b +b01111101 ^ +b01111101 Z +b01111101 U +b01111101 P +b01111101 I +b01111101 D +b11011101 ( +b11011101 9 +b11011101 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#965 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#966 +b01111101 E +b01111101 : +b01111101 * +b11011101 K +b11011101 ; +b11011101 + +b01111101 V +b01111101 = +b01111101 - +b01111101 _ +b01111101 ? +b01111101 / +b01111101 c +b01111101 @ +b01111101 0 +1g +#970 +0# +04 +0N +0% +06 +0G +b11001010 ' +b11001010 8 +b11001010 b +b11001010 ^ +b11001010 Z +b11001010 U +b11001010 P +b11001010 I +b11001010 D +b01001010 ( +b01001010 9 +b01001010 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#975 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#976 +b11001010 E +b11001010 : +b11001010 * +b11001010 K +b11001010 ; +b11001010 + +b11001010 Q +b11001010 < +b11001010 , +b11001010 V +b11001010 = +b11001010 - +b11001010 _ +b11001010 ? +b11001010 / +b11001010 c +b11001010 @ +b11001010 0 +0g +1f +1B +11 +#980 +1# +14 +1N +0& +07 +0X +b10000000 ' +b10000000 8 +b10000000 b +b10000000 ^ +b10000000 Z +b10000000 U +b10000000 P +b10000000 I +b10000000 D +b11110111 ( +b11110111 9 +b11110111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#985 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#986 +b10000000 E +b10000000 : +b10000000 * +b10000000 K +b10000000 ; +b10000000 + +b00000000 Q +b00000000 < +b00000000 , +b10000000 V +b10000000 = +b10000000 - +b10000000 [ +b10000000 > +b10000000 . +b10000000 _ +b10000000 ? +b10000000 / +b10000000 c +b10000000 @ +b10000000 0 +0f +0B +01 +#990 +1" +13 +1a +1S +1M +b00111001 ' +b00111001 8 +b00111001 b +b00111001 ^ +b00111001 Z +b00111001 U +b00111001 P +b00111001 I +b00111001 D +b01111110 ( +b01111110 9 +b01111110 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#995 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#996 +b00111001 E +b00111001 : +b00111001 * +b00111001 K +b00111001 ; +b00111001 + +b00000000 V +b00000000 = +b00000000 - +b00111001 [ +b00111001 > +b00111001 . +b00111001 _ +b00111001 ? +b00111001 / +b00000000 c +b00000000 @ +b00000000 0 +#1000 +0# +04 +0N +0$ +05 +0] +0Y +0T +0O +0H +1% +16 +1G +1& +17 +1X +b00110001 ' +b00110001 8 +b00110001 b +b00110001 ^ +b00110001 Z +b00110001 U +b00110001 P +b00110001 I +b00110001 D +b00010000 ( +b00010000 9 +b00010000 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#1005 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#1006 +b00110001 E +b00110001 : +b00110001 * +b00010000 K +b00010000 ; +b00010000 + +b00000001 [ +b00000001 > +b00000001 . +1g +#1010 +1$ +15 +1] +1Y +1T +1O +1H +0& +07 +0X +b10111010 ' +b10111010 8 +b10111010 b +b10111010 ^ +b10111010 Z +b10111010 U +b10111010 P +b10111010 I +b10111010 D +b00010010 ( +b00010010 9 +b00010010 J diff --git a/tests/vcs_examples/block_level_tests/generic/flop/top_flop.sv b/tests/vcs_examples/block_level_tests/generic/flop/top_flop.sv new file mode 100644 index 0000000000..f6c00feb72 --- /dev/null +++ b/tests/vcs_examples/block_level_tests/generic/flop/top_flop.sv @@ -0,0 +1,17 @@ +module top_flop( + input logic clk, reset, clear, en, load, set, + input logic [7:0] d, val, // Assuming WIDTH=8 for all submodules + output logic [7:0] q_flop, q_flopenl, q_flopenrc, q_flopenr, q_flopens, q_flopen, q_flopr, + input logic d_sync, // Separate input for synchronizer + output logic q_sync +); + + flop #(.WIDTH(8)) flop_inst (.clk(clk), .d(d), .q(q_flop)); + flopenl #(.WIDTH(8)) flopenl_inst (.clk(clk), .load(load), .en(en), .d(d), .val(val), .q(q_flopenl)); + flopenrc#(.WIDTH(8)) flopenrc_inst(.clk(clk), .reset(reset), .clear(clear), .en(en), .d(d), .q(q_flopenrc)); + flopenr #(.WIDTH(8)) flopenr_inst(.clk(clk), .reset(reset), .en(en), .d(d), .q(q_flopenr)); + flopens #(.WIDTH(8)) flopens_inst(.clk(clk), .set(set), .en(en), .d(d), .q(q_flopens)); + flopen #(.WIDTH(8)) flopen_inst (.clk(clk), .en(en), .d(d), .q(q_flopen)); + flopr #(.WIDTH(8)) flopr_inst (.clk(clk), .reset(reset), .d(d), .q(q_flopr)); + synchronizer synchronizer_inst (.clk(clk), .d(d_sync), .q(q_sync)); +endmodule diff --git a/tests/vcs_examples/block_level_tests/generic/flop_empty/Makefile b/tests/vcs_examples/block_level_tests/generic/flop_empty/Makefile new file mode 100644 index 0000000000..29897bc1da --- /dev/null +++ b/tests/vcs_examples/block_level_tests/generic/flop_empty/Makefile @@ -0,0 +1,61 @@ +# Makefile for running a design with Verilator and VCS + +# Variables +DESIGN_FILE = top_flop.sv +VERILATOR_TESTBENCH = tb_flop.cpp +VCS_TESTBENCH = tb_flop.sv +TOP_MODULE = top_flop # Specify your top-level module name here +BUILD_DIR = obj_dir +SOURCE_PATH = +incdir+../../../../../src/generic/flop/ +SIMFILES = ../../../../../src/generic/flop/*.sv + +# Verilator specific +VERILATOR = verilator +VERILATOR_FLAGS = -Wall --cc --exe --trace --timing -Wno-SYMRSVDWORD + +# VCS specific +VCS = vcs +# Enable code coverage and specify the directory for coverage results +VCS_FLAGS = -full64 -sverilog +v2k -debug_acc+all+dmptf -debug_region+cell+encrypt +CODE_COV_FLAGS= -cm line+cond+fsm+tgl+branch -cm_dir COVERAGE +# To handle the ASLR-related behavior/message +SIM_FLAGS = -no_save + +# Default target +all: + @echo "Specify 'make verilate' for Verilator or 'make vcs' for VCS." + + +# Verilate and run with Verilator +verilate: clean_verilate + $(VERILATOR) $(VERILATOR_FLAGS) --top-module $(TOP_MODULE) --relative-includes $(DESIGN_FILE) + + +# Compile and run with VCS with code coverage +vcs: clean_vcs + mkdir -p $(BUILD_DIR) # Ensure the build directory exists + mkdir -p $(BUILD_DIR)/coverage # Ensure the coverage directory exists as well + # To specify a different top-level module, replace $(TOP_MODULE) with your module name in the VCS command below + # $(VCS) $(VCS_FLAGS) $(SOURCE_PATH) $(SIMFILES) $(CODE_COV_FLAGS) $(DESIGN_FILE) $(VCS_TESTBENCH) -o $(BUILD_DIR)/vcs_simv + $(VCS) $(VCS_FLAGS) $(DESIGN_FILE) $(VCS_TESTBENCH) -o $(BUILD_DIR)/vcs_simv + ./$(BUILD_DIR)/vcs_simv $(SIM_FLAGS) + # Generate and view the coverage report + #urg -lca -dir COVERAGE.vdb + +# To pass parameters to your simulation, you can use the +define+NAME=VALUE syntax with VCS. +# For example, to define a parameter named PARAM with a value of 10, add '+define+PARAM=10' to the VCS_FLAGS variable. + +# Clean up Verilator generated files +clean_verilate: + rm -rf $(BUILD_DIR) + +# Clean up VCS generated files and coverage reports +clean_vcs: + rm -rf csrc $(BUILD_DIR)/vcs_simv.daidir $(BUILD_DIR)/vcs_simv ucli.key vc_hdrs.h $(BUILD_DIR)/coverage + +# Clean up all generated files +clean: clean_verilate clean_vcs + rm -rf *.vcd + +.PHONY: all verilate vcs clean clean_verilate clean_vcs + diff --git a/tests/vcs_examples/block_level_tests/generic/flop_empty/tb_flop.cpp b/tests/vcs_examples/block_level_tests/generic/flop_empty/tb_flop.cpp new file mode 100644 index 0000000000..02365e2d39 --- /dev/null +++ b/tests/vcs_examples/block_level_tests/generic/flop_empty/tb_flop.cpp @@ -0,0 +1,54 @@ +#include +#include "Vtop_flop.h" // Generated model header for top_flop +#include // Header for VCD tracing + +vluint64_t main_time = 0; // Current simulation time + +// Called by $time in Verilog +double sc_time_stamp() { + return main_time; // Note does conversion to real, to match SystemC +} + +int main(int argc, char** argv, char** env) { + Verilated::commandArgs(argc, argv); // Initialize Verilator's variables + Vtop_flop* top = new Vtop_flop; // Create an instance of our module under test + + Verilated::traceEverOn(true); // Enable waveform generation + VerilatedVcdC* tfp = new VerilatedVcdC; + top->trace(tfp, 99); // Trace 99 levels of hierarchy + tfp->open("top_flop.vcd"); // Open the waveform output + + top->reset = 1; // Start in reset + + while (main_time < 1000 && !Verilated::gotFinish()) { + if (main_time % 10 == 0) { + top->clk = !top->clk; // Toggle clock every 10 simulation cycles + } + if (main_time == 15) { + top->reset = 0; // Release reset + } + + // Randomly manipulate inputs every cycle after reset + if (main_time > 15) { + top->set = rand() % 2; + top->clear = rand() % 2; + top->en = rand() % 2; + top->load = rand() % 2; + top->d = rand() % 256; + top->val = rand() % 256; + top->d_sync = rand() % 2; + } + + top->eval(); // Evaluate model + tfp->dump(main_time); // Dump trace data for this cycle + + main_time++; // Time passes... + } + + top->final(); // Done simulating + tfp->close(); // Close the waveform + delete top; + delete tfp; + return 0; +} + diff --git a/tests/vcs_examples/block_level_tests/generic/flop_empty/tb_flop.sv b/tests/vcs_examples/block_level_tests/generic/flop_empty/tb_flop.sv new file mode 100644 index 0000000000..07462bf6ba --- /dev/null +++ b/tests/vcs_examples/block_level_tests/generic/flop_empty/tb_flop.sv @@ -0,0 +1,40 @@ +module tb_flop; + + logic clk, reset, clear, en, load, set; + logic [7:0] d, val; + logic d_sync; + logic [7:0] q_flop, q_flopenl, q_flopenrc, q_flopenr, q_flopens, q_flopen, q_flopr; + logic q_sync; + + // Instantiate the top module + top_flop dut( + .clk(clk), .reset(reset), .clear(clear), .en(en), .load(load), .set(set), + .d(d), .val(val), + .q_flop(q_flop), .q_flopenl(q_flopenl), .q_flopenrc(q_flopenrc), .q_flopenr(q_flopenr), .q_flopens(q_flopens), .q_flopen(q_flopen), .q_flopr(q_flopr), + .d_sync(d_sync), .q_sync(q_sync) + ); + + // Clock generation + initial begin + clk = 0; + forever #5 clk = ~clk; // Generate a clock with 100MHz frequency + end + + // Apply random inputs and dump VCD + initial begin + $dumpfile("tb_flop.vcd"); + $dumpvars(0, tb_flop); + + reset = 1; clear = 0; en = 0; load = 0; set = 0; d = 0; val = 0; d_sync = 0; + #10 reset = 0; // Release reset after 10ns + + repeat (100) begin + #10; // Every 10ns, apply new random inputs + reset = $random; clear = $random; en = $random; load = $random; set = $random; + d = $urandom%256; val = $urandom%256; d_sync = $urandom%2; + end + + $finish; + end +endmodule + diff --git a/tests/vcs_examples/block_level_tests/generic/flop_empty/tb_flop.vcd b/tests/vcs_examples/block_level_tests/generic/flop_empty/tb_flop.vcd new file mode 100644 index 0000000000..12b70aa442 --- /dev/null +++ b/tests/vcs_examples/block_level_tests/generic/flop_empty/tb_flop.vcd @@ -0,0 +1,4769 @@ +$date + Sat Mar 16 09:50:01 2024 +$end + +$version + Synopsys VCS version U-2023.03-SP2-4_Full64 +$end + +$timescale + 1s +$end + +$comment Csum: 1 b8c1dc1d2724083a $end + + +$scope module tb_flop $end +$var reg 1 ! clk $end +$var reg 1 " reset $end +$var reg 1 # clear $end +$var reg 1 $ en $end +$var reg 1 % load $end +$var reg 1 & set $end +$var reg 8 ' d [7:0] $end +$var reg 8 ( val [7:0] $end +$var reg 1 ) d_sync $end +$var reg 8 * q_flop [7:0] $end +$var reg 8 + q_flopenl [7:0] $end +$var reg 8 , q_flopenrc [7:0] $end +$var reg 8 - q_flopenr [7:0] $end +$var reg 8 . q_flopens [7:0] $end +$var reg 8 / q_flopen [7:0] $end +$var reg 8 0 q_flopr [7:0] $end +$var reg 1 1 q_sync $end + +$scope begin unnamed$$_vcs_0 $end +$upscope $end + + +$scope module dut $end +$var reg 1 2 clk $end +$var reg 1 3 reset $end +$var reg 1 4 clear $end +$var reg 1 5 en $end +$var reg 1 6 load $end +$var reg 1 7 set $end +$var reg 8 8 d [7:0] $end +$var reg 8 9 val [7:0] $end +$var reg 8 : q_flop [7:0] $end +$var reg 8 ; q_flopenl [7:0] $end +$var reg 8 < q_flopenrc [7:0] $end +$var reg 8 = q_flopenr [7:0] $end +$var reg 8 > q_flopens [7:0] $end +$var reg 8 ? q_flopen [7:0] $end +$var reg 8 @ q_flopr [7:0] $end +$var reg 1 A d_sync $end +$var reg 1 B q_sync $end + +$scope module flop_inst $end +$var reg 1 C clk $end +$var reg 8 D d [7:0] $end +$var reg 8 E q [7:0] $end +$upscope $end + + +$scope module flopenl_inst $end +$var reg 1 F clk $end +$var reg 1 G load $end +$var reg 1 H en $end +$var reg 8 I d [7:0] $end +$var reg 8 J val [7:0] $end +$var reg 8 K q [7:0] $end +$upscope $end + + +$scope module flopenrc_inst $end +$var reg 1 L clk $end +$var reg 1 M reset $end +$var reg 1 N clear $end +$var reg 1 O en $end +$var reg 8 P d [7:0] $end +$var reg 8 Q q [7:0] $end +$upscope $end + + +$scope module flopenr_inst $end +$var reg 1 R clk $end +$var reg 1 S reset $end +$var reg 1 T en $end +$var reg 8 U d [7:0] $end +$var reg 8 V q [7:0] $end +$upscope $end + + +$scope module flopens_inst $end +$var reg 1 W clk $end +$var reg 1 X set $end +$var reg 1 Y en $end +$var reg 8 Z d [7:0] $end +$var reg 8 [ q [7:0] $end +$upscope $end + + +$scope module flopen_inst $end +$var reg 1 \ clk $end +$var reg 1 ] en $end +$var reg 8 ^ d [7:0] $end +$var reg 8 _ q [7:0] $end +$upscope $end + + +$scope module flopr_inst $end +$var reg 1 ` clk $end +$var reg 1 a reset $end +$var reg 8 b d [7:0] $end +$var reg 8 c q [7:0] $end +$upscope $end + + +$scope module synchronizer_inst $end +$var reg 1 d clk $end +$var reg 1 e d $end +$var reg 1 f q $end +$var reg 1 g mid $end +$upscope $end + +$upscope $end + +$upscope $end + +$enddefinitions $end + +#0 +$dumpvars +0# +0! +0) +04 +0A +05 +06 +xB +13 +07 +0$ +0] +0H +0G +0T +1S +0N +0O +1M +0Y +0X +1a +0% +xg +x1 +1" +0& +0e +xf +b00000000 I +bxxxxxxxx K +b00000000 J +b00000000 ' +b00000000 8 +bxxxxxxxx : +bxxxxxxxx ? +bxxxxxxxx ; +bxxxxxxxx = +bxxxxxxxx < +bxxxxxxxx > +bxxxxxxxx @ +b00000000 9 +b00000000 D +b00000000 ^ +bxxxxxxxx _ +b00000000 U +bxxxxxxxx V +b00000000 P +bxxxxxxxx Q +b00000000 Z +bxxxxxxxx [ +b00000000 b +bxxxxxxxx c +bxxxxxxxx E +bxxxxxxxx * +bxxxxxxxx / +bxxxxxxxx + +bxxxxxxxx - +bxxxxxxxx , +bxxxxxxxx . +bxxxxxxxx 0 +b00000000 ( +02 +0C +0F +0L +0R +0W +0\ +0` +0d +$end +#5 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#10 +0" +03 +0a +0S +0M +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#15 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#20 +1# +14 +1N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b00010011 ' +b00010011 8 +b00010011 b +b00010011 ^ +b00010011 Z +b00010011 U +b00010011 P +b00010011 I +b00010011 D +b01110000 ( +b01110000 9 +b01110000 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#25 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#30 +1" +13 +1a +1S +1M +0$ +05 +0] +0Y +0T +0O +0H +b11100010 ' +b11100010 8 +b11100010 b +b11100010 ^ +b11100010 Z +b11100010 U +b11100010 P +b11100010 I +b11100010 D +b10010111 ( +b10010111 9 +b10010111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#35 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#40 +0" +03 +0a +0S +0M +1$ +15 +1] +1Y +1T +1O +1H +0% +06 +0G +b11000101 ' +b11000101 8 +b11000101 b +b11000101 ^ +b11000101 Z +b11000101 U +b11000101 P +b11000101 I +b11000101 D +b11101100 ( +b11101100 9 +b11101100 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#45 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#50 +0$ +05 +0] +0Y +0T +0O +0H +1% +16 +1G +b00001100 ' +b00001100 8 +b00001100 b +b00001100 ^ +b00001100 Z +b00001100 U +b00001100 P +b00001100 I +b00001100 D +b00101100 ( +b00101100 9 +b00101100 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#55 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#60 +0% +06 +0G +0& +07 +0X +b00011011 ' +b00011011 8 +b00011011 b +b00011011 ^ +b00011011 Z +b00011011 U +b00011011 P +b00011011 I +b00011011 D +b01000101 ( +b01000101 9 +b01000101 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#65 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#70 +1" +13 +1a +1S +1M +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b01101100 ' +b01101100 8 +b01101100 b +b01101100 ^ +b01101100 Z +b01101100 U +b01101100 P +b01101100 I +b01101100 D +b01100111 ( +b01100111 9 +b01100111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#75 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#80 +0$ +05 +0] +0Y +0T +0O +0H +0% +06 +0G +0& +07 +0X +b01001010 ' +b01001010 8 +b01001010 b +b01001010 ^ +b01001010 Z +b01001010 U +b01001010 P +b01001010 I +b01001010 D +b10100110 ( +b10100110 9 +b10100110 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#85 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#90 +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b10011101 ' +b10011101 8 +b10011101 b +b10011101 ^ +b10011101 Z +b10011101 U +b10011101 P +b10011101 I +b10011101 D +b01111100 ( +b01111100 9 +b01111100 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#95 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#100 +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +0% +06 +0G +b11101011 ' +b11101011 8 +b11101011 b +b11101011 ^ +b11101011 Z +b11101011 U +b11101011 P +b11101011 I +b11101011 D +b01011011 ( +b01011011 9 +b01011011 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#105 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#110 +0& +07 +0X +b01001101 ' +b01001101 8 +b01001101 b +b01001101 ^ +b01001101 Z +b01001101 U +b01001101 P +b01001101 I +b01001101 D +b01011100 ( +b01011100 9 +b01011100 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#115 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#120 +0" +03 +0a +0S +0M +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +b11011001 ' +b11011001 8 +b11011001 b +b11011001 ^ +b11011001 Z +b11011001 U +b11011001 P +b11011001 I +b11011001 D +b10101001 ( +b10101001 9 +b10101001 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#125 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#130 +1" +13 +1a +1S +1M +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +b10011110 ' +b10011110 8 +b10011110 b +b10011110 ^ +b10011110 Z +b10011110 U +b10011110 P +b10011110 I +b10011110 D +b11001000 ( +b11001000 9 +b11001000 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#135 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#140 +0" +03 +0a +0S +0M +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b00100110 ' +b00100110 8 +b00100110 b +b00100110 ^ +b00100110 Z +b00100110 U +b00100110 P +b00100110 I +b00100110 D +b11110110 ( +b11110110 9 +b11110110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#145 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#150 +1" +13 +1a +1S +1M +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +0% +06 +0G +b01011011 ' +b01011011 8 +b01011011 b +b01011011 ^ +b01011011 Z +b01011011 U +b01011011 P +b01011011 I +b01011011 D +b01000010 ( +b01000010 9 +b01000010 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#155 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#160 +b10010001 ' +b10010001 8 +b10010001 b +b10010001 ^ +b10010001 Z +b10010001 U +b10010001 P +b10010001 I +b10010001 D +b00111000 ( +b00111000 9 +b00111000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#165 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#170 +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +0& +07 +0X +b01101101 ' +b01101101 8 +b01101101 b +b01101101 ^ +b01101101 Z +b01101101 U +b01101101 P +b01101101 I +b01101101 D +b11000010 ( +b11000010 9 +b11000010 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#175 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#180 +1# +14 +1N +0% +06 +0G +1& +17 +1X +b01111100 ' +b01111100 8 +b01111100 b +b01111100 ^ +b01111100 Z +b01111100 U +b01111100 P +b01111100 I +b01111100 D +b00101110 ( +b00101110 9 +b00101110 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#185 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#190 +0# +04 +0N +0$ +05 +0] +0Y +0T +0O +0H +0& +07 +0X +b00011101 ' +b00011101 8 +b00011101 b +b00011101 ^ +b00011101 Z +b00011101 U +b00011101 P +b00011101 I +b00011101 D +b11100011 ( +b11100011 9 +b11100011 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#195 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#200 +1# +14 +1N +1& +17 +1X +b00001010 ' +b00001010 8 +b00001010 b +b00001010 ^ +b00001010 Z +b00001010 U +b00001010 P +b00001010 I +b00001010 D +b00010011 ( +b00010011 9 +b00010011 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#205 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#210 +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +0& +07 +0X +b00111100 ' +b00111100 8 +b00111100 b +b00111100 ^ +b00111100 Z +b00111100 U +b00111100 P +b00111100 I +b00111100 D +b00111010 ( +b00111010 9 +b00111010 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#215 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#220 +0% +06 +0G +b11100111 ' +b11100111 8 +b11100111 b +b11100111 ^ +b11100111 Z +b11100111 U +b11100111 P +b11100111 I +b11100111 D +b10010111 ( +b10010111 9 +b10010111 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#225 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#230 +0" +03 +0a +0S +0M +0# +04 +0N +0$ +05 +0] +0Y +0T +0O +0H +b11100011 ' +b11100011 8 +b11100011 b +b11100011 ^ +b11100011 Z +b11100011 U +b11100011 P +b11100011 I +b11100011 D +b00100000 ( +b00100000 9 +b00100000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#235 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#240 +1" +13 +1a +1S +1M +1# +14 +1N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b10111111 ' +b10111111 8 +b10111111 b +b10111111 ^ +b10111111 Z +b10111111 U +b10111111 P +b10111111 I +b10111111 D +b10010001 ( +b10010001 9 +b10010001 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#245 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#250 +0" +03 +0a +0S +0M +0% +06 +0G +0& +07 +0X +b01001100 ' +b01001100 8 +b01001100 b +b01001100 ^ +b01001100 Z +b01001100 U +b01001100 P +b01001100 I +b01001100 D +b01110110 ( +b01110110 9 +b01110110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#255 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#260 +1" +13 +1a +1S +1M +0$ +05 +0] +0Y +0T +0O +0H +1% +16 +1G +1& +17 +1X +b00001100 ( +b00001100 9 +b00001100 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#265 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#270 +0% +06 +0G +0& +07 +0X +b11001000 ' +b11001000 8 +b11001000 b +b11001000 ^ +b11001000 Z +b11001000 U +b11001000 P +b11001000 I +b11001000 D +b00011111 ( +b00011111 9 +b00011111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#275 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#280 +0# +04 +0N +1& +17 +1X +b00100011 ' +b00100011 8 +b00100011 b +b00100011 ^ +b00100011 Z +b00100011 U +b00100011 P +b00100011 I +b00100011 D +b10011001 ( +b10011001 9 +b10011001 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#285 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#290 +1% +16 +1G +0& +07 +0X +b10001111 ' +b10001111 8 +b10001111 b +b10001111 ^ +b10001111 Z +b10001111 U +b10001111 P +b10001111 I +b10001111 D +b11110110 ( +b11110110 9 +b11110110 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#295 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#300 +0" +03 +0a +0S +0M +1$ +15 +1] +1Y +1T +1O +1H +0% +06 +0G +b11110111 ' +b11110111 8 +b11110111 b +b11110111 ^ +b11110111 Z +b11110111 U +b11110111 P +b11110111 I +b11110111 D +b00001110 ( +b00001110 9 +b00001110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#305 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#310 +1" +13 +1a +1S +1M +1% +16 +1G +1& +17 +1X +b01101101 ' +b01101101 8 +b01101101 b +b01101101 ^ +b01101101 Z +b01101101 U +b01101101 P +b01101101 I +b01101101 D +b00000110 ( +b00000110 9 +b00000110 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#315 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#320 +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +0% +06 +0G +0& +07 +0X +b00011010 ' +b00011010 8 +b00011010 b +b00011010 ^ +b00011010 Z +b00011010 U +b00011010 P +b00011010 I +b00011010 D +b10001111 ( +b10001111 9 +b10001111 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#325 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#330 +0# +04 +0N +1% +16 +1G +1& +17 +1X +b00101111 ' +b00101111 8 +b00101111 b +b00101111 ^ +b00101111 Z +b00101111 U +b00101111 P +b00101111 I +b00101111 D +b00100001 ( +b00100001 9 +b00100001 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#335 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#340 +0" +03 +0a +0S +0M +b00001111 ' +b00001111 8 +b00001111 b +b00001111 ^ +b00001111 Z +b00001111 U +b00001111 P +b00001111 I +b00001111 D +b01110100 ( +b01110100 9 +b01110100 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#345 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#350 +b01000111 ' +b01000111 8 +b01000111 b +b01000111 ^ +b01000111 Z +b01000111 U +b01000111 P +b01000111 I +b01000111 D +b00111101 ( +b00111101 9 +b00111101 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#355 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#360 +0& +07 +0X +b10011100 ' +b10011100 8 +b10011100 b +b10011100 ^ +b10011100 Z +b10011100 U +b10011100 P +b10011100 I +b10011100 D +b00111110 ( +b00111110 9 +b00111110 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#365 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#370 +1# +14 +1N +0% +06 +0G +b10010100 ' +b10010100 8 +b10010100 b +b10010100 ^ +b10010100 Z +b10010100 U +b10010100 P +b10010100 I +b10010100 D +b10100101 ( +b10100101 9 +b10100101 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#375 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#380 +1" +13 +1a +1S +1M +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +b11100010 ' +b11100010 8 +b11100010 b +b11100010 ^ +b11100010 Z +b11100010 U +b11100010 P +b11100010 I +b11100010 D +b01000001 ( +b01000001 9 +b01000001 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#385 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#390 +0" +03 +0a +0S +0M +0$ +05 +0] +0Y +0T +0O +0H +b00110101 ' +b00110101 8 +b00110101 b +b00110101 ^ +b00110101 Z +b00110101 U +b00110101 P +b00110101 I +b00110101 D +b00011101 ( +b00011101 9 +b00011101 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#395 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#400 +1& +17 +1X +b11000011 ' +b11000011 8 +b11000011 b +b11000011 ^ +b11000011 Z +b11000011 U +b11000011 P +b11000011 I +b11000011 D +b00111101 ( +b00111101 9 +b00111101 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#405 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#410 +1" +13 +1a +1S +1M +1$ +15 +1] +1Y +1T +1O +1H +b10111110 ' +b10111110 8 +b10111110 b +b10111110 ^ +b10111110 Z +b10111110 U +b10111110 P +b10111110 I +b10111110 D +b10001100 ( +b10001100 9 +b10001100 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#415 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#420 +0" +03 +0a +0S +0M +b00111000 ' +b00111000 8 +b00111000 b +b00111000 ^ +b00111000 Z +b00111000 U +b00111000 P +b00111000 I +b00111000 D +b11001110 ( +b11001110 9 +b11001110 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#425 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#430 +1" +13 +1a +1S +1M +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +b01100101 ' +b01100101 8 +b01100101 b +b01100101 ^ +b01100101 Z +b01100101 U +b01100101 P +b01100101 I +b01100101 D +b00001100 ( +b00001100 9 +b00001100 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#435 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#440 +0" +03 +0a +0S +0M +0# +04 +0N +0% +06 +0G +b11110010 ' +b11110010 8 +b11110010 b +b11110010 ^ +b11110010 Z +b11110010 U +b11110010 P +b11110010 I +b11110010 D +b10000000 ( +b10000000 9 +b10000000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#445 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#450 +1" +13 +1a +1S +1M +1% +16 +1G +0& +07 +0X +b00010000 ' +b00010000 8 +b00010000 b +b00010000 ^ +b00010000 Z +b00010000 U +b00010000 P +b00010000 I +b00010000 D +b01100110 ( +b01100110 9 +b01100110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#455 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#460 +0" +03 +0a +0S +0M +1# +14 +1N +0% +06 +0G +1& +17 +1X +b01010110 ' +b01010110 8 +b01010110 b +b01010110 ^ +b01010110 Z +b01010110 U +b01010110 P +b01010110 I +b01010110 D +b10110011 ( +b10110011 9 +b10110011 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#465 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#470 +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +b01000110 ' +b01000110 8 +b01000110 b +b01000110 ^ +b01000110 Z +b01000110 U +b01000110 P +b01000110 I +b01000110 D +b01110100 ( +b01110100 9 +b01110100 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#475 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#480 +0$ +05 +0] +0Y +0T +0O +0H +0& +07 +0X +b00100100 ' +b00100100 8 +b00100100 b +b00100100 ^ +b00100100 Z +b00100100 U +b00100100 P +b00100100 I +b00100100 D +b00001111 ( +b00001111 9 +b00001111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#485 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#490 +1# +14 +1N +0% +06 +0G +b10100111 ' +b10100111 8 +b10100111 b +b10100111 ^ +b10100111 Z +b10100111 U +b10100111 P +b10100111 I +b10100111 D +b10111111 ( +b10111111 9 +b10111111 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#495 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#500 +b00010010 ' +b00010010 8 +b00010010 b +b00010010 ^ +b00010010 Z +b00010010 U +b00010010 P +b00010010 I +b00010010 D +b00111010 ( +b00111010 9 +b00111010 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#505 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#510 +1" +13 +1a +1S +1M +1% +16 +1G +1& +17 +1X +b01101101 ' +b01101101 8 +b01101101 b +b01101101 ^ +b01101101 Z +b01101101 U +b01101101 P +b01101101 I +b01101101 D +b10111110 ( +b10111110 9 +b10111110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#515 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#520 +b11010001 ' +b11010001 8 +b11010001 b +b11010001 ^ +b11010001 Z +b11010001 U +b11010001 P +b11010001 I +b11010001 D +b01110000 ( +b01110000 9 +b01110000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#525 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#530 +0# +04 +0N +0& +07 +0X +b10110100 ' +b10110100 8 +b10110100 b +b10110100 ^ +b10110100 Z +b10110100 U +b10110100 P +b10110100 I +b10110100 D +b10010101 ( +b10010101 9 +b10010101 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#535 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#540 +0" +03 +0a +0S +0M +1# +14 +1N +1$ +15 +1] +1Y +1T +1O +1H +0% +06 +0G +b00011010 ' +b00011010 8 +b00011010 b +b00011010 ^ +b00011010 Z +b00011010 U +b00011010 P +b00011010 I +b00011010 D +b10111000 ( +b10111000 9 +b10111000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#545 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#550 +1" +13 +1a +1S +1M +0# +04 +0N +0$ +05 +0] +0Y +0T +0O +0H +1% +16 +1G +b10011101 ' +b10011101 8 +b10011101 b +b10011101 ^ +b10011101 Z +b10011101 U +b10011101 P +b10011101 I +b10011101 D +b00101010 ( +b00101010 9 +b00101010 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#555 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#560 +1# +14 +1N +b11001100 ' +b11001100 8 +b11001100 b +b11001100 ^ +b11001100 Z +b11001100 U +b11001100 P +b11001100 I +b11001100 D +b00100011 ( +b00100011 9 +b00100011 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#565 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#570 +0# +04 +0N +b11010001 ' +b11010001 8 +b11010001 b +b11010001 ^ +b11010001 Z +b11010001 U +b11010001 P +b11010001 I +b11010001 D +b01001010 ( +b01001010 9 +b01001010 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#575 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#580 +0" +03 +0a +0S +0M +1$ +15 +1] +1Y +1T +1O +1H +1& +17 +1X +b11010100 ' +b11010100 8 +b11010100 b +b11010100 ^ +b11010100 Z +b11010100 U +b11010100 P +b11010100 I +b11010100 D +b01000000 ( +b01000000 9 +b01000000 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#585 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#590 +1" +13 +1a +1S +1M +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +b10100011 ' +b10100011 8 +b10100011 b +b10100011 ^ +b10100011 Z +b10100011 U +b10100011 P +b10100011 I +b10100011 D +b01111101 ( +b01111101 9 +b01111101 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#595 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#600 +0# +04 +0N +0% +06 +0G +0& +07 +0X +b10111011 ' +b10111011 8 +b10111011 b +b10111011 ^ +b10111011 Z +b10111011 U +b10111011 P +b10111011 I +b10111011 D +b01110010 ( +b01110010 9 +b01110010 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#605 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#610 +0" +03 +0a +0S +0M +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b10101000 ' +b10101000 8 +b10101000 b +b10101000 ^ +b10101000 Z +b10101000 U +b10101000 P +b10101000 I +b10101000 D +b01101001 ( +b01101001 9 +b01101001 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#615 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#620 +1" +13 +1a +1S +1M +1# +14 +1N +0& +07 +0X +b11001101 ' +b11001101 8 +b11001101 b +b11001101 ^ +b11001101 Z +b11001101 U +b11001101 P +b11001101 I +b11001101 D +b10001011 ( +b10001011 9 +b10001011 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#625 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#630 +1& +17 +1X +b01101100 ' +b01101100 8 +b01101100 b +b01101100 ^ +b01101100 Z +b01101100 U +b01101100 P +b01101100 I +b01101100 D +b01011011 ( +b01011011 9 +b01011011 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#635 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#640 +0% +06 +0G +0& +07 +0X +b11101010 ' +b11101010 8 +b11101010 b +b11101010 ^ +b11101010 Z +b11101010 U +b11101010 P +b11101010 I +b11101010 D +b10011001 ( +b10011001 9 +b10011001 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#645 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#650 +0$ +05 +0] +0Y +0T +0O +0H +b10111100 ' +b10111100 8 +b10111100 b +b10111100 ^ +b10111100 Z +b10111100 U +b10111100 P +b10111100 I +b10111100 D +b00101101 ( +b00101101 9 +b00101101 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#655 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#660 +0" +03 +0a +0S +0M +b10100111 ' +b10100111 8 +b10100111 b +b10100111 ^ +b10100111 Z +b10100111 U +b10100111 P +b10100111 I +b10100111 D +b00110011 ( +b00110011 9 +b00110011 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#665 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#670 +0# +04 +0N +1% +16 +1G +b11101000 ' +b11101000 8 +b11101000 b +b11101000 ^ +b11101000 Z +b11101000 U +b11101000 P +b11101000 I +b11101000 D +b10001001 ( +b10001001 9 +b10001001 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#675 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#680 +1# +14 +1N +0% +06 +0G +b00101010 ' +b00101010 8 +b00101010 b +b00101010 ^ +b00101010 Z +b00101010 U +b00101010 P +b00101010 I +b00101010 D +b10101100 ( +b10101100 9 +b10101100 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#685 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#690 +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +1& +17 +1X +b10001111 ' +b10001111 8 +b10001111 b +b10001111 ^ +b10001111 Z +b10001111 U +b10001111 P +b10001111 I +b10001111 D +b11010011 ( +b11010011 9 +b11010011 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#695 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#700 +1" +13 +1a +1S +1M +0# +04 +0N +b11101100 ' +b11101100 8 +b11101100 b +b11101100 ^ +b11101100 Z +b11101100 U +b11101100 P +b11101100 I +b11101100 D +b10010010 ( +b10010010 9 +b10010010 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#705 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#710 +0" +03 +0a +0S +0M +1# +14 +1N +0$ +05 +0] +0Y +0T +0O +0H +0% +06 +0G +b01101101 ' +b01101101 8 +b01101101 b +b01101101 ^ +b01101101 Z +b01101101 U +b01101101 P +b01101101 I +b01101101 D +b01101000 ( +b01101000 9 +b01101000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#715 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#720 +1" +13 +1a +1S +1M +0# +04 +0N +1$ +15 +1] +1Y +1T +1O +1H +0& +07 +0X +b10100000 ' +b10100000 8 +b10100000 b +b10100000 ^ +b10100000 Z +b10100000 U +b10100000 P +b10100000 I +b10100000 D +b01100110 ( +b01100110 9 +b01100110 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#725 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#730 +0$ +05 +0] +0Y +0T +0O +0H +b01111110 ' +b01111110 8 +b01111110 b +b01111110 ^ +b01111110 Z +b01111110 U +b01111110 P +b01111110 I +b01111110 D +b10001000 ( +b10001000 9 +b10001000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#735 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#740 +1# +14 +1N +1$ +15 +1] +1Y +1T +1O +1H +1% +16 +1G +b00101100 ' +b00101100 8 +b00101100 b +b00101100 ^ +b00101100 Z +b00101100 U +b00101100 P +b00101100 I +b00101100 D +b00010110 ( +b00010110 9 +b00010110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#745 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#750 +1& +17 +1X +b01110001 ' +b01110001 8 +b01110001 b +b01110001 ^ +b01110001 Z +b01110001 U +b01110001 P +b01110001 I +b01110001 D +b11110111 ( +b11110111 9 +b11110111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#755 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#760 +0$ +05 +0] +0Y +0T +0O +0H +0& +07 +0X +b00011100 ' +b00011100 8 +b00011100 b +b00011100 ^ +b00011100 Z +b00011100 U +b00011100 P +b00011100 I +b00011100 D +b00001111 ( +b00001111 9 +b00001111 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#765 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#770 +0# +04 +0N +b01111100 ' +b01111100 8 +b01111100 b +b01111100 ^ +b01111100 Z +b01111100 U +b01111100 P +b01111100 I +b01111100 D +b00110100 ( +b00110100 9 +b00110100 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#775 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#780 +0" +03 +0a +0S +0M +0% +06 +0G +1& +17 +1X +b00100011 ' +b00100011 8 +b00100011 b +b00100011 ^ +b00100011 Z +b00100011 U +b00100011 P +b00100011 I +b00100011 D +b11010010 ( +b11010010 9 +b11010010 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#785 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#790 +0& +07 +0X +b00111010 ' +b00111010 8 +b00111010 b +b00111010 ^ +b00111010 Z +b00111010 U +b00111010 P +b00111010 I +b00111010 D +b00010000 ( +b00010000 9 +b00010000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#795 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#800 +1# +14 +1N +1% +16 +1G +b11110001 ' +b11110001 8 +b11110001 b +b11110001 ^ +b11110001 Z +b11110001 U +b11110001 P +b11110001 I +b11110001 D +b01100111 ( +b01100111 9 +b01100111 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#805 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#810 +1& +17 +1X +b01011011 ' +b01011011 8 +b01011011 b +b01011011 ^ +b01011011 Z +b01011011 U +b01011011 P +b01011011 I +b01011011 D +b01101101 ( +b01101101 9 +b01101101 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#815 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#820 +0& +07 +0X +b10000101 ' +b10000101 8 +b10000101 b +b10000101 ^ +b10000101 Z +b10000101 U +b10000101 P +b10000101 I +b10000101 D +b00000111 ( +b00000111 9 +b00000111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#825 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#830 +0# +04 +0N +b01110110 ' +b01110110 8 +b01110110 b +b01110110 ^ +b01110110 Z +b01110110 U +b01110110 P +b01110110 I +b01110110 D +b10011111 ( +b10011111 9 +b10011111 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#835 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#840 +1" +13 +1a +1S +1M +1$ +15 +1] +1Y +1T +1O +1H +b11011011 ' +b11011011 8 +b11011011 b +b11011011 ^ +b11011011 Z +b11011011 U +b11011011 P +b11011011 I +b11011011 D +b10101111 ( +b10101111 9 +b10101111 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#845 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#850 +1& +17 +1X +b10001100 ' +b10001100 8 +b10001100 b +b10001100 ^ +b10001100 Z +b10001100 U +b10001100 P +b10001100 I +b10001100 D +b01011110 ( +b01011110 9 +b01011110 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#855 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#860 +0" +03 +0a +0S +0M +1# +14 +1N +0% +06 +0G +0& +07 +0X +b11001101 ' +b11001101 8 +b11001101 b +b11001101 ^ +b11001101 Z +b11001101 U +b11001101 P +b11001101 I +b11001101 D +b10111100 ( +b10111100 9 +b10111100 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#865 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#870 +1" +13 +1a +1S +1M +0$ +05 +0] +0Y +0T +0O +0H +1& +17 +1X +b00010010 ' +b00010010 8 +b00010010 b +b00010010 ^ +b00010010 Z +b00010010 U +b00010010 P +b00010010 I +b00010010 D +b00110101 ( +b00110101 9 +b00110101 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#875 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#880 +0# +04 +0N +1% +16 +1G +0& +07 +0X +b10001110 ' +b10001110 8 +b10001110 b +b10001110 ^ +b10001110 Z +b10001110 U +b10001110 P +b10001110 I +b10001110 D +b10110111 ( +b10110111 9 +b10110111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#885 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#890 +0" +03 +0a +0S +0M +1# +14 +1N +1$ +15 +1] +1Y +1T +1O +1H +0% +06 +0G +b11011111 ' +b11011111 8 +b11011111 b +b11011111 ^ +b11011111 Z +b11011111 U +b11011111 P +b11011111 I +b11011111 D +b10000000 ( +b10000000 9 +b10000000 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#895 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#900 +1" +13 +1a +1S +1M +0# +04 +0N +0$ +05 +0] +0Y +0T +0O +0H +1% +16 +1G +1& +17 +1X +b00001011 ' +b00001011 8 +b00001011 b +b00001011 ^ +b00001011 Z +b00001011 U +b00001011 P +b00001011 I +b00001011 D +b00001000 ( +b00001000 9 +b00001000 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#905 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#910 +0" +03 +0a +0S +0M +1# +14 +1N +b00000101 ' +b00000101 8 +b00000101 b +b00000101 ^ +b00000101 Z +b00000101 U +b00000101 P +b00000101 I +b00000101 D +b10000111 ( +b10000111 9 +b10000111 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#915 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#920 +1$ +15 +1] +1Y +1T +1O +1H +0& +07 +0X +b11000001 ' +b11000001 8 +b11000001 b +b11000001 ^ +b11000001 Z +b11000001 U +b11000001 P +b11000001 I +b11000001 D +b10111011 ( +b10111011 9 +b10111011 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#925 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#930 +1" +13 +1a +1S +1M +0% +06 +0G +b11001100 ' +b11001100 8 +b11001100 b +b11001100 ^ +b11001100 Z +b11001100 U +b11001100 P +b11001100 I +b11001100 D +b00110101 ( +b00110101 9 +b00110101 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#935 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#940 +0# +04 +0N +0$ +05 +0] +0Y +0T +0O +0H +1% +16 +1G +b11011100 ' +b11011100 8 +b11011100 b +b11011100 ^ +b11011100 Z +b11011100 U +b11011100 P +b11011100 I +b11011100 D +b11110110 ( +b11110110 9 +b11110110 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#945 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#950 +0" +03 +0a +0S +0M +1# +14 +1N +1$ +15 +1] +1Y +1T +1O +1H +0% +06 +0G +1& +17 +1X +b01000011 ' +b01000011 8 +b01000011 b +b01000011 ^ +b01000011 Z +b01000011 U +b01000011 P +b01000011 I +b01000011 D +b00110000 ( +b00110000 9 +b00110000 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#955 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#960 +1% +16 +1G +b01111101 ' +b01111101 8 +b01111101 b +b01111101 ^ +b01111101 Z +b01111101 U +b01111101 P +b01111101 I +b01111101 D +b11011101 ( +b11011101 9 +b11011101 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#965 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#970 +0# +04 +0N +0% +06 +0G +b11001010 ' +b11001010 8 +b11001010 b +b11001010 ^ +b11001010 Z +b11001010 U +b11001010 P +b11001010 I +b11001010 D +b01001010 ( +b01001010 9 +b01001010 J +0) +0A +0e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#975 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#980 +1# +14 +1N +0& +07 +0X +b10000000 ' +b10000000 8 +b10000000 b +b10000000 ^ +b10000000 Z +b10000000 U +b10000000 P +b10000000 I +b10000000 D +b11110111 ( +b11110111 9 +b11110111 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#985 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#990 +1" +13 +1a +1S +1M +b00111001 ' +b00111001 8 +b00111001 b +b00111001 ^ +b00111001 Z +b00111001 U +b00111001 P +b00111001 I +b00111001 D +b01111110 ( +b01111110 9 +b01111110 J +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#995 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#1000 +0# +04 +0N +0$ +05 +0] +0Y +0T +0O +0H +1% +16 +1G +1& +17 +1X +b00110001 ' +b00110001 8 +b00110001 b +b00110001 ^ +b00110001 Z +b00110001 U +b00110001 P +b00110001 I +b00110001 D +b00010000 ( +b00010000 9 +b00010000 J +1) +1A +1e +0! +02 +0C +0F +0L +0R +0W +0\ +0` +0d +#1005 +1! +12 +1C +1F +1L +1R +1W +1\ +1` +1d +#1010 +1$ +15 +1] +1Y +1T +1O +1H +0& +07 +0X +b10111010 ' +b10111010 8 +b10111010 b +b10111010 ^ +b10111010 Z +b10111010 U +b10111010 P +b10111010 I +b10111010 D +b00010010 ( +b00010010 9 +b00010010 J diff --git a/tests/vcs_examples/block_level_tests/generic/flop_empty/top_flop.sv b/tests/vcs_examples/block_level_tests/generic/flop_empty/top_flop.sv new file mode 100644 index 0000000000..7cc07d463c --- /dev/null +++ b/tests/vcs_examples/block_level_tests/generic/flop_empty/top_flop.sv @@ -0,0 +1,78 @@ +module flop #(parameter WIDTH = 8) ( + input logic clk, + input logic [WIDTH-1:0] d, + output logic [WIDTH-1:0] q); + +endmodule + +module flopenl #(parameter WIDTH = 8, parameter type TYPE=logic [WIDTH-1:0]) ( + input logic clk, load, en, + input TYPE d, + input TYPE val, + output TYPE q); + +endmodule + +module flopenrc #(parameter WIDTH = 8) ( + input logic clk, reset, clear, en, + input logic [WIDTH-1:0] d, + output logic [WIDTH-1:0] q); + +endmodule + +module flopenr #(parameter WIDTH = 8) ( + input logic clk, reset, en, + input logic [WIDTH-1:0] d, + output logic [WIDTH-1:0] q); + +endmodule + +module flopens #(parameter WIDTH = 8) ( + input logic clk, set, en, + input logic [WIDTH-1:0] d, + output logic [WIDTH-1:0] q); + +endmodule + +module flopen #(parameter WIDTH = 8) ( + input logic clk, en, + input logic [WIDTH-1:0] d, + output logic [WIDTH-1:0] q); + +endmodule + +module flopr #(parameter WIDTH = 8) ( + input logic clk, reset, + input logic [WIDTH-1:0] d, + output logic [WIDTH-1:0] q); + +endmodule + +module synchronizer ( + input logic clk, + input logic d, + output logic q); + + logic mid; + +endmodule + +// Top module for testing - doesn't drive or check signals itself, meant for use with external testbench + +module top_flop( + input logic clk, reset, clear, en, load, set, + input logic [7:0] d, val, // Assuming WIDTH=8 for all submodules + output logic [7:0] q_flop, q_flopenl, q_flopenrc, q_flopenr, q_flopens, q_flopen, q_flopr, + input logic d_sync, // Separate input for synchronizer + output logic q_sync +); + + flop #(.WIDTH(8)) flop_inst (.clk(clk), .d(d), .q(q_flop)); + flopenl #(.WIDTH(8)) flopenl_inst (.clk(clk), .load(load), .en(en), .d(d), .val(val), .q(q_flopenl)); + flopenrc#(.WIDTH(8)) flopenrc_inst(.clk(clk), .reset(reset), .clear(clear), .en(en), .d(d), .q(q_flopenrc)); + flopenr #(.WIDTH(8)) flopenr_inst(.clk(clk), .reset(reset), .en(en), .d(d), .q(q_flopenr)); + flopens #(.WIDTH(8)) flopens_inst(.clk(clk), .set(set), .en(en), .d(d), .q(q_flopens)); + flopen #(.WIDTH(8)) flopen_inst (.clk(clk), .en(en), .d(d), .q(q_flopen)); + flopr #(.WIDTH(8)) flopr_inst (.clk(clk), .reset(reset), .d(d), .q(q_flopr)); + synchronizer synchronizer_inst (.clk(clk), .d(d_sync), .q(q_sync)); +endmodule diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/references/WALLY-q-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/references/WALLY-q-01.reference_output new file mode 100644 index 0000000000..6f8523bbfa --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/references/WALLY-q-01.reference_output @@ -0,0 +1,36 @@ +00000000 # fsq of 1 +00000000 +00000000 +3fff0000 +dead4000 # fsh of 1 +deadbeef +deadbeef +deadbeef +00000000 # fsq of 3 +00000000 +00000000 +40008000 +00000000 # fsq of -1 +00000000 +00000000 +bfff0000 +00000000 # fsq of 6 +00000000 +00000000 +40018000 +00000000 # fsq of -4 +00000000 +00000000 +C0010000 +00000000 # fsq of -2 +00000000 +00000000 +C0000000 +00000000 # fsq of 4 +00000000 +00000000 +40010000 +00000000 # fsq of 2 +00000000 +00000000 +40000000 diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/src/WALLY-q-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/src/WALLY-q-01.S new file mode 100644 index 0000000000..ea8bd15d5f --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/src/WALLY-q-01.S @@ -0,0 +1,154 @@ +/////////////////////////////////////////// +// ../wally-riscv-arch-test/riscv-test-suite/rv64i_m/I/src/WALLY-ADD.S +// David_Harris@hmc.edu & Rose Thompson +// Created 07 March 2024 +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64IFDQZfh_Zicsr") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN + +#ifdef TEST_CASE_1 + +RVTEST_CASE(0,"//check ISA:=regex(.*Q.*);def TEST_CASE_1=True;def NO_SAIL=True",flq-align) + +RVTEST_FP_ENABLE() +RVTEST_VALBASEUPD(x3,test_dataset_0) +RVTEST_SIGBASE(x1,signature_x1_1) + +#endif + +# turn on the floating point unit +li x7, 1 +slli x7, x7, 13 +csrw mstatus, x7 + +li x4, 1 # 3fff 0000 0000 0000 0000 0000 0000 0000 +li x2, 2 # 4000 0000 0000 0000 0000 0000 0000 0000 +fcvt.q.w f2, x2 +fcvt.q.w f4, x4 + +fcvt.h.w f5, x2 # 4000 + +# test quad load/store +fsq f4, 0(x3) +flq f7, 0(x3) +fsq f7, 0(x1) + +# test half load/store +fsh f5, 16(x3) +flh f6, 16(x3) +fsh f6, 16(x1) + +# 1 + 2 = 3 # 4000 8000 0000 0000 0000 0000 0000 0000 +fadd.q f8, f2, f4 +fsq f8, 32(x1) + +# 1 - 2 = -1 +fsub.q f9, f4, f2 # bfff 0000000000000000000000000000 +fsq f9, 48(x1) + +# 2 * 3 = 6 +fmul.q f10, f2, f8 # 4001 8000000000000000000000000000 +fsq f10, 64(x1) + +# 6 * (-1) + 2 = -4 +fmadd.q f11, f10, f9, f2 # C001 0000000000000000000000000000 +fsq f11, 80(x1) + +# -4 / 2 = -2 +fdiv.q f12, f11, f2 # C000 0000000000000000000000000000 +fsq f12, 96(x1) + +# sign injection (-4, 1) = 4 +fsgnj.q f13, f11, f4 # 4001 0000000000000000000000000000 +fsq f13, 112(x1) + +# sqrt(4) = 2 +fsqrt.q f14, f13 # 4000 0000000000000000000000000000 +fsq f14, 128(x1) + + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +.align 4 +rvtest_data: +test_dataset_0: +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +.word 0xbabecafe +.word 0xabecafeb +.word 0xbecafeba +.word 0xecafebab +test_dataset_1: +RVTEST_DATA_END + +RVMODEL_DATA_BEGIN +rvtest_sig_begin: + + + + +signature_x1_1: + .int 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef + .int 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef + .int 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef + .int 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef + .int 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef + .int 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef + .int 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef + .int 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef + .int 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef +rvtest_sig_end: +RVMODEL_DATA_END