Compare commits

...

2 Commits

Author SHA1 Message Date
ebf1182b6d fix(scripts): add missing RTL files to create_project.tcl, switch default sim to hello_world
- Add sync_rtl/common/pipeline_reg.v and sync_rtl/comp_decomp/comp_decomp_sync.v
  (were missing vs xsim_run.tcl, would cause elaboration failure)
- Change default top module from tb_mlkem_kg_katK_xsim to tb_mlkem_hello_world_xsim
- Remove unused SIM_KP/SIM_CASE variables and pre-compile KAT copy hook
2026-06-29 23:24:03 +08:00
92dafc9696 fix(rtl): add use_dsp="no" attributes, fix duplicate wire declaration
Add (* use_dsp = "no" *) to all modules containing multiplication
operators to force LUT-based multiplication instead of DSP inference:
- barrett_mul.v (3 multipliers x 7 instances = 21 ops)
- comp_decomp_sync.v, sample_ntt_sync*.v, mlkem_top.v

Also fix duplicate wire declaration of ct_bytes_rt in mlkem_top.v.
2026-06-29 23:23:58 +08:00
6 changed files with 23 additions and 51 deletions

View File

@@ -1,36 +1,26 @@
# create_project.tcl — 自动创建 Vivado 工程(仿真用),加载 ML-KEM KeyGen
# 顶层 mlkem_top 及其全部叶子算子与参数化 KAT testbench。
# create_project.tcl — 自动创建 Vivado 工程(仿真用),加载 ML-KEM 顶层模块
# mlkem_top 及其全部叶子算子与 hello_world 端到端 testbench。
#
# 与已验证的 XSIM 流程sync_rtl/top/TB/xsim_run.tcl保持一致:
# 与已验证的 XSIM 流程保持一致:
# - 加载 mlkem_top 实际依赖的全部 RTL 源文件(含 sd_bram 存储)
# - 顶层仿真模块 = tb_mlkem_kg_katK_xsim
# - 运行时安全等级由 generic KP2/3/4选择用例号由 +CASE 选择
# - 顶层仿真模块 = tb_mlkem_hello_world_xsim
#
# Usage:
# cd ~/Dev/mlkem
# vivado -mode batch -source create_project.tcl
# 或在 Vivado Tcl Console 中:
# source create_project.tcl
#
# 切换被仿真的配置(默认 KP=2, CASE=0编辑下方 SIM_KP / SIM_CASE 后重跑,
# 或在工程打开后执行:
# set_property generic "KP=4" [get_filesets sim_1]
# set_property -name {xsim.simulate.xsim.more_options} -value {-testplusarg CASE=2} -objects [get_filesets sim_1]
set PROJECT_NAME mlkem
set PROJECT_DIR [file normalize [file dirname [info script]]]
# 默认仿真配置(可改)
set SIM_KP 2 ;# ML-KEM 方案2=512, 3=768, 4=1024
set SIM_CASE 0 ;# KAT 用例号K=2: 0..4, K=3/4: 0..2
# 仅仿真工程,无需指定 FPGA partXSim 用默认 part 即可)
create_project -force ${PROJECT_NAME} ${PROJECT_DIR}/vivado_prj
set_property target_simulator XSim [current_project]
# ===================================================================
# RTL 源文件 —— 与 xsim_run.tcl 完全一致
# RTL 源文件 —— hello_world 所需的全部模块
# ===================================================================
# ── SHA3 / Keccak ──
@@ -56,60 +46,41 @@ read_verilog -sv ${PROJECT_DIR}/sync_rtl/poly_mul/poly_mul_sync.v
# ── 存储ek/dk 字节缓冲registered-read BRAM──
read_verilog -sv ${PROJECT_DIR}/sync_rtl/storage/sd_bram.v
# ── 公共原语 ──
read_verilog -sv ${PROJECT_DIR}/sync_rtl/common/pipeline_reg.v
# ── 压缩 / 解压缩 ──
read_verilog -sv ${PROJECT_DIR}/sync_rtl/comp_decomp/comp_decomp_sync.v
# ── 顶层 KeyGen 集成 ──
read_verilog -sv ${PROJECT_DIR}/sync_rtl/top/mlkem_top.v
# ── 参数化 KAT testbench ──
read_verilog -sv ${PROJECT_DIR}/sync_rtl/top/TB/tb_mlkem_kg_katK_xsim.v
# ── hello_world 端到端 testbench ──
read_verilog -sv ${PROJECT_DIR}/sync_rtl/top/TB/tb_mlkem_hello_world_xsim.v
# ===================================================================
# 仿真设置
# ===================================================================
# 顶层仿真模块
set_property top tb_mlkem_kg_katK_xsim [get_filesets sim_1]
set_property top tb_mlkem_hello_world_xsim [get_filesets sim_1]
set_property top_lib xil_defaultlib [get_filesets sim_1]
# `include "sync_rtl/common/defines.vh" 的包含路径(相对工程根)
set_property include_dirs ${PROJECT_DIR} [get_filesets sim_1]
# 运行时安全等级:通过 TB 顶层 generic KP 传入2/3/4
set_property generic "KP=${SIM_KP}" [get_filesets sim_1]
# hello_world TB 使用 localparam KP=2硬编码无 generic 传入
# 切换 K 值需编辑 tb_mlkem_hello_world_xsim.v 中的 KP 参数后重跑
# 跑到 $finish 为止显式时标XSim 默认已加 --relax勿重复
set_property -name {xsim.simulate.runtime} -value {all} -objects [get_filesets sim_1]
set_property -name {xsim.elaborate.xelab.more_options} \
-value {--timescale 1ns/1ps} -objects [get_filesets sim_1]
# ===================================================================
# 测试向量Vivado GUI 在 vivado_prj/mlkem.sim/sim_1/behav/xsim/ 下运行
# xsim而 TB 的 $readmemh 路径相对工程根sync_rtl/top/TB/vectors/…)。
# 用 compile 的 pre-hook在 xsim 工作目录、且在 compile/elaborate/simulate
# 之前执行)把整套 KAT 向量复制到同名相对路径下CASE 经 -testplusarg 选择。
#
# 注意2019.2 的 sim_1 没有 simulate.tcl.pre 属性,且追加 -tclbatch 会排在
# Vivado 自带(含 "run all")的 tclbatch 之后、即仿真跑完才执行(太迟)。
# 因此用 xsim.compile.tcl.pre —— 它最早执行且就在仿真工作目录里。
# ===================================================================
set pre_tcl [file join ${PROJECT_DIR} vivado_prj copy_vectors_pre.tcl]
set fp [open $pre_tcl w]
puts $fp "# Auto-generated by create_project.tcl: KAT xsim "
puts $fp "file mkdir sync_rtl/top/TB/vectors"
puts $fp "foreach v \[glob -nocomplain [file join ${PROJECT_DIR} sync_rtl top TB vectors kat_k*_c*_*.hex]\] {"
puts $fp " file copy -force \$v sync_rtl/top/TB/vectors/"
puts $fp "}"
puts $fp "puts {\[create_project\] KAT vectors copied to xsim working dir}"
close $fp
set_property -name {xsim.compile.tcl.pre} -value $pre_tcl -objects [get_filesets sim_1]
set_property -name {xsim.simulate.xsim.more_options} \
-value "-testplusarg CASE=${SIM_CASE}" \
-objects [get_filesets sim_1]
# ===================================================================
puts "========================================"
puts " Project created: ${PROJECT_DIR}/vivado_prj/${PROJECT_NAME}.xpr"
puts " 仿: ML-KEM K=${SIM_KP}, KAT CASE=${SIM_CASE}"
puts " 仿: tb_mlkem_hello_world_xsim (K=2 )"
puts ""
puts " 仿runtime=all TB \$finish"
puts " - GUI: Run Simulation Tcl Console: launch_simulation"
@@ -117,8 +88,5 @@ puts " - batch: vivado -mode batch -source create_project.tcl 后,"
puts " : open_project vivado_prj/mlkem.xpr; launch_simulation"
puts " launch_simulation run all 仿 \$finish"
puts " run TB 120ms timeout"
puts " : K=${SIM_KP} CASE ${SIM_CASE} PASS: ek==pk, dk==sk"
puts ""
puts " K=4 SIM_KP/SIM_CASE "
puts " generic relaunch_sim"
puts " : hello_world : KeyGenEncapsXORDecapsXOR PASS"
puts "========================================"

