From 32c09ff0f181a4115b325276a24563ff5ab6073b Mon Sep 17 00:00:00 2001 From: leeyunlong <1203701249@qq.com> Date: Mon, 21 Jul 2025 09:45:15 +0800 Subject: [PATCH] new files --- Scripts/gen_apb_file/apb_file_test.xls | Bin 0 -> 9728 bytes Scripts/gen_apb_file/apb_file_test.xls.bak | Bin 0 -> 35840 bytes Scripts/gen_apb_file/do_apb_file.py | 138 ++++++++++++++++++ Scripts/{ => gen_apb_file}/gen_apb_file.py | 66 ++++++--- .../old_apb.py} | 0 Scripts/gen_sram_wrap/area_and_timing.txt | 31 ++++ Scripts/gen_sram_wrap/datasheet.txt | 0 Scripts/gen_sram_wrap/gen_sram_wrap.py | 19 ++- Scripts/gen_sram_wrap/get_ds_info.py | 91 ++++++++++++ ...ts1n12ffcllulvta1024x133_ssgnp0p72v125c.ds | 57 ++++++++ Scripts/template.xls | Bin 52736 -> 50176 bytes Scripts/test.xls | Bin 13824 -> 0 bytes 12 files changed, 379 insertions(+), 23 deletions(-) create mode 100644 Scripts/gen_apb_file/apb_file_test.xls create mode 100644 Scripts/gen_apb_file/apb_file_test.xls.bak create mode 100644 Scripts/gen_apb_file/do_apb_file.py rename Scripts/{ => gen_apb_file}/gen_apb_file.py (95%) rename Scripts/{do_apb_file.py => gen_apb_file/old_apb.py} (100%) create mode 100644 Scripts/gen_sram_wrap/area_and_timing.txt create mode 100644 Scripts/gen_sram_wrap/datasheet.txt create mode 100644 Scripts/gen_sram_wrap/get_ds_info.py create mode 100644 Scripts/gen_sram_wrap/ts1n12ffcllulvta1024x133/DATASHEET/ts1n12ffcllulvta1024x133_ssgnp0p72v125c.ds delete mode 100644 Scripts/test.xls diff --git a/Scripts/gen_apb_file/apb_file_test.xls b/Scripts/gen_apb_file/apb_file_test.xls new file mode 100644 index 0000000000000000000000000000000000000000..54871ab7bbeb045582ee7409081025cb1dbf3cf6 GIT binary patch literal 9728 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 M|4>AG(0|1LHyb$HQ2+n{ literal 0 HcmV?d00001 diff --git a/Scripts/gen_apb_file/apb_file_test.xls.bak b/Scripts/gen_apb_file/apb_file_test.xls.bak new file mode 100644 index 0000000000000000000000000000000000000000..2e4667ea8a207fe679a57a44abf649fdb7e6af7f GIT binary patch literal 35840 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 literal 0 HcmV?d00001 diff --git a/Scripts/gen_apb_file/do_apb_file.py b/Scripts/gen_apb_file/do_apb_file.py new file mode 100644 index 0000000..9ad18ee --- /dev/null +++ b/Scripts/gen_apb_file/do_apb_file.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +import os +import xlrd +import xlwt +import shutil + +def parse_args(): + if len(sys.argv) < 2: + print("Usage: python3 xxx.py xxx.xls [-name sheetName]") + sys.exit(1) + file_path = sys.argv[1] + sheet_name = None + if '-name' in sys.argv: + idx = sys.argv.index('-name') + if idx + 1 < len(sys.argv): + sheet_name = sys.argv[idx + 1] + else: + print("Error: -name 参数后需跟 sheet 名称") + sys.exit(1) + if not os.path.exists(file_path): + print(f"文件 {file_path} 不存在") + sys.exit(1) + return file_path, sheet_name + +def find_header_indices(sheet): + header = [str(sheet.cell_value(0, col)).strip() for col in range(sheet.ncols)] + try: + bits_col = header.index('Bits') + offset_col = header.index('OffsetAddress') + regname_col = header.index('RegName') + offsetwidth_col = header.index('OffsetWidth') + except ValueError as e: + print(f"表头缺失: {e}") + sys.exit(1) + return bits_col, offset_col, regname_col, offsetwidth_col + +def process_sheet(sheet, wb, sheet_name): + bits_col, offset_col, regname_col, offsetwidth_col = find_header_indices(sheet) + ws = wb.add_sheet(sheet_name) + # 复制表头 + for col in range(sheet.ncols): + ws.write(0, col, sheet.cell_value(0, col)) + + offset = 0 + reg_idx = 0 + row = 1 + while row < sheet.nrows: + bits_start_cell = str(sheet.cell_value(row, bits_col)).strip() + # 匹配 '31' 或 '[31:' 开头 + if bits_start_cell == '31.0' or bits_start_cell.startswith('[31:'): + print(f"Processing row {row+1}: Bits = {bits_start_cell}") + # replace OffsetAddress + offset_str = f"0x{offset:02X}" + ws.write(row, offset_col, offset_str) + # replace RegName + reg_str = f"reg_{reg_idx:02X}" + ws.write(row, regname_col, reg_str) + # 校验 + if offset // 4 != reg_idx: + print(f"[Check] OffsetAddress {offset_str} 与 RegName {reg_str} 不匹配") + # Bits列刷新 + offset += 4 + reg_idx += 1 + + bits_sum = 0 + left = 31 + start_row = row + # one Bits row starts and ends + while row < sheet.nrows: + # 复制其他列 + for col in range(sheet.ncols): + if col in (bits_col, offset_col, regname_col): + continue + ws.write(row, col, sheet.cell_value(row, col)) + + width = (sheet.cell_value(row, offsetwidth_col)) + if width is None or width == '': + ws.write(row, bits_col, sheet.cell_value(row, bits_col)) + bits_cell = str(sheet.cell_value(row, bits_col)).strip() + row += 1 + if bits_cell.endswith('0]'): + print(f"Bits cell ends with 0, breaking at row {row}") + break + else: + continue + + if int(width) < 0 or int(width) > 32: + raise ValueError(f"OffsetWidth {width} 不在 0-32 范围内") + + width = int(width) + right = left - width + 1 + if left == right: + bits_str = f"[{left}]" + else: + bits_str = f"[{left}:{right}]" + + ws.write(row, bits_col, bits_str) + + bits_sum += width + + left = right - 1 + # next row + bits_end_cell = str(sheet.cell_value(row, bits_col)).strip() + if bits_end_cell == '0' or bits_start_cell.endswith('0]') or right == 0: + row += 1 + print(f"The 0 is bits_end_cell") + break + row += 1 + + if bits_sum != 32: + print(f"[Warning] {sheet_name} 第{start_row+1}行起 OffsetWidth 累加为{bits_sum},应为32") + else: + # 其他行保持原样 + ws.write(row, offset_col, sheet.cell_value(row, offset_col)) + ws.write(row, regname_col, sheet.cell_value(row, regname_col)) + ws.write(row, bits_col, sheet.cell_value(row, bits_col)) + row += 1 + +def main(): + file_path, sheet_name = parse_args() + # 先备份原文件 + shutil.copyfile(file_path, file_path + ".bak") + book = xlrd.open_workbook(file_path) + wb = xlwt.Workbook() + sheets = [sheet_name] if sheet_name else book.sheet_names() + print(sheets) + for name in sheets: + sheet = book.sheet_by_name(name) + process_sheet(sheet, wb, name) + # 覆盖原文件 + wb.save(file_path) + print(f"已刷新并覆盖原文件: {file_path},原文件已备份为: {file_path}.bak") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/Scripts/gen_apb_file.py b/Scripts/gen_apb_file/gen_apb_file.py similarity index 95% rename from Scripts/gen_apb_file.py rename to Scripts/gen_apb_file/gen_apb_file.py index f590a5d..24eb2b3 100644 --- a/Scripts/gen_apb_file.py +++ b/Scripts/gen_apb_file/gen_apb_file.py @@ -2,10 +2,12 @@ # coding: utf-8 import xlrd +import xlwt import re import os import sys import math +import do_apb_file # ========================================================== # func process excel start#{{{ @@ -630,29 +632,53 @@ def gen_reg_ralf(p_sheet,ModuleName): #max_rows=sheet0.nrows#行数 #max_cols=sheet0.ncols#列数 -if(len(sys.argv) < 2): - print("[Error]:Not have input file") - print("Usage : %s .xlsx"%(sys.argv[0])) - sys.exit(1) +#def parse_args(): +# """解析命令行参数""" +# parser = argparse.ArgumentParser(description='Generate APB register files') +# parser.add_argument('xls_file', help='Excel configuration file path') +# parser.add_argument('-proc', action='store_true', +# help='Enable Excel preprocessing before generation') +# return parser.parse_args() + +if __name__ == "__main__": + if(len(sys.argv) < 2): + print("[Error]:Not have input file") + print("Usage : %s .xlsx"%(sys.argv[0])) + sys.exit(1) + + if(sys.argv[1]=='-help'): + print("Usage : %s .xlsx"%(sys.argv[0])) + sys.exit(0) + + if(os.path.exists(sys.argv[1])==False): + print(f"[Error]: 文件 {sys.argv[1]} 不存在") + print("[Error]:Not such file") + sys.exit(1) + + file_path = sys.argv[1] + + with_proc = False + if len(sys.argv) > 2 and '-proc' in sys.argv: + with_proc = True + + #book = xlrd.open_workbook(file_path) + + book = xlrd.open_workbook(file_path) + sheets = [sheet_name] if sheet_name else book.sheet_names() + + wb = xlwt.Workbook() + for name in sheets: + if with_proc: + process_sheet(sheets,wb,name) + wb.save(file_path) + + for name in sheets: + gen_reg_hdl(sheet0,ModuleName) + gen_reg_cheader(sheet0,ModuleName) + gen_reg_ralf(sheet0,ModuleName) -if(sys.argv[1]=='-help'): - print("Usage : %s .xlsx"%(sys.argv[0])) sys.exit(0) -if(os.path.exists(sys.argv[1])==False): - print(f"[Error]: 文件 {sys.argv[1]} 不存在") - print("[Error]:Not such file") - sys.exit(1) -book = xlrd.open_workbook(sys.argv[1]) -sheets_num = len(book.sheet_names()) -for index in range (sheets_num): - sheet0 = book.sheet_by_index(index) - ModuleName = sheet0.name - #ModuleName = re.search('^[a-z]+',sys.argv[1]).group()#从开头位置开始匹配返回第一个,而findall返回一个list - gen_reg_hdl(sheet0,ModuleName) - gen_reg_cheader(sheet0,ModuleName) - gen_reg_ralf(sheet0,ModuleName) -sys.exit(0) diff --git a/Scripts/do_apb_file.py b/Scripts/gen_apb_file/old_apb.py similarity index 100% rename from Scripts/do_apb_file.py rename to Scripts/gen_apb_file/old_apb.py diff --git a/Scripts/gen_sram_wrap/area_and_timing.txt b/Scripts/gen_sram_wrap/area_and_timing.txt new file mode 100644 index 0000000..59464df --- /dev/null +++ b/Scripts/gen_sram_wrap/area_and_timing.txt @@ -0,0 +1,31 @@ +======== ts1n12ffcllulvta1024x133_ssgnp0p72v125c.ds ========== +[Area Info] +1. Area +Pre-shrink (dimensions in GDS database) +Width(um) Height(um) Area(um²) +66.6950 284.9760 19006.4743 + +2.1 Timing Protocol (Refer to the waveforms in the databook) + +xxxxxxxxxxxxxxxxxx + +[Timing Info] +The following values are based on 1st point of LUT (Look Up Table) in NLDM liberty file + +I Normal +Symbol Param. Value (ns) Parameter +tcyc 0.9469 Minimum CLK cycle time +tckh 0.0952 Minimum CLK Pulse High +tckl 0.1565 Minimum CLK Pulse Low +tcd 0.5055 CLK to valid Q (data output) +thold 0.3776 CLK to invalid Q (data output) +tcs 0.1204 CEB setup before CLK rising +tch 0.0736 CEB hold after CLK rising +tas 0.0927 A setup before CLK rising +tah 0.0939 A hold after CLK rising +tws 0.1108 WEB setup before CLK rising +tbwh 0.0860 WEB hold after CLK rising +Error: tcycֵ (0.9469ns > 0.8ns) + +================================================================================ + diff --git a/Scripts/gen_sram_wrap/datasheet.txt b/Scripts/gen_sram_wrap/datasheet.txt new file mode 100644 index 0000000..e69de29 diff --git a/Scripts/gen_sram_wrap/gen_sram_wrap.py b/Scripts/gen_sram_wrap/gen_sram_wrap.py index 75d047f..afa7f24 100644 --- a/Scripts/gen_sram_wrap/gen_sram_wrap.py +++ b/Scripts/gen_sram_wrap/gen_sram_wrap.py @@ -90,6 +90,7 @@ def gen_sram_sh(rb,sheet_name, output_dir): with open(sh_path, 'w') as f: f.write("#!/bin/bash\n") f.write("\n".join(sorted(commands))) + os.chmod(sh_path, 0o755) # 设置可执行权限 except Exception as e: print(f"Generate shell script failed: {str(e)}") @@ -99,11 +100,23 @@ def gen_config_txt(sram_name, compiler, compile_depth, compile_width, mux, outpu config_dir = os.path.join(output_dir, "config") os.makedirs(config_dir, exist_ok=True) - config_content = f"{compile_depth}x{compile_width}m{mux}scp ulvt" + if(compiler == 'tsn12ffcllspsram_130b'): + config_content = f"{compile_depth}x{compile_width}m{mux}scp ulvt " + elif(compiler == 'tsn12ffcll2prf_130a'): + config_content = f"{compile_depth}x{compile_width}m{mux}scp ulvt " + elif(compiler == 'tsn12ffclluhd2prf_130b'): + config_content = f"{compile_depth}x{compile_width}m{mux} ulvt " + elif(compiler == 'tsn12ffcllshcspsbsram_130c'): + config_content = f"{compile_depth}x{compile_width}m{mux}s ulvt " + elif(compiler == 'tsn12ffcll1prf_130a'): + config_content = f"{compile_depth}x{compile_width}m{mux}scp ulvt " + else: + config_content = f"{compile_depth}x{compile_width}m{mux}scp ulvt " config_path = os.path.join(config_dir, f"{sram_name}_{compiler}_config.txt") with open(config_path, 'w') as f: f.write(config_content) + f.write("\n") def generate_files(xls_path, sheet_name=None): @@ -164,7 +177,7 @@ def generate_files(xls_path, sheet_name=None): sram_port = 'SRAM_SP' template_file = "template_sram_sp_wrap.v" elif row[col_map['port']] == 'TP': - sram_port = 'SRAM_SYNC_TP' if (row[col_map['ASYNC']] == 'No') else 'SRAM_ASYNC_TP' + sram_port = 'SRAM_SYNC_TP' if (row[col_map['ASYNC']] == 'No' or row[col_map['ASYNC']] == 'NO') else 'SRAM_ASYNC_TP' template_file = "template_sram_tp_wrap.v" if (row[col_map['ASYNC']] == 'No') \ else "template_sram_tp_async_wrap.v" else: # Assembly @@ -172,7 +185,7 @@ def generate_files(xls_path, sheet_name=None): sram_port = 'SRAM_SP' template_file = "template_sram_sp_wrap_asmbly.v" elif row[col_map['port']] == 'TP': - sram_port = 'SRAM_SYNC_TP_ASMBLY' if (row[col_map['ASYNC']] == 'No') else 'SRAM_ASYNC_TP_ASMBLY' + sram_port = 'SRAM_SYNC_TP_ASMBLY' if (row[col_map['ASYNC']] == 'No' or row[col_map['ASYNC']] == 'NO') else 'SRAM_ASYNC_TP_ASMBLY' template_file = "template_sram_tp_wrap_asmbly.v" if (row[col_map['ASYNC']] == 'No') \ else "template_sram_tp_async_wrap_asmbly.v" diff --git a/Scripts/gen_sram_wrap/get_ds_info.py b/Scripts/gen_sram_wrap/get_ds_info.py new file mode 100644 index 0000000..fad3713 --- /dev/null +++ b/Scripts/gen_sram_wrap/get_ds_info.py @@ -0,0 +1,91 @@ +import os +import glob + +def extract_info(file_path): + """提取关键信息""" + area_info = [] + sram_timing = [] + error_msgs = [] + + with open(file_path, 'r') as f: + lines = f.readlines() + in_area = False + + for i, line in enumerate(lines): + # 提取Area信息块 + if line.strip().startswith("1. Area"): + area_info = lines[i:i+8] + break # 每个文件只提取第一个Area块 + + # 提取时序信息(直接搜索tcyc到tbwh) + tcyc_line = next((i for i, line in enumerate(lines) if line.strip().startswith("2.2 SRAM timing")), None) + tbwh_line = next((i for i, line in enumerate(lines) if line.strip().startswith("tbwh")), None) + if tbwh_line is None: + tbwh_line = tcyc_line + 10 + + if tcyc_line is not None and tbwh_line is not None: + sram_timing = lines[tcyc_line+2:tbwh_line+1] + else: + print(f"Warning: Timing info not found in {file_path}") + + # 新增数值提取逻辑 + tcyc_value = None + tcd_value = None + + # 提取时序值 + for line in lines: + line_clean = line.strip() + # 提取tcyc值 + if line_clean.startswith('tcyc'): + parts = line_clean.split() + if len(parts) >= 2: + val_str = parts[1] + print(f"Processing tcyc value: {val_str}") + try: + tcyc_value = float(val_str) + if tcyc_value > 0.8: + error_msgs.append(f"Error: tcyc OVER ({tcyc_value}ns > 0.8ns)") + except ValueError: + pass + # 提取tcd值 + elif line_clean.startswith('tcd'): + parts = line_clean.split() + if len(parts) >= 2: + val_str = parts[1] + print(f"Processing tcyc value: {val_str}") + try: + tcd_value = float(val_str) + if tcd_value > 0.6: + error_msgs.append(f"Error: tcd OVER ({tcd_value}ns > 0.6ns)") + except ValueError: + pass + + return area_info, sram_timing, error_msgs + +def write_info(): + output = [] + + # 递归所有子目录 + for root, _, files in os.walk('.'): + # 匹配目标文件模式 + for ds_file in glob.glob(os.path.join(root, '*_ssgnp0p72v125c.ds')): + print(f"Processing: {ds_file}") + area, timing, error_msgs = extract_info(ds_file) + + output.append(f"======== {os.path.basename(ds_file)} ==========\n") + output.append("[Area Info]\n") + output.extend(area) + output.append("\n[Timing Info]\n") + output.extend(timing) + if error_msgs: + print (f"Errors found in {ds_file}: {error_msgs}") + output.extend([msg + "\n" for msg in error_msgs]) + output.append("\n" + "="*80 + "\n") + output.append("\n") + + # 写入结果文件 + with open('area_and_timing.txt', 'w') as f: + f.writelines(output) + +if __name__ == "__main__": + write_info() diff --git a/Scripts/gen_sram_wrap/ts1n12ffcllulvta1024x133/DATASHEET/ts1n12ffcllulvta1024x133_ssgnp0p72v125c.ds b/Scripts/gen_sram_wrap/ts1n12ffcllulvta1024x133/DATASHEET/ts1n12ffcllulvta1024x133_ssgnp0p72v125c.ds new file mode 100644 index 0000000..65360be --- /dev/null +++ b/Scripts/gen_sram_wrap/ts1n12ffcllulvta1024x133/DATASHEET/ts1n12ffcllulvta1024x133_ssgnp0p72v125c.ds @@ -0,0 +1,57 @@ +1. Area +Pre-shrink (dimensions in GDS database) +Width(um) Height(um) Area(um²) +66.6950 284.9760 19006.4743 + +2.1 Timing Protocol (Refer to the waveforms in the databook) + +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd + +2.2 SRAM timing +2.2.1 Normal Mode and Power Management Mode +The following values are based on 1st point of LUT (Look Up Table) in NLDM liberty file + +I Normal +Symbol Param. Value (ns) Parameter +tcyc 0.9469 Minimum CLK cycle time +tckh 0.0952 Minimum CLK Pulse High +tckl 0.1565 Minimum CLK Pulse Low +tcd 0.5055 CLK to valid Q (data output) +thold 0.3776 CLK to invalid Q (data output) +tcs 0.1204 CEB setup before CLK rising +tch 0.0736 CEB hold after CLK rising +tas 0.0927 A setup before CLK rising +tah 0.0939 A hold after CLK rising +tws 0.1108 WEB setup before CLK rising +tbwh 0.0860 WEB hold after CLK rising +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd +xxxxxxxxxxxxxxxxxx +ddddddddddddddd \ No newline at end of file diff --git a/Scripts/template.xls b/Scripts/template.xls index f16ee41de1f9e4ba762f5458a6f35772f8ae7cf5..6b179a1eed94764e00575a761465c5f56b8c0021 100644 GIT binary patch delta 9646 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 We!l-gYk|A&c_;5UG!nG)&;I~Jh>n>6 delta 11940 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 diff --git a/Scripts/test.xls b/Scripts/test.xls deleted file mode 100644 index 3b3ef241924c2d9b953092f9474d323b08891e88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13824 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