Fix ML-KEM arithmetic timing paths

This commit is contained in:
2026-07-07 18:28:47 +08:00
parent 2fb1cd67e3
commit 8c3f4317f5
12 changed files with 5030 additions and 63 deletions

View File

@@ -40,6 +40,7 @@ read_verilog -sv ${PROJECT_DIR}/sync_rtl/ntt/ntt_core.v
# ── 多项式乘法 ── # ── 多项式乘法 ──
read_verilog -sv ${PROJECT_DIR}/sync_rtl/poly_mul/basecase_mul.v read_verilog -sv ${PROJECT_DIR}/sync_rtl/poly_mul/basecase_mul.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/poly_mul/basecase_mul_pipe.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/poly_mul/poly_mul_zeta_rom.v read_verilog -sv ${PROJECT_DIR}/sync_rtl/poly_mul/poly_mul_zeta_rom.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/poly_mul/poly_mul_sync.v read_verilog -sv ${PROJECT_DIR}/sync_rtl/poly_mul/poly_mul_sync.v

BIN
reports/mlkem_top_synth.dcp Normal file

Binary file not shown.

652
reports/timing_synth.rpt Normal file
View File

@@ -0,0 +1,652 @@
Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
-------------------------------------------------------------------------------------------------
| Tool Version : Vivado v.2019.2 (lin64) Build 2708876 Wed Nov 6 21:39:14 MST 2019
| Date : Tue Jul 7 15:28:57 2026
| Host : fedora running 64-bit unknown
| Command : report_timing_summary -file /home/fallensigh/Dev/mlkem/reports/timing_synth.rpt
| Design : mlkem_top
| Device : 7a200t-fbg676
| Speed File : -1 PRODUCTION 1.23 2018-06-13
-------------------------------------------------------------------------------------------------
Timing Summary Report
------------------------------------------------------------------------------------------------
| Timer Settings
| --------------
------------------------------------------------------------------------------------------------
Enable Multi Corner Analysis : Yes
Enable Pessimism Removal : Yes
Pessimism Removal Resolution : Nearest Common Node
Enable Input Delay Default Clock : No
Enable Preset / Clear Arcs : No
Disable Flight Delays : No
Ignore I/O Paths : No
Timing Early Launch at Borrowing Latches : No
Borrow Time for Max Delay Exceptions : Yes
Merge Timing Exceptions : Yes
Corner Analyze Analyze
Name Max Paths Min Paths
------ --------- ---------
Slow Yes Yes
Fast Yes Yes
check_timing report
Table of Contents
-----------------
1. checking no_clock
2. checking constant_clock
3. checking pulse_width_clock
4. checking unconstrained_internal_endpoints
5. checking no_input_delay
6. checking no_output_delay
7. checking multiple_clock
8. checking generated_clocks
9. checking loops
10. checking partial_input_delay
11. checking partial_output_delay
12. checking latch_loops
1. checking no_clock
--------------------
There are 0 register/latch pins with no clock.
2. checking constant_clock
--------------------------
There are 0 register/latch pins with constant_clock.
3. checking pulse_width_clock
-----------------------------
There are 0 register/latch pins which need pulse_width check
4. checking unconstrained_internal_endpoints
--------------------------------------------
There are 0 pins that are not constrained for maximum delay.
There are 0 pins that are not constrained for maximum delay due to constant clock.
5. checking no_input_delay
--------------------------
There are 629 input ports with no input delay specified. (HIGH)
There are 0 input ports with no input delay but user has a false path constraint.
6. checking no_output_delay
---------------------------
There are 2342 ports with no output delay specified. (HIGH)
There are 0 ports with no output delay but user has a false path constraint
There are 0 ports with no output delay but with a timing clock defined on it or propagating through it
7. checking multiple_clock
--------------------------
There are 0 register/latch pins with multiple clocks.
8. checking generated_clocks
----------------------------
There are 0 generated clocks that are not connected to a clock source.
9. checking loops
-----------------
There are 0 combinational loops in the design.
10. checking partial_input_delay
--------------------------------
There are 0 input ports with partial input delay specified.
11. checking partial_output_delay
---------------------------------
There are 0 ports with partial output delay specified.
12. checking latch_loops
------------------------
There are 0 combinational latch loops in the design through latch input
------------------------------------------------------------------------------------------------
| Design Timing Summary
| ---------------------
------------------------------------------------------------------------------------------------
WNS(ns) TNS(ns) TNS Failing Endpoints TNS Total Endpoints WHS(ns) THS(ns) THS Failing Endpoints THS Total Endpoints WPWS(ns) TPWS(ns) TPWS Failing Endpoints TPWS Total Endpoints
------- ------- --------------------- ------------------- ------- ------- --------------------- ------------------- -------- -------- ---------------------- --------------------
-40.169 -37681.270 3108 45226 0.080 0.000 0 45226 9.020 0.000 0 23791
Timing constraints are not met.
------------------------------------------------------------------------------------------------
| Clock Summary
| -------------
------------------------------------------------------------------------------------------------
Clock Waveform(ns) Period(ns) Frequency(MHz)
----- ------------ ---------- --------------
sysclk {0.000 10.000} 20.000 50.000
------------------------------------------------------------------------------------------------
| Intra Clock Table
| -----------------
------------------------------------------------------------------------------------------------
Clock WNS(ns) TNS(ns) TNS Failing Endpoints TNS Total Endpoints WHS(ns) THS(ns) THS Failing Endpoints THS Total Endpoints WPWS(ns) TPWS(ns) TPWS Failing Endpoints TPWS Total Endpoints
----- ------- ------- --------------------- ------------------- ------- ------- --------------------- ------------------- -------- -------- ---------------------- --------------------
sysclk -40.169 -37681.270 3108 45226 0.080 0.000 0 45226 9.020 0.000 0 23791
------------------------------------------------------------------------------------------------
| Inter Clock Table
| -----------------
------------------------------------------------------------------------------------------------
From Clock To Clock WNS(ns) TNS(ns) TNS Failing Endpoints TNS Total Endpoints WHS(ns) THS(ns) THS Failing Endpoints THS Total Endpoints
---------- -------- ------- ------- --------------------- ------------------- ------- ------- --------------------- -------------------
------------------------------------------------------------------------------------------------
| Other Path Groups Table
| -----------------------
------------------------------------------------------------------------------------------------
Path Group From Clock To Clock WNS(ns) TNS(ns) TNS Failing Endpoints TNS Total Endpoints WHS(ns) THS(ns) THS Failing Endpoints THS Total Endpoints
---------- ---------- -------- ------- ------- --------------------- ------------------- ------- ------- --------------------- -------------------
------------------------------------------------------------------------------------------------
| Timing Details
| --------------
------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
From Clock: sysclk
To Clock: sysclk
Setup : 3108 Failing Endpoints, Worst Slack -40.169ns, Total Violation -37681.271ns
Hold : 0 Failing Endpoints, Worst Slack 0.080ns, Total Violation 0.000ns
PW : 0 Failing Endpoints, Worst Slack 9.020ns, Total Violation 0.000ns
---------------------------------------------------------------------------------------------------
Max Delay Paths
--------------------------------------------------------------------------------------
Slack (VIOLATED) : -40.169ns (required time - arrival time)
Source: st_reg[3]/C
(rising edge-triggered cell FDCE clocked by sysclk {rise@0.000ns fall@10.000ns period=20.000ns})
Destination: u_comp/u_pipe/data_r_reg[0]/D
(rising edge-triggered cell FDCE clocked by sysclk {rise@0.000ns fall@10.000ns period=20.000ns})
Path Group: sysclk
Path Type: Setup (Max at Slow Process Corner)
Requirement: 20.000ns (sysclk rise@20.000ns - sysclk rise@0.000ns)
Data Path Delay: 60.018ns (logic 37.409ns (62.330%) route 22.609ns (37.670%))
Logic Levels: 115 (CARRY4=105 LUT1=1 LUT2=2 LUT3=2 LUT5=3 LUT6=2)
Clock Path Skew: -0.145ns (DCD - SCD + CPR)
Destination Clock Delay (DCD): 2.106ns = ( 22.106 - 20.000 )
Source Clock Delay (SCD): 2.430ns
Clock Pessimism Removal (CPR): 0.178ns
Clock Uncertainty: 0.035ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE
Total System Jitter (TSJ): 0.071ns
Total Input Jitter (TIJ): 0.000ns
Discrete Jitter (DJ): 0.000ns
Phase Error (PE): 0.000ns
Location Delay type Incr(ns) Path(ns) Netlist Resource(s)
------------------------------------------------------------------- -------------------
(clock sysclk rise edge) 0.000 0.000 r
0.000 0.000 r clk (IN)
net (fo=0) 0.000 0.000 clk
IBUF (Prop_ibuf_I_O) 0.950 0.950 r clk_IBUF_inst/O
net (fo=1, unplaced) 0.800 1.750 clk_IBUF
BUFG (Prop_bufg_I_O) 0.096 1.846 r clk_IBUF_BUFG_inst/O
net (fo=23790, unplaced) 0.584 2.430 clk_IBUF_BUFG
FDCE r st_reg[3]/C
------------------------------------------------------------------- -------------------
FDCE (Prop_fdce_C_Q) 0.456 2.886 f st_reg[3]/Q
net (fo=118, unplaced) 0.910 3.796 u_bank_a/snt_valid_reg[2]
LUT5 (Prop_lut5_I0_O) 0.295 4.091 r u_bank_a/valid_r_i_2/O
net (fo=211, unplaced) 0.567 4.658 u_bank_a_n_38
LUT3 (Prop_lut3_I1_O) 0.124 4.782 r data_r[11]_i_227/O
net (fo=2, unplaced) 0.460 5.242 cd_in_mux[7]
LUT2 (Prop_lut2_I1_O) 0.124 5.366 r data_r[11]_i_170/O
net (fo=1, unplaced) 0.000 5.366 data_r[11]_i_170_n_0
CARRY4 (Prop_carry4_S[1]_CO[3])
0.550 5.916 r data_r_reg[11]_i_135/CO[3]
net (fo=1, unplaced) 0.009 5.925 data_r_reg[11]_i_135_n_0
CARRY4 (Prop_carry4_CI_O[1])
0.348 6.273 r data_r_reg[11]_i_140/O[1]
net (fo=3, unplaced) 0.629 6.902 data_r_reg[11]_i_140_n_6
LUT3 (Prop_lut3_I0_O) 0.306 7.208 r data_r[11]_i_141/O
net (fo=2, unplaced) 0.460 7.668 data_r[11]_i_141_n_0
LUT5 (Prop_lut5_I4_O) 0.124 7.792 r data_r[11]_i_130/O
net (fo=2, unplaced) 0.460 8.252 data_r[11]_i_130_n_0
LUT6 (Prop_lut6_I0_O) 0.124 8.376 r data_r[11]_i_134/O
net (fo=1, unplaced) 0.000 8.376 data_r[11]_i_134_n_0
CARRY4 (Prop_carry4_S[0]_CO[3])
0.532 8.908 r data_r_reg[11]_i_101/CO[3]
net (fo=1, unplaced) 0.000 8.908 data_r_reg[11]_i_101_n_0
CARRY4 (Prop_carry4_CI_O[1])
0.348 9.256 r data_r_reg[11]_i_252/O[1]
net (fo=1, unplaced) 0.715 9.971 product[17]
CARRY4 (Prop_carry4_S[1]_CO[3])
0.854 10.825 r data_r_reg[11]_i_203/CO[3]
net (fo=1, unplaced) 0.000 10.825 data_r_reg[11]_i_203_n_0
CARRY4 (Prop_carry4_CI_O[3])
0.329 11.154 r data_r_reg[11]_i_321/O[3]
net (fo=1, unplaced) 0.618 11.772 dividend[23]
LUT2 (Prop_lut2_I1_O) 0.307 12.079 r data_r[11]_i_365/O
net (fo=1, unplaced) 0.000 12.079 data_r[11]_i_365_n_0
CARRY4 (Prop_carry4_S[0]_CO[2])
0.536 12.615 r data_r_reg[11]_i_351/CO[2]
net (fo=3, unplaced) 0.354 12.969 data_r_reg[11]_i_351_n_1
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.766 13.735 r data_r_reg[11]_i_338/CO[3]
net (fo=3, unplaced) 0.838 14.573 data_r_reg[11]_i_338_n_0
CARRY4 (Prop_carry4_CYINIT_CO[2])
0.617 15.190 r data_r_reg[11]_i_334/CO[2]
net (fo=2, unplaced) 0.347 15.537 data_r_reg[11]_i_334_n_1
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.766 16.303 r data_r_reg[11]_i_306/CO[3]
net (fo=23, unplaced) 0.981 17.284 data_r_reg[11]_i_306_n_0
LUT6 (Prop_lut6_I5_O) 0.124 17.408 r data_r[11]_i_311/O
net (fo=1, unplaced) 0.639 18.047 data_r[11]_i_311_n_0
CARRY4 (Prop_carry4_DI[1]_CO[3])
0.507 18.554 r data_r_reg[11]_i_286/CO[3]
net (fo=1, unplaced) 0.000 18.554 data_r_reg[11]_i_286_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 18.732 r data_r_reg[11]_i_285/CO[1]
net (fo=20, unplaced) 0.585 19.317 data_r_reg[11]_i_285_n_2
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 20.105 r data_r_reg[11]_i_316/CO[3]
net (fo=1, unplaced) 0.009 20.114 data_r_reg[11]_i_316_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 20.228 r data_r_reg[11]_i_289/CO[3]
net (fo=1, unplaced) 0.000 20.228 data_r_reg[11]_i_289_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 20.342 r data_r_reg[11]_i_261/CO[3]
net (fo=1, unplaced) 0.000 20.342 data_r_reg[11]_i_261_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 20.520 r data_r_reg[11]_i_260/CO[1]
net (fo=20, unplaced) 0.585 21.105 data_r_reg[11]_i_260_n_2
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 21.893 r data_r_reg[11]_i_294/CO[3]
net (fo=1, unplaced) 0.009 21.902 data_r_reg[11]_i_294_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 22.016 r data_r_reg[11]_i_264/CO[3]
net (fo=1, unplaced) 0.000 22.016 data_r_reg[11]_i_264_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 22.130 r data_r_reg[11]_i_236/CO[3]
net (fo=1, unplaced) 0.000 22.130 data_r_reg[11]_i_236_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 22.308 r data_r_reg[11]_i_235/CO[1]
net (fo=20, unplaced) 0.585 22.893 data_r_reg[11]_i_235_n_2
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 23.681 r data_r_reg[11]_i_269/CO[3]
net (fo=1, unplaced) 0.009 23.690 data_r_reg[11]_i_269_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 23.804 r data_r_reg[11]_i_239/CO[3]
net (fo=1, unplaced) 0.000 23.804 data_r_reg[11]_i_239_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 23.918 r data_r_reg[11]_i_190/CO[3]
net (fo=1, unplaced) 0.000 23.918 data_r_reg[11]_i_190_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 24.096 r data_r_reg[11]_i_189/CO[1]
net (fo=20, unplaced) 0.585 24.681 data_r_reg[11]_i_189_n_2
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 25.469 r data_r_reg[11]_i_244/CO[3]
net (fo=1, unplaced) 0.009 25.478 data_r_reg[11]_i_244_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 25.592 r data_r_reg[11]_i_193/CO[3]
net (fo=1, unplaced) 0.000 25.592 data_r_reg[11]_i_193_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 25.706 r data_r_reg[11]_i_144/CO[3]
net (fo=1, unplaced) 0.000 25.706 data_r_reg[11]_i_144_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 25.884 r data_r_reg[11]_i_143/CO[1]
net (fo=20, unplaced) 0.585 26.469 data_r_reg[11]_i_143_n_2
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 27.257 r data_r_reg[11]_i_198/CO[3]
net (fo=1, unplaced) 0.009 27.266 data_r_reg[11]_i_198_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 27.380 r data_r_reg[11]_i_147/CO[3]
net (fo=1, unplaced) 0.000 27.380 data_r_reg[11]_i_147_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 27.494 r data_r_reg[11]_i_111/CO[3]
net (fo=1, unplaced) 0.000 27.494 data_r_reg[11]_i_111_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 27.672 r data_r_reg[11]_i_110/CO[1]
net (fo=20, unplaced) 0.585 28.257 data_r_reg[11]_i_110_n_2
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 29.045 r data_r_reg[11]_i_152/CO[3]
net (fo=1, unplaced) 0.009 29.054 data_r_reg[11]_i_152_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 29.168 r data_r_reg[11]_i_114/CO[3]
net (fo=1, unplaced) 0.000 29.168 data_r_reg[11]_i_114_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 29.282 r data_r_reg[11]_i_85/CO[3]
net (fo=1, unplaced) 0.000 29.282 data_r_reg[11]_i_85_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 29.460 r data_r_reg[11]_i_84/CO[1]
net (fo=20, unplaced) 0.585 30.045 data_r_reg[11]_i_84_n_2
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 30.833 r data_r_reg[11]_i_119/CO[3]
net (fo=1, unplaced) 0.009 30.842 data_r_reg[11]_i_119_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 30.956 r data_r_reg[11]_i_88/CO[3]
net (fo=1, unplaced) 0.000 30.956 data_r_reg[11]_i_88_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 31.070 r data_r_reg[11]_i_64/CO[3]
net (fo=1, unplaced) 0.000 31.070 data_r_reg[11]_i_64_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 31.248 r data_r_reg[11]_i_63/CO[1]
net (fo=20, unplaced) 0.585 31.833 data_r_reg[11]_i_63_n_2
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 32.621 r data_r_reg[11]_i_93/CO[3]
net (fo=1, unplaced) 0.009 32.630 data_r_reg[11]_i_93_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 32.744 r data_r_reg[11]_i_67/CO[3]
net (fo=1, unplaced) 0.000 32.744 data_r_reg[11]_i_67_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 32.858 r data_r_reg[11]_i_44/CO[3]
net (fo=1, unplaced) 0.000 32.858 data_r_reg[11]_i_44_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 33.036 r data_r_reg[11]_i_43/CO[1]
net (fo=20, unplaced) 0.585 33.621 data_r_reg[11]_i_43_n_2
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 34.409 r data_r_reg[11]_i_72/CO[3]
net (fo=1, unplaced) 0.009 34.418 data_r_reg[11]_i_72_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 34.532 r data_r_reg[11]_i_47/CO[3]
net (fo=1, unplaced) 0.000 34.532 data_r_reg[11]_i_47_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 34.646 r data_r_reg[11]_i_28/CO[3]
net (fo=1, unplaced) 0.000 34.646 data_r_reg[11]_i_28_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 34.824 r data_r_reg[11]_i_27/CO[1]
net (fo=20, unplaced) 0.585 35.409 data_r_reg[11]_i_27_n_2
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 36.197 r data_r_reg[11]_i_52/CO[3]
net (fo=1, unplaced) 0.009 36.206 data_r_reg[11]_i_52_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 36.320 r data_r_reg[11]_i_31/CO[3]
net (fo=1, unplaced) 0.000 36.320 data_r_reg[11]_i_31_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 36.434 r data_r_reg[11]_i_16/CO[3]
net (fo=1, unplaced) 0.000 36.434 data_r_reg[11]_i_16_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 36.612 r data_r_reg[11]_i_15/CO[1]
net (fo=20, unplaced) 0.585 37.197 data_r_reg[11]_i_15_n_2
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 37.985 r data_r_reg[11]_i_37/CO[3]
net (fo=1, unplaced) 0.009 37.994 data_r_reg[11]_i_37_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 38.108 r data_r_reg[11]_i_22/CO[3]
net (fo=1, unplaced) 0.000 38.108 data_r_reg[11]_i_22_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 38.222 r data_r_reg[11]_i_14/CO[3]
net (fo=1, unplaced) 0.000 38.222 data_r_reg[11]_i_14_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 38.400 r data_r_reg[11]_i_6/CO[1]
net (fo=23, unplaced) 0.588 38.988 div_result[11]
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 39.776 r data_r_reg[10]_i_11/CO[3]
net (fo=1, unplaced) 0.009 39.785 data_r_reg[10]_i_11_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 39.899 r data_r_reg[10]_i_6/CO[3]
net (fo=1, unplaced) 0.000 39.899 data_r_reg[10]_i_6_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 40.013 r data_r_reg[10]_i_3/CO[3]
net (fo=1, unplaced) 0.000 40.013 data_r_reg[10]_i_3_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 40.191 r data_r_reg[10]_i_2/CO[1]
net (fo=23, unplaced) 0.588 40.779 div_result[10]
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 41.567 r data_r_reg[9]_i_16/CO[3]
net (fo=1, unplaced) 0.009 41.576 data_r_reg[9]_i_16_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 41.690 r data_r_reg[9]_i_11/CO[3]
net (fo=1, unplaced) 0.000 41.690 data_r_reg[9]_i_11_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 41.804 r data_r_reg[9]_i_4/CO[3]
net (fo=1, unplaced) 0.000 41.804 data_r_reg[9]_i_4_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 41.982 r data_r_reg[9]_i_2/CO[1]
net (fo=23, unplaced) 0.588 42.570 div_result[9]
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 43.358 r data_r_reg[8]_i_11/CO[3]
net (fo=1, unplaced) 0.009 43.367 data_r_reg[8]_i_11_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 43.481 r data_r_reg[8]_i_6/CO[3]
net (fo=1, unplaced) 0.000 43.481 data_r_reg[8]_i_6_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 43.595 r data_r_reg[8]_i_3/CO[3]
net (fo=1, unplaced) 0.000 43.595 data_r_reg[8]_i_3_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 43.773 r data_r_reg[8]_i_2/CO[1]
net (fo=23, unplaced) 0.588 44.361 div_result[8]
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 45.149 r data_r_reg[7]_i_21/CO[3]
net (fo=1, unplaced) 0.009 45.158 data_r_reg[7]_i_21_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 45.272 r data_r_reg[7]_i_16/CO[3]
net (fo=1, unplaced) 0.000 45.272 data_r_reg[7]_i_16_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 45.386 r data_r_reg[7]_i_13/CO[3]
net (fo=1, unplaced) 0.000 45.386 data_r_reg[7]_i_13_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 45.564 r data_r_reg[7]_i_4/CO[1]
net (fo=23, unplaced) 0.588 46.152 div_result[7]
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 46.940 r data_r_reg[6]_i_11/CO[3]
net (fo=1, unplaced) 0.009 46.949 data_r_reg[6]_i_11_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 47.063 r data_r_reg[6]_i_6/CO[3]
net (fo=1, unplaced) 0.000 47.063 data_r_reg[6]_i_6_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 47.177 r data_r_reg[6]_i_3/CO[3]
net (fo=1, unplaced) 0.000 47.177 data_r_reg[6]_i_3_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 47.355 r data_r_reg[6]_i_2/CO[1]
net (fo=23, unplaced) 0.588 47.943 div_result[6]
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 48.731 r data_r_reg[5]_i_11/CO[3]
net (fo=1, unplaced) 0.009 48.740 data_r_reg[5]_i_11_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 48.854 r data_r_reg[5]_i_6/CO[3]
net (fo=1, unplaced) 0.000 48.854 data_r_reg[5]_i_6_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 48.968 r data_r_reg[5]_i_3/CO[3]
net (fo=1, unplaced) 0.000 48.968 data_r_reg[5]_i_3_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 49.146 r data_r_reg[5]_i_2/CO[1]
net (fo=23, unplaced) 0.588 49.734 div_result[5]
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 50.522 r data_r_reg[4]_i_11/CO[3]
net (fo=1, unplaced) 0.009 50.531 data_r_reg[4]_i_11_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 50.645 r data_r_reg[4]_i_6/CO[3]
net (fo=1, unplaced) 0.000 50.645 data_r_reg[4]_i_6_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 50.759 r data_r_reg[4]_i_3/CO[3]
net (fo=1, unplaced) 0.000 50.759 data_r_reg[4]_i_3_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 50.937 r data_r_reg[4]_i_2/CO[1]
net (fo=23, unplaced) 0.588 51.525 div_result[4]
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 52.313 r data_r_reg[3]_i_20/CO[3]
net (fo=1, unplaced) 0.009 52.322 data_r_reg[3]_i_20_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 52.436 r data_r_reg[3]_i_15/CO[3]
net (fo=1, unplaced) 0.000 52.436 data_r_reg[3]_i_15_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 52.550 r data_r_reg[3]_i_12/CO[3]
net (fo=1, unplaced) 0.000 52.550 data_r_reg[3]_i_12_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 52.728 r data_r_reg[3]_i_4/CO[1]
net (fo=23, unplaced) 0.588 53.316 div_result[3]
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 54.104 r data_r_reg[2]_i_11/CO[3]
net (fo=1, unplaced) 0.009 54.113 data_r_reg[2]_i_11_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 54.227 r data_r_reg[2]_i_6/CO[3]
net (fo=1, unplaced) 0.000 54.227 data_r_reg[2]_i_6_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 54.341 r data_r_reg[2]_i_3/CO[3]
net (fo=1, unplaced) 0.000 54.341 data_r_reg[2]_i_3_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 54.519 r data_r_reg[2]_i_2/CO[1]
net (fo=23, unplaced) 0.588 55.107 div_result[2]
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 55.895 r data_r_reg[1]_i_11/CO[3]
net (fo=1, unplaced) 0.009 55.904 data_r_reg[1]_i_11_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 56.018 r data_r_reg[1]_i_6/CO[3]
net (fo=1, unplaced) 0.000 56.018 data_r_reg[1]_i_6_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 56.132 r data_r_reg[1]_i_3/CO[3]
net (fo=1, unplaced) 0.000 56.132 data_r_reg[1]_i_3_n_0
CARRY4 (Prop_carry4_CI_CO[1])
0.178 56.310 r data_r_reg[1]_i_2/CO[1]
net (fo=23, unplaced) 0.588 56.898 div_result[1]
CARRY4 (Prop_carry4_CYINIT_CO[3])
0.788 57.686 r data_r_reg[0]_i_10/CO[3]
net (fo=1, unplaced) 0.009 57.695 data_r_reg[0]_i_10_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 57.809 r data_r_reg[0]_i_5/CO[3]
net (fo=1, unplaced) 0.000 57.809 data_r_reg[0]_i_5_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 57.923 r data_r_reg[0]_i_3/CO[3]
net (fo=1, unplaced) 0.000 57.923 data_r_reg[0]_i_3_n_0
CARRY4 (Prop_carry4_CI_CO[0])
0.293 58.216 f data_r_reg[0]_i_2/CO[0]
net (fo=3, unplaced) 0.329 58.545 u_comp/u_pipe/div_result[0]
LUT1 (Prop_lut1_I0_O) 0.367 58.912 r u_comp/u_pipe/data_r[3]_i_11/O
net (fo=1, unplaced) 0.000 58.912 u_comp/u_pipe/data_r[3]_i_11_n_0
CARRY4 (Prop_carry4_S[0]_CO[3])
0.532 59.444 r u_comp/u_pipe/data_r_reg[3]_i_3/CO[3]
net (fo=1, unplaced) 0.009 59.453 u_comp/u_pipe/data_r_reg[3]_i_3_n_0
CARRY4 (Prop_carry4_CI_CO[3])
0.114 59.567 r u_comp/u_pipe/data_r_reg[7]_i_3/CO[3]
net (fo=1, unplaced) 0.000 59.567 u_comp/u_pipe/data_r_reg[7]_i_3_n_0
CARRY4 (Prop_carry4_CI_O[3])
0.329 59.896 r u_comp/u_pipe/data_r_reg[11]_i_5/O[3]
net (fo=2, unplaced) 0.824 60.720 u_comp/u_pipe/data_r_reg[11]_i_5_n_4
CARRY4 (Prop_carry4_S[3]_CO[3])
0.709 61.429 r u_comp/u_pipe/data_r_reg[11]_i_3/CO[3]
net (fo=1, unplaced) 0.000 61.429 u_comp/u_pipe/data_r_reg[11]_i_3_n_0
CARRY4 (Prop_carry4_CI_CO[0])
0.293 61.722 r u_comp/u_pipe/data_r_reg[11]_i_4/CO[0]
net (fo=12, unplaced) 0.359 62.081 u_comp/u_pipe/data_r_reg[11]_i_4_n_3
LUT5 (Prop_lut5_I1_O) 0.367 62.448 r u_comp/u_pipe/data_r[0]_i_1/O
net (fo=1, unplaced) 0.000 62.448 u_comp/u_pipe/mod_result[0]
FDCE r u_comp/u_pipe/data_r_reg[0]/D
------------------------------------------------------------------- -------------------
(clock sysclk rise edge) 20.000 20.000 r
0.000 20.000 r clk (IN)
net (fo=0) 0.000 20.000 clk
IBUF (Prop_ibuf_I_O) 0.817 20.817 r clk_IBUF_inst/O
net (fo=1, unplaced) 0.760 21.576 clk_IBUF
BUFG (Prop_bufg_I_O) 0.091 21.667 r clk_IBUF_BUFG_inst/O
net (fo=23790, unplaced) 0.439 22.106 u_comp/u_pipe/clk_IBUF_BUFG
FDCE r u_comp/u_pipe/data_r_reg[0]/C
clock pessimism 0.178 22.285
clock uncertainty -0.035 22.249
FDCE (Setup_fdce_C_D) 0.029 22.278 u_comp/u_pipe/data_r_reg[0]
-------------------------------------------------------------------
required time 22.278
arrival time -62.448
-------------------------------------------------------------------
slack -40.169
Min Delay Paths
--------------------------------------------------------------------------------------
Slack (MET) : 0.080ns (arrival time - required time)
Source: u_pmul/FSM_onehot_state_reg[3]/C
(rising edge-triggered cell FDCE clocked by sysclk {rise@0.000ns fall@10.000ns period=20.000ns})
Destination: u_pmul/u_bc/valid_sr_reg[4]_srl5_u_pmul_u_bc_valid_sr_reg_c_3/D
(rising edge-triggered cell SRL16E clocked by sysclk {rise@0.000ns fall@10.000ns period=20.000ns})
Path Group: sysclk
Path Type: Hold (Min at Fast Process Corner)
Requirement: 0.000ns (sysclk rise@0.000ns - sysclk rise@0.000ns)
Data Path Delay: 0.289ns (logic 0.141ns (48.726%) route 0.148ns (51.274%))
Logic Levels: 0
Clock Path Skew: 0.145ns (DCD - SCD - CPR)
Destination Clock Delay (DCD): 1.011ns
Source Clock Delay (SCD): 0.656ns
Clock Pessimism Removal (CPR): 0.209ns
Location Delay type Incr(ns) Path(ns) Netlist Resource(s)
------------------------------------------------------------------- -------------------
(clock sysclk rise edge) 0.000 0.000 r
0.000 0.000 r clk (IN)
net (fo=0) 0.000 0.000 clk
IBUF (Prop_ibuf_I_O) 0.179 0.179 r clk_IBUF_inst/O
net (fo=1, unplaced) 0.337 0.516 clk_IBUF
BUFG (Prop_bufg_I_O) 0.026 0.542 r clk_IBUF_BUFG_inst/O
net (fo=23790, unplaced) 0.114 0.656 u_pmul/clk_IBUF_BUFG
FDCE r u_pmul/FSM_onehot_state_reg[3]/C
------------------------------------------------------------------- -------------------
FDCE (Prop_fdce_C_Q) 0.141 0.797 r u_pmul/FSM_onehot_state_reg[3]/Q
net (fo=3, unplaced) 0.148 0.946 u_pmul/u_bc/Q[3]
SRL16E r u_pmul/u_bc/valid_sr_reg[4]_srl5_u_pmul_u_bc_valid_sr_reg_c_3/D
------------------------------------------------------------------- -------------------
(clock sysclk rise edge) 0.000 0.000 r
0.000 0.000 r clk (IN)
net (fo=0) 0.000 0.000 clk
IBUF (Prop_ibuf_I_O) 0.368 0.368 r clk_IBUF_inst/O
net (fo=1, unplaced) 0.355 0.723 clk_IBUF
BUFG (Prop_bufg_I_O) 0.029 0.752 r clk_IBUF_BUFG_inst/O
net (fo=23790, unplaced) 0.259 1.011 u_pmul/u_bc/clk_IBUF_BUFG
SRL16E r u_pmul/u_bc/valid_sr_reg[4]_srl5_u_pmul_u_bc_valid_sr_reg_c_3/CLK
clock pessimism -0.209 0.801
SRL16E (Hold_srl16e_CLK_D)
0.064 0.865 u_pmul/u_bc/valid_sr_reg[4]_srl5_u_pmul_u_bc_valid_sr_reg_c_3
-------------------------------------------------------------------
required time -0.865
arrival time 0.946
-------------------------------------------------------------------
slack 0.080
Pulse Width Checks
--------------------------------------------------------------------------------------
Clock Name: sysclk
Waveform(ns): { 0.000 10.000 }
Period(ns): 20.000
Sources: { clk }
Check Type Corner Lib Pin Reference Pin Required(ns) Actual(ns) Slack(ns) Location Pin
Min Period n/a RAMB18E1/CLKARDCLK n/a 2.944 20.000 17.056 u_ct_bram/mem_reg/CLKARDCLK
Low Pulse Width Slow SRL16E/CLK n/a 0.980 10.000 9.020 u_pmul/u_bc/t1_s4_reg[0]_srl2_u_pmul_u_bc_valid_sr_reg_c_0/CLK
High Pulse Width Fast SRL16E/CLK n/a 0.980 10.000 9.020 u_pmul/u_bc/t1_s4_reg[0]_srl2_u_pmul_u_bc_valid_sr_reg_c_0/CLK