View File

@@ -10,6 +10,7 @@
`include "sync_rtl/common/defines.vh"
(* use_dsp = "no" *)
module comp_decomp_sync (
input clk,
input rst_n,

View File

@@ -6,6 +6,7 @@
// Pure combinational, single-cycle latency.
// All multiplication widths explicitly controlled to avoid Verilog truncation.
(* use_dsp = "no" *)
module barrett_mul (
input [11:0] a,
input [11:0] b,

View File

@@ -31,6 +31,7 @@
`include "sync_rtl/common/defines.vh"
/* verilator lint_off UNUSEDPARAM */
(* use_dsp = "no" *)
module sample_ntt_sync #(parameter K = 4) (
/* verilator lint_on UNUSEDPARAM */
input clk,

View File

@@ -44,6 +44,7 @@
`include "sync_rtl/common/defines.vh"
/* verilator lint_off UNUSEDPARAM */
(* use_dsp = "no" *)
module sample_ntt_sync_shared #(parameter K = 4) (
/* verilator lint_on UNUSEDPARAM */
input clk,

View File

@@ -22,6 +22,7 @@
`include "sync_rtl/common/defines.vh"
(* use_dsp = "no" *)
module mlkem_top #(
parameter KMAX = 4 // storage sizing (worst case = ML-KEM-1024)
) (
@@ -133,7 +134,6 @@ module mlkem_top #(
wire [11:0] c1_bytes_rt = 12'd32 * {7'b0, du_rt} * {9'b0, k_r}; // 640/960/1408
wire [11:0] c2_bytes_rt = 12'd32 * {7'b0, dv_rt}; // 128/128/160
wire [11:0] ct_bytes_rt = c1_bytes_rt + c2_bytes_rt; // 768/1088/1568
wire [11:0] ct_bytes_rt = c1_bytes_rt + c2_bytes_rt; // 768/1088/1568
// Shared secret out: Encaps drives ss_r = K directly. Decaps implicit reject:
// ss = (c' == c) ? K' : K-bar. K' is in ss_r, K-bar in kbar_r; dec_reject is
// the latched c' != c flag from D7 (0 for KeyGen/Encaps, so ss_r passes through).