diff --git a/.gitignore b/.gitignore index de7084d..ad93b67 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ out split_verilogs .vscode **/__pycache__/ +**.pytest_cache/ *.fst *.fst.hier *.log diff --git a/tests/Makefile b/tests/Makefile index eb75702..47949b8 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -5,12 +5,13 @@ PYTHON=python3 START_CODE="from mlvp.reporter import *;\ set_meta_info('test_case', '$(TEST)');\ -report = 'report/report.html';\ +report = 'report/$(TEST)/report.html';\ generate_pytest_report(report, args=['-s', '$(TEST_FOLDER)'], );\ " run: @echo "Running test $(TEST)..." + @mkdir report/$(TEST) -p @$(PYTHON) -c $(START_CODE) clean: diff --git a/tests/uFTB_raw/FTBEntry.py b/tests/uFTB-raw/FTBEntry.py similarity index 100% rename from tests/uFTB_raw/FTBEntry.py rename to tests/uFTB-raw/FTBEntry.py diff --git a/tests/uFTB_raw/FauFTB.py b/tests/uFTB-raw/FauFTB.py similarity index 100% rename from tests/uFTB_raw/FauFTB.py rename to tests/uFTB-raw/FauFTB.py diff --git a/tests/uFTB-raw/README.md b/tests/uFTB-raw/README.md new file mode 100644 index 0000000..8f27646 --- /dev/null +++ b/tests/uFTB-raw/README.md @@ -0,0 +1,58 @@ +# uFTB-raw + +## 介绍 + +本测试用例提供了基于模拟随机数据的香山处理器 uFTB 分支预测器的仿真验证环境,用于验证 uFTB 的缓存功能和预测功能。 + +为此,我们为 uFTB 提供了简易的 uFTB Wrapper,以向 uFTB 提供时序控制和输入输出处理。具体而言,我们提供了三种操作: + +1. 生成数据队列:由于uFTB实际上可以被是为FTB表项的一个缓存,所以我们将传递的信息封装为 FTBEntry,以便于 uFTB 的使用。而 FTBEntry 本身是一组受约束的数据,因此只要随机数据符合结果即可。 +2. 读取操作:uFTB 会根据传递的信息,从自身缓存的 FTB 表项中读取预测结果。因为我们的测试用例是随机生成的,所以我们不需要真实的预测结果,只需要保证 uFTB 的读取操作正确即可。 +3. 更新操作:uFTB 会根据传递的信息,更新自身缓存的 FTB 表项。只要更新生效,即可认为 uFTB 的更新操作正确。 + +对读取和更新操作,我们将对Pin接口的操作封装为 `get_pred` 和 `set_update` 方法,以便于 uFTB 的使用。 +同时对原始的 uFTB 模型进行了封装,由于存在很多重复的接口,我们使用 python 的元编程机制,将重复的接口合并,以减少对pin接口操作时的代码量。 + + +## 快速使用 + +### 环境配置 + +**1. 安装 mlvp** + +具体步骤参见 https://github.com/XS-MLVP/mlvp + +**2. 编译 DUT** + +在本仓库根目录下执行 + +```shell +make uftb TL=python +``` + +即可生成 DUT 编译结果,编译结果无需移动,程序会自动检索对应目录。 + +### 仿真验证 + +在 `tests` 目录下执行 + +```shell +make TEST=uFTB-raw run +``` + +即可开始仿真验证。 + +程序运行结束后,会生成对应的波形文件及覆盖率报告。波形文件位于 `tests/report/uFTB-raw` 目录下,覆盖率报告位于 `tests/report/uFTB-raw.html`。 + + +## 使用说明 + +### 目录结构 + +```bash +uFTB-raw # 测试用例名称 +|-- FTBEntry.py # 针对 FTB 表项的封装 +|-- FauFTB.py # 针对 uFTB 的二次封装,将重复信号合并,并恢复信号结构体层次 +|-- README.md +`-- test_raw.py # 测试入口,用于驱动随机数据生成、uFTB 操作 +``` diff --git a/tests/uFTB_raw/test_raw.py b/tests/uFTB-raw/test_raw.py similarity index 80% rename from tests/uFTB_raw/test_raw.py rename to tests/uFTB-raw/test_raw.py index b78b6ee..f54bba6 100644 --- a/tests/uFTB_raw/test_raw.py +++ b/tests/uFTB-raw/test_raw.py @@ -6,7 +6,7 @@ EntryList: List[Tuple[int, FTBEntry, bool, bool]] = [] def ftb_entry_list(): - for i in range(100): + for i in range(10000): pc = random.randint(0, 2**39) gentry = gen_ftb_entry(pc, True, True) EntryList.append( @@ -25,38 +25,41 @@ def get_pred(uFTB: FauFTB, pc: int) -> Tuple[int, FTBEntry, bool, bool]: return uFTB.s1_full_pred() - def set_update(uFTB: FauFTB, entry: Tuple[int, FTBEntry, bool, bool]): uFTB.io_update_valid.value = True uFTB.io_update_bits_pc.value = entry[0] # print("set_update", entry[1].brSlot) uFTB.update_ftb_entry(entry[0], entry[1], (entry[2], entry[3])) + import mlvp.funcov as fc from mlvp.reporter import * + def test_raw(request): - uFTB: FauFTB = FauFTB(waveform_filename="uftb_raw.fst", coverage_filename="uftb_raw_coverage.dat") + uFTB: FauFTB = FauFTB( + waveform_filename="report/uftb_raw.fst", coverage_filename="report/uftb_raw_coverage.dat" + ) ftb_entry_list() uFTB.reset.value = 1 uFTB.Step(100) uFTB.reset.value = 0 - for i in range(100): + for i in range(10000): # print("main1", EntryList[i - 10][1].brSlot) - j = i % 40 + j = i pred = get_pred(uFTB, EntryList[j][0]) if i > 9: # print("main2", EntryList[i - 10][1].brSlot) - set_update(uFTB, EntryList[(i - 10)%40]) + set_update(uFTB, EntryList[(i - 10)%10000]) # update data 10 cycles ago pass print("main", pred[0], pred[1].__dict__) uFTB.Step(1) uFTB.finalize() - set_line_coverage(request, "uftb_raw_coverage.dat") + set_line_coverage(request, "report/uftb_raw_coverage.dat") if __name__ == "__main__": diff --git a/tests/uFTB-with-ftq/tests/test_with_ftq.py b/tests/uFTB-with-ftq/tests/test_with_ftq.py index 3b49980..a8dcfec 100644 --- a/tests/uFTB-with-ftq/tests/test_with_ftq.py +++ b/tests/uFTB-with-ftq/tests/test_with_ftq.py @@ -41,7 +41,7 @@ from mlvp.reporter import * def test_uftb(request): # Create DUT - uFTB = DUTFauFTB(waveform_filename="uftb_with_ftq.fst", coverage_filename="uftb_with_ftq_coverage.dat") + uFTB = DUTFauFTB(waveform_filename="report/uftb_with_ftq.fst", coverage_filename="report/uftb_with_ftq_coverage.dat") uFTB.init_clock("clock") set_imm_mode(uFTB) @@ -67,10 +67,10 @@ def test_uftb(request): uFTB.xclock.StepRis(lambda _: g2.sample()) # Run the test - mlvp.setup_logging(log_level=logging.INFO, log_file="uftb_with_ftq.log") + mlvp.setup_logging(log_level=logging.INFO, log_file="report/uftb_with_ftq.log") mlvp.run(uftb_test(uFTB)) uFTB.finalize() pred_stat.summary() set_func_coverage(request, [g1, g2]) - set_line_coverage(request, "uftb_with_ftq_coverage.dat") + set_line_coverage(request, "report/uftb_with_ftq_coverage.dat")