File diff suppressed because it is too large Load Diff

192
reports/util_synth.rpt Normal file
View File

@@ -0,0 +1,192 @@
Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
--------------------------------------------------------------------------------------------
| Tool Version : Vivado v.2019.2 (lin64) Build 2708876 Wed Nov 6 21:39:14 MST 2019
| Date : Tue Jul 7 15:28:57 2026
| Host : fedora running 64-bit unknown
| Command : report_utilization -file /home/fallensigh/Dev/mlkem/reports/util_synth.rpt
| Design : mlkem_top
| Device : 7a200tfbg676-1
| Design State : Synthesized
--------------------------------------------------------------------------------------------
Utilization Design Information
Table of Contents
-----------------
1. Slice Logic
1.1 Summary of Registers by Type
2. Memory
3. DSP
4. IO and GT Specific
5. Clocking
6. Specific Feature
7. Primitives
8. Black Boxes
9. Instantiated Netlists
1. Slice Logic
--------------
+----------------------------+-------+-------+-----------+-------+
| Site Type | Used | Fixed | Available | Util% |
+----------------------------+-------+-------+-----------+-------+
| Slice LUTs* | 32814 | 0 | 134600 | 24.38 |
| LUT as Logic | 32777 | 0 | 134600 | 24.35 |
| LUT as Memory | 37 | 0 | 46200 | 0.08 |
| LUT as Distributed RAM | 0 | 0 | | |
| LUT as Shift Register | 37 | 0 | | |
| Slice Registers | 23737 | 0 | 269200 | 8.82 |
| Register as Flip Flop | 23737 | 0 | 269200 | 8.82 |
| Register as Latch | 0 | 0 | 269200 | 0.00 |
| F7 Muxes | 3384 | 0 | 67300 | 5.03 |
| F8 Muxes | 1205 | 0 | 33650 | 3.58 |
+----------------------------+-------+-------+-----------+-------+
* Warning! The Final LUT count, after physical optimizations and full implementation, is typically lower. Run opt_design after synthesis, if not already completed, for a more realistic count.
1.1 Summary of Registers by Type
--------------------------------
+-------+--------------+-------------+--------------+
| Total | Clock Enable | Synchronous | Asynchronous |
+-------+--------------+-------------+--------------+
| 0 | _ | - | - |
| 0 | _ | - | Set |
| 0 | _ | - | Reset |
| 0 | _ | Set | - |
| 0 | _ | Reset | - |
| 0 | Yes | - | - |
| 3 | Yes | - | Set |
| 23614 | Yes | - | Reset |
| 0 | Yes | Set | - |
| 120 | Yes | Reset | - |
+-------+--------------+-------------+--------------+
2. Memory
---------
+-------------------+------+-------+-----------+-------+
| Site Type | Used | Fixed | Available | Util% |
+-------------------+------+-------+-----------+-------+
| Block RAM Tile | 5 | 0 | 365 | 1.37 |
| RAMB36/FIFO* | 2 | 0 | 365 | 0.55 |
| RAMB36E1 only | 2 | | | |
| RAMB18 | 6 | 0 | 730 | 0.82 |
| RAMB18E1 only | 6 | | | |
+-------------------+------+-------+-----------+-------+
* Note: Each Block RAM Tile only has one FIFO logic available and therefore can accommodate only one FIFO36E1 or one FIFO18E1. However, if a FIFO18E1 occupies a Block RAM Tile, that tile can still accommodate a RAMB18E1
3. DSP
------
+-----------+------+-------+-----------+-------+
| Site Type | Used | Fixed | Available | Util% |
+-----------+------+-------+-----------+-------+
| DSPs | 0 | 0 | 740 | 0.00 |
+-----------+------+-------+-----------+-------+
4. IO and GT Specific
---------------------
+-----------------------------+------+-------+-----------+--------+
| Site Type | Used | Fixed | Available | Util% |
+-----------------------------+------+-------+-----------+--------+
| Bonded IOB | 3228 | 0 | 400 | 807.00 |
| Bonded IPADs | 0 | 0 | 26 | 0.00 |
| Bonded OPADs | 0 | 0 | 16 | 0.00 |
| PHY_CONTROL | 0 | 0 | 10 | 0.00 |
| PHASER_REF | 0 | 0 | 10 | 0.00 |
| OUT_FIFO | 0 | 0 | 40 | 0.00 |
| IN_FIFO | 0 | 0 | 40 | 0.00 |
| IDELAYCTRL | 0 | 0 | 10 | 0.00 |
| IBUFDS | 0 | 0 | 384 | 0.00 |
| GTPE2_CHANNEL | 0 | 0 | 8 | 0.00 |
| PHASER_OUT/PHASER_OUT_PHY | 0 | 0 | 40 | 0.00 |
| PHASER_IN/PHASER_IN_PHY | 0 | 0 | 40 | 0.00 |
| IDELAYE2/IDELAYE2_FINEDELAY | 0 | 0 | 500 | 0.00 |
| IBUFDS_GTE2 | 0 | 0 | 4 | 0.00 |
| ILOGIC | 0 | 0 | 400 | 0.00 |
| OLOGIC | 0 | 0 | 400 | 0.00 |
+-----------------------------+------+-------+-----------+--------+
5. Clocking
-----------
+------------+------+-------+-----------+-------+
| Site Type | Used | Fixed | Available | Util% |
+------------+------+-------+-----------+-------+
| BUFGCTRL | 1 | 0 | 32 | 3.13 |
| BUFIO | 0 | 0 | 40 | 0.00 |
| MMCME2_ADV | 0 | 0 | 10 | 0.00 |
| PLLE2_ADV | 0 | 0 | 10 | 0.00 |
| BUFMRCE | 0 | 0 | 20 | 0.00 |
| BUFHCE | 0 | 0 | 120 | 0.00 |
| BUFR | 0 | 0 | 40 | 0.00 |
+------------+------+-------+-----------+-------+
6. Specific Feature
-------------------
+-------------+------+-------+-----------+-------+
| Site Type | Used | Fixed | Available | Util% |
+-------------+------+-------+-----------+-------+
| BSCANE2 | 0 | 0 | 4 | 0.00 |
| CAPTUREE2 | 0 | 0 | 1 | 0.00 |
| DNA_PORT | 0 | 0 | 1 | 0.00 |
| EFUSE_USR | 0 | 0 | 1 | 0.00 |
| FRAME_ECCE2 | 0 | 0 | 1 | 0.00 |
| ICAPE2 | 0 | 0 | 2 | 0.00 |
| PCIE_2_1 | 0 | 0 | 1 | 0.00 |
| STARTUPE2 | 0 | 0 | 1 | 0.00 |
| XADC | 0 | 0 | 1 | 0.00 |
+-------------+------+-------+-----------+-------+
7. Primitives
-------------
+----------+-------+---------------------+
| Ref Name | Used | Functional Category |
+----------+-------+---------------------+
| FDCE | 23614 | Flop & Latch |
| LUT6 | 17906 | LUT |
| LUT3 | 8519 | LUT |
| LUT5 | 5910 | LUT |
| MUXF7 | 3384 | MuxFx |
| LUT4 | 3044 | LUT |
| LUT2 | 2820 | LUT |
| OBUF | 2342 | IO |
| MUXF8 | 1205 | MuxFx |
| IBUF | 886 | IO |
| CARRY4 | 879 | CarryLogic |
| LUT1 | 208 | LUT |
| FDRE | 120 | Flop & Latch |
| SRL16E | 37 | Distributed Memory |
| RAMB18E1 | 6 | Block Memory |
| FDPE | 3 | Flop & Latch |
| RAMB36E1 | 2 | Block Memory |
| BUFG | 1 | Clock |
+----------+-------+---------------------+
8. Black Boxes
--------------
+----------+------+
| Ref Name | Used |
+----------+------+
9. Instantiated Netlists
------------------------
+----------+------+
| Ref Name | Used |
+----------+------+

View File

@@ -1,8 +1,9 @@
// comp_decomp_sync.v - ML-KEM coefficient compression/decompression // comp_decomp_sync.v - ML-KEM coefficient compression/decompression
// //
// Streaming: one coefficient per cycle through pipeline_reg. // Streaming valid/ready interface. Compression is intentionally iterative to
// avoid inferring a long combinational divider for /Q.
// mode=0: compress round((2^d * x) / Q) mod 2^d // mode=0: compress round((2^d * x) / Q) mod 2^d
// mode=1: decompress round((Q * x) / 2^d) mod Q // mode=1: decompress round((Q * x) / 2^d)
// Uses round-half-up (round(2.5)=3, round(3.5)=4). // Uses round-half-up (round(2.5)=3, round(3.5)=4).
// Integer arithmetic: // Integer arithmetic:
// compress: (x * 2^d + Q/2) / Q, lower d bits as result // compress: (x * 2^d + Q/2) / Q, lower d bits as result
@@ -24,52 +25,81 @@ module comp_decomp_sync (
input ready_i input ready_i
); );
// 2^d for d in {4,5,10,11}; fits in 12 bits (max 2048) localparam [11:0] Q_VAL = 12'(`Q);
wire [11:0] two_pow_d; localparam [4:0] COMP_MSB = 5'd22; // max ((Q-1)<<11)+Q/2 is 23 bits
assign two_pow_d = 12'd1 << d;
// Product: 12-bit * 12-bit = max 2048*3328 = 6,815,744 23 bits (use 24) reg busy_r;
wire [23:0] product; reg [4:0] bit_idx_r;
reg [4:0] d_r;
reg [23:0] dividend_r;
reg [23:0] quotient_r;
reg [12:0] rem_r;
reg [11:0] data_r;
reg valid_r;
// compress: x * 2^d; decompress: x * Q wire fire_i = valid_i && ready_o;
assign product = mode ? {12'b0, coeff_in} * {12'b0, 12'(`Q)}
: {12'b0, coeff_in} * {12'b0, two_pow_d};
// Rounding offset: compressQ/2=1664; decompress2^(d-1) // Accept a new command only when the iterative divider and output slot are
wire [11:0] round_off; // both free. Current users tie ready_i high and issue one coefficient at a
assign round_off = mode ? (two_pow_d >> 1) : 12'd1664; // time, but this keeps the module from accepting work it cannot retain.
assign ready_o = !busy_r && (!valid_r || ready_i);
assign coeff_out = data_r;
assign valid_o = valid_r;
// Dividend = product + round_off (max ~ 6,817,408 fits in 24 bits) wire [23:0] comp_dividend = ({12'd0, coeff_in} << d) + 24'd1664;
wire [23:0] dividend; wire [23:0] decomp_product =
assign dividend = product + {12'b0, round_off}; {12'd0, coeff_in} +
({12'd0, coeff_in} << 8) +
({12'd0, coeff_in} << 10) +
({12'd0, coeff_in} << 11);
wire [23:0] decomp_rounded = decomp_product + (24'd1 << (d - 1'b1));
wire [11:0] decomp_result = decomp_rounded >> d;
// Divisor: compressQ=3329; decompress2^d wire [12:0] rem_shift = {rem_r[11:0], dividend_r[bit_idx_r]};
wire [11:0] divisor; wire rem_ge_q = rem_shift >= {1'b0, Q_VAL};
assign divisor = mode ? two_pow_d : 12'(`Q); wire [12:0] rem_sub_q = rem_shift - {1'b0, Q_VAL};
wire [12:0] rem_next = rem_ge_q ? rem_sub_q : rem_shift;
wire [23:0] quot_next = quotient_r | (rem_ge_q ? (24'd1 << bit_idx_r) : 24'd0);
wire [11:0] comp_mask = (12'd1 << d_r) - 12'd1;
// Integer division (both ops positive floor) always @(posedge clk or negedge rst_n) begin
// Quotient is computed as 24b (widest operand) but fits in 12b if (!rst_n) begin
/* verilator lint_off WIDTHTRUNC */ busy_r <= 1'b0;
wire [11:0] div_result; bit_idx_r <= 5'd0;
assign div_result = dividend / {12'b0, divisor}; d_r <= 5'd0;
/* verilator lint_on WIDTHTRUNC */ dividend_r <= 24'd0;
quotient_r <= 24'd0;
rem_r <= 13'd0;
data_r <= 12'd0;
valid_r <= 1'b0;
end else begin
if (valid_r && ready_i)
valid_r <= 1'b0;
// Final modular reduction if (busy_r) begin
// compress: lower d bits (mask with 2^d - 1) rem_r <= rem_next;
// decompress: result < Q always, but apply mod Q for safety quotient_r <= quot_next;
wire [11:0] mod_result; if (bit_idx_r == 5'd0) begin
assign mod_result = mode ? (div_result % 12'(`Q)) : (div_result & (two_pow_d - 1'b1)); busy_r <= 1'b0;
data_r <= quot_next[11:0] & comp_mask;
// Pipeline through valid/ready stage valid_r <= 1'b1;
pipeline_reg #(.DW(12)) u_pipe ( end else begin
.clk (clk), bit_idx_r <= bit_idx_r - 5'd1;
.rst_n (rst_n), end
.data_i (mod_result), end else if (fire_i) begin
.valid_i(valid_i), if (mode) begin
.ready_o(ready_o), data_r <= decomp_result;
.data_o (coeff_out), valid_r <= 1'b1;
.valid_o(valid_o), end else begin
.ready_i(ready_i) busy_r <= 1'b1;
); bit_idx_r <= COMP_MSB;
d_r <= d;
dividend_r <= comp_dividend;
quotient_r <= 24'd0;
rem_r <= 13'd0;
end
end
end
end
endmodule endmodule

View File

@@ -38,8 +38,9 @@ xvlog -sv ${NTT_DIR}/barrett_mul.v
# ================================================================ # ================================================================
puts "=== Compiling PolyMul RTL sources ===" puts "=== Compiling PolyMul RTL sources ==="
# Basecase multiplier (instantiates barrett_mul) # Basecase multipliers
xvlog -sv ${PM_DIR}/basecase_mul.v xvlog -sv ${PM_DIR}/basecase_mul.v
xvlog -sv ${PM_DIR}/basecase_mul_pipe.v
# PolyMul zeta ROM # PolyMul zeta ROM
xvlog -sv ${PM_DIR}/poly_mul_zeta_rom.v xvlog -sv ${PM_DIR}/poly_mul_zeta_rom.v

View File

@@ -0,0 +1,144 @@
// basecase_mul_pipe.v - pipelined NTT-domain degree-1 multiplication
//
// Fixed-latency replacement for the combinational basecase_mul hot path.
// The shared ntt/barrett_mul remains combinational for NTT users; this module
// keeps the extra registers local to poly_mul_sync.
(* use_dsp = "no" *)
module basecase_mul_pipe (
input clk,
input rst_n,
input valid_i,
input [11:0] a0, a1,
input [11:0] b0, b1,
input [11:0] zeta,
output [11:0] c0,
output [11:0] c1,
output valid_o
);
localparam [11:0] Q12 = 12'd3329;
localparam [12:0] K13 = 13'd5039;
localparam [24:0] Q25 = 25'd3329;
function [12:0] barrett_q;
input [23:0] p;
reg [36:0] prod;
begin
prod = {13'd0, p} * K13;
barrett_q = prod[36:24];
end
endfunction
function [11:0] barrett_reduce;
input [23:0] p;
input [12:0] qe;
reg [24:0] q_approx;
reg [24:0] r0;
reg [24:0] r1;
reg [24:0] r2;
begin
q_approx = qe * Q12;
r0 = {1'b0, p} - q_approx;
r1 = (r0 >= Q25) ? (r0 - Q25) : r0;
r2 = (r1 >= Q25) ? (r1 - Q25) : r1;
barrett_reduce = r2[11:0];
end
endfunction
function [11:0] mod_add;
input [11:0] x;
input [11:0] y;
reg [12:0] sum;
begin
sum = {1'b0, x} + {1'b0, y};
mod_add = (sum >= {1'b0, Q12}) ? (sum[11:0] - Q12) : sum[11:0];
end
endfunction
// Stage 1: first-level scalar products.
reg [23:0] p10, p11, p12, p13;
reg [11:0] zeta_s1;
// Stage 2: Barrett quotient estimates for first-level products.
reg [23:0] p20, p21, p22, p23;
reg [12:0] q20, q21, q22, q23;
reg [11:0] zeta_s2;
// Stage 3: first-level reduced products.
reg [11:0] t1_s3, t2_s3, t3_s3, t4_s3;
reg [11:0] zeta_s3;
// Stage 4: zeta product for c0's second Barrett multiply.
reg [11:0] t1_s4, t3_s4, t4_s4;
reg [23:0] pz_s4;
// Stage 5: Barrett quotient estimate for zeta product.
reg [11:0] t1_s5, t3_s5, t4_s5;
reg [23:0] pz_s5;
reg [12:0] qz_s5;
// Stage 6: reduced zeta product.
reg [11:0] t1_s6, t3_s6, t4_s6, tz_s6;
// Stage 7: final modular additions.
reg [11:0] c0_r, c1_r;
reg [6:0] valid_sr;
assign c0 = c0_r;
assign c1 = c1_r;
assign valid_o = valid_sr[6];
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
p10 <= 24'd0; p11 <= 24'd0; p12 <= 24'd0; p13 <= 24'd0; zeta_s1 <= 12'd0;
p20 <= 24'd0; p21 <= 24'd0; p22 <= 24'd0; p23 <= 24'd0;
q20 <= 13'd0; q21 <= 13'd0; q22 <= 13'd0; q23 <= 13'd0; zeta_s2 <= 12'd0;
t1_s3 <= 12'd0; t2_s3 <= 12'd0; t3_s3 <= 12'd0; t4_s3 <= 12'd0; zeta_s3 <= 12'd0;
t1_s4 <= 12'd0; t3_s4 <= 12'd0; t4_s4 <= 12'd0; pz_s4 <= 24'd0;
t1_s5 <= 12'd0; t3_s5 <= 12'd0; t4_s5 <= 12'd0; pz_s5 <= 24'd0; qz_s5 <= 13'd0;
t1_s6 <= 12'd0; t3_s6 <= 12'd0; t4_s6 <= 12'd0; tz_s6 <= 12'd0;
c0_r <= 12'd0; c1_r <= 12'd0; valid_sr <= 7'd0;
end else begin
valid_sr <= {valid_sr[5:0], valid_i};
p10 <= {12'd0, a0} * b0;
p11 <= {12'd0, a1} * b1;
p12 <= {12'd0, a1} * b0;
p13 <= {12'd0, a0} * b1;
zeta_s1 <= zeta;
p20 <= p10; p21 <= p11; p22 <= p12; p23 <= p13;
q20 <= barrett_q(p10);
q21 <= barrett_q(p11);
q22 <= barrett_q(p12);
q23 <= barrett_q(p13);
zeta_s2 <= zeta_s1;
t1_s3 <= barrett_reduce(p20, q20);
t2_s3 <= barrett_reduce(p21, q21);
t3_s3 <= barrett_reduce(p22, q22);
t4_s3 <= barrett_reduce(p23, q23);
zeta_s3 <= zeta_s2;
t1_s4 <= t1_s3;
t3_s4 <= t3_s3;
t4_s4 <= t4_s3;
pz_s4 <= {12'd0, t2_s3} * zeta_s3;
t1_s5 <= t1_s4;
t3_s5 <= t3_s4;
t4_s5 <= t4_s4;
pz_s5 <= pz_s4;
qz_s5 <= barrett_q(pz_s4);
t1_s6 <= t1_s5;
t3_s6 <= t3_s5;
t4_s6 <= t4_s5;
tz_s6 <= barrett_reduce(pz_s5, qz_s5);
c0_r <= mod_add(t1_s6, tz_s6);
c1_r <= mod_add(t3_s6, t4_s6);
end
end
endmodule

View File

@@ -4,7 +4,7 @@
// 256-coefficient NTT-domain polynomials. // 256-coefficient NTT-domain polynomials.
// //
// Operation flow: // Operation flow:
// IDLE LOAD (256× A+B pairs) COMP_CALC (read+compute, 1 cycle) // IDLE LOAD (256× A+B pairs) COMP_ISSUE COMP_WAIT
// COMP_C0 (output c0) COMP_C1 (output c1) DONE IDLE // COMP_C0 (output c0) COMP_C1 (output c1) DONE IDLE
// //
// The LOAD phase accepts both A and B coefficients simultaneously // The LOAD phase accepts both A and B coefficients simultaneously
@@ -39,10 +39,11 @@ module poly_mul_sync (
// State definitions // State definitions
localparam S_IDLE = 3'd0; localparam S_IDLE = 3'd0;
localparam S_LOAD = 3'd1; localparam S_LOAD = 3'd1;
localparam S_COMP_CALC = 3'd2; localparam S_COMP_ISSUE = 3'd2;
localparam S_COMP_C0 = 3'd3; localparam S_COMP_WAIT = 3'd3;
localparam S_COMP_C1 = 3'd4; localparam S_COMP_C0 = 3'd4;
localparam S_DONE = 3'd5; localparam S_COMP_C1 = 3'd5;
localparam S_DONE = 3'd6;
reg [2:0] state, next_state; reg [2:0] state, next_state;
@@ -72,16 +73,22 @@ module poly_mul_sync (
.zeta (zeta) .zeta (zeta)
); );
// Basecase multiply // Pipelined basecase multiply. One request is issued at a time; the
// output interface is unchanged for top-level consumers.
wire [11:0] bc_c0, bc_c1; wire [11:0] bc_c0, bc_c1;
basecase_mul u_bc ( wire bc_vo;
basecase_mul_pipe u_bc (
.clk (clk),
.rst_n(rst_n),
.valid_i(state == S_COMP_ISSUE),
.a0 (mem_a0), .a0 (mem_a0),
.a1 (mem_a1), .a1 (mem_a1),
.b0 (mem_b0), .b0 (mem_b0),
.b1 (mem_b1), .b1 (mem_b1),
.zeta(zeta), .zeta(zeta),
.c0 (bc_c0), .c0 (bc_c0),
.c1 (bc_c1) .c1 (bc_c1),
.valid_o(bc_vo)
); );
// Output interface // Output interface
@@ -95,12 +102,13 @@ module poly_mul_sync (
case (state) case (state)
S_IDLE: if (valid_i && ready_o) next_state = S_LOAD; S_IDLE: if (valid_i && ready_o) next_state = S_LOAD;
S_LOAD: if (load_cnt >= 255 && valid_i && ready_o) S_LOAD: if (load_cnt >= 255 && valid_i && ready_o)
next_state = S_COMP_CALC; next_state = S_COMP_ISSUE;
S_COMP_CALC: next_state = S_COMP_C0; S_COMP_ISSUE: next_state = S_COMP_WAIT;
S_COMP_WAIT: if (bc_vo) next_state = S_COMP_C0;
S_COMP_C0: if (valid_o && ready_i) next_state = S_COMP_C1; S_COMP_C0: if (valid_o && ready_i) next_state = S_COMP_C1;
S_COMP_C1: if (valid_o && ready_i) begin S_COMP_C1: if (valid_o && ready_i) begin
if (comp_k >= 127) next_state = S_DONE; if (comp_k >= 127) next_state = S_DONE;
else next_state = S_COMP_CALC; else next_state = S_COMP_ISSUE;
end end
S_DONE: next_state = S_IDLE; S_DONE: next_state = S_IDLE;
default: next_state = S_IDLE; default: next_state = S_IDLE;
@@ -139,8 +147,8 @@ module poly_mul_sync (
end end
// ---- COMPUTE phase ---- // ---- COMPUTE phase ----
// COMP_CALC: capture basecase_mul results // COMP_WAIT: capture pipelined basecase_mul results when ready.
if (state == S_COMP_CALC) begin if (state == S_COMP_WAIT && bc_vo) begin
c0_reg <= bc_c0; c0_reg <= bc_c0;
c1_reg <= bc_c1; c1_reg <= bc_c1;
end end

View File

@@ -17,6 +17,7 @@ xvlog -sv --relax -i . sync_rtl/ntt/zeta_rom.v
xvlog -sv --relax -i . sync_rtl/ntt/butterfly_unit.v xvlog -sv --relax -i . sync_rtl/ntt/butterfly_unit.v
xvlog -sv --relax -i . sync_rtl/ntt/ntt_core.v xvlog -sv --relax -i . sync_rtl/ntt/ntt_core.v
xvlog -sv --relax -i . sync_rtl/poly_mul/basecase_mul.v xvlog -sv --relax -i . sync_rtl/poly_mul/basecase_mul.v
xvlog -sv --relax -i . sync_rtl/poly_mul/basecase_mul_pipe.v
xvlog -sv --relax -i . sync_rtl/poly_mul/poly_mul_zeta_rom.v xvlog -sv --relax -i . sync_rtl/poly_mul/poly_mul_zeta_rom.v
xvlog -sv --relax -i . sync_rtl/poly_mul/poly_mul_sync.v xvlog -sv --relax -i . sync_rtl/poly_mul/poly_mul_sync.v
xvlog -sv --relax -i . sync_rtl/storage/sd_bram.v xvlog -sv --relax -i . sync_rtl/storage/sd_bram.v

View File

@@ -1009,7 +1009,7 @@ module mlkem_top #(
// (d=du), then c2 = 1 poly of v (d=dv). Per poly = 256 coeffs -> 32*d // (d=du), then c2 = 1 poly of v (d=dv). Per poly = 256 coeffs -> 32*d
// bytes (whole), so the bit buffer empties at each poly boundary. // bytes (whole), so the bit buffer empties at each poly boundary.
// micro-phase cp_ph: 0 present coeff addr; 1 feed comp_decomp (cd_valid); // micro-phase cp_ph: 0 present coeff addr; 1 feed comp_decomp (cd_valid);
// 2 wait pipe; 3 capture compressed + accumulate bits; 4..n drain bytes. // 2 drop valid pulse; 3 wait/capture cd_vo; 4..n drain bytes.
// ================================================================ // ================================================================
wire cd_active = (st == ST_ENC_C1) || (st == ST_ENC_C2); wire cd_active = (st == ST_ENC_C1) || (st == ST_ENC_C2);
reg [11:0] cd_coeff; // coeff presented to comp_decomp reg [11:0] cd_coeff; // coeff presented to comp_decomp
@@ -1701,8 +1701,8 @@ module mlkem_top #(
// ---- ST_ENC_C1/C2: Compress_d -> byteEncode_d -> ct region ---- // ---- ST_ENC_C1/C2: Compress_d -> byteEncode_d -> ct region ----
// C1 (E5): Compress_du(u[0..K-1]) from bank_se -> ct[0..c1_bytes). // C1 (E5): Compress_du(u[0..K-1]) from bank_se -> ct[0..c1_bytes).
// C2 (E7): Compress_dv(v) from bank_t[UPSUM] -> ct[c1_bytes..ct_bytes). // C2 (E7): Compress_dv(v) from bank_t[UPSUM] -> ct[c1_bytes..ct_bytes).
// Per coeff, 5-phase micro-sequence (read-ahead 1 cyc bram + 1 cyc // Per coeff, 5-phase micro-sequence (read-ahead 1 cyc bram plus
// comp_decomp pipe), then a drain sub-phase emitting whole bytes: // variable-latency comp_decomp), then a drain sub-phase emitting whole bytes:
// ph0: present coeff addr (cp_se_full / cp_bt_full by state). // ph0: present coeff addr (cp_se_full / cp_bt_full by state).
// ph1: coeff arrives (cp_coeff_src) -> latch into cd_coeff, pulse cd_valid. // ph1: coeff arrives (cp_coeff_src) -> latch into cd_coeff, pulse cd_valid.
// ph2: drop cd_valid (1-cyc pulse); comp_decomp captures. // ph2: drop cd_valid (1-cyc pulse); comp_decomp captures.
@@ -1723,10 +1723,12 @@ module mlkem_top #(
cp_ph <= 3'd3; cp_ph <= 3'd3;
end end
3'd3: begin 3'd3: begin
// cd_out valid (cd_vo): append cp_d bits LSB-first at bit cp_nbits if (cd_vo) begin
cp_buf <= cp_buf | (({13'd0, cd_out} & ((25'd1 << cp_d) - 25'd1)) << cp_nbits); // Append compressed low cp_d bits LSB-first at bit cp_nbits.
cp_nbits <= cp_nbits + {1'b0, cp_d}; cp_buf <= cp_buf | (({13'd0, cd_out} & ((25'd1 << cp_d) - 25'd1)) << cp_nbits);
cp_ph <= 3'd4; cp_nbits <= cp_nbits + {1'b0, cp_d};
cp_ph <= 3'd4;
end
end end
default: begin // 3'd4: drain whole bytes default: begin // 3'd4: drain whole bytes
if (cp_nbits >= 6'd8) begin if (cp_nbits >= 6'd8) begin

40
synth_timing.tcl Normal file
View File

@@ -0,0 +1,40 @@
set PROJECT_DIR [file normalize [file dirname [info script]]]
set REPORT_DIR ${PROJECT_DIR}/reports
file mkdir ${REPORT_DIR}
set PART xc7a200tfbg676-1
read_verilog -sv ${PROJECT_DIR}/sync_rtl/sha3/keccak_round.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/sha3/keccak_core.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/sha3/sha3_top_shared.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/sample_ntt/sample_ntt_sync_shared.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/sample_cbd/sample_cbd_sync_shared.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/ntt/barrett_mul.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/ntt/zeta_rom.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/ntt/butterfly_unit.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/ntt/ntt_core.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/poly_mul/basecase_mul.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/poly_mul/basecase_mul_pipe.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/poly_mul/poly_mul_zeta_rom.v
read_verilog -sv ${PROJECT_DIR}/sync_rtl/poly_mul/poly_mul_sync.v
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
read_verilog -sv ${PROJECT_DIR}/sync_rtl/top/mlkem_top.v
synth_design -top mlkem_top -part ${PART} -flatten_hierarchy rebuilt
create_clock -name sysclk -period 20.000 [get_ports clk]
report_timing_summary -file ${REPORT_DIR}/timing_synth.rpt
report_timing -max_paths 10 -sort_by group -file ${REPORT_DIR}/timing_synth_worst.rpt
report_utilization -file ${REPORT_DIR}/util_synth.rpt
write_checkpoint -force ${REPORT_DIR}/mlkem_top_synth.dcp
opt_design
place_design
route_design
report_timing_summary -file ${REPORT_DIR}/timing_impl.rpt
report_timing -max_paths 10 -sort_by group -file ${REPORT_DIR}/timing_impl_worst.rpt
report_utilization -file ${REPORT_DIR}/util_impl.rpt
write_checkpoint -force ${REPORT_DIR}/mlkem_top_impl.dcp