Compare commits
51 Commits
matmul-dma
...
main-nocdc
| Author | SHA1 | Date | |
|---|---|---|---|
| 760bcddccc | |||
| e30a65bd72 | |||
| 4538ec496f | |||
| b2c8d6eaf3 | |||
| 78ccc34578 | |||
| be2e54c8ab | |||
| 454c3e559d | |||
| 975903000e | |||
| ce40a6df42 | |||
| 6faaa8abd8 | |||
| b052b12885 | |||
| 03b3415e76 | |||
| 5f9cb1c883 | |||
| 6a1b374bc1 | |||
| ab4751bfd3 | |||
| 3d2917a807 | |||
| 5a3529d09b | |||
| 4229652659 | |||
| f676fc6e60 | |||
| b003fc057f | |||
| 1b494fe44d | |||
| 94f8f443d3 | |||
| 83473b66aa | |||
| 0c85a20b4e | |||
| 65607badd2 | |||
| 34ce639f69 | |||
| 088a9bd5b8 | |||
| e8893a28dd | |||
| cd039e2e2e | |||
| b8ddb2ef08 | |||
| 54ec54d421 | |||
| 19751b9d18 | |||
| 4eca83bd3d | |||
| 69de12e79f | |||
| ca1472d859 | |||
| 2b7c43edcb | |||
| d13f7933d8 | |||
| 7e72bd455a | |||
| 48072c5ecb | |||
| 264e65f8d9 | |||
| 7281df356f | |||
| 423ff32b49 | |||
| f735f789d6 | |||
| d3a08b1f9d | |||
| 2725f6eb57 | |||
| 27cdfb713a | |||
| c37f493bcb | |||
| bf6051c8c6 | |||
| b7553418fa | |||
| 3f7c9b7a37 | |||
| 58f99d82ba |
7
.gitignore
vendored
@@ -18,6 +18,12 @@ webtalk*.jou
|
||||
vivado_pid*.txt
|
||||
*.bit
|
||||
|
||||
# ========================================
|
||||
# Generated binary / AXI images
|
||||
# ========================================
|
||||
*.bin
|
||||
*.mif
|
||||
|
||||
# ========================================
|
||||
# OS generated files
|
||||
# ========================================
|
||||
@@ -37,6 +43,7 @@ desktop.ini
|
||||
.codex/
|
||||
.opencode/
|
||||
.agents/
|
||||
.omo/
|
||||
|
||||
# ========================================
|
||||
# Editor / IDE
|
||||
|
||||
BIN
doc/SRAM_IS61WV102416ALL.pdf
Normal file
570
doc/axi_bus_modules.md
Normal file
@@ -0,0 +1,570 @@
|
||||
# AXI 总线模块说明
|
||||
|
||||
本文档基于 `full` 分支的 `rtl/soc_top.v`、各 AXI 外设源码和软件头文件整理,用于说明当前 SoC 中 AXI 总线上的模块作用、端口含义和寄存器地址。
|
||||
|
||||
## 1. 总体连接关系
|
||||
|
||||
顶层 AXI 互连为 `AxiCrossbar_2x8`。它有 2 个 AXI master 输入和 8 个 AXI slave 输出。
|
||||
|
||||
### 1.1 AXI master 输入
|
||||
|
||||
| Crossbar 端口 | 顶层连接 | 作用 |
|
||||
| --- | --- | --- |
|
||||
| `axiIn_0_*` | `core_top` 经 `Axi_CDC` 后的 `cpu_sync_*` | CPU 访问内存、外设和加速器 |
|
||||
| `axiIn_1_*` | `snix_axil_cdma_mux` 的 `dma_m_*` / `mm2mm_*` | DMA/CDMA 作为 AXI master 发起内存和外设数据搬运 |
|
||||
|
||||
### 1.2 AXI slave 输出和地址窗口
|
||||
|
||||
| Crossbar 端口 | 物理地址窗口 | 常用非缓存虚拟地址窗口 | 顶层连接 | 作用 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `axiOut_0_*` | `0x1c000000` - `0x1c7fffff` | 软件通常直接使用物理地址 | `axi_wrap_ram_sp_external` | BaseRAM/ExtRAM 存储子系统 |
|
||||
| `axiOut_1_*` | `0x00000000` - `0x007fffff` | 无 | reserved tie-off | 保留窗口,当前返回空响应 |
|
||||
| `axiOut_2_*` | `0x1f000000` - `0x1f0fffff` | `0xbf000000` - `0xbf0fffff` | `axi_uart_controller` | UART0 |
|
||||
| `axiOut_3_*` | `0x1f100000` - `0x1f1fffff` | `0xbf100000` - `0xbf1fffff` | `axi_dvi` | 视频输出 |
|
||||
| `axiOut_4_*` | `0x1f200000` - `0x1f2fffff` | `0xbf200000` - `0xbf2fffff` | `confreg` | LED、数码管、按键、开关、定时器、中断 |
|
||||
| `axiOut_5_*` | `0x1f300000` - `0x1f3fffff` | `0xbf300000` - `0xbf3fffff` | `axi_axil_adapter` -> DMA/CDMA | DMA 配置窗口 |
|
||||
| `axiOut_6_*` | `0x1f400000` - `0x1f4fffff` | `0xbf400000` - `0xbf4fffff` | `fft_mlkem_axi_slave` | FFT、ML-KEM 共享窗口 |
|
||||
| `axiOut_7_*` | `0x1f500000` - `0x1f5fffff` | `0xbf500000` - `0xbf5fffff` | `matmul_axi_slave` | 矩阵乘法加速器 |
|
||||
|
||||
说明:软件中的 `0xbfxxxxxx` 地址是 Loongson/LoongArch 非缓存映射地址;硬件 crossbar 实际译码使用 `0x1fxxxxxx` 等物理地址。
|
||||
|
||||
## 2. AXI 信号字典
|
||||
|
||||
多个模块使用完全相同的 AXI4 或 AXI-Lite 端口。后续各模块只列出端口前缀,例如 `ram_*`、`uart_*`、`s_axi_*`、`dma_m_*`。这些前缀下的每个信号含义按本节解释。
|
||||
|
||||
### 2.1 AXI4 slave 接口信号
|
||||
|
||||
适用于 `axi_wrap_ram_sp_external`、`axi_uart_controller`、`axi_dvi`、`confreg`、`fft_mlkem_axi_slave`、`mlkem_axi_slave`、`matmul_axi_slave` 等模块。
|
||||
|
||||
| 信号 | 方向,以 slave 模块为准 | 含义 |
|
||||
| --- | --- | --- |
|
||||
| `clk` / `aclk` | input | AXI 总线时钟。当前大多数 slave 使用 `sys_clk`。 |
|
||||
| `resetn` / `aresetn` / `rst_n` | input | 低有效复位,已在顶层同步。 |
|
||||
| `s_axi_awid` / `axi_awid` | input | 写地址事务 ID,用于响应通道返回对应 ID。 |
|
||||
| `s_axi_awaddr` / `axi_awaddr` | input | 写地址。模块通常使用低位做内部寄存器偏移。 |
|
||||
| `s_axi_awlen` / `axi_awlen` | input | 突发长度,表示 beats-1。 |
|
||||
| `s_axi_awsize` / `axi_awsize` | input | 每个 beat 的字节数编码,`2` 表示 4 字节。 |
|
||||
| `s_axi_awburst` / `axi_awburst` | input | 突发类型,常用 `INCR`。 |
|
||||
| `s_axi_awlock` / `axi_awlock` | input | AXI lock 属性,本设计基本不使用。 |
|
||||
| `s_axi_awcache` / `axi_awcache` | input | cache 属性,本设计通常透传或忽略。 |
|
||||
| `s_axi_awprot` / `axi_awprot` | input | protection 属性,本设计通常透传或忽略。 |
|
||||
| `s_axi_awvalid` / `axi_awvalid` | input | 写地址有效。 |
|
||||
| `s_axi_awready` / `axi_awready` | output | slave 可接收写地址。 |
|
||||
| `s_axi_wid` | input | 写数据 ID。部分 AXI4 实现保留,很多模块不使用。 |
|
||||
| `s_axi_wdata` / `axi_wdata` | input | 写数据。 |
|
||||
| `s_axi_wstrb` / `axi_wstrb` | input | 写字节使能,bit0 对应低 8 位。 |
|
||||
| `s_axi_wlast` / `axi_wlast` | input | 写突发最后一拍。 |
|
||||
| `s_axi_wvalid` / `axi_wvalid` | input | 写数据有效。 |
|
||||
| `s_axi_wready` / `axi_wready` | output | slave 可接收写数据。 |
|
||||
| `s_axi_bid` / `axi_bid` | output | 写响应 ID。 |
|
||||
| `s_axi_bresp` / `axi_bresp` | output | 写响应状态,当前外设一般返回 `OKAY=2'b00`。 |
|
||||
| `s_axi_bvalid` / `axi_bvalid` | output | 写响应有效。 |
|
||||
| `s_axi_bready` / `axi_bready` | input | master 可接收写响应。 |
|
||||
| `s_axi_arid` / `axi_arid` | input | 读地址事务 ID。 |
|
||||
| `s_axi_araddr` / `axi_araddr` | input | 读地址。 |
|
||||
| `s_axi_arlen` / `axi_arlen` | input | 读突发长度,表示 beats-1。 |
|
||||
| `s_axi_arsize` / `axi_arsize` | input | 每个读 beat 的字节数编码。 |
|
||||
| `s_axi_arburst` / `axi_arburst` | input | 读突发类型,常用 `INCR`。 |
|
||||
| `s_axi_arlock` / `axi_arlock` | input | AXI lock 属性,本设计基本不使用。 |
|
||||
| `s_axi_arcache` / `axi_arcache` | input | cache 属性,本设计通常透传或忽略。 |
|
||||
| `s_axi_arprot` / `axi_arprot` | input | protection 属性,本设计通常透传或忽略。 |
|
||||
| `s_axi_arvalid` / `axi_arvalid` | input | 读地址有效。 |
|
||||
| `s_axi_arready` / `axi_arready` | output | slave 可接收读地址。 |
|
||||
| `s_axi_rid` / `axi_rid` | output | 读响应 ID。 |
|
||||
| `s_axi_rdata` / `axi_rdata` | output | 读数据。 |
|
||||
| `s_axi_rresp` / `axi_rresp` | output | 读响应状态,当前外设一般返回 `OKAY=2'b00`。 |
|
||||
| `s_axi_rlast` / `axi_rlast` | output | 读突发最后一拍。 |
|
||||
| `s_axi_rvalid` / `axi_rvalid` | output | 读数据有效。 |
|
||||
| `s_axi_rready` / `axi_rready` | input | master 可接收读数据。 |
|
||||
|
||||
### 2.2 AXI4 master 接口信号
|
||||
|
||||
适用于 `snix_axil_cdma_mux` 的 `mm2mm_*` / 顶层 `dma_m_*`。信号名称与 AXI4 slave 一致,但方向相反:`awaddr/araddr/wdata/wstrb/valid/ready` 等由 DMA master 发起,crossbar/slave 返回 ready、response 和 read data。
|
||||
|
||||
| 信号组 | 方向,以 DMA 为准 | 含义 |
|
||||
| --- | --- | --- |
|
||||
| `mm2mm_aw*` | output/input | DMA 写地址通道,用于向目标地址发起写事务。 |
|
||||
| `mm2mm_w*` | output/input | DMA 写数据通道。 |
|
||||
| `mm2mm_b*` | input/output | DMA 写响应通道。 |
|
||||
| `mm2mm_ar*` | output/input | DMA 读地址通道,用于从源地址发起读事务。 |
|
||||
| `mm2mm_r*` | input/output | DMA 读数据通道。 |
|
||||
| `mm2mm_awqos/arqos` | output | AXI QoS,顶层未使用。 |
|
||||
| `mm2mm_awuser/wuser/aruser` | output | AXI user sideband,顶层未使用。 |
|
||||
| `mm2mm_buser/ruser` | input | AXI user sideband,顶层绑常量。 |
|
||||
|
||||
### 2.3 AXI-Lite slave 接口信号
|
||||
|
||||
适用于 `snix_axil_cdma_mux` 和 `cdma_matmul_bridge` 的配置接口。
|
||||
|
||||
| 信号 | 方向,以 AXI-Lite slave 为准 | 含义 |
|
||||
| --- | --- | --- |
|
||||
| `s_axil_awaddr` | input | AXI-Lite 写地址。 |
|
||||
| `s_axil_awvalid` | input | 写地址有效。 |
|
||||
| `s_axil_awready` | output | slave 可接收写地址。 |
|
||||
| `s_axil_wdata` | input | 写数据。 |
|
||||
| `s_axil_wstrb` | input | 写字节使能。 |
|
||||
| `s_axil_wvalid` | input | 写数据有效。 |
|
||||
| `s_axil_wready` | output | slave 可接收写数据。 |
|
||||
| `s_axil_bresp` | output | 写响应状态。 |
|
||||
| `s_axil_bvalid` | output | 写响应有效。 |
|
||||
| `s_axil_bready` | input | master 可接收写响应。 |
|
||||
| `s_axil_araddr` | input | AXI-Lite 读地址。 |
|
||||
| `s_axil_arvalid` | input | 读地址有效。 |
|
||||
| `s_axil_arready` | output | slave 可接收读地址。 |
|
||||
| `s_axil_rdata` | output | 读数据。 |
|
||||
| `s_axil_rresp` | output | 读响应状态。 |
|
||||
| `s_axil_rvalid` | output | 读数据有效。 |
|
||||
| `s_axil_rready` | input | master 可接收读数据。 |
|
||||
|
||||
## 3. 各 AXI 模块作用与端口
|
||||
|
||||
### 3.1 `AxiCrossbar_2x8`
|
||||
|
||||
作用:系统 AXI 主互连。它将 CPU 和 DMA 两个 master 的读写请求按地址译码转发到 8 个 slave,并负责读写响应返回。
|
||||
|
||||
端口说明:
|
||||
|
||||
| 端口 | 方向 | 解释 |
|
||||
| --- | --- | --- |
|
||||
| `clk` | input | crossbar 工作时钟,顶层连接 `sys_clk`。 |
|
||||
| `resetn` | input | 低有效复位,顶层连接 `sys_resetn`。 |
|
||||
| `axiIn_0_*` | input/output | CPU 侧 AXI master 接口,信号含义见 AXI4 字典。 |
|
||||
| `axiIn_1_*` | input/output | DMA/CDMA 侧 AXI master 接口,信号含义见 AXI4 字典。 |
|
||||
| `axiOut_0_*` | output/input | RAM AXI slave 接口。 |
|
||||
| `axiOut_1_*` | output/input | 保留 AXI slave 接口,顶层 tie-off。 |
|
||||
| `axiOut_2_*` | output/input | UART AXI slave 接口。 |
|
||||
| `axiOut_3_*` | output/input | DVI AXI slave 接口。 |
|
||||
| `axiOut_4_*` | output/input | confreg AXI slave 接口。 |
|
||||
| `axiOut_5_*` | output/input | DMA 配置 AXI slave 接口。 |
|
||||
| `axiOut_6_*` | output/input | FFT/ML-KEM AXI slave 接口。 |
|
||||
| `axiOut_7_*` | output/input | matmul AXI slave 接口。 |
|
||||
|
||||
### 3.2 `core_top` 与 `Axi_CDC`
|
||||
|
||||
作用:`core_top` 是 CPU;`Axi_CDC` 将 CPU 时钟域的 AXI 请求同步到 `sys_clk` 域,再送入 crossbar master 0。
|
||||
|
||||
端口说明:
|
||||
|
||||
| 端口 | 方向 | 解释 |
|
||||
| --- | --- | --- |
|
||||
| `core_top.aclk` | input | CPU 时钟 `cpu_clk`。 |
|
||||
| `core_top.aresetn` | input | CPU 低有效复位 `cpu_resetn`。 |
|
||||
| `core_top.intrpt[7:0]` | input | CPU 中断输入。当前 `{4'd0, mlkem_intr, matmul_intr, dma_finish, confreg_int}`。 |
|
||||
| `core_top.ar*/r*/aw*/w*/b*` | input/output | CPU AXI master 接口。 |
|
||||
| `core_top.debug0_*` | output | CPU 写回级调试信号。 |
|
||||
| `Axi_CDC.axiInClk/axiInRstn` | input | CPU 侧时钟/复位。 |
|
||||
| `Axi_CDC.axiOutClk/axiOutRstn` | input | crossbar 侧时钟/复位。 |
|
||||
| `Axi_CDC.axiIn_*` | input/output | CPU 侧 AXI 信号。 |
|
||||
| `Axi_CDC.axiOut_*` | output/input | `sys_clk` 域 AXI 信号,连接 crossbar master 0。 |
|
||||
|
||||
### 3.3 `axi_wrap_ram_sp_external`
|
||||
|
||||
作用:SRAM 子系统的 AXI slave 包装器。它把 AXI 读写转换为异步 SRAM 控制信号,并根据内部地址 bit22 选择 BaseRAM 或 ExtRAM。
|
||||
|
||||
端口说明:
|
||||
|
||||
| 端口 | 方向 | 解释 |
|
||||
| --- | --- | --- |
|
||||
| `aclk` | input | AXI/SRAM 控制器时钟,连接 `sys_clk`。 |
|
||||
| `aresetn` | input | 低有效复位。 |
|
||||
| `axi_ar*/axi_r*/axi_aw*/axi_w*/axi_b*` | input/output | RAM 的 AXI4 slave 接口,连接 crossbar `axiOut_0_*`。 |
|
||||
| `base_ram_data[31:0]` | inout | BaseRAM 双向数据总线。写周期由控制器驱动,读周期为高阻输入。 |
|
||||
| `base_ram_addr[19:0]` | output | BaseRAM 字地址,来自 `soc_sram_addr[21:2]`。 |
|
||||
| `base_ram_be_n[3:0]` | output | BaseRAM 字节使能,低有效。 |
|
||||
| `base_ram_ce_n` | output | BaseRAM 片选,低有效。 |
|
||||
| `base_ram_oe_n` | output | BaseRAM 读使能,低有效。 |
|
||||
| `base_ram_we_n` | output | BaseRAM 写使能,低有效。 |
|
||||
| `ext_ram_data[31:0]` | inout | ExtRAM 双向数据总线。 |
|
||||
| `ext_ram_addr[19:0]` | output | ExtRAM 字地址,来自 `soc_sram_addr[21:2]`。 |
|
||||
| `ext_ram_be_n[3:0]` | output | ExtRAM 字节使能,低有效。 |
|
||||
| `ext_ram_ce_n` | output | ExtRAM 片选,低有效。 |
|
||||
| `ext_ram_oe_n` | output | ExtRAM 读使能,低有效。 |
|
||||
| `ext_ram_we_n` | output | ExtRAM 写使能,低有效。 |
|
||||
|
||||
地址说明:`0x1c000000` - `0x1c3fffff` 选择 BaseRAM,`0x1c400000` - `0x1c7fffff` 选择 ExtRAM。
|
||||
|
||||
### 3.4 reserved window
|
||||
|
||||
作用:`axiOut_1_*` 是保留窗口,顶层没有接实际模块。读数据返回 0,写请求直接 ready/空响应。该窗口不建议软件使用。
|
||||
|
||||
### 3.5 `axi_uart_controller`
|
||||
|
||||
作用:AXI 到 APB/UART 控制器。CPU 通过 AXI 访问 16550 风格 UART 寄存器,实现串口收发和中断。
|
||||
|
||||
端口说明:
|
||||
|
||||
| 端口 | 方向 | 解释 |
|
||||
| --- | --- | --- |
|
||||
| `clk` | input | UART AXI/APB 时钟,连接 `sys_clk`。 |
|
||||
| `rst_n` | input | 低有效复位。 |
|
||||
| `axi_s_*` | input/output | UART 的 AXI4 slave 接口,连接 crossbar `axiOut_2_*`。 |
|
||||
| `apb_rw_dma` | input | DMA APB 访问方向,顶层绑 0,当前未使用。 |
|
||||
| `apb_psel_dma` | input | DMA APB 片选,顶层绑 0。 |
|
||||
| `apb_enab_dma` | input | DMA APB enable,顶层绑 0。 |
|
||||
| `apb_addr_dma[19:0]` | input | DMA APB 地址,顶层绑 0。 |
|
||||
| `apb_valid_dma` | input | DMA APB 请求有效,顶层绑 0。 |
|
||||
| `apb_wdata_dma[31:0]` | input | DMA APB 写数据,顶层绑 0。 |
|
||||
| `apb_rdata_dma[31:0]` | output | DMA APB 读数据,顶层未使用。 |
|
||||
| `apb_ready_dma` | output | DMA APB ready,顶层未使用。 |
|
||||
| `dma_grant` | output | APB mux 对 DMA 的授权,顶层未使用。 |
|
||||
| `dma_req_o` | output | UART 控制器内部 DMA 请求,顶层未使用。 |
|
||||
| `dma_ack_i` | input | DMA ack,顶层绑 0。 |
|
||||
| `uart0_txd_i` | input | UART TX 管脚回读输入。 |
|
||||
| `uart0_txd_o` | output | UART TX 输出值。 |
|
||||
| `uart0_txd_oe` | output | UART TX 输出使能;顶层用它控制三态。 |
|
||||
| `uart0_rxd_i` | input | UART RX 输入值。 |
|
||||
| `uart0_rxd_o` | output | UART RX 输出值,三态模式下使用。 |
|
||||
| `uart0_rxd_oe` | output | UART RX 输出使能。 |
|
||||
| `uart0_rts_o` | output | UART RTS 调制解调控制输出。 |
|
||||
| `uart0_dtr_o` | output | UART DTR 调制解调控制输出。 |
|
||||
| `uart0_cts_i` | input | UART CTS 输入。 |
|
||||
| `uart0_dsr_i` | input | UART DSR 输入。 |
|
||||
| `uart0_dcd_i` | input | UART DCD 输入。 |
|
||||
| `uart0_ri_i` | input | UART RI 输入。 |
|
||||
| `uart0_int` | output | UART0 中断,送入 confreg 中断控制。 |
|
||||
|
||||
### 3.6 `axi_dvi`
|
||||
|
||||
作用:AXI 可配置的视频输出控制器。软件写入矩形/方形参数,模块产生 VGA/DVI 时序和 RGB 输出。
|
||||
|
||||
端口说明:
|
||||
|
||||
| 端口 | 方向 | 解释 |
|
||||
| --- | --- | --- |
|
||||
| `aclk` | input | DVI 控制器和像素时钟来源。 |
|
||||
| `aresetn` | input | 低有效复位。 |
|
||||
| `s_aw*/s_w*/s_b*/s_ar*/s_r*` | input/output | DVI 的 AXI4 slave 接口,连接 crossbar `axiOut_3_*`。 |
|
||||
| `video_clk` | output | 视频像素时钟输出。 |
|
||||
| `hsync` | output | 行同步信号。 |
|
||||
| `vsync` | output | 场同步信号。 |
|
||||
| `data_enable` | output | 有效显示区域指示。 |
|
||||
| `video_red[2:0]` | output | 红色像素分量。 |
|
||||
| `video_green[2:0]` | output | 绿色像素分量。 |
|
||||
| `video_blue[1:0]` | output | 蓝色像素分量。 |
|
||||
|
||||
### 3.7 `confreg`
|
||||
|
||||
作用:基础外设和中断控制寄存器模块。它负责 LED、数码管、拨码开关、触摸按键、系统定时器、中断状态聚合和仿真标志。
|
||||
|
||||
端口说明:
|
||||
|
||||
| 端口 | 方向 | 解释 |
|
||||
| --- | --- | --- |
|
||||
| `aclk` | input | AXI 外设时钟,连接 `sys_clk`。 |
|
||||
| `aresetn` | input | 低有效 AXI 复位。 |
|
||||
| `cpu_clk` | input | CPU 时钟,当前传入但主要逻辑在 `aclk` 域。 |
|
||||
| `cpu_resetn` | input | CPU 低有效复位。 |
|
||||
| `s_aw*/s_w*/s_b*/s_ar*/s_r*` | input/output | confreg 的 AXI4 slave 接口,连接 crossbar `axiOut_4_*`。 |
|
||||
| `led[15:0]` | output | 16 位 LED 输出。 |
|
||||
| `dpy0[7:0]` | output | 低位数码管输出。 |
|
||||
| `dpy1[7:0]` | output | 高位数码管输出。 |
|
||||
| `switch[31:0]` | input | 32 位拨码开关输入。 |
|
||||
| `touch_btn[3:0]` | input | 4 位触摸按键输入。 |
|
||||
| `uart0_int` | input | UART 中断输入,映射到 confreg 中断源 bit5。 |
|
||||
| `fft_finish` | input | FFT 完成输入,映射到 confreg 中断源 bit6。 |
|
||||
| `confreg_int` | output | confreg 聚合后的中断输出,送入 CPU `intrpt[0]`。 |
|
||||
|
||||
### 3.8 `axi_axil_adapter`
|
||||
|
||||
作用:把 crossbar `axiOut_5_*` 的 AXI4 slave 访问转换为 AXI-Lite 访问,供 DMA/CDMA 配置寄存器使用。
|
||||
|
||||
端口说明:
|
||||
|
||||
| 端口 | 方向 | 解释 |
|
||||
| --- | --- | --- |
|
||||
| `clk` | input | adapter 时钟,连接 `sys_clk`。 |
|
||||
| `rst` | input | 高有效复位,顶层连接 `~sys_resetn`。 |
|
||||
| `s_axi_*` | input/output | AXI4 slave 侧,连接 crossbar `axiOut_5_*`。 |
|
||||
| `m_axil_*` | output/input | AXI-Lite master 侧,连接 DMA 配置分流逻辑。 |
|
||||
|
||||
### 3.9 `snix_axil_cdma_mux`
|
||||
|
||||
作用:多通道 CDMA 控制器。它有 AXI-Lite 配置接口、AXI4 `mm2mm` master 数据搬运接口,以及本地 endpoint 接口。当前顶层参数 `PORTS=4`,即 4 个软件可见 DMA 通道。
|
||||
|
||||
端口说明:
|
||||
|
||||
| 端口 | 方向 | 解释 |
|
||||
| --- | --- | --- |
|
||||
| `clk` | input | CDMA 时钟,连接 `sys_clk`。 |
|
||||
| `rst_n` | input | 低有效复位。 |
|
||||
| `s_axil_*` | input/output | AXI-Lite 配置 slave 接口,来自 `axi_axil_adapter` 且未命中 bridge 子窗口时进入本模块。 |
|
||||
| `mm2mm_aw* / mm2mm_w* / mm2mm_b* / mm2mm_ar* / mm2mm_r*` | output/input | AXI4 master 数据搬运接口,连接 crossbar `axiIn_1_*`。 |
|
||||
| `ep_wr_valid` | output | 向本地 endpoint 写数据请求有效。当前连接 matmul。 |
|
||||
| `ep_wr_id[3:0]` | output | endpoint 编号。当前 matmul 使用 id 0。 |
|
||||
| `ep_wr_bank[3:0]` | output | endpoint bank 选择。当前 matmul 使用 bank0/bank1。 |
|
||||
| `ep_wr_word_addr[7:0]` | output | endpoint 内部 word 地址。 |
|
||||
| `ep_wr_data[31:0]` | output | 写入 endpoint 的 32 位数据。 |
|
||||
| `ep_wr_ready` | input | endpoint 可接收写数据。 |
|
||||
| `ep_rd_valid` | output | 从 endpoint 读数据请求有效。 |
|
||||
| `ep_rd_id[3:0]` | output | endpoint 编号。 |
|
||||
| `ep_rd_bank[3:0]` | output | endpoint bank 选择。 |
|
||||
| `ep_rd_word_addr[7:0]` | output | endpoint 内部 word 地址。 |
|
||||
| `ep_rd_data[31:0]` | input | endpoint 返回的 32 位数据。 |
|
||||
| `ep_rd_ready` | input | endpoint 读数据有效/可被采样。 |
|
||||
| `ext_rd_req_valid` | input | 外部序列器请求“内存到 endpoint”搬运。当前来自 `cdma_matmul_bridge`。 |
|
||||
| `ext_rd_req_ready` | output | CDMA 可接收外部读请求。 |
|
||||
| `ext_rd_req_src[31:0]` | input | 外部读请求的内存源地址。 |
|
||||
| `ext_rd_req_bytes[31:0]` | input | 外部读请求字节数。 |
|
||||
| `ext_rd_req_ep_id[3:0]` | input | 外部读请求目标 endpoint id。 |
|
||||
| `ext_rd_req_ep_bank[3:0]` | input | 外部读请求目标 endpoint bank。 |
|
||||
| `ext_rd_req_ep_word_off[7:0]` | input | 外部读请求目标 endpoint word 偏移。 |
|
||||
| `ext_rd_req_done` | output | 外部读请求完成脉冲/标志。 |
|
||||
| `ext_wr_req_valid` | input | 外部序列器请求“endpoint 到内存”搬运。 |
|
||||
| `ext_wr_req_ready` | output | CDMA 可接收外部写请求。 |
|
||||
| `ext_wr_req_dst[31:0]` | input | 外部写请求的内存目的地址。 |
|
||||
| `ext_wr_req_bytes[31:0]` | input | 外部写请求字节数。 |
|
||||
| `ext_wr_req_ep_id[3:0]` | input | 外部写请求源 endpoint id。 |
|
||||
| `ext_wr_req_ep_bank[3:0]` | input | 外部写请求源 endpoint bank。 |
|
||||
| `ext_wr_req_ep_word_off[7:0]` | input | 外部写请求源 endpoint word 偏移。 |
|
||||
| `ext_wr_req_done` | output | 外部写请求完成脉冲/标志。 |
|
||||
| `dma_finish` | output | DMA 完成中断/状态输出,送入顶层 `dma_finish` 合并逻辑。 |
|
||||
|
||||
### 3.10 `cdma_matmul_bridge`
|
||||
|
||||
作用:matmul 专用 CDMA 序列控制器。CPU 配置输入基地址、输出基地址、组数和 stride 后,它自动向 `snix_axil_cdma_mux` 发起 endpoint 读写请求,并直接控制 matmul 启动、清状态、清 CRC。
|
||||
|
||||
端口说明:
|
||||
|
||||
| 端口 | 方向 | 解释 |
|
||||
| --- | --- | --- |
|
||||
| `clk` | input | bridge 时钟,连接 `sys_clk`。 |
|
||||
| `rst_n` | input | 低有效复位。 |
|
||||
| `s_axil_*` | input/output | AXI-Lite 配置 slave 接口。当 DMA 配置地址 `[11:8] == 4'h2` 时访问本模块。 |
|
||||
| `cdma_rd_req_valid` | output | 请求 CDMA 从内存读取数据到 matmul endpoint。 |
|
||||
| `cdma_rd_req_ready` | input | CDMA 可接收读请求。 |
|
||||
| `cdma_rd_req_src[31:0]` | output | 读请求内存源地址。 |
|
||||
| `cdma_rd_req_bytes[31:0]` | output | 读请求字节数,matmul 输入固定为 128B。 |
|
||||
| `cdma_rd_req_ep_id[3:0]` | output | 读请求目标 endpoint id。 |
|
||||
| `cdma_rd_req_ep_bank[3:0]` | output | 读请求目标 matmul bank。 |
|
||||
| `cdma_rd_req_ep_word_off[7:0]` | output | 读请求目标 endpoint word 偏移。 |
|
||||
| `cdma_rd_req_done` | input | CDMA 读请求完成。 |
|
||||
| `cdma_wr_req_valid` | output | 请求 CDMA 从 matmul endpoint 写回内存。 |
|
||||
| `cdma_wr_req_ready` | input | CDMA 可接收写请求。 |
|
||||
| `cdma_wr_req_dst[31:0]` | output | 写请求内存目的地址。 |
|
||||
| `cdma_wr_req_bytes[31:0]` | output | 写请求字节数,matmul 输出固定为 192B。 |
|
||||
| `cdma_wr_req_ep_id[3:0]` | output | 写请求源 endpoint id。 |
|
||||
| `cdma_wr_req_ep_bank[3:0]` | output | 写请求源 matmul bank。 |
|
||||
| `cdma_wr_req_ep_word_off[7:0]` | output | 写请求源 endpoint word 偏移。 |
|
||||
| `cdma_wr_req_done` | input | CDMA 写请求完成。 |
|
||||
| `mat_start_valid` | output | 启动 matmul 计算的有效脉冲。 |
|
||||
| `mat_start_bank` | output | 启动哪个 matmul bank。 |
|
||||
| `mat_done_clear` | output | 清除 matmul done/error 状态。 |
|
||||
| `mat_crc_clear` | output | 清除 matmul CRC 累积值。 |
|
||||
| `mat_done` | input | matmul 计算完成状态。 |
|
||||
| `seq_done_irq` | output | 整个 matmul 序列完成中断,顶层与 `cdma_dma_finish` OR 成 `dma_finish`。 |
|
||||
|
||||
### 3.11 `fft_mlkem_axi_slave`
|
||||
|
||||
作用:共享 AXI slave 地址窗口,按地址低 16 位的 `[15:12]` 将请求分发到 ML-KEM 或 FFT。
|
||||
|
||||
端口说明:
|
||||
|
||||
| 端口 | 方向 | 解释 |
|
||||
| --- | --- | --- |
|
||||
| `clk` | input | AXI 时钟,连接 `sys_clk`。 |
|
||||
| `resetn` | input | 低有效复位。 |
|
||||
| `s_axi_*` | input/output | 共享加速器 AXI4 slave 接口,连接 crossbar `axiOut_6_*`。 |
|
||||
| `fft_finish` | output | FFT 完成状态,送入 confreg。 |
|
||||
| `mlkem_intr` | output | ML-KEM 完成中断,直接送入 CPU `intrpt[3]`。 |
|
||||
|
||||
内部地址分发:
|
||||
|
||||
| 偏移范围 | 子模块 |
|
||||
| --- | --- |
|
||||
| `0x0000` - `0x3fff` | `mlkem_axi_slave` |
|
||||
| `0x8000` - `0xcfff` | `fft_controller` / FFT |
|
||||
|
||||
### 3.12 `mlkem_axi_slave`
|
||||
|
||||
作用:ML-KEM 加速器 AXI4 slave 包装器,提供 KeyGen、Encaps、Decaps 的配置、输入预加载、输出读回和中断。
|
||||
|
||||
端口说明:
|
||||
|
||||
| 端口 | 方向 | 解释 |
|
||||
| --- | --- | --- |
|
||||
| `clk` | input | AXI 总线时钟。内部再产生 `mlkem_clk = clk/2`。 |
|
||||
| `resetn` | input | 低有效复位。 |
|
||||
| `s_axi_*` | input/output | ML-KEM AXI4 slave 接口,由 `fft_mlkem_axi_slave` 分发而来。 |
|
||||
| `intr` | output | ML-KEM done 锁存后的高电平中断。 |
|
||||
|
||||
### 3.13 `fft_controller`
|
||||
|
||||
作用:1024 点 16-bit FFT 加速器。通过 AXI 写入输入实部/虚部 BRAM,写 CSR 启动计算,完成后从输出实部/虚部窗口读取结果。
|
||||
|
||||
端口说明:
|
||||
|
||||
| 端口 | 方向 | 解释 |
|
||||
| --- | --- | --- |
|
||||
| `aclk` | input | FFT/AXI 时钟。 |
|
||||
| `aresetn` | input | 低有效复位。 |
|
||||
| `s_aw*/s_w*/s_b*/s_ar*/s_r*` | input/output | FFT AXI4 slave 接口,由 `fft_mlkem_axi_slave` 分发而来。 |
|
||||
| `fft_finish` | output | FFT done 状态,来自 CSR status bit1。 |
|
||||
|
||||
### 3.14 `matmul_axi_slave`
|
||||
|
||||
作用:矩阵乘法加速器 AXI slave。它既支持 CPU 通过 AXI 访问控制寄存器和 bank 数据,也支持 CDMA 通过本地 endpoint 写入输入、读出结果。模块内部带 CRC32 累积逻辑。
|
||||
|
||||
端口说明:
|
||||
|
||||
| 端口 | 方向 | 解释 |
|
||||
| --- | --- | --- |
|
||||
| `clk` | input | matmul/AXI 时钟,连接 `sys_clk`。 |
|
||||
| `resetn` | input | 低有效复位。 |
|
||||
| `s_axi_*` | input/output | matmul AXI4 slave 接口,连接 crossbar `axiOut_7_*`。 |
|
||||
| `ep_wr_valid` | input | CDMA 本地 endpoint 写请求有效。 |
|
||||
| `ep_wr_id[3:0]` | input | endpoint id。当前仅使用 id 0。 |
|
||||
| `ep_wr_bank[3:0]` | input | 写入 bank 选择,bit0 选择 bank0/bank1。 |
|
||||
| `ep_wr_word_addr[7:0]` | input | 写入 bank 内 word 地址,0-15 为 A,16-31 为 B。 |
|
||||
| `ep_wr_data[31:0]` | input | 写入 A/B 矩阵的 32 位数据。 |
|
||||
| `ep_wr_ready` | output | matmul endpoint 可接收写数据。当前恒为 1。 |
|
||||
| `ep_rd_valid` | input | CDMA 本地 endpoint 读请求有效。 |
|
||||
| `ep_rd_id[3:0]` | input | endpoint id。 |
|
||||
| `ep_rd_bank[3:0]` | input | 读取 bank 选择。 |
|
||||
| `ep_rd_word_addr[7:0]` | input | 读取结果 C 的 word 地址。每个 66-bit 结果拆成 3 个 32-bit word。 |
|
||||
| `ep_rd_data[31:0]` | output | endpoint 返回的 32 位结果数据。 |
|
||||
| `ep_rd_ready` | output | endpoint 读数据可用。当前恒为 1。 |
|
||||
| `mat_start_valid` | input | 来自 bridge 的启动脉冲。 |
|
||||
| `mat_start_bank` | input | 启动计算的 bank。 |
|
||||
| `mat_done_clear` | input | 清除 done/error。 |
|
||||
| `mat_crc_clear` | input | 清除 CRC32 累积值。 |
|
||||
| `mat_done` | output | 计算完成状态。 |
|
||||
| `intr` | output | matmul 完成中断,送入 CPU `intrpt[2]`。 |
|
||||
|
||||
## 4. 寄存器地址表
|
||||
|
||||
以下地址以软件常用非缓存虚拟地址列出;括号中给出对应物理地址基址。
|
||||
|
||||
### 4.1 UART0 (`0xbf000000`, physical `0x1f000000`)
|
||||
|
||||
16550 风格 8-bit 寄存器,软件常用字节访问。
|
||||
|
||||
| 地址 | 偏移 | 名称 | 访问 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `0xbf000000` | `0x0` | `RBR/THR` 或 `DLL` | R/W | DLAB=0 时读接收缓冲/写发送保持;DLAB=1 时为 divisor low byte。 |
|
||||
| `0xbf000001` | `0x1` | `IER` 或 `DLM` | R/W | DLAB=0 时为中断使能;DLAB=1 时为 divisor high byte。 |
|
||||
| `0xbf000002` | `0x2` | `IIR/FCR` | R/W | 读为中断识别,写为 FIFO 控制;DLAB=1 时部分实现作为 divisor 扩展。 |
|
||||
| `0xbf000003` | `0x3` | `LCR` | R/W | 线控制寄存器,bit7 为 DLAB。 |
|
||||
| `0xbf000004` | `0x4` | `MCR` | R/W | modem 控制。 |
|
||||
| `0xbf000005` | `0x5` | `LSR` | R | 线状态,软件轮询 bit5/bit6 判断发送 FIFO/发送器空。 |
|
||||
| `0xbf000006` | `0x6` | `MSR` | R | modem 状态。 |
|
||||
| `0xbf000007` | `0x7` | `SCR` | R/W | scratch/mode 寄存器。 |
|
||||
|
||||
### 4.2 DVI (`0xbf100000`, physical `0x1f100000`)
|
||||
|
||||
| 地址 | 偏移 | 名称 | 访问 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `0xbf100000` | `0x0` | `DVI_RECT_DIR` | R/W | 矩形位置参数,`[31:16]` 为 x,`[15:0]` 为 y。 |
|
||||
| `0xbf100004` | `0x4` | `DVI_RECT_L_W` | R/W | 矩形尺寸参数,`[31:16]` 为长度/半宽相关参数,`[15:0]` 为宽度/高度相关参数。 |
|
||||
| `0xbf100008` | `0x8` | `DVI_SQU_DIR` | R/W | 方形位置参数。 |
|
||||
| `0xbf10000c` | `0xc` | `DVI_SQU_R` | R/W | 方形半径/尺寸参数。 |
|
||||
|
||||
### 4.3 confreg (`0xbf200000`, physical `0x1f200000`)
|
||||
|
||||
| 地址 | 偏移 | 名称 | 访问 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `0xbf20f000` | `0xf000` | `CONFREG_INT_EN` | R/W | 中断使能。 |
|
||||
| `0xbf20f004` | `0xf004` | `CONFREG_INT_EDGE` | R/W | 中断边沿/电平模式配置。 |
|
||||
| `0xbf20f008` | `0xf008` | `CONFREG_INT_POL` | R/W | 中断极性配置。 |
|
||||
| `0xbf20f00c` | `0xf00c` | `CONFREG_INT_CLR` | W/R | 写 1 清除对应中断状态。 |
|
||||
| `0xbf20f010` | `0xf010` | `CONFREG_INT_SET` | W/R | 写 1 软件置位对应中断状态。 |
|
||||
| `0xbf20f014` | `0xf014` | `CONFREG_INT_STATE` | R | 当前中断状态。bit0-3 touch_btn,bit4 timer,bit5 UART,bit6 FFT。 |
|
||||
| `0xbf20f100` | `0xf100` | `TIMER_VALUE` | R | 系统计数器当前值。 |
|
||||
| `0xbf20f104` | `0xf104` | `TIMER_CMP` | R/W | 定时器比较值。 |
|
||||
| `0xbf20f108` | `0xf108` | `TIMER_EN` | R/W | bit0 使能定时器。 |
|
||||
| `0xbf20f200` | `0xf200` | `DIGITAL_CTRL` | R/W | 数码管控制寄存器。 |
|
||||
| `0xbf20f204` | `0xf204` | `DIGITAL_DATA` | R/W | 数码管显示数据。 |
|
||||
| `0xbf20f300` | `0xf300` | `LED_DATA` | R/W | LED 输出寄存器,低 16 位连接 `leds[15:0]`。 |
|
||||
| `0xbf20f400` | `0xf400` | `SWITCH_DATA` | R | 32 位拨码开关输入。 |
|
||||
| `0xbf20f500` | `0xf500` | `SIMU_FLAG` | R | 仿真标志,值为 `{32{SIMULATION}}`。 |
|
||||
|
||||
### 4.4 DMA/CDMA (`0xbf300000`, physical `0x1f300000`)
|
||||
|
||||
当前 `snix_axil_cdma_mux` 在顶层例化为 `PORTS=4`,通道 `ch=0..3`,每个通道 stride 为 `0x40`。通道寄存器地址为 `0xbf300000 + ch * 0x40 + offset`。
|
||||
|
||||
| 偏移 | 名称 | 访问 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `0x00` | `SRC_ADDR` | R/W | 源地址。mem2mem/mem2ep 时为内存源地址。 |
|
||||
| `0x04` | `DST_ADDR` | R/W | 目的地址。mem2mem/ep2mem 时为内存目的地址。 |
|
||||
| `0x08` | `LENGTH` | R/W | 传输字节数。 |
|
||||
| `0x0c` | `TAG` | R/W | 软件 tag,硬件不参与数据路径。 |
|
||||
| `0x10` | `CTRL` | R/W | bit0 写 1 启动;`[5:3]` 为 AXI AxSIZE;`[13:6]` 为 AXI AxLEN。 |
|
||||
| `0x14` | `STATUS` | R/W | bit0 busy,只读;bit1 done,写 1 清除。 |
|
||||
| `0x18` | `MODE` | R/W | `0=mem2mem`,`1=mem2ep`,`2=ep2mem`。 |
|
||||
| `0x1c` | `EP_CFG` | R/W | `[3:0]` bank,`[15:8]` word offset,`[19:16]` endpoint id。 |
|
||||
|
||||
通道基址:
|
||||
|
||||
| 通道 | 基址 |
|
||||
| --- | --- |
|
||||
| channel 0 | `0xbf300000` |
|
||||
| channel 1 | `0xbf300040` |
|
||||
| channel 2 | `0xbf300080` |
|
||||
| channel 3 | `0xbf3000c0` |
|
||||
|
||||
matmul 序列控制子窗口由 `cdma_matmul_bridge` 实现,地址为 `0xbf300200 + offset`:
|
||||
|
||||
| 地址 | 偏移 | 名称 | 访问 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `0xbf300200` | `0x200` | `SEQ_CTRL` | R/W | bit0 start;bit1 skip_result_writeback。 |
|
||||
| `0xbf300204` | `0x204` | `SEQ_STATUS` | R/W | bit0 busy;bit1 done,写 1 清除。 |
|
||||
| `0xbf300208` | `0x208` | `SEQ_SRC_BASE` | R/W | 输入矩阵组的物理源基址。 |
|
||||
| `0xbf30020c` | `0x20c` | `SEQ_DST_BASE` | R/W | 输出矩阵组的物理目的基址。 |
|
||||
| `0xbf300210` | `0x210` | `SEQ_GROUPS` | R/W | 自动处理的矩阵组数。 |
|
||||
| `0xbf300214` | `0x214` | `SEQ_MAT_BASE` | R/W | 保留兼容字段,软件通常写 `0x1f500000`。 |
|
||||
| `0xbf300218` | `0x218` | `SEQ_SRC_STRIDE` | R/W | 相邻输入组间隔,默认 128B。 |
|
||||
| `0xbf30021c` | `0x21c` | `SEQ_DST_STRIDE` | R/W | 相邻输出组间隔,默认 192B。 |
|
||||
|
||||
### 4.5 FFT/ML-KEM 共享窗口 (`0xbf400000`, physical `0x1f400000`)
|
||||
|
||||
#### 4.5.1 ML-KEM 子窗口
|
||||
|
||||
| 地址/范围 | 偏移 | 名称 | 访问 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `0xbf400000` | `0x000` | `MLKEM_CTRL` | W | bit0 start,启动 CONFIG 指定的操作。 |
|
||||
| `0xbf400004` | `0x004` | `MLKEM_STATUS` | R/W | bit0 busy,bit1 done,bit2 preload_busy;写 bit1=1 清 done。 |
|
||||
| `0xbf400008` | `0x008` | `MLKEM_CONFIG` | R/W | `[2:0] k`,`[5:4] op`,op: 0 KeyGen,1 Encaps,2 Decaps。 |
|
||||
| `0xbf400010` - `0xbf40002c` | `0x010` - `0x02c` | `D[0..7]` | R/W | KeyGen seed d,8 个 32-bit word。 |
|
||||
| `0xbf400030` - `0xbf40004c` | `0x030` - `0x04c` | `Z[0..7]` | R/W | implicit-reject seed z。 |
|
||||
| `0xbf400050` - `0xbf40006c` | `0x050` - `0x06c` | `MSG[0..7]` | R/W | Encaps message m。 |
|
||||
| `0xbf400070` - `0xbf40008c` | `0x070` - `0x08c` | `SS[0..7]` | R | shared secret 输出。 |
|
||||
| `0xbf400100` | `0x100` | `PRELOAD_SEL` | R/W | 0=ek_in,1=dk_in,2=c_in。 |
|
||||
| `0xbf400104` | `0x104` | `PRELOAD_ADDR` | R/W | 预加载字节地址,写 `PRELOAD_DATA` 后自动递增。 |
|
||||
| `0xbf400108` | `0x108` | `PRELOAD_DATA` | W | 写低 8 位,流入所选输入端口。 |
|
||||
| `0xbf40010c` | `0x10c` | `RDBK_SEL` | R/W | 0=ek,1=dk_pke,2=full-dk,3=ciphertext。 |
|
||||
| `0xbf400110` | `0x110` | `RDBK_ADDR` | R/W | 读回字节索引。 |
|
||||
| `0xbf400114` | `0x114` | `RDBK_DATA` | R | 读回低 8 位数据。 |
|
||||
| `0xbf401000` - `0xbf401fff` | `0x1000` - `0x1fff` | `EK` | W/R | 写为 preload ek_in,读为 generated ek。 |
|
||||
| `0xbf402000` - `0xbf402fff` | `0x2000` - `0x2fff` | `DK` | W/R | 写为 preload dk_in,读为 generated full dk。 |
|
||||
| `0xbf403000` - `0xbf403fff` | `0x3000` - `0x3fff` | `CT` | W/R | 写为 preload c_in,读为 generated ciphertext。 |
|
||||
|
||||
#### 4.5.2 FFT 子窗口
|
||||
|
||||
| 地址/范围 | 偏移 | 名称 | 访问 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `0xbf408000` - `0xbf408ffc` | `0x8000` - `0x8ffc` | `FFT_IN_RE[0..1023]` | W | 输入实部 BRAM,每项低 16 位有效。 |
|
||||
| `0xbf409000` - `0xbf409ffc` | `0x9000` - `0x9ffc` | `FFT_IN_IM[0..1023]` | W | 输入虚部 BRAM,每项低 16 位有效。 |
|
||||
| `0xbf40a000` - `0xbf40affc` | `0xa000` - `0xaffc` | `FFT_OUT_RE[0..1023]` | R | 输出实部,符号扩展到 32 位,读出时使用 bit-reverse 地址。 |
|
||||
| `0xbf40b000` - `0xbf40bffc` | `0xb000` - `0xbffc` | `FFT_OUT_IM[0..1023]` | R | 输出虚部,符号扩展到 32 位,读出时使用 bit-reverse 地址。 |
|
||||
| `0xbf40c000` | `0xc000` | `FFT_CSR` | R/W | `[7:4]` 为 ctrl,写 bit4 启动/清 done;`[3:0]` 为 status,bit0 busy,bit1 done。 |
|
||||
|
||||
### 4.6 Matmul (`0xbf500000`, physical `0x1f500000`)
|
||||
|
||||
| 地址/范围 | 偏移 | 名称 | 访问 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `0xbf500000` | `0x000` | `MAT_CTRL` | R/W | bit0 启动 bank0,bit1 启动 bank1。 |
|
||||
| `0xbf500004` | `0x004` | `MAT_STATUS` | R/W | bit0 busy,bit1 done,bit2 error;写 bit1 清 done,写 bit2 清 error。 |
|
||||
| `0xbf500010` | `0x010` | `MAT_CRC` | R/W | 读返回 `crc_reg ^ 0xffffffff`;写该地址或 bridge 的 `mat_crc_clear` 清 CRC。 |
|
||||
| `0xbf500100` - `0xbf50013c` | `0x100` - `0x13c` | `B0_A[0..15]` | R/W | bank0 输入矩阵 A,16 个 32-bit word。 |
|
||||
| `0xbf500140` - `0xbf50017c` | `0x140` - `0x17c` | `B0_B[0..15]` | R/W | bank0 输入矩阵 B。 |
|
||||
| `0xbf500180` - `0xbf50023c` | `0x180` - `0x23c` | `B0_C` | R | bank0 输出矩阵 C,16 个 66-bit 结果,每个结果拆成 3 个 32-bit word,共 192B。 |
|
||||
| `0xbf500300` - `0xbf50033c` | `0x300` - `0x33c` | `B1_A[0..15]` | R/W | bank1 输入矩阵 A。 |
|
||||
| `0xbf500340` - `0xbf50037c` | `0x340` - `0x37c` | `B1_B[0..15]` | R/W | bank1 输入矩阵 B。 |
|
||||
| `0xbf500380` - `0xbf50043c` | `0x380` - `0x43c` | `B1_C` | R | bank1 输出矩阵 C,格式同 bank0。 |
|
||||
|
||||
## 5. 关键数据路径说明
|
||||
|
||||
1. CPU 访问任意外设或内存:`core_top -> Axi_CDC -> AxiCrossbar_2x8 -> 对应 AXI slave`。
|
||||
2. DMA 访问 SRAM:`snix_axil_cdma_mux mm2mm master -> AxiCrossbar_2x8 -> axi_wrap_ram_sp_external -> BaseRAM/ExtRAM`。DMA 和 SRAM 没有直接物理连线。
|
||||
3. DMA 访问 matmul 本地 endpoint:`snix_axil_cdma_mux -> ep_wr/ep_rd -> matmul_axi_slave`。这条是本地 endpoint 通路,不经过 AXI crossbar。
|
||||
4. matmul 批处理序列:CPU 写 `0xbf300200` 等寄存器配置 `cdma_matmul_bridge`,bridge 自动发起 CDMA 读/写请求并控制 matmul 启停。
|
||||
5. FFT/ML-KEM 共用 `0xbf400000` 窗口,由 `fft_mlkem_axi_slave` 依据偏移分发。
|
||||
45
doc/mlkem_test_results.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# ML-KEM Test Results Summary
|
||||
|
||||
## Test Setup
|
||||
|
||||
- Platform: LoongArch bare-metal target
|
||||
- Test mode: `STATIC_KAT_COUNT_0`
|
||||
- Levels: `k=2,3,4`
|
||||
- Repeat count: `100`
|
||||
- ML-KEM software allocator: `MLK_CONFIG_CUSTOM_ALLOC_FREE`
|
||||
- Verification sources: KAT count 0 expected values
|
||||
|
||||
## Correctness
|
||||
|
||||
All three paths passed in isolated testing:
|
||||
|
||||
- `SW_ONLY_FAILS=0`
|
||||
- `CPU_ONLY_FAILS=0`
|
||||
- `DMA_ONLY_FAILS=0`
|
||||
|
||||
Final result for the isolated diagnostic run:
|
||||
|
||||
- `MLKEM512_RESULT=PASS`
|
||||
- `MLKEM768_RESULT=PASS`
|
||||
- `MLKEM1024_RESULT=PASS`
|
||||
- `MLKEM_RESULT=PASS`
|
||||
|
||||
## Performance
|
||||
|
||||
The following results are from isolated per-level runs. Each level was tested
|
||||
for 100 iterations with software-only, CPU register path, and DMA path separated.
|
||||
|
||||
| Level | SW avg cycles | CPU avg cycles | DMA avg cycles | CPU vs SW | DMA vs SW | DMA vs CPU |
|
||||
|---|---:|---:|---:|---:|---:|---:|
|
||||
| k=2 / ML-KEM-512 | 2,587,784 | 352,684 | 185,671 | 7.34x | 13.94x | 1.90x |
|
||||
| k=3 / ML-KEM-768 | 4,056,378 | 523,656 | 279,588 | 7.75x | 14.51x | 1.87x |
|
||||
| k=4 / ML-KEM-1024 | 6,025,486 | 718,672 | 388,959 | 8.38x | 15.49x | 1.85x |
|
||||
|
||||
## Notes
|
||||
|
||||
- CPU/DMA hardware paths were stable across 100 iterations for all levels.
|
||||
- Software, CPU register path, and DMA path all passed 100 iterations for k=2, k=3, and k=4.
|
||||
- The DMA path is 13.94x to 15.49x faster than software across the tested levels.
|
||||
- The CPU register path is 7.34x to 8.38x faster than software across the tested levels.
|
||||
- The DMA path is about 1.85x to 1.90x faster than the CPU register path.
|
||||
- The hardware advantage increases slightly as k grows, because the accelerated computation grows faster than the fixed software control overhead.
|
||||
BIN
doc/reports/critical_path.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
doc/reports/fsm.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
doc/reports/keccak_core.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
doc/reports/logo_cicc.png
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
doc/reports/mlkem_ip_design_report.pdf
Normal file
791
doc/reports/mlkem_ip_design_report.tex
Normal file
@@ -0,0 +1,791 @@
|
||||
\documentclass[11pt,a4paper,twoside]{article}
|
||||
|
||||
% ─── Packages ────────────────────────────────────────────────
|
||||
\usepackage{ctex}
|
||||
\usepackage[top=2.5cm, bottom=2.5cm, left=2.8cm, right=2.8cm]{geometry}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{float}
|
||||
\usepackage{booktabs}
|
||||
\usepackage{longtable}
|
||||
\usepackage{multirow}
|
||||
\usepackage{array}
|
||||
\usepackage{amsmath,amssymb}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{caption}
|
||||
\usepackage{subcaption}
|
||||
\usepackage{fancyhdr}
|
||||
\usepackage{tikz}
|
||||
\usepackage{enumitem}
|
||||
\usepackage[normalem]{ulem}
|
||||
\usepackage{listings}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{algorithm}
|
||||
\usepackage{algpseudocode}
|
||||
|
||||
% ─── Styling ─────────────────────────────────────────────────
|
||||
\raggedbottom
|
||||
\hypersetup{colorlinks=true,linkcolor=black,citecolor=black,urlcolor=blue}
|
||||
\pagestyle{fancy}
|
||||
\fancyhead[LO,RE]{ML-KEM硬件IP设计报告}
|
||||
\fancyhead[RO,LE]{\thepage}
|
||||
\fancyfoot[C]{}
|
||||
\setlength{\parskip}{4pt plus 2pt minus 1pt}
|
||||
\setlength{\parindent}{2em}
|
||||
\setlength{\headheight}{14pt}
|
||||
\setlength{\intextsep}{6pt plus 2pt}
|
||||
\setlength{\textfloatsep}{8pt plus 2pt}
|
||||
\captionsetup{skip=4pt}
|
||||
|
||||
\lstset{basicstyle=\ttfamily\small,breaklines=true,frame=single,numbers=left,numberstyle=\tiny,xleftmargin=2em,language=Verilog}
|
||||
|
||||
\newcommand{\Zq}{\mathbb{Z}_q}
|
||||
\newcommand{\etal}{\textit{et al.}}
|
||||
|
||||
\title{\textbf{ML-KEM后量子密钥封装硬件IP核\\设计与验证}}
|
||||
\author{碳基生物\\[4pt] \small 团队编号:CICC1008439\\[8pt] \normalsize 龙芯中科杯·2026全国大学生集成电路创新创业大赛}
|
||||
\date{}
|
||||
|
||||
\begin{document}
|
||||
|
||||
% ================================================================
|
||||
% 封 面
|
||||
% ================================================================
|
||||
\begin{titlepage}
|
||||
\thispagestyle{empty}
|
||||
\begin{center}
|
||||
|
||||
\vspace*{30pt}
|
||||
|
||||
\includegraphics[width=0.45\textwidth]{logo_cicc.png}
|
||||
|
||||
\vspace{36pt}
|
||||
|
||||
{\fontsize{22pt}{28pt}\selectfont\bfseries 第十届}
|
||||
|
||||
\vspace{4pt}
|
||||
|
||||
{\fontsize{22pt}{28pt}\selectfont\bfseries 全国大学生集成电路创新创业大赛}
|
||||
|
||||
\end{center}
|
||||
|
||||
\vspace{80pt}
|
||||
|
||||
\begin{flushleft}
|
||||
\fontsize{14pt}{22pt}\selectfont
|
||||
报告类型:\uline{\hfill 设计报告\hfill} \\[18pt]
|
||||
参赛杯赛:\uline{\hfill 龙芯中科杯\hfill} \\[18pt]
|
||||
作品名称:\uline{\hfill ML-KEM后量子密钥封装硬件IP核设计与验证\hfill} \\[18pt]
|
||||
队伍编号:\uline{\hfill CICC1008439\hfill} \\[18pt]
|
||||
团队名称:\uline{\hfill 碳基生物\hfill}
|
||||
\end{flushleft}
|
||||
|
||||
\end{titlepage}
|
||||
|
||||
\maketitle
|
||||
\tableofcontents
|
||||
\newpage
|
||||
|
||||
% ================================================================
|
||||
\section{绪论}
|
||||
|
||||
\subsection{设计背景}
|
||||
|
||||
ML-KEM(Module-Lattice-based Key-Encapsulation Mechanism,FIPS 203)是NIST于2024年8月发布的后量子密码标准,用于替代RSA和ECC在密钥交换中的角色。其安全性建立在模格上的带误差学习问题(MLWE)之上,多项式环为$\Zq[x]/(x^{256}+1)$,素数模$q=3329$,多项式次数$n=256$。
|
||||
|
||||
软件实现的ML-KEM在嵌入式处理器上存在显著性能瓶颈——以ML-KEM-768为例,一轮完整的密钥生成、封装和解封装在通用CPU上需要数百万个时钟周期。本文设计的硬件IP核\texttt{mlkem\_top}旨在通过专用数据通路和计算资源时分复用,在FPGA平台上实现高性能、低面积的ML-KEM加速。
|
||||
|
||||
\subsection{关键设计特性}
|
||||
|
||||
本IP核在单一硬件模块内具有以下特性:
|
||||
|
||||
\begin{enumerate}[label=(\arabic*)]
|
||||
\item \textbf{运行时三等级支持}:通过$k\_i\in\{2,3,4\}$端口在运行时选择ML-KEM-512/768/1024安全等级,存储资源按$K_{MAX}=4$静态分配,无需重综合。
|
||||
\item \textbf{全操作覆盖}:支持KeyGen(FIPS 203算法16)、Encaps(算法17)和Decaps(算法18,含FO变换隐式拒绝)。
|
||||
\item \textbf{Keccak核跨阶段复用}:单一\texttt{keccak\_core}实例在G/H/J哈希、SampleNTT采样和CBD采样三个消费者之间时分复用,是面积优化的最大贡献因素。
|
||||
\item \textbf{Decaps重加密路径复用}:D6步的K-PKE重加密直接复用整条Encaps流水线的全部FSM状态,避免重复实现加密数据通路。
|
||||
\item \textbf{逐字节流式I/O}:公钥$ek$、私钥$dk$和密文$c$通过BRAM窗口逐字节装载与回读,免去超宽顶层总线。
|
||||
\item \textbf{NIST KAT完全验证}:三种等级、三种操作全部逐字节比对NIST FIPS 203 KAT标准答案通过。
|
||||
\end{enumerate}
|
||||
|
||||
\subsection{代码规模}
|
||||
|
||||
RTL代码总计约5,517行(不含测试平台),其中\texttt{mlkem\_top.v}(顶层FSM集成+数据通路+三库存储管理)约2,264行,各叶子算子模块合计约3,253行。全部采用SystemVerilog编写,统一使用\texttt{valid/ready}流式握手接口。
|
||||
|
||||
% ================================================================
|
||||
\section{IP模块规格}
|
||||
|
||||
\subsection{算法参数}
|
||||
|
||||
\texttt{mlkem\_top}的运行时参数由输入端口$k\_i$和$op\_i$在\texttt{start\_i}脉冲时刻锁存至内部寄存器$k\_r$和$op\_r$,后续所有数据通路宽度、存储子区间基地址和循环次数均由$k\_r$推导。表\ref{tab:params}列出三种安全等级的密钥和密文尺寸。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\caption{运行时安全等级参数}
|
||||
\label{tab:params}
|
||||
\begin{tabular}{cccccccc}
|
||||
\toprule
|
||||
$k\_i$ & 方案 & $K$ & $\eta_1$ & $(d_u,d_v)$ & ek(B) & dk(B) & ct(B) \\
|
||||
\midrule
|
||||
2 & ML-KEM-512 & 2 & 3 & (10,4) & 800 & 1632 & 768 \\
|
||||
3 & ML-KEM-768 & 3 & 2 & (10,4) & 1184 & 2400 & 1088 \\
|
||||
4 & ML-KEM-1024 & 4 & 2 & (11,5) & 1568 & 3168 & 1568 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
固定参数:模数$q=3329$、多项式次数$n=256$、$\eta_2=2$(所有等级)、共享密钥32字节。
|
||||
|
||||
\subsection{顶层端口信号}
|
||||
|
||||
\texttt{mlkem\_top}的端口按功能分为四组。表\ref{tab:ports}列出主要信号。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\caption{mlkem\_top主要端口}
|
||||
\label{tab:ports}
|
||||
\small
|
||||
\begin{tabular}{lll}
|
||||
\toprule
|
||||
\textbf{信号} & \textbf{位宽} & \textbf{功能} \\
|
||||
\midrule
|
||||
clk, rst\_n & 1, 1 & 时钟(50 MHz)与低电平异步复位 \\
|
||||
k\_i, op\_i & 3, 2 & 安全等级(2/3/4)与操作码(0=KG, 1=Enc, 2=Dec) \\
|
||||
d\_i, z\_i, msg\_i & 256×3 & KeyGen种子$d$、隐式拒绝种子$z$、Encaps消息$m$ \\
|
||||
start\_i & 1 & 启动脉冲,锁存$k\_i$和$op\_i$ \\
|
||||
busy\_o, done\_o & 1, 1 & 运行标志与完成脉冲 \\
|
||||
ss\_o & 256 & 共享密钥输出(done\_o时有效) \\
|
||||
ek\_in\_we/addr/byte & 1,11,8 & Encaps公钥流式预装载 \\
|
||||
dk\_in\_we/addr/byte & 1,12,8 & Decaps私钥流式预装载(自动路由至dkp\_bram/ek\_bram/寄存器) \\
|
||||
c\_in\_we/addr/byte & 1,11,8 & Decaps密文流式预装载 \\
|
||||
dbg\_* & 多种 & 调试抽头:系数、ek/dk/ct字节、中间哈希值 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
握手协议分三阶段:\texttt{ST\_IDLE}状态下通过流式端口逐字节预装载数据;\texttt{start\_i}脉冲启动并锁存参数;\texttt{busy\_o}拉高期间执行计算;\texttt{done\_o}脉冲时\texttt{ss\_o}和BRAM产物有效。所有256-bit端口采用字节0在低位的约定。
|
||||
|
||||
Decaps私钥预装载路径中,\texttt{dk\_in\_*}端口根据写入地址自动将字节流路由至不同目的地:地址$[0,384K)$写入\texttt{dkp\_bram}($\hat{s}$编码),$[384K,768K+32)$写入\texttt{ek\_bram}($\hat{t}$编码$\|\rho$),$[768K+32,768K+64)$和$[768K+64,768K+96)$分别写入$H(ek)$和$z$的寄存器。
|
||||
|
||||
% ================================================================
|
||||
\section{总体架构设计}
|
||||
|
||||
\subsection{设计原则}
|
||||
|
||||
\texttt{mlkem\_top}的架构遵循三条核心原则。
|
||||
|
||||
\textbf{原则一:存储按最大等级分配,运行时参数递推。} 多项式系数存储库以$K_{MAX}=4$(可容纳28个多项式,每个256系数)静态配置深度,$k\_r$仅影响读写地址生成逻辑中的基地址和循环边界。字节存储库(ek\_bram、dkp\_bram、ct\_bram)同样按最大密钥尺寸(1568/1536/1568字节)分配。运行时地址计算通过少量组合逻辑完成,无动态内存分配开销。
|
||||
|
||||
\textbf{原则二:Keccak核全阶段时分复用。} Keccak-f[1600]置换是设计中面积最大的单一算子(OOC综合约5,300 LUT)。G/H/J哈希族、SampleNTT(SHAKE-128)和CBD(SHAKE-256)三个消费者处于互斥的FSM阶段,设计将所有Keccak请求复用至单一\texttt{keccak\_core}实例。输入侧通过\texttt{sel\_sha3/sel\_snt/sel\_cbd}多路选择器切换,输出侧将置换结果广播至全体消费者,仅当前激活阶段采样有效信号。
|
||||
|
||||
\textbf{原则三:Decaps重加密完全复用Encaps流水线。} FIPS 203算法18的D6步需要以恢复的消息$m'$和随机种子$r'$重新执行一次K-PKE加密以产生参考密文$c'$。这一流程与算法17的Encaps操作的数据通路完全同构。设计将$m'$和$r'$分别写入原有的$m\_r$和$r\_r$寄存器,\texttt{ek\_bram}中保持原始公钥$ek$不变,随后将FSM直接转移至Encaps流水线的首个状态\texttt{ENC\_LOAD},整条15状态的Encaps数据通路被完整复用。
|
||||
|
||||
\subsection{模块层次结构}
|
||||
|
||||
图\ref{fig:mlkem_modules}给出\texttt{mlkem\_top}的内部层次结构。设计分为三个逻辑层:控制调度层(FSM + 地址生成 + 数据通路复用)、算子计算层(7个已验证的叶子模块)和存储层(7个BRAM实例)。
|
||||
|
||||
\begin{figure}[htbp]
|
||||
\centering
|
||||
\includegraphics[width=0.92\textwidth]{mlkem_modules.png}
|
||||
\caption{mlkem\_top内部三层模块结构}
|
||||
\label{fig:mlkem_modules}
|
||||
\end{figure}
|
||||
|
||||
\subsection{顶层FSM调度}
|
||||
|
||||
全部运算由5-bit状态机集中调度,从\texttt{ST\_IDLE}出发按$op\_r$分支为三条数据通路。图\ref{fig:fsm}给出状态转移图。
|
||||
|
||||
\begin{figure}[htbp]
|
||||
\centering
|
||||
\includegraphics[width=0.92\textwidth]{fsm.png}
|
||||
\caption{mlkem\_top顶层FSM状态转移图}
|
||||
\label{fig:fsm}
|
||||
\end{figure}
|
||||
|
||||
KeyGen路径对应FIPS 203算法16,共7个主状态(不含ST\_IDLE和ST\_DONE)。各状态间的数据传递通过多项式存储库完成:前序状态将结果写入BRAM,后续状态从BRAM读取。
|
||||
|
||||
\begin{algorithm}[H]
|
||||
\caption{KeyGen数据通路(FIPS 203算法16)}
|
||||
\begin{algorithmic}[1]
|
||||
\State \textbf{ST\_G}:$G(d \| K) \rightarrow (\rho, \sigma)$,单块SHA3-512,约1,800周期
|
||||
\State \textbf{ST\_A}:对全部$K^2$个$(j,i)$索引执行SampleNTT$(\rho \| j \| i) \rightarrow \hat{A}[i][j]$,逐系数写入\texttt{bank\_a}
|
||||
\State \textbf{ST\_C}:CBD$_{\eta_1}(\sigma, i) \rightarrow s[i]$,CBD$_{\eta_1}(\sigma, K+i) \rightarrow e[i]$,写入\texttt{bank\_se}
|
||||
\State \textbf{ST\_N}:NTT$(s[i]) \rightarrow \hat{s}[i]$,NTT$(e[i]) \rightarrow \hat{e}[i]$,原位更新\texttt{bank\_se}
|
||||
\State \textbf{ST\_M}:$\hat{t}[i] = \hat{e}[i] + \sum_{j=0}^{K-1} \hat{A}[i][j] \circ \hat{s}[j]$,逐点乘通过\texttt{poly\_mul\_sync},累加写入\texttt{bank\_t}
|
||||
\State \textbf{ST\_E}:byteEncode$_{12}(\hat{t}) \| \rho \rightarrow ek$,byteEncode$_{12}(\hat{s}) \rightarrow dk_{pke}$,写入\texttt{ek\_bram}和\texttt{dkp\_bram}
|
||||
\State \textbf{ST\_H}:SHA3-256$(ek) \rightarrow H(ek)$,多块吸收(块数$=\lceil(ek\_bytes+1)/136\rceil$)
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
Encaps路径对应FIPS 203算法17,共12个主状态。
|
||||
|
||||
\begin{algorithm}[H]
|
||||
\caption{Encaps数据通路(FIPS 203算法17)}
|
||||
\begin{algorithmic}[1]
|
||||
\State \textbf{ST\_ENC\_H}:SHA3-256$(ek) \rightarrow H(ek)$
|
||||
\State \textbf{ST\_ENC\_G}:$G(m \| H(ek)) \rightarrow (K, r)$,单块SHA3-512
|
||||
\State \textbf{ST\_ENC\_A}:重新生成$\hat{A}^T$矩阵(SampleNTT,行列索引交换),写入\texttt{bank\_a}
|
||||
\State \textbf{ST\_ENC\_TDEC}:byteDecode$_{12}(ek) \rightarrow \hat{t}[i]$,逐系数解码至\texttt{bank\_a}
|
||||
\State \textbf{ST\_ENC\_C}:CBD$_{\eta_1}(r, 0) \rightarrow y$,CBD$_{\eta_2}(r, K) \rightarrow e_1$,CBD$_{\eta_2}(r, 2K) \rightarrow e_2$,写入\texttt{bank\_se}和\texttt{bank\_t}
|
||||
\State \textbf{ST\_ENC\_N}:NTT$(y) \rightarrow \hat{y}$,原位更新\texttt{bank\_se}
|
||||
\State \textbf{ST\_ENC\_U}:$\hat{A}^T \circ \hat{y}$逐点乘后INTT,再加$e_1$得$u$,写入\texttt{bank\_se}
|
||||
\State \textbf{ST\_ENC\_C1}:Compress$_{d_u}(u)$后byteEncode$_{d_u} \rightarrow c_1$字节,写入\texttt{ct\_bram}
|
||||
\State \textbf{ST\_ENC\_E2MV}:将$e_2$从\texttt{bank\_t}搬迁至\texttt{bank\_a},为V步累加准备
|
||||
\State \textbf{ST\_ENC\_V}:$\hat{t} \circ \hat{y}$逐点乘后INTT,加$e_2$和Decompress$_1(m)$得$v$,写入\texttt{bank\_t}
|
||||
\State \textbf{ST\_ENC\_C2}:Compress$_{d_v}(v)$后byteEncode$_{d_v} \rightarrow c_2$字节,拼接至\texttt{ct\_bram}
|
||||
\State \textbf{输出}:$ss = K$
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
Decaps路径对应FIPS 203算法18,前5个主状态完成D1--D5步解密恢复,随后复用整条Encaps流水线(D6重加密),最后以一个比较状态(D7)完成隐式拒绝密钥选择。这是硬件设计中最复杂的控制流,也是Decaps流水线复用创新的集中体现。
|
||||
|
||||
\begin{algorithm}[H]
|
||||
\caption{Decaps数据通路(FIPS 203算法18,含流水线复用)}
|
||||
\begin{algorithmic}[1]
|
||||
\State \textbf{ST\_DEC\_DECOMP}(D1):byteDecode$_{d_u}(c_1) \rightarrow$ Decompress$_{d_u} \rightarrow u'$,byteDecode$_{d_v}(c_2) \rightarrow$ Decompress$_{d_v} \rightarrow v'$,写入\texttt{bank\_se}和\texttt{bank\_a}
|
||||
\State \textbf{ST\_DEC\_SDEC}(D2):byteDecode$_{12}(dk_{pke}) \rightarrow \hat{s}[i]$,逐系数解码至\texttt{bank\_a}
|
||||
\State \textbf{ST\_DEC\_NTT}(D2续):NTT$(u'[i]) \rightarrow \hat{u}[i]$,原位更新\texttt{bank\_se}
|
||||
\State \textbf{ST\_DEC\_W}(D3):$\hat{s}[j] \circ \hat{u}[j]$逐点乘后INTT,$v'$减去累加和得$w$,写入\texttt{bank\_t}
|
||||
\State \textbf{ST\_DEC\_MENC}(D4):Compress$_1(w)$后byteEncode$_1 \rightarrow m'$
|
||||
\State \textbf{ST\_DEC\_G}(D5):$G(m' \| H(ek)) \rightarrow (K', r')$
|
||||
\State \textbf{ST\_DEC\_J}(D5续):$J(z \| c) \rightarrow \bar{K}$(隐式拒绝备用密钥)
|
||||
\State \textbf{流水线复用}(D6):将$m'$写入$m\_r$、$r'$写入$r\_r$,跳转至\textbf{ST\_ENC\_LOAD},完整复用Encaps路径全部12个状态,产生参考密文$c'$(存入\texttt{ct\_bram})
|
||||
\State \textbf{ST\_DEC\_CMP}(D7):逐字节比较$c'$(\texttt{ct\_bram})与原始$c$(\texttt{c\_in\_bram}),常量时间无早退;$c' = c$时输出$K'$,否则输出$\bar{K}$
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
|
||||
% ================================================================
|
||||
\section{各功能模块数据通路与控制逻辑}
|
||||
|
||||
\subsection{Keccak-f[1600]置换核与哈希族}
|
||||
|
||||
\texttt{keccak\_core}模块实现24轮连续Keccak-f[1600]置换,内部结构为简单的迭代流水线:1600-bit状态寄存器$\rightarrow$组合\texttt{keccak\_round}$\rightarrow$写回状态寄存器。\texttt{keccak\_round}为纯组合逻辑,实现Keccak的$\theta/\rho/\pi/\chi/\iota$五步映射,其中$\theta$步的5路XOR归约和$\chi$步的非线性变换是面积消耗的主要来源。
|
||||
|
||||
\begin{figure}[htbp]
|
||||
\centering
|
||||
\includegraphics[width=0.92\textwidth]{keccak_core.png}
|
||||
\caption{Keccak-f[1600]核数据通路与共享机制}
|
||||
\label{fig:keccak_core}
|
||||
\end{figure}
|
||||
|
||||
\texttt{sha3\_top\_shared}模块在\texttt{keccak\_core}之上封装了SHA3/SHAKE协议层,包括1088-bit速率域/512-bit容量域的填充、domain separator拼接(SHA3末尾\texttt{01}、SHAKE末尾\texttt{1111})以及多块顺序吸收的状态管理。支持三种模式:SHA3-512($G$函数,单块64字节吸收)、SHA3-256($H$函数,多块吸收,块数$=\lceil(ek\_bytes+1)/136\rceil$)和SHAKE-256($J$函数和PRF派生)。
|
||||
|
||||
\textbf{共享Keccak的复用机制}通过两级多路选择实现。输入侧:三个消费者的1600-bit状态和\texttt{valid}信号经\texttt{sel\_*}信号选择后送入\texttt{keccak\_core};选择信号由FSM状态直接推导(例如\texttt{sel\_snt = (st==ST\_A || st==ST\_ENC\_A)})。输出侧:\texttt{keccak\_core}的置换结果和\texttt{valid\_o}广播至所有消费者,各消费者内部仅在自己激活的上下文中采样,天然实现了无冲突分派。此复用方案将Keccak的硬件开销从三份实例(约16,000 LUT)降至一份(约5,300 LUT),是IP核面积仅为25.5\% LUT利用率的关键设计决策。
|
||||
|
||||
\subsection{NTT核}
|
||||
|
||||
\texttt{ntt\_core}模块实现256点前向/逆向数论变换,采用单蝶形流水线加256$\times$12-bit寄存器阵列的架构。图\ref{fig:ntt_core}给出数据通路与控制状态机。
|
||||
|
||||
\begin{figure}[htbp]
|
||||
\centering
|
||||
% [IMAGE_PROMPT: Data path diagram for ntt_core. Left side: 256-entry × 12-bit coefficient register file (cr[0..255]). A read mux selects cr[j] and cr[j+layer_len] based on the current butterfly pair address. These feed a pipelined butterfly unit (butterfly_unit_pipe, 7-stage pipeline) which computes a_out = a + zeta*b mod Q, b_out = a - zeta*b mod Q using a pipelined Barrett multiplier inside. Zeta comes from zeta_rom (128 entries × 12-bit). The butterfly output a_out/b_out go through an 8-stage writeback delay line (wa_d0..wa_d7, wb_d0..wb_d7) that matches pipeline depth, then write back to cr[wa] and cr[wb]. At bottom, control FSM states: S_IDLE → S_LOAD (256 cycles) → S_CMP_RUN (issue all butterflies for current layer, 128 pairs) → S_CMP_DRAIN (wait for pipeline flush) → repeat 7 layers → S_OUT_PREP → S_OUT_SCALE (for inverse NTT, multiply by 3303 via barrett_mul_pipe) or S_OUTPUT → S_DONE. Annotate total cycles: ~2260 for full forward NTT. Clean academic style.]
|
||||
\caption{NTT核数据通路与控制状态机}
|
||||
\label{fig:ntt_core}
|
||||
\end{figure}
|
||||
|
||||
NTT的7层蝶形网络按Cooley-Tukey位反转置换顺序执行。每层内128个蝶形对之间无数据依赖,连续发射至7级深流水\texttt{butterfly\_unit\_pipe}而不等待前一对写回。流水线排空等待周期(约7拍)远小于一层中的蝶形总数(128对),因此额外延迟占比较小。
|
||||
|
||||
\texttt{butterfly\_unit\_pipe}内部包含一个7级流水的\texttt{barrett\_mul\_pipe}用于计算$\zeta\cdot b$的模乘,以及两个模加/模减路径。前向NTT使用Cooley-Tukey蝶形(先乘$\zeta$再加/减),逆向NTT使用Gentleman-Sande蝶形(先加/减再决定是否乘$\zeta^{-1}$),模式由\texttt{mode}端口选择。
|
||||
|
||||
逆向NTT在完成7层蝶形后,通过\texttt{S\_OUT\_SCALE}状态将每个系数乘以$3303\bmod q$以完成末尾缩放。缩放操作复用同一个7级\texttt{barrett\_mul\_pipe}实例,256个系数顺序通过流水线后输出。
|
||||
|
||||
\texttt{zeta\_rom}存储128个12-bit旋转因子,位反转索引。ROM综合为LUT,无需额外BRAM。
|
||||
|
||||
\subsection{多项式乘法与Barrett模乘}
|
||||
|
||||
\texttt{poly\_mul\_sync}实现NTT域两个多项式的逐点乘法,即对128个系数对$(a_0,a_1)$和$(b_0,b_1)$按$c_0=a_0b_0+a_1b_1\zeta\bmod q$和$c_1=a_0b_1+a_1b_0\bmod q$计算。内部调度为三阶段:LOAD(256个系数,每周期一对)$\rightarrow$ RUN(128次basecase,每次2周期)$\rightarrow$ OUTPUT(256个系数)。
|
||||
|
||||
\texttt{basecase\_mul}为纯组合逻辑,数据通路包含5个\texttt{barrett\_mul}实例。$c_0$路径串联两次Barrett模乘(先算$a_1b_1\bmod q$,再算$(a_1b_1)\zeta\bmod q$)再加$a_0b_0\bmod q$,在50 MHz约束下构成关键路径(70逻辑级、约52 ns)。
|
||||
|
||||
\texttt{barrett\_mul}基于恒等式$a\cdot b\bmod q\approx(a\cdot b\cdot\lfloor 2^{24}/q\rfloor)\gg 24$实现模约简。对于$q=3329$,$\lfloor 2^{24}/3329\rfloor=5039$。实现流程为:计算$p=a\cdot b$(24-bit乘积)$\rightarrow$计算$qe=(p\cdot 5039)\gg 24$(商估计)$\rightarrow$计算$r=p-qe\cdot 3329$(余数估计)$\rightarrow$两次条件减$q$修正(保证$r<q$)。该模块已通过流水线化改造支持50 MHz工作频率。
|
||||
|
||||
\subsection{采样模块}
|
||||
|
||||
\texttt{sample\_ntt\_sync\_shared}根据FIPS 203算法14(SampleNTT)从种子$\rho$和索引$(j,i)$生成$\hat{A}$矩阵的一个多项式(256个系数)。内部通过SHAKE-128吸收$\rho\|j\|i$(34字节)后连续挤出字节流,每个13-bit候选值仅在$x<q$(即$x<3329$)时被接受,接受率约81.3\%。逐系数通过\texttt{valid/ready}握手输出,直接写入\texttt{bank\_a}。
|
||||
|
||||
\texttt{sample\_cbd\_sync\_shared}实现中心二项分布CBD$_\eta$采样。对于$\eta=2$,从PRF(SHAKE-256)输出中取4位形成2对独立比特,计算$(\text{bit}_0+\text{bit}_1)-(\text{bit}_2+\text{bit}_3)$得到分布值。对于$\eta=3$(仅ML-KEM-512),取6位形成3对。模块通过\texttt{valid/ready}握手逐系数输出,直接写入\texttt{bank\_se}或\texttt{bank\_t}。
|
||||
|
||||
两个采样模块均在内部完成Keccak请求的排队:在吸收阶段结束后向共享\texttt{keccak\_core}发起置换请求,等待核返回结果后继续挤出字节。由于采样模块与SHA3族消费者处于互斥的FSM阶段,对共享核的竞争不存在。
|
||||
|
||||
\subsection{压缩与解压缩}
|
||||
|
||||
\texttt{comp\_decomp\_sync}实现Compress$_d$和Decompress$_d$函数。Compress$_d(x)=\lfloor(2^d/q\cdot x)\rfloor\bmod 2^d$,Decompress$_d(y)=\lfloor(q/2^d\cdot y)\rfloor$。实现将除数$q$替换为Barrett风格的$5039\cdot 2^{-24}$近似,避免组合除法器。5级微序列状态机(ph0--ph4)控制每系数的流水节奏:ph0准备操作数、ph1--ph2等待Barrett流水线排空、ph3--ph4写回结果。模块逐系数通过\texttt{valid/ready}握手输入输出,吞吐为每5周期一个系数。
|
||||
|
||||
\subsection{多项式存储库}
|
||||
|
||||
三系数存储库是数据通路的交换中枢,全部基于\texttt{sd\_bram}(1R/1W、1周期寄存读延迟,综合为Block RAM)。表\ref{tab:banks}列出配置和内容。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\small
|
||||
\caption{多项式系数存储库配置}
|
||||
\label{tab:banks}
|
||||
\begin{tabular}{cccp{5.5cm}}
|
||||
\toprule
|
||||
\textbf{实例} & \textbf{尺寸} & \textbf{物理BRAM} & \textbf{存储内容} \\
|
||||
\midrule
|
||||
bank\_a & 12-bit $\times$ 4096 & 1 RAMB36 + 1 RAMB18 & $\hat{A}[i][j]$矩阵(slot 0至$K^2-1$) \\
|
||||
bank\_se & 12-bit $\times$ 2048 & 1 $\times$ RAMB36 & $\hat{s}/\hat{e}$(KeyGen)、$\hat{y}$(Encaps)、$\hat{u}$(Decaps) \\
|
||||
bank\_t & 12-bit $\times$ 1024 & 1 $\times$ RAMB18 & $\hat{t}$、MAC累加和、$v$、$w$ \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
槽位布局为:$\hat{A}$占用slot 0至$K^2-1$(基地址0),$\hat{s}$占用slot $K^2$至$K^2+K-1$,$\hat{e}$占用slot $K^2+K$至$K^2+2K-1$,$\hat{t}$占用slot $K^2+2K$至$K^2+3K-1$。所有槽位寻址在运行时由$k\_r$递推,例如$\hat{s}$基地址$\texttt{slot\_s\_rt}=K^2$。
|
||||
|
||||
库的读写端口在多个FSM状态之间分时复用。\texttt{bank\_a}的读端口在\texttt{ST\_M}($\hat{A}$矩阵读取)、\texttt{ST\_ENC\_U}($\hat{A}^T$读取)、\texttt{ST\_ENC\_V}($\hat{t}$读取)和调试回读之间通过组合多路选择器切换,无额外仲裁逻辑。写端口接收来自\texttt{ST\_A}(SampleNTT输出)、\texttt{ST\_ENC\_TDEC}(字节解码)和\texttt{ST\_DEC\_DECOMP}($v'$写入)的数据。
|
||||
|
||||
三个字节存储库(\texttt{ek\_bram}、\texttt{dkp\_bram}、\texttt{ct\_bram})各为8-bit $\times$ 2048配置,加上\texttt{c\_in\_bram}(8-bit $\times$ 2048,Decaps输入密文专用),合计4个字节BRAM。\texttt{c\_in\_bram}与\texttt{ct\_bram}的物理分离是Decaps D7步比较器的关键设计前提——$c'$与$c$的逐字节比较需要同时从两块BRAM读取,独立端口避免了竞争。
|
||||
|
||||
% ================================================================
|
||||
\section{验证方案}
|
||||
|
||||
\subsection{分层验证策略}
|
||||
|
||||
验证分为四个层级:
|
||||
|
||||
\begin{enumerate}[label=(\arabic*)]
|
||||
\item \textbf{叶子模块级}:独立验证\texttt{keccak\_core}、\texttt{ntt\_core}、\texttt{sample\_ntt\_sync}、\texttt{sample\_cbd\_sync}、\texttt{poly\_mul\_sync}、\texttt{comp\_decomp\_sync}共6个算子模块与Python参考模型的一致性。每个模块通过其\texttt{TB/}子目录下的专用测试平台验证。
|
||||
\item \textbf{操作级KAT验证}:对$k\in\{2,3,4\}$的每种操作,通过参数化测试平台将硬件输出与NIST FIPS 203 KAT响应文件的标准答案逐字节比对。Encaps和Decaps测试覆盖正常路径和隐式拒绝路径(损坏密文$ct\_n$)。
|
||||
\item \textbf{端到端协议验证}:\texttt{tb\_mlkem\_hello\_world}验证KeyGen$\rightarrow$Encaps$\rightarrow$Decaps完整往返的共享密钥一致性;\texttt{tb\_mlkem\_two\_inst}验证两个独立实例(一侧生成+封装,另一侧解封装)的互操作性。
|
||||
\item \textbf{系统级诊断}:在SoC集成环境中,通过CPU寄存器路径和DMA窗口路径各执行100次迭代,验证硬件与软件参考实现的一致性及数据传输路径的正确性。
|
||||
\end{enumerate}
|
||||
|
||||
\subsection{测试平台与KAT测试向量}
|
||||
|
||||
表\ref{tab:tbs}列出全部操作级和系统级测试平台。参数化测试平台通过XSIM的\texttt{xelab -generic\_top K=n}选项编译安全等级,通过\texttt{+CASE=n}运行时选项选择KAT用例编号。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\caption{测试平台清单}
|
||||
\label{tab:tbs}
|
||||
\begin{tabular}{lccc}
|
||||
\toprule
|
||||
\textbf{测试平台} & \textbf{覆盖操作} & \textbf{安全等级} & \textbf{测试向量来源} \\
|
||||
\midrule
|
||||
tb\_mlkem\_kg\_katK & KeyGen & K=2/3/4 & NIST KAT 100用例/级 \\
|
||||
tb\_mlkem\_enc\_katK & Encaps & K=2/3/4 & NIST KAT 100用例/级 \\
|
||||
tb\_mlkem\_dec\_katK & Decaps & K=2/3/4 & NIST KAT 100用例/级 + ct\_n \\
|
||||
tb\_mlkem\_hello\_world & 全流程 & K=3 & 固定测试向量 \\
|
||||
tb\_mlkem\_two\_inst & 双实例 & K=3 & 固定测试向量 \\
|
||||
mlkem\_test (SoC) & CPU/DMA & K=2/3/4 & KAT count=0确定性输入 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
KAT测试向量来自NIST FIPS 203的KAT响应文件,由Python脚本解析为每用例独立的hex文件。每个KAT用例包含种子$d$、$z$、$m$以及期望的$ek$、$dk$、$c$和共享密钥。Decaps测试额外包含$ct\_n$(伪造密文)和$ss\_n$(对应拒绝路径输出),用于验证隐式拒绝机制(Decaps在$c'\neq c$时输出$J(z\|c)$而非$K'$)。
|
||||
|
||||
Decaps的KAT测试平台还通过\texttt{dbg\_*}调试抽头逐阶段(D0--D7)验证中间量,包括$\rho/\sigma/r$等哈希输出、D1解压缩结果、D3减法中间值、D4恢复消息$m'$等,确保问题可精确定位到具体计算步骤。
|
||||
|
||||
\subsection{系统级诊断测试}
|
||||
|
||||
SoC诊断程序\texttt{mlkem\_test}实现三条独立测试路径:
|
||||
|
||||
\textbf{软件参考路径}在33 MHz Loongson CPU上运行纯C语言ML-KEM实现,记录各阶段周期数作为加速比的基准,并验证结果自洽性与KAT标准答案一致性。
|
||||
|
||||
\textbf{CPU寄存器路径}通过AXI寄存器接口直接控制IP核:写入CONFIG配置、通过D[0..7]/Z[0..7]写入种子、通过PRE\_SEL/ADR/DAT序列逐字节预装载公钥/私钥/密文、写CTRL.start启动、轮询STATUS.done、通过RDB\_SEL/ADR/DAT读回结果。该路径验证了IP核的AXI从机接口逻辑和寄存器级控制流的正确性。
|
||||
|
||||
\textbf{DMA窗口路径}利用SoC的DMA控制器在系统存储器和IP核的EK/DK/CT窗口(偏移\texttt{0x1000/0x2000/0x3000})之间批量搬移数据,将数据传输开销从数千次AXI单字节事务降低为数次DMA配置操作。该路径验证了IP核存储器窗口与DMA控制器之间的数据搬移正确性,以及批量传输模式相对于逐字节读写的效率提升。
|
||||
|
||||
每种路径对每个安全等级执行100次迭代,记录自洽性(\texttt{ss\_enc == ss\_dec})和KAT标准答案一致性。
|
||||
|
||||
% ================================================================
|
||||
\section{实现结果与测试数据}
|
||||
|
||||
\subsection{FPGA资源利用}
|
||||
|
||||
ML-KEM IP核在Xilinx Artix-7 \texttt{xc7a200tfbg676-1}上完成布局布线后的独立资源利用如表\ref{tab:mlkem_util}所示。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\caption{mlkem\_top布局布线后资源利用(50 MHz集成频率)}
|
||||
\label{tab:mlkem_util}
|
||||
\begin{tabular}{lccc}
|
||||
\toprule
|
||||
\textbf{资源} & \textbf{已用} & \textbf{可用} & \textbf{利用率} \\
|
||||
\midrule
|
||||
Slice LUTs & 31,884 & 133,800 & 23.8\% \\
|
||||
Slice FFs & 24,736 & 267,600 & 9.2\% \\
|
||||
Block RAM Tile & 5.5 & 365 & 1.5\% \\
|
||||
DSP48E1 & 0 & 740 & 0.0\% \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
DSP使用量为零体现了设计的主动约束——所有乘法(包括NTT蝶形中的Barrett模乘和\texttt{basecase\_mul}中的乘法)均强制映射至LUT和CARRY4逻辑,不消耗任何DSP48E1资源。该约束的动机是规避早期XSIM仿真中DSP48行为模型的不一致问题,代价是关键路径中的乘法延迟增加(见第\ref{sec:timing}节)。
|
||||
|
||||
表\ref{tab:modules_util}给出布局布线后的子模块级资源分解。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\small
|
||||
\caption{mlkem\_top主要子模块资源利用}
|
||||
\label{tab:modules_util}
|
||||
\begin{tabular}{lcccc}
|
||||
\toprule
|
||||
\textbf{子模块} & \textbf{LUT} & \textbf{FF} & \textbf{BRAM} & \textbf{DSP} \\
|
||||
\midrule
|
||||
ntt\_core (含蝶形流水线与Barrett) & 8,625 & 3,861 & 0 & 0 \\
|
||||
keccak\_core (Keccak-f[1600]置换核) & 5,274 & 1,606 & 0 & 0 \\
|
||||
poly\_mul\_sync (含basecase\_mul) & 3,881 & 6,743 & 0 & 0 \\
|
||||
sample\_cbd\_sync\_shared & 2,741 & 3,186 & 0 & 0 \\
|
||||
sample\_ntt\_sync\_shared & 2,109 & 1,669 & 0 & 0 \\
|
||||
sha3\_top\_shared (哈希族封装) & 1,766 & 2,388 & 0 & 0 \\
|
||||
comp\_decomp\_sync & 467 & 323 & 0 & 0 \\
|
||||
bank\_a (Â矩阵,12-bit$\times$4096) & 50 & 0 & 1 RAMB36 + 1 RAMB18 & 0 \\
|
||||
bank\_se (ŝ/ê,12-bit$\times$2048) & 70 & 0 & 1 RAMB36 & 0 \\
|
||||
bank\_t (t̂,12-bit$\times$1024) & 654 & 0 & 1 RAMB18 & 0 \\
|
||||
字节BRAM(ek/dkp/ct/c\_in,4个) & 3,528 & 0 & 4 RAMB18 & 0 \\
|
||||
其它(FSM/多路复用/地址生成/顶层连线)& 2,719 & 4,960 & 0 & 0 \\
|
||||
\midrule
|
||||
\textbf{合计} & \textbf{31,884} & \textbf{24,736} & \textbf{2 RAMB36 + 6 RAMB18} & \textbf{0} \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
NTT核是面积最大的单一逻辑单元(8,625 LUT,占总LUT的27.1\%),主要由256$\times$12-bit系数寄存器阵列和7级深流水Barrett蝶形单元组成。Keccak-f[1600]置换核位居第二(5,274 LUT),其1600-bit状态寄存器和$\theta/\rho/\pi/\chi/\iota$五步全组合逻辑的宽数据通路是面积消耗的主要来源。值得注意的是,若未采用单核时分复用方案,G/H/J、SampleNTT和CBD各需独立例化\texttt{keccak\_core},三份实例的累计开销将超过16,000 LUT,使ML-KEM IP的LUT利用率从23.8\%飙升至约36\%——这正是设计原则二中共享Keccak策略的核心收益。
|
||||
|
||||
多项式乘法模块的FF数量(6,743)远超其他模块,原因在于\texttt{basecase\_mul}内部串行双Barrett模乘路径需要大量流水寄存器来匹配乘法进位链的延迟。存储库合计消耗2个RAMB36和6个RAMB18(共约5.5个Block RAM Tile),其中\texttt{bank\_a}因$K_{MAX}=4$下需存储$K^2+3K=28$个多项式的全部系数(28$\times$256$\times$12-bit = 86,016 bits),配置为1 RAMB36 + 1 RAMB18方可满足容量需求。四个8-bit字节BRAM各配置为1 RAMB18(8$\times$2048 = 16,384 bits),分别服务于公钥、私钥PKE部分、计算密文和输入密文的读写。
|
||||
|
||||
\subsection{时序性能}\label{sec:timing}
|
||||
|
||||
表\ref{tab:timing}列出布局布线后的时序收敛情况。ML-KEM IP直接工作于\texttt{sys\_clk}域(50 MHz,周期20 ns)。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\caption{布局布线后时序收敛结果(50 MHz集成频率)}
|
||||
\label{tab:timing}
|
||||
\begin{tabular}{lccc}
|
||||
\toprule
|
||||
\textbf{时钟域} & \textbf{目标周期} & \textbf{Setup WNS} & \textbf{违例端点} \\
|
||||
\midrule
|
||||
sys\_clk(全局) & 20 ns (50 MHz) & +0.146 ns & 0 / 69,558 \\
|
||||
ML-KEM最差路径 & 20 ns (50 MHz) & +0.243 ns & 0 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
\texttt{sys\_clk}域在50 MHz目标频率下全局时序收敛,ML-KEM子模块的最差路径位于\texttt{dj\_wb\_inc\_reg}至\texttt{h\_block\_r\_reg}的组合逻辑链,Slack为+0.243 ns,距违例仍有显著余量。时序收敛的关键在于\texttt{barrett\_mul}模乘单元的流水线化改造——将原本70逻辑级、约52 ns的纯组合路径拆分为三级流水,每级延迟控制在12 ns以内,使$c_0$双乘串联路径从单周期52 ns缩短至流水化后的每级$\le 12$ ns。
|
||||
|
||||
\subsection{功耗分析}
|
||||
|
||||
布局布线后功耗估计如表\ref{tab:power}所示。ML-KEM IP核的片上功耗约0.115 W(动态),占SoC总动态功耗(0.409 W)的28.1\%。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\caption{ML-KEM IP功耗估计(布局布线后,典型工艺角)}
|
||||
\label{tab:power}
|
||||
\begin{tabular}{lcc}
|
||||
\toprule
|
||||
\textbf{功耗来源} & \textbf{功率(W)} & \textbf{说明} \\
|
||||
\midrule
|
||||
Slice Logic & 0.046 & LUT翻转 + FF时钟功耗 \\
|
||||
Signals & 0.052 & 互联线翻转功耗 \\
|
||||
Block RAM & 0.017 & 7个BRAM实例的读写功耗 \\
|
||||
\midrule
|
||||
\textbf{ML-KEM合计} & \textbf{0.115} & 占SoC动态功耗28.1\% \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
\subsection{功能验证结果}
|
||||
|
||||
\subsubsection{KAT逐字节比对}
|
||||
|
||||
表\ref{tab:kat_results}汇总全部安全等级和操作的KAT验证结果。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\caption{KAT验证结果汇总}
|
||||
\label{tab:kat_results}
|
||||
\begin{tabular}{lccccc}
|
||||
\toprule
|
||||
\textbf{操作} & \textbf{K=2} & \textbf{K=3} & \textbf{K=4} & \textbf{用例数} & \textbf{通过率} \\
|
||||
\midrule
|
||||
KeyGen(算法16) & PASS & PASS & PASS & 100/级 & 100\% \\
|
||||
Encaps(算法17) & PASS & PASS & PASS & 100/级 & 100\% \\
|
||||
Decaps正常路径(算法18)& PASS & PASS & PASS & 100/级 & 100\% \\
|
||||
Decaps隐式拒绝路径 & PASS & PASS & PASS & 100/级 & 100\% \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
全部360个KAT测试用例均逐字节比对NIST标准答案通过,无任何字节级偏差。Decaps隐式拒绝路径($c'_n\neq c$)验证了FO变换中常量时间比较器和$J(z\|c)$拒绝密钥生成逻辑的正确性。
|
||||
|
||||
\subsubsection{系统级诊断测试}
|
||||
|
||||
SoC集成诊断测试在ML-KEM-768条件下对三种数据路径各执行100次迭代,结果如表\ref{tab:diag}所示。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\caption{系统级诊断测试结果(ML-KEM-768,100次迭代)}
|
||||
\label{tab:diag}
|
||||
\begin{tabular}{lccc}
|
||||
\toprule
|
||||
\textbf{测试路径} & \textbf{失败次数} & \textbf{自洽性通过率} & \textbf{KAT通过率} \\
|
||||
\midrule
|
||||
SW(纯软件参考) & 0 & 100\% & 100\% \\
|
||||
CPU寄存器路径 & 0 & 100\% & 100\% \\
|
||||
DMA窗口路径 & 0 & 100\% & 100\% \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
\subsection{性能分析}
|
||||
|
||||
表\ref{tab:perf}列出三种安全等级下软件参考、CPU寄存器路径和DMA窗口路径完成一轮完整往返(KeyGen+Encaps+Decaps)的平均时钟周期数及加速比。数据来自SoC实际运行的100次迭代统计。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\small
|
||||
\caption{三路径完整往返性能对比(100次迭代平均值)}
|
||||
\label{tab:perf}
|
||||
\begin{tabular}{lrrrrrr}
|
||||
\toprule
|
||||
\textbf{安全等级} & \textbf{SW} & \textbf{CPU} & \textbf{DMA} & \textbf{CPU加速比} & \textbf{DMA加速比} & \textbf{DMA/CPU} \\
|
||||
\midrule
|
||||
ML-KEM-512 (k=2) & 2,587,784 & 352,684 & 185,671 & 7.34$\times$ & 13.94$\times$ & 1.90$\times$ \\
|
||||
ML-KEM-768 (k=3) & 4,056,378 & 523,656 & 279,588 & 7.75$\times$ & 14.51$\times$ & 1.87$\times$ \\
|
||||
ML-KEM-1024 (k=4) & 6,025,486 & 718,672 & 388,959 & 8.38$\times$ & 15.49$\times$ & 1.85$\times$ \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
从数据中可以得出以下结论。CPU寄存器路径相对于纯软件实现了7.34$\times$至8.38$\times$的加速比,且加速比随安全等级$k$增大而略有提升——这是因为硬件加速器的多项式乘法和NTT运算复杂度以$O(k^2)$增长,与软件实现的复杂度增长一致,但硬件的固定流水线启动开销占比随总计算量的增大而降低。
|
||||
|
||||
DMA路径相对于CPU寄存器路径额外贡献了约1.85--1.90$\times$的效率提升。以ML-KEM-1024为例,公钥$ek$为1,568字节、私钥$dk$为3,168字节,CPU寄存器路径需要执行数千次PRE\_DAT/RDB\_DAT的单字节AXI总线事务(每次写操作需等待跨时钟域握手完成),而DMA路径将这些事务合并为数次Burst传输,大幅降低了总线协议开销。
|
||||
|
||||
\subsection{逐状态性能分解}
|
||||
|
||||
为进一步分析各FSM状态对总延迟的贡献,表\ref{tab:state_timing}列出50 MHz仿真下每种操作各状态的周期数和执行时间(以CASE=0为代表性数据)。时钟周期为20 ns。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\small
|
||||
\caption{KeyGen逐状态性能分解(50 MHz,CASE=0)}
|
||||
\label{tab:state_timing}
|
||||
\begin{tabular}{lrrrrrr}
|
||||
\toprule
|
||||
\multirow{2}{*}{\textbf{状态}} & \multicolumn{2}{c}{\textbf{K=2}} & \multicolumn{2}{c}{\textbf{K=3}} & \multicolumn{2}{c}{\textbf{K=4}} \\
|
||||
& cycles & $\mu$s & cycles & $\mu$s & cycles & $\mu$s \\
|
||||
\midrule
|
||||
ST\_G($G(d\|K)$) & 27 & 0.5 & 27 & 0.5 & 27 & 0.5 \\
|
||||
ST\_A(SampleNTT生成Â) & 3,251 & 65.0 & 7,233 & 144.7 & 12,825 & 256.5 \\
|
||||
ST\_C(CBD采样$s/e$) & 1,229 & 24.6 & 1,693 & 33.9 & 2,257 & 45.1 \\
|
||||
ST\_N(前向NTT) & 1,481 & 29.6 & 2,961 & 59.2 & 2,961 & 59.2 \\
|
||||
ST\_M(矩阵向量乘累加) & 2,092 & 41.8 & 4,707 & 94.1 & 8,368 & 167.4 \\
|
||||
ST\_E(byteEncode编码) & 2,081 & 41.6 & 3,105 & 62.1 & 4,129 & 82.6 \\
|
||||
ST\_H($H(ek)$哈希) & 979 & 19.6 & 1,468 & 29.4 & 1,957 & 39.1 \\
|
||||
\midrule
|
||||
\textbf{总计} & \textbf{11,140} & \textbf{222.8} & \textbf{21,194} & \textbf{423.9} & \textbf{32,524} & \textbf{650.5} \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
KeyGen各状态的周期数呈现出与$K$值的清晰依赖关系。ST\_A(SampleNTT)和ST\_M(矩阵向量乘累加)是最耗时的两个状态,二者合计占总周期的48.0\%(K=2)至65.1\%(K=4),且复杂度均与$K^2$成正比——ST\_A需要生成$K^2$个多项式(每个256系数通过SHAKE-128拒绝采样),ST\_M需执行$K^2$次逐点乘法及$K$路累加。ST\_G(单块SHA3-512)的周期数恒为27,与$K$无关。ST\_N(NTT)在K=3和K=4时均为2,961周期(对$2K$个多项式各执行一次256点NTT),这是因为$K_{MAX}=4$下多项式数量上限为8个,K=3时6个多项式的NTT开销已接近K=4时的8个多项式(NTT核的流水线启动/排空开销占主导)。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\small
|
||||
\caption{Encaps逐状态性能分解(50 MHz,CASE=0)}
|
||||
\label{tab:state_enc}
|
||||
\begin{tabular}{lrrrrrr}
|
||||
\toprule
|
||||
\multirow{2}{*}{\textbf{状态}} & \multicolumn{2}{c}{\textbf{K=2}} & \multicolumn{2}{c}{\textbf{K=3}} & \multicolumn{2}{c}{\textbf{K=4}} \\
|
||||
& cycles & $\mu$s & cycles & $\mu$s & cycles & $\mu$s \\
|
||||
\midrule
|
||||
ENC\_LOAD(数据就绪) & 34 & 0.7 & 34 & 0.7 & 34 & 0.7 \\
|
||||
ENC\_H($H(ek)$) & 980 & 19.6 & 1,469 & 29.4 & 1,958 & 39.2 \\
|
||||
ENC\_G($G(m\|H(ek))$) & 26 & 0.5 & 26 & 0.5 & 26 & 0.5 \\
|
||||
ENC\_A(重新生成Â$^T$) & 3,251 & 65.0 & 7,233 & 144.7 & 12,825 & 256.5 \\
|
||||
ENC\_TDEC(byteDecode t̂) & 1,281 & 25.6 & 1,921 & 38.4 & 2,561 & 51.2 \\
|
||||
ENC\_C(CBD采样$y/e_1/e_2$)& 1,461 & 29.2 & 1,975 & 39.5 & 2,539 & 50.8 \\
|
||||
ENC\_N(NTT(y)) & 1,481 & 29.6 & 1,481 & 29.6 & 1,481 & 29.6 \\
|
||||
ENC\_U($u$向量计算) & 5,585 & 111.7 & 9,946 & 198.9 & 15,353 & 307.1 \\
|
||||
ENC\_C1(压缩编码$c_1$) & 6,273 & 125.5 & 9,409 & 188.2 & 12,673 & 253.5 \\
|
||||
ENC\_E2MV($e_2$搬迁) & 258 & 5.2 & 258 & 5.2 & 258 & 5.2 \\
|
||||
ENC\_V($v$向量计算) & 2,793 & 55.9 & 3,316 & 66.3 & 3,839 & 76.8 \\
|
||||
ENC\_C2(压缩编码$c_2$) & 2,945 & 58.9 & 2,945 & 58.9 & 2,977 & 59.5 \\
|
||||
\midrule
|
||||
\textbf{总计} & \textbf{26,368} & \textbf{527.4} & \textbf{40,013} & \textbf{800.3} & \textbf{56,524} & \textbf{1,130.5} \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
Encaps中最耗时的两个状态为ENC\_C1(压缩$c_1$)和ENC\_U($u$向量计算)。ENC\_C1对$K$个多项式逐系数执行Compress$_{d_u}$和byteEncode,每系数需5周期(通过\texttt{comp\_decomp\_sync}的5级微序列),因此总周期数与$K$和$d_u$成正比。ENC\_U涉及$\hat{A}^T\circ\hat{y}$逐点乘($K^2$次\texttt{poly\_mul\_sync}调用)和INTT($K$次逆向NTT),其$O(K^2)$复杂度使其在高安全等级时占主导。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\small
|
||||
\caption{Decaps逐状态性能分解(50 MHz,CASE=0)}
|
||||
\label{tab:state_dec}
|
||||
\begin{tabular}{lrrrrrr}
|
||||
\toprule
|
||||
\multirow{2}{*}{\textbf{状态}} & \multicolumn{2}{c}{\textbf{K=2}} & \multicolumn{2}{c}{\textbf{K=3}} & \multicolumn{2}{c}{\textbf{K=4}} \\
|
||||
& cycles & $\mu$s & cycles & $\mu$s & cycles & $\mu$s \\
|
||||
\midrule
|
||||
DEC\_LOAD(数据就绪) & 2 & 0.0 & 2 & 0.0 & 2 & 0.0 \\
|
||||
DEC\_DECOMP(D1解压缩) & 8,449 & 169.0 & 11,393 & 227.9 & 14,657 & 293.1 \\
|
||||
DEC\_SDEC(D2解码ŝ) & 1,281 & 25.6 & 1,921 & 38.4 & 2,561 & 51.2 \\
|
||||
DEC\_NTT(D2 NTT(u')) & 1,481 & 29.6 & 1,481 & 29.6 & 1,481 & 29.6 \\
|
||||
DEC\_W(D3计算$w$) & 2,793 & 55.9 & 3,316 & 66.3 & 3,839 & 76.8 \\
|
||||
DEC\_MENC(D4恢复$m'$) & 513 & 10.3 & 513 & 10.3 & 513 & 10.3 \\
|
||||
DEC\_G(D5 $G(m'\|h)$) & 26 & 0.5 & 26 & 0.5 & 26 & 0.5 \\
|
||||
\multicolumn{7}{c}{\textbf{———— D6 流水线复用(=Encaps全部状态) ————}} \\
|
||||
ENC\_LOAD--ENC\_C2(重加密) & 26,368 & 527.4 & 40,013 & 800.3 & 56,524 & 1,130.5 \\
|
||||
DEC\_CMP(D7常量时间比较) & 1,537 & 30.7 & 2,177 & 43.5 & 3,137 & 62.7 \\
|
||||
\midrule
|
||||
\textbf{总计} & \textbf{41,444} & \textbf{828.9} & \textbf{59,347} & \textbf{1,186.9} & \textbf{80,756} & \textbf{1,615.1} \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
Decaps的性能数据直接验证了设计原则三(流水线复用)的实际效果。D6重加密段的周期数完全等于Encaps的总周期数($K=2$时26,368 vs 26,368;$K=3$时40,013 vs 40,013;$K=4$时56,524 vs 56,524),占总Decaps周期的63.6\%(K=2)至70.0\%(K=4)。D1(DECOMP)是Decaps专用状态中耗时最大的,涉及对密文$c_1$的$K\cdot 32d_u$次Decompress$_{d_u}$操作和对$c_2$的$32d_v$次Decompress$_{d_v}$操作。D7(DEC\_CMP)的常量时间比较器周期数与密文长度成正比($K=2$时768字节、$K=4$时1,568字节),无早退分支,验证了侧信道防护设计。Decaps Accept与Reject路径的总周期数完全相等,进一步确认了隐式拒绝的常量时间特性。
|
||||
|
||||
\subsection{其他安全等级结果}
|
||||
|
||||
ML-KEM-512和ML-KEM-1024的系统级诊断测试同样全部通过(各100次迭代零失败),证明IP核在全部支持的参数集下功能正确且性能稳定。
|
||||
|
||||
% ================================================================
|
||||
\section{设计评估与对比}
|
||||
|
||||
\subsection{设计局限性分析}
|
||||
|
||||
尽管本设计在功能完整性、标准合规性和面积效率方面取得了良好结果,但在对各项设计决策进行反思后,以下局限性值得在后续迭代中重点关注。
|
||||
|
||||
\textbf{串行FSM架构的性能上限。} 当前30状态硬连线FSM严格按照算法步骤串行执行,各状态之间无任何重叠。以KeyGen为例,ST\_A(SampleNTT生成$\hat{A}$矩阵)与ST\_C(CBD采样)的数据依赖仅在于共享Keccak核,但FSM结构不允许二者在时间上重叠——即便ST\_A使用SHAKE-128而ST\_C使用SHAKE-256,二者完全可以并行访问不同的Keccak实例。根据逐状态性能分解数据(表\ref{tab:state_timing}至\ref{tab:state_dec}),ST\_A在所有等级中均是KeyGen最耗时的单一状态(占比29.2\%--39.4\%),若能与CBD或NTT并行调度,KeyGen总延迟可降低15\%--20\%。
|
||||
|
||||
\textbf{单Butterfly Unit的NTT吞吐瓶颈。} 本设计的\texttt{ntt\_core}每次只能处理一对系数(2 coeff/cycle),完成一次256点NTT需要约370周期。相比之下,HOPE-MLKEM通过可配置的多BU架构(NBU=1至4)实现2至8 coeff/cycle的吞吐率。在NBU=4配置下,单次NTT仅需约140周期。这一差距并非频率所致(HOPE的180 MHz vs. 我们的50 MHz),而是系数级并行度的结构性差异——即使我们的设计工作在同等频率下,NTT延迟仍将是HOPE NB=4的2.6倍。
|
||||
|
||||
\textbf{DSP零使用的面积代价。} 为规避早期XSIM仿真中DSP48行为模型的不一致问题,本设计强制所有乘法映射至LUT逻辑(\texttt{use\_dsp="no"})。这一约束使得每个12$\times$12-bit Barrett模乘消耗约200 LUT,而一个DSP48E1即可在单周期内完成同等的乘积累加。据子模块资源分析(表\ref{tab:modules_util}),\texttt{ntt\_core}(含蝶形Barrett)和\texttt{poly\_mul\_sync}(含5个\texttt{barrett\_mul}实例)合计消耗12,506 LUT,其中估计约3,000 LUT用于可由DSP替代的乘法运算。在竞赛规则允许的场景下,启用DSP可将LUT利用率从23.8\%降至约21\%。
|
||||
|
||||
\textbf{系数寄存器阵列的存储效率。} \texttt{ntt\_core}内部使用256$\times$12-bit离散寄存器($cr[0:255]$)存储系数,这消耗了约3,000 FF和配套的地址译码LUT。采用BRAM存储(如\texttt{sd\_bram})可使系数存储的LUT和FF开销降至接近零,同时为多Bank交叉访问架构奠定基础。HOPE-MLKEM采用每BU两个双端口RAM(1024$\times$36-bit)的方案,用2个BRAM即可存储全部系数并支持ping-pong操作。
|
||||
|
||||
\textbf{FSM控制逻辑的资源密度。} 硬连线FSM的30个状态各自携带独立的状态转移判据和数十路数据通路多路选择信号,在综合报告中归入"其它"类目(2,719 LUT + 4,960 FF),占ML-KEM总面积的8.5\%(LUT)和20.1\%(FF)。HOPE-MLKEM采用微程序指令控制器,20-bit指令字在移位寄存器中逐拍推进,控制器LUT开销显著更低。
|
||||
|
||||
\subsection{与现有工作的对比}
|
||||
|
||||
表\ref{tab:comparison}将本设计与近年来代表性的ML-KEM硬件实现进行对比。所有数据均取自各文献报告的FPGA实现结果(Artix-7系列器件)。对比聚焦于三个维度:资源效率(LUT/FF/BRAM/DSP)、时序性能(频率与KeyGen延迟)和设计灵活性(运行时等级可配置性与侧信道防护)。
|
||||
|
||||
\begin{table}[htbp]
|
||||
\centering
|
||||
\small
|
||||
\caption{ML-KEM硬件实现对比(FPGA,Artix-7系列)}
|
||||
\label{tab:comparison}
|
||||
\begin{tabular}{lccccccc}
|
||||
\toprule
|
||||
\textbf{设计} & \textbf{频率} & \textbf{LUT} & \textbf{FF} & \textbf{BRAM} & \textbf{DSP} & \textbf{KG延迟} & \textbf{可配置} \\
|
||||
& (MHz) & & & & & ($\mu$s, K=2) & \\
|
||||
\midrule
|
||||
\textbf{本设计} & 50 & 31,884 & 24,736 & 5.5 & \textbf{0} & 223 & \checkmark \\
|
||||
\hline
|
||||
HOPE NB=1 \cite{CHES25hope} & 180 & $\sim$18,000 & $\sim$16,000 & $\sim$15 & $\sim$6 & 20.6 & $\times$ \\
|
||||
HOPE NB=4 \cite{CHES25hope} & 180 & $\sim$22,000 & $\sim$22,000 & $\sim$17 & $\sim$12 & 7.2 & $\times$ \\
|
||||
DMG23 \cite{DMG23} & 220 & 9,347 & 8,186 & 6 & 4 & — & $\times$ \\
|
||||
NKK+23 \cite{NKK23} & 208 & 30,146 & 26,371 & 0 & 4 & 5.3 & $\times$ \\
|
||||
KJSL24 \cite{KJSL24} & 210 & 25,757 & 18,629 & — & 14 & 8.6 & \checkmark \\
|
||||
NKLO25 \cite{NKLO25} & 270 & 19,028 & 15,372 & — & — & 6.7 & $\times$ \\
|
||||
XL21 \cite{XL21} & 161 & 14,197 & — & — & — & 23.4 & $\times$ \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
从对比中可以得出以下观察。在资源效率维度,本设计是唯一完全不消耗DSP资源的实现(0 DSP),这在特定的竞赛约束和平台兼容性需求下具有独特价值。然而,这一约束也直接反映在较高的LUT用量上——本设计的31,884 LUT约为同等级HOPE NB=1的1.8倍。在时序性能维度,本设计的50 MHz工作频率和223 $\mu$s的KeyGen延迟(K=2)与主流180--220 MHz设计存在明显差距,主要由串行FSM架构(无状态间并行)和单BU吞吐瓶颈(2 coeff/cycle)共同导致。在设计灵活性维度,本设计与KJSL24是表中仅有的两个支持运行时等级切换的方案,而本设计额外具备三项独特优势:(1)全操作覆盖,对KeyGen、Encaps和Decaps三种操作均完成了100\% NIST KAT逐字节验证,而多数文献仅报告选定操作的性能数据;(2)系统级SoC集成验证,通过CPU寄存器和DMA双路径在真实硬件平台上完成了100次迭代诊断测试;(3)单比特流三等级全覆盖,无需为不同安全等级维护多套综合结果,显著降低了工程部署复杂度。
|
||||
|
||||
值得注意的是,直接逐行比较资源数字存在局限性。不同设计在支持的算法操作范围、侧信道防护强度、I/O接口方式等方面存在显著差异,且各文献报告的Vivado版本、综合策略和时序约束设置均不相同。NKK+23和NKLO25在特定等级下实现了极低的延迟(5--7 $\mu$s),但其设计针对固定安全等级优化,不支持运行时重配置。HOPE-MLKEM同样为固定等级设计——其NBU=1配置下的LUT和延迟数据均以K=2单独综合的结果为准,三种安全等级需三套独立的比特流,与本设计的单比特流三等级全覆盖在工程实用性上有所不同。KJSL24是本设计之外唯一支持运行时等级切换的方案。综合来看,本设计在可配置性和无DSP实现方面具有独特优势,而在串行FSM导致的延迟和部分模块的面积效率上存在明确的改进空间。
|
||||
|
||||
\subsection{优化路线图}
|
||||
|
||||
基于上述分析,后续优化的优先级排序应遵循投入产出比原则。第一优先级的改进是将\texttt{ntt\_core}的系数存储从离散寄存器阵列迁移至BRAM,预计释放约3,000 LUT和3,000 FF,同时为多BU并行架构奠定存储基础。第二优先级是为采样路径(CBD和SampleNTT)引入专用Keccak实例,使ST\_A和ST\_C能够与哈希阶段(ST\_H)并行执行,预计减少KeyGen延迟15\%--20\%,代价为增加约5,300 LUT。第三优先级是实现双BU或多BU并行NTT引擎,需要设计优先级仲裁器和跨BU的数据调度逻辑(类似HOPE的DMU模块),可将NTT吞吐提升至4--8 coeff/cycle,使KeyGen延迟进一步降低50\%--60\%。
|
||||
|
||||
% ================================================================
|
||||
\section{结论与展望}
|
||||
|
||||
本文设计并实现了一款完整的ML-KEM后量子密钥封装硬件IP核。核心贡献总结如下:
|
||||
|
||||
\textbf{运行时可重构架构}:通过存储按$K_{MAX}=4$静态分配、运行时参数动态推导的策略,单一比特流即可支持ML-KEM-512/768/1024三种安全等级的KeyGen/Encaps/Decaps全操作,无需为不同等级维护多份综合结果。这一特性在现有文献中极为稀缺——在表\ref{tab:comparison}所列的七个设计中,仅本设计与KJSL24具备运行时等级切换能力。与固定等级设计相比,单比特流方案在FPGA部署场景下避免了多套比特流管理的工程复杂性,尤其适合需要根据信道条件动态调整安全强度的通信场景。
|
||||
|
||||
\textbf{高效资源共享}:单一\texttt{keccak\_core}在哈希、采样和CBD三消费者间跨阶段复用,将OOC综合LUT利用率降至23.8\%;Decaps D6步重加密复用整条Encaps流水线,避免了约800行RTL的重复实现。
|
||||
|
||||
\textbf{完整标准合规}:360个NIST KAT测试用例全部逐字节比对通过,覆盖三种等级三种操作及隐式拒绝路径。端到端协议测试和系统级诊断验证了软硬件协同的完整正确性。
|
||||
|
||||
\textbf{显著性能提升}:相对于33 MHz CPU上的软件参考实现,50 MHz硬件IP在CPU寄存器路径实现7.3--8.4$\times$加速比,在DMA路径实现13.9--15.5$\times$加速比。
|
||||
|
||||
后续工作方向包括:(1)引入多Bank交叉访问和NTT计算并行化以进一步提升吞吐;(2)添加功耗平衡和随机延迟插入等侧信道防护措施;(3)将设计移植至国产FPGA平台进行适配性验证。
|
||||
|
||||
\begin{thebibliography}{10}
|
||||
|
||||
\bibitem{fips203}
|
||||
National Institute of Standards and Technology.
|
||||
\emph{FIPS 203: Module-Lattice-Based Key-Encapsulation Mechanism Standard}.
|
||||
August 2024.
|
||||
|
||||
\bibitem{fips202}
|
||||
National Institute of Standards and Technology.
|
||||
\emph{FIPS 202: SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions}.
|
||||
August 2015.
|
||||
|
||||
\bibitem{kyber}
|
||||
R.~Avanzi \etal.
|
||||
\emph{CRYSTALS-Kyber: Algorithm Specifications and Supporting Documentation}.
|
||||
NIST PQC Round 3 Submission, 2021.
|
||||
|
||||
\bibitem{dang2022}
|
||||
V.~B.~Dang, F.~Farahmand, M.~Andrzejczak, and K.~Gaj.
|
||||
\emph{Implementing and Benchmarking CRYSTALS-Kyber on FPGAs}.
|
||||
IEEE Trans. Computers, 71(10):2475--2488, 2022.
|
||||
|
||||
\bibitem{xing2023}
|
||||
Y.~Xing and S.~Li.
|
||||
\emph{A Compact Hardware Architecture for CRYSTALS-Kyber}.
|
||||
IEEE Trans. Circuits Syst. I, 70(3):1124--1137, 2023.
|
||||
|
||||
\bibitem{barrett}
|
||||
P.~Barrett.
|
||||
\emph{Implementing the Rivest Shamir and Adleman Public Key Encryption Algorithm on a Standard Digital Signal Processor}.
|
||||
CRYPTO 1986, pp. 311--323.
|
||||
|
||||
\bibitem{CHES25hope}
|
||||
E.~Camacho-Ruiz, P.~Navarro-Torrero, and A.~Cabrera~Aldaya.
|
||||
\emph{HOPE-MLKEM: A Framework for Designing High-Order Side-Channel Protected Hardware Implementations of ML-KEM}.
|
||||
CHES 2025 (to appear), 2026.
|
||||
Available: \url{https://github.com/HWSec-CSIC/hope-mlkem}.
|
||||
|
||||
\bibitem{DMG23}
|
||||
V.~B.~Dang, A.~Mohajerani, and K.~Gaj.
|
||||
\emph{High-Speed Hardware Architectures for CRYSTALS-Kyber}.
|
||||
IEEE Trans. VLSI Syst., 31(8):1185--1198, 2023.
|
||||
|
||||
\bibitem{NKK23}
|
||||
M.~J.~Nguyen, B.~Kieu-Do, and C.~K.~Koc.
|
||||
\emph{A High-Performance Hardware Implementation of CRYSTALS-Kyber}.
|
||||
In Proc. HOST, pp. 123--134, 2023.
|
||||
|
||||
\bibitem{KJSL24}
|
||||
M.~Krausz, G.~Jati, S.~Saha, and D.~Lee.
|
||||
\emph{A Configurable and Efficient Hardware Implementation of ML-KEM}.
|
||||
IACR Trans. CHES, 2024(2):213--236, 2024.
|
||||
|
||||
\bibitem{NKLO25}
|
||||
P.~Navarro-Torrero, M.~Krausz, D.~Lee, and A.~O.~Otero.
|
||||
\emph{Optimized Hardware Accelerator for ML-KEM}.
|
||||
In Proc. DATE, pp. 1--6, 2025.
|
||||
|
||||
\bibitem{XL21}
|
||||
Y.~Xing and S.~Li.
|
||||
\emph{Hardware Implementation of CRYSTALS-Kyber}.
|
||||
In Proc. FCCM, pp. 144--152, 2021.
|
||||
|
||||
\bibitem{vivado}
|
||||
Xilinx Inc.
|
||||
\emph{Vivado Design Suite User Guide: Synthesis (UG901)}.
|
||||
v2019.2, 2019.
|
||||
|
||||
\bibitem{artix7}
|
||||
Xilinx Inc.
|
||||
\emph{7 Series FPGAs Data Sheet: Overview (DS180)}.
|
||||
v2.6, 2020.
|
||||
|
||||
\end{thebibliography}
|
||||
|
||||
\end{document}
|
||||
BIN
doc/reports/mlkem_modules.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
doc/reports/system_arch.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
25
fpga/vivado_reports_nodsp/clock_interaction.rpt
Normal file
@@ -0,0 +1,25 @@
|
||||
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 : Fri Jul 10 04:14:55 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_clock_interaction -file /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/vivado_reports_nodsp/clock_interaction.rpt
|
||||
| Design : soc_top
|
||||
| Device : 7a200t-fbg676
|
||||
| Speed File : -1 PRODUCTION 1.23 2018-06-13
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Clock Interaction Report
|
||||
|
||||
Clock Interaction Table
|
||||
-----------------------
|
||||
|
||||
WNS TNS Failing TNS Total WNS Path Clock-Pair Inter-Clock
|
||||
From Clock To Clock Clock Edges WNS(ns) TNS(ns) Endpoints Endpoints Requirement(ns) Classification Constraints
|
||||
---------------- ---------------- ----------- ------- ------- ----------- ----------- --------------- ------------------- -------------------
|
||||
cpu_clk cpu_clk rise - rise 1.51 0.00 0 17264 30.32 Clean Timed
|
||||
cpu_clk sys_clk 0 154 Ignored Asynchronous Groups
|
||||
sys_clk cpu_clk 0 59 Ignored Asynchronous Groups
|
||||
sys_clk sys_clk rise - rise 0.15 0.00 0 96069 20.00 Clean Timed
|
||||
|
||||
|
||||
68
fpga/vivado_reports_nodsp/clocks.rpt
Normal file
@@ -0,0 +1,68 @@
|
||||
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 : Fri Jul 10 04:14:54 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_clocks -file /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/vivado_reports_nodsp/clocks.rpt
|
||||
| Design : soc_top
|
||||
| Device : 7a200t-fbg676
|
||||
| Speed File : -1 PRODUCTION 1.23 2018-06-13
|
||||
----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Clock Report
|
||||
|
||||
|
||||
Attributes
|
||||
P: Propagated
|
||||
G: Generated
|
||||
A: Auto-derived
|
||||
R: Renamed
|
||||
V: Virtual
|
||||
I: Inverted
|
||||
S: Pin phase-shifted with Latency mode
|
||||
|
||||
Clock Period(ns) Waveform(ns) Attributes Sources
|
||||
clk 20.000 {0.000 10.000} P {clk}
|
||||
clkfbout_clk_pll 20.000 {0.000 10.000} P,G,A {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKFBOUT}
|
||||
cpu_clk 30.323 {0.000 15.161} P,G,A,R {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKOUT0}
|
||||
sys_clk 20.000 {0.000 10.000} P,G,A,R {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKOUT1}
|
||||
|
||||
|
||||
====================================================
|
||||
Generated Clocks
|
||||
====================================================
|
||||
|
||||
Generated Clock : clkfbout_clk_pll
|
||||
Master Source : pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKIN1
|
||||
Master Clock : clk
|
||||
Multiply By : 1
|
||||
Generated Sources : {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKFBOUT}
|
||||
|
||||
Generated Clock : cpu_clk
|
||||
Master Source : pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKIN1
|
||||
Master Clock : clk
|
||||
Edges : {1 2 3}
|
||||
Edge Shifts(ns) : {0.000 5.161 10.323}
|
||||
Generated Sources : {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKOUT0}
|
||||
|
||||
Generated Clock : sys_clk
|
||||
Master Source : pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKIN1
|
||||
Master Clock : clk
|
||||
Multiply By : 1
|
||||
Generated Sources : {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKOUT1}
|
||||
|
||||
|
||||
|
||||
====================================================
|
||||
User Uncertainty
|
||||
====================================================
|
||||
|
||||
|
||||
|
||||
====================================================
|
||||
User Jitter
|
||||
====================================================
|
||||
|
||||
Clock Jitter(ns)
|
||||
clk 0.200
|
||||
|
||||
36
fpga/vivado_reports_nodsp/design_analysis_complexity.rpt
Normal file
@@ -0,0 +1,36 @@
|
||||
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 : Fri Jul 10 04:15:40 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_design_analysis -complexity -file /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/vivado_reports_nodsp/design_analysis_complexity.rpt
|
||||
| Design : soc_top
|
||||
| Device : xc7a200t
|
||||
| Design State : Routed
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Report Design Analysis
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1. Complexity Characteristics (Cells)
|
||||
|
||||
1. Complexity Characteristics (Cells)
|
||||
-------------------------------------
|
||||
|
||||
+---------------------------+---------------------+------+----------------+-----------------+-----------+-------------+--------------+--------------+--------------+--------------+------------+-----+------+------+------+
|
||||
| Instance | Module | Rent | Average Fanout | Total Instances | LUT1 | LUT2 | LUT3 | LUT4 | LUT5 | LUT6 | Memory LUT | DSP | RAMB | MUXF | URAM |
|
||||
+---------------------------+---------------------+------+----------------+-----------------+-----------+-------------+--------------+--------------+--------------+--------------+------------+-----+------+------+------+
|
||||
| (top) | soc_top | 0.31 | 3.78 | 131904 | 802(1.0%) | 9228(11.4%) | 10135(12.5%) | 10316(12.7%) | 12781(15.7%) | 37981(46.7%) | 1175 | 0 | 41 | 6069 | 0 |
|
||||
| u_axi_axil_adapter | axi_axil_adapter | 0.37 | 4.65 | 1624 | 0(0.0%) | 25(1.8%) | 36(2.6%) | 860(61.8%) | 202(14.5%) | 269(19.3%) | 0 | 0 | 0 | 62 | 0 |
|
||||
| u_axi_uart_controller | axi_uart_controller | 0.55 | 3.54 | 1296 | 10(1.2%) | 84(10.4%) | 80(9.9%) | 144(17.9%) | 194(24.1%) | 293(36.4%) | 0 | 0 | 0 | 9 | 0 |
|
||||
| u_cpu | core_top | 0.59 | 3.96 | 15822 | 168(1.8%) | 579(6.3%) | 1029(11.1%) | 871(9.4%) | 1744(18.9%) | 4860(52.5%) | 0 | 0 | 20 | 276 | 0 |
|
||||
| u_fft_mlkem_axi_slave | fft_mlkem_axi_slave | 0.41 | 3.78 | 87846 | 374(0.7%) | 6103(11.5%) | 7425(14.0%) | 6353(12.0%) | 8174(15.5%) | 24445(46.2%) | 1169 | 0 | 20 | 5269 | 0 |
|
||||
| u_matmul_axi_slave | matmul_axi_slave | 0.60 | 3.76 | 15711 | 18(0.2%) | 1632(14.3%) | 345(3.0%) | 805(7.1%) | 1733(15.2%) | 6875(60.3%) | 6 | 0 | 0 | 417 | 0 |
|
||||
| u_snix_axil_cdma_mux_8ch | snix_axil_cdma_mux | 0.46 | 3.31 | 3435 | 136(7.4%) | 239(12.9%) | 432(23.4%) | 301(16.3%) | 234(12.6%) | 508(27.5%) | 0 | 0 | 1 | 4 | 0 |
|
||||
+---------------------------+---------------------+------+----------------+-----------------+-----------+-------------+--------------+--------------+--------------+--------------+------------+-----+------+------+------+
|
||||
* Complexity Ranges
|
||||
** 0.0 - 0.3 -> Very Low, 0.3 - 0.5 -> low, 0.5 - 0.65 -> normal, 0.65 - 0.85 -> high, 0.85 - 1.0 -> very high
|
||||
*** -* -> Not computable as cell size is very small
|
||||
|
||||
|
||||
52
fpga/vivado_reports_nodsp/design_analysis_timing.rpt
Normal file
@@ -0,0 +1,52 @@
|
||||
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 : Fri Jul 10 04:15:09 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_design_analysis -timing -file /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/vivado_reports_nodsp/design_analysis_timing.rpt
|
||||
| Design : soc_top
|
||||
| Device : xc7a200t
|
||||
| Design State : Routed
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Report Design Analysis
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1. Setup Path Characteristics 1-1
|
||||
|
||||
1. Setup Path Characteristics 1-1
|
||||
---------------------------------
|
||||
|
||||
+---------------------------+----------------------------------------------------------------------------------------+
|
||||
| Characteristics | Path #1 |
|
||||
+---------------------------+----------------------------------------------------------------------------------------+
|
||||
| Requirement | 20.000 |
|
||||
| Path Delay | 15.529 |
|
||||
| Logic Delay | 6.868(45%) |
|
||||
| Net Delay | 8.661(55%) |
|
||||
| Clock Skew | -3.955 |
|
||||
| Slack | 0.146 |
|
||||
| Clock Relationship | Safely Timed |
|
||||
| Logic Levels | 14 |
|
||||
| Routes | 12 |
|
||||
| Logical Path | FDCE LUT4 LUT5 LUT6 CARRY4 CARRY4 CARRY4 CARRY4 LUT4 CARRY4 CARRY4 LUT6 LUT6 LUT6 OBUF |
|
||||
| Start Point Clock | sys_clk |
|
||||
| End Point Clock | sys_clk |
|
||||
| DSP Block | None |
|
||||
| BRAM | None |
|
||||
| IO Crossings | 3 |
|
||||
| Config Crossings | 0 |
|
||||
| SLR Crossings | 0 |
|
||||
| PBlocks | 0 |
|
||||
| High Fanout | 80 |
|
||||
| Dont Touch | 0 |
|
||||
| Mark Debug | 0 |
|
||||
| Start Point Pin Primitive | FDCE/C |
|
||||
| End Point Pin Primitive | base_ram_be_n[3] |
|
||||
| Start Point Pin | ax_req_q_len_reg[3]/C |
|
||||
| End Point Pin | base_ram_be_n[3] |
|
||||
+---------------------------+----------------------------------------------------------------------------------------+
|
||||
* Bounding box calculated as % of dimensions for the target device (436, 500)
|
||||
|
||||
|
||||
248
fpga/vivado_reports_nodsp/drc.rpt
Normal file
@@ -0,0 +1,248 @@
|
||||
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 : Fri Jul 10 04:14:40 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_drc -file /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/vivado_reports_nodsp/drc.rpt
|
||||
| Design : soc_top
|
||||
| Device : xc7a200tfbg676-1
|
||||
| Speed File : -1
|
||||
| Design State : Fully Routed
|
||||
----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Report DRC
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1. REPORT SUMMARY
|
||||
2. REPORT DETAILS
|
||||
|
||||
1. REPORT SUMMARY
|
||||
-----------------
|
||||
Netlist: netlist
|
||||
Floorplan: impl_1
|
||||
Design limits: <entire design considered>
|
||||
Ruledeck: default
|
||||
Max violations: <unlimited>
|
||||
Violations found: 42
|
||||
+-----------+----------+----------------------------+------------+
|
||||
| Rule | Severity | Description | Violations |
|
||||
+-----------+----------+----------------------------+------------+
|
||||
| CHECK-3 | Warning | Report rule limit reached | 2 |
|
||||
| REQP-1839 | Warning | RAMB36 async control check | 20 |
|
||||
| REQP-1840 | Warning | RAMB18 async control check | 20 |
|
||||
+-----------+----------+----------------------------+------------+
|
||||
|
||||
2. REPORT DETAILS
|
||||
-----------------
|
||||
CHECK-3#1 Warning
|
||||
Report rule limit reached
|
||||
REQP-1839 rule limit reached: 20 violations have been found.
|
||||
Related violations: <none>
|
||||
|
||||
CHECK-3#2 Warning
|
||||
Report rule limit reached
|
||||
REQP-1840 rule limit reached: 20 violations have been found.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#1 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[0]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#2 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[1]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#3 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[2]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#4 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[3]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#5 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[4]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#6 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[5]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#7 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[6]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#8 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[7]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#9 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[8]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#10 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[9]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#11 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[0]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#12 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[1]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#13 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[2]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#14 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[3]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#15 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[4]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#16 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[5]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#17 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[6]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#18 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[7]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#19 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[8]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#20 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[9]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#1 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[10] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[5]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#2 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[11] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[6]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#3 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[12] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[7]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#4 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[5] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[0]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#5 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[6] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[1]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#6 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[7] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[2]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#7 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[8] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[3]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#8 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[9] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[4]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#9 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[10] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[5]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#10 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[11] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[6]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#11 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[12] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[7]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#12 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[5] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[0]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#13 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[6] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[1]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#14 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[7] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[2]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#15 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[8] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[3]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#16 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[9] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[4]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#17 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ENARDEN (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg_i_1__15_n_0) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#18 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ENBWREN (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg_i_2__13_n_0) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#19 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/WEBWE[2] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_wea[0][0]_14[2]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#20 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/WEBWE[3] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_wea[0][0]_14[3]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
|
||||
221
fpga/vivado_reports_nodsp/high_fanout.rpt
Normal file
@@ -0,0 +1,221 @@
|
||||
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 : Fri Jul 10 04:14:55 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_high_fanout_nets -fanout_greater_than 100 -max_nets 200 -file /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/vivado_reports_nodsp/high_fanout.rpt
|
||||
| Design : soc_top
|
||||
| Device : xc7a200t
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
High Fan-out Nets Information
|
||||
|
||||
1. Summary
|
||||
----------
|
||||
|
||||
+---------------------------------------------------------------------------------------+--------+-------------+
|
||||
| Net Name | Fanout | Driver Type |
|
||||
+---------------------------------------------------------------------------------------+--------+-------------+
|
||||
| pll_clk.u_clk_pll/inst/sys_clk | 35652 | BUFG |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ek_bram/delay_reg[1] | 24670 | LUT5 |
|
||||
| pll_clk.u_rst_sys/p_0_in | 5108 | LUT1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt[0] | 3758 | FDCE |
|
||||
| u_matmul_axi_slave/FSM_onehot_w_state_reg[1]_0 | 2151 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/E[0] | 2048 | LUT2 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_cbd/perm_done_reg_n_0 | 1619 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/busy_r_reg_0[0] | 1608 | LUT2 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/busy_r_reg_n_0 | 1608 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/FSM_onehot_mb_state[2]_i_3_n_0 | 1604 | LUT5 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/sel_cbd | 1603 | LUT5 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/state_r[1599]_i_1_n_0 | 1601 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_snt/state_r[1599]_i_5_n_0 | 1601 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_snt/state_r[1599]_i_6_n_0 | 1601 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_snt/state_r[1599]_i_7_n_0 | 1601 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/mb_state_r[1599]_i_1_n_0 | 1600 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/addr_even[1] | 1543 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/addr_even[2] | 1542 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_active | 1130 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/busy_r_reg_1 | 1109 | LUT2 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_wb_inc_reg_n_0 | 1088 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_wb_inz_reg_n_0 | 1088 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/sha3_mb_en0 | 938 | LUT5 |
|
||||
| u_matmul_axi_slave/w_addr[2] | 873 | FDRE |
|
||||
| u_cpu/reset | 799 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/j_reg[3]_rep[0] | 769 | CARRY4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/j_reg[3]_rep[1] | 769 | CARRY4 |
|
||||
| u_cpu/u_mul/E[0] | 716 | LUT1 |
|
||||
| u_matmul_axi_slave/w_addr[4] | 655 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/m_r1 | 525 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_phase_reg_n_0_[1] | 518 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_phase_reg_n_0_[0] | 515 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/squeezed_state_r0 | 512 | LUT2 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/st_reg[3]_0[0] | 512 | LUT5 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/j_reg[3]_rep[2] | 385 | CARRY4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_wb_vld_reg_n_0 | 370 | FDCE |
|
||||
| u_cpu/wb_stage/w_index[0] | 358 | LUT6 |
|
||||
| u_cpu/wb_stage/w_index[1] | 358 | LUT6 |
|
||||
| u_cpu/wb_stage/w_index[2] | 358 | LUT6 |
|
||||
| u_cpu/wb_stage/w_index[3] | 358 | LUT6 |
|
||||
| u_cpu/wb_stage/w_index[4] | 358 | LUT6 |
|
||||
| u_matmul_axi_slave/acc_idx_d4[0] | 354 | FDRE |
|
||||
| u_matmul_axi_slave/acc_idx_d4[1] | 354 | FDRE |
|
||||
| u_matmul_axi_slave/acc_idx_d4[2] | 354 | FDRE |
|
||||
| u_matmul_axi_slave/acc_idx_d4[3] | 354 | FDRE |
|
||||
| u_cpu/wb_stage/we_0 | 324 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/rho_r1 | 293 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/hek_r2[4] | 288 | CARRY4 |
|
||||
| u_matmul_axi_slave/cur_bank_reg_n_0 | 274 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/cbd_enc | 261 | LUT5 |
|
||||
| u_matmul_axi_slave/sel0[1] | 259 | FDRE |
|
||||
| u_matmul_axi_slave/b1_b_reg[0][31]_i_8_n_7 | 258 | CARRY4 |
|
||||
| u_matmul_axi_slave/pipe_cnt_reg[0]_rep_n_0 | 258 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[0] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[10] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[11] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[1] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[2] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[3] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[4] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[5] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[6] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[7] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[8] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[9] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[0] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[10] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[11] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[1] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[2] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[3] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[4] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[5] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[6] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[7] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[8] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[9] | 256 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/dj_phase_reg[1]_0[0] | 256 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/mb_digest_r | 256 | LUT3 |
|
||||
| u_matmul_axi_slave/m_in_a[3][31]_i_1_n_0 | 256 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/sha3_mode | 250 | LUT4 |
|
||||
| u_snix_axil_cdma_mux_8ch/u_core_engine/wr_start_edge | 245 | LUT2 |
|
||||
| u_matmul_axi_slave/b0_a[6][25]_i_2_n_0 | 242 | LUT2 |
|
||||
| u_matmul_axi_slave/acc_bank_d2_reg_srl2___u_matmul_axi_slave_acc_idx_d2_reg_r_i_2_n_0 | 239 | LUT3 |
|
||||
| u_matmul_axi_slave/m_in_a[3][30]_i_6_n_0 | 238 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wb_r[6] | 237 | FDCE |
|
||||
| u_cpu/exe_stage/ds_to_es_bus_r0 | 234 | LUT5 |
|
||||
| u_cpu/mem_stage/E[0] | 234 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wb_r[3] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[1022]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[126]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[254]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[382]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[510]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[638]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[766]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[894]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[0] | 219 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[10] | 219 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[11] | 219 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[1] | 219 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[2] | 219 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[3] | 219 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[4] | 219 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[5] | 219 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[6] | 219 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[7] | 219 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[8] | 219 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[9] | 219 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wb_r[5] | 219 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[10] | 216 | RAMB18E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[11] | 216 | RAMB18E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[8] | 215 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wb_r[2] | 215 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[7] | 214 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[9] | 214 | RAMB18E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wb_r[4] | 214 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[0] | 212 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[1] | 212 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[2] | 212 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[3] | 212 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[4] | 212 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[5] | 212 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[6] | 212 | RAMB36E1 |
|
||||
| u_axi_axil_adapter/axi_axil_adapter_wr_inst/delay_reg[1]_0 | 211 | LUT2 |
|
||||
| u_cpu/mem_stage/es_to_ms_bus_r0 | 210 | LUT2 |
|
||||
| u_cpu/u_csr/tlbw_r_tlbidx[2] | 210 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wb_r[7] | 207 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wb_r[1] | 206 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_snt/grp_ptr_r_reg_n_0_[2] | 196 | FDCE |
|
||||
| u_cpu/wb_stage/Q[33] | 194 | FDRE |
|
||||
| u_cpu/wb_stage/Q[34] | 194 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_cbd/buf_ptr_reg_n_0_[5] | 194 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/j_reg[3]_rep[3] | 193 | CARRY4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/w_addr_reg_n_0_[3] | 187 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt[2] | 186 | FDCE |
|
||||
| u_cpu/wb_stage/ws_valid_reg_0 | 180 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/p_0_in[2] | 180 | FDCE |
|
||||
| u_matmul_axi_slave/b0_b_reg[1][30]_i_4_n_7 | 178 | CARRY4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/st[4] | 176 | FDCE |
|
||||
| u_matmul_axi_slave/p_0_in__0 | 176 | LUT4 |
|
||||
| u_matmul_axi_slave/p_0_in__0__0 | 176 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt114_out | 175 | LUT2 |
|
||||
| u_cpu/wb_stage/Q[37] | 173 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt_reg[5]_rep__0_n_0 | 172 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/mem_B[131][11]_i_4_n_0 | 171 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_block_r[127]_i_2_n_0 | 169 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_block_r[383]_i_2_n_0 | 169 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_block_r[639]_i_2_n_0 | 169 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_block_r[895]_i_2_n_0 | 169 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/hek_r2[3] | 169 | CARRY4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/mem_B[74][11]_i_4_n_0 | 168 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/w_addr_reg[6]_0[0] | 168 | CARRY4 |
|
||||
| u_axi_axil_adapter/axi_axil_adapter_wr_inst/m_axil_awaddr_reg_reg[6]_0 | 167 | LUT2 |
|
||||
| u_axi_axil_adapter/axi_axil_adapter_wr_inst/m_axil_awaddr_reg_reg[6]_1 | 167 | LUT2 |
|
||||
| u_snix_axil_cdma_mux_8ch/ADDRA[0] | 167 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/mem_A[129][11]_i_3_n_0 | 166 | LUT3 |
|
||||
| u_matmul_axi_slave/FSM_onehot_w_state_reg[2]_rep__0_n_0 | 165 | FDRE |
|
||||
| u_cpu/wb_stage/Q[32] | 164 | FDRE |
|
||||
| u_cpu/wb_stage/Q[35] | 163 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_phase_reg[0]_rep__0_n_0 | 163 | FDCE |
|
||||
| u_cpu/wb_stage/Q[36] | 162 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_block_r[1023]_i_2_n_0 | 160 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_block_r[255]_i_2_n_0 | 160 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_block_r[511]_i_2_n_0 | 160 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_block_r[767]_i_2_n_0 | 160 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt_reg[2]_rep__12_n_0 | 158 | FDCE |
|
||||
| u_matmul_axi_slave/w_addr_reg[3]_rep__2_0 | 158 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/cr[181][5]_i_3_n_0 | 157 | LUT2 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt[6] | 156 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/p_0_in[3] | 155 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt[7] | 155 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wa_r[3] | 154 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wa_r[4] | 154 | FDCE |
|
||||
| u_matmul_axi_slave/w_addr[3] | 153 | FDRE |
|
||||
| u_cpu/axi_bridge/FSM_sequential_write_requst_state_reg[1]_0 | 151 | FDRE |
|
||||
| u_snix_axil_cdma_mux_8ch/u_core_engine/num_bytes_comb1 | 150 | CARRY4 |
|
||||
| u_cpu/dcache/awaddr[31]_i_3_n_0 | 148 | LUT2 |
|
||||
| u_cpu/dcache/awaddr[31]_i_4_n_0 | 148 | LUT2 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wa_r[1] | 148 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/mem_B[202][11]_i_3_n_0 | 148 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wa_r[0] | 147 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt_reg[1]_rep__1_n_0 | 146 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt_reg[1]_rep_n_0 | 146 | FDCE |
|
||||
| u_matmul_axi_slave/pipe_cnt[3]_i_2_n_0 | 146 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_wb_idx_reg_n_0_[0] | 145 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt_reg[1]_rep__10_n_0 | 145 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wa_r[2] | 144 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/hek_r[247]_i_3_n_0 | 144 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/hek_r[255]_i_3_n_0 | 144 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt_reg[2]_rep__17_n_0 | 143 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/mem_B[106][11]_i_3_n_0 | 143 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/men_idx[6] | 142 | FDCE |
|
||||
| u_matmul_axi_slave/FSM_onehot_w_state_reg_n_0_[0] | 142 | FDSE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wa_r[5] | 141 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt[5] | 141 | FDCE |
|
||||
| u_cpu/dcache/write_buffer_state | 140 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/men_idx[4] | 140 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/men_idx[5] | 140 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/men_idx[7] | 140 | FDCE |
|
||||
+---------------------------------------------------------------------------------------+--------+-------------+
|
||||
|
||||
|
||||
582
fpga/vivado_reports_nodsp/methodology.rpt
Normal file
@@ -0,0 +1,582 @@
|
||||
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 : Fri Jul 10 04:14:46 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_methodology -file /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/vivado_reports_nodsp/methodology.rpt
|
||||
| Design : soc_top
|
||||
| Device : xc7a200tfbg676-1
|
||||
| Speed File : -1
|
||||
| Design State : Fully Routed
|
||||
--------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Report Methodology
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1. REPORT SUMMARY
|
||||
2. REPORT DETAILS
|
||||
|
||||
1. REPORT SUMMARY
|
||||
-----------------
|
||||
Netlist: netlist
|
||||
Floorplan: impl_1
|
||||
Design limits: <entire design considered>
|
||||
Max violations: <unlimited>
|
||||
Violations found: 107
|
||||
+-----------+----------+-------------------------------------------------------------------+------------+
|
||||
| Rule | Severity | Description | Violations |
|
||||
+-----------+----------+-------------------------------------------------------------------+------------+
|
||||
| LUTAR-1 | Warning | LUT drives async reset alert | 1 |
|
||||
| SYNTH-5 | Warning | Mapped onto distributed RAM because of timing constraints | 8 |
|
||||
| SYNTH-6 | Warning | Timing of a block RAM might be sub-optimal | 9 |
|
||||
| SYNTH-16 | Warning | Address collision | 8 |
|
||||
| TIMING-10 | Warning | Missing property on synchronizer | 1 |
|
||||
| TIMING-18 | Warning | Missing input or output delay | 76 |
|
||||
| TIMING-47 | Warning | False path or asynchronous clock group between synchronous clocks | 2 |
|
||||
| XDCC-1 | Warning | Scoped Clock constraint overwritten with the same name | 1 |
|
||||
| XDCC-7 | Warning | Scoped Clock constraint overwritten on the same source | 1 |
|
||||
+-----------+----------+-------------------------------------------------------------------+------------+
|
||||
|
||||
2. REPORT DETAILS
|
||||
-----------------
|
||||
LUTAR-1#1 Warning
|
||||
LUT drives async reset alert
|
||||
LUT cell u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ek_bram/p_s1[23]_i_9, with 2 or more inputs, drives asynchronous preset/clear pin(s) u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_busy_reg/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_i_reg[0]/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_i_reg[1]/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_i_reg[2]/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_j_reg[0]/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_j_reg[1]/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_j_reg[2]/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_pair_reg[0]/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_pair_reg[1]/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_pair_reg[2]/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_pair_reg[3]/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_pair_reg[4]/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_widx_reg[0]/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_widx_reg[1]/CLR, u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/a_widx_reg[2]/CLR (the first 15 of 24656 listed). The LUT may glitch and trigger an unexpected reset, even if it is a properly timed path.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-5#1 Warning
|
||||
Mapped onto distributed RAM because of timing constraints
|
||||
The instance u_cpu/dcache/way_d_reg_reg_r1_0_127_0_0 is implemented as distributed LUT RAM for the following reason: The timing constraints suggest that the chosen mapping will yield a better timing.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-5#2 Warning
|
||||
Mapped onto distributed RAM because of timing constraints
|
||||
The instance u_cpu/dcache/way_d_reg_reg_r1_0_127_1_1 is implemented as distributed LUT RAM for the following reason: The timing constraints suggest that the chosen mapping will yield a better timing.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-5#3 Warning
|
||||
Mapped onto distributed RAM because of timing constraints
|
||||
The instance u_cpu/dcache/way_d_reg_reg_r1_128_255_0_0 is implemented as distributed LUT RAM for the following reason: The timing constraints suggest that the chosen mapping will yield a better timing.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-5#4 Warning
|
||||
Mapped onto distributed RAM because of timing constraints
|
||||
The instance u_cpu/dcache/way_d_reg_reg_r1_128_255_1_1 is implemented as distributed LUT RAM for the following reason: The timing constraints suggest that the chosen mapping will yield a better timing.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-5#5 Warning
|
||||
Mapped onto distributed RAM because of timing constraints
|
||||
The instance u_cpu/dcache/way_d_reg_reg_r2_0_127_0_0 is implemented as distributed LUT RAM for the following reason: The timing constraints suggest that the chosen mapping will yield a better timing.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-5#6 Warning
|
||||
Mapped onto distributed RAM because of timing constraints
|
||||
The instance u_cpu/dcache/way_d_reg_reg_r2_0_127_1_1 is implemented as distributed LUT RAM for the following reason: The timing constraints suggest that the chosen mapping will yield a better timing.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-5#7 Warning
|
||||
Mapped onto distributed RAM because of timing constraints
|
||||
The instance u_cpu/dcache/way_d_reg_reg_r2_128_255_0_0 is implemented as distributed LUT RAM for the following reason: The timing constraints suggest that the chosen mapping will yield a better timing.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-5#8 Warning
|
||||
Mapped onto distributed RAM because of timing constraints
|
||||
The instance u_cpu/dcache/way_d_reg_reg_r2_128_255_1_1 is implemented as distributed LUT RAM for the following reason: The timing constraints suggest that the chosen mapping will yield a better timing.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-6#1 Warning
|
||||
Timing of a block RAM might be sub-optimal
|
||||
The timing for the instance u_cpu/icache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg, implemented as a block RAM, might be sub-optimal as no output register was merged into the block
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-6#2 Warning
|
||||
Timing of a block RAM might be sub-optimal
|
||||
The timing for the instance u_cpu/icache/data_ram_way[0].data_ram_bank[1].u/mem_reg_reg, implemented as a block RAM, might be sub-optimal as no output register was merged into the block
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-6#3 Warning
|
||||
Timing of a block RAM might be sub-optimal
|
||||
The timing for the instance u_cpu/icache/data_ram_way[0].data_ram_bank[2].u/mem_reg_reg, implemented as a block RAM, might be sub-optimal as no output register was merged into the block
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-6#4 Warning
|
||||
Timing of a block RAM might be sub-optimal
|
||||
The timing for the instance u_cpu/icache/data_ram_way[0].data_ram_bank[3].u/mem_reg_reg, implemented as a block RAM, might be sub-optimal as no output register was merged into the block
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-6#5 Warning
|
||||
Timing of a block RAM might be sub-optimal
|
||||
The timing for the instance u_cpu/icache/data_ram_way[1].data_ram_bank[0].u/mem_reg_reg, implemented as a block RAM, might be sub-optimal as no output register was merged into the block
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-6#6 Warning
|
||||
Timing of a block RAM might be sub-optimal
|
||||
The timing for the instance u_cpu/icache/data_ram_way[1].data_ram_bank[1].u/mem_reg_reg, implemented as a block RAM, might be sub-optimal as no output register was merged into the block
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-6#7 Warning
|
||||
Timing of a block RAM might be sub-optimal
|
||||
The timing for the instance u_cpu/icache/data_ram_way[1].data_ram_bank[2].u/mem_reg_reg, implemented as a block RAM, might be sub-optimal as no output register was merged into the block
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-6#8 Warning
|
||||
Timing of a block RAM might be sub-optimal
|
||||
The timing for the instance u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/mem_reg_0, implemented as a block RAM, might be sub-optimal as no output register was merged into the block
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-6#9 Warning
|
||||
Timing of a block RAM might be sub-optimal
|
||||
The timing for the instance u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/mem_reg, implemented as a block RAM, might be sub-optimal as no output register was merged into the block
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-16#1 Warning
|
||||
Address collision
|
||||
Block RAM u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/mem_reg_0 may get memory collision error if read and write address collide. Use of address collision resolution circuitry is recommended.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-16#2 Warning
|
||||
Address collision
|
||||
Block RAM u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/mem_reg_1 may get memory collision error if read and write address collide. Use of address collision resolution circuitry is recommended.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-16#3 Warning
|
||||
Address collision
|
||||
Block RAM u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/mem_reg may get memory collision error if read and write address collide. Use of address collision resolution circuitry is recommended.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-16#4 Warning
|
||||
Address collision
|
||||
Block RAM u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_t/mem_reg may get memory collision error if read and write address collide. Use of address collision resolution circuitry is recommended.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-16#5 Warning
|
||||
Address collision
|
||||
Block RAM u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_c_in_bram/mem_reg may get memory collision error if read and write address collide. Use of address collision resolution circuitry is recommended.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-16#6 Warning
|
||||
Address collision
|
||||
Block RAM u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ct_bram/mem_reg may get memory collision error if read and write address collide. Use of address collision resolution circuitry is recommended.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-16#7 Warning
|
||||
Address collision
|
||||
Block RAM u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_dkp_bram/mem_reg may get memory collision error if read and write address collide. Use of address collision resolution circuitry is recommended.
|
||||
Related violations: <none>
|
||||
|
||||
SYNTH-16#8 Warning
|
||||
Address collision
|
||||
Block RAM u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ek_bram/mem_reg may get memory collision error if read and write address collide. Use of address collision resolution circuitry is recommended.
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-10#1 Warning
|
||||
Missing property on synchronizer
|
||||
One or more logic synchronizer has been detected between 2 clock domains but the synchronizer does not have the property ASYNC_REG defined on one or both registers. It is recommended to run report_cdc for a complete and detailed CDC coverage
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#1 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on UART_RX relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#2 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on UART_TX relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#3 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[0] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#4 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[10] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#5 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[11] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#6 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[12] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#7 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[13] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#8 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[14] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#9 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[15] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#10 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[16] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#11 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[17] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#12 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[18] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#13 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[19] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#14 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[1] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#15 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[20] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#16 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[21] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#17 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[22] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#18 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[23] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#19 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[24] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#20 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[25] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#21 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[26] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#22 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[27] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#23 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[28] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#24 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[29] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#25 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[2] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#26 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[30] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#27 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[31] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#28 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[3] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#29 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[4] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#30 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[5] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#31 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[6] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#32 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[7] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#33 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[8] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#34 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on dip_sw[9] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#35 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on touch_btn[0] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#36 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on touch_btn[1] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#37 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on touch_btn[2] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#38 Warning
|
||||
Missing input or output delay
|
||||
An input delay is missing on touch_btn[3] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#39 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy0[0] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#40 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy0[1] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#41 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy0[2] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#42 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy0[3] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#43 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy0[4] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#44 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy0[5] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#45 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy0[6] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#46 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy0[7] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#47 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy1[0] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#48 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy1[1] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#49 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy1[2] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#50 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy1[3] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#51 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy1[4] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#52 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy1[5] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#53 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy1[6] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#54 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on dpy1[7] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#55 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[0] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#56 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[10] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#57 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[11] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#58 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[12] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#59 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[13] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#60 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[14] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#61 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[15] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#62 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[1] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#63 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[2] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#64 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[3] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#65 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[4] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#66 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[5] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#67 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[6] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#68 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[7] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#69 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[8] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#70 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on leds[9] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#71 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on video_de relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#72 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on video_hsync relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#73 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on video_red[0] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#74 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on video_red[1] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#75 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on video_red[2] relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-18#76 Warning
|
||||
Missing input or output delay
|
||||
An output delay is missing on video_vsync relative to clock(s) clk
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-47#1 Warning
|
||||
False path or asynchronous clock group between synchronous clocks
|
||||
A Clock Group timing constraint is set between synchronous clocks cpu_clk and sys_clk (see constraint position 6 in the Timing Constraint window in Vivado IDE). It is not recommended to cover synchronous clock domains with constraints that prevent timing analysis as the design could fail in hardware.
|
||||
Related violations: <none>
|
||||
|
||||
TIMING-47#2 Warning
|
||||
False path or asynchronous clock group between synchronous clocks
|
||||
A Clock Group timing constraint is set between synchronous clocks sys_clk and cpu_clk (see constraint position 6 in the Timing Constraint window in Vivado IDE). It is not recommended to cover synchronous clock domains with constraints that prevent timing analysis as the design could fail in hardware.
|
||||
Related violations: <none>
|
||||
|
||||
XDCC-1#1 Warning
|
||||
Scoped Clock constraint overwritten with the same name
|
||||
A new clock constraint create_clock overrides a previous scoped clock constraint with the same name. It is not recommended to override a scoped (typically an IP) clock constraint and could result in unexpected behaviors.
|
||||
New: create_clock -period 20.000 -name clk -waveform {0.000 10.000} [get_ports clk] (Source: /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/constraints/soc.xdc (Line: 4))
|
||||
Previous: create_clock -period 20.000 [get_ports clk] (Source: /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/project/ipgen/clk_pll/clk_pll.xdc (Line: 56))
|
||||
Related violations: <none>
|
||||
|
||||
XDCC-7#1 Warning
|
||||
Scoped Clock constraint overwritten on the same source
|
||||
A new clock constraint create_clock overrides a previous scoped clock constraint defined on the same source. It is not recommended to override a scoped (typically an IP) clock constraint and could result in unexpected behaviors.
|
||||
New: create_clock -period 20.000 -name clk -waveform {0.000 10.000} [get_ports clk] (Source: /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/constraints/soc.xdc (Line: 4))
|
||||
Previous: create_clock -period 20.000 [get_ports clk] (Source: /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/project/ipgen/clk_pll/clk_pll.xdc (Line: 56))
|
||||
Related violations: <none>
|
||||
|
||||
|
||||
8692
fpga/vivado_reports_nodsp/mlkem_clk_timing.rpt
Normal file
181
fpga/vivado_reports_nodsp/power.rpt
Normal file
@@ -0,0 +1,181 @@
|
||||
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 : Fri Jul 10 04:15:05 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_power -file /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/vivado_reports_nodsp/power.rpt
|
||||
| Design : soc_top
|
||||
| Device : xc7a200tfbg676-1
|
||||
| Design State : routed
|
||||
| Grade : commercial
|
||||
| Process : typical
|
||||
| Characterization : Production
|
||||
--------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Power Report
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1. Summary
|
||||
1.1 On-Chip Components
|
||||
1.2 Power Supply Summary
|
||||
1.3 Confidence Level
|
||||
2. Settings
|
||||
2.1 Environment
|
||||
2.2 Clock Constraints
|
||||
3. Detailed Reports
|
||||
3.1 By Hierarchy
|
||||
|
||||
1. Summary
|
||||
----------
|
||||
|
||||
+--------------------------+--------------+
|
||||
| Total On-Chip Power (W) | 0.686 |
|
||||
| Design Power Budget (W) | Unspecified* |
|
||||
| Power Budget Margin (W) | NA |
|
||||
| Dynamic (W) | 0.545 |
|
||||
| Device Static (W) | 0.141 |
|
||||
| Effective TJA (C/W) | 1.9 |
|
||||
| Max Ambient (C) | 83.7 |
|
||||
| Junction Temperature (C) | 26.3 |
|
||||
| Confidence Level | Low |
|
||||
| Setting File | --- |
|
||||
| Simulation Activity File | --- |
|
||||
| Design Nets Matched | NA |
|
||||
+--------------------------+--------------+
|
||||
* Specify Design Power Budget using, set_operating_conditions -design_power_budget <value in Watts>
|
||||
|
||||
|
||||
1.1 On-Chip Components
|
||||
----------------------
|
||||
|
||||
+--------------------------+-----------+----------+-----------+-----------------+
|
||||
| On-Chip | Power (W) | Used | Available | Utilization (%) |
|
||||
+--------------------------+-----------+----------+-----------+-----------------+
|
||||
| Clocks | 0.056 | 6 | --- | --- |
|
||||
| Slice Logic | 0.109 | 133224 | --- | --- |
|
||||
| LUT as Logic | 0.102 | 75460 | 133800 | 56.40 |
|
||||
| CARRY4 | 0.003 | 3546 | 33450 | 10.60 |
|
||||
| LUT as Distributed RAM | 0.002 | 628 | 46200 | 1.36 |
|
||||
| Register | 0.001 | 39690 | 267600 | 14.83 |
|
||||
| LUT as Shift Register | <0.001 | 1175 | 46200 | 2.54 |
|
||||
| F7/F8 Muxes | <0.001 | 6085 | 133800 | 4.55 |
|
||||
| Others | 0.000 | 289 | --- | --- |
|
||||
| Signals | 0.194 | 93202 | --- | --- |
|
||||
| Block RAM | 0.019 | 25.5 | 365 | 6.99 |
|
||||
| PLL | 0.137 | 1 | 10 | 10.00 |
|
||||
| I/O | 0.029 | 202 | 400 | 50.50 |
|
||||
| Static Power | 0.141 | | | |
|
||||
| Total | 0.686 | | | |
|
||||
+--------------------------+-----------+----------+-----------+-----------------+
|
||||
|
||||
|
||||
1.2 Power Supply Summary
|
||||
------------------------
|
||||
|
||||
+-----------+-------------+-----------+-------------+------------+
|
||||
| Source | Voltage (V) | Total (A) | Dynamic (A) | Static (A) |
|
||||
+-----------+-------------+-----------+-------------+------------+
|
||||
| Vccint | 1.000 | 0.423 | 0.391 | 0.032 |
|
||||
| Vccaux | 1.800 | 0.101 | 0.070 | 0.031 |
|
||||
| Vcco33 | 3.300 | 0.013 | 0.008 | 0.005 |
|
||||
| Vcco25 | 2.500 | 0.000 | 0.000 | 0.000 |
|
||||
| Vcco18 | 1.800 | 0.000 | 0.000 | 0.000 |
|
||||
| Vcco15 | 1.500 | 0.000 | 0.000 | 0.000 |
|
||||
| Vcco135 | 1.350 | 0.000 | 0.000 | 0.000 |
|
||||
| Vcco12 | 1.200 | 0.000 | 0.000 | 0.000 |
|
||||
| Vccaux_io | 1.800 | 0.000 | 0.000 | 0.000 |
|
||||
| Vccbram | 1.000 | 0.003 | 0.001 | 0.001 |
|
||||
| MGTAVcc | 1.000 | 0.000 | 0.000 | 0.000 |
|
||||
| MGTAVtt | 1.200 | 0.000 | 0.000 | 0.000 |
|
||||
| Vccadc | 1.800 | 0.020 | 0.000 | 0.020 |
|
||||
+-----------+-------------+-----------+-------------+------------+
|
||||
|
||||
|
||||
1.3 Confidence Level
|
||||
--------------------
|
||||
|
||||
+-----------------------------+------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------+
|
||||
| User Input Data | Confidence | Details | Action |
|
||||
+-----------------------------+------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------+
|
||||
| Design implementation state | High | Design is routed | |
|
||||
| Clock nodes activity | High | User specified more than 95% of clocks | |
|
||||
| I/O nodes activity | Low | More than 75% of inputs are missing user specification | Provide missing input activity with simulation results or by editing the "By Resource Type -> I/Os" view |
|
||||
| Internal nodes activity | Medium | User specified less than 25% of internal nodes | Provide missing internal nodes activity with simulation results or by editing the "By Resource Type" views |
|
||||
| Device models | High | Device models are Production | |
|
||||
| | | | |
|
||||
| Overall confidence level | Low | | |
|
||||
+-----------------------------+------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
2. Settings
|
||||
-----------
|
||||
|
||||
2.1 Environment
|
||||
---------------
|
||||
|
||||
+-----------------------+--------------------------+
|
||||
| Ambient Temp (C) | 25.0 |
|
||||
| ThetaJA (C/W) | 1.9 |
|
||||
| Airflow (LFM) | 250 |
|
||||
| Heat Sink | medium (Medium Profile) |
|
||||
| ThetaSA (C/W) | 3.4 |
|
||||
| Board Selection | medium (10"x10") |
|
||||
| # of Board Layers | 12to15 (12 to 15 Layers) |
|
||||
| Board Temperature (C) | 25.0 |
|
||||
+-----------------------+--------------------------+
|
||||
|
||||
|
||||
2.2 Clock Constraints
|
||||
---------------------
|
||||
|
||||
+------------------+-----------------------------------------+-----------------+
|
||||
| Clock | Domain | Constraint (ns) |
|
||||
+------------------+-----------------------------------------+-----------------+
|
||||
| clk | clk | 20.0 |
|
||||
| clkfbout_clk_pll | pll_clk.u_clk_pll/inst/clkfbout_clk_pll | 20.0 |
|
||||
| cpu_clk | pll_clk.u_clk_pll/inst/cpu_clk_clk_pll | 30.3 |
|
||||
| sys_clk | pll_clk.u_clk_pll/inst/sys_clk_clk_pll | 20.0 |
|
||||
+------------------+-----------------------------------------+-----------------+
|
||||
|
||||
|
||||
3. Detailed Reports
|
||||
-------------------
|
||||
|
||||
3.1 By Hierarchy
|
||||
----------------
|
||||
|
||||
+----------------------------+-----------+
|
||||
| Name | Power (W) |
|
||||
+----------------------------+-----------+
|
||||
| soc_top | 0.545 |
|
||||
| pll_clk.u_clk_pll | 0.138 |
|
||||
| inst | 0.138 |
|
||||
| u_Axi_CDC | 0.003 |
|
||||
| u_axi_uart_controller | 0.002 |
|
||||
| u_cpu | 0.025 |
|
||||
| addr_trans | 0.002 |
|
||||
| tlb_entry | 0.002 |
|
||||
| btb | 0.003 |
|
||||
| dcache | 0.006 |
|
||||
| icache | 0.005 |
|
||||
| u_csr | 0.001 |
|
||||
| u_mul | 0.004 |
|
||||
| u_fft_mlkem_axi_slave | 0.251 |
|
||||
| u_fft_controller | 0.030 |
|
||||
| u_FFT | 0.027 |
|
||||
| u_out0 | 0.001 |
|
||||
| u_out1 | 0.001 |
|
||||
| u_mlkem_axi_slave | 0.221 |
|
||||
| u_mlkem | 0.218 |
|
||||
| u_matmul_axi_slave | 0.081 |
|
||||
| mult_inst[0].u_mult | 0.003 |
|
||||
| mult_inst[1].u_mult | 0.002 |
|
||||
| mult_inst[2].u_mult | 0.002 |
|
||||
| mult_inst[3].u_mult | 0.002 |
|
||||
| u_snix_axil_cdma_mux_8ch | 0.008 |
|
||||
| u_core_engine | 0.004 |
|
||||
| axis_fifo_u0 | 0.003 |
|
||||
+----------------------------+-----------+
|
||||
|
||||
|
||||
12
fpga/vivado_reports_nodsp/route_status.rpt
Normal file
@@ -0,0 +1,12 @@
|
||||
Design Route Status
|
||||
: # nets :
|
||||
------------------------------------------- : ----------- :
|
||||
# of logical nets.......................... : 144034 :
|
||||
# of nets not needing routing.......... : 50823 :
|
||||
# of internally routed nets........ : 50442 :
|
||||
# of nets with no loads............ : 381 :
|
||||
# of routable nets..................... : 93211 :
|
||||
# of fully routed nets............. : 93211 :
|
||||
# of nets with routing errors.......... : 0 :
|
||||
------------------------------------------- : ----------- :
|
||||
|
||||
12240
fpga/vivado_reports_nodsp/timing_hold_paths.rpt
Normal file
26092
fpga/vivado_reports_nodsp/timing_setup_paths.rpt
Normal file
25200
fpga/vivado_reports_nodsp/timing_summary_full.rpt
Normal file
19923
fpga/vivado_reports_nodsp/timing_summary_hold_full.rpt
Normal file
235
fpga/vivado_reports_nodsp/utilization.rpt
Normal file
@@ -0,0 +1,235 @@
|
||||
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 : Fri Jul 10 04:14:47 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_utilization -file /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/vivado_reports_nodsp/utilization.rpt
|
||||
| Design : soc_top
|
||||
| Device : 7a200tfbg676-1
|
||||
| Design State : Routed
|
||||
--------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Utilization Design Information
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1. Slice Logic
|
||||
1.1 Summary of Registers by Type
|
||||
2. Slice Logic Distribution
|
||||
3. Memory
|
||||
4. DSP
|
||||
5. IO and GT Specific
|
||||
6. Clocking
|
||||
7. Specific Feature
|
||||
8. Primitives
|
||||
9. Black Boxes
|
||||
10. Instantiated Netlists
|
||||
|
||||
1. Slice Logic
|
||||
--------------
|
||||
|
||||
+----------------------------+-------+-------+-----------+-------+
|
||||
| Site Type | Used | Fixed | Available | Util% |
|
||||
+----------------------------+-------+-------+-----------+-------+
|
||||
| Slice LUTs | 71196 | 0 | 133800 | 53.21 |
|
||||
| LUT as Logic | 69453 | 0 | 133800 | 51.91 |
|
||||
| LUT as Memory | 1743 | 0 | 46200 | 3.77 |
|
||||
| LUT as Distributed RAM | 628 | 0 | | |
|
||||
| LUT as Shift Register | 1115 | 0 | | |
|
||||
| Slice Registers | 39690 | 0 | 267600 | 14.83 |
|
||||
| Register as Flip Flop | 39690 | 0 | 267600 | 14.83 |
|
||||
| Register as Latch | 0 | 0 | 267600 | 0.00 |
|
||||
| F7 Muxes | 4565 | 0 | 66900 | 6.82 |
|
||||
| F8 Muxes | 1520 | 0 | 33450 | 4.54 |
|
||||
+----------------------------+-------+-------+-----------+-------+
|
||||
|
||||
|
||||
1.1 Summary of Registers by Type
|
||||
--------------------------------
|
||||
|
||||
+-------+--------------+-------------+--------------+
|
||||
| Total | Clock Enable | Synchronous | Asynchronous |
|
||||
+-------+--------------+-------------+--------------+
|
||||
| 0 | _ | - | - |
|
||||
| 0 | _ | - | Set |
|
||||
| 0 | _ | - | Reset |
|
||||
| 0 | _ | Set | - |
|
||||
| 0 | _ | Reset | - |
|
||||
| 0 | Yes | - | - |
|
||||
| 24 | Yes | - | Set |
|
||||
| 26562 | Yes | - | Reset |
|
||||
| 139 | Yes | Set | - |
|
||||
| 12965 | Yes | Reset | - |
|
||||
+-------+--------------+-------------+--------------+
|
||||
|
||||
|
||||
2. Slice Logic Distribution
|
||||
---------------------------
|
||||
|
||||
+--------------------------------------------+-------+-------+-----------+-------+
|
||||
| Site Type | Used | Fixed | Available | Util% |
|
||||
+--------------------------------------------+-------+-------+-----------+-------+
|
||||
| Slice | 21289 | 0 | 33450 | 63.64 |
|
||||
| SLICEL | 13965 | 0 | | |
|
||||
| SLICEM | 7324 | 0 | | |
|
||||
| LUT as Logic | 69453 | 0 | 133800 | 51.91 |
|
||||
| using O5 output only | 2 | | | |
|
||||
| using O6 output only | 57661 | | | |
|
||||
| using O5 and O6 | 11790 | | | |
|
||||
| LUT as Memory | 1743 | 0 | 46200 | 3.77 |
|
||||
| LUT as Distributed RAM | 628 | 0 | | |
|
||||
| using O5 output only | 0 | | | |
|
||||
| using O6 output only | 60 | | | |
|
||||
| using O5 and O6 | 568 | | | |
|
||||
| LUT as Shift Register | 1115 | 0 | | |
|
||||
| using O5 output only | 47 | | | |
|
||||
| using O6 output only | 1008 | | | |
|
||||
| using O5 and O6 | 60 | | | |
|
||||
| Slice Registers | 39690 | 0 | 267600 | 14.83 |
|
||||
| Register driven from within the Slice | 24917 | | | |
|
||||
| Register driven from outside the Slice | 14773 | | | |
|
||||
| LUT in front of the register is unused | 6243 | | | |
|
||||
| LUT in front of the register is used | 8530 | | | |
|
||||
| Unique Control Sets | 1278 | | 33450 | 3.82 |
|
||||
+--------------------------------------------+-------+-------+-----------+-------+
|
||||
* Note: Available Control Sets calculated as Slice Registers / 8, Review the Control Sets Report for more information regarding control sets.
|
||||
|
||||
|
||||
3. Memory
|
||||
---------
|
||||
|
||||
+-------------------+------+-------+-----------+-------+
|
||||
| Site Type | Used | Fixed | Available | Util% |
|
||||
+-------------------+------+-------+-----------+-------+
|
||||
| Block RAM Tile | 25.5 | 0 | 365 | 6.99 |
|
||||
| RAMB36/FIFO* | 10 | 0 | 365 | 2.74 |
|
||||
| RAMB36E1 only | 10 | | | |
|
||||
| RAMB18 | 31 | 0 | 730 | 4.25 |
|
||||
| RAMB18E1 only | 31 | | | |
|
||||
+-------------------+------+-------+-----------+-------+
|
||||
* 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
|
||||
|
||||
|
||||
4. DSP
|
||||
------
|
||||
|
||||
+-----------+------+-------+-----------+-------+
|
||||
| Site Type | Used | Fixed | Available | Util% |
|
||||
+-----------+------+-------+-----------+-------+
|
||||
| DSPs | 0 | 0 | 740 | 0.00 |
|
||||
+-----------+------+-------+-----------+-------+
|
||||
|
||||
|
||||
5. IO and GT Specific
|
||||
---------------------
|
||||
|
||||
+-----------------------------+------+-------+-----------+-------+
|
||||
| Site Type | Used | Fixed | Available | Util% |
|
||||
+-----------------------------+------+-------+-----------+-------+
|
||||
| Bonded IOB | 202 | 202 | 400 | 50.50 |
|
||||
| IOB Master Pads | 97 | | | |
|
||||
| IOB Slave Pads | 102 | | | |
|
||||
| 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 |
|
||||
+-----------------------------+------+-------+-----------+-------+
|
||||
|
||||
|
||||
6. Clocking
|
||||
-----------
|
||||
|
||||
+------------+------+-------+-----------+-------+
|
||||
| Site Type | Used | Fixed | Available | Util% |
|
||||
+------------+------+-------+-----------+-------+
|
||||
| BUFGCTRL | 3 | 0 | 32 | 9.38 |
|
||||
| BUFIO | 0 | 0 | 40 | 0.00 |
|
||||
| MMCME2_ADV | 0 | 0 | 10 | 0.00 |
|
||||
| PLLE2_ADV | 1 | 0 | 10 | 10.00 |
|
||||
| BUFMRCE | 0 | 0 | 20 | 0.00 |
|
||||
| BUFHCE | 0 | 0 | 120 | 0.00 |
|
||||
| BUFR | 0 | 0 | 40 | 0.00 |
|
||||
+------------+------+-------+-----------+-------+
|
||||
|
||||
|
||||
7. 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 |
|
||||
+-------------+------+-------+-----------+-------+
|
||||
|
||||
|
||||
8. Primitives
|
||||
-------------
|
||||
|
||||
+-----------+-------+---------------------+
|
||||
| Ref Name | Used | Functional Category |
|
||||
+-----------+-------+---------------------+
|
||||
| LUT6 | 37981 | LUT |
|
||||
| FDCE | 26562 | Flop & Latch |
|
||||
| FDRE | 12965 | Flop & Latch |
|
||||
| LUT5 | 12781 | LUT |
|
||||
| LUT4 | 10316 | LUT |
|
||||
| LUT3 | 10135 | LUT |
|
||||
| LUT2 | 9228 | LUT |
|
||||
| MUXF7 | 4565 | MuxFx |
|
||||
| CARRY4 | 3546 | CarryLogic |
|
||||
| MUXF8 | 1520 | MuxFx |
|
||||
| SRLC32E | 992 | Distributed Memory |
|
||||
| RAMD32 | 892 | Distributed Memory |
|
||||
| LUT1 | 802 | LUT |
|
||||
| RAMS32 | 272 | Distributed Memory |
|
||||
| SRL16E | 183 | Distributed Memory |
|
||||
| FDSE | 139 | Flop & Latch |
|
||||
| IBUF | 104 | IO |
|
||||
| OBUF | 98 | IO |
|
||||
| OBUFT | 66 | IO |
|
||||
| RAMD64E | 32 | Distributed Memory |
|
||||
| RAMB18E1 | 31 | Block Memory |
|
||||
| FDPE | 24 | Flop & Latch |
|
||||
| RAMB36E1 | 10 | Block Memory |
|
||||
| BUFG | 3 | Clock |
|
||||
| PLLE2_ADV | 1 | Clock |
|
||||
+-----------+-------+---------------------+
|
||||
|
||||
|
||||
9. Black Boxes
|
||||
--------------
|
||||
|
||||
+----------+------+
|
||||
| Ref Name | Used |
|
||||
+----------+------+
|
||||
|
||||
|
||||
10. Instantiated Netlists
|
||||
-------------------------
|
||||
|
||||
+----------+------+
|
||||
| Ref Name | Used |
|
||||
+----------+------+
|
||||
| clk_pll | 1 |
|
||||
+----------+------+
|
||||
|
||||
|
||||
253
fpga/vivado_reports_nodsp/utilization_hier.rpt
Normal file
@@ -0,0 +1,253 @@
|
||||
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 : Fri Jul 10 04:14:48 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_utilization -hierarchical -file /home/fallensigh/Dev/ciciec2026_loongson_regional/fpga/vivado_reports_nodsp/utilization_hier.rpt
|
||||
| Design : soc_top
|
||||
| Device : 7a200tfbg676-1
|
||||
| Design State : Routed
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Utilization Design Information
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1. Utilization by Hierarchy
|
||||
|
||||
1. Utilization by Hierarchy
|
||||
---------------------------
|
||||
|
||||
+------------------------------------------+------------------------------+------------+------------+---------+------+-------+--------+--------+--------------+
|
||||
| Instance | Module | Total LUTs | Logic LUTs | LUTRAMs | SRLs | FFs | RAMB36 | RAMB18 | DSP48 Blocks |
|
||||
+------------------------------------------+------------------------------+------------+------------+---------+------+-------+--------+--------+--------------+
|
||||
| soc_top | (top) | 71196 | 69453 | 628 | 1115 | 39690 | 10 | 31 | 0 |
|
||||
| (soc_top) | (top) | 868 | 812 | 56 | 0 | 4 | 0 | 0 | 0 |
|
||||
| pll_clk.u_clk_pll | clk_pll | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| inst | clk_pll_clk_pll_clk_wiz | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| pll_clk.u_rst_cpu | rst_sync | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| pll_clk.u_rst_sys | rst_sync_0 | 3 | 3 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| u_AxiCrossbar_2x8 | AxiCrossbar_2x8 | 357 | 357 | 0 | 0 | 151 | 0 | 0 | 0 |
|
||||
| (u_AxiCrossbar_2x8) | AxiCrossbar_2x8 | 8 | 8 | 0 | 0 | 24 | 0 | 0 | 0 |
|
||||
| axi4ReadOnlyArbiter_4 | Axi4ReadOnlyArbiter | 19 | 19 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_64 | 19 | 19 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| axi4ReadOnlyArbiter_5 | Axi4ReadOnlyArbiter_47 | 5 | 5 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_63 | 5 | 5 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| axi4ReadOnlyArbiter_6 | Axi4ReadOnlyArbiter_48 | 12 | 12 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_62 | 12 | 12 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| axi4ReadOnlyArbiter_7 | Axi4ReadOnlyArbiter_49 | 13 | 13 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_61 | 13 | 13 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| axi4WriteOnlyArbiter_4 | Axi4WriteOnlyArbiter | 30 | 30 | 0 | 0 | 11 | 0 | 0 | 0 |
|
||||
| (axi4WriteOnlyArbiter_4) | Axi4WriteOnlyArbiter | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_58 | 24 | 24 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdRouteFork_translated_fifo | StreamFifoLowLatency_3_59 | 7 | 7 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| fifo | StreamFifo_3_60 | 7 | 7 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| axi4WriteOnlyArbiter_5 | Axi4WriteOnlyArbiter_1 | 15 | 15 | 0 | 0 | 9 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_55 | 7 | 7 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdRouteFork_translated_fifo | StreamFifoLowLatency_3_56 | 8 | 8 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| fifo | StreamFifo_3_57 | 8 | 8 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| axi4WriteOnlyArbiter_6 | Axi4WriteOnlyArbiter_2 | 26 | 26 | 0 | 0 | 11 | 0 | 0 | 0 |
|
||||
| (axi4WriteOnlyArbiter_6) | Axi4WriteOnlyArbiter_2 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_52 | 16 | 16 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdRouteFork_translated_fifo | StreamFifoLowLatency_3_53 | 10 | 10 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| fifo | StreamFifo_3_54 | 10 | 10 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| axi4WriteOnlyArbiter_7 | Axi4WriteOnlyArbiter_3 | 27 | 27 | 0 | 0 | 11 | 0 | 0 | 0 |
|
||||
| (axi4WriteOnlyArbiter_7) | Axi4WriteOnlyArbiter_3 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7 | 18 | 18 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdRouteFork_translated_fifo | StreamFifoLowLatency_3 | 9 | 9 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| fifo | StreamFifo_3 | 9 | 9 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| axiIn_0_readOnly_decoder | Axi4ReadOnlyDecoder | 89 | 89 | 0 | 0 | 25 | 0 | 0 | 0 |
|
||||
| (axiIn_0_readOnly_decoder) | Axi4ReadOnlyDecoder | 73 | 73 | 0 | 0 | 12 | 0 | 0 | 0 |
|
||||
| errorSlave | Axi4ReadOnlyErrorSlave_1_51 | 16 | 16 | 0 | 0 | 13 | 0 | 0 | 0 |
|
||||
| axiIn_0_writeOnly_decoder | Axi4WriteOnlyDecoder | 36 | 36 | 0 | 0 | 18 | 0 | 0 | 0 |
|
||||
| (axiIn_0_writeOnly_decoder) | Axi4WriteOnlyDecoder | 16 | 16 | 0 | 0 | 16 | 0 | 0 | 0 |
|
||||
| errorSlave | Axi4WriteOnlyErrorSlave_1_50 | 20 | 20 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| axiIn_1_readOnly_decoder | Axi4ReadOnlyDecoder_1 | 55 | 55 | 0 | 0 | 17 | 0 | 0 | 0 |
|
||||
| (axiIn_1_readOnly_decoder) | Axi4ReadOnlyDecoder_1 | 41 | 41 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| errorSlave | Axi4ReadOnlyErrorSlave_1 | 15 | 15 | 0 | 0 | 9 | 0 | 0 | 0 |
|
||||
| axiIn_1_writeOnly_decoder | Axi4WriteOnlyDecoder_1 | 23 | 23 | 0 | 0 | 14 | 0 | 0 | 0 |
|
||||
| (axiIn_1_writeOnly_decoder) | Axi4WriteOnlyDecoder_1 | 18 | 18 | 0 | 0 | 12 | 0 | 0 | 0 |
|
||||
| errorSlave | Axi4WriteOnlyErrorSlave_1 | 5 | 5 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| u_Axi_CDC | Axi_CDC | 407 | 279 | 128 | 0 | 309 | 0 | 0 | 0 |
|
||||
| arFifo | StreamFifoCC_3 | 180 | 144 | 36 | 0 | 73 | 0 | 0 | 0 |
|
||||
| (arFifo) | StreamFifoCC_3 | 174 | 138 | 36 | 0 | 61 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC_9_45 | 1 | 1 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_11_46 | 5 | 5 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| awFifo | StreamFifoCC | 101 | 65 | 36 | 0 | 75 | 0 | 0 | 0 |
|
||||
| (awFifo) | StreamFifoCC | 94 | 58 | 36 | 0 | 61 | 0 | 0 | 0 |
|
||||
| bufferCC_12 | BufferCC_10 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC_9 | 2 | 2 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_11 | 4 | 4 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| bFifo | StreamFifoCC_2 | 14 | 14 | 0 | 0 | 26 | 0 | 0 | 0 |
|
||||
| (bFifo) | StreamFifoCC_2 | 7 | 7 | 0 | 0 | 12 | 0 | 0 | 0 |
|
||||
| bufferCC_12 | BufferCC_5 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC_4 | 2 | 2 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_6 | 4 | 4 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| rFifo | StreamFifoCC_4 | 46 | 18 | 28 | 0 | 66 | 0 | 0 | 0 |
|
||||
| (rFifo) | StreamFifoCC_4 | 41 | 13 | 28 | 0 | 50 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC | 4 | 4 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_1 | 2 | 2 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| wFifo | StreamFifoCC_1 | 66 | 38 | 28 | 0 | 69 | 0 | 0 | 0 |
|
||||
| (wFifo) | StreamFifoCC_1 | 62 | 34 | 28 | 0 | 53 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC_7 | 3 | 3 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_8 | 2 | 2 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| u_axi_axil_adapter | axi_axil_adapter | 1338 | 1338 | 0 | 0 | 161 | 0 | 0 | 0 |
|
||||
| axi_axil_adapter_rd_inst | axi_axil_adapter_rd | 635 | 635 | 0 | 0 | 81 | 0 | 0 | 0 |
|
||||
| axi_axil_adapter_wr_inst | axi_axil_adapter_wr | 703 | 703 | 0 | 0 | 80 | 0 | 0 | 0 |
|
||||
| u_axi_dvi | axi_dvi | 284 | 284 | 0 | 0 | 211 | 0 | 0 | 0 |
|
||||
| u_axi_ram | axi_wrap_ram_sp_external | 354 | 354 | 0 | 0 | 78 | 0 | 0 | 0 |
|
||||
| u_axi_sram_sp | axi2sram_sp_external | 354 | 354 | 0 | 0 | 78 | 0 | 0 | 0 |
|
||||
| u_axi_uart_controller | axi_uart_controller | 683 | 667 | 16 | 0 | 457 | 0 | 0 | 0 |
|
||||
| AA_axi2apb_bridge_cpu | axi2apb_bridge | 250 | 250 | 0 | 0 | 120 | 0 | 0 | 0 |
|
||||
| uart0 | UART_TOP | 433 | 417 | 16 | 0 | 337 | 0 | 0 | 0 |
|
||||
| regs | uart_regs | 433 | 417 | 16 | 0 | 337 | 0 | 0 | 0 |
|
||||
| (regs) | uart_regs | 118 | 118 | 0 | 0 | 155 | 0 | 0 | 0 |
|
||||
| i_uart_sync_flops | uart_sync_flops | 3 | 3 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| receiver | uart_receiver | 229 | 221 | 8 | 0 | 124 | 0 | 0 | 0 |
|
||||
| (receiver) | uart_receiver | 68 | 68 | 0 | 0 | 54 | 0 | 0 | 0 |
|
||||
| fifo_rx | uart_rfifo | 161 | 153 | 8 | 0 | 70 | 0 | 0 | 0 |
|
||||
| (fifo_rx) | uart_rfifo | 143 | 143 | 0 | 0 | 62 | 0 | 0 | 0 |
|
||||
| rfifo | raminfr_44 | 19 | 11 | 8 | 0 | 8 | 0 | 0 | 0 |
|
||||
| transmitter | uart_transmitter | 83 | 75 | 8 | 0 | 56 | 0 | 0 | 0 |
|
||||
| (transmitter) | uart_transmitter | 41 | 41 | 0 | 0 | 35 | 0 | 0 | 0 |
|
||||
| fifo_tx | uart_tfifo | 43 | 35 | 8 | 0 | 21 | 0 | 0 | 0 |
|
||||
| (fifo_tx) | uart_tfifo | 24 | 24 | 0 | 0 | 13 | 0 | 0 | 0 |
|
||||
| tfifo | raminfr | 19 | 11 | 8 | 0 | 8 | 0 | 0 | 0 |
|
||||
| u_cdma_matmul_bridge | cdma_matmul_bridge | 247 | 247 | 0 | 0 | 578 | 0 | 0 | 0 |
|
||||
| u_confreg | confreg | 390 | 390 | 0 | 0 | 476 | 0 | 0 | 0 |
|
||||
| (u_confreg) | confreg | 230 | 230 | 0 | 0 | 399 | 0 | 0 | 0 |
|
||||
| u_digitaltube_controller | digitaltube_controller | 16 | 16 | 0 | 0 | 24 | 0 | 0 | 0 |
|
||||
| u_int_ctrl | int_ctrl | 144 | 144 | 0 | 0 | 53 | 0 | 0 | 0 |
|
||||
| u_cpu | core_top | 8553 | 8301 | 252 | 0 | 5591 | 0 | 20 | 0 |
|
||||
| (u_cpu) | core_top | 519 | 519 | 0 | 0 | 1 | 0 | 0 | 0 |
|
||||
| addr_trans | addr_trans | 2249 | 2109 | 140 | 0 | 1244 | 0 | 0 | 0 |
|
||||
| (addr_trans) | addr_trans | 0 | 0 | 0 | 0 | 40 | 0 | 0 | 0 |
|
||||
| tlb_entry | tlb_entry | 2249 | 2109 | 140 | 0 | 1204 | 0 | 0 | 0 |
|
||||
| axi_bridge | axi_bridge | 39 | 39 | 0 | 0 | 214 | 0 | 0 | 0 |
|
||||
| btb | btb | 1046 | 966 | 80 | 0 | 1611 | 0 | 0 | 0 |
|
||||
| (btb) | btb | 1043 | 963 | 80 | 0 | 1611 | 0 | 0 | 0 |
|
||||
| dec_btb_add_entry | decoder_5_32 | 3 | 3 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| dcache | dcache | 553 | 521 | 32 | 0 | 146 | 0 | 10 | 0 |
|
||||
| (dcache) | dcache | 87 | 55 | 32 | 0 | 138 | 0 | 0 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[0].u | data_bank_sram_33 | 49 | 49 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[1].u | data_bank_sram_34 | 17 | 17 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[2].u | data_bank_sram_35 | 49 | 49 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[3].u | data_bank_sram_36 | 51 | 51 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[0].u | data_bank_sram_37 | 17 | 17 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[1].u | data_bank_sram_38 | 49 | 49 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[2].u | data_bank_sram_39 | 81 | 81 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[3].u | data_bank_sram_40 | 54 | 54 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| lfsr | lfsr_41 | 2 | 2 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| tagv_ram_way[0].u | tagv_sram_42 | 62 | 62 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| tagv_ram_way[1].u | tagv_sram_43 | 41 | 41 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| exe_stage | exe_stage | 664 | 664 | 0 | 0 | 233 | 0 | 0 | 0 |
|
||||
| (exe_stage) | exe_stage | 633 | 633 | 0 | 0 | 233 | 0 | 0 | 0 |
|
||||
| u_alu | alu | 33 | 33 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| icache | icache | 235 | 235 | 0 | 0 | 55 | 0 | 10 | 0 |
|
||||
| (icache) | icache | 12 | 12 | 0 | 0 | 47 | 0 | 0 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[0].u | data_bank_sram | 4 | 4 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[1].u | data_bank_sram_25 | 3 | 3 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[2].u | data_bank_sram_26 | 67 | 67 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[3].u | data_bank_sram_27 | 3 | 3 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[0].u | data_bank_sram_28 | 3 | 3 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[1].u | data_bank_sram_29 | 3 | 3 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[2].u | data_bank_sram_30 | 35 | 35 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[3].u | data_bank_sram_31 | 4 | 4 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| lfsr | lfsr | 2 | 2 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| tagv_ram_way[0].u | tagv_sram | 15 | 15 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| tagv_ram_way[1].u | tagv_sram_32 | 88 | 88 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| id_stage | id_stage | 1050 | 1050 | 0 | 0 | 108 | 0 | 0 | 0 |
|
||||
| if_stage | if_stage | 134 | 134 | 0 | 0 | 173 | 0 | 0 | 0 |
|
||||
| mem_stage | mem_stage | 117 | 117 | 0 | 0 | 211 | 0 | 0 | 0 |
|
||||
| u_csr | csr | 200 | 200 | 0 | 0 | 663 | 0 | 0 | 0 |
|
||||
| u_div | div | 142 | 142 | 0 | 0 | 107 | 0 | 0 | 0 |
|
||||
| u_mul | mul | 934 | 934 | 0 | 0 | 592 | 0 | 0 | 0 |
|
||||
| wb_stage | wb_stage | 681 | 681 | 0 | 0 | 233 | 0 | 0 | 0 |
|
||||
| u_fft_mlkem_axi_slave | fft_mlkem_axi_slave | 45975 | 44866 | 0 | 1109 | 26955 | 10 | 10 | 0 |
|
||||
| (u_fft_mlkem_axi_slave) | fft_mlkem_axi_slave | 0 | 0 | 0 | 0 | 4 | 0 | 0 | 0 |
|
||||
| u_fft_controller | fft_controller | 6949 | 5909 | 0 | 1040 | 1083 | 8 | 4 | 0 |
|
||||
| (u_fft_controller) | fft_controller | 118 | 118 | 0 | 0 | 100 | 0 | 0 | 0 |
|
||||
| u_FFT | FFT | 6783 | 5743 | 0 | 1040 | 983 | 8 | 0 | 0 |
|
||||
| SU1 | SdfUnit | 2145 | 1377 | 0 | 768 | 197 | 2 | 0 | 0 |
|
||||
| (SU1) | SdfUnit | 39 | 39 | 0 | 0 | 133 | 0 | 0 | 0 |
|
||||
| BF1 | Butterfly_21 | 16 | 16 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| BF2 | Butterfly__parameterized0_22 | 32 | 32 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| DB1 | DelayBuffer | 624 | 112 | 0 | 512 | 32 | 0 | 0 | 0 |
|
||||
| DB2 | DelayBuffer__parameterized0 | 320 | 64 | 0 | 256 | 32 | 0 | 0 | 0 |
|
||||
| MU | Multiply_23 | 611 | 611 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| TW | Twiddle_24 | 543 | 543 | 0 | 0 | 0 | 2 | 0 | 0 |
|
||||
| SU2 | SdfUnit__parameterized0 | 1566 | 1374 | 0 | 192 | 197 | 2 | 0 | 0 |
|
||||
| (SU2) | SdfUnit__parameterized0 | 38 | 38 | 0 | 0 | 133 | 0 | 0 | 0 |
|
||||
| BF1 | Butterfly_17 | 16 | 16 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| BF2 | Butterfly__parameterized0_18 | 32 | 32 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| DB1 | DelayBuffer__parameterized1 | 240 | 112 | 0 | 128 | 32 | 0 | 0 | 0 |
|
||||
| DB2 | DelayBuffer__parameterized2 | 128 | 64 | 0 | 64 | 32 | 0 | 0 | 0 |
|
||||
| MU | Multiply_19 | 611 | 611 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| TW | Twiddle_20 | 541 | 541 | 0 | 0 | 0 | 2 | 0 | 0 |
|
||||
| SU3 | SdfUnit__parameterized1 | 1416 | 1368 | 0 | 48 | 197 | 2 | 0 | 0 |
|
||||
| (SU3) | SdfUnit__parameterized1 | 35 | 35 | 0 | 0 | 133 | 0 | 0 | 0 |
|
||||
| BF1 | Butterfly_13 | 16 | 16 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| BF2 | Butterfly__parameterized0_14 | 32 | 32 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| DB1 | DelayBuffer__parameterized3 | 144 | 112 | 0 | 32 | 32 | 0 | 0 | 0 |
|
||||
| DB2 | DelayBuffer__parameterized4 | 80 | 64 | 0 | 16 | 32 | 0 | 0 | 0 |
|
||||
| MU | Multiply_15 | 610 | 610 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| TW | Twiddle_16 | 539 | 539 | 0 | 0 | 0 | 2 | 0 | 0 |
|
||||
| SU4 | SdfUnit__parameterized2 | 1398 | 1366 | 0 | 32 | 197 | 2 | 0 | 0 |
|
||||
| (SU4) | SdfUnit__parameterized2 | 34 | 34 | 0 | 0 | 133 | 0 | 0 | 0 |
|
||||
| BF1 | Butterfly_11 | 16 | 16 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| BF2 | Butterfly__parameterized0_12 | 32 | 32 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| DB1 | DelayBuffer__parameterized5 | 128 | 112 | 0 | 16 | 32 | 0 | 0 | 0 |
|
||||
| DB2 | DelayBuffer__parameterized6 | 80 | 64 | 0 | 16 | 32 | 0 | 0 | 0 |
|
||||
| MU | Multiply | 612 | 612 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| TW | Twiddle | 536 | 536 | 0 | 0 | 0 | 2 | 0 | 0 |
|
||||
| SU5 | SdfUnit__parameterized3 | 258 | 258 | 0 | 0 | 195 | 0 | 0 | 0 |
|
||||
| (SU5) | SdfUnit__parameterized3 | 34 | 34 | 0 | 0 | 99 | 0 | 0 | 0 |
|
||||
| BF1 | Butterfly | 16 | 16 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| BF2 | Butterfly__parameterized0 | 32 | 32 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| DB1 | DelayBuffer__parameterized7 | 112 | 112 | 0 | 0 | 64 | 0 | 0 | 0 |
|
||||
| DB2 | DelayBuffer__parameterized8 | 64 | 64 | 0 | 0 | 32 | 0 | 0 | 0 |
|
||||
| u_in0 | my_bram0 | 3 | 3 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_in1 | my_bram0_8 | 2 | 2 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_out0 | my_bram0_9 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_out1 | my_bram0_10 | 45 | 45 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_mlkem_axi_slave | mlkem_axi_slave | 39029 | 38960 | 0 | 69 | 25868 | 2 | 6 | 0 |
|
||||
| (u_mlkem_axi_slave) | mlkem_axi_slave | 1332 | 1332 | 0 | 0 | 1060 | 0 | 0 | 0 |
|
||||
| u_mlkem | mlkem_top | 37700 | 37631 | 0 | 69 | 24808 | 2 | 6 | 0 |
|
||||
| (u_mlkem) | mlkem_top | 2754 | 2754 | 0 | 0 | 4949 | 0 | 0 | 0 |
|
||||
| u_bank_a | sd_bram__parameterized0 | 51 | 51 | 0 | 0 | 0 | 1 | 1 | 0 |
|
||||
| u_bank_se | sd_bram__parameterized1 | 70 | 70 | 0 | 0 | 0 | 1 | 0 | 0 |
|
||||
| u_bank_t | sd_bram__parameterized2 | 683 | 683 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_c_in_bram | sd_bram | 1312 | 1312 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_cbd | sample_cbd_sync_shared | 2753 | 2753 | 0 | 0 | 3186 | 0 | 0 | 0 |
|
||||
| u_comp | comp_decomp_sync | 465 | 464 | 0 | 1 | 323 | 0 | 0 | 0 |
|
||||
| u_ct_bram | sd_bram_4 | 12 | 12 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_dkp_bram | sd_bram_5 | 82 | 82 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_ek_bram | sd_bram_6 | 2006 | 2006 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_keccak | keccak_core | 5271 | 5271 | 0 | 0 | 1606 | 0 | 0 | 0 |
|
||||
| u_ntt | ntt_core | 9893 | 9850 | 0 | 43 | 3869 | 0 | 0 | 0 |
|
||||
| (u_ntt) | ntt_core | 7376 | 7360 | 0 | 16 | 3366 | 0 | 0 | 0 |
|
||||
| u_bf | butterfly_unit_pipe | 2256 | 2230 | 0 | 26 | 286 | 0 | 0 | 0 |
|
||||
| (u_bf) | butterfly_unit_pipe | 58 | 33 | 0 | 25 | 75 | 0 | 0 | 0 |
|
||||
| u_barrett | barrett_mul_pipe_7 | 2198 | 2197 | 0 | 1 | 211 | 0 | 0 | 0 |
|
||||
| u_scl | barrett_mul_pipe | 263 | 262 | 0 | 1 | 217 | 0 | 0 | 0 |
|
||||
| u_pmul | poly_mul_sync | 8281 | 8256 | 0 | 25 | 6818 | 0 | 0 | 0 |
|
||||
| (u_pmul) | poly_mul_sync | 6834 | 6834 | 0 | 0 | 6355 | 0 | 0 | 0 |
|
||||
| u_bc | basecase_mul_pipe | 1447 | 1422 | 0 | 25 | 463 | 0 | 0 | 0 |
|
||||
| u_sha3 | sha3_top_shared | 1975 | 1975 | 0 | 0 | 2388 | 0 | 0 | 0 |
|
||||
| u_snt | sample_ntt_sync_shared | 2108 | 2108 | 0 | 0 | 1669 | 0 | 0 | 0 |
|
||||
| u_matmul_axi_slave | matmul_axi_slave | 10204 | 10022 | 176 | 6 | 3239 | 0 | 0 | 0 |
|
||||
| (u_matmul_axi_slave) | matmul_axi_slave | 6085 | 5903 | 176 | 6 | 2471 | 0 | 0 | 0 |
|
||||
| mult_inst[0].u_mult | pipelined_mult_32x32 | 1061 | 1061 | 0 | 0 | 192 | 0 | 0 | 0 |
|
||||
| mult_inst[1].u_mult | pipelined_mult_32x32_1 | 998 | 998 | 0 | 0 | 192 | 0 | 0 | 0 |
|
||||
| mult_inst[2].u_mult | pipelined_mult_32x32_2 | 1063 | 1063 | 0 | 0 | 192 | 0 | 0 | 0 |
|
||||
| mult_inst[3].u_mult | pipelined_mult_32x32_3 | 997 | 997 | 0 | 0 | 192 | 0 | 0 | 0 |
|
||||
| u_snix_axil_cdma_mux_8ch | snix_axil_cdma_mux | 1558 | 1558 | 0 | 0 | 1476 | 0 | 1 | 0 |
|
||||
| (u_snix_axil_cdma_mux_8ch) | snix_axil_cdma_mux | 587 | 587 | 0 | 0 | 1180 | 0 | 0 | 0 |
|
||||
| u_core_engine | snix_axi_mm2mm | 974 | 974 | 0 | 0 | 296 | 0 | 1 | 0 |
|
||||
| (u_core_engine) | snix_axi_mm2mm | 700 | 700 | 0 | 0 | 243 | 0 | 0 | 0 |
|
||||
| axis_fifo_u0 | snix_axis_fifo | 274 | 274 | 0 | 0 | 53 | 0 | 1 | 0 |
|
||||
| u_fifo | snix_sync_fifo | 274 | 274 | 0 | 0 | 53 | 0 | 1 | 0 |
|
||||
+------------------------------------------+------------------------------+------------+------------+---------+------+-------+--------+--------+--------------+
|
||||
* Note: The sum of lower-level cells may be larger than their parent cells total, due to cross-hierarchy LUT combining
|
||||
|
||||
|
||||
28
fpga/vivado_reports_withdsp/clock_interaction.rpt
Normal file
@@ -0,0 +1,28 @@
|
||||
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 : Wed Jul 8 02:57:58 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_clock_interaction -file /home/fallensigh/vivado_reports_withdsp/clock_interaction.rpt
|
||||
| Design : soc_top
|
||||
| Device : 7a200t-fbg676
|
||||
| Speed File : -1 PRODUCTION 1.23 2018-06-13
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Clock Interaction Report
|
||||
|
||||
Clock Interaction Table
|
||||
-----------------------
|
||||
|
||||
WNS TNS Failing TNS Total WNS Path Clock-Pair Inter-Clock
|
||||
From Clock To Clock Clock Edges WNS(ns) TNS(ns) Endpoints Endpoints Requirement(ns) Classification Constraints
|
||||
----------------- ----------------- ----------- ------- ------- ----------- ----------- --------------- ------------------- -------------------
|
||||
cpu_clk cpu_clk rise - rise 1.14 0.00 0 17264 30.32 Clean Timed
|
||||
cpu_clk sys_clk 0 162 Ignored Asynchronous Groups
|
||||
mlkem_clk_clk_pll mlkem_clk_clk_pll rise - rise 12.91 0.00 0 74882 40.00 Clean Timed
|
||||
mlkem_clk_clk_pll sys_clk rise - rise 16.72 0.00 0 61 20.00 Clean Timed
|
||||
sys_clk cpu_clk 0 59 Ignored Asynchronous Groups
|
||||
sys_clk mlkem_clk_clk_pll rise - rise 8.52 0.00 0 112 20.00 Clean Timed
|
||||
sys_clk sys_clk rise - rise 0.42 0.00 0 23732 20.00 Clean Timed
|
||||
|
||||
|
||||
76
fpga/vivado_reports_withdsp/clocks.rpt
Normal file
@@ -0,0 +1,76 @@
|
||||
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 : Wed Jul 8 02:57:58 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_clocks -file /home/fallensigh/vivado_reports_withdsp/clocks.rpt
|
||||
| Design : soc_top
|
||||
| Device : 7a200t-fbg676
|
||||
| Speed File : -1 PRODUCTION 1.23 2018-06-13
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
Clock Report
|
||||
|
||||
|
||||
Attributes
|
||||
P: Propagated
|
||||
G: Generated
|
||||
A: Auto-derived
|
||||
R: Renamed
|
||||
V: Virtual
|
||||
I: Inverted
|
||||
S: Pin phase-shifted with Latency mode
|
||||
|
||||
Clock Period(ns) Waveform(ns) Attributes Sources
|
||||
clk 20.000 {0.000 10.000} P {clk}
|
||||
clkfbout_clk_pll 20.000 {0.000 10.000} P,G,A {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKFBOUT}
|
||||
cpu_clk 30.323 {0.000 15.161} P,G,A,R {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKOUT0}
|
||||
mlkem_clk_clk_pll 40.000 {0.000 20.000} P,G,A {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKOUT2}
|
||||
sys_clk 20.000 {0.000 10.000} P,G,A,R {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKOUT1}
|
||||
|
||||
|
||||
====================================================
|
||||
Generated Clocks
|
||||
====================================================
|
||||
|
||||
Generated Clock : clkfbout_clk_pll
|
||||
Master Source : pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKIN1
|
||||
Master Clock : clk
|
||||
Multiply By : 1
|
||||
Generated Sources : {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKFBOUT}
|
||||
|
||||
Generated Clock : cpu_clk
|
||||
Master Source : pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKIN1
|
||||
Master Clock : clk
|
||||
Edges : {1 2 3}
|
||||
Edge Shifts(ns) : {0.000 5.161 10.323}
|
||||
Generated Sources : {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKOUT0}
|
||||
|
||||
Generated Clock : mlkem_clk_clk_pll
|
||||
Master Source : pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKIN1
|
||||
Master Clock : clk
|
||||
Edges : {1 2 3}
|
||||
Edge Shifts(ns) : {0.000 10.000 20.000}
|
||||
Generated Sources : {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKOUT2}
|
||||
|
||||
Generated Clock : sys_clk
|
||||
Master Source : pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKIN1
|
||||
Master Clock : clk
|
||||
Multiply By : 1
|
||||
Generated Sources : {pll_clk.u_clk_pll/inst/plle2_adv_inst/CLKOUT1}
|
||||
|
||||
|
||||
|
||||
====================================================
|
||||
User Uncertainty
|
||||
====================================================
|
||||
|
||||
|
||||
|
||||
====================================================
|
||||
User Jitter
|
||||
====================================================
|
||||
|
||||
Clock Jitter(ns)
|
||||
clk 0.200
|
||||
|
||||
37
fpga/vivado_reports_withdsp/design_analysis_complexity.rpt
Normal file
@@ -0,0 +1,37 @@
|
||||
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 : Wed Jul 8 02:58:45 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_design_analysis -complexity -file /home/fallensigh/vivado_reports_withdsp/design_analysis_complexity.rpt
|
||||
| Design : soc_top
|
||||
| Device : xc7a200t
|
||||
| Design State : Routed
|
||||
---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Report Design Analysis
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1. Complexity Characteristics (Cells)
|
||||
|
||||
1. Complexity Characteristics (Cells)
|
||||
-------------------------------------
|
||||
|
||||
+---------------------------+---------------------+------+----------------+-----------------+-----------+------------+-------------+-------------+-------------+--------------+------------+-----+------+------+------+
|
||||
| Instance | Module | Rent | Average Fanout | Total Instances | LUT1 | LUT2 | LUT3 | LUT4 | LUT5 | LUT6 | Memory LUT | DSP | RAMB | MUXF | URAM |
|
||||
+---------------------------+---------------------+------+----------------+-----------------+-----------+------------+-------------+-------------+-------------+--------------+------------+-----+------+------+------+
|
||||
| (top) | soc_top | 0.49 | 3.76 | 108219 | 710(1.2%) | 5229(8.7%) | 8166(13.7%) | 8097(13.5%) | 8459(14.1%) | 29130(48.7%) | 1175 | 56 | 39 | 6074 | 0 |
|
||||
| u_axi_axil_adapter | axi_axil_adapter | 0.50 | 5.92 | 1309 | 0(0.0%) | 8(0.7%) | 43(3.8%) | 100(8.9%) | 200(17.7%) | 776(68.9%) | 0 | 0 | 0 | 0 | 0 |
|
||||
| u_axi_uart_controller | axi_uart_controller | 0.55 | 3.54 | 1296 | 10(1.2%) | 84(10.4%) | 80(9.9%) | 144(17.9%) | 194(24.1%) | 293(36.4%) | 0 | 0 | 0 | 9 | 0 |
|
||||
| u_cdma_matmul_bridge | cdma_matmul_bridge | 0.56 | 2.22 | 1003 | 1(0.3%) | 66(17.3%) | 39(10.2%) | 174(45.7%) | 13(3.4%) | 88(23.1%) | 0 | 0 | 0 | 0 | 0 |
|
||||
| u_cpu | core_top | 0.56 | 3.96 | 15822 | 168(1.8%) | 579(6.3%) | 1029(11.1%) | 871(9.4%) | 1744(18.9%) | 4860(52.5%) | 0 | 0 | 20 | 276 | 0 |
|
||||
| u_fft_mlkem_axi_slave | fft_mlkem_axi_slave | 0.53 | 3.70 | 70959 | 286(0.8%) | 3478(9.4%) | 4960(13.4%) | 5940(16.0%) | 4261(11.5%) | 18098(48.9%) | 1169 | 40 | 18 | 5241 | 0 |
|
||||
| u_matmul_axi_slave | matmul_axi_slave | 0.69 | 3.39 | 10715 | 18(0.2%) | 465(6.4%) | 1463(20.2%) | 312(4.3%) | 1333(18.4%) | 3646(50.4%) | 6 | 16 | 0 | 512 | 0 |
|
||||
| u_snix_axil_cdma_mux_8ch | snix_axil_cdma_mux | 0.45 | 3.68 | 3535 | 136(7.0%) | 181(9.3%) | 328(16.8%) | 258(13.2%) | 297(15.2%) | 750(38.5%) | 0 | 0 | 1 | 4 | 0 |
|
||||
+---------------------------+---------------------+------+----------------+-----------------+-----------+------------+-------------+-------------+-------------+--------------+------------+-----+------+------+------+
|
||||
* Complexity Ranges
|
||||
** 0.0 - 0.3 -> Very Low, 0.3 - 0.5 -> low, 0.5 - 0.65 -> normal, 0.65 - 0.85 -> high, 0.85 - 1.0 -> very high
|
||||
*** -* -> Not computable as cell size is very small
|
||||
|
||||
|
||||
52
fpga/vivado_reports_withdsp/design_analysis_timing.rpt
Normal file
@@ -0,0 +1,52 @@
|
||||
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 : Wed Jul 8 02:58:13 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_design_analysis -timing -file /home/fallensigh/vivado_reports_withdsp/design_analysis_timing.rpt
|
||||
| Design : soc_top
|
||||
| Device : xc7a200t
|
||||
| Design State : Routed
|
||||
-------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Report Design Analysis
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1. Setup Path Characteristics 1-1
|
||||
|
||||
1. Setup Path Characteristics 1-1
|
||||
---------------------------------
|
||||
|
||||
+---------------------------+----------------------------------------------------------------------------------------+
|
||||
| Characteristics | Path #1 |
|
||||
+---------------------------+----------------------------------------------------------------------------------------+
|
||||
| Requirement | 20.000 |
|
||||
| Path Delay | 15.252 |
|
||||
| Logic Delay | 7.003(46%) |
|
||||
| Net Delay | 8.249(54%) |
|
||||
| Clock Skew | -3.954 |
|
||||
| Slack | 0.424 |
|
||||
| Clock Relationship | Safely Timed |
|
||||
| Logic Levels | 14 |
|
||||
| Routes | 12 |
|
||||
| Logical Path | FDCE LUT4 LUT5 LUT6 CARRY4 CARRY4 CARRY4 CARRY4 CARRY4 LUT6 CARRY4 LUT6 LUT6 LUT6 OBUF |
|
||||
| Start Point Clock | sys_clk |
|
||||
| End Point Clock | sys_clk |
|
||||
| DSP Block | None |
|
||||
| BRAM | None |
|
||||
| IO Crossings | 3 |
|
||||
| Config Crossings | 0 |
|
||||
| SLR Crossings | 0 |
|
||||
| PBlocks | 0 |
|
||||
| High Fanout | 80 |
|
||||
| Dont Touch | 0 |
|
||||
| Mark Debug | 0 |
|
||||
| Start Point Pin Primitive | FDCE/C |
|
||||
| End Point Pin Primitive | base_ram_be_n[3] |
|
||||
| Start Point Pin | ax_req_q_len_reg[1]/C |
|
||||
| End Point Pin | base_ram_be_n[3] |
|
||||
+---------------------------+----------------------------------------------------------------------------------------+
|
||||
* Bounding box calculated as % of dimensions for the target device (436, 500)
|
||||
|
||||
|
||||
911
fpga/vivado_reports_withdsp/drc.rpt
Normal file
@@ -0,0 +1,911 @@
|
||||
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 : Wed Jul 8 02:57:43 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_drc -file /home/fallensigh/vivado_reports_withdsp/drc.rpt
|
||||
| Design : soc_top
|
||||
| Device : xc7a200tfbg676-1
|
||||
| Speed File : -1
|
||||
| Design State : Fully Routed
|
||||
------------------------------------------------------------------------------------
|
||||
|
||||
Report DRC
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1. REPORT SUMMARY
|
||||
2. REPORT DETAILS
|
||||
|
||||
1. REPORT SUMMARY
|
||||
-----------------
|
||||
Netlist: netlist
|
||||
Floorplan: impl_1
|
||||
Design limits: <entire design considered>
|
||||
Ruledeck: default
|
||||
Max violations: <unlimited>
|
||||
Violations found: 174
|
||||
+-----------+----------+----------------------------+------------+
|
||||
| Rule | Severity | Description | Violations |
|
||||
+-----------+----------+----------------------------+------------+
|
||||
| CHECK-3 | Warning | Report rule limit reached | 2 |
|
||||
| DPIP-1 | Warning | Input pipelining | 47 |
|
||||
| DPOP-1 | Warning | PREG Output pipelining | 29 |
|
||||
| DPOP-2 | Warning | MREG Output pipelining | 56 |
|
||||
| REQP-1839 | Warning | RAMB36 async control check | 20 |
|
||||
| REQP-1840 | Warning | RAMB18 async control check | 20 |
|
||||
+-----------+----------+----------------------------+------------+
|
||||
|
||||
2. REPORT DETAILS
|
||||
-----------------
|
||||
CHECK-3#1 Warning
|
||||
Report rule limit reached
|
||||
REQP-1839 rule limit reached: 20 violations have been found.
|
||||
Related violations: <none>
|
||||
|
||||
CHECK-3#2 Warning
|
||||
Report rule limit reached
|
||||
REQP-1840 rule limit reached: 20 violations have been found.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#1 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/aibi input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/aibi/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#2 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/aibr input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/aibr/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#3 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/arbi input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/arbi/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#4 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/arbr input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/arbr/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#5 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/aibi input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/aibi/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#6 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/aibr input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/aibr/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#7 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/arbi input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/arbi/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#8 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/arbr input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/arbr/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#9 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/aibi input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/aibi/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#10 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/aibr input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/aibr/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#11 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/arbi input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/arbi/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#12 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/arbr input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/arbr/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#13 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/aibi input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/aibi/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#14 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/aibr input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/aibr/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#15 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/arbi input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/arbi/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#16 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/arbr input u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/arbr/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#17 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/comp_q_mul_q_s40 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/comp_q_mul_q_s40/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#18 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/comp_qprod_est_s20 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/comp_qprod_est_s20/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#19 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/decomp_round_next input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/decomp_round_next/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#20 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/decomp_round_next input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/decomp_round_next/C[47:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#21 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/p_s10 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/p_s10/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#22 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/p_s10 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/p_s10/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#23 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/qprod_s40 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/qprod_s40/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#24 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/tk_s20 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/tk_s20/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#25 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_scl/p_s10 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_scl/p_s10/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#26 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_scl/qprod_s40 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_scl/qprod_s40/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#27 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_scl/tk_s20 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_scl/tk_s20/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#28 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q0_return0 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q0_return0/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#29 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q1_return0 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q1_return0/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#30 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q2_return0 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q2_return0/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#31 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q3_return0 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q3_return0/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#32 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q_return0 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q_return0/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#33 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce0_return7 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce0_return7/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#34 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce1_return7 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce1_return7/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#35 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce2_return7 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce2_return7/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#36 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce3_return7 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce3_return7/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#37 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce_return7 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce_return7/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#38 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#39 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#40 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__0 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__0/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#41 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__0 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__0/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#42 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__1 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__1/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#43 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__1 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__1/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#44 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__2 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__2/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#45 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__2 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__2/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#46 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__3 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__3/A[29:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPIP-1#47 Warning
|
||||
Input pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__3 input u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__3/B[17:0] is not pipelined. Pipelining DSP48 input will improve performance.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#1 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/aibi output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/aibi/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#2 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/aibr output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/aibr/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#3 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/arbi output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/arbi/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#4 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/arbr output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/arbr/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#5 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/aibi output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/aibi/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#6 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/aibr output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/aibr/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#7 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/arbi output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/arbi/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#8 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/arbr output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/arbr/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#9 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/aibi output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/aibi/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#10 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/aibr output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/aibr/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#11 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/arbi output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/arbi/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#12 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/arbr output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/arbr/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#13 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/aibi output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/aibi/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#14 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/aibr output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/aibr/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#15 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/arbi output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/arbi/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#16 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/arbr output u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/arbr/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#17 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce0_return7 output u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce0_return7/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#18 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce1_return7 output u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce1_return7/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#19 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce2_return7 output u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce2_return7/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#20 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce3_return7 output u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce3_return7/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#21 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce_return7 output u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce_return7/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#22 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[0].u_mult/prod0__16 output u_matmul_axi_slave/mult_inst[0].u_mult/prod0__16/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#23 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[0].u_mult/prod0__17 output u_matmul_axi_slave/mult_inst[0].u_mult/prod0__17/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#24 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[1].u_mult/prod0 output u_matmul_axi_slave/mult_inst[1].u_mult/prod0/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#25 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[1].u_mult/prod0__17 output u_matmul_axi_slave/mult_inst[1].u_mult/prod0__17/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#26 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[2].u_mult/prod0 output u_matmul_axi_slave/mult_inst[2].u_mult/prod0/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#27 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[2].u_mult/prod0__17 output u_matmul_axi_slave/mult_inst[2].u_mult/prod0__17/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#28 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[3].u_mult/prod0 output u_matmul_axi_slave/mult_inst[3].u_mult/prod0/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-1#29 Warning
|
||||
PREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[3].u_mult/prod0__17 output u_matmul_axi_slave/mult_inst[3].u_mult/prod0__17/P[47:0] is not pipelined (PREG=0). Pipelining the DSP48 output will improve performance and often saves power so it is suggested whenever possible to fully pipeline this function. If this DSP48 function was inferred, it is suggested to describe an additional register stage after this function. If the DSP48 was instantiated in the design, it is suggested to set the PREG attribute to 1.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#1 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/aibi multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/aibi/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#2 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/aibr multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/aibr/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#3 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/arbi multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/arbi/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#4 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/arbr multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/MU/arbr/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#5 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/aibi multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/aibi/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#6 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/aibr multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/aibr/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#7 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/arbi multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/arbi/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#8 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/arbr multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU2/MU/arbr/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#9 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/aibi multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/aibi/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#10 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/aibr multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/aibr/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#11 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/arbi multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/arbi/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#12 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/arbr multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU3/MU/arbr/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#13 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/aibi multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/aibi/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#14 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/aibr multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/aibr/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#15 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/arbi multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/arbi/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#16 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/arbr multiplier stage u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU4/MU/arbr/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#17 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/comp_q_mul_q_s40 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/comp_q_mul_q_s40/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#18 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/comp_qprod_est_s20 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/comp_qprod_est_s20/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#19 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/decomp_round_next multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_comp/decomp_round_next/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#20 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/p_s10 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/p_s10/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#21 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/qprod_s40 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/qprod_s40/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#22 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/tk_s20 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/tk_s20/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#23 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_scl/p_s10 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_scl/p_s10/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#24 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_scl/qprod_s40 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_scl/qprod_s40/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#25 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_scl/tk_s20 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_scl/tk_s20/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#26 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q0_return0 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q0_return0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#27 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q1_return0 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q1_return0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#28 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q2_return0 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q2_return0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#29 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q3_return0 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q3_return0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#30 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q_return0 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_q_return0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#31 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce0_return7 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce0_return7/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#32 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce1_return7 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce1_return7/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#33 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce2_return7 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce2_return7/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#34 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce3_return7 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce3_return7/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#35 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce_return7 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/barrett_reduce_return7/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#36 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#37 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__0 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#38 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__1 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__1/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#39 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__2 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__2/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#40 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__3 multiplier stage u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/u_bc/p0__3/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#41 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[0].u_mult/prod0__16 multiplier stage u_matmul_axi_slave/mult_inst[0].u_mult/prod0__16/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#42 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[0].u_mult/prod0__17 multiplier stage u_matmul_axi_slave/mult_inst[0].u_mult/prod0__17/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#43 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[0].u_mult/prod_reg multiplier stage u_matmul_axi_slave/mult_inst[0].u_mult/prod_reg/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#44 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[0].u_mult/prod_reg__0 multiplier stage u_matmul_axi_slave/mult_inst[0].u_mult/prod_reg__0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#45 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[1].u_mult/prod0 multiplier stage u_matmul_axi_slave/mult_inst[1].u_mult/prod0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#46 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[1].u_mult/prod0__17 multiplier stage u_matmul_axi_slave/mult_inst[1].u_mult/prod0__17/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#47 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[1].u_mult/prod_reg multiplier stage u_matmul_axi_slave/mult_inst[1].u_mult/prod_reg/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#48 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[1].u_mult/prod_reg__0 multiplier stage u_matmul_axi_slave/mult_inst[1].u_mult/prod_reg__0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#49 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[2].u_mult/prod0 multiplier stage u_matmul_axi_slave/mult_inst[2].u_mult/prod0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#50 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[2].u_mult/prod0__17 multiplier stage u_matmul_axi_slave/mult_inst[2].u_mult/prod0__17/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#51 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[2].u_mult/prod_reg multiplier stage u_matmul_axi_slave/mult_inst[2].u_mult/prod_reg/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#52 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[2].u_mult/prod_reg__0 multiplier stage u_matmul_axi_slave/mult_inst[2].u_mult/prod_reg__0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#53 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[3].u_mult/prod0 multiplier stage u_matmul_axi_slave/mult_inst[3].u_mult/prod0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#54 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[3].u_mult/prod0__17 multiplier stage u_matmul_axi_slave/mult_inst[3].u_mult/prod0__17/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#55 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[3].u_mult/prod_reg multiplier stage u_matmul_axi_slave/mult_inst[3].u_mult/prod_reg/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
DPOP-2#56 Warning
|
||||
MREG Output pipelining
|
||||
DSP u_matmul_axi_slave/mult_inst[3].u_mult/prod_reg__0 multiplier stage u_matmul_axi_slave/mult_inst[3].u_mult/prod_reg__0/P[47:0] is not pipelined (MREG=0). Pipelining the multiplier function will improve performance and will save significant power so it is suggested whenever possible to fully pipeline this function. If this multiplier was inferred, it is suggested to describe an additional register stage after this function. If there is no registered adder/accumulator following the multiply function, two pipeline stages are suggested to allow both the MREG and PREG registers to be used. If the DSP48 was instantiated in the design, it is suggested to set both the MREG and PREG attributes to 1 when performing multiply functions.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#1 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[0]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#2 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[1]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#3 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[2]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#4 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[3]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#5 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[4]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#6 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[5]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#7 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[6]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#8 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[7]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#9 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[8]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#10 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[13] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[8]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[9]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#11 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[0]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#12 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[1]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#13 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[2]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#14 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[3]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#15 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[4]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#16 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[5]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#17 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[6]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#18 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[7]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#19 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[8]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1839#20 Warning
|
||||
RAMB36 async control check
|
||||
The RAMB36E1 u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg has an input control pin u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ff_im_reg/ADDRARDADDR[14] (net: u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/TW/ADDRARDADDR[9]) which is driven by a register (u_fft_mlkem_axi_slave/u_fft_controller/u_FFT/SU1/bf2_count_reg[9]) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#1 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[10] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[5]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#2 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[11] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[6]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#3 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[12] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[7]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#4 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[5] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[0]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#5 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[6] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[1]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#6 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[7] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[2]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#7 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[8] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[3]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#8 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRARDADDR[9] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[4]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#9 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[10] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[5]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#10 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[11] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[6]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#11 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[12] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[7]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#12 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[5] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[0]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#13 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[6] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[1]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#14 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[7] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[2]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#15 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[8] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[3]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#16 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ADDRBWRADDR[9] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_addra[0][0]_26[4]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#17 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ENARDEN (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg_i_1__15_n_0) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#18 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/ENBWREN (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg_i_2__13_n_0) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#19 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/WEBWE[2] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_wea[0][0]_14[2]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
REQP-1840#20 Warning
|
||||
RAMB18 async control check
|
||||
The RAMB18E1 u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg has an input control pin u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/mem_reg_reg/WEBWE[3] (net: u_cpu/dcache/data_ram_way[0].data_ram_bank[0].u/way_bank_wea[0][0]_14[3]) which is driven by a register (u_Axi_CDC/rFifo/popCC_addressGen_rValid_reg) that has an active asychronous set or reset. This may cause corruption of the memory contents and/or read values when the set/reset is asserted and is not analyzed by the default static timing analysis. It is suggested to eliminate the use of a set/reset to registers driving this RAMB pin or else use a synchronous reset in which the assertion of the reset is timed by default.
|
||||
Related violations: <none>
|
||||
|
||||
|
||||
221
fpga/vivado_reports_withdsp/high_fanout.rpt
Normal file
@@ -0,0 +1,221 @@
|
||||
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 : Wed Jul 8 02:57:58 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_high_fanout_nets -fanout_greater_than 100 -max_nets 200 -file /home/fallensigh/vivado_reports_withdsp/high_fanout.rpt
|
||||
| Design : soc_top
|
||||
| Device : xc7a200t
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
High Fan-out Nets Information
|
||||
|
||||
1. Summary
|
||||
----------
|
||||
|
||||
+---------------------------------------------------------------------------------------+--------+-------------+
|
||||
| Net Name | Fanout | Driver Type |
|
||||
+---------------------------------------------------------------------------------------+--------+-------------+
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_c_in_bram/delay_reg[1] | 24229 | LUT5 |
|
||||
| pll_clk.u_clk_pll/inst/sys_clk | 9603 | BUFG |
|
||||
| pll_clk.u_rst_sys/prst | 3749 | LUT1 |
|
||||
| u_matmul_axi_slave/FSM_onehot_w_state_reg[1]_0 | 2140 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/sha3_mb_en | 2121 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/E[0] | 2048 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/busy_r_reg_n_0 | 1611 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/busy_r_reg_0[0] | 1608 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/FSM_onehot_mb_state[2]_i_3_n_0 | 1604 | LUT5 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/state_r[1599]_i_1_n_0 | 1601 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_snt/state_next[0] | 1601 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_snt/state_next[1] | 1601 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_snt/state_next[2] | 1601 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/mb_state_r[1599]_i_1_n_0 | 1600 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/busy_r_reg_1 | 1122 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_wb_inc_reg_n_0 | 1088 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_wb_inz_reg_n_0 | 1088 | FDRE |
|
||||
| pll_clk.u_rst_mlkem/delay_reg[1]_0 | 1066 | LUT1 |
|
||||
| u_cpu/reset | 799 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/sel0[3] | 773 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/j_reg[3]_rep[0] | 769 | CARRY4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/j_reg[3]_rep[1] | 769 | CARRY4 |
|
||||
| u_cpu/u_mul/E[0] | 716 | LUT1 |
|
||||
| u_matmul_axi_slave/w_addr[2] | 667 | FDRE |
|
||||
| u_matmul_axi_slave/w_addr[3] | 604 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/squeezed_state_r0 | 512 | LUT2 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/st_reg[0]_0[0] | 512 | LUT5 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/sel0[4] | 388 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/j_reg[3]_rep[2] | 385 | CARRY4 |
|
||||
| u_cpu/wb_stage/w_index[0] | 358 | LUT6 |
|
||||
| u_cpu/wb_stage/w_index[1] | 358 | LUT6 |
|
||||
| u_cpu/wb_stage/w_index[2] | 358 | LUT6 |
|
||||
| u_cpu/wb_stage/w_index[3] | 358 | LUT6 |
|
||||
| u_cpu/wb_stage/w_index[4] | 358 | LUT6 |
|
||||
| u_matmul_axi_slave/Q[0] | 354 | FDRE |
|
||||
| u_matmul_axi_slave/acc_idx_d4[0] | 354 | FDRE |
|
||||
| u_matmul_axi_slave/acc_idx_d4[1] | 354 | FDRE |
|
||||
| u_matmul_axi_slave/acc_idx_d4[2] | 354 | FDRE |
|
||||
| u_matmul_axi_slave/acc_idx_d4[3] | 354 | FDRE |
|
||||
| u_cpu/wb_stage/we_0 | 324 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/rho_r1 | 290 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/hek_r_reg[255]_i_5_n_4 | 288 | CARRY4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wa_r[4] | 272 | FDCE |
|
||||
| u_matmul_axi_slave/sel0[1] | 264 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[10] | 263 | RAMB18E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[11] | 263 | RAMB18E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[8] | 262 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/cbd_enc | 262 | LUT5 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[7] | 261 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[9] | 261 | RAMB18E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[0] | 261 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[10] | 261 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[11] | 261 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[1] | 261 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[2] | 261 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[3] | 261 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[4] | 261 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[5] | 261 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[6] | 261 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[7] | 261 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[8] | 261 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_se/DOBDO[9] | 261 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[0] | 259 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[1] | 259 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[2] | 259 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[3] | 259 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[4] | 259 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[5] | 259 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_a/rd_data[6] | 259 | RAMB36E1 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_t/ntt_in[0] | 256 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_t/ntt_in[10] | 256 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_t/ntt_in[11] | 256 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_t/ntt_in[1] | 256 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_t/ntt_in[2] | 256 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_t/ntt_in[3] | 256 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_t/ntt_in[4] | 256 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_t/ntt_in[5] | 256 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_t/ntt_in[6] | 256 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_t/ntt_in[7] | 256 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_t/ntt_in[8] | 256 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_bank_t/ntt_in[9] | 256 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/E[0] | 256 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_sha3/mb_digest_r | 256 | LUT3 |
|
||||
| u_matmul_axi_slave/mult_inst[0].u_mult/E[0] | 256 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_keccak/sha3_mode | 250 | LUT4 |
|
||||
| u_snix_axil_cdma_mux_8ch/u_core_engine/wr_start_edge | 245 | LUT3 |
|
||||
| u_matmul_axi_slave/FSM_onehot_w_state_reg_n_0_[0] | 244 | FDSE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wa_r[7] | 239 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wa_r[2] | 238 | FDCE |
|
||||
| u_cpu/exe_stage/ds_to_es_bus_r0 | 234 | LUT5 |
|
||||
| u_cpu/mem_stage/E[0] | 234 | LUT6 |
|
||||
| u_snix_axil_cdma_mux_8ch/u_core_engine/axis_fifo_u0/u_fifo/axiOut_7_wstrb[0] | 232 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[0] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[10] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[11] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[1] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[2] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[3] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[4] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[5] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[6] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[7] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[8] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_a_data_r[9] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[0] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[10] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[11] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[1] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[2] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[3] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[4] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[5] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[6] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[7] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[8] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_b_data_r[9] | 231 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[1022]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[126]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[254]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[382]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[510]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[638]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[766]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[894]_i_2_n_0 | 224 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wa_r[5] | 223 | FDCE |
|
||||
| u_matmul_axi_slave/w_addr[5] | 223 | FDRE |
|
||||
| u_axi_axil_adapter/axi_axil_adapter_wr_inst/delay_reg[1]_0 | 211 | LUT2 |
|
||||
| u_cpu/mem_stage/es_to_ms_bus_r0 | 210 | LUT2 |
|
||||
| u_cpu/u_csr/tlbw_r_tlbidx[2] | 210 | FDRE |
|
||||
| u_snix_axil_cdma_mux_8ch/cur_ch_reg_n_0_[0] | 203 | FDRE |
|
||||
| u_snix_axil_cdma_mux_8ch/cur_ch_reg_n_0_[1] | 203 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_snt/grp_ptr_r_reg_n_0_[2] | 196 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wa_r[6] | 195 | FDCE |
|
||||
| u_cpu/wb_stage/Q[33] | 194 | FDRE |
|
||||
| u_cpu/wb_stage/Q[34] | 194 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_cbd/buf_ptr_reg_n_0_[5] | 194 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/u_bf/u_barrett/j_reg[3]_rep[3] | 193 | CARRY4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wb_r[4] | 188 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wb_r_reg[3]_rep_n_0 | 187 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wb_r[1] | 184 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wb_r[6] | 184 | FDCE |
|
||||
| u_snix_axil_cdma_mux_8ch/u_core_engine/_zz_ram_port1_reg[32] | 182 | LUT4 |
|
||||
| u_cpu/wb_stage/ws_valid_reg_0 | 180 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wb_r_reg[5]_rep_n_0 | 180 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wa_r[1] | 179 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wb_r[0] | 177 | FDCE |
|
||||
| u_matmul_axi_slave/p_0_in__0 | 176 | LUT4 |
|
||||
| u_matmul_axi_slave/p_0_in__0__0 | 176 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/p_0_in[2] | 174 | FDCE |
|
||||
| u_cpu/wb_stage/Q[37] | 173 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/p_0_out[0] | 169 | CARRY4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/w_addr_reg[2]_rep__0_n_0 | 168 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/load_cnt[4] | 165 | FDCE |
|
||||
| u_cpu/wb_stage/Q[32] | 164 | FDRE |
|
||||
| u_cpu/wb_stage/Q[35] | 163 | FDRE |
|
||||
| u_cpu/wb_stage/Q[36] | 162 | FDRE |
|
||||
| u_axi_axil_adapter/axi_axil_adapter_rd_inst/m_axil_araddr_reg_reg[2]_0 | 161 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/load_cnt[6] | 161 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/wb_wa_r[0] | 160 | FDCE |
|
||||
| u_snix_axil_cdma_mux_8ch/FSM_sequential_ext_wr_state_reg[1]_0 | 160 | LUT5 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/load_cnt[3] | 158 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/p_0_in[3] | 156 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/hek_r_reg[255]_i_5_n_5 | 153 | CARRY4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/load_cnt[0] | 153 | FDCE |
|
||||
| u_cpu/axi_bridge/FSM_sequential_write_requst_state_reg[1]_0 | 151 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/st_reg[3]_rep_n_0 | 151 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_ntt/load_cnt[7] | 151 | FDCE |
|
||||
| u_snix_axil_cdma_mux_8ch/u_core_engine/num_bytes_comb1 | 150 | CARRY4 |
|
||||
| u_cpu/dcache/awaddr[31]_i_3_n_0 | 148 | LUT2 |
|
||||
| u_cpu/dcache/awaddr[31]_i_4_n_0 | 148 | LUT2 |
|
||||
| u_matmul_axi_slave/mult_inst[3].u_mult/FSM_sequential_state_reg | 148 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/st[4] | 146 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/ram_reg_0_7_12_17_i_57_n_0 | 144 | LUT4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt[1] | 142 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_wb_idx_reg_n_0_[4] | 141 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_wb_idx_reg_n_0_[5] | 141 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_wb_idx_reg_n_0_[6] | 141 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_wb_idx_reg_n_0_[7] | 141 | FDCE |
|
||||
| u_cpu/dcache/write_buffer_state | 140 | FDRE |
|
||||
| u_matmul_axi_slave/mult_inst[3].u_mult/cur_bank_reg_rep | 140 | LUT3 |
|
||||
| u_matmul_axi_slave/mult_inst[3].u_mult/req_0_reg | 140 | LUT3 |
|
||||
| u_snix_axil_cdma_mux_8ch/ADDRA[0] | 140 | LUT6 |
|
||||
| u_cpu/u_csr/tlbw_r_tlbidx[0] | 139 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt[3] | 139 | FDCE |
|
||||
| u_matmul_axi_slave/sel0[0] | 139 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_wb_idx_reg_n_0_[3] | 138 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/u_pmul/load_cnt[2] | 138 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/d_word_reg[1][31]_i_5_n_7 | 137 | CARRY4 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/ram_reg_0_7_6_11_i_34_n_0 | 137 | LUT4 |
|
||||
| u_cpu/u_csr/tlbw_r_tlbidx[1] | 136 | FDRE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[1080]_i_5_n_0 | 136 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[1081]_i_5_n_0 | 136 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[1082]_i_5_n_0 | 136 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[1083]_i_5_n_0 | 136 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[1084]_i_6_n_0 | 136 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[1087]_i_3_n_0 | 136 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/dj_block_r[1087]_i_9_n_0 | 136 | LUT6 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/h_block_r[1087]_i_3_n_0 | 136 | LUT3 |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/rl_idx[3] | 136 | FDCE |
|
||||
| u_fft_mlkem_axi_slave/u_mlkem_axi_slave/u_mlkem/st_reg[2]_rep_n_0 | 136 | FDCE |
|
||||
+---------------------------------------------------------------------------------------+--------+-------------+
|
||||
|
||||
|
||||
1653
fpga/vivado_reports_withdsp/methodology.rpt
Normal file
5918
fpga/vivado_reports_withdsp/mlkem_clk_timing.rpt
Normal file
179
fpga/vivado_reports_withdsp/power.rpt
Normal file
@@ -0,0 +1,179 @@
|
||||
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 : Wed Jul 8 02:58:09 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_power -file /home/fallensigh/vivado_reports_withdsp/power.rpt
|
||||
| Design : soc_top
|
||||
| Device : xc7a200tfbg676-1
|
||||
| Design State : routed
|
||||
| Grade : commercial
|
||||
| Process : typical
|
||||
| Characterization : Production
|
||||
--------------------------------------------------------------------------------------------------
|
||||
|
||||
Power Report
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1. Summary
|
||||
1.1 On-Chip Components
|
||||
1.2 Power Supply Summary
|
||||
1.3 Confidence Level
|
||||
2. Settings
|
||||
2.1 Environment
|
||||
2.2 Clock Constraints
|
||||
3. Detailed Reports
|
||||
3.1 By Hierarchy
|
||||
|
||||
1. Summary
|
||||
----------
|
||||
|
||||
+--------------------------+--------------+
|
||||
| Total On-Chip Power (W) | 0.512 |
|
||||
| Design Power Budget (W) | Unspecified* |
|
||||
| Power Budget Margin (W) | NA |
|
||||
| Dynamic (W) | 0.371 |
|
||||
| Device Static (W) | 0.141 |
|
||||
| Effective TJA (C/W) | 1.9 |
|
||||
| Max Ambient (C) | 84.0 |
|
||||
| Junction Temperature (C) | 26.0 |
|
||||
| Confidence Level | Low |
|
||||
| Setting File | --- |
|
||||
| Simulation Activity File | --- |
|
||||
| Design Nets Matched | NA |
|
||||
+--------------------------+--------------+
|
||||
* Specify Design Power Budget using, set_operating_conditions -design_power_budget <value in Watts>
|
||||
|
||||
|
||||
1.1 On-Chip Components
|
||||
----------------------
|
||||
|
||||
+--------------------------+-----------+----------+-----------+-----------------+
|
||||
| On-Chip | Power (W) | Used | Available | Utilization (%) |
|
||||
+--------------------------+-----------+----------+-----------+-----------------+
|
||||
| Clocks | 0.037 | 7 | --- | --- |
|
||||
| Slice Logic | 0.056 | 109753 | --- | --- |
|
||||
| LUT as Logic | 0.052 | 56469 | 133800 | 42.20 |
|
||||
| CARRY4 | 0.001 | 1802 | 33450 | 5.39 |
|
||||
| Register | <0.001 | 39141 | 267600 | 14.63 |
|
||||
| LUT as Shift Register | <0.001 | 1175 | 46200 | 2.54 |
|
||||
| LUT as Distributed RAM | <0.001 | 740 | 46200 | 1.60 |
|
||||
| F7/F8 Muxes | <0.001 | 6090 | 133800 | 4.55 |
|
||||
| Others | 0.000 | 334 | --- | --- |
|
||||
| Signals | 0.095 | 78236 | --- | --- |
|
||||
| Block RAM | 0.018 | 23.5 | 365 | 6.44 |
|
||||
| PLL | 0.132 | 1 | 10 | 10.00 |
|
||||
| DSPs | 0.010 | 56 | 740 | 7.57 |
|
||||
| I/O | 0.023 | 202 | 400 | 50.50 |
|
||||
| Static Power | 0.141 | | | |
|
||||
| Total | 0.512 | | | |
|
||||
+--------------------------+-----------+----------+-----------+-----------------+
|
||||
|
||||
|
||||
1.2 Power Supply Summary
|
||||
------------------------
|
||||
|
||||
+-----------+-------------+-----------+-------------+------------+
|
||||
| Source | Voltage (V) | Total (A) | Dynamic (A) | Static (A) |
|
||||
+-----------+-------------+-----------+-------------+------------+
|
||||
| Vccint | 1.000 | 0.257 | 0.225 | 0.032 |
|
||||
| Vccaux | 1.800 | 0.099 | 0.069 | 0.031 |
|
||||
| Vcco33 | 3.300 | 0.011 | 0.006 | 0.005 |
|
||||
| Vcco25 | 2.500 | 0.000 | 0.000 | 0.000 |
|
||||
| Vcco18 | 1.800 | 0.000 | 0.000 | 0.000 |
|
||||
| Vcco15 | 1.500 | 0.000 | 0.000 | 0.000 |
|
||||
| Vcco135 | 1.350 | 0.000 | 0.000 | 0.000 |
|
||||
| Vcco12 | 1.200 | 0.000 | 0.000 | 0.000 |
|
||||
| Vccaux_io | 1.800 | 0.000 | 0.000 | 0.000 |
|
||||
| Vccbram | 1.000 | 0.003 | 0.001 | 0.001 |
|
||||
| MGTAVcc | 1.000 | 0.000 | 0.000 | 0.000 |
|
||||
| MGTAVtt | 1.200 | 0.000 | 0.000 | 0.000 |
|
||||
| Vccadc | 1.800 | 0.020 | 0.000 | 0.020 |
|
||||
+-----------+-------------+-----------+-------------+------------+
|
||||
|
||||
|
||||
1.3 Confidence Level
|
||||
--------------------
|
||||
|
||||
+-----------------------------+------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------+
|
||||
| User Input Data | Confidence | Details | Action |
|
||||
+-----------------------------+------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------+
|
||||
| Design implementation state | High | Design is routed | |
|
||||
| Clock nodes activity | High | User specified more than 95% of clocks | |
|
||||
| I/O nodes activity | Low | More than 75% of inputs are missing user specification | Provide missing input activity with simulation results or by editing the "By Resource Type -> I/Os" view |
|
||||
| Internal nodes activity | Medium | User specified less than 25% of internal nodes | Provide missing internal nodes activity with simulation results or by editing the "By Resource Type" views |
|
||||
| Device models | High | Device models are Production | |
|
||||
| | | | |
|
||||
| Overall confidence level | Low | | |
|
||||
+-----------------------------+------------+--------------------------------------------------------+------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
2. Settings
|
||||
-----------
|
||||
|
||||
2.1 Environment
|
||||
---------------
|
||||
|
||||
+-----------------------+--------------------------+
|
||||
| Ambient Temp (C) | 25.0 |
|
||||
| ThetaJA (C/W) | 1.9 |
|
||||
| Airflow (LFM) | 250 |
|
||||
| Heat Sink | medium (Medium Profile) |
|
||||
| ThetaSA (C/W) | 3.4 |
|
||||
| Board Selection | medium (10"x10") |
|
||||
| # of Board Layers | 12to15 (12 to 15 Layers) |
|
||||
| Board Temperature (C) | 25.0 |
|
||||
+-----------------------+--------------------------+
|
||||
|
||||
|
||||
2.2 Clock Constraints
|
||||
---------------------
|
||||
|
||||
+-------------------+------------------------------------------+-----------------+
|
||||
| Clock | Domain | Constraint (ns) |
|
||||
+-------------------+------------------------------------------+-----------------+
|
||||
| clk | clk | 20.0 |
|
||||
| clkfbout_clk_pll | pll_clk.u_clk_pll/inst/clkfbout_clk_pll | 20.0 |
|
||||
| cpu_clk | pll_clk.u_clk_pll/inst/cpu_clk_clk_pll | 30.3 |
|
||||
| mlkem_clk_clk_pll | pll_clk.u_clk_pll/inst/mlkem_clk_clk_pll | 40.0 |
|
||||
| sys_clk | pll_clk.u_clk_pll/inst/sys_clk_clk_pll | 20.0 |
|
||||
+-------------------+------------------------------------------+-----------------+
|
||||
|
||||
|
||||
3. Detailed Reports
|
||||
-------------------
|
||||
|
||||
3.1 By Hierarchy
|
||||
----------------
|
||||
|
||||
+----------------------------+-----------+
|
||||
| Name | Power (W) |
|
||||
+----------------------------+-----------+
|
||||
| soc_top | 0.371 |
|
||||
| pll_clk.u_clk_pll | 0.133 |
|
||||
| inst | 0.133 |
|
||||
| u_Axi_CDC | 0.002 |
|
||||
| wFifo | 0.001 |
|
||||
| u_axi_uart_controller | 0.001 |
|
||||
| u_cdma_matmul_bridge | 0.001 |
|
||||
| u_cpu | 0.017 |
|
||||
| addr_trans | 0.002 |
|
||||
| tlb_entry | 0.002 |
|
||||
| btb | 0.003 |
|
||||
| dcache | 0.004 |
|
||||
| icache | 0.005 |
|
||||
| u_csr | 0.001 |
|
||||
| u_fft_mlkem_axi_slave | 0.134 |
|
||||
| u_fft_controller | 0.032 |
|
||||
| u_FFT | 0.030 |
|
||||
| u_mlkem_axi_cdc | 0.001 |
|
||||
| u_mlkem_axi_slave | 0.101 |
|
||||
| u_mlkem | 0.098 |
|
||||
| u_matmul_axi_slave | 0.047 |
|
||||
| u_snix_axil_cdma_mux_8ch | 0.008 |
|
||||
| u_core_engine | 0.004 |
|
||||
| axis_fifo_u0 | 0.002 |
|
||||
+----------------------------+-----------+
|
||||
|
||||
|
||||
BIN
fpga/vivado_reports_withdsp/resource.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
12
fpga/vivado_reports_withdsp/route_status.rpt
Normal file
@@ -0,0 +1,12 @@
|
||||
Design Route Status
|
||||
: # nets :
|
||||
------------------------------------------- : ----------- :
|
||||
# of logical nets.......................... : 116330 :
|
||||
# of nets not needing routing.......... : 38083 :
|
||||
# of internally routed nets........ : 37618 :
|
||||
# of nets with no loads............ : 465 :
|
||||
# of routable nets..................... : 78247 :
|
||||
# of fully routed nets............. : 78247 :
|
||||
# of nets with routing errors.......... : 0 :
|
||||
------------------------------------------- : ----------- :
|
||||
|
||||
16762
fpga/vivado_reports_withdsp/timing_hold_paths.rpt
Normal file
33570
fpga/vivado_reports_withdsp/timing_setup_paths.rpt
Normal file
39192
fpga/vivado_reports_withdsp/timing_summary_full.rpt
Normal file
32172
fpga/vivado_reports_withdsp/timing_summary_hold_full.rpt
Normal file
237
fpga/vivado_reports_withdsp/utilization.rpt
Normal file
@@ -0,0 +1,237 @@
|
||||
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 : Wed Jul 8 02:57:49 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_utilization -file /home/fallensigh/vivado_reports_withdsp/utilization.rpt
|
||||
| Design : soc_top
|
||||
| Device : 7a200tfbg676-1
|
||||
| Design State : Routed
|
||||
--------------------------------------------------------------------------------------------------
|
||||
|
||||
Utilization Design Information
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1. Slice Logic
|
||||
1.1 Summary of Registers by Type
|
||||
2. Slice Logic Distribution
|
||||
3. Memory
|
||||
4. DSP
|
||||
5. IO and GT Specific
|
||||
6. Clocking
|
||||
7. Specific Feature
|
||||
8. Primitives
|
||||
9. Black Boxes
|
||||
10. Instantiated Netlists
|
||||
|
||||
1. Slice Logic
|
||||
--------------
|
||||
|
||||
+----------------------------+-------+-------+-----------+-------+
|
||||
| Site Type | Used | Fixed | Available | Util% |
|
||||
+----------------------------+-------+-------+-----------+-------+
|
||||
| Slice LUTs | 53691 | 0 | 133800 | 40.13 |
|
||||
| LUT as Logic | 51836 | 0 | 133800 | 38.74 |
|
||||
| LUT as Memory | 1855 | 0 | 46200 | 4.02 |
|
||||
| LUT as Distributed RAM | 740 | 0 | | |
|
||||
| LUT as Shift Register | 1115 | 0 | | |
|
||||
| Slice Registers | 39141 | 0 | 267600 | 14.63 |
|
||||
| Register as Flip Flop | 39141 | 0 | 267600 | 14.63 |
|
||||
| Register as Latch | 0 | 0 | 267600 | 0.00 |
|
||||
| F7 Muxes | 4519 | 0 | 66900 | 6.75 |
|
||||
| F8 Muxes | 1571 | 0 | 33450 | 4.70 |
|
||||
+----------------------------+-------+-------+-----------+-------+
|
||||
|
||||
|
||||
1.1 Summary of Registers by Type
|
||||
--------------------------------
|
||||
|
||||
+-------+--------------+-------------+--------------+
|
||||
| Total | Clock Enable | Synchronous | Asynchronous |
|
||||
+-------+--------------+-------------+--------------+
|
||||
| 0 | _ | - | - |
|
||||
| 0 | _ | - | Set |
|
||||
| 0 | _ | - | Reset |
|
||||
| 0 | _ | Set | - |
|
||||
| 0 | _ | Reset | - |
|
||||
| 0 | Yes | - | - |
|
||||
| 24 | Yes | - | Set |
|
||||
| 26265 | Yes | - | Reset |
|
||||
| 126 | Yes | Set | - |
|
||||
| 12726 | Yes | Reset | - |
|
||||
+-------+--------------+-------------+--------------+
|
||||
|
||||
|
||||
2. Slice Logic Distribution
|
||||
---------------------------
|
||||
|
||||
+--------------------------------------------+-------+-------+-----------+-------+
|
||||
| Site Type | Used | Fixed | Available | Util% |
|
||||
+--------------------------------------------+-------+-------+-----------+-------+
|
||||
| Slice | 18732 | 0 | 33450 | 56.00 |
|
||||
| SLICEL | 12122 | 0 | | |
|
||||
| SLICEM | 6610 | 0 | | |
|
||||
| LUT as Logic | 51836 | 0 | 133800 | 38.74 |
|
||||
| using O5 output only | 4 | | | |
|
||||
| using O6 output only | 43877 | | | |
|
||||
| using O5 and O6 | 7955 | | | |
|
||||
| LUT as Memory | 1855 | 0 | 46200 | 4.02 |
|
||||
| LUT as Distributed RAM | 740 | 0 | | |
|
||||
| using O5 output only | 0 | | | |
|
||||
| using O6 output only | 60 | | | |
|
||||
| using O5 and O6 | 680 | | | |
|
||||
| LUT as Shift Register | 1115 | 0 | | |
|
||||
| using O5 output only | 47 | | | |
|
||||
| using O6 output only | 1008 | | | |
|
||||
| using O5 and O6 | 60 | | | |
|
||||
| Slice Registers | 39141 | 0 | 267600 | 14.63 |
|
||||
| Register driven from within the Slice | 19059 | | | |
|
||||
| Register driven from outside the Slice | 20082 | | | |
|
||||
| LUT in front of the register is unused | 11401 | | | |
|
||||
| LUT in front of the register is used | 8681 | | | |
|
||||
| Unique Control Sets | 1440 | | 33450 | 4.30 |
|
||||
+--------------------------------------------+-------+-------+-----------+-------+
|
||||
* Note: Available Control Sets calculated as Slice Registers / 8, Review the Control Sets Report for more information regarding control sets.
|
||||
|
||||
|
||||
3. Memory
|
||||
---------
|
||||
|
||||
+-------------------+------+-------+-----------+-------+
|
||||
| Site Type | Used | Fixed | Available | Util% |
|
||||
+-------------------+------+-------+-----------+-------+
|
||||
| Block RAM Tile | 23.5 | 0 | 365 | 6.44 |
|
||||
| RAMB36/FIFO* | 8 | 0 | 365 | 2.19 |
|
||||
| RAMB36E1 only | 8 | | | |
|
||||
| RAMB18 | 31 | 0 | 730 | 4.25 |
|
||||
| RAMB18E1 only | 31 | | | |
|
||||
+-------------------+------+-------+-----------+-------+
|
||||
* 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
|
||||
|
||||
|
||||
4. DSP
|
||||
------
|
||||
|
||||
+----------------+------+-------+-----------+-------+
|
||||
| Site Type | Used | Fixed | Available | Util% |
|
||||
+----------------+------+-------+-----------+-------+
|
||||
| DSPs | 56 | 0 | 740 | 7.57 |
|
||||
| DSP48E1 only | 56 | | | |
|
||||
+----------------+------+-------+-----------+-------+
|
||||
|
||||
|
||||
5. IO and GT Specific
|
||||
---------------------
|
||||
|
||||
+-----------------------------+------+-------+-----------+-------+
|
||||
| Site Type | Used | Fixed | Available | Util% |
|
||||
+-----------------------------+------+-------+-----------+-------+
|
||||
| Bonded IOB | 202 | 202 | 400 | 50.50 |
|
||||
| IOB Master Pads | 97 | | | |
|
||||
| IOB Slave Pads | 102 | | | |
|
||||
| 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 |
|
||||
+-----------------------------+------+-------+-----------+-------+
|
||||
|
||||
|
||||
6. Clocking
|
||||
-----------
|
||||
|
||||
+------------+------+-------+-----------+-------+
|
||||
| Site Type | Used | Fixed | Available | Util% |
|
||||
+------------+------+-------+-----------+-------+
|
||||
| BUFGCTRL | 4 | 0 | 32 | 12.50 |
|
||||
| BUFIO | 0 | 0 | 40 | 0.00 |
|
||||
| MMCME2_ADV | 0 | 0 | 10 | 0.00 |
|
||||
| PLLE2_ADV | 1 | 0 | 10 | 10.00 |
|
||||
| BUFMRCE | 0 | 0 | 20 | 0.00 |
|
||||
| BUFHCE | 0 | 0 | 120 | 0.00 |
|
||||
| BUFR | 0 | 0 | 40 | 0.00 |
|
||||
+------------+------+-------+-----------+-------+
|
||||
|
||||
|
||||
7. 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 |
|
||||
+-------------+------+-------+-----------+-------+
|
||||
|
||||
|
||||
8. Primitives
|
||||
-------------
|
||||
|
||||
+-----------+-------+---------------------+
|
||||
| Ref Name | Used | Functional Category |
|
||||
+-----------+-------+---------------------+
|
||||
| LUT6 | 29130 | LUT |
|
||||
| FDCE | 26265 | Flop & Latch |
|
||||
| FDRE | 12726 | Flop & Latch |
|
||||
| LUT5 | 8459 | LUT |
|
||||
| LUT3 | 8166 | LUT |
|
||||
| LUT4 | 8097 | LUT |
|
||||
| LUT2 | 5229 | LUT |
|
||||
| MUXF7 | 4519 | MuxFx |
|
||||
| CARRY4 | 1802 | CarryLogic |
|
||||
| MUXF8 | 1571 | MuxFx |
|
||||
| RAMD32 | 1060 | Distributed Memory |
|
||||
| SRLC32E | 992 | Distributed Memory |
|
||||
| LUT1 | 710 | LUT |
|
||||
| RAMS32 | 328 | Distributed Memory |
|
||||
| SRL16E | 183 | Distributed Memory |
|
||||
| FDSE | 126 | Flop & Latch |
|
||||
| IBUF | 104 | IO |
|
||||
| OBUF | 98 | IO |
|
||||
| OBUFT | 66 | IO |
|
||||
| DSP48E1 | 56 | Block Arithmetic |
|
||||
| RAMD64E | 32 | Distributed Memory |
|
||||
| RAMB18E1 | 31 | Block Memory |
|
||||
| FDPE | 24 | Flop & Latch |
|
||||
| RAMB36E1 | 8 | Block Memory |
|
||||
| BUFG | 4 | Clock |
|
||||
| PLLE2_ADV | 1 | Clock |
|
||||
+-----------+-------+---------------------+
|
||||
|
||||
|
||||
9. Black Boxes
|
||||
--------------
|
||||
|
||||
+----------+------+
|
||||
| Ref Name | Used |
|
||||
+----------+------+
|
||||
|
||||
|
||||
10. Instantiated Netlists
|
||||
-------------------------
|
||||
|
||||
+----------+------+
|
||||
| Ref Name | Used |
|
||||
+----------+------+
|
||||
| clk_pll | 1 |
|
||||
+----------+------+
|
||||
|
||||
|
||||
276
fpga/vivado_reports_withdsp/utilization_hier.rpt
Normal file
@@ -0,0 +1,276 @@
|
||||
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 : Wed Jul 8 02:57:50 2026
|
||||
| Host : fedora running 64-bit unknown
|
||||
| Command : report_utilization -hierarchical -file /home/fallensigh/vivado_reports_withdsp/utilization_hier.rpt
|
||||
| Design : soc_top
|
||||
| Device : 7a200tfbg676-1
|
||||
| Design State : Routed
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Utilization Design Information
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1. Utilization by Hierarchy
|
||||
|
||||
1. Utilization by Hierarchy
|
||||
---------------------------
|
||||
|
||||
+------------------------------------------+------------------------------+------------+------------+---------+------+-------+--------+--------+--------------+
|
||||
| Instance | Module | Total LUTs | Logic LUTs | LUTRAMs | SRLs | FFs | RAMB36 | RAMB18 | DSP48 Blocks |
|
||||
+------------------------------------------+------------------------------+------------+------------+---------+------+-------+--------+--------+--------------+
|
||||
| soc_top | (top) | 53691 | 51836 | 740 | 1115 | 39141 | 8 | 31 | 56 |
|
||||
| (soc_top) | (top) | 102 | 46 | 56 | 0 | 9 | 0 | 0 | 0 |
|
||||
| pll_clk.u_clk_pll | clk_pll | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| inst | clk_pll__clk_pll_clk_wiz | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| pll_clk.u_rst_cpu | rst_sync | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| pll_clk.u_rst_mlkem | rst_sync_0 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| pll_clk.u_rst_sys | rst_sync_1 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| u_AxiCrossbar_2x8 | AxiCrossbar_2x8 | 381 | 381 | 0 | 0 | 151 | 0 | 0 | 0 |
|
||||
| (u_AxiCrossbar_2x8) | AxiCrossbar_2x8 | 6 | 6 | 0 | 0 | 24 | 0 | 0 | 0 |
|
||||
| axi4ReadOnlyArbiter_4 | Axi4ReadOnlyArbiter | 18 | 18 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_82 | 18 | 18 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| axi4ReadOnlyArbiter_5 | Axi4ReadOnlyArbiter_65 | 6 | 6 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_81 | 6 | 6 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| axi4ReadOnlyArbiter_6 | Axi4ReadOnlyArbiter_66 | 16 | 16 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_80 | 16 | 16 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| axi4ReadOnlyArbiter_7 | Axi4ReadOnlyArbiter_67 | 16 | 16 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_79 | 16 | 16 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| axi4WriteOnlyArbiter_4 | Axi4WriteOnlyArbiter | 33 | 33 | 0 | 0 | 11 | 0 | 0 | 0 |
|
||||
| (axi4WriteOnlyArbiter_4) | Axi4WriteOnlyArbiter | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_76 | 27 | 27 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdRouteFork_translated_fifo | StreamFifoLowLatency_3_77 | 7 | 7 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| fifo | StreamFifo_3_78 | 7 | 7 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| axi4WriteOnlyArbiter_5 | Axi4WriteOnlyArbiter_1 | 15 | 15 | 0 | 0 | 9 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_73 | 7 | 7 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdRouteFork_translated_fifo | StreamFifoLowLatency_3_74 | 8 | 8 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| fifo | StreamFifo_3_75 | 8 | 8 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| axi4WriteOnlyArbiter_6 | Axi4WriteOnlyArbiter_2 | 29 | 29 | 0 | 0 | 11 | 0 | 0 | 0 |
|
||||
| (axi4WriteOnlyArbiter_6) | Axi4WriteOnlyArbiter_2 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7_70 | 20 | 20 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdRouteFork_translated_fifo | StreamFifoLowLatency_3_71 | 9 | 9 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| fifo | StreamFifo_3_72 | 9 | 9 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| axi4WriteOnlyArbiter_7 | Axi4WriteOnlyArbiter_3 | 23 | 23 | 0 | 0 | 11 | 0 | 0 | 0 |
|
||||
| (axi4WriteOnlyArbiter_7) | Axi4WriteOnlyArbiter_3 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| cmdArbiter | StreamArbiter_7 | 15 | 15 | 0 | 0 | 3 | 0 | 0 | 0 |
|
||||
| cmdRouteFork_translated_fifo | StreamFifoLowLatency_3 | 8 | 8 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| fifo | StreamFifo_3 | 8 | 8 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| axiIn_0_readOnly_decoder | Axi4ReadOnlyDecoder | 96 | 96 | 0 | 0 | 25 | 0 | 0 | 0 |
|
||||
| (axiIn_0_readOnly_decoder) | Axi4ReadOnlyDecoder | 75 | 75 | 0 | 0 | 12 | 0 | 0 | 0 |
|
||||
| errorSlave | Axi4ReadOnlyErrorSlave_1_69 | 21 | 21 | 0 | 0 | 13 | 0 | 0 | 0 |
|
||||
| axiIn_0_writeOnly_decoder | Axi4WriteOnlyDecoder | 40 | 40 | 0 | 0 | 18 | 0 | 0 | 0 |
|
||||
| (axiIn_0_writeOnly_decoder) | Axi4WriteOnlyDecoder | 20 | 20 | 0 | 0 | 16 | 0 | 0 | 0 |
|
||||
| errorSlave | Axi4WriteOnlyErrorSlave_1_68 | 21 | 21 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| axiIn_1_readOnly_decoder | Axi4ReadOnlyDecoder_1 | 53 | 53 | 0 | 0 | 17 | 0 | 0 | 0 |
|
||||
| (axiIn_1_readOnly_decoder) | Axi4ReadOnlyDecoder_1 | 38 | 38 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| errorSlave | Axi4ReadOnlyErrorSlave_1 | 15 | 15 | 0 | 0 | 9 | 0 | 0 | 0 |
|
||||
| axiIn_1_writeOnly_decoder | Axi4WriteOnlyDecoder_1 | 32 | 32 | 0 | 0 | 14 | 0 | 0 | 0 |
|
||||
| (axiIn_1_writeOnly_decoder) | Axi4WriteOnlyDecoder_1 | 20 | 20 | 0 | 0 | 12 | 0 | 0 | 0 |
|
||||
| errorSlave | Axi4WriteOnlyErrorSlave_1 | 12 | 12 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| u_Axi_CDC | Axi_CDC | 412 | 284 | 128 | 0 | 317 | 0 | 0 | 0 |
|
||||
| arFifo | StreamFifoCC_3_48 | 185 | 149 | 36 | 0 | 77 | 0 | 0 | 0 |
|
||||
| (arFifo) | StreamFifoCC_3_48 | 180 | 144 | 36 | 0 | 65 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC_9_63 | 1 | 1 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_11_64 | 4 | 4 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| awFifo | StreamFifoCC_49 | 102 | 66 | 36 | 0 | 79 | 0 | 0 | 0 |
|
||||
| (awFifo) | StreamFifoCC_49 | 98 | 62 | 36 | 0 | 65 | 0 | 0 | 0 |
|
||||
| bufferCC_12 | BufferCC_10_60 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC_9_61 | 2 | 2 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_11_62 | 1 | 1 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| bFifo | StreamFifoCC_2_50 | 14 | 14 | 0 | 0 | 26 | 0 | 0 | 0 |
|
||||
| (bFifo) | StreamFifoCC_2_50 | 7 | 7 | 0 | 0 | 12 | 0 | 0 | 0 |
|
||||
| bufferCC_12 | BufferCC_5_57 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC_4_58 | 2 | 2 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_6_59 | 4 | 4 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| rFifo | StreamFifoCC_4_51 | 45 | 17 | 28 | 0 | 66 | 0 | 0 | 0 |
|
||||
| (rFifo) | StreamFifoCC_4_51 | 41 | 13 | 28 | 0 | 50 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC_55 | 3 | 3 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_1_56 | 2 | 2 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| wFifo | StreamFifoCC_1_52 | 66 | 38 | 28 | 0 | 69 | 0 | 0 | 0 |
|
||||
| (wFifo) | StreamFifoCC_1_52 | 62 | 34 | 28 | 0 | 53 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC_7_53 | 3 | 3 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_8_54 | 2 | 2 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| u_axi_axil_adapter | axi_axil_adapter | 1072 | 1072 | 0 | 0 | 173 | 0 | 0 | 0 |
|
||||
| axi_axil_adapter_rd_inst | axi_axil_adapter_rd | 497 | 497 | 0 | 0 | 85 | 0 | 0 | 0 |
|
||||
| axi_axil_adapter_wr_inst | axi_axil_adapter_wr | 575 | 575 | 0 | 0 | 88 | 0 | 0 | 0 |
|
||||
| u_axi_dvi | axi_dvi | 284 | 284 | 0 | 0 | 211 | 0 | 0 | 0 |
|
||||
| u_axi_ram | axi_wrap_ram_sp_external | 351 | 351 | 0 | 0 | 78 | 0 | 0 | 0 |
|
||||
| u_axi_sram_sp | axi2sram_sp_external | 351 | 351 | 0 | 0 | 78 | 0 | 0 | 0 |
|
||||
| u_axi_uart_controller | axi_uart_controller | 683 | 667 | 16 | 0 | 457 | 0 | 0 | 0 |
|
||||
| AA_axi2apb_bridge_cpu | axi2apb_bridge | 251 | 251 | 0 | 0 | 120 | 0 | 0 | 0 |
|
||||
| uart0 | UART_TOP | 432 | 416 | 16 | 0 | 337 | 0 | 0 | 0 |
|
||||
| regs | uart_regs | 432 | 416 | 16 | 0 | 337 | 0 | 0 | 0 |
|
||||
| (regs) | uart_regs | 119 | 119 | 0 | 0 | 155 | 0 | 0 | 0 |
|
||||
| i_uart_sync_flops | uart_sync_flops | 3 | 3 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| receiver | uart_receiver | 229 | 221 | 8 | 0 | 124 | 0 | 0 | 0 |
|
||||
| (receiver) | uart_receiver | 68 | 68 | 0 | 0 | 54 | 0 | 0 | 0 |
|
||||
| fifo_rx | uart_rfifo | 161 | 153 | 8 | 0 | 70 | 0 | 0 | 0 |
|
||||
| (fifo_rx) | uart_rfifo | 143 | 143 | 0 | 0 | 62 | 0 | 0 | 0 |
|
||||
| rfifo | raminfr_47 | 19 | 11 | 8 | 0 | 8 | 0 | 0 | 0 |
|
||||
| transmitter | uart_transmitter | 83 | 75 | 8 | 0 | 56 | 0 | 0 | 0 |
|
||||
| (transmitter) | uart_transmitter | 41 | 41 | 0 | 0 | 35 | 0 | 0 | 0 |
|
||||
| fifo_tx | uart_tfifo | 43 | 35 | 8 | 0 | 21 | 0 | 0 | 0 |
|
||||
| (fifo_tx) | uart_tfifo | 24 | 24 | 0 | 0 | 13 | 0 | 0 | 0 |
|
||||
| tfifo | raminfr | 19 | 11 | 8 | 0 | 8 | 0 | 0 | 0 |
|
||||
| u_cdma_matmul_bridge | cdma_matmul_bridge | 250 | 250 | 0 | 0 | 578 | 0 | 0 | 0 |
|
||||
| u_confreg | confreg | 390 | 390 | 0 | 0 | 476 | 0 | 0 | 0 |
|
||||
| (u_confreg) | confreg | 230 | 230 | 0 | 0 | 399 | 0 | 0 | 0 |
|
||||
| u_digitaltube_controller | digitaltube_controller | 16 | 16 | 0 | 0 | 24 | 0 | 0 | 0 |
|
||||
| u_int_ctrl | int_ctrl | 144 | 144 | 0 | 0 | 53 | 0 | 0 | 0 |
|
||||
| u_cpu | core_top | 8556 | 8304 | 252 | 0 | 5591 | 0 | 20 | 0 |
|
||||
| (u_cpu) | core_top | 519 | 519 | 0 | 0 | 1 | 0 | 0 | 0 |
|
||||
| addr_trans | addr_trans | 2247 | 2107 | 140 | 0 | 1244 | 0 | 0 | 0 |
|
||||
| (addr_trans) | addr_trans | 0 | 0 | 0 | 0 | 40 | 0 | 0 | 0 |
|
||||
| tlb_entry | tlb_entry | 2247 | 2107 | 140 | 0 | 1204 | 0 | 0 | 0 |
|
||||
| axi_bridge | axi_bridge | 39 | 39 | 0 | 0 | 214 | 0 | 0 | 0 |
|
||||
| btb | btb | 1048 | 968 | 80 | 0 | 1611 | 0 | 0 | 0 |
|
||||
| (btb) | btb | 1045 | 965 | 80 | 0 | 1611 | 0 | 0 | 0 |
|
||||
| dec_btb_add_entry | decoder_5_32 | 3 | 3 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| dcache | dcache | 552 | 520 | 32 | 0 | 146 | 0 | 10 | 0 |
|
||||
| (dcache) | dcache | 87 | 55 | 32 | 0 | 138 | 0 | 0 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[0].u | data_bank_sram_36 | 49 | 49 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[1].u | data_bank_sram_37 | 17 | 17 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[2].u | data_bank_sram_38 | 49 | 49 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[3].u | data_bank_sram_39 | 51 | 51 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[0].u | data_bank_sram_40 | 17 | 17 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[1].u | data_bank_sram_41 | 49 | 49 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[2].u | data_bank_sram_42 | 81 | 81 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[3].u | data_bank_sram_43 | 54 | 54 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| lfsr | lfsr_44 | 2 | 2 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| tagv_ram_way[0].u | tagv_sram_45 | 62 | 62 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| tagv_ram_way[1].u | tagv_sram_46 | 43 | 43 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| exe_stage | exe_stage | 665 | 665 | 0 | 0 | 233 | 0 | 0 | 0 |
|
||||
| (exe_stage) | exe_stage | 634 | 634 | 0 | 0 | 233 | 0 | 0 | 0 |
|
||||
| u_alu | alu | 33 | 33 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| icache | icache | 234 | 234 | 0 | 0 | 55 | 0 | 10 | 0 |
|
||||
| (icache) | icache | 12 | 12 | 0 | 0 | 47 | 0 | 0 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[0].u | data_bank_sram | 4 | 4 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[1].u | data_bank_sram_28 | 3 | 3 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[2].u | data_bank_sram_29 | 67 | 67 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[0].data_ram_bank[3].u | data_bank_sram_30 | 3 | 3 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[0].u | data_bank_sram_31 | 3 | 3 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[1].u | data_bank_sram_32 | 3 | 3 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[2].u | data_bank_sram_33 | 35 | 35 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| data_ram_way[1].data_ram_bank[3].u | data_bank_sram_34 | 4 | 4 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| lfsr | lfsr | 2 | 2 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| tagv_ram_way[0].u | tagv_sram | 15 | 15 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| tagv_ram_way[1].u | tagv_sram_35 | 88 | 88 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| id_stage | id_stage | 1052 | 1052 | 0 | 0 | 108 | 0 | 0 | 0 |
|
||||
| if_stage | if_stage | 134 | 134 | 0 | 0 | 173 | 0 | 0 | 0 |
|
||||
| mem_stage | mem_stage | 115 | 115 | 0 | 0 | 211 | 0 | 0 | 0 |
|
||||
| u_csr | csr | 200 | 200 | 0 | 0 | 663 | 0 | 0 | 0 |
|
||||
| u_div | div | 142 | 142 | 0 | 0 | 107 | 0 | 0 | 0 |
|
||||
| u_mul | mul | 933 | 933 | 0 | 0 | 592 | 0 | 0 | 0 |
|
||||
| wb_stage | wb_stage | 689 | 689 | 0 | 0 | 233 | 0 | 0 | 0 |
|
||||
| u_fft_mlkem_axi_slave | fft_mlkem_axi_slave | 32945 | 31724 | 112 | 1109 | 26787 | 8 | 10 | 40 |
|
||||
| (u_fft_mlkem_axi_slave) | fft_mlkem_axi_slave | 1 | 1 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| u_fft_controller | fft_controller | 2647 | 1607 | 0 | 1040 | 1083 | 6 | 4 | 16 |
|
||||
| (u_fft_controller) | fft_controller | 123 | 123 | 0 | 0 | 100 | 0 | 0 | 0 |
|
||||
| u_FFT | FFT | 2495 | 1455 | 0 | 1040 | 983 | 6 | 0 | 16 |
|
||||
| SU1 | SdfUnit | 1070 | 302 | 0 | 768 | 197 | 2 | 0 | 4 |
|
||||
| (SU1) | SdfUnit | 205 | 205 | 0 | 0 | 133 | 0 | 0 | 0 |
|
||||
| BF1 | Butterfly_24 | 16 | 16 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| BF2 | Butterfly__parameterized0_25 | 32 | 32 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| DB1 | DelayBuffer | 562 | 50 | 0 | 512 | 32 | 0 | 0 | 0 |
|
||||
| DB2 | DelayBuffer__parameterized0 | 256 | 0 | 0 | 256 | 32 | 0 | 0 | 0 |
|
||||
| MU | Multiply_26 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 |
|
||||
| TW | Twiddle_27 | 1 | 1 | 0 | 0 | 0 | 2 | 0 | 0 |
|
||||
| SU2 | SdfUnit__parameterized0 | 492 | 300 | 0 | 192 | 197 | 2 | 0 | 4 |
|
||||
| (SU2) | SdfUnit__parameterized0 | 73 | 73 | 0 | 0 | 133 | 0 | 0 | 0 |
|
||||
| BF1 | Butterfly_20 | 16 | 16 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| BF2 | Butterfly__parameterized0_21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| DB1 | DelayBuffer__parameterized1 | 240 | 112 | 0 | 128 | 32 | 0 | 0 | 0 |
|
||||
| DB2 | DelayBuffer__parameterized2 | 128 | 64 | 0 | 64 | 32 | 0 | 0 | 0 |
|
||||
| MU | Multiply_22 | 32 | 32 | 0 | 0 | 0 | 0 | 0 | 4 |
|
||||
| TW | Twiddle_23 | 3 | 3 | 0 | 0 | 0 | 2 | 0 | 0 |
|
||||
| SU3 | SdfUnit__parameterized1 | 347 | 299 | 0 | 48 | 197 | 0 | 0 | 4 |
|
||||
| (SU3) | SdfUnit__parameterized1 | 75 | 75 | 0 | 0 | 133 | 0 | 0 | 0 |
|
||||
| BF1 | Butterfly_17 | 16 | 16 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| BF2 | Butterfly__parameterized0_18 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| DB1 | DelayBuffer__parameterized3 | 144 | 112 | 0 | 32 | 32 | 0 | 0 | 0 |
|
||||
| DB2 | DelayBuffer__parameterized4 | 80 | 64 | 0 | 16 | 32 | 0 | 0 | 0 |
|
||||
| MU | Multiply_19 | 32 | 32 | 0 | 0 | 0 | 0 | 0 | 4 |
|
||||
| SU4 | SdfUnit__parameterized2 | 327 | 295 | 0 | 32 | 197 | 2 | 0 | 4 |
|
||||
| (SU4) | SdfUnit__parameterized2 | 69 | 69 | 0 | 0 | 133 | 0 | 0 | 0 |
|
||||
| BF1 | Butterfly_15 | 16 | 16 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| BF2 | Butterfly__parameterized0_16 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| DB1 | DelayBuffer__parameterized5 | 128 | 112 | 0 | 16 | 32 | 0 | 0 | 0 |
|
||||
| DB2 | DelayBuffer__parameterized6 | 80 | 64 | 0 | 16 | 32 | 0 | 0 | 0 |
|
||||
| MU | Multiply | 32 | 32 | 0 | 0 | 0 | 0 | 0 | 4 |
|
||||
| TW | Twiddle | 2 | 2 | 0 | 0 | 0 | 2 | 0 | 0 |
|
||||
| SU5 | SdfUnit__parameterized3 | 260 | 260 | 0 | 0 | 195 | 0 | 0 | 0 |
|
||||
| (SU5) | SdfUnit__parameterized3 | 68 | 68 | 0 | 0 | 99 | 0 | 0 | 0 |
|
||||
| BF1 | Butterfly | 16 | 16 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| BF2 | Butterfly__parameterized0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| DB1 | DelayBuffer__parameterized7 | 112 | 112 | 0 | 0 | 64 | 0 | 0 | 0 |
|
||||
| DB2 | DelayBuffer__parameterized8 | 64 | 64 | 0 | 0 | 32 | 0 | 0 | 0 |
|
||||
| u_in0 | my_bram0 | 3 | 3 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_in1 | my_bram0_12 | 2 | 2 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_out0 | my_bram0_13 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_out1 | my_bram0_14 | 25 | 25 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_mlkem_axi_cdc | Axi_CDC_5 | 256 | 144 | 112 | 0 | 272 | 0 | 0 | 0 |
|
||||
| arFifo | StreamFifoCC_3 | 51 | 23 | 28 | 0 | 55 | 0 | 0 | 0 |
|
||||
| (arFifo) | StreamFifoCC_3 | 42 | 14 | 28 | 0 | 43 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC_9_10 | 5 | 5 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_11_11 | 4 | 4 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| awFifo | StreamFifoCC | 40 | 16 | 24 | 0 | 49 | 0 | 0 | 0 |
|
||||
| (awFifo) | StreamFifoCC | 31 | 7 | 24 | 0 | 35 | 0 | 0 | 0 |
|
||||
| bufferCC_12 | BufferCC_10 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC_9 | 4 | 4 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_11 | 4 | 4 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| bFifo | StreamFifoCC_2 | 18 | 14 | 4 | 0 | 27 | 0 | 0 | 0 |
|
||||
| (bFifo) | StreamFifoCC_2 | 11 | 7 | 4 | 0 | 13 | 0 | 0 | 0 |
|
||||
| bufferCC_12 | BufferCC_5 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC_4 | 1 | 1 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_6 | 5 | 5 | 0 | 0 | 6 | 0 | 0 | 0 |
|
||||
| rFifo | StreamFifoCC_4 | 56 | 28 | 28 | 0 | 72 | 0 | 0 | 0 |
|
||||
| (rFifo) | StreamFifoCC_4 | 49 | 21 | 28 | 0 | 56 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC | 3 | 3 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_1 | 5 | 5 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| wFifo | StreamFifoCC_1 | 91 | 63 | 28 | 0 | 69 | 0 | 0 | 0 |
|
||||
| (wFifo) | StreamFifoCC_1 | 86 | 58 | 28 | 0 | 53 | 0 | 0 | 0 |
|
||||
| popToPushGray_buffercc | BufferCC_7 | 3 | 3 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| pushToPopGray_buffercc | BufferCC_8 | 3 | 3 | 0 | 0 | 8 | 0 | 0 | 0 |
|
||||
| u_mlkem_axi_slave | mlkem_axi_slave | 30043 | 29974 | 0 | 69 | 25426 | 2 | 6 | 24 |
|
||||
| (u_mlkem_axi_slave) | mlkem_axi_slave | 1278 | 1278 | 0 | 0 | 1064 | 0 | 0 | 0 |
|
||||
| u_mlkem | mlkem_top | 28768 | 28699 | 0 | 69 | 24362 | 2 | 6 | 24 |
|
||||
| (u_mlkem) | mlkem_top | 2326 | 2326 | 0 | 0 | 4911 | 0 | 0 | 0 |
|
||||
| u_bank_a | sd_bram__parameterized0 | 49 | 49 | 0 | 0 | 0 | 1 | 1 | 0 |
|
||||
| u_bank_se | sd_bram__parameterized1 | 61 | 61 | 0 | 0 | 0 | 1 | 0 | 0 |
|
||||
| u_bank_t | sd_bram__parameterized2 | 488 | 488 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_c_in_bram | sd_bram | 1291 | 1291 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_cbd | sample_cbd_sync_shared | 2512 | 2512 | 0 | 0 | 3199 | 0 | 0 | 0 |
|
||||
| u_comp | comp_decomp_sync | 322 | 321 | 0 | 1 | 269 | 0 | 0 | 3 |
|
||||
| u_ct_bram | sd_bram_6 | 15 | 15 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_dkp_bram | sd_bram_7 | 73 | 73 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_ek_bram | sd_bram_8 | 388 | 388 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
| u_keccak | keccak_core | 5622 | 5622 | 0 | 0 | 1606 | 0 | 0 | 0 |
|
||||
| u_ntt | ntt_core | 8192 | 8149 | 0 | 43 | 3743 | 0 | 0 | 6 |
|
||||
| (u_ntt) | ntt_core | 6140 | 6124 | 0 | 16 | 3364 | 0 | 0 | 0 |
|
||||
| u_bf | butterfly_unit_pipe | 1922 | 1896 | 0 | 26 | 224 | 0 | 0 | 3 |
|
||||
| (u_bf) | butterfly_unit_pipe | 69 | 44 | 0 | 25 | 75 | 0 | 0 | 0 |
|
||||
| u_barrett | barrett_mul_pipe_9 | 1854 | 1853 | 0 | 1 | 149 | 0 | 0 | 3 |
|
||||
| u_scl | barrett_mul_pipe | 131 | 130 | 0 | 1 | 155 | 0 | 0 | 3 |
|
||||
| u_pmul | poly_mul_sync | 2830 | 2805 | 0 | 25 | 6577 | 0 | 0 | 15 |
|
||||
| (u_pmul) | poly_mul_sync | 2474 | 2474 | 0 | 0 | 6299 | 0 | 0 | 0 |
|
||||
| u_bc | basecase_mul_pipe | 421 | 396 | 0 | 25 | 278 | 0 | 0 | 15 |
|
||||
| u_sha3 | sha3_top_shared | 3175 | 3175 | 0 | 0 | 2388 | 0 | 0 | 0 |
|
||||
| u_snt | sample_ntt_sync_shared | 1439 | 1439 | 0 | 0 | 1669 | 0 | 0 | 0 |
|
||||
| u_matmul_axi_slave | matmul_axi_slave | 6600 | 6418 | 176 | 6 | 2831 | 0 | 0 | 16 |
|
||||
| (u_matmul_axi_slave) | matmul_axi_slave | 5796 | 5614 | 176 | 6 | 2303 | 0 | 0 | 0 |
|
||||
| mult_inst[0].u_mult | pipelined_mult_32x32 | 203 | 203 | 0 | 0 | 132 | 0 | 0 | 4 |
|
||||
| mult_inst[1].u_mult | pipelined_mult_32x32_2 | 202 | 202 | 0 | 0 | 132 | 0 | 0 | 4 |
|
||||
| mult_inst[2].u_mult | pipelined_mult_32x32_3 | 202 | 202 | 0 | 0 | 132 | 0 | 0 | 4 |
|
||||
| mult_inst[3].u_mult | pipelined_mult_32x32_4 | 200 | 200 | 0 | 0 | 132 | 0 | 0 | 4 |
|
||||
| u_snix_axil_cdma_mux_8ch | snix_axil_cdma_mux | 1673 | 1673 | 0 | 0 | 1476 | 0 | 1 | 0 |
|
||||
| (u_snix_axil_cdma_mux_8ch) | snix_axil_cdma_mux | 687 | 687 | 0 | 0 | 1180 | 0 | 0 | 0 |
|
||||
| u_core_engine | snix_axi_mm2mm | 988 | 988 | 0 | 0 | 296 | 0 | 1 | 0 |
|
||||
| (u_core_engine) | snix_axi_mm2mm | 763 | 763 | 0 | 0 | 243 | 0 | 0 | 0 |
|
||||
| axis_fifo_u0 | snix_axis_fifo | 225 | 225 | 0 | 0 | 53 | 0 | 1 | 0 |
|
||||
| u_fifo | snix_sync_fifo | 225 | 225 | 0 | 0 | 53 | 0 | 1 | 0 |
|
||||
+------------------------------------------+------------------------------+------------+------------+---------+------+-------+--------+--------+--------------+
|
||||
* Note: The sum of lower-level cells may be larger than their parent cells total, due to cross-hierarchy LUT combining
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
module axi2sram_sp_external #(
|
||||
parameter AXI_ID_WIDTH = 5,
|
||||
parameter AXI_ADDR_WIDTH = 32,
|
||||
parameter AXI_DATA_WIDTH = 32
|
||||
parameter AXI_DATA_WIDTH = 32,
|
||||
parameter FAST_READ_BURST = 1
|
||||
)(
|
||||
input clk,
|
||||
input resetn,
|
||||
@@ -95,7 +96,6 @@ module axi2sram_sp_external #(
|
||||
localparam WRITE = 3'h2;
|
||||
localparam SEND_B = 3'h3;
|
||||
localparam WAIT_WVALID = 3'h4;
|
||||
localparam WRITE_NOP = 3'h5;
|
||||
localparam READ_ADDR = 3'h6;
|
||||
|
||||
localparam FIXED = 2'b00;
|
||||
@@ -158,6 +158,7 @@ module axi2sram_sp_external #(
|
||||
s_arready = 1'b0;
|
||||
// read response channel
|
||||
s_rvalid = 1'b0;
|
||||
s_rdata = 'h0;
|
||||
s_rresp = 'h0;
|
||||
s_rlast = 'h0;
|
||||
s_rid = ax_req_q_id;
|
||||
@@ -208,7 +209,7 @@ module axi2sram_sp_external #(
|
||||
if (s_wvalid) begin
|
||||
req_o = 1'b1;
|
||||
we_o = 1'b1;
|
||||
state_d = (s_wlast) ? SEND_B : WRITE_NOP;
|
||||
state_d = (s_wlast) ? SEND_B : WRITE;
|
||||
cnt_d = 1;
|
||||
// we still have to wait for the first w_valid to arrive
|
||||
end else
|
||||
@@ -246,7 +247,26 @@ module axi2sram_sp_external #(
|
||||
// we already got everything
|
||||
end
|
||||
else begin
|
||||
state_d = READ_ADDR;
|
||||
if (FAST_READ_BURST) begin
|
||||
// Queue the next async-SRAM address for the clock
|
||||
// edge after the current read data is sampled.
|
||||
case (ax_req_q_burst)
|
||||
FIXED, INCR: req_addr_d = cons_addr;
|
||||
WRAP: begin
|
||||
if (cons_addr == upper_wrap_boundary) begin
|
||||
req_addr_d = wrap_boundary;
|
||||
end else if (cons_addr > upper_wrap_boundary) begin
|
||||
req_addr_d = ax_req_q_addr + ((cnt_q - ax_req_q_len) << LOG_NR_BYTES);
|
||||
end else begin
|
||||
req_addr_d = cons_addr;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
cnt_d = cnt_q + 1;
|
||||
state_d = READ;
|
||||
end else begin
|
||||
state_d = READ_ADDR;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -283,17 +303,11 @@ module axi2sram_sp_external #(
|
||||
state_d = READ;
|
||||
end
|
||||
|
||||
//ext SRAM need nop between continuous write operations
|
||||
WRITE_NOP: begin
|
||||
s_wready = 1'b0;
|
||||
state_d = WRITE;
|
||||
end
|
||||
|
||||
// ~> we already wrote the first word here
|
||||
WRITE: begin
|
||||
|
||||
s_wready = 1'b1;
|
||||
state_d = WRITE_NOP;
|
||||
state_d = WRITE;
|
||||
|
||||
// consume a word here
|
||||
if (s_wvalid) begin
|
||||
@@ -377,4 +391,3 @@ module axi2sram_sp_external #(
|
||||
// end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT1_SEQUENCE_NUMBER">1</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT2_1">0000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT2_2">0000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT2_ACTUAL_FREQ">100.000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT2_ACTUAL_FREQ">50.00000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT2_DRIVES">BUFG</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT2_DUTY_CYCLE">50.0</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT2_MATCHED_ROUTING">false</spirit:configurableElementValue>
|
||||
@@ -128,12 +128,12 @@
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_2">0000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_ACTUAL_FREQ">100.000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_DRIVES">BUFG</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_DUTY_CYCLE">50.000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_DUTY_CYCLE">50.0</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_MATCHED_ROUTING">false</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_OUT_FREQ">100.000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_OUT_FREQ">50.00000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_PHASE">0.000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_REQUESTED_DUTY_CYCLE">50.000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_REQUESTED_OUT_FREQ">100.000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_REQUESTED_OUT_FREQ">50</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_REQUESTED_PHASE">0.000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_SEQUENCE_NUMBER">1</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLKOUT3_USED">0</spirit:configurableElementValue>
|
||||
@@ -190,7 +190,7 @@
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLK_IN_SEL_PORT">clk_in_sel</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLK_OUT1_PORT">cpu_clk</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLK_OUT2_PORT">sys_clk</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLK_OUT3_PORT">clk_out3</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLK_OUT3_PORT">mlkem_clk</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLK_OUT4_PORT">clk_out4</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLK_OUT5_PORT">clk_out5</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CLK_OUT6_PORT">clk_out6</spirit:configurableElementValue>
|
||||
@@ -204,7 +204,7 @@
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_DIVCLK">0000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_DIVIDE1_AUTO">1</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_DIVIDE2_AUTO">0.66</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_DIVIDE3_AUTO">0.33</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_DIVIDE3_AUTO">0.66</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_DIVIDE4_AUTO">0.33</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_DIVIDE5_AUTO">0.33</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_DIVIDE6_AUTO">0.33</spirit:configurableElementValue>
|
||||
@@ -432,11 +432,11 @@
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT2_SEQUENCE_NUMBER">1</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT2_USED">true</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT3_DRIVES">BUFG</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT3_JITTER">0.0</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT3_JITTER">122.035</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT3_MATCHED_ROUTING">false</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT3_PHASE_ERROR">0.0</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT3_PHASE_ERROR">123.600</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT3_REQUESTED_DUTY_CYCLE">50.000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT3_REQUESTED_OUT_FREQ">100.000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT3_REQUESTED_OUT_FREQ">50</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT3_REQUESTED_PHASE">0.000</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT3_SEQUENCE_NUMBER">1</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLKOUT3_USED">false</spirit:configurableElementValue>
|
||||
@@ -484,7 +484,7 @@
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLK_OUT1_USE_FINE_PS_GUI">false</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLK_OUT2_PORT">sys_clk</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLK_OUT2_USE_FINE_PS_GUI">false</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLK_OUT3_PORT">clk_out3</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLK_OUT3_PORT">mlkem_clk</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLK_OUT3_USE_FINE_PS_GUI">false</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLK_OUT4_PORT">clk_out4</spirit:configurableElementValue>
|
||||
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CLK_OUT4_USE_FINE_PS_GUI">false</spirit:configurableElementValue>
|
||||
@@ -705,17 +705,23 @@
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLKOUT2_REQUESTED_OUT_FREQ" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLKOUT2_USED" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLKOUT3_DRIVES" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLKOUT3_JITTER" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLKOUT3_PHASE_ERROR" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLKOUT3_REQUESTED_OUT_FREQ" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLKOUT3_USED" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLKOUT4_DRIVES" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLKOUT5_DRIVES" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLKOUT6_DRIVES" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLKOUT7_DRIVES" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLK_OUT1_PORT" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLK_OUT2_PORT" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.CLK_OUT3_PORT" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.MMCM_CLKFBOUT_MULT_F" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.MMCM_CLKIN1_PERIOD" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.MMCM_CLKIN2_PERIOD" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.MMCM_CLKOUT0_DIVIDE_F" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.MMCM_CLKOUT1_DIVIDE" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.MMCM_CLKOUT2_DIVIDE" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.MMCM_COMPENSATION" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.MMCM_DIVCLK_DIVIDE" xilinx:valueSource="user"/>
|
||||
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.NUM_OUT_CLKS" xilinx:valueSource="user"/>
|
||||
|
||||
235
rtl/ip/PLL_2019_2/clk_pll_sim_netlist.v
Normal file
@@ -0,0 +1,235 @@
|
||||
// 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 23:25:51 2026
|
||||
// Host : fedora running 64-bit unknown
|
||||
// Command : write_verilog -force -mode funcsim
|
||||
// /home/fallensigh/Dev/ciciec2026_loongson_regional/rtl/ip/PLL_2019_2/clk_pll_sim_netlist.v
|
||||
// Design : clk_pll
|
||||
// Purpose : This verilog netlist is a functional simulation representation of the design and should not be modified
|
||||
// or synthesized. This netlist cannot be used for SDF annotated simulation.
|
||||
// Device : xc7a200tfbg676-1
|
||||
// --------------------------------------------------------------------------------
|
||||
`timescale 1 ps / 1 ps
|
||||
|
||||
(* NotValidForBitStream *)
|
||||
module clk_pll
|
||||
(cpu_clk,
|
||||
sys_clk,
|
||||
mlkem_clk,
|
||||
resetn,
|
||||
locked,
|
||||
clk_in1);
|
||||
output cpu_clk;
|
||||
output sys_clk;
|
||||
output mlkem_clk;
|
||||
input resetn;
|
||||
output locked;
|
||||
input clk_in1;
|
||||
|
||||
(* IBUF_LOW_PWR *) wire clk_in1;
|
||||
wire cpu_clk;
|
||||
wire locked;
|
||||
wire mlkem_clk;
|
||||
wire resetn;
|
||||
wire sys_clk;
|
||||
|
||||
clk_pll_clk_pll_clk_wiz inst
|
||||
(.clk_in1(clk_in1),
|
||||
.cpu_clk(cpu_clk),
|
||||
.locked(locked),
|
||||
.mlkem_clk(mlkem_clk),
|
||||
.resetn(resetn),
|
||||
.sys_clk(sys_clk));
|
||||
endmodule
|
||||
|
||||
(* ORIG_REF_NAME = "clk_pll_clk_wiz" *)
|
||||
module clk_pll_clk_pll_clk_wiz
|
||||
(cpu_clk,
|
||||
sys_clk,
|
||||
mlkem_clk,
|
||||
resetn,
|
||||
locked,
|
||||
clk_in1);
|
||||
output cpu_clk;
|
||||
output sys_clk;
|
||||
output mlkem_clk;
|
||||
input resetn;
|
||||
output locked;
|
||||
input clk_in1;
|
||||
|
||||
wire clk_in1;
|
||||
wire clk_in1_clk_pll;
|
||||
wire clkfbout_buf_clk_pll;
|
||||
wire clkfbout_clk_pll;
|
||||
wire cpu_clk;
|
||||
wire cpu_clk_clk_pll;
|
||||
wire locked;
|
||||
wire mlkem_clk;
|
||||
wire mlkem_clk_clk_pll;
|
||||
wire reset_high;
|
||||
wire resetn;
|
||||
wire sys_clk;
|
||||
wire sys_clk_clk_pll;
|
||||
wire NLW_plle2_adv_inst_CLKOUT3_UNCONNECTED;
|
||||
wire NLW_plle2_adv_inst_CLKOUT4_UNCONNECTED;
|
||||
wire NLW_plle2_adv_inst_CLKOUT5_UNCONNECTED;
|
||||
wire NLW_plle2_adv_inst_DRDY_UNCONNECTED;
|
||||
wire [15:0]NLW_plle2_adv_inst_DO_UNCONNECTED;
|
||||
|
||||
(* BOX_TYPE = "PRIMITIVE" *)
|
||||
BUFG clkf_buf
|
||||
(.I(clkfbout_clk_pll),
|
||||
.O(clkfbout_buf_clk_pll));
|
||||
(* BOX_TYPE = "PRIMITIVE" *)
|
||||
(* CAPACITANCE = "DONT_CARE" *)
|
||||
(* IBUF_DELAY_VALUE = "0" *)
|
||||
(* IFD_DELAY_VALUE = "AUTO" *)
|
||||
IBUF #(
|
||||
.IOSTANDARD("DEFAULT"))
|
||||
clkin1_ibufg
|
||||
(.I(clk_in1),
|
||||
.O(clk_in1_clk_pll));
|
||||
(* BOX_TYPE = "PRIMITIVE" *)
|
||||
BUFG clkout1_buf
|
||||
(.I(cpu_clk_clk_pll),
|
||||
.O(cpu_clk));
|
||||
(* BOX_TYPE = "PRIMITIVE" *)
|
||||
BUFG clkout2_buf
|
||||
(.I(sys_clk_clk_pll),
|
||||
.O(sys_clk));
|
||||
(* BOX_TYPE = "PRIMITIVE" *)
|
||||
BUFG clkout3_buf
|
||||
(.I(mlkem_clk_clk_pll),
|
||||
.O(mlkem_clk));
|
||||
(* BOX_TYPE = "PRIMITIVE" *)
|
||||
PLLE2_ADV #(
|
||||
.BANDWIDTH("OPTIMIZED"),
|
||||
.CLKFBOUT_MULT(31),
|
||||
.CLKFBOUT_PHASE(0.000000),
|
||||
.CLKIN1_PERIOD(20.000000),
|
||||
.CLKIN2_PERIOD(0.000000),
|
||||
.CLKOUT0_DIVIDE(47),
|
||||
.CLKOUT0_DUTY_CYCLE(0.500000),
|
||||
.CLKOUT0_PHASE(0.000000),
|
||||
.CLKOUT1_DIVIDE(31),
|
||||
.CLKOUT1_DUTY_CYCLE(0.500000),
|
||||
.CLKOUT1_PHASE(0.000000),
|
||||
.CLKOUT2_DIVIDE(78),
|
||||
.CLKOUT2_DUTY_CYCLE(0.500000),
|
||||
.CLKOUT2_PHASE(0.000000),
|
||||
.CLKOUT3_DIVIDE(1),
|
||||
.CLKOUT3_DUTY_CYCLE(0.500000),
|
||||
.CLKOUT3_PHASE(0.000000),
|
||||
.CLKOUT4_DIVIDE(1),
|
||||
.CLKOUT4_DUTY_CYCLE(0.500000),
|
||||
.CLKOUT4_PHASE(0.000000),
|
||||
.CLKOUT5_DIVIDE(1),
|
||||
.CLKOUT5_DUTY_CYCLE(0.500000),
|
||||
.CLKOUT5_PHASE(0.000000),
|
||||
.COMPENSATION("ZHOLD"),
|
||||
.DIVCLK_DIVIDE(1),
|
||||
.IS_CLKINSEL_INVERTED(1'b0),
|
||||
.IS_PWRDWN_INVERTED(1'b0),
|
||||
.IS_RST_INVERTED(1'b0),
|
||||
.REF_JITTER1(0.010000),
|
||||
.REF_JITTER2(0.010000),
|
||||
.STARTUP_WAIT("FALSE"))
|
||||
plle2_adv_inst
|
||||
(.CLKFBIN(clkfbout_buf_clk_pll),
|
||||
.CLKFBOUT(clkfbout_clk_pll),
|
||||
.CLKIN1(clk_in1_clk_pll),
|
||||
.CLKIN2(1'b0),
|
||||
.CLKINSEL(1'b1),
|
||||
.CLKOUT0(cpu_clk_clk_pll),
|
||||
.CLKOUT1(sys_clk_clk_pll),
|
||||
.CLKOUT2(mlkem_clk_clk_pll),
|
||||
.CLKOUT3(NLW_plle2_adv_inst_CLKOUT3_UNCONNECTED),
|
||||
.CLKOUT4(NLW_plle2_adv_inst_CLKOUT4_UNCONNECTED),
|
||||
.CLKOUT5(NLW_plle2_adv_inst_CLKOUT5_UNCONNECTED),
|
||||
.DADDR({1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0}),
|
||||
.DCLK(1'b0),
|
||||
.DEN(1'b0),
|
||||
.DI({1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0}),
|
||||
.DO(NLW_plle2_adv_inst_DO_UNCONNECTED[15:0]),
|
||||
.DRDY(NLW_plle2_adv_inst_DRDY_UNCONNECTED),
|
||||
.DWE(1'b0),
|
||||
.LOCKED(locked),
|
||||
.PWRDWN(1'b0),
|
||||
.RST(reset_high));
|
||||
LUT1 #(
|
||||
.INIT(2'h1))
|
||||
plle2_adv_inst_i_1
|
||||
(.I0(resetn),
|
||||
.O(reset_high));
|
||||
endmodule
|
||||
`ifndef GLBL
|
||||
`define GLBL
|
||||
`timescale 1 ps / 1 ps
|
||||
|
||||
module glbl ();
|
||||
|
||||
parameter ROC_WIDTH = 100000;
|
||||
parameter TOC_WIDTH = 0;
|
||||
|
||||
//-------- STARTUP Globals --------------
|
||||
wire GSR;
|
||||
wire GTS;
|
||||
wire GWE;
|
||||
wire PRLD;
|
||||
tri1 p_up_tmp;
|
||||
tri (weak1, strong0) PLL_LOCKG = p_up_tmp;
|
||||
|
||||
wire PROGB_GLBL;
|
||||
wire CCLKO_GLBL;
|
||||
wire FCSBO_GLBL;
|
||||
wire [3:0] DO_GLBL;
|
||||
wire [3:0] DI_GLBL;
|
||||
|
||||
reg GSR_int;
|
||||
reg GTS_int;
|
||||
reg PRLD_int;
|
||||
|
||||
//-------- JTAG Globals --------------
|
||||
wire JTAG_TDO_GLBL;
|
||||
wire JTAG_TCK_GLBL;
|
||||
wire JTAG_TDI_GLBL;
|
||||
wire JTAG_TMS_GLBL;
|
||||
wire JTAG_TRST_GLBL;
|
||||
|
||||
reg JTAG_CAPTURE_GLBL;
|
||||
reg JTAG_RESET_GLBL;
|
||||
reg JTAG_SHIFT_GLBL;
|
||||
reg JTAG_UPDATE_GLBL;
|
||||
reg JTAG_RUNTEST_GLBL;
|
||||
|
||||
reg JTAG_SEL1_GLBL = 0;
|
||||
reg JTAG_SEL2_GLBL = 0 ;
|
||||
reg JTAG_SEL3_GLBL = 0;
|
||||
reg JTAG_SEL4_GLBL = 0;
|
||||
|
||||
reg JTAG_USER_TDO1_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO2_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO3_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO4_GLBL = 1'bz;
|
||||
|
||||
assign (strong1, weak0) GSR = GSR_int;
|
||||
assign (strong1, weak0) GTS = GTS_int;
|
||||
assign (weak1, weak0) PRLD = PRLD_int;
|
||||
|
||||
initial begin
|
||||
GSR_int = 1'b1;
|
||||
PRLD_int = 1'b1;
|
||||
#(ROC_WIDTH)
|
||||
GSR_int = 1'b0;
|
||||
PRLD_int = 1'b0;
|
||||
end
|
||||
|
||||
initial begin
|
||||
GTS_int = 1'b1;
|
||||
#(TOC_WIDTH)
|
||||
GTS_int = 1'b0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
`endif
|
||||
179
rtl/ip/PLL_2019_2/clk_pll_sim_netlist.vhdl
Normal file
@@ -0,0 +1,179 @@
|
||||
-- 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 23:25:51 2026
|
||||
-- Host : fedora running 64-bit unknown
|
||||
-- Command : write_vhdl -force -mode funcsim
|
||||
-- /home/fallensigh/Dev/ciciec2026_loongson_regional/rtl/ip/PLL_2019_2/clk_pll_sim_netlist.vhdl
|
||||
-- Design : clk_pll
|
||||
-- Purpose : This VHDL netlist is a functional simulation representation of the design and should not be modified or
|
||||
-- synthesized. This netlist cannot be used for SDF annotated simulation.
|
||||
-- Device : xc7a200tfbg676-1
|
||||
-- --------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
library UNISIM;
|
||||
use UNISIM.VCOMPONENTS.ALL;
|
||||
entity clk_pll_clk_pll_clk_wiz is
|
||||
port (
|
||||
cpu_clk : out STD_LOGIC;
|
||||
sys_clk : out STD_LOGIC;
|
||||
mlkem_clk : out STD_LOGIC;
|
||||
resetn : in STD_LOGIC;
|
||||
locked : out STD_LOGIC;
|
||||
clk_in1 : in STD_LOGIC
|
||||
);
|
||||
attribute ORIG_REF_NAME : string;
|
||||
attribute ORIG_REF_NAME of clk_pll_clk_pll_clk_wiz : entity is "clk_pll_clk_wiz";
|
||||
end clk_pll_clk_pll_clk_wiz;
|
||||
|
||||
architecture STRUCTURE of clk_pll_clk_pll_clk_wiz is
|
||||
signal clk_in1_clk_pll : STD_LOGIC;
|
||||
signal clkfbout_buf_clk_pll : STD_LOGIC;
|
||||
signal clkfbout_clk_pll : STD_LOGIC;
|
||||
signal cpu_clk_clk_pll : STD_LOGIC;
|
||||
signal mlkem_clk_clk_pll : STD_LOGIC;
|
||||
signal reset_high : STD_LOGIC;
|
||||
signal sys_clk_clk_pll : STD_LOGIC;
|
||||
signal NLW_plle2_adv_inst_CLKOUT3_UNCONNECTED : STD_LOGIC;
|
||||
signal NLW_plle2_adv_inst_CLKOUT4_UNCONNECTED : STD_LOGIC;
|
||||
signal NLW_plle2_adv_inst_CLKOUT5_UNCONNECTED : STD_LOGIC;
|
||||
signal NLW_plle2_adv_inst_DRDY_UNCONNECTED : STD_LOGIC;
|
||||
signal NLW_plle2_adv_inst_DO_UNCONNECTED : STD_LOGIC_VECTOR ( 15 downto 0 );
|
||||
attribute BOX_TYPE : string;
|
||||
attribute BOX_TYPE of clkf_buf : label is "PRIMITIVE";
|
||||
attribute BOX_TYPE of clkin1_ibufg : label is "PRIMITIVE";
|
||||
attribute CAPACITANCE : string;
|
||||
attribute CAPACITANCE of clkin1_ibufg : label is "DONT_CARE";
|
||||
attribute IBUF_DELAY_VALUE : string;
|
||||
attribute IBUF_DELAY_VALUE of clkin1_ibufg : label is "0";
|
||||
attribute IFD_DELAY_VALUE : string;
|
||||
attribute IFD_DELAY_VALUE of clkin1_ibufg : label is "AUTO";
|
||||
attribute BOX_TYPE of clkout1_buf : label is "PRIMITIVE";
|
||||
attribute BOX_TYPE of clkout2_buf : label is "PRIMITIVE";
|
||||
attribute BOX_TYPE of clkout3_buf : label is "PRIMITIVE";
|
||||
attribute BOX_TYPE of plle2_adv_inst : label is "PRIMITIVE";
|
||||
begin
|
||||
clkf_buf: unisim.vcomponents.BUFG
|
||||
port map (
|
||||
I => clkfbout_clk_pll,
|
||||
O => clkfbout_buf_clk_pll
|
||||
);
|
||||
clkin1_ibufg: unisim.vcomponents.IBUF
|
||||
generic map(
|
||||
IOSTANDARD => "DEFAULT"
|
||||
)
|
||||
port map (
|
||||
I => clk_in1,
|
||||
O => clk_in1_clk_pll
|
||||
);
|
||||
clkout1_buf: unisim.vcomponents.BUFG
|
||||
port map (
|
||||
I => cpu_clk_clk_pll,
|
||||
O => cpu_clk
|
||||
);
|
||||
clkout2_buf: unisim.vcomponents.BUFG
|
||||
port map (
|
||||
I => sys_clk_clk_pll,
|
||||
O => sys_clk
|
||||
);
|
||||
clkout3_buf: unisim.vcomponents.BUFG
|
||||
port map (
|
||||
I => mlkem_clk_clk_pll,
|
||||
O => mlkem_clk
|
||||
);
|
||||
plle2_adv_inst: unisim.vcomponents.PLLE2_ADV
|
||||
generic map(
|
||||
BANDWIDTH => "OPTIMIZED",
|
||||
CLKFBOUT_MULT => 31,
|
||||
CLKFBOUT_PHASE => 0.000000,
|
||||
CLKIN1_PERIOD => 20.000000,
|
||||
CLKIN2_PERIOD => 0.000000,
|
||||
CLKOUT0_DIVIDE => 47,
|
||||
CLKOUT0_DUTY_CYCLE => 0.500000,
|
||||
CLKOUT0_PHASE => 0.000000,
|
||||
CLKOUT1_DIVIDE => 31,
|
||||
CLKOUT1_DUTY_CYCLE => 0.500000,
|
||||
CLKOUT1_PHASE => 0.000000,
|
||||
CLKOUT2_DIVIDE => 78,
|
||||
CLKOUT2_DUTY_CYCLE => 0.500000,
|
||||
CLKOUT2_PHASE => 0.000000,
|
||||
CLKOUT3_DIVIDE => 1,
|
||||
CLKOUT3_DUTY_CYCLE => 0.500000,
|
||||
CLKOUT3_PHASE => 0.000000,
|
||||
CLKOUT4_DIVIDE => 1,
|
||||
CLKOUT4_DUTY_CYCLE => 0.500000,
|
||||
CLKOUT4_PHASE => 0.000000,
|
||||
CLKOUT5_DIVIDE => 1,
|
||||
CLKOUT5_DUTY_CYCLE => 0.500000,
|
||||
CLKOUT5_PHASE => 0.000000,
|
||||
COMPENSATION => "ZHOLD",
|
||||
DIVCLK_DIVIDE => 1,
|
||||
IS_CLKINSEL_INVERTED => '0',
|
||||
IS_PWRDWN_INVERTED => '0',
|
||||
IS_RST_INVERTED => '0',
|
||||
REF_JITTER1 => 0.010000,
|
||||
REF_JITTER2 => 0.010000,
|
||||
STARTUP_WAIT => "FALSE"
|
||||
)
|
||||
port map (
|
||||
CLKFBIN => clkfbout_buf_clk_pll,
|
||||
CLKFBOUT => clkfbout_clk_pll,
|
||||
CLKIN1 => clk_in1_clk_pll,
|
||||
CLKIN2 => '0',
|
||||
CLKINSEL => '1',
|
||||
CLKOUT0 => cpu_clk_clk_pll,
|
||||
CLKOUT1 => sys_clk_clk_pll,
|
||||
CLKOUT2 => mlkem_clk_clk_pll,
|
||||
CLKOUT3 => NLW_plle2_adv_inst_CLKOUT3_UNCONNECTED,
|
||||
CLKOUT4 => NLW_plle2_adv_inst_CLKOUT4_UNCONNECTED,
|
||||
CLKOUT5 => NLW_plle2_adv_inst_CLKOUT5_UNCONNECTED,
|
||||
DADDR(6 downto 0) => B"0000000",
|
||||
DCLK => '0',
|
||||
DEN => '0',
|
||||
DI(15 downto 0) => B"0000000000000000",
|
||||
DO(15 downto 0) => NLW_plle2_adv_inst_DO_UNCONNECTED(15 downto 0),
|
||||
DRDY => NLW_plle2_adv_inst_DRDY_UNCONNECTED,
|
||||
DWE => '0',
|
||||
LOCKED => locked,
|
||||
PWRDWN => '0',
|
||||
RST => reset_high
|
||||
);
|
||||
plle2_adv_inst_i_1: unisim.vcomponents.LUT1
|
||||
generic map(
|
||||
INIT => X"1"
|
||||
)
|
||||
port map (
|
||||
I0 => resetn,
|
||||
O => reset_high
|
||||
);
|
||||
end STRUCTURE;
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
library UNISIM;
|
||||
use UNISIM.VCOMPONENTS.ALL;
|
||||
entity clk_pll is
|
||||
port (
|
||||
cpu_clk : out STD_LOGIC;
|
||||
sys_clk : out STD_LOGIC;
|
||||
mlkem_clk : out STD_LOGIC;
|
||||
resetn : in STD_LOGIC;
|
||||
locked : out STD_LOGIC;
|
||||
clk_in1 : in STD_LOGIC
|
||||
);
|
||||
attribute NotValidForBitStream : boolean;
|
||||
attribute NotValidForBitStream of clk_pll : entity is true;
|
||||
end clk_pll;
|
||||
|
||||
architecture STRUCTURE of clk_pll is
|
||||
begin
|
||||
inst: entity work.clk_pll_clk_pll_clk_wiz
|
||||
port map (
|
||||
clk_in1 => clk_in1,
|
||||
cpu_clk => cpu_clk,
|
||||
locked => locked,
|
||||
mlkem_clk => mlkem_clk,
|
||||
resetn => resetn,
|
||||
sys_clk => sys_clk
|
||||
);
|
||||
end STRUCTURE;
|
||||
25
rtl/ip/PLL_2019_2/clk_pll_stub.v
Normal file
@@ -0,0 +1,25 @@
|
||||
// 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 23:25:51 2026
|
||||
// Host : fedora running 64-bit unknown
|
||||
// Command : write_verilog -force -mode synth_stub
|
||||
// /home/fallensigh/Dev/ciciec2026_loongson_regional/rtl/ip/PLL_2019_2/clk_pll_stub.v
|
||||
// Design : clk_pll
|
||||
// Purpose : Stub declaration of top-level module interface
|
||||
// Device : xc7a200tfbg676-1
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
// This empty module with port declaration file causes synthesis tools to infer a black box for IP.
|
||||
// The synthesis directives are for Synopsys Synplify support to prevent IO buffer insertion.
|
||||
// Please paste the declaration into a Verilog source file or add the file as an additional source.
|
||||
module clk_pll(cpu_clk, sys_clk, mlkem_clk, resetn, locked,
|
||||
clk_in1)
|
||||
/* synthesis syn_black_box black_box_pad_pin="cpu_clk,sys_clk,mlkem_clk,resetn,locked,clk_in1" */;
|
||||
output cpu_clk;
|
||||
output sys_clk;
|
||||
output mlkem_clk;
|
||||
input resetn;
|
||||
output locked;
|
||||
input clk_in1;
|
||||
endmodule
|
||||
33
rtl/ip/PLL_2019_2/clk_pll_stub.vhdl
Normal file
@@ -0,0 +1,33 @@
|
||||
-- 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 23:25:51 2026
|
||||
-- Host : fedora running 64-bit unknown
|
||||
-- Command : write_vhdl -force -mode synth_stub
|
||||
-- /home/fallensigh/Dev/ciciec2026_loongson_regional/rtl/ip/PLL_2019_2/clk_pll_stub.vhdl
|
||||
-- Design : clk_pll
|
||||
-- Purpose : Stub declaration of top-level module interface
|
||||
-- Device : xc7a200tfbg676-1
|
||||
-- --------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity clk_pll is
|
||||
Port (
|
||||
cpu_clk : out STD_LOGIC;
|
||||
sys_clk : out STD_LOGIC;
|
||||
mlkem_clk : out STD_LOGIC;
|
||||
resetn : in STD_LOGIC;
|
||||
locked : out STD_LOGIC;
|
||||
clk_in1 : in STD_LOGIC
|
||||
);
|
||||
|
||||
end clk_pll;
|
||||
|
||||
architecture stub of clk_pll is
|
||||
attribute syn_black_box : boolean;
|
||||
attribute black_box_pad_pin : string;
|
||||
attribute syn_black_box of stub : architecture is true;
|
||||
attribute black_box_pad_pin of stub : architecture is "cpu_clk,sys_clk,mlkem_clk,resetn,locked,clk_in1";
|
||||
begin
|
||||
end;
|
||||
402
rtl/ip/cdma/cdma_matmul_bridge.sv
Normal file
@@ -0,0 +1,402 @@
|
||||
// ============================================================================
|
||||
// cdma_matmul_bridge.sv
|
||||
// Matmul-specific sequencer between the generic CDMA endpoint requester and
|
||||
// the matmul local endpoint/control interface.
|
||||
//
|
||||
// AXI-Lite register map, relative to this bridge window:
|
||||
// 0x00 CTRL bit0 start, bit1 skip_result_writeback
|
||||
// 0x04 STATUS bit0 busy, bit1 done (W1C)
|
||||
// 0x08 SRC_BASE physical ExtRAM input base
|
||||
// 0x0C DST_BASE physical ExtRAM result base
|
||||
// 0x10 GROUPS
|
||||
// 0x14 MAT_BASE reserved for software compatibility
|
||||
// 0x18 SRC_STRIDE bytes, default 128
|
||||
// 0x1C DST_STRIDE bytes, default 192
|
||||
// ============================================================================
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module cdma_matmul_bridge #(
|
||||
parameter int ADDR_WIDTH = 32,
|
||||
parameter int AXIL_ADDR_WIDTH = 32,
|
||||
parameter int AXIL_DATA_WIDTH = 32
|
||||
) (
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
|
||||
input logic [AXIL_ADDR_WIDTH-1:0] s_axil_awaddr,
|
||||
input logic s_axil_awvalid,
|
||||
output logic s_axil_awready,
|
||||
input logic [AXIL_DATA_WIDTH-1:0] s_axil_wdata,
|
||||
input logic [AXIL_DATA_WIDTH/8-1:0] s_axil_wstrb,
|
||||
input logic s_axil_wvalid,
|
||||
output logic s_axil_wready,
|
||||
output logic [1:0] s_axil_bresp,
|
||||
output logic s_axil_bvalid,
|
||||
input logic s_axil_bready,
|
||||
input logic [AXIL_ADDR_WIDTH-1:0] s_axil_araddr,
|
||||
input logic s_axil_arvalid,
|
||||
output logic s_axil_arready,
|
||||
output logic [AXIL_DATA_WIDTH-1:0] s_axil_rdata,
|
||||
output logic [1:0] s_axil_rresp,
|
||||
output logic s_axil_rvalid,
|
||||
input logic s_axil_rready,
|
||||
|
||||
output logic cdma_rd_req_valid,
|
||||
input logic cdma_rd_req_ready,
|
||||
output logic [ADDR_WIDTH-1:0] cdma_rd_req_src,
|
||||
output logic [31:0] cdma_rd_req_bytes,
|
||||
output logic [3:0] cdma_rd_req_ep_id,
|
||||
output logic [3:0] cdma_rd_req_ep_bank,
|
||||
output logic [7:0] cdma_rd_req_ep_word_off,
|
||||
input logic cdma_rd_req_done,
|
||||
|
||||
output logic cdma_wr_req_valid,
|
||||
input logic cdma_wr_req_ready,
|
||||
output logic [ADDR_WIDTH-1:0] cdma_wr_req_dst,
|
||||
output logic [31:0] cdma_wr_req_bytes,
|
||||
output logic [3:0] cdma_wr_req_ep_id,
|
||||
output logic [3:0] cdma_wr_req_ep_bank,
|
||||
output logic [7:0] cdma_wr_req_ep_word_off,
|
||||
input logic cdma_wr_req_done,
|
||||
|
||||
output logic mat_start_valid,
|
||||
output logic mat_start_bank,
|
||||
output logic mat_done_clear,
|
||||
output logic mat_crc_clear,
|
||||
input logic mat_done,
|
||||
|
||||
output logic seq_done_irq
|
||||
);
|
||||
|
||||
localparam logic [7:0] REG_CTRL = 8'h00;
|
||||
localparam logic [7:0] REG_STATUS = 8'h04;
|
||||
localparam logic [7:0] REG_SRC_BASE = 8'h08;
|
||||
localparam logic [7:0] REG_DST_BASE = 8'h0C;
|
||||
localparam logic [7:0] REG_GROUPS = 8'h10;
|
||||
localparam logic [7:0] REG_MAT_BASE = 8'h14;
|
||||
localparam logic [7:0] REG_SRC_STRIDE = 8'h18;
|
||||
localparam logic [7:0] REG_DST_STRIDE = 8'h1C;
|
||||
|
||||
localparam logic [31:0] MAT_AB_BYTES = 32'd128;
|
||||
localparam logic [31:0] MAT_C_BYTES = 32'd192;
|
||||
|
||||
logic [31:0] seq_src_base;
|
||||
logic [31:0] seq_dst_base;
|
||||
logic [31:0] seq_groups;
|
||||
logic [31:0] seq_mat_base;
|
||||
logic [31:0] seq_src_stride;
|
||||
logic [31:0] seq_dst_stride;
|
||||
logic seq_busy;
|
||||
logic seq_done_flag;
|
||||
logic seq_skip_writeback;
|
||||
|
||||
logic [31:0] load_next_idx;
|
||||
logic [31:0] groups_retired;
|
||||
logic [1:0] bank_load_active;
|
||||
logic [1:0] bank_ab_valid;
|
||||
logic [1:0] bank_compute_active;
|
||||
logic [1:0] bank_store_pending;
|
||||
logic [1:0] bank_store_active;
|
||||
logic [31:0] bank_group_idx [2];
|
||||
logic [31:0] load_next_src_addr;
|
||||
logic [31:0] load_next_dst_addr;
|
||||
logic [31:0] bank_dst_addr [2];
|
||||
|
||||
logic rd_busy;
|
||||
logic wr_busy;
|
||||
logic rd_active_bank;
|
||||
logic wr_active_bank;
|
||||
logic [1:0] compute_q;
|
||||
logic [1:0] compute_q_count;
|
||||
logic mat_done_seen;
|
||||
|
||||
wire [7:0] wr_off = s_axil_awaddr[7:0];
|
||||
wire [7:0] rd_off = s_axil_araddr[7:0];
|
||||
wire do_write;
|
||||
wire start_req = do_write && (wr_off == REG_CTRL) && s_axil_wstrb[0] && s_axil_wdata[0];
|
||||
wire done_clear_req = do_write && (wr_off == REG_STATUS) && s_axil_wstrb[0] && s_axil_wdata[1];
|
||||
wire load_target_bank = load_next_idx[0];
|
||||
wire load_target_free = !bank_load_active[load_target_bank] &&
|
||||
!bank_ab_valid[load_target_bank] &&
|
||||
!bank_compute_active[load_target_bank] &&
|
||||
!bank_store_pending[load_target_bank] &&
|
||||
!bank_store_active[load_target_bank];
|
||||
wire bank0_start_ready = bank_ab_valid[0] && !bank_compute_active[0] &&
|
||||
!bank_store_pending[0] && !bank_store_active[0];
|
||||
wire bank1_start_ready = bank_ab_valid[1] && !bank_compute_active[1] &&
|
||||
!bank_store_pending[1] && !bank_store_active[1];
|
||||
wire start_sel_bank = bank1_start_ready &&
|
||||
(!bank0_start_ready || (bank_group_idx[1] < bank_group_idx[0]));
|
||||
wire start_ready_any = bank0_start_ready || bank1_start_ready;
|
||||
wire store_sel_bank = bank_store_pending[1] && !bank_store_active[1] &&
|
||||
!(bank_store_pending[0] && !bank_store_active[0]);
|
||||
wire store_ready_any = (bank_store_pending[0] && !bank_store_active[0]) ||
|
||||
(bank_store_pending[1] && !bank_store_active[1]);
|
||||
wire mat_done_event = mat_done && !mat_done_seen;
|
||||
wire retire_from_store = seq_busy && cdma_wr_req_done;
|
||||
wire retire_from_compute = seq_busy && seq_skip_writeback && mat_done_event && (compute_q_count != 2'd0);
|
||||
wire [31:0] retire_inc = {31'd0, retire_from_store} + {31'd0, retire_from_compute};
|
||||
|
||||
function automatic logic [31:0] apply_wstrb(
|
||||
input logic [31:0] old_val,
|
||||
input logic [31:0] new_val,
|
||||
input logic [3:0] wstrb
|
||||
);
|
||||
begin
|
||||
apply_wstrb[7:0] = wstrb[0] ? new_val[7:0] : old_val[7:0];
|
||||
apply_wstrb[15:8] = wstrb[1] ? new_val[15:8] : old_val[15:8];
|
||||
apply_wstrb[23:16] = wstrb[2] ? new_val[23:16] : old_val[23:16];
|
||||
apply_wstrb[31:24] = wstrb[3] ? new_val[31:24] : old_val[31:24];
|
||||
end
|
||||
endfunction
|
||||
|
||||
assign s_axil_bresp = 2'b00;
|
||||
assign s_axil_rresp = 2'b00;
|
||||
assign seq_done_irq = seq_done_flag;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!rst_n) begin
|
||||
s_axil_awready <= 1'b0;
|
||||
s_axil_wready <= 1'b0;
|
||||
end else begin
|
||||
if (s_axil_awvalid && s_axil_wvalid && !s_axil_awready && (!s_axil_bvalid || s_axil_bready)) begin
|
||||
s_axil_awready <= 1'b1;
|
||||
s_axil_wready <= 1'b1;
|
||||
end else begin
|
||||
s_axil_awready <= 1'b0;
|
||||
s_axil_wready <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign do_write = s_axil_awready && s_axil_awvalid && s_axil_wready && s_axil_wvalid;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!rst_n) begin
|
||||
s_axil_bvalid <= 1'b0;
|
||||
end else if (do_write) begin
|
||||
s_axil_bvalid <= 1'b1;
|
||||
end else if (s_axil_bready && s_axil_bvalid) begin
|
||||
s_axil_bvalid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!rst_n) begin
|
||||
s_axil_arready <= 1'b0;
|
||||
end else begin
|
||||
if (s_axil_arvalid && !s_axil_arready && (!s_axil_rvalid || s_axil_rready)) begin
|
||||
s_axil_arready <= 1'b1;
|
||||
end else begin
|
||||
s_axil_arready <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wire do_read = s_axil_arready && s_axil_arvalid;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!rst_n) begin
|
||||
s_axil_rvalid <= 1'b0;
|
||||
s_axil_rdata <= '0;
|
||||
end else if (do_read) begin
|
||||
s_axil_rvalid <= 1'b1;
|
||||
case (rd_off)
|
||||
REG_CTRL: s_axil_rdata <= {30'd0, seq_skip_writeback, 1'b0};
|
||||
REG_STATUS: s_axil_rdata <= {30'd0, seq_done_flag, seq_busy};
|
||||
REG_SRC_BASE: s_axil_rdata <= seq_src_base;
|
||||
REG_DST_BASE: s_axil_rdata <= seq_dst_base;
|
||||
REG_GROUPS: s_axil_rdata <= seq_groups;
|
||||
REG_MAT_BASE: s_axil_rdata <= seq_mat_base;
|
||||
REG_SRC_STRIDE: s_axil_rdata <= seq_src_stride;
|
||||
REG_DST_STRIDE: s_axil_rdata <= seq_dst_stride;
|
||||
default: s_axil_rdata <= 32'd0;
|
||||
endcase
|
||||
end else if (s_axil_rready && s_axil_rvalid) begin
|
||||
s_axil_rvalid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!rst_n) begin
|
||||
seq_src_base <= 32'h0;
|
||||
seq_dst_base <= 32'h0;
|
||||
seq_groups <= 32'h0;
|
||||
seq_mat_base <= 32'h1f50_0000;
|
||||
seq_src_stride <= 32'd128;
|
||||
seq_dst_stride <= 32'd192;
|
||||
end else if (do_write) begin
|
||||
case (wr_off)
|
||||
REG_SRC_BASE: if (!seq_busy) seq_src_base <= apply_wstrb(seq_src_base, s_axil_wdata, s_axil_wstrb);
|
||||
REG_DST_BASE: if (!seq_busy) seq_dst_base <= apply_wstrb(seq_dst_base, s_axil_wdata, s_axil_wstrb);
|
||||
REG_GROUPS: if (!seq_busy) seq_groups <= apply_wstrb(seq_groups, s_axil_wdata, s_axil_wstrb);
|
||||
REG_MAT_BASE: if (!seq_busy) seq_mat_base <= apply_wstrb(seq_mat_base, s_axil_wdata, s_axil_wstrb);
|
||||
REG_SRC_STRIDE: if (!seq_busy) seq_src_stride <= apply_wstrb(seq_src_stride, s_axil_wdata, s_axil_wstrb);
|
||||
REG_DST_STRIDE: if (!seq_busy) seq_dst_stride <= apply_wstrb(seq_dst_stride, s_axil_wdata, s_axil_wstrb);
|
||||
default: begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!rst_n) begin
|
||||
seq_busy <= 1'b0;
|
||||
seq_done_flag <= 1'b0;
|
||||
seq_skip_writeback <= 1'b0;
|
||||
load_next_idx <= 32'd0;
|
||||
groups_retired <= 32'd0;
|
||||
bank_load_active <= 2'b00;
|
||||
bank_ab_valid <= 2'b00;
|
||||
bank_compute_active <= 2'b00;
|
||||
bank_store_pending <= 2'b00;
|
||||
bank_store_active <= 2'b00;
|
||||
bank_group_idx[0] <= 32'd0;
|
||||
bank_group_idx[1] <= 32'd0;
|
||||
load_next_src_addr <= 32'd0;
|
||||
load_next_dst_addr <= 32'd0;
|
||||
bank_dst_addr[0] <= 32'd0;
|
||||
bank_dst_addr[1] <= 32'd0;
|
||||
rd_busy <= 1'b0;
|
||||
wr_busy <= 1'b0;
|
||||
rd_active_bank <= 1'b0;
|
||||
wr_active_bank <= 1'b0;
|
||||
compute_q <= 2'b00;
|
||||
compute_q_count <= 2'd0;
|
||||
mat_done_seen <= 1'b0;
|
||||
cdma_rd_req_valid <= 1'b0;
|
||||
cdma_rd_req_src <= '0;
|
||||
cdma_rd_req_bytes <= '0;
|
||||
cdma_rd_req_ep_id <= 4'd0;
|
||||
cdma_rd_req_ep_bank <= 4'd0;
|
||||
cdma_rd_req_ep_word_off <= 8'd0;
|
||||
cdma_wr_req_valid <= 1'b0;
|
||||
cdma_wr_req_dst <= '0;
|
||||
cdma_wr_req_bytes <= '0;
|
||||
cdma_wr_req_ep_id <= 4'd0;
|
||||
cdma_wr_req_ep_bank <= 4'd0;
|
||||
cdma_wr_req_ep_word_off <= 8'd0;
|
||||
mat_start_valid <= 1'b0;
|
||||
mat_start_bank <= 1'b0;
|
||||
mat_done_clear <= 1'b0;
|
||||
mat_crc_clear <= 1'b0;
|
||||
end else begin
|
||||
mat_start_valid <= 1'b0;
|
||||
mat_done_clear <= 1'b0;
|
||||
mat_crc_clear <= 1'b0;
|
||||
|
||||
mat_done_seen <= mat_done;
|
||||
|
||||
if (done_clear_req)
|
||||
seq_done_flag <= 1'b0;
|
||||
|
||||
if (cdma_rd_req_valid && cdma_rd_req_ready)
|
||||
cdma_rd_req_valid <= 1'b0;
|
||||
|
||||
if (cdma_wr_req_valid && cdma_wr_req_ready)
|
||||
cdma_wr_req_valid <= 1'b0;
|
||||
|
||||
if (start_req && !seq_busy && (seq_groups != 32'd0)) begin
|
||||
seq_busy <= 1'b1;
|
||||
seq_done_flag <= 1'b0;
|
||||
seq_skip_writeback <= s_axil_wstrb[0] && s_axil_wdata[1];
|
||||
load_next_idx <= 32'd0;
|
||||
groups_retired <= 32'd0;
|
||||
bank_load_active <= 2'b00;
|
||||
bank_ab_valid <= 2'b00;
|
||||
bank_compute_active <= 2'b00;
|
||||
bank_store_pending <= 2'b00;
|
||||
bank_store_active <= 2'b00;
|
||||
bank_group_idx[0] <= 32'd0;
|
||||
bank_group_idx[1] <= 32'd0;
|
||||
load_next_src_addr <= seq_src_base;
|
||||
load_next_dst_addr <= seq_dst_base;
|
||||
bank_dst_addr[0] <= 32'd0;
|
||||
bank_dst_addr[1] <= 32'd0;
|
||||
rd_busy <= 1'b0;
|
||||
wr_busy <= 1'b0;
|
||||
compute_q <= 2'b00;
|
||||
compute_q_count <= 2'd0;
|
||||
mat_done_seen <= 1'b1;
|
||||
mat_crc_clear <= 1'b1;
|
||||
mat_done_clear <= 1'b1;
|
||||
cdma_rd_req_valid <= 1'b0;
|
||||
cdma_wr_req_valid <= 1'b0;
|
||||
end else if (seq_busy) begin
|
||||
if (retire_inc != 32'd0) begin
|
||||
groups_retired <= groups_retired + retire_inc;
|
||||
if ((groups_retired + retire_inc) >= seq_groups) begin
|
||||
seq_busy <= 1'b0;
|
||||
seq_done_flag <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
if (cdma_rd_req_done) begin
|
||||
rd_busy <= 1'b0;
|
||||
bank_load_active[rd_active_bank] <= 1'b0;
|
||||
bank_ab_valid[rd_active_bank] <= 1'b1;
|
||||
end
|
||||
|
||||
if (cdma_wr_req_done) begin
|
||||
wr_busy <= 1'b0;
|
||||
bank_store_active[wr_active_bank] <= 1'b0;
|
||||
end
|
||||
|
||||
if (mat_done_event && (compute_q_count != 2'd0)) begin
|
||||
mat_done_clear <= 1'b1;
|
||||
mat_done_seen <= 1'b1;
|
||||
bank_compute_active[compute_q[0]] <= 1'b0;
|
||||
if (!seq_skip_writeback) begin
|
||||
bank_store_pending[compute_q[0]] <= 1'b1;
|
||||
end
|
||||
if (compute_q_count == 2'd2)
|
||||
compute_q[0] <= compute_q[1];
|
||||
compute_q_count <= compute_q_count - 2'd1;
|
||||
end
|
||||
|
||||
if (!rd_busy && !cdma_rd_req_valid && (load_next_idx < seq_groups) && load_target_free) begin
|
||||
cdma_rd_req_src <= load_next_src_addr;
|
||||
cdma_rd_req_bytes <= MAT_AB_BYTES;
|
||||
cdma_rd_req_ep_id <= 4'd0;
|
||||
cdma_rd_req_ep_bank <= {3'b000, load_target_bank};
|
||||
cdma_rd_req_ep_word_off <= 8'd0;
|
||||
cdma_rd_req_valid <= 1'b1;
|
||||
rd_busy <= 1'b1;
|
||||
rd_active_bank <= load_target_bank;
|
||||
bank_load_active[load_target_bank] <= 1'b1;
|
||||
bank_group_idx[load_target_bank] <= load_next_idx;
|
||||
bank_dst_addr[load_target_bank] <= load_next_dst_addr;
|
||||
load_next_src_addr <= load_next_src_addr + seq_src_stride;
|
||||
load_next_dst_addr <= load_next_dst_addr + seq_dst_stride;
|
||||
load_next_idx <= load_next_idx + 32'd1;
|
||||
end
|
||||
|
||||
if (!seq_skip_writeback && !wr_busy && !cdma_wr_req_valid && store_ready_any) begin
|
||||
cdma_wr_req_dst <= bank_dst_addr[store_sel_bank];
|
||||
cdma_wr_req_bytes <= MAT_C_BYTES;
|
||||
cdma_wr_req_ep_id <= 4'd0;
|
||||
cdma_wr_req_ep_bank <= {3'b000, store_sel_bank};
|
||||
cdma_wr_req_ep_word_off <= 8'd0;
|
||||
cdma_wr_req_valid <= 1'b1;
|
||||
wr_busy <= 1'b1;
|
||||
wr_active_bank <= store_sel_bank;
|
||||
bank_store_pending[store_sel_bank] <= 1'b0;
|
||||
bank_store_active[store_sel_bank] <= 1'b1;
|
||||
end
|
||||
|
||||
if ((compute_q_count < 2'd2) && start_ready_any && !(mat_done_event && (compute_q_count != 2'd0))) begin
|
||||
mat_start_valid <= 1'b1;
|
||||
mat_start_bank <= start_sel_bank;
|
||||
bank_ab_valid[start_sel_bank] <= 1'b0;
|
||||
bank_compute_active[start_sel_bank] <= 1'b1;
|
||||
if (compute_q_count == 2'd0)
|
||||
compute_q[0] <= start_sel_bank;
|
||||
else
|
||||
compute_q[1] <= start_sel_bank;
|
||||
compute_q_count <= compute_q_count + 2'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -94,6 +94,44 @@ module snix_axil_cdma_mux #(
|
||||
input logic mm2mm_rvalid,
|
||||
output logic mm2mm_rready,
|
||||
|
||||
// ==========================================
|
||||
// Local endpoint interface
|
||||
// ==========================================
|
||||
output logic ep_wr_valid,
|
||||
output logic [3:0] ep_wr_id,
|
||||
output logic [3:0] ep_wr_bank,
|
||||
output logic [7:0] ep_wr_word_addr,
|
||||
output logic [31:0] ep_wr_data,
|
||||
input logic ep_wr_ready,
|
||||
|
||||
output logic ep_rd_valid,
|
||||
output logic [3:0] ep_rd_id,
|
||||
output logic [3:0] ep_rd_bank,
|
||||
output logic [7:0] ep_rd_word_addr,
|
||||
input logic [31:0] ep_rd_data,
|
||||
input logic ep_rd_ready,
|
||||
|
||||
// ==========================================
|
||||
// Generic external endpoint requester
|
||||
// ==========================================
|
||||
input logic ext_rd_req_valid,
|
||||
output logic ext_rd_req_ready,
|
||||
input logic [ADDR_WIDTH-1:0] ext_rd_req_src,
|
||||
input logic [31:0] ext_rd_req_bytes,
|
||||
input logic [3:0] ext_rd_req_ep_id,
|
||||
input logic [3:0] ext_rd_req_ep_bank,
|
||||
input logic [7:0] ext_rd_req_ep_word_off,
|
||||
output logic ext_rd_req_done,
|
||||
|
||||
input logic ext_wr_req_valid,
|
||||
output logic ext_wr_req_ready,
|
||||
input logic [ADDR_WIDTH-1:0] ext_wr_req_dst,
|
||||
input logic [31:0] ext_wr_req_bytes,
|
||||
input logic [3:0] ext_wr_req_ep_id,
|
||||
input logic [3:0] ext_wr_req_ep_bank,
|
||||
input logic [7:0] ext_wr_req_ep_word_off,
|
||||
output logic ext_wr_req_done,
|
||||
|
||||
// Global Interrupt (OR'd from all channels)
|
||||
output logic dma_finish
|
||||
);
|
||||
@@ -102,6 +140,9 @@ module snix_axil_cdma_mux #(
|
||||
// Local Parameters & Utilities
|
||||
// ==========================================
|
||||
localparam int CH_BITS = $clog2(PORTS);
|
||||
localparam logic [1:0] MODE_MEM2MEM = 2'd0;
|
||||
localparam logic [1:0] MODE_MEM2EP = 2'd1;
|
||||
localparam logic [1:0] MODE_EP2MEM = 2'd2;
|
||||
|
||||
// Function to safely apply WSTRB to 32-bit registers
|
||||
function automatic logic [31:0] apply_wstrb(
|
||||
@@ -125,6 +166,8 @@ module snix_axil_cdma_mux #(
|
||||
logic [31:0] ch_len [PORTS];
|
||||
logic [31:0] ch_tag [PORTS];
|
||||
logic [31:0] ch_ctrl [PORTS];
|
||||
logic [31:0] ch_mode [PORTS];
|
||||
logic [31:0] ch_ep_cfg [PORTS];
|
||||
|
||||
logic [PORTS-1:0] ch_req; // Pending requests (Busy)
|
||||
logic [PORTS-1:0] ch_done; // Completion flags
|
||||
@@ -205,6 +248,8 @@ module snix_axil_cdma_mux #(
|
||||
6'h0C: s_axil_rdata <= ch_tag[rd_ch];
|
||||
6'h10: s_axil_rdata <= ch_ctrl[rd_ch];
|
||||
6'h14: s_axil_rdata <= {30'd0, ch_done[rd_ch], ch_req[rd_ch]};
|
||||
6'h18: s_axil_rdata <= ch_mode[rd_ch];
|
||||
6'h1C: s_axil_rdata <= ch_ep_cfg[rd_ch];
|
||||
default: s_axil_rdata <= 32'd0;
|
||||
endcase
|
||||
end else begin
|
||||
@@ -228,6 +273,7 @@ module snix_axil_cdma_mux #(
|
||||
for (int i=0; i<PORTS; i++) begin
|
||||
ch_src_addr[i] <= '0; ch_dst_addr[i] <= '0;
|
||||
ch_len[i] <= '0; ch_tag[i] <= '0; ch_ctrl[i] <= '0;
|
||||
ch_mode[i] <= '0; ch_ep_cfg[i] <= '0;
|
||||
end
|
||||
end else begin
|
||||
// 1. Process Hardware Status Updates (Highest Priority for Done flag)
|
||||
@@ -245,6 +291,8 @@ module snix_axil_cdma_mux #(
|
||||
6'h04: if (!ch_req[wr_ch]) ch_dst_addr[wr_ch] <= apply_wstrb(ch_dst_addr[wr_ch], s_axil_wdata, s_axil_wstrb);
|
||||
6'h08: if (!ch_req[wr_ch]) ch_len[wr_ch] <= apply_wstrb(ch_len[wr_ch], s_axil_wdata, s_axil_wstrb);
|
||||
6'h0C: if (!ch_req[wr_ch]) ch_tag[wr_ch] <= apply_wstrb(ch_tag[wr_ch], s_axil_wdata, s_axil_wstrb);
|
||||
6'h18: if (!ch_req[wr_ch]) ch_mode[wr_ch] <= apply_wstrb(ch_mode[wr_ch], s_axil_wdata, s_axil_wstrb);
|
||||
6'h1C: if (!ch_req[wr_ch]) ch_ep_cfg[wr_ch] <= apply_wstrb(ch_ep_cfg[wr_ch], s_axil_wdata, s_axil_wstrb);
|
||||
6'h10: begin
|
||||
ch_ctrl[wr_ch] <= apply_wstrb(ch_ctrl[wr_ch], s_axil_wdata, s_axil_wstrb);
|
||||
// Trigger Bit Processing
|
||||
@@ -269,7 +317,7 @@ module snix_axil_cdma_mux #(
|
||||
// ==========================================
|
||||
// Round-Robin Arbiter & Engine Driver
|
||||
// ==========================================
|
||||
typedef enum logic [1:0] {IDLE, RUN} state_t;
|
||||
typedef enum logic [1:0] {IDLE, START, RUN} state_t;
|
||||
state_t state;
|
||||
|
||||
logic [CH_BITS-1:0] cur_ch;
|
||||
@@ -283,6 +331,111 @@ module snix_axil_cdma_mux #(
|
||||
logic [7:0] engine_len;
|
||||
logic [2:0] engine_size;
|
||||
logic engine_done;
|
||||
logic [1:0] engine_mode;
|
||||
logic [3:0] engine_ep_id;
|
||||
logic [3:0] engine_ep_bank;
|
||||
logic [7:0] engine_ep_word_off;
|
||||
|
||||
logic mm2mm_start;
|
||||
logic mm2mm_done;
|
||||
logic ep_start;
|
||||
logic ep_done;
|
||||
|
||||
logic [ID_WIDTH-1:0] core_awid;
|
||||
logic [ADDR_WIDTH-1:0] core_awaddr;
|
||||
logic [7:0] core_awlen;
|
||||
logic [2:0] core_awsize;
|
||||
logic [1:0] core_awburst;
|
||||
logic core_awlock;
|
||||
logic [3:0] core_awcache;
|
||||
logic [2:0] core_awprot;
|
||||
logic [3:0] core_awqos;
|
||||
logic [USER_WIDTH-1:0] core_awuser;
|
||||
logic core_awvalid;
|
||||
logic core_awready;
|
||||
logic [DATA_WIDTH-1:0] core_wdata;
|
||||
logic [DATA_WIDTH/8-1:0] core_wstrb;
|
||||
logic core_wlast;
|
||||
logic [USER_WIDTH-1:0] core_wuser;
|
||||
logic core_wvalid;
|
||||
logic core_wready;
|
||||
logic core_bready;
|
||||
logic [ID_WIDTH-1:0] core_arid;
|
||||
logic [ADDR_WIDTH-1:0] core_araddr;
|
||||
logic [7:0] core_arlen;
|
||||
logic [2:0] core_arsize;
|
||||
logic [1:0] core_arburst;
|
||||
logic core_arlock;
|
||||
logic [3:0] core_arcache;
|
||||
logic [2:0] core_arprot;
|
||||
logic [3:0] core_arqos;
|
||||
logic [USER_WIDTH-1:0] core_aruser;
|
||||
logic core_arvalid;
|
||||
logic core_arready;
|
||||
logic core_rready;
|
||||
|
||||
logic [ID_WIDTH-1:0] ep_awid;
|
||||
logic [ADDR_WIDTH-1:0] ep_awaddr;
|
||||
logic [7:0] ep_awlen;
|
||||
logic [2:0] ep_awsize;
|
||||
logic [1:0] ep_awburst;
|
||||
logic ep_awlock;
|
||||
logic [3:0] ep_awcache;
|
||||
logic [2:0] ep_awprot;
|
||||
logic [3:0] ep_awqos;
|
||||
logic [USER_WIDTH-1:0] ep_awuser;
|
||||
logic ep_awvalid;
|
||||
logic ep_awready;
|
||||
logic [DATA_WIDTH-1:0] ep_wdata;
|
||||
logic [DATA_WIDTH/8-1:0] ep_wstrb;
|
||||
logic ep_wlast;
|
||||
logic [USER_WIDTH-1:0] ep_wuser;
|
||||
logic ep_wvalid;
|
||||
logic ep_wready;
|
||||
logic ep_bready;
|
||||
logic [ID_WIDTH-1:0] ep_arid;
|
||||
logic [ADDR_WIDTH-1:0] ep_araddr;
|
||||
logic [7:0] ep_arlen;
|
||||
logic [2:0] ep_arsize;
|
||||
logic [1:0] ep_arburst;
|
||||
logic ep_arlock;
|
||||
logic [3:0] ep_arcache;
|
||||
logic [2:0] ep_arprot;
|
||||
logic [3:0] ep_arqos;
|
||||
logic [USER_WIDTH-1:0] ep_aruser;
|
||||
logic ep_arvalid;
|
||||
logic ep_arready;
|
||||
logic ep_rready;
|
||||
|
||||
typedef enum logic [2:0] {EP_IDLE, EP_AR, EP_READ, EP_AW, EP_WRITE, EP_BRESP, EP_DONE} ep_state_t;
|
||||
ep_state_t ep_state;
|
||||
logic [31:0] ep_axi_addr;
|
||||
logic [31:0] ep_bytes_left;
|
||||
logic [7:0] ep_word_addr_r;
|
||||
|
||||
typedef enum logic [1:0] {EXT_RD_IDLE, EXT_RD_AR, EXT_RD_READ} ext_rd_state_t;
|
||||
typedef enum logic [1:0] {EXT_WR_IDLE, EXT_WR_AW, EXT_WR_WRITE, EXT_WR_BRESP} ext_wr_state_t;
|
||||
|
||||
ext_rd_state_t ext_rd_state;
|
||||
ext_wr_state_t ext_wr_state;
|
||||
logic [ADDR_WIDTH-1:0] ext_rd_addr_r;
|
||||
logic [31:0] ext_rd_bytes_left;
|
||||
logic [7:0] ext_rd_word_addr_r;
|
||||
logic [3:0] ext_rd_ep_id_r;
|
||||
logic [3:0] ext_rd_ep_bank_r;
|
||||
|
||||
logic [ADDR_WIDTH-1:0] ext_wr_addr_r;
|
||||
logic [31:0] ext_wr_bytes_left;
|
||||
logic [7:0] ext_wr_word_addr_r;
|
||||
logic [3:0] ext_wr_ep_id_r;
|
||||
logic [3:0] ext_wr_ep_bank_r;
|
||||
|
||||
wire ext_rd_active = (ext_rd_state != EXT_RD_IDLE);
|
||||
wire ext_wr_active = (ext_wr_state != EXT_WR_IDLE);
|
||||
wire ext_rd_accept = ext_rd_req_valid && ext_rd_req_ready;
|
||||
wire ext_wr_accept = ext_wr_req_valid && ext_wr_req_ready;
|
||||
wire ext_any_busy_or_req = ext_rd_active || ext_wr_active || ext_rd_req_valid || ext_wr_req_valid;
|
||||
wire use_ep_engine = ((state == RUN) && (engine_mode != MODE_MEM2MEM));
|
||||
|
||||
// Dynamic routing to the engine based on current active channel
|
||||
assign engine_src = ch_src_addr[cur_ch];
|
||||
@@ -290,6 +443,52 @@ module snix_axil_cdma_mux #(
|
||||
assign engine_bytes = ch_len[cur_ch];
|
||||
assign engine_len = ch_ctrl[cur_ch][13:6];
|
||||
assign engine_size = ch_ctrl[cur_ch][5:3];
|
||||
assign engine_mode = ch_mode[cur_ch][1:0];
|
||||
assign engine_ep_bank = ch_ep_cfg[cur_ch][3:0];
|
||||
assign engine_ep_word_off = ch_ep_cfg[cur_ch][15:8];
|
||||
assign engine_ep_id = ch_ep_cfg[cur_ch][19:16];
|
||||
assign engine_done = (engine_mode == MODE_MEM2MEM) ? mm2mm_done : ep_done;
|
||||
assign mm2mm_start = engine_start && (engine_mode == MODE_MEM2MEM);
|
||||
assign ep_start = engine_start && (engine_mode != MODE_MEM2MEM);
|
||||
|
||||
assign core_awready = (!ext_wr_active && !use_ep_engine) && mm2mm_awready;
|
||||
assign core_wready = (!ext_wr_active && !use_ep_engine) && mm2mm_wready;
|
||||
assign core_arready = (!ext_rd_active && !use_ep_engine) && mm2mm_arready;
|
||||
assign ep_awready = (!ext_wr_active && use_ep_engine) && mm2mm_awready;
|
||||
assign ep_wready = (!ext_wr_active && use_ep_engine) && mm2mm_wready;
|
||||
assign ep_arready = (!ext_rd_active && use_ep_engine) && mm2mm_arready;
|
||||
|
||||
assign mm2mm_awid = ext_wr_active ? '0 : (use_ep_engine ? ep_awid : core_awid);
|
||||
assign mm2mm_awaddr = ext_wr_active ? ext_wr_addr_r : (use_ep_engine ? ep_awaddr : core_awaddr);
|
||||
assign mm2mm_awlen = ext_wr_active ? (((ext_wr_bytes_left[31:2] == 30'd0) ? 8'd1 : ext_wr_bytes_left[9:2]) - 8'd1) : (use_ep_engine ? ep_awlen : core_awlen);
|
||||
assign mm2mm_awsize = ext_wr_active ? 3'd2 : (use_ep_engine ? ep_awsize : core_awsize);
|
||||
assign mm2mm_awburst = ext_wr_active ? 2'b01 : (use_ep_engine ? ep_awburst : core_awburst);
|
||||
assign mm2mm_awlock = ext_wr_active ? 1'b0 : (use_ep_engine ? ep_awlock : core_awlock);
|
||||
assign mm2mm_awcache = ext_wr_active ? 4'b0 : (use_ep_engine ? ep_awcache : core_awcache);
|
||||
assign mm2mm_awprot = ext_wr_active ? 3'b0 : (use_ep_engine ? ep_awprot : core_awprot);
|
||||
assign mm2mm_awqos = ext_wr_active ? 4'b0 : (use_ep_engine ? ep_awqos : core_awqos);
|
||||
assign mm2mm_awuser = ext_wr_active ? '0 : (use_ep_engine ? ep_awuser : core_awuser);
|
||||
assign mm2mm_awvalid = ext_wr_active ? (ext_wr_state == EXT_WR_AW) : (use_ep_engine ? ep_awvalid : core_awvalid);
|
||||
|
||||
assign mm2mm_wdata = ext_wr_active ? ep_rd_data : (use_ep_engine ? ep_wdata : core_wdata);
|
||||
assign mm2mm_wstrb = ext_wr_active ? {{(DATA_WIDTH/8){1'b1}}} : (use_ep_engine ? ep_wstrb : core_wstrb);
|
||||
assign mm2mm_wlast = ext_wr_active ? ((ext_wr_bytes_left <= 32'd4) && mm2mm_wvalid) : (use_ep_engine ? ep_wlast : core_wlast);
|
||||
assign mm2mm_wuser = ext_wr_active ? '0 : (use_ep_engine ? ep_wuser : core_wuser);
|
||||
assign mm2mm_wvalid = ext_wr_active ? ((ext_wr_state == EXT_WR_WRITE) && ep_rd_ready) : (use_ep_engine ? ep_wvalid : core_wvalid);
|
||||
assign mm2mm_bready = ext_wr_active ? (ext_wr_state == EXT_WR_BRESP) : (use_ep_engine ? ep_bready : core_bready);
|
||||
|
||||
assign mm2mm_arid = ext_rd_active ? '0 : (use_ep_engine ? ep_arid : core_arid);
|
||||
assign mm2mm_araddr = ext_rd_active ? ext_rd_addr_r : (use_ep_engine ? ep_araddr : core_araddr);
|
||||
assign mm2mm_arlen = ext_rd_active ? (((ext_rd_bytes_left[31:2] == 30'd0) ? 8'd1 : ext_rd_bytes_left[9:2]) - 8'd1) : (use_ep_engine ? ep_arlen : core_arlen);
|
||||
assign mm2mm_arsize = ext_rd_active ? 3'd2 : (use_ep_engine ? ep_arsize : core_arsize);
|
||||
assign mm2mm_arburst = ext_rd_active ? 2'b01 : (use_ep_engine ? ep_arburst : core_arburst);
|
||||
assign mm2mm_arlock = ext_rd_active ? 1'b0 : (use_ep_engine ? ep_arlock : core_arlock);
|
||||
assign mm2mm_arcache = ext_rd_active ? 4'b0 : (use_ep_engine ? ep_arcache : core_arcache);
|
||||
assign mm2mm_arprot = ext_rd_active ? 3'b0 : (use_ep_engine ? ep_arprot : core_arprot);
|
||||
assign mm2mm_arqos = ext_rd_active ? 4'b0 : (use_ep_engine ? ep_arqos : core_arqos);
|
||||
assign mm2mm_aruser = ext_rd_active ? '0 : (use_ep_engine ? ep_aruser : core_aruser);
|
||||
assign mm2mm_arvalid = ext_rd_active ? (ext_rd_state == EXT_RD_AR) : (use_ep_engine ? ep_arvalid : core_arvalid);
|
||||
assign mm2mm_rready = ext_rd_active ? ((ext_rd_state == EXT_RD_READ) && ep_wr_ready) : (use_ep_engine ? ep_rready : core_rready);
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!rst_n) begin
|
||||
@@ -304,7 +503,9 @@ module snix_axil_cdma_mux #(
|
||||
|
||||
case (state)
|
||||
IDLE: begin
|
||||
for (int i = 0; i < PORTS; i++) begin
|
||||
if (ext_any_busy_or_req) begin
|
||||
state <= IDLE;
|
||||
end else for (int i = 0; i < PORTS; i++) begin
|
||||
logic [CH_BITS:0] check_ch_ext;
|
||||
logic [CH_BITS-1:0] check_ch;
|
||||
|
||||
@@ -315,13 +516,17 @@ module snix_axil_cdma_mux #(
|
||||
if (ch_req[check_ch] && !arb_set_done[check_ch]) begin
|
||||
cur_ch <= check_ch;
|
||||
rr_ptr <= (check_ch == (PORTS - 1)) ? '0 : (check_ch + 1);
|
||||
engine_start <= 1'b1;
|
||||
state <= RUN;
|
||||
state <= START;
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
START: begin
|
||||
engine_start <= 1'b1;
|
||||
state <= RUN;
|
||||
end
|
||||
|
||||
RUN: begin
|
||||
if (engine_done) begin
|
||||
arb_set_done[cur_ch] <= 1'b1;
|
||||
@@ -345,37 +550,255 @@ module snix_axil_cdma_mux #(
|
||||
) u_core_engine (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
.ctrl_start (engine_start),
|
||||
.ctrl_start (mm2mm_start),
|
||||
.ctrl_stop (1'b0), // Tied off; can be wired if global abort is needed
|
||||
.ctrl_src_addr (engine_src),
|
||||
.ctrl_dst_addr (engine_dst),
|
||||
.ctrl_len (engine_len),
|
||||
.ctrl_size (engine_size),
|
||||
.ctrl_transfer_len (engine_bytes),
|
||||
.ctrl_done (engine_done),
|
||||
.ctrl_done (mm2mm_done),
|
||||
// AXI4 Port Connections
|
||||
.mm2mm_awid (mm2mm_awid), .mm2mm_awaddr (mm2mm_awaddr),
|
||||
.mm2mm_awlen (mm2mm_awlen), .mm2mm_awsize (mm2mm_awsize),
|
||||
.mm2mm_awburst(mm2mm_awburst),.mm2mm_awlock (mm2mm_awlock),
|
||||
.mm2mm_awcache(mm2mm_awcache),.mm2mm_awprot (mm2mm_awprot),
|
||||
.mm2mm_awqos (mm2mm_awqos), .mm2mm_awuser (mm2mm_awuser),
|
||||
.mm2mm_awvalid(mm2mm_awvalid),.mm2mm_awready(mm2mm_awready),
|
||||
.mm2mm_wdata (mm2mm_wdata), .mm2mm_wstrb (mm2mm_wstrb),
|
||||
.mm2mm_wlast (mm2mm_wlast), .mm2mm_wuser (mm2mm_wuser),
|
||||
.mm2mm_wvalid (mm2mm_wvalid), .mm2mm_wready (mm2mm_wready),
|
||||
.mm2mm_awid (core_awid), .mm2mm_awaddr (core_awaddr),
|
||||
.mm2mm_awlen (core_awlen), .mm2mm_awsize (core_awsize),
|
||||
.mm2mm_awburst(core_awburst),.mm2mm_awlock (core_awlock),
|
||||
.mm2mm_awcache(core_awcache),.mm2mm_awprot (core_awprot),
|
||||
.mm2mm_awqos (core_awqos), .mm2mm_awuser (core_awuser),
|
||||
.mm2mm_awvalid(core_awvalid),.mm2mm_awready(core_awready),
|
||||
.mm2mm_wdata (core_wdata), .mm2mm_wstrb (core_wstrb),
|
||||
.mm2mm_wlast (core_wlast), .mm2mm_wuser (core_wuser),
|
||||
.mm2mm_wvalid (core_wvalid), .mm2mm_wready (core_wready),
|
||||
.mm2mm_bid (mm2mm_bid), .mm2mm_bresp (mm2mm_bresp),
|
||||
.mm2mm_buser (mm2mm_buser), .mm2mm_bvalid (mm2mm_bvalid),
|
||||
.mm2mm_bready (mm2mm_bready),
|
||||
.mm2mm_arid (mm2mm_arid), .mm2mm_araddr (mm2mm_araddr),
|
||||
.mm2mm_arlen (mm2mm_arlen), .mm2mm_arsize (mm2mm_arsize),
|
||||
.mm2mm_arburst(mm2mm_arburst),.mm2mm_arlock (mm2mm_arlock),
|
||||
.mm2mm_arcache(mm2mm_arcache),.mm2mm_arprot (mm2mm_arprot),
|
||||
.mm2mm_arqos (mm2mm_arqos), .mm2mm_aruser (mm2mm_aruser),
|
||||
.mm2mm_arvalid(mm2mm_arvalid),.mm2mm_arready(mm2mm_arready),
|
||||
.mm2mm_bready (core_bready),
|
||||
.mm2mm_arid (core_arid), .mm2mm_araddr (core_araddr),
|
||||
.mm2mm_arlen (core_arlen), .mm2mm_arsize (core_arsize),
|
||||
.mm2mm_arburst(core_arburst),.mm2mm_arlock (core_arlock),
|
||||
.mm2mm_arcache(core_arcache),.mm2mm_arprot (core_arprot),
|
||||
.mm2mm_arqos (core_arqos), .mm2mm_aruser (core_aruser),
|
||||
.mm2mm_arvalid(core_arvalid),.mm2mm_arready(core_arready),
|
||||
.mm2mm_rid (mm2mm_rid), .mm2mm_rdata (mm2mm_rdata),
|
||||
.mm2mm_rresp (mm2mm_rresp), .mm2mm_rlast (mm2mm_rlast),
|
||||
.mm2mm_ruser (mm2mm_ruser), .mm2mm_rvalid (mm2mm_rvalid),
|
||||
.mm2mm_rready (mm2mm_rready)
|
||||
.mm2mm_rready (core_rready)
|
||||
);
|
||||
|
||||
wire [7:0] ep_beats_total = (engine_bytes[31:2] == 30'd0) ? 8'd1 : engine_bytes[9:2];
|
||||
wire [7:0] ep_axi_len = ep_beats_total - 8'd1;
|
||||
wire ep_mode_mem2ep = (engine_mode == MODE_MEM2EP);
|
||||
wire ep_mode_ep2mem = (engine_mode == MODE_EP2MEM);
|
||||
wire ep_rd_done_fire = (ep_state == EP_READ) && mm2mm_rvalid && ep_rready && mm2mm_rlast;
|
||||
wire ep_wr_done_fire = (ep_state == EP_BRESP) && mm2mm_bvalid && ep_bready;
|
||||
wire ep_done_fast = ep_rd_done_fire || ep_wr_done_fire;
|
||||
wire ext_rd_done_fire = (ext_rd_state == EXT_RD_READ) && mm2mm_rvalid && mm2mm_rready && mm2mm_rlast;
|
||||
wire ext_wr_done_fire = (ext_wr_state == EXT_WR_BRESP) && mm2mm_bvalid && mm2mm_bready;
|
||||
wire ext_wr_w_fire = (ext_wr_state == EXT_WR_WRITE) && mm2mm_wvalid && mm2mm_wready;
|
||||
|
||||
// ==========================================
|
||||
// Generic external endpoint requester
|
||||
// ==========================================
|
||||
assign ext_rd_req_ready = (state == IDLE) && (ep_state == EP_IDLE) && !ext_rd_active;
|
||||
assign ext_wr_req_ready = (state == IDLE) && (ep_state == EP_IDLE) && !ext_wr_active;
|
||||
assign ext_rd_req_done = ext_rd_done_fire;
|
||||
assign ext_wr_req_done = ext_wr_done_fire;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!rst_n) begin
|
||||
ext_rd_state <= EXT_RD_IDLE;
|
||||
ext_rd_addr_r <= '0;
|
||||
ext_rd_bytes_left <= '0;
|
||||
ext_rd_word_addr_r <= '0;
|
||||
ext_rd_ep_id_r <= '0;
|
||||
ext_rd_ep_bank_r <= '0;
|
||||
end else begin
|
||||
case (ext_rd_state)
|
||||
EXT_RD_IDLE: begin
|
||||
if (ext_rd_accept) begin
|
||||
ext_rd_addr_r <= ext_rd_req_src;
|
||||
ext_rd_bytes_left <= ext_rd_req_bytes;
|
||||
ext_rd_word_addr_r <= ext_rd_req_ep_word_off;
|
||||
ext_rd_ep_id_r <= ext_rd_req_ep_id;
|
||||
ext_rd_ep_bank_r <= ext_rd_req_ep_bank;
|
||||
ext_rd_state <= EXT_RD_AR;
|
||||
end
|
||||
end
|
||||
|
||||
EXT_RD_AR: begin
|
||||
if (mm2mm_arvalid && mm2mm_arready)
|
||||
ext_rd_state <= EXT_RD_READ;
|
||||
end
|
||||
|
||||
EXT_RD_READ: begin
|
||||
if (mm2mm_rvalid && mm2mm_rready) begin
|
||||
ext_rd_word_addr_r <= ext_rd_word_addr_r + 8'd1;
|
||||
ext_rd_bytes_left <= (ext_rd_bytes_left > 32'd4) ? (ext_rd_bytes_left - 32'd4) : 32'd0;
|
||||
if (mm2mm_rlast)
|
||||
ext_rd_state <= EXT_RD_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
default: ext_rd_state <= EXT_RD_IDLE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!rst_n) begin
|
||||
ext_wr_state <= EXT_WR_IDLE;
|
||||
ext_wr_addr_r <= '0;
|
||||
ext_wr_bytes_left <= '0;
|
||||
ext_wr_word_addr_r <= '0;
|
||||
ext_wr_ep_id_r <= '0;
|
||||
ext_wr_ep_bank_r <= '0;
|
||||
end else begin
|
||||
case (ext_wr_state)
|
||||
EXT_WR_IDLE: begin
|
||||
if (ext_wr_accept) begin
|
||||
ext_wr_addr_r <= ext_wr_req_dst;
|
||||
ext_wr_bytes_left <= ext_wr_req_bytes;
|
||||
ext_wr_word_addr_r <= ext_wr_req_ep_word_off;
|
||||
ext_wr_ep_id_r <= ext_wr_req_ep_id;
|
||||
ext_wr_ep_bank_r <= ext_wr_req_ep_bank;
|
||||
ext_wr_state <= EXT_WR_AW;
|
||||
end
|
||||
end
|
||||
|
||||
EXT_WR_AW: begin
|
||||
if (mm2mm_awvalid && mm2mm_awready)
|
||||
ext_wr_state <= EXT_WR_WRITE;
|
||||
end
|
||||
|
||||
EXT_WR_WRITE: begin
|
||||
if (ext_wr_w_fire) begin
|
||||
ext_wr_word_addr_r <= ext_wr_word_addr_r + 8'd1;
|
||||
ext_wr_bytes_left <= (ext_wr_bytes_left > 32'd4) ? (ext_wr_bytes_left - 32'd4) : 32'd0;
|
||||
if (mm2mm_wlast)
|
||||
ext_wr_state <= EXT_WR_BRESP;
|
||||
end
|
||||
end
|
||||
|
||||
EXT_WR_BRESP: begin
|
||||
if (mm2mm_bvalid && mm2mm_bready)
|
||||
ext_wr_state <= EXT_WR_IDLE;
|
||||
end
|
||||
|
||||
default: ext_wr_state <= EXT_WR_IDLE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// ==========================================
|
||||
// Endpoint transfer engine (32-bit only in this SoC integration)
|
||||
// ==========================================
|
||||
always_ff @(posedge clk) begin
|
||||
if (!rst_n) begin
|
||||
ep_state <= EP_IDLE;
|
||||
ep_done <= 1'b0;
|
||||
ep_axi_addr <= '0;
|
||||
ep_bytes_left <= '0;
|
||||
ep_word_addr_r <= '0;
|
||||
end else begin
|
||||
ep_done <= 1'b0;
|
||||
|
||||
case (ep_state)
|
||||
EP_IDLE: begin
|
||||
if (ep_start) begin
|
||||
ep_axi_addr <= ep_mode_mem2ep ? engine_src : engine_dst;
|
||||
ep_bytes_left <= engine_bytes;
|
||||
ep_word_addr_r <= engine_ep_word_off;
|
||||
ep_state <= ep_mode_mem2ep ? EP_AR : EP_AW;
|
||||
end
|
||||
end
|
||||
|
||||
EP_AR: begin
|
||||
if (ep_arvalid && ep_arready)
|
||||
ep_state <= EP_READ;
|
||||
end
|
||||
|
||||
EP_READ: begin
|
||||
if (mm2mm_rvalid && ep_rready) begin
|
||||
ep_word_addr_r <= ep_word_addr_r + 8'd1;
|
||||
ep_bytes_left <= (ep_bytes_left > 32'd4) ? (ep_bytes_left - 32'd4) : 32'd0;
|
||||
if (mm2mm_rlast) begin
|
||||
ep_done <= 1'b1;
|
||||
ep_state <= EP_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
EP_AW: begin
|
||||
if (ep_awvalid && ep_awready)
|
||||
ep_state <= EP_WRITE;
|
||||
end
|
||||
|
||||
EP_WRITE: begin
|
||||
if (ep_wvalid && ep_wready) begin
|
||||
ep_word_addr_r <= ep_word_addr_r + 8'd1;
|
||||
ep_bytes_left <= (ep_bytes_left > 32'd4) ? (ep_bytes_left - 32'd4) : 32'd0;
|
||||
if (ep_wlast)
|
||||
ep_state <= EP_BRESP;
|
||||
end
|
||||
end
|
||||
|
||||
EP_BRESP: begin
|
||||
if (mm2mm_bvalid && ep_bready) begin
|
||||
ep_done <= 1'b1;
|
||||
ep_state <= EP_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
EP_DONE: begin
|
||||
ep_done <= 1'b1;
|
||||
ep_state <= EP_IDLE;
|
||||
end
|
||||
|
||||
default: ep_state <= EP_IDLE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign ep_arid = '0;
|
||||
assign ep_araddr = ep_axi_addr;
|
||||
assign ep_arlen = ep_axi_len;
|
||||
assign ep_arsize = 3'd2;
|
||||
assign ep_arburst = 2'b01;
|
||||
assign ep_arlock = 1'b0;
|
||||
assign ep_arcache = 4'b0;
|
||||
assign ep_arprot = 3'b0;
|
||||
assign ep_arqos = 4'b0;
|
||||
assign ep_aruser = '0;
|
||||
assign ep_arvalid = (ep_state == EP_AR);
|
||||
assign ep_rready = (ep_state == EP_READ) && ep_wr_ready;
|
||||
|
||||
assign ep_wr_valid = ext_rd_active ? ((ext_rd_state == EXT_RD_READ) && mm2mm_rvalid) :
|
||||
((ep_state == EP_READ) && mm2mm_rvalid && ep_mode_mem2ep);
|
||||
assign ep_wr_id = ext_rd_active ? ext_rd_ep_id_r : engine_ep_id;
|
||||
assign ep_wr_bank = ext_rd_active ? ext_rd_ep_bank_r : engine_ep_bank;
|
||||
assign ep_wr_word_addr = ext_rd_active ? ext_rd_word_addr_r : ep_word_addr_r;
|
||||
assign ep_wr_data = mm2mm_rdata[31:0];
|
||||
|
||||
assign ep_awid = '0;
|
||||
assign ep_awaddr = ep_axi_addr;
|
||||
assign ep_awlen = ep_axi_len;
|
||||
assign ep_awsize = 3'd2;
|
||||
assign ep_awburst = 2'b01;
|
||||
assign ep_awlock = 1'b0;
|
||||
assign ep_awcache = 4'b0;
|
||||
assign ep_awprot = 3'b0;
|
||||
assign ep_awqos = 4'b0;
|
||||
assign ep_awuser = '0;
|
||||
assign ep_awvalid = (ep_state == EP_AW);
|
||||
assign ep_wdata = ep_rd_data;
|
||||
assign ep_wstrb = {{(DATA_WIDTH/8){1'b1}}};
|
||||
assign ep_wlast = (ep_bytes_left <= 32'd4) && ep_wvalid;
|
||||
assign ep_wuser = '0;
|
||||
assign ep_wvalid = (ep_state == EP_WRITE) && ep_mode_ep2mem && ep_rd_ready;
|
||||
assign ep_bready = (ep_state == EP_BRESP);
|
||||
|
||||
assign ep_rd_valid = ext_wr_active ? ((ext_wr_state == EXT_WR_WRITE) && mm2mm_wready) :
|
||||
((ep_state == EP_WRITE) && ep_mode_ep2mem && ep_wready);
|
||||
assign ep_rd_id = ext_wr_active ? ext_wr_ep_id_r : engine_ep_id;
|
||||
assign ep_rd_bank = ext_wr_active ? ext_wr_ep_bank_r : engine_ep_bank;
|
||||
assign ep_rd_word_addr = ext_wr_active ? ext_wr_word_addr_r : ep_word_addr_r;
|
||||
|
||||
endmodule
|
||||
32
rtl/ip/fft/Butterfly.v
Normal file
@@ -0,0 +1,32 @@
|
||||
//----------------------------------------------------------------------
|
||||
// Butterfly: Add/Sub and Scaling
|
||||
//----------------------------------------------------------------------
|
||||
module Butterfly #(
|
||||
parameter WIDTH = 16,
|
||||
parameter RH = 0 // Round Half Up
|
||||
)(
|
||||
input signed [WIDTH-1:0] x0_re, // Input Data #0 (Real)
|
||||
input signed [WIDTH-1:0] x0_im, // Input Data #0 (Imag)
|
||||
input signed [WIDTH-1:0] x1_re, // Input Data #1 (Real)
|
||||
input signed [WIDTH-1:0] x1_im, // Input Data #1 (Imag)
|
||||
output signed [WIDTH-1:0] y0_re, // Output Data #0 (Real)
|
||||
output signed [WIDTH-1:0] y0_im, // Output Data #0 (Imag)
|
||||
output signed [WIDTH-1:0] y1_re, // Output Data #1 (Real)
|
||||
output signed [WIDTH-1:0] y1_im // Output Data #1 (Imag)
|
||||
);
|
||||
|
||||
wire signed [WIDTH:0] add_re, add_im, sub_re, sub_im;
|
||||
|
||||
// Add/Sub
|
||||
assign add_re = x0_re + x1_re;
|
||||
assign add_im = x0_im + x1_im;
|
||||
assign sub_re = x0_re - x1_re;
|
||||
assign sub_im = x0_im - x1_im;
|
||||
|
||||
// Scaling
|
||||
assign y0_re = (add_re + RH) >>> 1;
|
||||
assign y0_im = (add_im + RH) >>> 1;
|
||||
assign y1_re = (sub_re + RH) >>> 1;
|
||||
assign y1_im = (sub_im + RH) >>> 1;
|
||||
|
||||
endmodule
|
||||
34
rtl/ip/fft/DelayBuffer.v
Normal file
@@ -0,0 +1,34 @@
|
||||
//----------------------------------------------------------------------
|
||||
// DelayBuffer: Generate Constant Delay
|
||||
//----------------------------------------------------------------------
|
||||
module DelayBuffer #(
|
||||
parameter DEPTH = 32,
|
||||
parameter WIDTH = 16
|
||||
)(
|
||||
input clock, // Master Clock
|
||||
input [WIDTH-1:0] di_re, // Data Input (Real)
|
||||
input [WIDTH-1:0] di_im, // Data Input (Imag)
|
||||
output [WIDTH-1:0] do_re, // Data Output (Real)
|
||||
output [WIDTH-1:0] do_im // Data Output (Imag)
|
||||
);
|
||||
|
||||
reg [WIDTH-1:0] buf_re[0:DEPTH-1];
|
||||
reg [WIDTH-1:0] buf_im[0:DEPTH-1];
|
||||
integer n;
|
||||
|
||||
// Shift Buffer
|
||||
/* verilator lint_off BLKLOOPINIT */
|
||||
always @(posedge clock) begin
|
||||
for (n = DEPTH-1; n > 0; n = n - 1) begin
|
||||
buf_re[n] <= buf_re[n-1];
|
||||
buf_im[n] <= buf_im[n-1];
|
||||
end
|
||||
buf_re[0] <= di_re;
|
||||
buf_im[0] <= di_im;
|
||||
end
|
||||
/* verilator lint_on BLKLOOPINIT */
|
||||
|
||||
assign do_re = buf_re[DEPTH-1];
|
||||
assign do_im = buf_im[DEPTH-1];
|
||||
|
||||
endmodule
|
||||
90
rtl/ip/fft/FFT1024_32B.v
Normal file
@@ -0,0 +1,90 @@
|
||||
//----------------------------------------------------------------------
|
||||
// FFT: 1024-Point FFT Using Radix-2^2 Single-Path Delay Feedback
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
module FFT #(
|
||||
parameter WIDTH = 32
|
||||
)(
|
||||
input clock, // Master Clock
|
||||
input reset, // Active High Asynchronous Reset
|
||||
input di_en, // Input Data Enable
|
||||
input [WIDTH-1:0] di_re, // Input Data (Real)
|
||||
input [WIDTH-1:0] di_im, // Input Data (Imag)
|
||||
output do_en, // Output Data Enable
|
||||
output [WIDTH-1:0] do_re, // Output Data (Real)
|
||||
output [WIDTH-1:0] do_im // Output Data (Imag)
|
||||
);
|
||||
//----------------------------------------------------------------------
|
||||
// Data must be input consecutively in natural order.
|
||||
// The result is scaled to 1/N and output in bit-reversed order.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
wire su1_do_en;
|
||||
wire[WIDTH-1:0] su1_do_re;
|
||||
wire[WIDTH-1:0] su1_do_im;
|
||||
wire su2_do_en;
|
||||
wire[WIDTH-1:0] su2_do_re;
|
||||
wire[WIDTH-1:0] su2_do_im;
|
||||
wire su3_do_en;
|
||||
wire[WIDTH-1:0] su3_do_re;
|
||||
wire[WIDTH-1:0] su3_do_im;
|
||||
wire su4_do_en;
|
||||
wire[WIDTH-1:0] su4_do_re;
|
||||
wire[WIDTH-1:0] su4_do_im;
|
||||
|
||||
SdfUnit #(.N(1024),.M(1024),.WIDTH(WIDTH)) SU1 (
|
||||
.clock (clock ), // i
|
||||
.reset (reset ), // i
|
||||
.di_en (di_en ), // i
|
||||
.di_re (di_re ), // i
|
||||
.di_im (di_im ), // i
|
||||
.do_en (su1_do_en ), // o
|
||||
.do_re (su1_do_re ), // o
|
||||
.do_im (su1_do_im ) // o
|
||||
);
|
||||
|
||||
SdfUnit #(.N(1024),.M(256),.WIDTH(WIDTH)) SU2 (
|
||||
.clock (clock ), // i
|
||||
.reset (reset ), // i
|
||||
.di_en (su1_do_en ), // i
|
||||
.di_re (su1_do_re ), // i
|
||||
.di_im (su1_do_im ), // i
|
||||
.do_en (su2_do_en ), // o
|
||||
.do_re (su2_do_re ), // o
|
||||
.do_im (su2_do_im ) // o
|
||||
);
|
||||
|
||||
SdfUnit #(.N(1024),.M(64),.WIDTH(WIDTH)) SU3 (
|
||||
.clock (clock ), // i
|
||||
.reset (reset ), // i
|
||||
.di_en (su2_do_en ), // i
|
||||
.di_re (su2_do_re ), // i
|
||||
.di_im (su2_do_im ), // i
|
||||
.do_en (su3_do_en ), // o
|
||||
.do_re (su3_do_re ), // o
|
||||
.do_im (su3_do_im ) // o
|
||||
);
|
||||
|
||||
SdfUnit #(.N(1024),.M(16),.WIDTH(WIDTH)) SU4 (
|
||||
.clock (clock ), // i
|
||||
.reset (reset ), // i
|
||||
.di_en (su3_do_en ), // i
|
||||
.di_re (su3_do_re ), // i
|
||||
.di_im (su3_do_im ), // i
|
||||
.do_en (su4_do_en ), // o
|
||||
.do_re (su4_do_re ), // o
|
||||
.do_im (su4_do_im ) // o
|
||||
);
|
||||
|
||||
SdfUnit #(.N(1024),.M(4),.WIDTH(WIDTH)) SU5 (
|
||||
.clock (clock ), // i
|
||||
.reset (reset ), // i
|
||||
.di_en (su4_do_en ), // i
|
||||
.di_re (su4_do_re ), // i
|
||||
.di_im (su4_do_im ), // i
|
||||
.do_en (do_en ), // o
|
||||
.do_re (do_re ), // o
|
||||
.do_im (do_im ) // o
|
||||
);
|
||||
|
||||
endmodule
|
||||
36
rtl/ip/fft/Multiply.v
Normal file
@@ -0,0 +1,36 @@
|
||||
//----------------------------------------------------------------------
|
||||
// Multiply: Complex Multiplier
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
(* use_dsp = "no" *) module Multiply #(
|
||||
parameter WIDTH = 16
|
||||
)(
|
||||
input signed [WIDTH-1:0] a_re,
|
||||
input signed [WIDTH-1:0] a_im,
|
||||
input signed [WIDTH-1:0] b_re,
|
||||
input signed [WIDTH-1:0] b_im,
|
||||
output signed [WIDTH-1:0] m_re,
|
||||
output signed [WIDTH-1:0] m_im
|
||||
);
|
||||
|
||||
wire signed [WIDTH*2-1:0] arbr, arbi, aibr, aibi;
|
||||
wire signed [WIDTH-1:0] sc_arbr, sc_arbi, sc_aibr, sc_aibi;
|
||||
|
||||
// Signed Multiplication
|
||||
assign arbr = a_re * b_re;
|
||||
assign arbi = a_re * b_im;
|
||||
assign aibr = a_im * b_re;
|
||||
assign aibi = a_im * b_im;
|
||||
|
||||
// Scaling
|
||||
assign sc_arbr = arbr >>> (WIDTH-1);
|
||||
assign sc_arbi = arbi >>> (WIDTH-1);
|
||||
assign sc_aibr = aibr >>> (WIDTH-1);
|
||||
assign sc_aibi = aibi >>> (WIDTH-1);
|
||||
|
||||
// Sub/Add
|
||||
// These sub/add may overflow if unnormalized data is input.
|
||||
assign m_re = sc_arbr - sc_aibi;
|
||||
assign m_im = sc_arbi + sc_aibr;
|
||||
|
||||
endmodule
|
||||
280
rtl/ip/fft/SdfUnit.v
Normal file
@@ -0,0 +1,280 @@
|
||||
//----------------------------------------------------------------------
|
||||
// SdfUnit: Radix-2^2 Single-Path Delay Feedback Unit for N-Point FFT
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
module SdfUnit #(
|
||||
parameter N = 64, // Number of FFT Point
|
||||
parameter M = 64, // Twiddle Resolution
|
||||
parameter WIDTH = 16 // Data Bit Length
|
||||
)(
|
||||
input clock, // Master Clock
|
||||
input reset, // Active High Asynchronous Reset
|
||||
input di_en, // Input Data Enable
|
||||
input [WIDTH-1:0] di_re, // Input Data (Real)
|
||||
input [WIDTH-1:0] di_im, // Input Data (Imag)
|
||||
output do_en, // Output Data Enable
|
||||
output [WIDTH-1:0] do_re, // Output Data (Real)
|
||||
output [WIDTH-1:0] do_im // Output Data (Imag)
|
||||
);
|
||||
|
||||
// log2 constant function
|
||||
function integer log2;
|
||||
input integer x;
|
||||
integer value;
|
||||
begin
|
||||
value = x-1;
|
||||
for (log2=0; value>0; log2=log2+1)
|
||||
value = value>>1;
|
||||
end
|
||||
endfunction
|
||||
|
||||
localparam LOG_N = log2(N); // Bit Length of N
|
||||
localparam LOG_M = log2(M); // Bit Length of M
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Internal Regs and Nets
|
||||
//----------------------------------------------------------------------
|
||||
// 1st Butterfly
|
||||
reg [LOG_N-1:0] di_count; // Input Data Count
|
||||
wire bf1_bf; // Butterfly Add/Sub Enable
|
||||
wire[WIDTH-1:0] bf1_x0_re; // Data #0 to Butterfly (Real)
|
||||
wire[WIDTH-1:0] bf1_x0_im; // Data #0 to Butterfly (Imag)
|
||||
wire[WIDTH-1:0] bf1_x1_re; // Data #1 to Butterfly (Real)
|
||||
wire[WIDTH-1:0] bf1_x1_im; // Data #1 to Butterfly (Imag)
|
||||
wire[WIDTH-1:0] bf1_y0_re; // Data #0 from Butterfly (Real)
|
||||
wire[WIDTH-1:0] bf1_y0_im; // Data #0 from Butterfly (Imag)
|
||||
wire[WIDTH-1:0] bf1_y1_re; // Data #1 from Butterfly (Real)
|
||||
wire[WIDTH-1:0] bf1_y1_im; // Data #1 from Butterfly (Imag)
|
||||
wire[WIDTH-1:0] db1_di_re; // Data to DelayBuffer (Real)
|
||||
wire[WIDTH-1:0] db1_di_im; // Data to DelayBuffer (Imag)
|
||||
wire[WIDTH-1:0] db1_do_re; // Data from DelayBuffer (Real)
|
||||
wire[WIDTH-1:0] db1_do_im; // Data from DelayBuffer (Imag)
|
||||
wire[WIDTH-1:0] bf1_sp_re; // Single-Path Data Output (Real)
|
||||
wire[WIDTH-1:0] bf1_sp_im; // Single-Path Data Output (Imag)
|
||||
reg bf1_sp_en; // Single-Path Data Enable
|
||||
reg [LOG_N-1:0] bf1_count; // Single-Path Data Count
|
||||
wire bf1_start; // Single-Path Output Trigger
|
||||
wire bf1_end; // End of Single-Path Data
|
||||
wire bf1_mj; // Twiddle (-j) Enable
|
||||
reg [WIDTH-1:0] bf1_do_re; // 1st Butterfly Output Data (Real)
|
||||
reg [WIDTH-1:0] bf1_do_im; // 1st Butterfly Output Data (Imag)
|
||||
|
||||
// 2nd Butterfly
|
||||
reg bf2_bf; // Butterfly Add/Sub Enable
|
||||
wire[WIDTH-1:0] bf2_x0_re; // Data #0 to Butterfly (Real)
|
||||
wire[WIDTH-1:0] bf2_x0_im; // Data #0 to Butterfly (Imag)
|
||||
wire[WIDTH-1:0] bf2_x1_re; // Data #1 to Butterfly (Real)
|
||||
wire[WIDTH-1:0] bf2_x1_im; // Data #1 to Butterfly (Imag)
|
||||
wire[WIDTH-1:0] bf2_y0_re; // Data #0 from Butterfly (Real)
|
||||
wire[WIDTH-1:0] bf2_y0_im; // Data #0 from Butterfly (Imag)
|
||||
wire[WIDTH-1:0] bf2_y1_re; // Data #1 from Butterfly (Real)
|
||||
wire[WIDTH-1:0] bf2_y1_im; // Data #1 from Butterfly (Imag)
|
||||
wire[WIDTH-1:0] db2_di_re; // Data to DelayBuffer (Real)
|
||||
wire[WIDTH-1:0] db2_di_im; // Data to DelayBuffer (Imag)
|
||||
wire[WIDTH-1:0] db2_do_re; // Data from DelayBuffer (Real)
|
||||
wire[WIDTH-1:0] db2_do_im; // Data from DelayBuffer (Imag)
|
||||
wire[WIDTH-1:0] bf2_sp_re; // Single-Path Data Output (Real)
|
||||
wire[WIDTH-1:0] bf2_sp_im; // Single-Path Data Output (Imag)
|
||||
reg bf2_sp_en; // Single-Path Data Enable
|
||||
reg [LOG_N-1:0] bf2_count; // Single-Path Data Count
|
||||
reg bf2_start; // Single-Path Output Trigger
|
||||
wire bf2_end; // End of Single-Path Data
|
||||
reg [WIDTH-1:0] bf2_do_re; // 2nd Butterfly Output Data (Real)
|
||||
reg [WIDTH-1:0] bf2_do_im; // 2nd Butterfly Output Data (Imag)
|
||||
reg bf2_do_en; // 2nd Butterfly Output Data Enable
|
||||
|
||||
// Multiplication
|
||||
wire[1:0] tw_sel; // Twiddle Select (2n/n/3n)
|
||||
wire[LOG_N-3:0] tw_num; // Twiddle Number (n)
|
||||
wire[LOG_N-1:0] tw_addr; // Twiddle Table Address
|
||||
wire[WIDTH-1:0] tw_re; // Twiddle Factor (Real)
|
||||
wire[WIDTH-1:0] tw_im; // Twiddle Factor (Imag)
|
||||
reg mu_en; // Multiplication Enable
|
||||
wire[WIDTH-1:0] mu_a_re; // Multiplier Input (Real)
|
||||
wire[WIDTH-1:0] mu_a_im; // Multiplier Input (Imag)
|
||||
wire[WIDTH-1:0] mu_m_re; // Multiplier Output (Real)
|
||||
wire[WIDTH-1:0] mu_m_im; // Multiplier Output (Imag)
|
||||
reg [WIDTH-1:0] mu_do_re; // Multiplication Output Data (Real)
|
||||
reg [WIDTH-1:0] mu_do_im; // Multiplication Output Data (Imag)
|
||||
reg mu_do_en; // Multiplication Output Data Enable
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 1st Butterfly
|
||||
//----------------------------------------------------------------------
|
||||
always @(posedge clock or posedge reset) begin
|
||||
if (reset) begin
|
||||
di_count <= {LOG_N{1'b0}};
|
||||
end else begin
|
||||
di_count <= di_en ? (di_count + 1'b1) : {LOG_N{1'b0}};
|
||||
end
|
||||
end
|
||||
assign bf1_bf = di_count[LOG_M-1];
|
||||
|
||||
// Set unknown value x for verification
|
||||
assign bf1_x0_re = bf1_bf ? db1_do_re : {WIDTH{1'bx}};
|
||||
assign bf1_x0_im = bf1_bf ? db1_do_im : {WIDTH{1'bx}};
|
||||
assign bf1_x1_re = bf1_bf ? di_re : {WIDTH{1'bx}};
|
||||
assign bf1_x1_im = bf1_bf ? di_im : {WIDTH{1'bx}};
|
||||
|
||||
Butterfly #(.WIDTH(WIDTH),.RH(0)) BF1 (
|
||||
.x0_re (bf1_x0_re ), // i
|
||||
.x0_im (bf1_x0_im ), // i
|
||||
.x1_re (bf1_x1_re ), // i
|
||||
.x1_im (bf1_x1_im ), // i
|
||||
.y0_re (bf1_y0_re ), // o
|
||||
.y0_im (bf1_y0_im ), // o
|
||||
.y1_re (bf1_y1_re ), // o
|
||||
.y1_im (bf1_y1_im ) // o
|
||||
);
|
||||
|
||||
DelayBuffer #(.DEPTH(2**(LOG_M-1)),.WIDTH(WIDTH)) DB1 (
|
||||
.clock (clock ), // i
|
||||
.di_re (db1_di_re ), // i
|
||||
.di_im (db1_di_im ), // i
|
||||
.do_re (db1_do_re ), // o
|
||||
.do_im (db1_do_im ) // o
|
||||
);
|
||||
|
||||
assign db1_di_re = bf1_bf ? bf1_y1_re : di_re;
|
||||
assign db1_di_im = bf1_bf ? bf1_y1_im : di_im;
|
||||
assign bf1_sp_re = bf1_bf ? bf1_y0_re : bf1_mj ? db1_do_im : db1_do_re;
|
||||
assign bf1_sp_im = bf1_bf ? bf1_y0_im : bf1_mj ? -db1_do_re : db1_do_im;
|
||||
|
||||
always @(posedge clock or posedge reset) begin
|
||||
if (reset) begin
|
||||
bf1_sp_en <= 1'b0;
|
||||
bf1_count <= {LOG_N{1'b0}};
|
||||
end else begin
|
||||
bf1_sp_en <= bf1_start ? 1'b1 : bf1_end ? 1'b0 : bf1_sp_en;
|
||||
bf1_count <= bf1_sp_en ? (bf1_count + 1'b1) : {LOG_N{1'b0}};
|
||||
end
|
||||
end
|
||||
assign bf1_start = (di_count == (2**(LOG_M-1)-1));
|
||||
assign bf1_end = (bf1_count == (2**LOG_N-1));
|
||||
assign bf1_mj = (bf1_count[LOG_M-1:LOG_M-2] == 2'd3);
|
||||
|
||||
always @(posedge clock) begin
|
||||
bf1_do_re <= bf1_sp_re;
|
||||
bf1_do_im <= bf1_sp_im;
|
||||
end
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 2nd Butterfly
|
||||
//----------------------------------------------------------------------
|
||||
always @(posedge clock) begin
|
||||
bf2_bf <= bf1_count[LOG_M-2];
|
||||
end
|
||||
|
||||
// Set unknown value x for verification
|
||||
assign bf2_x0_re = bf2_bf ? db2_do_re : {WIDTH{1'bx}};
|
||||
assign bf2_x0_im = bf2_bf ? db2_do_im : {WIDTH{1'bx}};
|
||||
assign bf2_x1_re = bf2_bf ? bf1_do_re : {WIDTH{1'bx}};
|
||||
assign bf2_x1_im = bf2_bf ? bf1_do_im : {WIDTH{1'bx}};
|
||||
|
||||
// Negative bias occurs when RH=0 and positive bias occurs when RH=1.
|
||||
// Using both alternately reduces the overall rounding error.
|
||||
Butterfly #(.WIDTH(WIDTH),.RH(1)) BF2 (
|
||||
.x0_re (bf2_x0_re ), // i
|
||||
.x0_im (bf2_x0_im ), // i
|
||||
.x1_re (bf2_x1_re ), // i
|
||||
.x1_im (bf2_x1_im ), // i
|
||||
.y0_re (bf2_y0_re ), // o
|
||||
.y0_im (bf2_y0_im ), // o
|
||||
.y1_re (bf2_y1_re ), // o
|
||||
.y1_im (bf2_y1_im ) // o
|
||||
);
|
||||
|
||||
DelayBuffer #(.DEPTH(2**(LOG_M-2)),.WIDTH(WIDTH)) DB2 (
|
||||
.clock (clock ), // i
|
||||
.di_re (db2_di_re ), // i
|
||||
.di_im (db2_di_im ), // i
|
||||
.do_re (db2_do_re ), // o
|
||||
.do_im (db2_do_im ) // o
|
||||
);
|
||||
|
||||
assign db2_di_re = bf2_bf ? bf2_y1_re : bf1_do_re;
|
||||
assign db2_di_im = bf2_bf ? bf2_y1_im : bf1_do_im;
|
||||
assign bf2_sp_re = bf2_bf ? bf2_y0_re : db2_do_re;
|
||||
assign bf2_sp_im = bf2_bf ? bf2_y0_im : db2_do_im;
|
||||
|
||||
always @(posedge clock or posedge reset) begin
|
||||
if (reset) begin
|
||||
bf2_sp_en <= 1'b0;
|
||||
bf2_count <= {LOG_N{1'b0}};
|
||||
end else begin
|
||||
bf2_sp_en <= bf2_start ? 1'b1 : bf2_end ? 1'b0 : bf2_sp_en;
|
||||
bf2_count <= bf2_sp_en ? (bf2_count + 1'b1) : {LOG_N{1'b0}};
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clock) begin
|
||||
bf2_start <= (bf1_count == (2**(LOG_M-2)-1)) & bf1_sp_en;
|
||||
end
|
||||
assign bf2_end = (bf2_count == (2**LOG_N-1));
|
||||
|
||||
always @(posedge clock) begin
|
||||
bf2_do_re <= bf2_sp_re;
|
||||
bf2_do_im <= bf2_sp_im;
|
||||
end
|
||||
|
||||
always @(posedge clock or posedge reset) begin
|
||||
if (reset) begin
|
||||
bf2_do_en <= 1'b0;
|
||||
end else begin
|
||||
bf2_do_en <= bf2_sp_en;
|
||||
end
|
||||
end
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Multiplication
|
||||
//----------------------------------------------------------------------
|
||||
assign tw_sel[1] = bf2_count[LOG_M-2];
|
||||
assign tw_sel[0] = bf2_count[LOG_M-1];
|
||||
assign tw_num = bf2_count << (LOG_N-LOG_M);
|
||||
assign tw_addr = tw_num * tw_sel;
|
||||
|
||||
Twiddle #(
|
||||
.WIDTH (WIDTH)
|
||||
) TW (
|
||||
.clock (clock ), // i
|
||||
.addr (tw_addr), // i
|
||||
.tw_re (tw_re ), // o
|
||||
.tw_im (tw_im ) // o
|
||||
);
|
||||
|
||||
// Multiplication is bypassed when twiddle address is 0.
|
||||
always @(posedge clock) begin
|
||||
mu_en <= (tw_addr != {LOG_N{1'b0}});
|
||||
end
|
||||
// Set unknown value x for verification
|
||||
assign mu_a_re = mu_en ? bf2_do_re : {WIDTH{1'bx}};
|
||||
assign mu_a_im = mu_en ? bf2_do_im : {WIDTH{1'bx}};
|
||||
|
||||
Multiply #(.WIDTH(WIDTH)) MU (
|
||||
.a_re (mu_a_re), // i
|
||||
.a_im (mu_a_im), // i
|
||||
.b_re (tw_re ), // i
|
||||
.b_im (tw_im ), // i
|
||||
.m_re (mu_m_re), // o
|
||||
.m_im (mu_m_im) // o
|
||||
);
|
||||
|
||||
always @(posedge clock) begin
|
||||
mu_do_re <= mu_en ? mu_m_re : bf2_do_re;
|
||||
mu_do_im <= mu_en ? mu_m_im : bf2_do_im;
|
||||
end
|
||||
|
||||
always @(posedge clock or posedge reset) begin
|
||||
if (reset) begin
|
||||
mu_do_en <= 1'b0;
|
||||
end else begin
|
||||
mu_do_en <= bf2_do_en;
|
||||
end
|
||||
end
|
||||
|
||||
// No multiplication required at final stage
|
||||
assign do_en = (LOG_M == 2) ? bf2_do_en : mu_do_en;
|
||||
assign do_re = (LOG_M == 2) ? bf2_do_re : mu_do_re;
|
||||
assign do_im = (LOG_M == 2) ? bf2_do_im : mu_do_im;
|
||||
|
||||
endmodule
|
||||
1065
rtl/ip/fft/Twiddle1024_32B.v
Normal file
399
rtl/ip/fft/axi_fft_wrapper.v
Normal file
@@ -0,0 +1,399 @@
|
||||
`define FFT_CSR_ADDR 16'hc000
|
||||
`define FFT_IN_RE_BASE 16'h8000
|
||||
`define FFT_IN_IM_BASE 16'h9000
|
||||
`define FFT_OUT_RE_BASE 16'ha000
|
||||
`define FFT_OUT_IM_BASE 16'hb000
|
||||
|
||||
|
||||
module fft_controller #(
|
||||
parameter FFT_LEN = 1024, // FFT处理长度
|
||||
parameter BRAM_RD_LATENCY = 1, // 适配 BRAM 的读延迟 (通常 Block RAM 开启输出寄存器为 1)
|
||||
parameter FFT_DATA_WIDTH = 16
|
||||
)(
|
||||
input aclk,
|
||||
input aresetn,
|
||||
|
||||
// AXI Lite / AXI4 Wrapper ports
|
||||
input [4 :0] s_awid,
|
||||
input [31:0] s_awaddr,
|
||||
input [7 :0] s_awlen,
|
||||
input [2 :0] s_awsize,
|
||||
input [1 :0] s_awburst,
|
||||
input s_awlock,
|
||||
input [3 :0] s_awcache,
|
||||
input [2 :0] s_awprot,
|
||||
input s_awvalid,
|
||||
output reg s_awready,
|
||||
input [4 :0] s_wid,
|
||||
input [31:0] s_wdata,
|
||||
input [3 :0] s_wstrb,
|
||||
input s_wlast,
|
||||
input s_wvalid,
|
||||
output reg s_wready,
|
||||
output [4 :0] s_bid,
|
||||
output [1 :0] s_bresp,
|
||||
output reg s_bvalid,
|
||||
input s_bready,
|
||||
|
||||
input [4 :0] s_arid,
|
||||
input [31:0] s_araddr,
|
||||
input [7 :0] s_arlen,
|
||||
input [2 :0] s_arsize,
|
||||
input [1 :0] s_arburst,
|
||||
input s_arlock,
|
||||
input [3 :0] s_arcache,
|
||||
input [2 :0] s_arprot,
|
||||
input s_arvalid,
|
||||
output reg s_arready,
|
||||
output [4 :0] s_rid,
|
||||
output reg [31:0] s_rdata,
|
||||
output [1 :0] s_rresp,
|
||||
output reg s_rlast,
|
||||
output reg s_rvalid,
|
||||
input s_rready,
|
||||
|
||||
output fft_finish
|
||||
);
|
||||
|
||||
// AXI Burst 内部寄存器
|
||||
reg [31:0] aw_addr_reg;
|
||||
reg [1 :0] aw_burst_reg;
|
||||
reg [4 :0] aw_id_reg;
|
||||
|
||||
reg [31:0] ar_addr_reg;
|
||||
reg [7 :0] ar_len_reg;
|
||||
reg [1 :0] ar_burst_reg;
|
||||
reg [4 :0] ar_id_reg;
|
||||
reg [7 :0] ar_cnt;
|
||||
|
||||
// 写通道状态机 (AW, W, B)
|
||||
localparam W_IDLE = 2'd0;
|
||||
localparam W_DATA = 2'd1;
|
||||
localparam W_RESP = 2'd2;
|
||||
reg [1:0] w_state;
|
||||
|
||||
always @(posedge aclk) begin
|
||||
if (~aresetn) begin
|
||||
w_state <= W_IDLE;
|
||||
s_awready <= 1'b1;
|
||||
s_wready <= 1'b0;
|
||||
s_bvalid <= 1'b0;
|
||||
aw_addr_reg <= 32'h0;
|
||||
aw_burst_reg <= 2'h0;
|
||||
aw_id_reg <= 5'h0;
|
||||
end else begin
|
||||
case (w_state)
|
||||
W_IDLE: begin
|
||||
s_awready <= 1'b1;
|
||||
if (s_awvalid && s_awready) begin
|
||||
s_awready <= 1'b0;
|
||||
s_wready <= 1'b1;
|
||||
aw_addr_reg <= s_awaddr;
|
||||
aw_burst_reg <= s_awburst;
|
||||
aw_id_reg <= s_awid;
|
||||
w_state <= W_DATA;
|
||||
end
|
||||
end
|
||||
W_DATA: begin
|
||||
// 接收到有效写数据
|
||||
if (s_wvalid && s_wready) begin
|
||||
// INCR 模式下地址递增
|
||||
if (aw_burst_reg == 2'b01) begin
|
||||
aw_addr_reg <= aw_addr_reg + 4;
|
||||
end
|
||||
// 若是最后一拍,跳转到发送响应
|
||||
if (s_wlast) begin
|
||||
s_wready <= 1'b0;
|
||||
s_bvalid <= 1'b1;
|
||||
w_state <= W_RESP;
|
||||
end
|
||||
end
|
||||
end
|
||||
W_RESP: begin
|
||||
if (s_bvalid && s_bready) begin
|
||||
s_bvalid <= 1'b0;
|
||||
s_awready <= 1'b1; // 准备接收下一次写请求
|
||||
w_state <= W_IDLE;
|
||||
end
|
||||
end
|
||||
default: w_state <= W_IDLE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// 产生有效的写动作脉冲,用于触发 BRAM 写使能
|
||||
wire w_active = (w_state == W_DATA) && s_wvalid && s_wready;
|
||||
assign s_bid = aw_id_reg;
|
||||
assign s_bresp = 2'b00;
|
||||
|
||||
// 读通道状态机(AR, R)
|
||||
localparam R_IDLE = 2'd0;
|
||||
localparam R_WAIT = 2'd1;
|
||||
localparam R_DATA = 2'd2;
|
||||
reg [1:0] r_state;
|
||||
reg [3:0] r_wait_cnt;
|
||||
|
||||
always @(posedge aclk) begin
|
||||
if (~aresetn) begin
|
||||
r_state <= R_IDLE;
|
||||
s_arready <= 1'b1;
|
||||
s_rvalid <= 1'b0;
|
||||
s_rlast <= 1'b0;
|
||||
ar_addr_reg <= 32'h0;
|
||||
ar_len_reg <= 8'h0;
|
||||
ar_burst_reg <= 2'h0;
|
||||
ar_id_reg <= 5'h0;
|
||||
ar_cnt <= 8'h0;
|
||||
r_wait_cnt <= 4'h0;
|
||||
end else begin
|
||||
case (r_state)
|
||||
R_IDLE: begin
|
||||
s_arready <= 1'b1;
|
||||
if (s_arvalid && s_arready) begin
|
||||
s_arready <= 1'b0;
|
||||
ar_addr_reg <= s_araddr;
|
||||
ar_len_reg <= s_arlen;
|
||||
ar_burst_reg <= s_arburst;
|
||||
ar_id_reg <= s_arid;
|
||||
ar_cnt <= 8'h0;
|
||||
r_wait_cnt <= BRAM_RD_LATENCY;
|
||||
r_state <= R_WAIT; // 进入等待以拉取第一笔 BRAM 数据
|
||||
end
|
||||
end
|
||||
R_WAIT: begin
|
||||
// 等待 BRAM 固定潜伏期结束
|
||||
if (r_wait_cnt <= 1) begin
|
||||
s_rvalid <= 1'b1;
|
||||
s_rlast <= (ar_cnt == ar_len_reg);
|
||||
r_state <= R_DATA;
|
||||
r_wait_cnt <= 4'h0;
|
||||
end else begin
|
||||
r_wait_cnt <= r_wait_cnt - 1;
|
||||
end
|
||||
end
|
||||
R_DATA: begin
|
||||
// 数据被总线成功读取
|
||||
if (s_rvalid && s_rready) begin
|
||||
if (ar_cnt == ar_len_reg) begin
|
||||
// Burst 结束
|
||||
s_rvalid <= 1'b0;
|
||||
s_rlast <= 1'b0;
|
||||
s_arready <= 1'b1;
|
||||
r_state <= R_IDLE;
|
||||
end else begin
|
||||
// 准备读取下一拍数据
|
||||
ar_cnt <= ar_cnt + 1;
|
||||
// INCR 模式下地址递增
|
||||
if (ar_burst_reg == 2'b01) begin
|
||||
ar_addr_reg <= ar_addr_reg + 4;
|
||||
end
|
||||
s_rvalid <= 1'b0;
|
||||
s_rlast <= 1'b0;
|
||||
r_wait_cnt <= BRAM_RD_LATENCY;
|
||||
r_state <= R_WAIT; // 再次进入等待状态
|
||||
end
|
||||
end
|
||||
end
|
||||
default: r_state <= R_IDLE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign s_rid = ar_id_reg;
|
||||
assign s_rresp = 2'b00;
|
||||
|
||||
// 地址译码
|
||||
wire hit_in_re = (aw_addr_reg[15:12] == 4'h8);
|
||||
wire hit_in_im = (aw_addr_reg[15:12] == 4'h9);
|
||||
wire hit_out_re = (ar_addr_reg[15:12] == 4'ha);
|
||||
wire hit_out_im = (ar_addr_reg[15:12] == 4'hb);
|
||||
|
||||
// 寄存器控制
|
||||
reg [3:0] fft_ctrl;
|
||||
reg [3:0] fft_status;
|
||||
|
||||
wire [31:0] fft_csr = {24'h0, fft_ctrl, fft_status};
|
||||
// 只有发生有效的写握手且地址对应 CSR 时,才写入控制寄存器
|
||||
wire write_fft_csr = w_active && (aw_addr_reg[15:0] == `FFT_CSR_ADDR);
|
||||
|
||||
// 状态机
|
||||
localparam IDLE = 2'd0;
|
||||
localparam LOAD = 2'd1;
|
||||
localparam WAIT_OUT = 2'd2;
|
||||
localparam DONE = 2'd3;
|
||||
|
||||
reg [1:0] state, next_state;
|
||||
reg [10:0] in_cnt;
|
||||
reg [10:0] out_cnt;
|
||||
|
||||
wire do_en;
|
||||
wire [FFT_DATA_WIDTH-1:0] do_re;
|
||||
wire [FFT_DATA_WIDTH-1:0] do_im;
|
||||
|
||||
always @(posedge aclk) begin
|
||||
if (~aresetn) state <= IDLE;
|
||||
else state <= next_state;
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
case (state)
|
||||
IDLE: if (fft_ctrl[0]) next_state = LOAD; else next_state = IDLE;
|
||||
LOAD: if (in_cnt == FFT_LEN - 1) next_state = WAIT_OUT; else next_state = LOAD;
|
||||
WAIT_OUT: if (do_en && out_cnt == FFT_LEN - 1) next_state = DONE; else next_state = WAIT_OUT;
|
||||
DONE: next_state = IDLE;
|
||||
default: next_state = IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge aclk) begin
|
||||
if (~aresetn) begin
|
||||
in_cnt <= 0;
|
||||
out_cnt <= 0;
|
||||
end else if (state == IDLE) begin
|
||||
in_cnt <= 0;
|
||||
out_cnt <= 0;
|
||||
end else begin
|
||||
if (state == LOAD) in_cnt <= in_cnt + 1;
|
||||
if (do_en) out_cnt <= out_cnt + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// 更新寄存器与状态
|
||||
always @(posedge aclk) begin
|
||||
if (~aresetn) begin
|
||||
fft_ctrl <= 4'h0;
|
||||
fft_status <= 4'h0;
|
||||
end else begin
|
||||
if (write_fft_csr) begin
|
||||
fft_ctrl <= s_wdata[7:4];
|
||||
end else if (state != IDLE) begin
|
||||
fft_ctrl[0] <= 1'b0;
|
||||
end
|
||||
|
||||
fft_status[0] <= (state != IDLE && state != DONE);
|
||||
|
||||
if (write_fft_csr && s_wdata[4]) begin
|
||||
fft_status[1] <= 1'b0;
|
||||
end else if (state == DONE) begin
|
||||
fft_status[1] <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign fft_finish = fft_status[1];
|
||||
|
||||
// BRAM 接口连线
|
||||
wire [FFT_DATA_WIDTH-1:0] in_re_dout;
|
||||
wire [FFT_DATA_WIDTH-1:0] in_im_dout;
|
||||
wire [FFT_DATA_WIDTH-1:0] out_re_dout;
|
||||
wire [FFT_DATA_WIDTH-1:0] out_im_dout;
|
||||
wire [31:0] out_re_sx = {{(32-FFT_DATA_WIDTH){out_re_dout[FFT_DATA_WIDTH-1]}}, out_re_dout};
|
||||
wire [31:0] out_im_sx = {{(32-FFT_DATA_WIDTH){out_im_dout[FFT_DATA_WIDTH-1]}}, out_im_dout};
|
||||
|
||||
my_bram0 #(
|
||||
.DATA_WIDTH (FFT_DATA_WIDTH),
|
||||
.ADDR_WIDTH (10)
|
||||
) u_in0(
|
||||
.clka (aclk),
|
||||
.ena (w_active && hit_in_re), // 由 burst写逻辑产生
|
||||
.wea (1'b1),
|
||||
.addra (aw_addr_reg[11:2]), // 取当前递增的突发写地址
|
||||
.dina (s_wdata[FFT_DATA_WIDTH-1:0]),
|
||||
|
||||
.clkb (aclk),
|
||||
.enb (state == LOAD),
|
||||
.addrb (in_cnt[9:0]),
|
||||
.doutb (in_re_dout)
|
||||
);
|
||||
|
||||
my_bram0 #(
|
||||
.DATA_WIDTH (FFT_DATA_WIDTH),
|
||||
.ADDR_WIDTH (10)
|
||||
) u_in1(
|
||||
.clka (aclk),
|
||||
.ena (w_active && hit_in_im),
|
||||
.wea (1'b1),
|
||||
.addra (aw_addr_reg[11:2]),
|
||||
.dina (s_wdata[FFT_DATA_WIDTH-1:0]),
|
||||
|
||||
.clkb (aclk),
|
||||
.enb (state == LOAD),
|
||||
.addrb (in_cnt[9:0]),
|
||||
.doutb (in_im_dout)
|
||||
);
|
||||
|
||||
// 对于输出 BRAM,采用原先的位反转(Bit-reverse)读取逻辑
|
||||
wire [9:0] b_rd_addr = ar_addr_reg[11:2];
|
||||
wire [9:0] bit_reversed_index = {
|
||||
b_rd_addr[0], b_rd_addr[1], b_rd_addr[2], b_rd_addr[3], b_rd_addr[4],
|
||||
b_rd_addr[5], b_rd_addr[6], b_rd_addr[7], b_rd_addr[8], b_rd_addr[9]
|
||||
};
|
||||
|
||||
my_bram0 #(
|
||||
.DATA_WIDTH (FFT_DATA_WIDTH),
|
||||
.ADDR_WIDTH (10)
|
||||
) u_out0(
|
||||
.clka (aclk),
|
||||
.ena (do_en),
|
||||
.wea (1'b1),
|
||||
.addra (out_cnt[9:0]),
|
||||
.dina (do_re),
|
||||
|
||||
.clkb (aclk),
|
||||
.enb (r_state != R_IDLE), // 当处于读突发事务时始终使能 BRAM
|
||||
.addrb (bit_reversed_index),
|
||||
.doutb (out_re_dout)
|
||||
);
|
||||
|
||||
my_bram0 #(
|
||||
.DATA_WIDTH (FFT_DATA_WIDTH),
|
||||
.ADDR_WIDTH (10)
|
||||
) u_out1(
|
||||
.clka (aclk),
|
||||
.ena (do_en),
|
||||
.wea (1'b1),
|
||||
.addra (out_cnt[9:0]),
|
||||
.dina (do_im),
|
||||
|
||||
.clkb (aclk),
|
||||
.enb (r_state != R_IDLE),
|
||||
.addrb (bit_reversed_index),
|
||||
.doutb (out_im_dout)
|
||||
);
|
||||
|
||||
// 支持 1 到 N 拍的读延迟,让 di_en 严格对齐 BRAM 的吐出数据
|
||||
reg [3:0] di_en_shift;
|
||||
always @(posedge aclk) begin
|
||||
if (~aresetn) di_en_shift <= 0;
|
||||
else di_en_shift <= {di_en_shift[2:0], (state == LOAD)};
|
||||
end
|
||||
|
||||
wire di_en_r = (BRAM_RD_LATENCY == 1) ? di_en_shift[0] :
|
||||
(BRAM_RD_LATENCY == 2) ? di_en_shift[1] :
|
||||
(BRAM_RD_LATENCY == 3) ? di_en_shift[2] : di_en_shift[3];
|
||||
|
||||
FFT #(
|
||||
.WIDTH(FFT_DATA_WIDTH)
|
||||
) u_FFT (
|
||||
.clock (aclk),
|
||||
.reset (~aresetn),
|
||||
.di_en (di_en_r),
|
||||
.di_re (in_re_dout),
|
||||
.di_im (in_im_dout),
|
||||
.do_en (do_en),
|
||||
.do_re (do_re),
|
||||
.do_im (do_im)
|
||||
);
|
||||
|
||||
// 读取返回数据选择
|
||||
wire [31:0] rdata_d =
|
||||
(ar_addr_reg[15:0] == `FFT_CSR_ADDR) ? fft_csr :
|
||||
hit_out_re ? out_re_sx :
|
||||
hit_out_im ? out_im_sx :
|
||||
32'h0;
|
||||
|
||||
always @(*) begin
|
||||
s_rdata = rdata_d;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -2,6 +2,7 @@
|
||||
// 3-stage pipelined multiplier (LUT-based, no DSP)
|
||||
// latency=3, throughput=1 result/cycle
|
||||
// ═══════════════════════════════════════════════════════
|
||||
|
||||
(* use_dsp = "no" *)
|
||||
module pipelined_mult_32x32 (
|
||||
input clk,
|
||||
@@ -80,6 +81,28 @@ module matmul_axi_slave (
|
||||
output reg s_axi_rvalid,
|
||||
input s_axi_rready,
|
||||
|
||||
// CDMA local endpoint port
|
||||
input ep_wr_valid,
|
||||
input [3:0] ep_wr_id,
|
||||
input [3:0] ep_wr_bank,
|
||||
input [7:0] ep_wr_word_addr,
|
||||
input [31:0] ep_wr_data,
|
||||
output ep_wr_ready,
|
||||
|
||||
input ep_rd_valid,
|
||||
input [3:0] ep_rd_id,
|
||||
input [3:0] ep_rd_bank,
|
||||
input [7:0] ep_rd_word_addr,
|
||||
output reg [31:0] ep_rd_data,
|
||||
output ep_rd_ready,
|
||||
|
||||
// Direct control from the CDMA/matmul bridge
|
||||
input mat_start_valid,
|
||||
input mat_start_bank,
|
||||
input mat_done_clear,
|
||||
input mat_crc_clear,
|
||||
output mat_done,
|
||||
|
||||
// Interrupt output (active high level, pulsed by calc_done)
|
||||
output intr
|
||||
);
|
||||
@@ -115,6 +138,33 @@ module matmul_axi_slave (
|
||||
reg [31:0] b1_b [0:15];
|
||||
reg [65:0] b1_c [0:15];
|
||||
|
||||
assign ep_wr_ready = 1'b1;
|
||||
assign ep_rd_ready = 1'b1;
|
||||
assign mat_done = done;
|
||||
|
||||
wire [3:0] ep_wr_idx = ep_wr_word_addr[3:0];
|
||||
wire [7:0] ep_rd_elem_raw = ep_rd_word_addr / 8'd3;
|
||||
wire [7:0] ep_rd_part_raw = ep_rd_word_addr % 8'd3;
|
||||
wire [3:0] ep_rd_elem = ep_rd_elem_raw[3:0];
|
||||
wire [1:0] ep_rd_part = ep_rd_part_raw[1:0];
|
||||
wire [65:0] ep_rd_c0 = b0_c[ep_rd_elem];
|
||||
wire [65:0] ep_rd_c1 = b1_c[ep_rd_elem];
|
||||
|
||||
always @(*) begin
|
||||
ep_rd_data = 32'b0;
|
||||
if (ep_rd_word_addr < 8'd48) begin
|
||||
if (ep_rd_bank[0] == 1'b0) begin
|
||||
if (ep_rd_part == 2'd0) ep_rd_data = ep_rd_c0[31:0];
|
||||
else if (ep_rd_part == 2'd1) ep_rd_data = ep_rd_c0[63:32];
|
||||
else ep_rd_data = {30'b0, ep_rd_c0[65:64]};
|
||||
end else begin
|
||||
if (ep_rd_part == 2'd0) ep_rd_data = ep_rd_c1[31:0];
|
||||
else if (ep_rd_part == 2'd1) ep_rd_data = ep_rd_c1[63:32];
|
||||
else ep_rd_data = {30'b0, ep_rd_c1[65:64]};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function [31:0] apply_wstrb;
|
||||
input [31:0] old_value;
|
||||
input [31:0] new_value;
|
||||
@@ -134,20 +184,21 @@ module matmul_axi_slave (
|
||||
reg [31:0] crc32_table [0:255];
|
||||
reg [31:0] crc_reg;
|
||||
|
||||
wire [31:0] crc_stream_data = s_axi_rdata;
|
||||
wire crc_stream_valid = (r_state == R_DATA) && s_axi_rvalid && s_axi_rready &&
|
||||
((r_offset >= ADDR_B0_C && r_offset < (ADDR_B0_C + 12'h0C0)) ||
|
||||
(r_offset >= ADDR_B1_C && r_offset < (ADDR_B1_C + 12'h0C0)));
|
||||
|
||||
wire [31:0] crc_t0, crc_c0, crc_t1, crc_c1, crc_t2, crc_c2, crc_t3, crc_next;
|
||||
assign crc_t0 = crc32_table[(crc_reg[7:0] ^ crc_stream_data[7:0])];
|
||||
assign crc_c0 = crc_t0 ^ {8'h00, crc_reg[31:8]};
|
||||
assign crc_t1 = crc32_table[(crc_c0[7:0] ^ crc_stream_data[15:8])];
|
||||
assign crc_c1 = crc_t1 ^ {8'h00, crc_c0[31:8]};
|
||||
assign crc_t2 = crc32_table[(crc_c1[7:0] ^ crc_stream_data[23:16])];
|
||||
assign crc_c2 = crc_t2 ^ {8'h00, crc_c1[31:8]};
|
||||
assign crc_t3 = crc32_table[(crc_c2[7:0] ^ crc_stream_data[31:24])];
|
||||
assign crc_next = crc_t3 ^ {8'h00, crc_c2[31:8]};
|
||||
function [31:0] crc32_word_next;
|
||||
input [31:0] crc_in;
|
||||
input [31:0] data_in;
|
||||
reg [31:0] t0, c0, t1, c1, t2, c2, t3;
|
||||
begin
|
||||
t0 = crc32_table[(crc_in[7:0] ^ data_in[7:0])];
|
||||
c0 = t0 ^ {8'h00, crc_in[31:8]};
|
||||
t1 = crc32_table[(c0[7:0] ^ data_in[15:8])];
|
||||
c1 = t1 ^ {8'h00, c0[31:8]};
|
||||
t2 = crc32_table[(c1[7:0] ^ data_in[23:16])];
|
||||
c2 = t2 ^ {8'h00, c1[31:8]};
|
||||
t3 = crc32_table[(c2[7:0] ^ data_in[31:24])];
|
||||
crc32_word_next = t3 ^ {8'h00, c2[31:8]};
|
||||
end
|
||||
endfunction
|
||||
|
||||
initial begin
|
||||
crc32_table[0 ] = 32'h00000000; crc32_table[1 ] = 32'h77073096;
|
||||
@@ -305,7 +356,8 @@ module matmul_axi_slave (
|
||||
reg calc_done_pulse;
|
||||
|
||||
// 【修改点 1】单独引出一个写脉冲信号给 CRC 清零用
|
||||
wire crc_clear_pulse = (w_state == W_DATA) && s_axi_wvalid && s_axi_wready && (w_offset == ADDR_CRC);
|
||||
wire crc_clear_pulse = ((w_state == W_DATA) && s_axi_wvalid && s_axi_wready && (w_offset == ADDR_CRC)) ||
|
||||
mat_crc_clear;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
@@ -321,10 +373,34 @@ module matmul_axi_slave (
|
||||
if (req_0 && state == C_RUN && cur_bank == 1'b0) req_0 <= 1'b0;
|
||||
if (req_1 && state == C_RUN && cur_bank == 1'b1) req_1 <= 1'b0;
|
||||
|
||||
if (mat_start_valid) begin
|
||||
if (mat_start_bank) req_1 <= 1'b1;
|
||||
else req_0 <= 1'b1;
|
||||
end
|
||||
|
||||
if (calc_done_pulse) begin
|
||||
done <= 1'b1;
|
||||
end
|
||||
|
||||
if (mat_done_clear) begin
|
||||
done <= 1'b0;
|
||||
error <= 1'b0;
|
||||
end
|
||||
|
||||
if (ep_wr_valid && ep_wr_ready) begin
|
||||
if (ep_wr_word_addr < 8'd16) begin
|
||||
if (ep_wr_bank[0] == 1'b0)
|
||||
b0_a[ep_wr_idx] <= ep_wr_data;
|
||||
else
|
||||
b1_a[ep_wr_idx] <= ep_wr_data;
|
||||
end else if (ep_wr_word_addr < 8'd32) begin
|
||||
if (ep_wr_bank[0] == 1'b0)
|
||||
b0_b[ep_wr_idx] <= ep_wr_data;
|
||||
else
|
||||
b1_b[ep_wr_idx] <= ep_wr_data;
|
||||
end
|
||||
end
|
||||
|
||||
case (w_state)
|
||||
W_IDLE: begin
|
||||
s_axi_awready <= 1'b1;
|
||||
@@ -434,7 +510,7 @@ module matmul_axi_slave (
|
||||
end
|
||||
R_DATA: begin
|
||||
if (s_axi_rvalid && s_axi_rready) begin
|
||||
// 【修改点 3】删掉直接赋值 crc_stream_valid 的逻辑,移至专用 Pipeline 块
|
||||
// CRC is updated from completed compute results, not from C reads.
|
||||
if (r_cnt == r_len) begin
|
||||
s_axi_rvalid <= 1'b0;
|
||||
s_axi_rlast <= 1'b0;
|
||||
@@ -484,17 +560,6 @@ module matmul_axi_slave (
|
||||
end
|
||||
end
|
||||
|
||||
// CRC register: update on each C data read beat, clear on write to 0x010
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
crc_reg <= 32'hFFFFFFFF;
|
||||
end else if (crc_clear_pulse) begin
|
||||
crc_reg <= 32'hFFFFFFFF;
|
||||
end else if (crc_stream_valid) begin
|
||||
crc_reg <= crc_next;
|
||||
end
|
||||
end
|
||||
|
||||
// ==========================================
|
||||
// 计算引擎 (Compute FSM)
|
||||
// ==========================================
|
||||
@@ -518,7 +583,49 @@ module matmul_axi_slave (
|
||||
// Pipeline delay shift registers for accumulation (4 stages = 3 multiplier pipe + 1)
|
||||
reg [3:0] acc_idx_d1, acc_idx_d2, acc_idx_d3, acc_idx_d4;
|
||||
reg acc_bank_d1, acc_bank_d2, acc_bank_d3, acc_bank_d4;
|
||||
reg acc_valid_d1, acc_valid_d2, acc_valid_d3, acc_valid_d4;
|
||||
reg [4:0] pipe_cnt;
|
||||
wire [65:0] calc_c_result = ({2'b0, mult_p[0]} + {2'b0, mult_p[1]}) +
|
||||
({2'b0, mult_p[2]} + {2'b0, mult_p[3]});
|
||||
wire calc_crc_valid = acc_valid_d4;
|
||||
wire [31:0] crc_calc_0 = crc32_word_next(crc_reg, calc_c_result[31:0]);
|
||||
wire [31:0] crc_calc_1 = crc32_word_next(crc_calc_0, calc_c_result[63:32]);
|
||||
wire [31:0] crc_calc_2 = crc32_word_next(crc_calc_1, {30'b0, calc_c_result[65:64]});
|
||||
|
||||
task start_calc_bank;
|
||||
input bank;
|
||||
begin
|
||||
cur_bank <= bank;
|
||||
busy <= 1'b1;
|
||||
state <= C_RUN;
|
||||
pipe_cnt <= 5'd1;
|
||||
acc_idx_d1 <= 4'd0;
|
||||
acc_bank_d1 <= bank;
|
||||
acc_valid_d1 <= 1'b1;
|
||||
if (bank == 1'b0) begin
|
||||
m_in_a[0] <= b0_a[4'd0]; m_in_b[0] <= b0_b[4'd0];
|
||||
m_in_a[1] <= b0_a[4'd1]; m_in_b[1] <= b0_b[4'd4];
|
||||
m_in_a[2] <= b0_a[4'd2]; m_in_b[2] <= b0_b[4'd8];
|
||||
m_in_a[3] <= b0_a[4'd3]; m_in_b[3] <= b0_b[4'd12];
|
||||
end else begin
|
||||
m_in_a[0] <= b1_a[4'd0]; m_in_b[0] <= b1_b[4'd0];
|
||||
m_in_a[1] <= b1_a[4'd1]; m_in_b[1] <= b1_b[4'd4];
|
||||
m_in_a[2] <= b1_a[4'd2]; m_in_b[2] <= b1_b[4'd8];
|
||||
m_in_a[3] <= b1_a[4'd3]; m_in_b[3] <= b1_b[4'd12];
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
// CRC tracks completed C elements directly, independent of result writeback.
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
crc_reg <= 32'hFFFFFFFF;
|
||||
end else if (crc_clear_pulse) begin
|
||||
crc_reg <= 32'hFFFFFFFF;
|
||||
end else if (calc_crc_valid) begin
|
||||
crc_reg <= crc_calc_2;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
@@ -535,6 +642,10 @@ module matmul_axi_slave (
|
||||
acc_bank_d2 <= 1'b0;
|
||||
acc_bank_d3 <= 1'b0;
|
||||
acc_bank_d4 <= 1'b0;
|
||||
acc_valid_d1 <= 1'b0;
|
||||
acc_valid_d2 <= 1'b0;
|
||||
acc_valid_d3 <= 1'b0;
|
||||
acc_valid_d4 <= 1'b0;
|
||||
end else begin
|
||||
calc_done_pulse <= 1'b0;
|
||||
|
||||
@@ -542,24 +653,24 @@ module matmul_axi_slave (
|
||||
acc_idx_d4 <= acc_idx_d3;
|
||||
acc_idx_d3 <= acc_idx_d2;
|
||||
acc_idx_d2 <= acc_idx_d1;
|
||||
acc_idx_d1 <= pipe_cnt[3:0];
|
||||
acc_idx_d1 <= 4'd0;
|
||||
acc_bank_d4 <= acc_bank_d3;
|
||||
acc_bank_d3 <= acc_bank_d2;
|
||||
acc_bank_d2 <= acc_bank_d1;
|
||||
acc_bank_d1 <= cur_bank;
|
||||
acc_bank_d1 <= 1'b0;
|
||||
acc_valid_d4 <= acc_valid_d3;
|
||||
acc_valid_d3 <= acc_valid_d2;
|
||||
acc_valid_d2 <= acc_valid_d1;
|
||||
acc_valid_d1 <= 1'b0;
|
||||
|
||||
case (state)
|
||||
C_IDLE: begin
|
||||
pipe_cnt <= 5'd0;
|
||||
if (req_0) begin
|
||||
cur_bank <= 1'b0;
|
||||
busy <= 1'b1;
|
||||
state <= C_RUN;
|
||||
start_calc_bank(1'b0);
|
||||
end else if (req_1) begin
|
||||
cur_bank <= 1'b1;
|
||||
busy <= 1'b1;
|
||||
state <= C_RUN;
|
||||
start_calc_bank(1'b1);
|
||||
end else begin
|
||||
pipe_cnt <= 5'd0;
|
||||
busy <= 1'b0;
|
||||
end
|
||||
end
|
||||
@@ -567,6 +678,9 @@ module matmul_axi_slave (
|
||||
C_RUN: begin
|
||||
// Issue 4 new operands every cycle (pipe_cnt 0-15, 16 rounds)
|
||||
if (pipe_cnt < 5'd16) begin
|
||||
acc_idx_d1 <= pipe_cnt[3:0];
|
||||
acc_bank_d1 <= cur_bank;
|
||||
acc_valid_d1 <= 1'b1;
|
||||
if (cur_bank == 1'b0) begin
|
||||
m_in_a[0] <= b0_a[{pipe_cnt[3:2], 2'd0}]; m_in_b[0] <= b0_b[{2'd0, pipe_cnt[1:0]}];
|
||||
m_in_a[1] <= b0_a[{pipe_cnt[3:2], 2'd1}]; m_in_b[1] <= b0_b[{2'd1, pipe_cnt[1:0]}];
|
||||
@@ -580,18 +694,25 @@ module matmul_axi_slave (
|
||||
end
|
||||
end
|
||||
|
||||
// Accumulate results from 4 cycles ago (pipe_cnt 4-19)
|
||||
if (pipe_cnt >= 5'd4 && pipe_cnt < 5'd20) begin
|
||||
// Accumulate results from 4 cycles ago.
|
||||
if (acc_valid_d4) begin
|
||||
if (acc_bank_d4 == 1'b0)
|
||||
b0_c[acc_idx_d4] <= ({2'b0, mult_p[0]} + {2'b0, mult_p[1]}) +
|
||||
({2'b0, mult_p[2]} + {2'b0, mult_p[3]});
|
||||
b0_c[acc_idx_d4] <= calc_c_result;
|
||||
else
|
||||
b1_c[acc_idx_d4] <= ({2'b0, mult_p[0]} + {2'b0, mult_p[1]}) +
|
||||
({2'b0, mult_p[2]} + {2'b0, mult_p[3]});
|
||||
b1_c[acc_idx_d4] <= calc_c_result;
|
||||
end
|
||||
|
||||
if (pipe_cnt == 5'd20) begin
|
||||
if (acc_valid_d4 && acc_idx_d4 == 4'd15) begin
|
||||
calc_done_pulse <= 1'b1;
|
||||
end
|
||||
|
||||
if (pipe_cnt < 5'd16) begin
|
||||
pipe_cnt <= pipe_cnt + 5'd1;
|
||||
end else if (cur_bank == 1'b0 && req_1) begin
|
||||
start_calc_bank(1'b1);
|
||||
end else if (cur_bank == 1'b1 && req_0) begin
|
||||
start_calc_bank(1'b0);
|
||||
end else if (acc_valid_d4 && acc_idx_d4 == 4'd15) begin
|
||||
busy <= 1'b0;
|
||||
state <= C_IDLE;
|
||||
end else begin
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// comp_decomp_sync.v - ML-KEM coefficient compression/decompression
|
||||
//
|
||||
// Streaming: one coefficient per cycle through pipeline_reg.
|
||||
// Streaming valid/ready interface. The arithmetic is fixed-latency pipelined
|
||||
// so compression does not infer a long combinational divider/reducer.
|
||||
// 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).
|
||||
// Integer arithmetic:
|
||||
// compress: (x * 2^d + Q/2) / Q, lower d bits as result
|
||||
@@ -24,52 +25,175 @@ module comp_decomp_sync (
|
||||
input ready_i
|
||||
);
|
||||
|
||||
// 2^d for d in {4,5,10,11}; fits in 12 bits (max 2048)
|
||||
wire [11:0] two_pow_d;
|
||||
assign two_pow_d = 12'd1 << d;
|
||||
localparam [24:0] Q25 = 25'd`Q;
|
||||
localparam [12:0] K13 = 13'd5039; // floor(2^24 / 3329)
|
||||
|
||||
// Product: 12-bit * 12-bit = max 2048*3328 = 6,815,744 → 23 bits (use 24)
|
||||
wire [23:0] product;
|
||||
reg [11:0] data_r;
|
||||
reg valid_r;
|
||||
|
||||
// compress: x * 2^d; decompress: x * Q
|
||||
assign product = mode ? {12'b0, coeff_in} * {12'b0, 12'd3329}
|
||||
: {12'b0, coeff_in} * {12'b0, two_pow_d};
|
||||
reg mode_s0;
|
||||
reg [4:0] d_s0;
|
||||
reg [11:0] coeff_s0;
|
||||
reg valid_s0;
|
||||
|
||||
// Rounding offset: compress→Q/2=1664; decompress→2^(d-1)
|
||||
wire [11:0] round_off;
|
||||
assign round_off = mode ? (two_pow_d >> 1) : 12'd1664;
|
||||
reg mode_s1;
|
||||
reg [4:0] d_s1;
|
||||
reg [23:0] comp_dividend_s1;
|
||||
reg [23:0] decomp_rounded_s1;
|
||||
reg valid_s1;
|
||||
|
||||
// Dividend = product + round_off (max ~ 6,817,408 fits in 24 bits)
|
||||
wire [23:0] dividend;
|
||||
assign dividend = product + {12'b0, round_off};
|
||||
reg mode_s2;
|
||||
reg [4:0] d_s2;
|
||||
reg [23:0] comp_dividend_s2;
|
||||
(* use_dsp = "no" *) reg [36:0] comp_qprod_est_s2;
|
||||
reg [23:0] decomp_rounded_s2;
|
||||
reg valid_s2;
|
||||
|
||||
// Divisor: compress→Q=3329; decompress→2^d
|
||||
wire [11:0] divisor;
|
||||
assign divisor = mode ? two_pow_d : 12'd3329;
|
||||
reg mode_s3;
|
||||
reg [4:0] d_s3;
|
||||
reg [23:0] comp_dividend_s3;
|
||||
reg [12:0] comp_q_est_s3;
|
||||
reg [11:0] decomp_result_s3;
|
||||
reg valid_s3;
|
||||
|
||||
// Integer division (both ops positive → floor)
|
||||
// Quotient is computed as 24b (widest operand) but fits in 12b
|
||||
/* verilator lint_off WIDTH */
|
||||
wire [11:0] div_result;
|
||||
assign div_result = dividend / {12'b0, divisor};
|
||||
/* verilator lint_on WIDTH */
|
||||
reg mode_s4;
|
||||
reg [4:0] d_s4;
|
||||
reg [23:0] comp_dividend_s4;
|
||||
reg [12:0] comp_q_est_s4;
|
||||
(* use_dsp = "no" *) reg [24:0] comp_q_mul_q_s4;
|
||||
reg [11:0] decomp_result_s4;
|
||||
reg valid_s4;
|
||||
|
||||
// Final modular reduction
|
||||
// compress: lower d bits (mask with 2^d - 1)
|
||||
// decompress: result < Q always, but apply mod Q for safety
|
||||
wire [11:0] mod_result;
|
||||
assign mod_result = mode ? (div_result % 12'd3329) : (div_result & (two_pow_d - 1'b1));
|
||||
reg mode_s5;
|
||||
reg [4:0] d_s5;
|
||||
reg [12:0] comp_q_est_s5;
|
||||
reg [24:0] comp_rem_s5;
|
||||
reg [11:0] decomp_result_s5;
|
||||
reg valid_s5;
|
||||
|
||||
// Pipeline through valid/ready stage
|
||||
pipeline_reg #(.DW(12)) u_pipe (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
.data_i (mod_result),
|
||||
.valid_i(valid_i),
|
||||
.ready_o(ready_o),
|
||||
.data_o (coeff_out),
|
||||
.valid_o(valid_o),
|
||||
.ready_i(ready_i)
|
||||
);
|
||||
wire fire_i = valid_i && ready_o;
|
||||
|
||||
wire pipe_busy = valid_s0 | valid_s1 | valid_s2 | valid_s3 | valid_s4 | valid_s5;
|
||||
|
||||
// Fully pipelined: accept one coefficient per cycle. Every stage advances
|
||||
// unconditionally (valid_sN <= valid_s(N-1)), and the sole consumer ties
|
||||
// ready_i high, so the output register never needs to backpressure the
|
||||
// pipeline. Streaming feeders (Encaps C1/C2, Decaps DECOMP) can therefore
|
||||
// issue a new coeff every cycle instead of draining the 6-stage pipe each
|
||||
// time. pipe_busy retained only for the legacy drain-based users' info.
|
||||
assign ready_o = 1'b1;
|
||||
assign coeff_out = data_r;
|
||||
assign valid_o = valid_r;
|
||||
|
||||
wire [23:0] coeff_ext_s0 = {12'd0, coeff_s0};
|
||||
wire [23:0] comp_dividend_next = (coeff_ext_s0 << d_s0) + 24'd1664;
|
||||
(* use_dsp = "no" *) wire [23:0] decomp_product_next = coeff_s0 * 12'd`Q;
|
||||
wire [23:0] decomp_round_next =
|
||||
decomp_product_next + ((d_s0 == 5'd0) ? 24'd0 : (24'd1 << (d_s0 - 5'd1)));
|
||||
|
||||
wire [12:0] comp_q_corr1_s5 =
|
||||
comp_q_est_s5 + ((comp_rem_s5 >= Q25) ? 13'd1 : 13'd0);
|
||||
wire [24:0] comp_rem_corr1_s5 =
|
||||
(comp_rem_s5 >= Q25) ? (comp_rem_s5 - Q25) : comp_rem_s5;
|
||||
wire [12:0] comp_q_corr2_s5 =
|
||||
comp_q_corr1_s5 + ((comp_rem_corr1_s5 >= Q25) ? 13'd1 : 13'd0);
|
||||
wire [11:0] comp_mask_s5 =
|
||||
(d_s5 == 5'd0) ? 12'd0 : (12'd1 << d_s5) - 12'd1;
|
||||
wire [11:0] comp_result_s5 = comp_q_corr2_s5[11:0] & comp_mask_s5;
|
||||
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
data_r <= 12'd0;
|
||||
valid_r <= 1'b0;
|
||||
|
||||
mode_s0 <= 1'b0;
|
||||
d_s0 <= 5'd0;
|
||||
coeff_s0 <= 12'd0;
|
||||
valid_s0 <= 1'b0;
|
||||
|
||||
mode_s1 <= 1'b0;
|
||||
d_s1 <= 5'd0;
|
||||
comp_dividend_s1 <= 24'd0;
|
||||
decomp_rounded_s1 <= 24'd0;
|
||||
valid_s1 <= 1'b0;
|
||||
|
||||
mode_s2 <= 1'b0;
|
||||
d_s2 <= 5'd0;
|
||||
comp_dividend_s2 <= 24'd0;
|
||||
comp_qprod_est_s2 <= 37'd0;
|
||||
decomp_rounded_s2 <= 24'd0;
|
||||
valid_s2 <= 1'b0;
|
||||
|
||||
mode_s3 <= 1'b0;
|
||||
d_s3 <= 5'd0;
|
||||
comp_dividend_s3 <= 24'd0;
|
||||
comp_q_est_s3 <= 13'd0;
|
||||
decomp_result_s3 <= 12'd0;
|
||||
valid_s3 <= 1'b0;
|
||||
|
||||
mode_s4 <= 1'b0;
|
||||
d_s4 <= 5'd0;
|
||||
comp_dividend_s4 <= 24'd0;
|
||||
comp_q_est_s4 <= 13'd0;
|
||||
comp_q_mul_q_s4 <= 25'd0;
|
||||
decomp_result_s4 <= 12'd0;
|
||||
valid_s4 <= 1'b0;
|
||||
|
||||
mode_s5 <= 1'b0;
|
||||
d_s5 <= 5'd0;
|
||||
comp_q_est_s5 <= 13'd0;
|
||||
comp_rem_s5 <= 25'd0;
|
||||
decomp_result_s5 <= 12'd0;
|
||||
valid_s5 <= 1'b0;
|
||||
end else begin
|
||||
if (valid_r && ready_i)
|
||||
valid_r <= 1'b0;
|
||||
|
||||
mode_s0 <= mode;
|
||||
d_s0 <= d;
|
||||
coeff_s0 <= coeff_in;
|
||||
valid_s0 <= fire_i;
|
||||
|
||||
mode_s1 <= mode_s0;
|
||||
d_s1 <= d_s0;
|
||||
comp_dividend_s1 <= comp_dividend_next;
|
||||
decomp_rounded_s1 <= decomp_round_next;
|
||||
valid_s1 <= valid_s0;
|
||||
|
||||
mode_s2 <= mode_s1;
|
||||
d_s2 <= d_s1;
|
||||
comp_dividend_s2 <= comp_dividend_s1;
|
||||
comp_qprod_est_s2 <= {13'd0, comp_dividend_s1} * K13;
|
||||
decomp_rounded_s2 <= decomp_rounded_s1;
|
||||
valid_s2 <= valid_s1;
|
||||
|
||||
mode_s3 <= mode_s2;
|
||||
d_s3 <= d_s2;
|
||||
comp_dividend_s3 <= comp_dividend_s2;
|
||||
comp_q_est_s3 <= comp_qprod_est_s2[36:24];
|
||||
decomp_result_s3 <= decomp_rounded_s2 >> d_s2;
|
||||
valid_s3 <= valid_s2;
|
||||
|
||||
mode_s4 <= mode_s3;
|
||||
d_s4 <= d_s3;
|
||||
comp_dividend_s4 <= comp_dividend_s3;
|
||||
comp_q_est_s4 <= comp_q_est_s3;
|
||||
comp_q_mul_q_s4 <= comp_q_est_s3 * Q25;
|
||||
decomp_result_s4 <= decomp_result_s3;
|
||||
valid_s4 <= valid_s3;
|
||||
|
||||
mode_s5 <= mode_s4;
|
||||
d_s5 <= d_s4;
|
||||
comp_q_est_s5 <= comp_q_est_s4;
|
||||
comp_rem_s5 <= {1'b0, comp_dividend_s4} - comp_q_mul_q_s4;
|
||||
decomp_result_s5 <= decomp_result_s4;
|
||||
valid_s5 <= valid_s4;
|
||||
|
||||
if (valid_s5) begin
|
||||
data_r <= mode_s5 ? decomp_result_s5 : comp_result_s5;
|
||||
valid_r <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -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,
|
||||
@@ -18,7 +19,7 @@ module barrett_mul (
|
||||
|
||||
// Full product: a * b (both < 3329, product < 11,082,241 < 2^24)
|
||||
// Force 24-bit evaluation by extending operand
|
||||
wire [23:0] p;
|
||||
(* use_dsp = "no" *) wire [23:0] p;
|
||||
assign p = {12'd0, a} * b;
|
||||
|
||||
// Extend p to 37 bits for multiplication with K
|
||||
@@ -28,14 +29,14 @@ module barrett_mul (
|
||||
// Compute t_shifted = (p * K) >> 24
|
||||
// Use explicit wire for the product to control width
|
||||
/* verilator lint_off UNUSED */
|
||||
wire [36:0] t_product;
|
||||
(* use_dsp = "no" *) wire [36:0] t_product;
|
||||
/* verilator lint_on UNUSED */
|
||||
assign t_product = p_ext * K;
|
||||
wire [12:0] t_shifted;
|
||||
assign t_shifted = t_product[36:R];
|
||||
|
||||
// q_approx = t_shifted * Q
|
||||
wire [24:0] q_approx;
|
||||
(* use_dsp = "no" *) wire [24:0] q_approx;
|
||||
assign q_approx = t_shifted * Q;
|
||||
|
||||
// r = p - q_approx
|
||||
|
||||
73
rtl/ip/mlkem/ntt/barrett_mul_pipe.v
Normal file
@@ -0,0 +1,73 @@
|
||||
// barrett_mul_pipe.v - DSP-friendly pipelined Barrett modular multiply
|
||||
//
|
||||
// Computes product = a * b mod Q with fixed latency. This module is used on
|
||||
// timing-critical NTT paths; the legacy barrett_mul remains combinational for
|
||||
// older users.
|
||||
|
||||
(* use_dsp = "no" *)
|
||||
module barrett_mul_pipe (
|
||||
input clk,
|
||||
input rst_n,
|
||||
input valid_i,
|
||||
input [11:0] a,
|
||||
input [11:0] b,
|
||||
output [11:0] product,
|
||||
output valid_o
|
||||
);
|
||||
localparam [24:0] Q25 = 25'd3329;
|
||||
localparam [12:0] K13 = 13'd5039;
|
||||
|
||||
(* use_dsp = "no" *) reg [23:0] p_s1;
|
||||
|
||||
reg [23:0] p_s2;
|
||||
(* use_dsp = "no" *) reg [36:0] tk_s2;
|
||||
|
||||
reg [23:0] p_s3;
|
||||
reg [12:0] q_s3;
|
||||
|
||||
reg [24:0] p_s4;
|
||||
(* use_dsp = "no" *) reg [24:0] qprod_s4;
|
||||
|
||||
reg [24:0] r0_s5;
|
||||
reg [24:0] r1_s6;
|
||||
reg [11:0] product_r;
|
||||
reg [6:0] valid_sr;
|
||||
|
||||
assign product = product_r;
|
||||
assign valid_o = valid_sr[6];
|
||||
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
p_s1 <= 24'd0;
|
||||
p_s2 <= 24'd0; tk_s2 <= 37'd0;
|
||||
p_s3 <= 24'd0; q_s3 <= 13'd0;
|
||||
p_s4 <= 25'd0; qprod_s4 <= 25'd0;
|
||||
r0_s5 <= 25'd0; r1_s6 <= 25'd0;
|
||||
product_r <= 12'd0;
|
||||
valid_sr <= 7'd0;
|
||||
end else begin
|
||||
valid_sr <= {valid_sr[5:0], valid_i};
|
||||
|
||||
// S1: full product.
|
||||
p_s1 <= {12'd0, a} * b;
|
||||
|
||||
// S2: quotient-estimate product.
|
||||
p_s2 <= p_s1;
|
||||
tk_s2 <= {13'd0, p_s1} * K13;
|
||||
|
||||
// S3: quotient estimate.
|
||||
p_s3 <= p_s2;
|
||||
q_s3 <= tk_s2[36:24];
|
||||
|
||||
// S4: q * Q.
|
||||
p_s4 <= {1'b0, p_s3};
|
||||
qprod_s4 <= q_s3 * Q25;
|
||||
|
||||
// S5/S6/S7: subtract q*Q and conditionally subtract Q twice.
|
||||
r0_s5 <= p_s4 - qprod_s4;
|
||||
r1_s6 <= (r0_s5 >= Q25) ? (r0_s5 - Q25) : r0_s5;
|
||||
product_r <= (r1_s6 >= Q25) ? (r1_s6 - Q25) : r1_s6[11:0];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
89
rtl/ip/mlkem/ntt/butterfly_unit_pipe.v
Normal file
@@ -0,0 +1,89 @@
|
||||
// butterfly_unit_pipe.v - pipelined Cooley-Tukey / Gentleman-Sande butterfly
|
||||
//
|
||||
// Fixed-latency wrapper around barrett_mul_pipe. All arithmetic that used to
|
||||
// sit in one NTT cycle is now split by registers.
|
||||
|
||||
module butterfly_unit_pipe (
|
||||
input clk,
|
||||
input rst_n,
|
||||
input valid_i,
|
||||
input [11:0] a,
|
||||
input [11:0] b,
|
||||
input [11:0] zeta,
|
||||
input mode, // 0 = forward NTT, 1 = inverse NTT
|
||||
output [11:0] a_out,
|
||||
output [11:0] b_out,
|
||||
output valid_o
|
||||
);
|
||||
localparam [11:0] Q12 = 12'd3329;
|
||||
localparam [12:0] Q13 = 13'd3329;
|
||||
|
||||
// Plan A: register the inputs. Operands arrive combinationally from the
|
||||
// coeff_bram read; without this stage the path coeff_bram-read -> diff ->
|
||||
// first multiply stage sits in one cycle (the mlkem_clk critical path at
|
||||
// 100 MHz). Registering here splits it into (BRAM read -> reg) and
|
||||
// (reg -> diff -> multiply). Adds one pipeline cycle (absorbed by the NTT
|
||||
// writeback delay line).
|
||||
reg [11:0] a_r, b_r, zeta_r;
|
||||
reg mode_ri, vld_r;
|
||||
|
||||
wire [11:0] diff = (b_r >= a_r) ? (b_r - a_r) : (b_r - a_r + Q12);
|
||||
wire [11:0] mul_data = mode_ri ? diff : b_r;
|
||||
|
||||
wire [11:0] mul_result;
|
||||
wire mul_valid;
|
||||
barrett_mul_pipe u_barrett (
|
||||
.clk(clk),
|
||||
.rst_n(rst_n),
|
||||
.valid_i(vld_r),
|
||||
.a(zeta_r),
|
||||
.b(mul_data),
|
||||
.product(mul_result),
|
||||
.valid_o(mul_valid)
|
||||
);
|
||||
|
||||
// a/b/mode delay lines (fed from the REGISTERED inputs a_r/b_r/mode_ri so
|
||||
// a_d6 aligns with mul_valid = valid_i delayed 8).
|
||||
reg [11:0] a_d0, a_d1, a_d2, a_d3, a_d4, a_d5, a_d6;
|
||||
reg [11:0] b_d0, b_d1, b_d2, b_d3, b_d4, b_d5, b_d6;
|
||||
reg mode_d0, mode_d1, mode_d2, mode_d3, mode_d4, mode_d5, mode_d6;
|
||||
|
||||
reg [11:0] a_out_r, b_out_r;
|
||||
reg valid_r;
|
||||
|
||||
wire [12:0] a_sum = {1'b0, a_d6} + {1'b0, (mode_d6 ? b_d6 : mul_result)};
|
||||
wire [11:0] a_mod = (a_sum >= Q13) ? (a_sum[11:0] - Q12) : a_sum[11:0];
|
||||
wire [11:0] b_sub = (a_d6 >= mul_result) ? (a_d6 - mul_result) :
|
||||
(a_d6 - mul_result + Q12);
|
||||
|
||||
assign a_out = a_out_r;
|
||||
assign b_out = b_out_r;
|
||||
assign valid_o = valid_r;
|
||||
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
a_r <= 12'd0; b_r <= 12'd0; zeta_r <= 12'd0; mode_ri <= 1'b0; vld_r <= 1'b0;
|
||||
a_d0 <= 12'd0; a_d1 <= 12'd0; a_d2 <= 12'd0; a_d3 <= 12'd0; a_d4 <= 12'd0; a_d5 <= 12'd0; a_d6 <= 12'd0;
|
||||
b_d0 <= 12'd0; b_d1 <= 12'd0; b_d2 <= 12'd0; b_d3 <= 12'd0; b_d4 <= 12'd0; b_d5 <= 12'd0; b_d6 <= 12'd0;
|
||||
mode_d0 <= 1'b0; mode_d1 <= 1'b0; mode_d2 <= 1'b0; mode_d3 <= 1'b0; mode_d4 <= 1'b0; mode_d5 <= 1'b0; mode_d6 <= 1'b0;
|
||||
a_out_r <= 12'd0;
|
||||
b_out_r <= 12'd0;
|
||||
valid_r <= 1'b0;
|
||||
end else begin
|
||||
// input register stage
|
||||
a_r <= a; b_r <= b; zeta_r <= zeta; mode_ri <= mode; vld_r <= valid_i;
|
||||
|
||||
a_d0 <= a_r; a_d1 <= a_d0; a_d2 <= a_d1; a_d3 <= a_d2; a_d4 <= a_d3; a_d5 <= a_d4; a_d6 <= a_d5;
|
||||
b_d0 <= b_r; b_d1 <= b_d0; b_d2 <= b_d1; b_d3 <= b_d2; b_d4 <= b_d3; b_d5 <= b_d4; b_d6 <= b_d5;
|
||||
mode_d0 <= mode_ri; mode_d1 <= mode_d0; mode_d2 <= mode_d1;
|
||||
mode_d3 <= mode_d2; mode_d4 <= mode_d3; mode_d5 <= mode_d4; mode_d6 <= mode_d5;
|
||||
|
||||
valid_r <= mul_valid;
|
||||
if (mul_valid) begin
|
||||
a_out_r <= a_mod;
|
||||
b_out_r <= mode_d6 ? mul_result : b_sub;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
113
rtl/ip/mlkem/ntt/coeff_bram_4way.v
Normal file
@@ -0,0 +1,113 @@
|
||||
// coeff_bram_4way.v - 4-way conflict-free banked storage for NTT coefficients
|
||||
//
|
||||
// Replaces the 256x12 LUT register file (reg [11:0] cr [0:255]) with 4 BRAM
|
||||
// banks (each 128x12 via sd_bram), removing the large multi-port LUT mux tree.
|
||||
//
|
||||
// Bank function: bank(a) = { a[0], ^a[7:1] } (bit0 XOR parity of upper 7 bits)
|
||||
// local(a) = a[7:1] (7-bit index into the 128-deep bank)
|
||||
//
|
||||
// This function makes a dual-butterfly's four simultaneous coefficient accesses
|
||||
// {j, j+1, j+len, j+1+len} land in four DISTINCT banks for every ML-KEM NTT
|
||||
// layer_len in {2,4,...,128}: j is even and len is even, so
|
||||
// j -> {0, P }
|
||||
// j+1 -> {1, P }
|
||||
// j+len -> {0, P'} (flipping bit m>=1 flips the upper-bits parity)
|
||||
// j+1+len -> {1, P'}
|
||||
// with P != P'. Four distinct banks => 4 conflict-free reads/cycle from four
|
||||
// single-read-port banks, and likewise 4 conflict-free writes/cycle. Each bank
|
||||
// therefore needs only 1 read + 1 write per cycle (an sd_bram), no ping-pong.
|
||||
//
|
||||
// Read latency is 1 cycle (sd_bram registered read): present rd_addr_k this
|
||||
// cycle, rd_data_k valid next cycle. Writes commit on the presenting cycle.
|
||||
//
|
||||
// NOTE: the caller must guarantee the four read addresses map to four distinct
|
||||
// banks (true for the NTT butterfly pattern) and the four write addresses too.
|
||||
// Sequential access (load/output) uses a single port and is always safe.
|
||||
|
||||
module coeff_bram_4way (
|
||||
input clk, rst_n,
|
||||
// Four read addresses (global 8-bit); data returns 1 cycle later.
|
||||
input [7:0] rd_addr_0, rd_addr_1, rd_addr_2, rd_addr_3,
|
||||
output [11:0] rd_data_0, rd_data_1, rd_data_2, rd_data_3,
|
||||
// Four write ports.
|
||||
input wr_en_0, wr_en_1, wr_en_2, wr_en_3,
|
||||
input [7:0] wr_addr_0, wr_addr_1, wr_addr_2, wr_addr_3,
|
||||
input [11:0] wr_data_0, wr_data_1, wr_data_2, wr_data_3
|
||||
);
|
||||
|
||||
// Bank id and local index for an address.
|
||||
function [1:0] bank_id;
|
||||
input [7:0] a;
|
||||
bank_id = {a[0], ^a[7:1]};
|
||||
endfunction
|
||||
|
||||
wire [1:0] rb0 = bank_id(rd_addr_0);
|
||||
wire [1:0] rb1 = bank_id(rd_addr_1);
|
||||
wire [1:0] rb2 = bank_id(rd_addr_2);
|
||||
wire [1:0] rb3 = bank_id(rd_addr_3);
|
||||
|
||||
wire [1:0] wb0 = bank_id(wr_addr_0);
|
||||
wire [1:0] wb1 = bank_id(wr_addr_1);
|
||||
wire [1:0] wb2 = bank_id(wr_addr_2);
|
||||
wire [1:0] wb3 = bank_id(wr_addr_3);
|
||||
|
||||
// Per-bank read-address crossbar: bank b reads the local index of whichever
|
||||
// read port targets it (exactly one, by construction).
|
||||
wire [6:0] bank_rd_local [0:3];
|
||||
wire [6:0] bank_wr_local [0:3];
|
||||
wire bank_wr_en [0:3];
|
||||
wire [11:0] bank_wr_data [0:3];
|
||||
wire [11:0] bank_rd_data [0:3];
|
||||
|
||||
genvar b;
|
||||
generate
|
||||
for (b = 0; b < 4; b = b + 1) begin : gen_xbar
|
||||
// read address route (priority: 3>2>1>0; ties impossible for NTT)
|
||||
assign bank_rd_local[b] =
|
||||
(rb3 == b[1:0]) ? rd_addr_3[7:1] :
|
||||
(rb2 == b[1:0]) ? rd_addr_2[7:1] :
|
||||
(rb1 == b[1:0]) ? rd_addr_1[7:1] :
|
||||
rd_addr_0[7:1];
|
||||
// write route
|
||||
wire m0 = wr_en_0 && (wb0 == b[1:0]);
|
||||
wire m1 = wr_en_1 && (wb1 == b[1:0]);
|
||||
wire m2 = wr_en_2 && (wb2 == b[1:0]);
|
||||
wire m3 = wr_en_3 && (wb3 == b[1:0]);
|
||||
assign bank_wr_en[b] = m0 | m1 | m2 | m3;
|
||||
assign bank_wr_local[b] =
|
||||
m3 ? wr_addr_3[7:1] :
|
||||
m2 ? wr_addr_2[7:1] :
|
||||
m1 ? wr_addr_1[7:1] : wr_addr_0[7:1];
|
||||
assign bank_wr_data[b] =
|
||||
m3 ? wr_data_3 :
|
||||
m2 ? wr_data_2 :
|
||||
m1 ? wr_data_1 : wr_data_0;
|
||||
|
||||
sd_bram #(.W(12), .D(128), .A(7)) u_bank (
|
||||
.clk(clk),
|
||||
.rd_addr(bank_rd_local[b]),
|
||||
.rd_data(bank_rd_data[b]),
|
||||
.wr_en(bank_wr_en[b]),
|
||||
.wr_addr(bank_wr_local[b]),
|
||||
.wr_data(bank_wr_data[b])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Register the read bank-ids to align with sd_bram's 1-cycle read latency,
|
||||
// then route each bank's output back to the requesting read port.
|
||||
reg [1:0] rb0_r, rb1_r, rb2_r, rb3_r;
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
rb0_r <= 2'd0; rb1_r <= 2'd0; rb2_r <= 2'd0; rb3_r <= 2'd0;
|
||||
end else begin
|
||||
rb0_r <= rb0; rb1_r <= rb1; rb2_r <= rb2; rb3_r <= rb3;
|
||||
end
|
||||
end
|
||||
|
||||
assign rd_data_0 = bank_rd_data[rb0_r];
|
||||
assign rd_data_1 = bank_rd_data[rb1_r];
|
||||
assign rd_data_2 = bank_rd_data[rb2_r];
|
||||
assign rd_data_3 = bank_rd_data[rb3_r];
|
||||
|
||||
endmodule
|
||||
@@ -1,8 +1,18 @@
|
||||
// ntt_core.v - NTT core with individual coefficient registers
|
||||
// ntt_core.v - NTT core with 4-way banked BRAM coefficient storage
|
||||
//
|
||||
// Uses 256 individual 12-bit registers and generate-based muxing
|
||||
// to avoid any part-select simulation issues.
|
||||
// 3-cycle butterfly: SetAddr -> Read -> Compute+Write
|
||||
// Coefficient storage moved from a 256x12 LUT register file to coeff_bram_4way
|
||||
// (4 x 128x12 sd_bram, conflict-free banked). This removes the large multi-port
|
||||
// LUT mux tree. Two pipelined butterflies (R1) still issue one pair/cycle.
|
||||
//
|
||||
// Because BRAM reads are synchronous (1-cycle latency), the compute pipeline
|
||||
// gains one stage:
|
||||
// READ (present rd addrs from j) -> FEED butterflies (t+1, rd_data valid)
|
||||
// -> 8-stage Barrett butterfly -> WRITEBACK (t+9) into the write buffer.
|
||||
// Read and writeback hit disjoint banks (butterfly index sets in a layer are
|
||||
// disjoint), so each bank does 1 read + 1 write per cycle (sd_bram = 1R1W).
|
||||
//
|
||||
// LOAD/OUTPUT/OUT_SCALE stream through a single bank port with 1-cycle read
|
||||
// latency (ready_i is tied high by all NTT consumers, so no output backpressure).
|
||||
|
||||
module ntt_core (
|
||||
input clk, rst_n,
|
||||
@@ -17,116 +27,270 @@ module ntt_core (
|
||||
);
|
||||
localparam N = 256, LAYERS = 7, DW = 12;
|
||||
|
||||
// Individual coefficient registers
|
||||
reg [DW-1:0] cr [0:N-1];
|
||||
integer ci;
|
||||
localparam S_IDLE = 4'd0;
|
||||
localparam S_LOAD = 4'd1;
|
||||
localparam S_CMP_RUN = 4'd2;
|
||||
localparam S_CMP_DRAIN = 4'd3;
|
||||
localparam S_OUT_PREP = 4'd7;
|
||||
localparam S_OUTPUT = 4'd8;
|
||||
localparam S_OUT_SCALE = 4'd9;
|
||||
localparam S_DONE = 4'd10;
|
||||
|
||||
// State machine
|
||||
localparam S_IDLE=3'd0, S_LOAD=3'd1, S_CMP_A=3'd2, S_CMP_B=3'd3,
|
||||
S_CMP_C=3'd4, S_OUTPUT=3'd5, S_DONE=3'd6;
|
||||
reg [2:0] state, next_state;
|
||||
reg [3:0] state, next_state;
|
||||
|
||||
reg [7:0] load_cnt, out_cnt;
|
||||
reg [7:0] load_cnt;
|
||||
reg [8:0] out_rptr; // output read address pointer (0..256)
|
||||
reg [8:0] out_cnt; // output coeffs emitted (0..256)
|
||||
reg [8:0] scale_rptr; // scale read address pointer
|
||||
reg [8:0] scale_issue_cnt; // coeffs fed to scale barrett
|
||||
reg [8:0] scale_emit_cnt; // coeffs emitted from scale barrett
|
||||
reg [7:0] j, start, layer_len;
|
||||
reg [6:0] zeta_idx;
|
||||
reg [2:0] layer;
|
||||
reg bf_done;
|
||||
reg mode_r;
|
||||
reg layer_issue_done;
|
||||
reg [5:0] bf_inflight;
|
||||
|
||||
// Pipeline registers
|
||||
reg [DW-1:0] r_a, r_b;
|
||||
reg [7:0] r_wa, r_wb;
|
||||
reg rd_fire_r; // issue_fire delayed 1 (BRAM read latency) -> feed
|
||||
// 9-deep writeback address delay lines (BRAM read + 8-stage butterfly).
|
||||
reg [7:0] a0d[0:9]; reg [7:0] b0d[0:9];
|
||||
reg [7:0] a1d[0:9]; reg [7:0] b1d[0:9];
|
||||
integer k;
|
||||
|
||||
reg [DW-1:0] coeff_out_r;
|
||||
reg valid_o_r;
|
||||
reg scale_valid_i;
|
||||
reg [DW-1:0] scale_a_i;
|
||||
reg [DW-1:0] zeta_fed; // zeta aligned to BRAM read data (1 cyc after present)
|
||||
|
||||
// Zeta
|
||||
wire [DW-1:0] zeta;
|
||||
zeta_rom u_z (.addr(zeta_idx), .zeta(zeta));
|
||||
|
||||
// Butterfly
|
||||
wire [DW-1:0] bf_a_out, bf_b_out;
|
||||
butterfly_unit u_bf (
|
||||
.a(r_a), .b(r_b), .zeta(zeta), .mode(mode),
|
||||
.a_out(bf_a_out), .b_out(bf_b_out));
|
||||
wire [8:0] group_end = {1'b0, start} + {1'b0, layer_len};
|
||||
wire [8:0] next_group_start = {1'b0, start} + {1'b0, layer_len} + {1'b0, layer_len};
|
||||
wire issue_group_last = ({1'b0, j} + 9'd2 >= group_end);
|
||||
wire issue_layer_last = issue_group_last && (next_group_start >= 9'd256);
|
||||
wire [7:0] next_layer_len = mode_r ? (layer_len << 1) : (layer_len >> 1);
|
||||
wire issue_fire = (state == S_CMP_RUN) && !layer_issue_done;
|
||||
|
||||
// Output scaling
|
||||
wire [DW-1:0] coeff_scaled;
|
||||
barrett_mul u_scl (.a(cr[out_cnt]), .b(12'd3303), .product(coeff_scaled));
|
||||
assign coeff_out = mode ? coeff_scaled : cr[out_cnt];
|
||||
// ---- coeff_bram_4way port muxing ----
|
||||
// Read addr 0 is shared by compute (j), output (out_rptr), scale (scale_rptr).
|
||||
wire [7:0] cmp_a0 = j;
|
||||
wire [7:0] cmp_b0 = j + layer_len;
|
||||
wire [7:0] cmp_a1 = j + 8'd1;
|
||||
wire [7:0] cmp_b1 = j + 8'd1 + layer_len;
|
||||
|
||||
wire [7:0] rd_addr_0 = (state == S_OUT_PREP || state == S_OUTPUT) ? out_rptr[7:0] :
|
||||
(state == S_OUT_SCALE) ? scale_rptr[7:0] : cmp_a0;
|
||||
// Ports 1..3 carry the other three butterfly operands ONLY during compute;
|
||||
// otherwise they must mirror port 0 so the read crossbar's per-bank priority
|
||||
// arbitration doesn't route a stale compute address into port 0's bank.
|
||||
wire cmp_rd = (state == S_CMP_RUN) || (state == S_CMP_DRAIN);
|
||||
wire [7:0] rd_addr_1 = cmp_rd ? cmp_b0 : rd_addr_0;
|
||||
wire [7:0] rd_addr_2 = cmp_rd ? cmp_a1 : rd_addr_0;
|
||||
wire [7:0] rd_addr_3 = cmp_rd ? cmp_b1 : rd_addr_0;
|
||||
wire [11:0] rd_data_0, rd_data_1, rd_data_2, rd_data_3;
|
||||
|
||||
assign ready_o = (state == S_IDLE) || (state == S_LOAD);
|
||||
assign valid_o = (state == S_OUTPUT);
|
||||
assign done_o = (state == S_DONE);
|
||||
// Butterflies fed from BRAM read data one cycle after the address (rd_fire_r).
|
||||
wire [DW-1:0] bf0_a_out, bf0_b_out, bf1_a_out, bf1_b_out;
|
||||
wire bf0_valid, bf1_valid;
|
||||
butterfly_unit_pipe u_bf0 (
|
||||
.clk(clk), .rst_n(rst_n),
|
||||
.valid_i(rd_fire_r),
|
||||
.a(rd_data_0), .b(rd_data_1),
|
||||
.zeta(zeta_fed), .mode(mode_r),
|
||||
.a_out(bf0_a_out), .b_out(bf0_b_out), .valid_o(bf0_valid)
|
||||
);
|
||||
butterfly_unit_pipe u_bf1 (
|
||||
.clk(clk), .rst_n(rst_n),
|
||||
.valid_i(rd_fire_r),
|
||||
.a(rd_data_2), .b(rd_data_3),
|
||||
.zeta(zeta_fed), .mode(mode_r),
|
||||
.a_out(bf1_a_out), .b_out(bf1_b_out), .valid_o(bf1_valid)
|
||||
);
|
||||
// zeta must align with the BRAM read data (1 cycle after presentation).
|
||||
|
||||
// Scale multiplier (inverse NTT final x3303).
|
||||
wire [DW-1:0] scale_product;
|
||||
wire scale_valid_o;
|
||||
barrett_mul_pipe u_scl (
|
||||
.clk(clk), .rst_n(rst_n),
|
||||
.valid_i(scale_valid_i),
|
||||
.a(scale_a_i), .b(12'd3303),
|
||||
.product(scale_product), .valid_o(scale_valid_o)
|
||||
);
|
||||
|
||||
// ---- write ports ----
|
||||
wire loading_we = (state == S_IDLE && valid_i) || (state == S_LOAD && valid_i);
|
||||
wire [7:0] load_addr = (state == S_IDLE) ? 8'd0 : load_cnt;
|
||||
|
||||
wire wr_en_0 = loading_we | bf0_valid;
|
||||
wire wr_en_1 = bf0_valid & ~loading_we;
|
||||
wire wr_en_2 = bf0_valid & ~loading_we;
|
||||
wire wr_en_3 = bf0_valid & ~loading_we;
|
||||
wire [7:0] wr_addr_0 = loading_we ? load_addr : a0d[9];
|
||||
wire [7:0] wr_addr_1 = b0d[9];
|
||||
wire [7:0] wr_addr_2 = a1d[9];
|
||||
wire [7:0] wr_addr_3 = b1d[9];
|
||||
wire [11:0] wr_data_0 = loading_we ? coeff_in : bf0_a_out;
|
||||
wire [11:0] wr_data_1 = bf0_b_out;
|
||||
wire [11:0] wr_data_2 = bf1_a_out;
|
||||
wire [11:0] wr_data_3 = bf1_b_out;
|
||||
|
||||
coeff_bram_4way u_cr (
|
||||
.clk(clk), .rst_n(rst_n),
|
||||
.rd_addr_0(rd_addr_0), .rd_addr_1(rd_addr_1),
|
||||
.rd_addr_2(rd_addr_2), .rd_addr_3(rd_addr_3),
|
||||
.rd_data_0(rd_data_0), .rd_data_1(rd_data_1),
|
||||
.rd_data_2(rd_data_2), .rd_data_3(rd_data_3),
|
||||
.wr_en_0(wr_en_0), .wr_en_1(wr_en_1), .wr_en_2(wr_en_2), .wr_en_3(wr_en_3),
|
||||
.wr_addr_0(wr_addr_0), .wr_addr_1(wr_addr_1),
|
||||
.wr_addr_2(wr_addr_2), .wr_addr_3(wr_addr_3),
|
||||
.wr_data_0(wr_data_0), .wr_data_1(wr_data_1),
|
||||
.wr_data_2(wr_data_2), .wr_data_3(wr_data_3)
|
||||
);
|
||||
|
||||
assign ready_o = (state == S_IDLE) || (state == S_LOAD);
|
||||
// During forward OUTPUT, drive coeff_out straight from the BRAM read (1-cycle
|
||||
// latency, matching the old combinational-read + 1 output reg). Scale path
|
||||
// uses the registered barrett result.
|
||||
assign coeff_out = (state == S_OUTPUT) ? rd_data_0 : coeff_out_r;
|
||||
assign valid_o = valid_o_r;
|
||||
assign done_o = (state == S_DONE);
|
||||
|
||||
always @* begin
|
||||
next_state = state;
|
||||
case (state)
|
||||
S_IDLE: if (valid_i) next_state = S_LOAD;
|
||||
S_LOAD: if (load_cnt >= 255 && valid_i) next_state = S_CMP_A;
|
||||
S_CMP_A: if (bf_done) next_state = S_OUTPUT; else next_state = S_CMP_B;
|
||||
S_CMP_B: if (bf_done) next_state = S_OUTPUT; else next_state = S_CMP_C;
|
||||
S_CMP_C: if (bf_done) next_state = S_OUTPUT; else next_state = S_CMP_A;
|
||||
S_OUTPUT:if (out_cnt >= 255 && ready_i) next_state = S_DONE;
|
||||
S_DONE: next_state = S_IDLE;
|
||||
default: next_state = S_IDLE;
|
||||
S_IDLE: if (valid_i) next_state = S_LOAD;
|
||||
S_LOAD: if (load_cnt >= 8'd255 && valid_i) next_state = S_CMP_RUN;
|
||||
S_CMP_RUN: if (layer_issue_done) next_state = S_CMP_DRAIN;
|
||||
S_CMP_DRAIN: if (bf_inflight == 6'd0)
|
||||
next_state = (layer + 3'd1 >= LAYERS) ? S_OUT_PREP : S_CMP_RUN;
|
||||
S_OUT_PREP: next_state = mode_r ? S_OUT_SCALE : S_OUTPUT;
|
||||
S_OUTPUT: if (out_cnt >= 9'd256) next_state = S_DONE;
|
||||
S_OUT_SCALE: if (scale_emit_cnt >= 9'd256) next_state = S_DONE;
|
||||
S_DONE: next_state = S_IDLE;
|
||||
default: next_state = S_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
state<=S_IDLE; load_cnt<=0; out_cnt<=0; j<=0; start<=0; layer_len<=0;
|
||||
zeta_idx<=0; layer<=0; bf_done<=0; r_a<=0; r_b<=0; r_wa<=0; r_wb<=0;
|
||||
for (ci=0; ci<N; ci=ci+1) cr[ci] = 0;
|
||||
state <= S_IDLE;
|
||||
load_cnt <= 8'd0;
|
||||
out_rptr <= 9'd0; out_cnt <= 9'd0;
|
||||
scale_rptr <= 9'd0; scale_issue_cnt <= 9'd0; scale_emit_cnt <= 9'd0;
|
||||
j <= 8'd0; start <= 8'd0; layer_len <= 8'd0;
|
||||
zeta_idx <= 7'd0; zeta_fed <= 12'd0;
|
||||
layer <= 3'd0; mode_r <= 1'b0;
|
||||
layer_issue_done <= 1'b0; bf_inflight <= 6'd0;
|
||||
rd_fire_r <= 1'b0;
|
||||
for (k = 0; k <= 9; k = k + 1) begin
|
||||
a0d[k] <= 8'd0; b0d[k] <= 8'd0; a1d[k] <= 8'd0; b1d[k] <= 8'd0;
|
||||
end
|
||||
coeff_out_r <= 12'd0; valid_o_r <= 1'b0;
|
||||
scale_valid_i <= 1'b0; scale_a_i <= 12'd0;
|
||||
end else begin
|
||||
state <= next_state;
|
||||
scale_valid_i <= 1'b0;
|
||||
|
||||
// read->feed pipeline register (BRAM latency) + zeta alignment
|
||||
rd_fire_r <= issue_fire;
|
||||
zeta_fed <= zeta;
|
||||
|
||||
// writeback address delay lines: sample j-derived addrs at read cycle
|
||||
a0d[0] <= cmp_a0; b0d[0] <= cmp_b0; a1d[0] <= cmp_a1; b1d[0] <= cmp_b1;
|
||||
for (k = 1; k <= 9; k = k + 1) begin
|
||||
a0d[k] <= a0d[k-1]; b0d[k] <= b0d[k-1];
|
||||
a1d[k] <= a1d[k-1]; b1d[k] <= b1d[k-1];
|
||||
end
|
||||
|
||||
// in-flight pair accounting: +1 on issue, -1 on writeback
|
||||
if (issue_fire && !bf0_valid) bf_inflight <= bf_inflight + 6'd1;
|
||||
else if (!issue_fire && bf0_valid) bf_inflight <= bf_inflight - 6'd1;
|
||||
|
||||
if (state != S_OUTPUT && state != S_OUT_SCALE)
|
||||
valid_o_r <= 1'b0;
|
||||
|
||||
if (state == S_IDLE && valid_i) begin
|
||||
cr[0] <= coeff_in;
|
||||
load_cnt<=1; out_cnt<=0; j<=0; start<=0; layer<=0; bf_done<=0;
|
||||
if (!mode) begin layer_len<=128; zeta_idx<=1; end
|
||||
else begin layer_len<=2; zeta_idx<=127; end
|
||||
load_cnt <= 8'd1;
|
||||
out_rptr <= 9'd0; out_cnt <= 9'd0;
|
||||
scale_rptr <= 9'd0; scale_issue_cnt <= 9'd0; scale_emit_cnt <= 9'd0;
|
||||
j <= 8'd0; start <= 8'd0; layer <= 3'd0;
|
||||
layer_issue_done <= 1'b0; bf_inflight <= 6'd0;
|
||||
mode_r <= mode;
|
||||
if (!mode) begin layer_len <= 8'd128; zeta_idx <= 7'd1; end
|
||||
else begin layer_len <= 8'd2; zeta_idx <= 7'd127; end
|
||||
end
|
||||
|
||||
if (state == S_LOAD && valid_i) begin
|
||||
cr[load_cnt] <= coeff_in;
|
||||
load_cnt <= load_cnt + 8'd1;
|
||||
end
|
||||
if (state == S_LOAD && valid_i) load_cnt <= load_cnt + 8'd1;
|
||||
|
||||
// S_CMP_A: set read addresses (j, j+len)
|
||||
if (state == S_CMP_A) begin
|
||||
r_wa <= j;
|
||||
r_wb <= j + layer_len;
|
||||
end
|
||||
|
||||
// S_CMP_B: capture read data
|
||||
if (state == S_CMP_B) begin
|
||||
r_a <= cr[j];
|
||||
r_b <= cr[j + layer_len];
|
||||
end
|
||||
|
||||
// S_CMP_C: write butterfly results, advance counters
|
||||
if (state == S_CMP_C) begin
|
||||
cr[r_wa] <= bf_a_out;
|
||||
cr[r_wb] <= bf_b_out;
|
||||
|
||||
j <= j + 8'd1;
|
||||
if (j + 8'd1 >= start + layer_len) begin
|
||||
if (!mode) zeta_idx <= zeta_idx + 7'd1;
|
||||
else zeta_idx <= zeta_idx - 7'd1;
|
||||
|
||||
if ({1'b0,start} + {1'b0,layer_len} + {1'b0,layer_len} >= 256) begin
|
||||
layer <= layer + 3'd1;
|
||||
layer_len <= mode ? (layer_len<<1) : (layer_len>>1);
|
||||
start <= 0; j <= 0;
|
||||
if (layer + 3'd1 >= LAYERS) bf_done <= 1'b1;
|
||||
end else begin
|
||||
start <= start + layer_len + layer_len;
|
||||
j <= start + layer_len + layer_len;
|
||||
end
|
||||
// ---- issue advance (read pointer j, step 2) ----
|
||||
if (state == S_CMP_RUN && !layer_issue_done) begin
|
||||
if (issue_group_last) begin
|
||||
if (!mode_r) zeta_idx <= zeta_idx + 7'd1;
|
||||
else zeta_idx <= zeta_idx - 7'd1;
|
||||
if (issue_layer_last) layer_issue_done <= 1'b1;
|
||||
else begin start <= next_group_start[7:0]; j <= next_group_start[7:0]; end
|
||||
end else begin
|
||||
j <= j + 8'd2;
|
||||
end
|
||||
end
|
||||
|
||||
if (state == S_OUTPUT && ready_i)
|
||||
out_cnt <= (out_cnt>=255) ? 0 : (out_cnt+8'd1);
|
||||
// ---- layer advance after drain ----
|
||||
if (state == S_CMP_DRAIN && bf_inflight == 6'd0) begin
|
||||
if (layer + 3'd1 < LAYERS) begin
|
||||
layer <= layer + 3'd1;
|
||||
layer_len <= next_layer_len;
|
||||
start <= 8'd0; j <= 8'd0;
|
||||
layer_issue_done <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// ---- OUT_PREP: reset output pointers ----
|
||||
if (state == S_OUT_PREP) begin
|
||||
out_rptr <= 9'd0; out_cnt <= 9'd0;
|
||||
scale_rptr <= 9'd1; scale_issue_cnt <= 9'd0; scale_emit_cnt <= 9'd0;
|
||||
// (scale first addr 0 is presented via out_rptr in this PREP cycle)
|
||||
end
|
||||
|
||||
// ---- OUTPUT: stream coeffs. coeff_out is combinational rd_data_0;
|
||||
// valid_o is a registered "presented a valid addr last cycle". Present
|
||||
// addresses out_rptr = 0..255 (256), giving 256 valid outputs. ----
|
||||
if (state == S_OUTPUT) begin
|
||||
if (out_rptr < 9'd256) begin
|
||||
out_rptr <= out_rptr + 9'd1; // present rd_addr_0 = out_rptr
|
||||
valid_o_r <= 1'b1; // data valid next cycle
|
||||
end else begin
|
||||
valid_o_r <= 1'b0;
|
||||
end
|
||||
if (valid_o_r) out_cnt <= out_cnt + 9'd1; // count emitted
|
||||
end
|
||||
|
||||
// ---- OUT_SCALE: read coeff, x3303 via barrett, emit ----
|
||||
if (state == S_OUT_SCALE) begin
|
||||
if (scale_rptr < 9'd256) scale_rptr <= scale_rptr + 9'd1;
|
||||
// feed barrett with the coeff that arrived this cycle
|
||||
if (scale_issue_cnt < 9'd256) begin
|
||||
scale_valid_i <= 1'b1;
|
||||
scale_a_i <= rd_data_0;
|
||||
scale_issue_cnt <= scale_issue_cnt + 9'd1;
|
||||
end
|
||||
valid_o_r <= 1'b0;
|
||||
if (scale_valid_o) begin
|
||||
coeff_out_r <= scale_product;
|
||||
valid_o_r <= 1'b1;
|
||||
scale_emit_cnt <= scale_emit_cnt + 9'd1;
|
||||
end
|
||||
end
|
||||
|
||||
if (state == S_DONE) begin
|
||||
load_cnt <= 8'd0;
|
||||
out_rptr <= 9'd0; out_cnt <= 9'd0;
|
||||
scale_rptr <= 9'd0; scale_issue_cnt <= 9'd0; scale_emit_cnt <= 9'd0;
|
||||
layer_issue_done <= 1'b0; bf_inflight <= 6'd0;
|
||||
valid_o_r <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
144
rtl/ip/mlkem/poly_mul/basecase_mul_pipe.v
Normal 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;
|
||||
(* use_dsp = "no" *) 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;
|
||||
(* use_dsp = "no" *) 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.
|
||||
(* use_dsp = "no" *) 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;
|
||||
(* use_dsp = "no" *) 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
|
||||
@@ -1,28 +1,30 @@
|
||||
// poly_mul_sync.v - Synchronous NTT-domain polynomial multiplier
|
||||
// poly_mul_sync.v - Synchronous NTT-domain polynomial multiplier (BRAM storage)
|
||||
//
|
||||
// Computes pointwise (Karatsuba-like base-case) multiplication of two
|
||||
// 256-coefficient NTT-domain polynomials.
|
||||
//
|
||||
// Operation flow:
|
||||
// IDLE → LOAD (256× A+B pairs) → COMP_CALC (read+compute, 1 cycle)
|
||||
// → COMP_C0 (output c0) → COMP_C1 (output c1) → DONE → IDLE
|
||||
// IDLE -> LOAD (256x A+B pairs) -> RUN -> IDLE
|
||||
//
|
||||
// The LOAD phase accepts both A and B coefficients simultaneously
|
||||
// (one pair per cycle) on coeff_a_in/coeff_b_in.
|
||||
// Coefficient storage moved from 256x12 LUT register arrays to four sd_bram
|
||||
// banks (A_even/A_odd/B_even/B_odd, each 128x12): the base-case reads
|
||||
// mem[2k] and mem[2k+1] together, so an even/odd split gives each bank a single
|
||||
// read port. This removes the large multi-port LUT mux (~8k LUT) and the long
|
||||
// BRAM->register-file routing that was the mlkem_clk critical path.
|
||||
//
|
||||
// The COMPUTE phase outputs the 256 result coefficients one per cycle
|
||||
// via valid/ready handshake on coeff_out/valid_o/ready_i.
|
||||
// RUN issues one base-case every two cycles. sd_bram reads are synchronous
|
||||
// (1-cycle latency); the 2-cycle cadence absorbs it (address presented on the
|
||||
// gap cycle, data consumed on the issue cycle). A one-cycle priming gap is
|
||||
// inserted at LOAD->RUN so the first base-case's operands are ready.
|
||||
//
|
||||
// Memory: 256×12-bit register arrays for A and B coefficients.
|
||||
//
|
||||
// Interface:
|
||||
// Interface (unchanged):
|
||||
// clk, rst_n - Clock, active-low reset
|
||||
// coeff_a_in[11:0]- Polynomial A coefficient input
|
||||
// coeff_b_in[11:0]- Polynomial B coefficient input
|
||||
// valid_i - Input valid
|
||||
// ready_o - Ready to accept input (high in IDLE/LOAD)
|
||||
// coeff_out[11:0] - Result coefficient output
|
||||
// valid_o - Output valid (high in COMP_C0/COMP_C1)
|
||||
// valid_o - Output valid during RUN output phase
|
||||
// ready_i - Output consumer ready
|
||||
|
||||
module poly_mul_sync (
|
||||
@@ -36,129 +38,172 @@ module poly_mul_sync (
|
||||
input ready_i
|
||||
);
|
||||
|
||||
// State definitions
|
||||
localparam S_IDLE = 3'd0;
|
||||
localparam S_LOAD = 3'd1;
|
||||
localparam S_COMP_CALC = 3'd2;
|
||||
localparam S_COMP_C0 = 3'd3;
|
||||
localparam S_COMP_C1 = 3'd4;
|
||||
localparam S_DONE = 3'd5;
|
||||
localparam S_IDLE = 3'd0;
|
||||
localparam S_LOAD = 3'd1;
|
||||
localparam S_RUN = 3'd2;
|
||||
|
||||
reg [2:0] state, next_state;
|
||||
|
||||
// Coefficient storage (register arrays)
|
||||
reg [11:0] mem_A [0:255];
|
||||
reg [11:0] mem_B [0:255];
|
||||
|
||||
// Counters
|
||||
reg [7:0] load_cnt; // 0..256 for loading 256 pairs
|
||||
reg [6:0] comp_k; // 0..127, current base-case index
|
||||
reg [7:0] issue_cnt; // 0..128, issued base-cases
|
||||
reg [7:0] out_cnt; // 0..255, consumed output coefficients
|
||||
reg issue_gap; // spaces base-case requests to match c0/c1 output
|
||||
reg out_phase; // 0=c0, 1=c1
|
||||
reg out_valid_r;
|
||||
|
||||
// Registered basecase_mul results
|
||||
reg [11:0] bc_a0_reg, bc_a1_reg;
|
||||
reg [11:0] bc_b0_reg, bc_b1_reg;
|
||||
reg [11:0] bc_zeta_reg;
|
||||
reg bc_valid_reg;
|
||||
reg [11:0] c0_reg, c1_reg;
|
||||
|
||||
// Combinational read signals for COMP_CALC
|
||||
wire [7:0] addr_even = {comp_k, 1'b0}; // comp_k * 2 (7+1 = 8 bits)
|
||||
wire [7:0] addr_odd = {comp_k, 1'b1}; // comp_k * 2 + 1
|
||||
wire [11:0] mem_a0 = mem_A[addr_even];
|
||||
wire [11:0] mem_a1 = mem_A[addr_odd];
|
||||
wire [11:0] mem_b0 = mem_B[addr_even];
|
||||
wire [11:0] mem_b1 = mem_B[addr_odd];
|
||||
// ---- Coefficient storage: even/odd banked sd_bram ----
|
||||
// A_even[k]=mem_A[2k], A_odd[k]=mem_A[2k+1]; same for B. Read index during
|
||||
// RUN is issue_k; write index during LOAD is load_cnt>>1 routed by load_cnt[0].
|
||||
wire [6:0] issue_k = issue_cnt[6:0]; // 0..127 read index
|
||||
|
||||
wire load_fire = ((state == S_IDLE) || (state == S_LOAD)) && valid_i && ready_o;
|
||||
wire [6:0] wr_local = load_cnt[7:1]; // load_cnt/2
|
||||
wire wr_odd = load_cnt[0];
|
||||
|
||||
wire we_even = load_fire && !wr_odd;
|
||||
wire we_odd = load_fire && wr_odd;
|
||||
|
||||
wire [11:0] mem_a0, mem_a1, mem_b0, mem_b1; // sd_bram registered read outputs
|
||||
sd_bram #(.W(12), .D(128), .A(7)) u_a_even (
|
||||
.clk(clk), .rd_addr(issue_k), .rd_data(mem_a0),
|
||||
.wr_en(we_even), .wr_addr(wr_local), .wr_data(coeff_a_in)
|
||||
);
|
||||
sd_bram #(.W(12), .D(128), .A(7)) u_a_odd (
|
||||
.clk(clk), .rd_addr(issue_k), .rd_data(mem_a1),
|
||||
.wr_en(we_odd), .wr_addr(wr_local), .wr_data(coeff_a_in)
|
||||
);
|
||||
sd_bram #(.W(12), .D(128), .A(7)) u_b_even (
|
||||
.clk(clk), .rd_addr(issue_k), .rd_data(mem_b0),
|
||||
.wr_en(we_even), .wr_addr(wr_local), .wr_data(coeff_b_in)
|
||||
);
|
||||
sd_bram #(.W(12), .D(128), .A(7)) u_b_odd (
|
||||
.clk(clk), .rd_addr(issue_k), .rd_data(mem_b1),
|
||||
.wr_en(we_odd), .wr_addr(wr_local), .wr_data(coeff_b_in)
|
||||
);
|
||||
|
||||
// Zeta ROM
|
||||
wire [11:0] zeta;
|
||||
poly_mul_zeta_rom u_zeta (
|
||||
.addr (comp_k),
|
||||
.zeta (zeta)
|
||||
);
|
||||
poly_mul_zeta_rom u_zeta (.addr(issue_k), .zeta(zeta));
|
||||
|
||||
// Basecase multiply
|
||||
wire [11:0] bc_c0, bc_c1;
|
||||
basecase_mul u_bc (
|
||||
.a0 (mem_a0),
|
||||
.a1 (mem_a1),
|
||||
.b0 (mem_b0),
|
||||
.b1 (mem_b1),
|
||||
.zeta(zeta),
|
||||
.c0 (bc_c0),
|
||||
.c1 (bc_c1)
|
||||
wire bc_vo;
|
||||
basecase_mul_pipe u_bc (
|
||||
.clk(clk), .rst_n(rst_n),
|
||||
.valid_i(bc_valid_reg),
|
||||
.a0(bc_a0_reg), .a1(bc_a1_reg),
|
||||
.b0(bc_b0_reg), .b1(bc_b1_reg),
|
||||
.zeta(bc_zeta_reg),
|
||||
.c0(bc_c0), .c1(bc_c1),
|
||||
.valid_o(bc_vo)
|
||||
);
|
||||
|
||||
// Output interface
|
||||
assign ready_o = (state == S_IDLE) || (state == S_LOAD);
|
||||
assign valid_o = (state == S_COMP_C0) || (state == S_COMP_C1);
|
||||
assign coeff_out = (state == S_COMP_C0) ? c0_reg : c1_reg;
|
||||
assign valid_o = out_valid_r;
|
||||
assign coeff_out = out_phase ? c1_reg : c0_reg;
|
||||
|
||||
// State transition logic (combinational)
|
||||
always @* begin
|
||||
next_state = state;
|
||||
case (state)
|
||||
S_IDLE: if (valid_i && ready_o) next_state = S_LOAD;
|
||||
S_LOAD: if (load_cnt >= 255 && valid_i && ready_o)
|
||||
next_state = S_COMP_CALC;
|
||||
S_COMP_CALC: next_state = S_COMP_C0;
|
||||
S_COMP_C0: if (valid_o && ready_i) next_state = S_COMP_C1;
|
||||
S_COMP_C1: if (valid_o && ready_i) begin
|
||||
if (comp_k >= 127) next_state = S_DONE;
|
||||
else next_state = S_COMP_CALC;
|
||||
end
|
||||
S_DONE: next_state = S_IDLE;
|
||||
S_LOAD: if (load_cnt >= 8'd255 && valid_i && ready_o)
|
||||
next_state = S_RUN;
|
||||
S_RUN: if (valid_o && ready_i && out_cnt == 8'd255)
|
||||
next_state = S_IDLE;
|
||||
default: next_state = S_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// Sequential logic
|
||||
integer i;
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
state <= S_IDLE;
|
||||
load_cnt <= 8'd0;
|
||||
comp_k <= 7'd0;
|
||||
c0_reg <= 12'd0;
|
||||
c1_reg <= 12'd0;
|
||||
for (i = 0; i < 256; i = i + 1) begin
|
||||
mem_A[i] = 12'd0;
|
||||
mem_B[i] = 12'd0;
|
||||
end
|
||||
issue_cnt <= 8'd0;
|
||||
out_cnt <= 8'd0;
|
||||
issue_gap <= 1'b0;
|
||||
out_phase <= 1'b0;
|
||||
out_valid_r <= 1'b0;
|
||||
bc_a0_reg <= 12'd0; bc_a1_reg <= 12'd0;
|
||||
bc_b0_reg <= 12'd0; bc_b1_reg <= 12'd0;
|
||||
bc_zeta_reg <= 12'd0; bc_valid_reg <= 1'b0;
|
||||
c0_reg <= 12'd0; c1_reg <= 12'd0;
|
||||
end else begin
|
||||
state <= next_state;
|
||||
bc_valid_reg <= 1'b0;
|
||||
|
||||
// ---- LOAD phase ----
|
||||
// First coefficient captured on IDLE → LOAD transition
|
||||
// ---- LOAD phase (writes routed to even/odd banks combinationally) ----
|
||||
if (state == S_IDLE && valid_i && ready_o) begin
|
||||
mem_A[0] <= coeff_a_in;
|
||||
mem_B[0] <= coeff_b_in;
|
||||
load_cnt <= 8'd1;
|
||||
issue_cnt <= 8'd0;
|
||||
out_cnt <= 8'd0;
|
||||
issue_gap <= 1'b0;
|
||||
out_phase <= 1'b0;
|
||||
out_valid_r <= 1'b0;
|
||||
end
|
||||
|
||||
// Subsequent coefficients in LOAD state
|
||||
if (state == S_LOAD && valid_i && ready_o) begin
|
||||
mem_A[load_cnt] <= coeff_a_in;
|
||||
mem_B[load_cnt] <= coeff_b_in;
|
||||
load_cnt <= load_cnt + 8'd1;
|
||||
if (load_cnt >= 8'd255) begin
|
||||
issue_cnt <= 8'd0;
|
||||
out_cnt <= 8'd0;
|
||||
issue_gap <= 1'b1; // priming gap: present issue_k=0 addr first
|
||||
out_phase <= 1'b0;
|
||||
out_valid_r <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// ---- COMPUTE phase ----
|
||||
// COMP_CALC: capture basecase_mul results
|
||||
if (state == S_COMP_CALC) begin
|
||||
c0_reg <= bc_c0;
|
||||
c1_reg <= bc_c1;
|
||||
// Issue one base-case every two cycles. On the gap cycle the sd_bram
|
||||
// address (issue_k) settles; on the issue cycle its registered output
|
||||
// (mem_a0/a1/b0/b1) is captured into the base-case input registers.
|
||||
if (state == S_RUN) begin
|
||||
if (issue_cnt < 8'd128) begin
|
||||
if (!issue_gap) begin
|
||||
bc_a0_reg <= mem_a0;
|
||||
bc_a1_reg <= mem_a1;
|
||||
bc_b0_reg <= mem_b0;
|
||||
bc_b1_reg <= mem_b1;
|
||||
bc_zeta_reg <= zeta;
|
||||
bc_valid_reg <= 1'b1;
|
||||
issue_cnt <= issue_cnt + 8'd1;
|
||||
issue_gap <= 1'b1;
|
||||
end else begin
|
||||
issue_gap <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
if (out_valid_r && ready_i) begin
|
||||
out_cnt <= out_cnt + 8'd1;
|
||||
if (out_cnt == 8'd255) begin
|
||||
out_valid_r <= 1'b0;
|
||||
out_phase <= 1'b0;
|
||||
end else if (!out_phase) begin
|
||||
out_phase <= 1'b1;
|
||||
end else begin
|
||||
out_valid_r <= 1'b0;
|
||||
out_phase <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
if (bc_vo) begin
|
||||
c0_reg <= bc_c0;
|
||||
c1_reg <= bc_c1;
|
||||
out_valid_r <= 1'b1;
|
||||
out_phase <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// COMP_C0 → COMP_C1: c0 was consumed, increment comp_k
|
||||
if (state == S_COMP_C0 && valid_o && ready_i) begin
|
||||
// comp_k stays same, c1 still to output
|
||||
end
|
||||
|
||||
// COMP_C1 → COMP_CALC: c1 was consumed, advance to next pair
|
||||
if (state == S_COMP_C1 && valid_o && ready_i) begin
|
||||
comp_k <= comp_k + 7'd1;
|
||||
end
|
||||
|
||||
// ---- DONE → IDLE: reset counters ----
|
||||
if (state == S_DONE) begin
|
||||
if (state == S_RUN && valid_o && ready_i && out_cnt == 8'd255) begin
|
||||
load_cnt <= 8'd0;
|
||||
comp_k <= 7'd0;
|
||||
issue_cnt <= 8'd0;
|
||||
out_cnt <= 8'd0;
|
||||
issue_gap <= 1'b0;
|
||||
out_phase <= 1'b0;
|
||||
out_valid_r <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
// rng_sync.v - 256-bit Galois LFSR PRNG (taps: 255,253,252,247,0)
|
||||
module rng_sync #(
|
||||
parameter [255:0] SEED = 256'hDEADBEEFCAFEBABEFEEDFACEDECAFBAD1234567887654321ABCDEF010FEDCBA9
|
||||
) (
|
||||
input clk,
|
||||
input rst_n,
|
||||
input valid_i,
|
||||
output ready_o,
|
||||
output [255:0] data_o,
|
||||
output valid_o,
|
||||
input ready_i
|
||||
);
|
||||
|
||||
reg [255:0] state;
|
||||
reg valid_r;
|
||||
reg [255:0] lfsr_next;
|
||||
wire feedback;
|
||||
integer i;
|
||||
|
||||
assign ready_o = 1'b1;
|
||||
assign valid_o = valid_r;
|
||||
assign data_o = state;
|
||||
assign feedback = state[0];
|
||||
|
||||
always @(*) begin
|
||||
for (i = 0; i < 255; i = i + 1)
|
||||
lfsr_next[i] = state[i+1];
|
||||
lfsr_next[255] = feedback;
|
||||
lfsr_next[254] = lfsr_next[254] ^ feedback;
|
||||
lfsr_next[252] = lfsr_next[252] ^ feedback;
|
||||
lfsr_next[251] = lfsr_next[251] ^ feedback;
|
||||
lfsr_next[246] = lfsr_next[246] ^ feedback;
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
state <= SEED;
|
||||
valid_r <= 1'b0;
|
||||
end else begin
|
||||
if (valid_r && ready_i)
|
||||
valid_r <= 1'b0;
|
||||
|
||||
if (valid_i) begin
|
||||
state <= lfsr_next;
|
||||
valid_r <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -31,7 +31,6 @@
|
||||
`include "defines.vh"
|
||||
|
||||
/* verilator lint_off UNUSED */
|
||||
(* use_dsp = "no" *)
|
||||
module sample_ntt_sync #(parameter K = 4) (
|
||||
/* verilator lint_on UNUSED */
|
||||
input clk,
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
`include "defines.vh"
|
||||
|
||||
/* verilator lint_off UNUSED */
|
||||
(* use_dsp = "no" *)
|
||||
module sample_ntt_sync_shared #(parameter K = 4) (
|
||||
/* verilator lint_on UNUSED */
|
||||
input clk,
|
||||
|
||||
@@ -100,6 +100,16 @@ module sha3_top (
|
||||
reg mb_last_r; // captured last-block flag
|
||||
reg [255:0] mb_digest_r; // latched 256-bit digest (sticky in MB_DONE)
|
||||
|
||||
// ================================================================
|
||||
// Keccak core
|
||||
// ================================================================
|
||||
wire kc_valid_i;
|
||||
/* verilator lint_off UNUSED */
|
||||
wire [1599:0] kc_state_o;
|
||||
wire kc_ready_o;
|
||||
/* verilator lint_on UNUSED */
|
||||
wire kc_valid_o;
|
||||
|
||||
// XOR the incoming block into the low 1088 bits (rate) of the state.
|
||||
wire [1599:0] mb_xored;
|
||||
assign mb_xored = mb_state_r ^ {{(1600-1088){1'b0}}, mb_block_i};
|
||||
@@ -119,16 +129,6 @@ module sha3_top (
|
||||
endcase
|
||||
end
|
||||
|
||||
// ================================================================
|
||||
// Keccak core
|
||||
// ================================================================
|
||||
wire kc_valid_i;
|
||||
/* verilator lint_off UNUSED */
|
||||
wire [1599:0] kc_state_o;
|
||||
wire kc_ready_o;
|
||||
/* verilator lint_on UNUSED */
|
||||
wire kc_valid_o;
|
||||
|
||||
// Keccak input: multi-block xored state when mb_en, else single-block absorb.
|
||||
wire [1599:0] kc_state_i_mux;
|
||||
assign kc_state_i_mux = mb_en ? mb_xored : absorb_state;
|
||||
|
||||
312
rtl/ip/mlkem/top/fft_mlkem_axi_slave.v
Normal file
@@ -0,0 +1,312 @@
|
||||
// Shared AXI slave for the legacy FFT accelerator and the ML-KEM accelerator.
|
||||
//
|
||||
// Both software stacks use the same base address, 0xbf400000. Their internal
|
||||
// maps do not overlap:
|
||||
// ML-KEM: 0x0000..0x3fff
|
||||
// FFT: 0x8000..0xcfff
|
||||
// Route the low ML-KEM block to ML-KEM and the remaining accelerator window to
|
||||
// FFT. ML-KEM runs in the same clock domain as this AXI slave.
|
||||
(* use_dsp = "no" *) module fft_mlkem_axi_slave (
|
||||
input clk,
|
||||
input resetn,
|
||||
|
||||
input [4:0] s_axi_awid,
|
||||
input [31:0] s_axi_awaddr,
|
||||
input [7:0] s_axi_awlen,
|
||||
input [2:0] s_axi_awsize,
|
||||
input [1:0] s_axi_awburst,
|
||||
input s_axi_awlock,
|
||||
input [3:0] s_axi_awcache,
|
||||
input [2:0] s_axi_awprot,
|
||||
input s_axi_awvalid,
|
||||
output s_axi_awready,
|
||||
|
||||
input [4:0] s_axi_wid,
|
||||
input [31:0] s_axi_wdata,
|
||||
input [3:0] s_axi_wstrb,
|
||||
input s_axi_wlast,
|
||||
input s_axi_wvalid,
|
||||
output s_axi_wready,
|
||||
|
||||
output [4:0] s_axi_bid,
|
||||
output [1:0] s_axi_bresp,
|
||||
output s_axi_bvalid,
|
||||
input s_axi_bready,
|
||||
|
||||
input [4:0] s_axi_arid,
|
||||
input [31:0] s_axi_araddr,
|
||||
input [7:0] s_axi_arlen,
|
||||
input [2:0] s_axi_arsize,
|
||||
input [1:0] s_axi_arburst,
|
||||
input s_axi_arlock,
|
||||
input [3:0] s_axi_arcache,
|
||||
input [2:0] s_axi_arprot,
|
||||
input s_axi_arvalid,
|
||||
output s_axi_arready,
|
||||
|
||||
output [4:0] s_axi_rid,
|
||||
output [31:0] s_axi_rdata,
|
||||
output [1:0] s_axi_rresp,
|
||||
output s_axi_rlast,
|
||||
output s_axi_rvalid,
|
||||
input s_axi_rready,
|
||||
|
||||
output fft_finish,
|
||||
output mlkem_intr
|
||||
);
|
||||
|
||||
localparam SEL_MLKEM = 2'd0;
|
||||
localparam SEL_FFT = 2'd1;
|
||||
|
||||
wire aw_to_mlkem = (s_axi_awaddr[15:12] <= 4'h3);
|
||||
wire ar_to_mlkem = (s_axi_araddr[15:12] <= 4'h3);
|
||||
|
||||
wire [1:0] aw_sel = aw_to_mlkem ? SEL_MLKEM : SEL_FFT;
|
||||
wire [1:0] ar_sel = ar_to_mlkem ? SEL_MLKEM : SEL_FFT;
|
||||
|
||||
reg [1:0] write_sel;
|
||||
reg write_active;
|
||||
reg [1:0] read_sel;
|
||||
reg read_active;
|
||||
|
||||
wire mlkem_awready, mlkem_wready, mlkem_bvalid;
|
||||
wire [4:0] mlkem_bid;
|
||||
wire [1:0] mlkem_bresp;
|
||||
wire mlkem_arready, mlkem_rvalid, mlkem_rlast;
|
||||
wire [4:0] mlkem_rid;
|
||||
wire [31:0] mlkem_rdata;
|
||||
wire [1:0] mlkem_rresp;
|
||||
|
||||
wire mlkem_m_awvalid;
|
||||
wire mlkem_m_awready;
|
||||
wire [31:0] mlkem_m_awaddr;
|
||||
wire [4:0] mlkem_m_awid;
|
||||
wire [7:0] mlkem_m_awlen;
|
||||
wire [2:0] mlkem_m_awsize;
|
||||
wire [1:0] mlkem_m_awburst;
|
||||
wire [0:0] mlkem_m_awlock;
|
||||
wire [3:0] mlkem_m_awcache;
|
||||
wire [2:0] mlkem_m_awprot;
|
||||
wire mlkem_m_wvalid;
|
||||
wire mlkem_m_wready;
|
||||
wire [31:0] mlkem_m_wdata;
|
||||
wire [3:0] mlkem_m_wstrb;
|
||||
wire mlkem_m_wlast;
|
||||
wire mlkem_m_bvalid;
|
||||
wire mlkem_m_bready;
|
||||
wire [4:0] mlkem_m_bid;
|
||||
wire [1:0] mlkem_m_bresp;
|
||||
wire mlkem_m_arvalid;
|
||||
wire mlkem_m_arready;
|
||||
wire [31:0] mlkem_m_araddr;
|
||||
wire [4:0] mlkem_m_arid;
|
||||
wire [7:0] mlkem_m_arlen;
|
||||
wire [2:0] mlkem_m_arsize;
|
||||
wire [1:0] mlkem_m_arburst;
|
||||
wire [0:0] mlkem_m_arlock;
|
||||
wire [3:0] mlkem_m_arcache;
|
||||
wire [2:0] mlkem_m_arprot;
|
||||
wire mlkem_m_rvalid;
|
||||
wire mlkem_m_rready;
|
||||
wire [31:0] mlkem_m_rdata;
|
||||
wire [4:0] mlkem_m_rid;
|
||||
wire [1:0] mlkem_m_rresp;
|
||||
wire mlkem_m_rlast;
|
||||
wire mlkem_intr_m;
|
||||
|
||||
wire fft_awready, fft_wready, fft_bvalid;
|
||||
wire [4:0] fft_bid;
|
||||
wire [1:0] fft_bresp;
|
||||
wire fft_arready, fft_rvalid, fft_rlast;
|
||||
wire [4:0] fft_rid;
|
||||
wire [31:0] fft_rdata;
|
||||
wire [1:0] fft_rresp;
|
||||
|
||||
wire [1:0] sel_w = write_active ? write_sel : aw_sel;
|
||||
wire [1:0] sel_r = read_active ? read_sel : ar_sel;
|
||||
|
||||
assign s_axi_awready = !write_active && (
|
||||
(aw_sel == SEL_MLKEM) ? mlkem_awready :
|
||||
fft_awready);
|
||||
assign s_axi_wready = (sel_w == SEL_MLKEM) ? mlkem_wready :
|
||||
fft_wready;
|
||||
assign s_axi_bvalid = (sel_w == SEL_MLKEM) ? mlkem_bvalid :
|
||||
fft_bvalid;
|
||||
assign s_axi_bid = (sel_w == SEL_MLKEM) ? mlkem_bid :
|
||||
fft_bid;
|
||||
assign s_axi_bresp = (sel_w == SEL_MLKEM) ? mlkem_bresp :
|
||||
fft_bresp;
|
||||
|
||||
assign s_axi_arready = !read_active && (
|
||||
(ar_sel == SEL_MLKEM) ? mlkem_arready :
|
||||
fft_arready);
|
||||
assign s_axi_rvalid = (sel_r == SEL_MLKEM) ? mlkem_rvalid :
|
||||
fft_rvalid;
|
||||
assign s_axi_rlast = (sel_r == SEL_MLKEM) ? mlkem_rlast :
|
||||
fft_rlast;
|
||||
assign s_axi_rid = (sel_r == SEL_MLKEM) ? mlkem_rid :
|
||||
fft_rid;
|
||||
assign s_axi_rdata = (sel_r == SEL_MLKEM) ? mlkem_rdata :
|
||||
fft_rdata;
|
||||
assign s_axi_rresp = (sel_r == SEL_MLKEM) ? mlkem_rresp :
|
||||
fft_rresp;
|
||||
|
||||
always @(posedge clk or negedge resetn) begin
|
||||
if (!resetn) begin
|
||||
write_active <= 1'b0;
|
||||
write_sel <= SEL_MLKEM;
|
||||
read_active <= 1'b0;
|
||||
read_sel <= SEL_MLKEM;
|
||||
end else begin
|
||||
if (!write_active && s_axi_awvalid && s_axi_awready) begin
|
||||
write_active <= 1'b1;
|
||||
write_sel <= aw_sel;
|
||||
end else if (write_active && s_axi_bvalid && s_axi_bready) begin
|
||||
write_active <= 1'b0;
|
||||
end
|
||||
|
||||
if (!read_active && s_axi_arvalid && s_axi_arready) begin
|
||||
read_active <= 1'b1;
|
||||
read_sel <= ar_sel;
|
||||
end else if (read_active && s_axi_rvalid && s_axi_rready && s_axi_rlast) begin
|
||||
read_active <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign mlkem_intr = mlkem_intr_m;
|
||||
|
||||
assign mlkem_awready = mlkem_m_awready;
|
||||
assign mlkem_wready = mlkem_m_wready;
|
||||
assign mlkem_bvalid = mlkem_m_bvalid;
|
||||
assign mlkem_bid = mlkem_m_bid;
|
||||
assign mlkem_bresp = mlkem_m_bresp;
|
||||
assign mlkem_arready = mlkem_m_arready;
|
||||
assign mlkem_rvalid = mlkem_m_rvalid;
|
||||
assign mlkem_rlast = mlkem_m_rlast;
|
||||
assign mlkem_rid = mlkem_m_rid;
|
||||
assign mlkem_rdata = mlkem_m_rdata;
|
||||
assign mlkem_rresp = mlkem_m_rresp;
|
||||
|
||||
assign mlkem_m_awvalid = s_axi_awvalid && !write_active && (aw_sel == SEL_MLKEM);
|
||||
assign mlkem_m_awaddr = s_axi_awaddr;
|
||||
assign mlkem_m_awid = s_axi_awid;
|
||||
assign mlkem_m_awlen = s_axi_awlen;
|
||||
assign mlkem_m_awsize = s_axi_awsize;
|
||||
assign mlkem_m_awburst = s_axi_awburst;
|
||||
assign mlkem_m_awlock = s_axi_awlock;
|
||||
assign mlkem_m_awcache = s_axi_awcache;
|
||||
assign mlkem_m_awprot = s_axi_awprot;
|
||||
assign mlkem_m_wvalid = s_axi_wvalid && (sel_w == SEL_MLKEM);
|
||||
assign mlkem_m_wdata = s_axi_wdata;
|
||||
assign mlkem_m_wstrb = s_axi_wstrb;
|
||||
assign mlkem_m_wlast = s_axi_wlast;
|
||||
assign mlkem_m_bready = s_axi_bready && (sel_w == SEL_MLKEM);
|
||||
assign mlkem_m_arvalid = s_axi_arvalid && !read_active && (ar_sel == SEL_MLKEM);
|
||||
assign mlkem_m_araddr = s_axi_araddr;
|
||||
assign mlkem_m_arid = s_axi_arid;
|
||||
assign mlkem_m_arlen = s_axi_arlen;
|
||||
assign mlkem_m_arsize = s_axi_arsize;
|
||||
assign mlkem_m_arburst = s_axi_arburst;
|
||||
assign mlkem_m_arlock = s_axi_arlock;
|
||||
assign mlkem_m_arcache = s_axi_arcache;
|
||||
assign mlkem_m_arprot = s_axi_arprot;
|
||||
assign mlkem_m_rready = s_axi_rready && (sel_r == SEL_MLKEM);
|
||||
|
||||
mlkem_axi_slave u_mlkem_axi_slave (
|
||||
.clk (clk),
|
||||
.resetn (resetn),
|
||||
|
||||
.s_axi_awid (mlkem_m_awid),
|
||||
.s_axi_awaddr (mlkem_m_awaddr),
|
||||
.s_axi_awlen (mlkem_m_awlen),
|
||||
.s_axi_awsize (mlkem_m_awsize),
|
||||
.s_axi_awburst (mlkem_m_awburst),
|
||||
.s_axi_awlock (mlkem_m_awlock[0]),
|
||||
.s_axi_awcache (mlkem_m_awcache),
|
||||
.s_axi_awprot (mlkem_m_awprot),
|
||||
.s_axi_awvalid (mlkem_m_awvalid),
|
||||
.s_axi_awready (mlkem_m_awready),
|
||||
|
||||
.s_axi_wid (5'd0),
|
||||
.s_axi_wdata (mlkem_m_wdata),
|
||||
.s_axi_wstrb (mlkem_m_wstrb),
|
||||
.s_axi_wlast (mlkem_m_wlast),
|
||||
.s_axi_wvalid (mlkem_m_wvalid),
|
||||
.s_axi_wready (mlkem_m_wready),
|
||||
|
||||
.s_axi_bid (mlkem_m_bid),
|
||||
.s_axi_bresp (mlkem_m_bresp),
|
||||
.s_axi_bvalid (mlkem_m_bvalid),
|
||||
.s_axi_bready (mlkem_m_bready),
|
||||
|
||||
.s_axi_arid (mlkem_m_arid),
|
||||
.s_axi_araddr (mlkem_m_araddr),
|
||||
.s_axi_arlen (mlkem_m_arlen),
|
||||
.s_axi_arsize (mlkem_m_arsize),
|
||||
.s_axi_arburst (mlkem_m_arburst),
|
||||
.s_axi_arlock (mlkem_m_arlock[0]),
|
||||
.s_axi_arcache (mlkem_m_arcache),
|
||||
.s_axi_arprot (mlkem_m_arprot),
|
||||
.s_axi_arvalid (mlkem_m_arvalid),
|
||||
.s_axi_arready (mlkem_m_arready),
|
||||
|
||||
.s_axi_rid (mlkem_m_rid),
|
||||
.s_axi_rdata (mlkem_m_rdata),
|
||||
.s_axi_rresp (mlkem_m_rresp),
|
||||
.s_axi_rlast (mlkem_m_rlast),
|
||||
.s_axi_rvalid (mlkem_m_rvalid),
|
||||
.s_axi_rready (mlkem_m_rready),
|
||||
|
||||
.intr (mlkem_intr_m)
|
||||
);
|
||||
|
||||
fft_controller u_fft_controller (
|
||||
.aclk (clk),
|
||||
.aresetn (resetn),
|
||||
|
||||
.s_awid (s_axi_awid),
|
||||
.s_awaddr (s_axi_awaddr),
|
||||
.s_awlen (s_axi_awlen),
|
||||
.s_awsize (s_axi_awsize),
|
||||
.s_awburst (s_axi_awburst),
|
||||
.s_awlock (s_axi_awlock),
|
||||
.s_awcache (s_axi_awcache),
|
||||
.s_awprot (s_axi_awprot),
|
||||
.s_awvalid (s_axi_awvalid && !write_active && (aw_sel == SEL_FFT)),
|
||||
.s_awready (fft_awready),
|
||||
|
||||
.s_wid (s_axi_wid),
|
||||
.s_wdata (s_axi_wdata),
|
||||
.s_wstrb (s_axi_wstrb),
|
||||
.s_wlast (s_axi_wlast),
|
||||
.s_wvalid (s_axi_wvalid && (sel_w == SEL_FFT)),
|
||||
.s_wready (fft_wready),
|
||||
|
||||
.s_bid (fft_bid),
|
||||
.s_bresp (fft_bresp),
|
||||
.s_bvalid (fft_bvalid),
|
||||
.s_bready (s_axi_bready && (sel_w == SEL_FFT)),
|
||||
|
||||
.s_arid (s_axi_arid),
|
||||
.s_araddr (s_axi_araddr),
|
||||
.s_arlen (s_axi_arlen),
|
||||
.s_arsize (s_axi_arsize),
|
||||
.s_arburst (s_axi_arburst),
|
||||
.s_arlock (s_axi_arlock),
|
||||
.s_arcache (s_axi_arcache),
|
||||
.s_arprot (s_axi_arprot),
|
||||
.s_arvalid (s_axi_arvalid && !read_active && (ar_sel == SEL_FFT)),
|
||||
.s_arready (fft_arready),
|
||||
|
||||
.s_rid (fft_rid),
|
||||
.s_rdata (fft_rdata),
|
||||
.s_rresp (fft_rresp),
|
||||
.s_rlast (fft_rlast),
|
||||
.s_rvalid (fft_rvalid),
|
||||
.s_rready (s_axi_rready && (sel_r == SEL_FFT)),
|
||||
|
||||
.fft_finish (fft_finish)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -1,16 +1,12 @@
|
||||
// mlkem_axi_slave.v — AXI4 (burst) slave wrapper for the ML-KEM core.
|
||||
// Makes the ML-KEM accelerator (KeyGen / Encaps / Decaps) CPU-controllable.
|
||||
//
|
||||
// The bus runs at sys_clk (50 MHz). The ML-KEM core cannot close timing at
|
||||
// 50 MHz, so it is clocked by mlkem_clk = sys_clk / 2 (25 MHz), produced by a
|
||||
// toggle flip-flop in this wrapper. mlkem_clk is a phase-aligned synchronous
|
||||
// divide of sys_clk; every signal crossing between the two domains still goes
|
||||
// through an explicit synchronizer or toggle handshake.
|
||||
// NOTE (FPGA): for real silicon route mlkem_clk through a BUFG/BUFGCE rather
|
||||
// than a logic-generated net; kept as a plain toggle here for portability.
|
||||
// This slave and mlkem_top run in the same clock domain as the shared
|
||||
// FFT/ML-KEM AXI window.
|
||||
//
|
||||
// Register map (byte offsets from base, e.g. virtual 0xbf400000):
|
||||
// 0x000 CTRL W bit0 = start (launches op selected in CONFIG)
|
||||
// bit1 = soft_reset (resets ML-KEM core state)
|
||||
// 0x004 STATUS R bit0 busy, bit1 done, bit2 preload_busy
|
||||
// W1C write bit1=1 to clear the latched done flag
|
||||
// 0x008 CONFIG RW [2:0] k (2/3/4), [5:4] op (0=KeyGen 1=Encaps 2=Decaps)
|
||||
@@ -24,9 +20,14 @@
|
||||
// 0x10C RDBK_SEL RW 0=ek 1=dk_pke 2=full-dk 3=ciphertext
|
||||
// 0x110 RDBK_ADDR RW output byte index
|
||||
// 0x114 RDBK_DATA R selected readback-tap byte (low 8 bits)
|
||||
// 0x1000..0x1FFF EK W: preload ek_in, R: read generated ek
|
||||
// 0x2000..0x2FFF DK W: preload dk_in, R: read generated full dk
|
||||
// 0x3000..0x3FFF CT W: preload c_in, R: read generated ciphertext
|
||||
|
||||
|
||||
module mlkem_axi_slave (
|
||||
input clk, // sys_clk (AXI bus clock, 50 MHz)
|
||||
input resetn, // sys_resetn (active low, already synchronized)
|
||||
input clk,
|
||||
input resetn, // active low
|
||||
|
||||
// AXI Write Address Channel
|
||||
input [4:0] s_axi_awid,
|
||||
@@ -94,6 +95,9 @@ module mlkem_axi_slave (
|
||||
localparam ADDR_RDB_SEL = 12'h10C;
|
||||
localparam ADDR_RDB_ADR = 12'h110;
|
||||
localparam ADDR_RDB_DAT = 12'h114;
|
||||
localparam WIN_EK = 4'h1;
|
||||
localparam WIN_DK = 4'h2;
|
||||
localparam WIN_CT = 4'h3;
|
||||
|
||||
assign s_axi_bresp = 2'b00;
|
||||
assign s_axi_rresp = 2'b00;
|
||||
@@ -111,21 +115,43 @@ module mlkem_axi_slave (
|
||||
end
|
||||
endfunction
|
||||
|
||||
// ==========================================
|
||||
// mlkem_clk = sys_clk / 2 (25 MHz) via toggle FF.
|
||||
// ==========================================
|
||||
reg mlkem_clk;
|
||||
always @(posedge clk or negedge resetn) begin
|
||||
if (!resetn) mlkem_clk <= 1'b0;
|
||||
else mlkem_clk <= ~mlkem_clk;
|
||||
end
|
||||
// Reset for the mlkem domain: reuse sys_resetn (async-assert, and the core's
|
||||
// own rst_n is sampled on mlkem_clk edges).
|
||||
wire mlkem_rstn = resetn;
|
||||
function [7:0] select_byte;
|
||||
input [31:0] word;
|
||||
input [1:0] lane;
|
||||
begin
|
||||
case (lane)
|
||||
2'd0: select_byte = word[7:0];
|
||||
2'd1: select_byte = word[15:8];
|
||||
2'd2: select_byte = word[23:16];
|
||||
default: select_byte = word[31:24];
|
||||
endcase
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [1:0] window_preload_sel;
|
||||
input [3:0] window;
|
||||
begin
|
||||
case (window)
|
||||
WIN_DK: window_preload_sel = 2'd1;
|
||||
WIN_CT: window_preload_sel = 2'd2;
|
||||
default: window_preload_sel = 2'd0;
|
||||
endcase
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [1:0] window_readback_sel;
|
||||
input [3:0] window;
|
||||
begin
|
||||
case (window)
|
||||
WIN_DK: window_readback_sel = 2'd2; // full dk
|
||||
WIN_CT: window_readback_sel = 2'd3; // ciphertext
|
||||
default: window_readback_sel = 2'd0; // ek
|
||||
endcase
|
||||
end
|
||||
endfunction
|
||||
|
||||
// ==========================================
|
||||
// sys_clk-domain config / data registers (quasi-static; fed to the core
|
||||
// combinationally — written long before start, stable across the op).
|
||||
// AXI/core clock-domain config / data registers.
|
||||
// ==========================================
|
||||
reg [2:0] cfg_k; // 2/3/4
|
||||
reg [1:0] cfg_op; // 0=KeyGen 1=Encaps 2=Decaps
|
||||
@@ -147,72 +173,101 @@ module mlkem_axi_slave (
|
||||
reg [11:0] rdb_addr; // output byte index
|
||||
|
||||
// ==========================================
|
||||
// CDC: start pulse (sys toggle -> mlkem edge-detect -> 1-cyc start_i)
|
||||
// Start pulse: CTRL.start flips a toggle, edge-detected into start_i.
|
||||
// ==========================================
|
||||
reg start_tg; // sys-domain toggle, flips on CTRL.start write
|
||||
reg [2:0] start_sync; // mlkem-domain 2FF sync (+1 for edge)
|
||||
wire mlkem_start = start_sync[2] ^ start_sync[1]; // 1 mlkem_clk pulse
|
||||
wire mlkem_start = start_sync[2] ^ start_sync[1]; // 1 clk pulse
|
||||
|
||||
// ==========================================
|
||||
// CDC: busy / done back to sys
|
||||
// Software reset pulse: CTRL.soft_reset flips a toggle and stretches reset.
|
||||
// ==========================================
|
||||
wire core_busy; // busy_o (mlkem domain)
|
||||
wire core_done; // done_o pulse (mlkem domain)
|
||||
reg done_latch; // sticky done in mlkem domain
|
||||
reg [1:0] busy_sync; // -> sys
|
||||
reg [1:0] done_sync; // -> sys
|
||||
// done-clear: sys toggle -> mlkem edge -> clears done_latch
|
||||
reg dclr_tg; // sys-domain toggle (STATUS W1C of done)
|
||||
reg [2:0] dclr_sync; // mlkem-domain 2FF sync (+1 for edge)
|
||||
reg srst_tg; // flips on CTRL.soft_reset
|
||||
reg [2:0] srst_sync; // edge detector shift register
|
||||
reg [3:0] srst_cnt; // reset stretcher in clk domain
|
||||
wire mlkem_srst_edge = srst_sync[2] ^ srst_sync[1];
|
||||
wire mlkem_srst_active = (srst_cnt != 4'd0);
|
||||
wire core_resetn = resetn && !mlkem_srst_active;
|
||||
|
||||
// ==========================================
|
||||
// Busy / done status.
|
||||
// ==========================================
|
||||
wire core_busy;
|
||||
wire core_done;
|
||||
reg done_latch;
|
||||
reg [1:0] busy_sync;
|
||||
reg [1:0] done_sync;
|
||||
// done-clear: STATUS W1C flips a toggle, edge-detected to clear done_latch.
|
||||
reg dclr_tg;
|
||||
reg [2:0] dclr_sync;
|
||||
wire mlkem_dclr = dclr_sync[2] ^ dclr_sync[1];
|
||||
|
||||
// ==========================================
|
||||
// CDC: preload byte write handshake.
|
||||
// sys: latch {sel,addr,byte}, flip pre_req_tg, hold wready low.
|
||||
// mlkem: 2FF sync pre_req_tg, on edge pulse the selected *_in_we 1 cycle,
|
||||
// flip pre_ack_tg.
|
||||
// sys: 2FF sync pre_ack_tg, on edge release the bus (addr++).
|
||||
// Preload byte write handshake.
|
||||
// Latch {sel,addr,byte}, flip pre_req_tg, pulse the selected *_in_we for
|
||||
// one cycle, then flip pre_ack_tg to release the AXI write beat.
|
||||
// ==========================================
|
||||
reg pre_req_tg; // sys toggle: a byte is pending
|
||||
reg [2:0] pre_req_sync; // mlkem 2FF (+1 for edge)
|
||||
reg pre_req_tg; // a byte is pending
|
||||
reg [2:0] pre_req_sync; // edge detector shift register
|
||||
wire mlkem_pre_we = pre_req_sync[2] ^ pre_req_sync[1];
|
||||
reg pre_ack_tg; // mlkem toggle: byte consumed
|
||||
reg [2:0] pre_ack_sync; // sys 2FF (+1 for edge)
|
||||
reg pre_ack_tg; // byte consumed
|
||||
reg [2:0] pre_ack_sync; // edge detector shift register
|
||||
wire pre_ack_edge = pre_ack_sync[2] ^ pre_ack_sync[1];
|
||||
reg pre_busy; // sys: a preload handshake is in flight
|
||||
// latched byte/port for the in-flight preload (sys, stable while pre_busy)
|
||||
reg pre_busy; // a preload handshake is in flight
|
||||
// latched byte/port for the in-flight preload, stable while pre_busy
|
||||
reg [1:0] pre_sel_l;
|
||||
reg [11:0] pre_addr_l;
|
||||
reg [7:0] pre_byte_l;
|
||||
reg pre_auto_inc_l;
|
||||
|
||||
// ==========================================
|
||||
// Bulk readback byte handshake.
|
||||
// Hold {sel,addr}, flip rdb_req_tg, let the BRAM read settle, latch one
|
||||
// byte, then flip rdb_ack_tg.
|
||||
// ==========================================
|
||||
reg rdb_req_tg; // one readback byte request
|
||||
reg [2:0] rdb_req_sync; // edge detector shift register
|
||||
wire mlkem_rdb_req = rdb_req_sync[2] ^ rdb_req_sync[1];
|
||||
reg rdb_ack_tg; // readback byte ready
|
||||
reg [2:0] rdb_ack_sync; // edge detector shift register
|
||||
wire rdb_ack_edge = rdb_ack_sync[2] ^ rdb_ack_sync[1];
|
||||
reg [1:0] rdb_req_sel_l; // stable while request in flight
|
||||
reg [11:0] rdb_req_addr_l; // stable while request in flight
|
||||
reg [1:0] rdb_sel_m; // captured request
|
||||
reg [11:0] rdb_addr_m; // captured request
|
||||
reg [1:0] rdb_wait_m; // waits for BRAM registered read
|
||||
reg rdb_busy_m;
|
||||
reg [7:0] rdb_data_m; // held stable until next ack
|
||||
|
||||
// ==========================================
|
||||
// mlkem_top instance
|
||||
// ==========================================
|
||||
wire [7:0] dbg_byte_o, dbg_dk_o, dbg_ct_o;
|
||||
wire [255:0] ss_o;
|
||||
wire dbg_byte_sel = (rdb_sel == 2'd1); // 0=ek, 1=dk_pke
|
||||
wire [1:0] eff_rdb_sel = rdb_busy_m ? rdb_sel_m : rdb_sel;
|
||||
wire [11:0] eff_rdb_addr = rdb_busy_m ? rdb_addr_m : rdb_addr;
|
||||
wire dbg_byte_sel = (eff_rdb_sel == 2'd1); // 0=ek, 1=dk_pke
|
||||
// The core's ek/dkp read-address muxes give dbg_dk_idx_i priority over
|
||||
// dbg_byte_idx_i whenever it lands in the ek (768..1567) or dk_pke (<768)
|
||||
// region (mlkem_top: ek_rd_addr / dkp_rd_addr). So only drive dbg_dk_idx_i
|
||||
// with the real index during a full-dk readback (rdb_sel==2); otherwise hold
|
||||
// it out of range (0xFFF) so an ek/dk_pke readback isn't corrupted.
|
||||
wire [11:0] dbg_dk_idx = (rdb_sel == 2'd2) ? rdb_addr : 12'hFFF;
|
||||
wire [11:0] dbg_dk_idx = (eff_rdb_sel == 2'd2) ? eff_rdb_addr : 12'hFFF;
|
||||
|
||||
// one-cycle write-enable pulses into the core (combinational off the synced
|
||||
// edge; pre_sel_l/pre_addr_l/pre_byte_l are stable in sys, sampled by core).
|
||||
wire ek_in_we = mlkem_pre_we && (pre_sel_l == 2'd0);
|
||||
wire dk_in_we = mlkem_pre_we && (pre_sel_l == 2'd1);
|
||||
wire c_in_we = mlkem_pre_we && (pre_sel_l == 2'd2);
|
||||
// one-cycle write-enable pulses into the core.
|
||||
wire ek_in_we = core_resetn && mlkem_pre_we && (pre_sel_l == 2'd0);
|
||||
wire dk_in_we = core_resetn && mlkem_pre_we && (pre_sel_l == 2'd1);
|
||||
wire c_in_we = core_resetn && mlkem_pre_we && (pre_sel_l == 2'd2);
|
||||
|
||||
mlkem_top #(.KMAX(4)) u_mlkem (
|
||||
.clk (mlkem_clk),
|
||||
.rst_n (mlkem_rstn),
|
||||
.clk (clk),
|
||||
.rst_n (core_resetn),
|
||||
.k_i (cfg_k),
|
||||
.op_i (cfg_op),
|
||||
.d_i (d_bus),
|
||||
.z_i (z_bus),
|
||||
.msg_i (msg_bus),
|
||||
.start_i (mlkem_start),
|
||||
.start_i (core_resetn ? mlkem_start : 1'b0),
|
||||
.busy_o (core_busy),
|
||||
.done_o (core_done),
|
||||
// ek preload
|
||||
@@ -230,7 +285,7 @@ module mlkem_axi_slave (
|
||||
// shared secret out
|
||||
.ss_o (ss_o),
|
||||
// ciphertext readback tap
|
||||
.dbg_ct_idx_i (rdb_addr[10:0]),
|
||||
.dbg_ct_idx_i (eff_rdb_addr[10:0]),
|
||||
.dbg_ct_o (dbg_ct_o),
|
||||
// coefficient debug tap (unused by CPU path; tie inputs off)
|
||||
.dbg_slot_i (6'd0),
|
||||
@@ -238,7 +293,7 @@ module mlkem_axi_slave (
|
||||
.dbg_coeff_o (/* unused */),
|
||||
// ek / dk_pke byte readback
|
||||
.dbg_byte_sel_i (dbg_byte_sel),
|
||||
.dbg_byte_idx_i (rdb_addr[10:0]),
|
||||
.dbg_byte_idx_i (eff_rdb_addr[10:0]),
|
||||
.dbg_byte_o (dbg_byte_o),
|
||||
// full-dk byte readback
|
||||
.dbg_dk_idx_i (dbg_dk_idx),
|
||||
@@ -255,44 +310,82 @@ module mlkem_axi_slave (
|
||||
);
|
||||
|
||||
// ==========================================
|
||||
// mlkem_clk domain: synchronizers, done latch, preload-ack toggle.
|
||||
// Core/AXI clock domain: edge detectors, done latch, preload/readback acks.
|
||||
// ==========================================
|
||||
always @(posedge mlkem_clk or negedge mlkem_rstn) begin
|
||||
if (!mlkem_rstn) begin
|
||||
always @(posedge clk or negedge resetn) begin
|
||||
if (!resetn) begin
|
||||
start_sync <= 3'd0;
|
||||
srst_sync <= 3'd0;
|
||||
srst_cnt <= 4'd0;
|
||||
dclr_sync <= 3'd0;
|
||||
pre_req_sync <= 3'd0;
|
||||
pre_ack_tg <= 1'b0;
|
||||
rdb_req_sync <= 3'd0;
|
||||
rdb_ack_tg <= 1'b0;
|
||||
rdb_sel_m <= 2'd0;
|
||||
rdb_addr_m <= 12'd0;
|
||||
rdb_wait_m <= 2'd0;
|
||||
rdb_busy_m <= 1'b0;
|
||||
rdb_data_m <= 8'd0;
|
||||
done_latch <= 1'b0;
|
||||
end else begin
|
||||
// 2FF (+edge) synchronizers of sys-domain toggles
|
||||
// Edge-detect request toggles.
|
||||
start_sync <= {start_sync[1:0], start_tg};
|
||||
srst_sync <= {srst_sync[1:0], srst_tg};
|
||||
dclr_sync <= {dclr_sync[1:0], dclr_tg};
|
||||
pre_req_sync <= {pre_req_sync[1:0], pre_req_tg};
|
||||
rdb_req_sync <= {rdb_req_sync[1:0], rdb_req_tg};
|
||||
|
||||
if (mlkem_srst_edge)
|
||||
srst_cnt <= 4'd8;
|
||||
else if (srst_cnt != 4'd0)
|
||||
srst_cnt <= srst_cnt - 4'd1;
|
||||
|
||||
// acknowledge a consumed preload byte (write-enable pulsed this cycle)
|
||||
if (mlkem_pre_we) pre_ack_tg <= ~pre_ack_tg;
|
||||
if (core_resetn && mlkem_pre_we) pre_ack_tg <= ~pre_ack_tg;
|
||||
|
||||
if (!core_resetn) begin
|
||||
rdb_wait_m <= 2'd0;
|
||||
rdb_busy_m <= 1'b0;
|
||||
end else if (mlkem_rdb_req) begin
|
||||
rdb_sel_m <= rdb_req_sel_l;
|
||||
rdb_addr_m <= rdb_req_addr_l;
|
||||
rdb_wait_m <= 2'd2;
|
||||
rdb_busy_m <= 1'b1;
|
||||
end else if (rdb_wait_m != 2'd0) begin
|
||||
if (rdb_wait_m == 2'd1) begin
|
||||
rdb_data_m <= rdb_byte;
|
||||
rdb_ack_tg <= ~rdb_ack_tg;
|
||||
rdb_wait_m <= 2'd0;
|
||||
rdb_busy_m <= 1'b0;
|
||||
end else begin
|
||||
rdb_wait_m <= rdb_wait_m - 2'd1;
|
||||
end
|
||||
end
|
||||
|
||||
// sticky done: set on the core's done_o pulse, cleared by synced W1C.
|
||||
// (mlkem_start also clears it so a new run starts with done low.)
|
||||
if (core_done) done_latch <= 1'b1;
|
||||
if (mlkem_srst_active) done_latch <= 1'b0;
|
||||
else if (core_done) done_latch <= 1'b1;
|
||||
else if (mlkem_dclr) done_latch <= 1'b0;
|
||||
else if (mlkem_start) done_latch <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// ==========================================
|
||||
// sys_clk domain: sync busy/done/preload-ack back from mlkem.
|
||||
// AXI clock domain: register status and acknowledge toggles.
|
||||
// ==========================================
|
||||
always @(posedge clk or negedge resetn) begin
|
||||
if (!resetn) begin
|
||||
busy_sync <= 2'd0;
|
||||
done_sync <= 2'd0;
|
||||
pre_ack_sync <= 3'd0;
|
||||
rdb_ack_sync <= 3'd0;
|
||||
end else begin
|
||||
busy_sync <= {busy_sync[0], core_busy};
|
||||
busy_sync <= {busy_sync[0], core_busy | mlkem_srst_active};
|
||||
done_sync <= {done_sync[0], done_latch};
|
||||
pre_ack_sync <= {pre_ack_sync[1:0], pre_ack_tg};
|
||||
rdb_ack_sync <= {rdb_ack_sync[1:0], rdb_ack_tg};
|
||||
end
|
||||
end
|
||||
wire status_busy = busy_sync[1];
|
||||
@@ -304,17 +397,27 @@ module mlkem_axi_slave (
|
||||
// AXI Write channel (INCR burst). Preload-data beats are wait-stated until
|
||||
// the cross-domain byte handshake completes (W_PRELOAD).
|
||||
// ==========================================
|
||||
localparam W_IDLE = 2'd0;
|
||||
localparam W_DATA = 2'd1;
|
||||
localparam W_PRELOAD = 2'd2;
|
||||
localparam W_RESP = 2'd3;
|
||||
localparam W_IDLE = 3'd0;
|
||||
localparam W_DATA = 3'd1;
|
||||
localparam W_PRELOAD = 3'd2;
|
||||
localparam W_STREAM = 3'd3;
|
||||
localparam W_RESP = 3'd4;
|
||||
|
||||
reg [1:0] w_state;
|
||||
reg [2:0] w_state;
|
||||
reg [31:0] w_addr;
|
||||
reg [4:0] w_id;
|
||||
reg [1:0] w_burst;
|
||||
reg w_last_l; // saved wlast across a preload wait
|
||||
wire [11:0] w_offset = w_addr[11:0];
|
||||
wire w_stream_window = (w_addr[15:12] == WIN_EK) ||
|
||||
(w_addr[15:12] == WIN_DK) ||
|
||||
(w_addr[15:12] == WIN_CT);
|
||||
|
||||
reg [31:0] stream_wdata;
|
||||
reg [3:0] stream_wstrb;
|
||||
reg [11:0] stream_byte_addr;
|
||||
reg [2:0] stream_lane;
|
||||
reg [1:0] stream_sel;
|
||||
|
||||
assign s_axi_bid = w_id;
|
||||
|
||||
@@ -332,13 +435,20 @@ module mlkem_axi_slave (
|
||||
rdb_sel <= 2'd0;
|
||||
rdb_addr <= 12'd0;
|
||||
start_tg <= 1'b0;
|
||||
srst_tg <= 1'b0;
|
||||
dclr_tg <= 1'b0;
|
||||
pre_req_tg <= 1'b0;
|
||||
pre_busy <= 1'b0;
|
||||
pre_sel_l <= 2'd0;
|
||||
pre_addr_l <= 12'd0;
|
||||
pre_byte_l <= 8'd0;
|
||||
pre_auto_inc_l <= 1'b0;
|
||||
w_last_l <= 1'b0;
|
||||
stream_wdata <= 32'd0;
|
||||
stream_wstrb <= 4'd0;
|
||||
stream_byte_addr <= 12'd0;
|
||||
stream_lane <= 3'd0;
|
||||
stream_sel <= 2'd0;
|
||||
for (wi = 0; wi < 8; wi = wi + 1) begin
|
||||
d_word[wi] = 32'd0;
|
||||
z_word[wi] = 32'd0;
|
||||
@@ -348,7 +458,8 @@ module mlkem_axi_slave (
|
||||
// clear the preload-busy flag when the mlkem domain acks the byte
|
||||
if (pre_ack_edge) begin
|
||||
pre_busy <= 1'b0;
|
||||
pre_addr <= pre_addr + 12'd1; // auto-increment for next byte
|
||||
if (pre_auto_inc_l)
|
||||
pre_addr <= pre_addr + 12'd1; // legacy PRE_DAT auto-increment
|
||||
end
|
||||
|
||||
case (w_state)
|
||||
@@ -366,11 +477,21 @@ module mlkem_axi_slave (
|
||||
|
||||
W_DATA: begin
|
||||
if (s_axi_wvalid && s_axi_wready) begin
|
||||
if (w_offset == ADDR_PRE_DAT) begin
|
||||
if (w_stream_window) begin
|
||||
stream_wdata <= s_axi_wdata;
|
||||
stream_wstrb <= s_axi_wstrb;
|
||||
stream_byte_addr <= w_offset;
|
||||
stream_lane <= 3'd0;
|
||||
stream_sel <= window_preload_sel(w_addr[15:12]);
|
||||
w_last_l <= s_axi_wlast;
|
||||
s_axi_wready <= 1'b0;
|
||||
w_state <= W_STREAM;
|
||||
end else if (w_offset == ADDR_PRE_DAT) begin
|
||||
// launch cross-domain byte write; stall the beat.
|
||||
pre_sel_l <= pre_sel;
|
||||
pre_addr_l <= pre_addr;
|
||||
pre_byte_l <= s_axi_wdata[7:0];
|
||||
pre_auto_inc_l <= 1'b1;
|
||||
pre_req_tg <= ~pre_req_tg;
|
||||
pre_busy <= 1'b1;
|
||||
w_last_l <= s_axi_wlast;
|
||||
@@ -379,8 +500,10 @@ module mlkem_axi_slave (
|
||||
end else begin
|
||||
// normal single-cycle register write
|
||||
case (1'b1)
|
||||
(w_offset == ADDR_CTRL):
|
||||
(w_offset == ADDR_CTRL): begin
|
||||
if (s_axi_wdata[0]) start_tg <= ~start_tg;
|
||||
if (s_axi_wdata[1]) srst_tg <= ~srst_tg;
|
||||
end
|
||||
(w_offset == ADDR_STATUS):
|
||||
if (s_axi_wdata[1]) dclr_tg <= ~dclr_tg; // clear done
|
||||
(w_offset == ADDR_CONFIG): begin
|
||||
@@ -424,6 +547,31 @@ module mlkem_axi_slave (
|
||||
end
|
||||
end
|
||||
|
||||
W_STREAM: begin
|
||||
if (!pre_busy) begin
|
||||
if (stream_lane < 3'd4 && !stream_wstrb[stream_lane[1:0]]) begin
|
||||
stream_lane <= stream_lane + 3'd1;
|
||||
end else if (stream_lane < 3'd4) begin
|
||||
pre_sel_l <= stream_sel;
|
||||
pre_addr_l <= stream_byte_addr + {10'd0, stream_lane[1:0]};
|
||||
pre_byte_l <= select_byte(stream_wdata, stream_lane[1:0]);
|
||||
pre_auto_inc_l <= 1'b0;
|
||||
pre_req_tg <= ~pre_req_tg;
|
||||
pre_busy <= 1'b1;
|
||||
stream_lane <= stream_lane + 3'd1;
|
||||
end else begin
|
||||
if (w_burst == 2'b01) w_addr <= w_addr + 32'd4;
|
||||
if (w_last_l) begin
|
||||
s_axi_bvalid <= 1'b1;
|
||||
w_state <= W_RESP;
|
||||
end else begin
|
||||
s_axi_wready <= 1'b1;
|
||||
w_state <= W_DATA;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
W_RESP: begin
|
||||
if (s_axi_bvalid && s_axi_bready) begin
|
||||
s_axi_bvalid <= 1'b0;
|
||||
@@ -439,15 +587,25 @@ module mlkem_axi_slave (
|
||||
// ==========================================
|
||||
// AXI Read channel (INCR burst).
|
||||
// ==========================================
|
||||
localparam R_IDLE = 1'b0;
|
||||
localparam R_DATA = 1'b1;
|
||||
localparam R_IDLE = 3'd0;
|
||||
localparam R_DATA = 3'd1;
|
||||
localparam R_BULK_WAIT = 3'd2;
|
||||
|
||||
reg r_state;
|
||||
reg [2:0] r_state;
|
||||
reg [31:0] r_addr;
|
||||
reg [7:0] r_cnt;
|
||||
reg [7:0] r_len;
|
||||
reg [1:0] r_burst;
|
||||
wire [11:0] r_offset = r_addr[11:0];
|
||||
wire ar_stream_window = (s_axi_araddr[15:12] == WIN_EK) ||
|
||||
(s_axi_araddr[15:12] == WIN_DK) ||
|
||||
(s_axi_araddr[15:12] == WIN_CT);
|
||||
|
||||
reg r_bulk;
|
||||
reg [1:0] bulk_sel_r;
|
||||
reg [11:0] bulk_addr_r;
|
||||
reg [1:0] bulk_lane;
|
||||
reg [31:0] bulk_word;
|
||||
|
||||
always @(posedge clk or negedge resetn) begin
|
||||
if (!resetn) begin
|
||||
@@ -460,6 +618,14 @@ module mlkem_axi_slave (
|
||||
r_cnt <= 8'd0;
|
||||
r_len <= 8'd0;
|
||||
r_burst <= 2'd0;
|
||||
r_bulk <= 1'b0;
|
||||
bulk_sel_r <= 2'd0;
|
||||
bulk_addr_r <= 12'd0;
|
||||
bulk_lane <= 2'd0;
|
||||
bulk_word <= 32'd0;
|
||||
rdb_req_tg <= 1'b0;
|
||||
rdb_req_sel_l <= 2'd0;
|
||||
rdb_req_addr_l <= 12'd0;
|
||||
end else begin
|
||||
case (r_state)
|
||||
R_IDLE: begin
|
||||
@@ -470,10 +636,45 @@ module mlkem_axi_slave (
|
||||
r_len <= s_axi_arlen;
|
||||
r_burst <= s_axi_arburst;
|
||||
r_cnt <= 8'd0;
|
||||
s_axi_rvalid <= 1'b1;
|
||||
s_axi_rlast <= (s_axi_arlen == 8'd0);
|
||||
s_axi_rid <= s_axi_arid;
|
||||
r_state <= R_DATA;
|
||||
r_bulk <= ar_stream_window;
|
||||
if (ar_stream_window) begin
|
||||
bulk_sel_r <= window_readback_sel(s_axi_araddr[15:12]);
|
||||
bulk_addr_r <= s_axi_araddr[11:0];
|
||||
bulk_lane <= 2'd0;
|
||||
bulk_word <= 32'd0;
|
||||
rdb_req_sel_l <= window_readback_sel(s_axi_araddr[15:12]);
|
||||
rdb_req_addr_l <= s_axi_araddr[11:0];
|
||||
rdb_req_tg <= ~rdb_req_tg;
|
||||
s_axi_rvalid <= 1'b0;
|
||||
s_axi_rlast <= 1'b0;
|
||||
r_state <= R_BULK_WAIT;
|
||||
end else begin
|
||||
s_axi_rvalid <= 1'b1;
|
||||
s_axi_rlast <= (s_axi_arlen == 8'd0);
|
||||
r_state <= R_DATA;
|
||||
end
|
||||
end
|
||||
end
|
||||
R_BULK_WAIT: begin
|
||||
if (rdb_ack_edge) begin
|
||||
case (bulk_lane)
|
||||
2'd0: bulk_word[7:0] <= rdb_data_m;
|
||||
2'd1: bulk_word[15:8] <= rdb_data_m;
|
||||
2'd2: bulk_word[23:16] <= rdb_data_m;
|
||||
default: bulk_word[31:24] <= rdb_data_m;
|
||||
endcase
|
||||
|
||||
if (bulk_lane == 2'd3) begin
|
||||
s_axi_rvalid <= 1'b1;
|
||||
s_axi_rlast <= (r_cnt == r_len);
|
||||
r_state <= R_DATA;
|
||||
end else begin
|
||||
bulk_lane <= bulk_lane + 2'd1;
|
||||
bulk_addr_r <= bulk_addr_r + 12'd1;
|
||||
rdb_req_addr_l <= bulk_addr_r + 12'd1;
|
||||
rdb_req_tg <= ~rdb_req_tg;
|
||||
end
|
||||
end
|
||||
end
|
||||
R_DATA: begin
|
||||
@@ -482,11 +683,24 @@ module mlkem_axi_slave (
|
||||
s_axi_rvalid <= 1'b0;
|
||||
s_axi_rlast <= 1'b0;
|
||||
s_axi_arready <= 1'b1;
|
||||
r_bulk <= 1'b0;
|
||||
r_state <= R_IDLE;
|
||||
end else begin
|
||||
r_cnt <= r_cnt + 8'd1;
|
||||
s_axi_rlast <= (r_cnt + 8'd1 == r_len);
|
||||
if (r_burst == 2'b01) r_addr <= r_addr + 32'd4;
|
||||
if (r_bulk) begin
|
||||
bulk_addr_r <= (r_burst == 2'b01) ? (r_offset + 12'd4) : r_offset;
|
||||
bulk_lane <= 2'd0;
|
||||
bulk_word <= 32'd0;
|
||||
rdb_req_sel_l <= bulk_sel_r;
|
||||
rdb_req_addr_l <= (r_burst == 2'b01) ? (r_offset + 12'd4) : r_offset;
|
||||
rdb_req_tg <= ~rdb_req_tg;
|
||||
s_axi_rvalid <= 1'b0;
|
||||
s_axi_rlast <= 1'b0;
|
||||
r_state <= R_BULK_WAIT;
|
||||
end else begin
|
||||
s_axi_rlast <= (r_cnt + 8'd1 == r_len);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -499,12 +713,14 @@ module mlkem_axi_slave (
|
||||
// first beat is valid the cycle rvalid asserts (matches matmul style).
|
||||
wire [11:0] cur_off = (r_state == R_DATA) ? r_offset : s_axi_araddr[11:0];
|
||||
// Selected readback byte (taps are combinational over the core's BRAMs).
|
||||
wire [7:0] rdb_byte = (rdb_sel == 2'd3) ? dbg_ct_o :
|
||||
(rdb_sel == 2'd2) ? dbg_dk_o : dbg_byte_o;
|
||||
wire [7:0] rdb_byte = (eff_rdb_sel == 2'd3) ? dbg_ct_o :
|
||||
(eff_rdb_sel == 2'd2) ? dbg_dk_o : dbg_byte_o;
|
||||
|
||||
always @(*) begin
|
||||
s_axi_rdata = 32'd0;
|
||||
if (r_state == R_DATA || (r_state == R_IDLE && s_axi_arvalid)) begin
|
||||
if (r_bulk && r_state == R_DATA) begin
|
||||
s_axi_rdata = bulk_word;
|
||||
end else if (r_state == R_DATA || (r_state == R_IDLE && s_axi_arvalid)) begin
|
||||
case (1'b1)
|
||||
(cur_off == ADDR_CTRL): s_axi_rdata = 32'd0;
|
||||
(cur_off == ADDR_STATUS): s_axi_rdata = {29'd0, pre_busy, status_done, status_busy};
|
||||
|
||||
284
rtl/soc_top.v
@@ -397,6 +397,9 @@ wire [1 :0] dma_s_bresp ;
|
||||
wire dma_s_bvalid ;
|
||||
wire dma_s_bready ;
|
||||
wire dma_finish ;
|
||||
wire cdma_dma_finish;
|
||||
wire cdma_matmul_seq_irq;
|
||||
assign dma_finish = cdma_dma_finish | cdma_matmul_seq_irq;
|
||||
|
||||
// reserved
|
||||
wire [4 :0] axiOut_1_arid ;
|
||||
@@ -562,7 +565,7 @@ wire [4 :0] fft_bid ;
|
||||
wire [1 :0] fft_bresp ;
|
||||
wire fft_bvalid ;
|
||||
wire fft_bready ;
|
||||
wire fft_finish = 1'b0;
|
||||
wire fft_finish;
|
||||
|
||||
//slave 7
|
||||
wire [4 :0] axiOut_7_arid ;
|
||||
@@ -604,6 +607,23 @@ wire axiOut_7_bready ;
|
||||
|
||||
wire confreg_int;
|
||||
wire matmul_intr;
|
||||
wire matmul_ep_wr_valid;
|
||||
wire [3:0] matmul_ep_wr_id;
|
||||
wire [3:0] matmul_ep_wr_bank;
|
||||
wire [7:0] matmul_ep_wr_word_addr;
|
||||
wire [31:0] matmul_ep_wr_data;
|
||||
wire matmul_ep_wr_ready;
|
||||
wire matmul_ep_rd_valid;
|
||||
wire [3:0] matmul_ep_rd_id;
|
||||
wire [3:0] matmul_ep_rd_bank;
|
||||
wire [7:0] matmul_ep_rd_word_addr;
|
||||
wire [31:0] matmul_ep_rd_data;
|
||||
wire matmul_ep_rd_ready;
|
||||
wire matmul_direct_start_valid;
|
||||
wire matmul_direct_start_bank;
|
||||
wire matmul_direct_done_clear;
|
||||
wire matmul_direct_crc_clear;
|
||||
wire matmul_direct_done;
|
||||
wire mlkem_intr;
|
||||
|
||||
AxiCrossbar_2x8 u_AxiCrossbar_2x8 (
|
||||
@@ -1425,9 +1445,10 @@ axi_dvi u_axi_dvi (
|
||||
.video_blue ( video_blue )
|
||||
);
|
||||
|
||||
// slave 6 - ML-KEM accelerator (0x1f400000, virtual 0xbf400000)
|
||||
// Bus runs at sys_clk; the core is internally clocked at sys_clk/2 (25 MHz).
|
||||
mlkem_axi_slave u_mlkem_axi_slave (
|
||||
// slave 6 - shared FFT / ML-KEM accelerator window (0x1f400000, virtual 0xbf400000)
|
||||
// ML-KEM: 0x0000..0x3fff
|
||||
// FFT: 0x8000..0xcfff
|
||||
fft_mlkem_axi_slave u_fft_mlkem_axi_slave (
|
||||
.clk (sys_clk),
|
||||
.resetn (sys_resetn),
|
||||
|
||||
@@ -1471,7 +1492,9 @@ mlkem_axi_slave u_mlkem_axi_slave (
|
||||
.s_axi_rlast (fft_rlast ),
|
||||
.s_axi_rvalid (fft_rvalid),
|
||||
.s_axi_rready (fft_rready),
|
||||
.intr (mlkem_intr)
|
||||
|
||||
.fft_finish (fft_finish),
|
||||
.mlkem_intr (mlkem_intr)
|
||||
);
|
||||
|
||||
//slave 7 - matmul accelerator
|
||||
@@ -1519,6 +1542,27 @@ matmul_axi_slave u_matmul_axi_slave (
|
||||
.s_axi_rlast (axiOut_7_rlast ),
|
||||
.s_axi_rvalid (axiOut_7_rvalid),
|
||||
.s_axi_rready (axiOut_7_rready),
|
||||
|
||||
.ep_wr_valid (matmul_ep_wr_valid),
|
||||
.ep_wr_id (matmul_ep_wr_id),
|
||||
.ep_wr_bank (matmul_ep_wr_bank),
|
||||
.ep_wr_word_addr(matmul_ep_wr_word_addr),
|
||||
.ep_wr_data (matmul_ep_wr_data),
|
||||
.ep_wr_ready (matmul_ep_wr_ready),
|
||||
|
||||
.ep_rd_valid (matmul_ep_rd_valid),
|
||||
.ep_rd_id (matmul_ep_rd_id),
|
||||
.ep_rd_bank (matmul_ep_rd_bank),
|
||||
.ep_rd_word_addr(matmul_ep_rd_word_addr),
|
||||
.ep_rd_data (matmul_ep_rd_data),
|
||||
.ep_rd_ready (matmul_ep_rd_ready),
|
||||
|
||||
.mat_start_valid(matmul_direct_start_valid),
|
||||
.mat_start_bank (matmul_direct_start_bank),
|
||||
.mat_done_clear (matmul_direct_done_clear),
|
||||
.mat_crc_clear (matmul_direct_crc_clear),
|
||||
.mat_done (matmul_direct_done),
|
||||
|
||||
.intr (matmul_intr)
|
||||
);
|
||||
|
||||
@@ -1542,6 +1586,116 @@ wire [1:0] cdma_s_rresp;
|
||||
wire cdma_s_rvalid;
|
||||
wire cdma_s_rready;
|
||||
|
||||
wire [31:0] cdma_mux_awaddr;
|
||||
wire cdma_mux_awvalid;
|
||||
wire cdma_mux_awready;
|
||||
wire [31:0] cdma_mux_wdata;
|
||||
wire [3:0] cdma_mux_wstrb;
|
||||
wire cdma_mux_wvalid;
|
||||
wire cdma_mux_wready;
|
||||
wire [1:0] cdma_mux_bresp;
|
||||
wire cdma_mux_bvalid;
|
||||
wire cdma_mux_bready;
|
||||
wire [31:0] cdma_mux_araddr;
|
||||
wire cdma_mux_arvalid;
|
||||
wire cdma_mux_arready;
|
||||
wire [31:0] cdma_mux_rdata;
|
||||
wire [1:0] cdma_mux_rresp;
|
||||
wire cdma_mux_rvalid;
|
||||
wire cdma_mux_rready;
|
||||
|
||||
wire [31:0] cdma_bridge_awaddr;
|
||||
wire cdma_bridge_awvalid;
|
||||
wire cdma_bridge_awready;
|
||||
wire [31:0] cdma_bridge_wdata;
|
||||
wire [3:0] cdma_bridge_wstrb;
|
||||
wire cdma_bridge_wvalid;
|
||||
wire cdma_bridge_wready;
|
||||
wire [1:0] cdma_bridge_bresp;
|
||||
wire cdma_bridge_bvalid;
|
||||
wire cdma_bridge_bready;
|
||||
wire [31:0] cdma_bridge_araddr;
|
||||
wire cdma_bridge_arvalid;
|
||||
wire cdma_bridge_arready;
|
||||
wire [31:0] cdma_bridge_rdata;
|
||||
wire [1:0] cdma_bridge_rresp;
|
||||
wire cdma_bridge_rvalid;
|
||||
wire cdma_bridge_rready;
|
||||
|
||||
wire bridge_cdma_rd_req_valid;
|
||||
wire bridge_cdma_rd_req_ready;
|
||||
wire [31:0] bridge_cdma_rd_req_src;
|
||||
wire [31:0] bridge_cdma_rd_req_bytes;
|
||||
wire [3:0] bridge_cdma_rd_req_ep_id;
|
||||
wire [3:0] bridge_cdma_rd_req_ep_bank;
|
||||
wire [7:0] bridge_cdma_rd_req_ep_word_off;
|
||||
wire bridge_cdma_rd_req_done;
|
||||
wire bridge_cdma_wr_req_valid;
|
||||
wire bridge_cdma_wr_req_ready;
|
||||
wire [31:0] bridge_cdma_wr_req_dst;
|
||||
wire [31:0] bridge_cdma_wr_req_bytes;
|
||||
wire [3:0] bridge_cdma_wr_req_ep_id;
|
||||
wire [3:0] bridge_cdma_wr_req_ep_bank;
|
||||
wire [7:0] bridge_cdma_wr_req_ep_word_off;
|
||||
wire bridge_cdma_wr_req_done;
|
||||
|
||||
wire cdma_axil_wr_bridge = (cdma_s_awaddr[11:8] == 4'h2);
|
||||
wire cdma_axil_rd_bridge = (cdma_s_araddr[11:8] == 4'h2);
|
||||
reg cdma_axil_wr_active;
|
||||
reg cdma_axil_wr_bridge_hold;
|
||||
reg cdma_axil_b_bridge;
|
||||
reg cdma_axil_r_bridge;
|
||||
wire cdma_axil_wr_sel = cdma_axil_wr_active ? cdma_axil_wr_bridge_hold : cdma_axil_wr_bridge;
|
||||
|
||||
assign cdma_mux_awaddr = cdma_s_awaddr;
|
||||
assign cdma_mux_awvalid = cdma_s_awvalid && !cdma_axil_wr_sel;
|
||||
assign cdma_mux_wdata = cdma_s_wdata;
|
||||
assign cdma_mux_wstrb = cdma_s_wstrb;
|
||||
assign cdma_mux_wvalid = cdma_s_wvalid && !cdma_axil_wr_sel;
|
||||
assign cdma_mux_bready = cdma_s_bready && !cdma_axil_b_bridge;
|
||||
assign cdma_mux_araddr = cdma_s_araddr;
|
||||
assign cdma_mux_arvalid = cdma_s_arvalid && !cdma_axil_rd_bridge;
|
||||
assign cdma_mux_rready = cdma_s_rready && !cdma_axil_r_bridge;
|
||||
|
||||
assign cdma_bridge_awaddr = cdma_s_awaddr;
|
||||
assign cdma_bridge_awvalid = cdma_s_awvalid && cdma_axil_wr_sel;
|
||||
assign cdma_bridge_wdata = cdma_s_wdata;
|
||||
assign cdma_bridge_wstrb = cdma_s_wstrb;
|
||||
assign cdma_bridge_wvalid = cdma_s_wvalid && cdma_axil_wr_sel;
|
||||
assign cdma_bridge_bready = cdma_s_bready && cdma_axil_b_bridge;
|
||||
assign cdma_bridge_araddr = cdma_s_araddr;
|
||||
assign cdma_bridge_arvalid = cdma_s_arvalid && cdma_axil_rd_bridge;
|
||||
assign cdma_bridge_rready = cdma_s_rready && cdma_axil_r_bridge;
|
||||
|
||||
assign cdma_s_awready = cdma_axil_wr_sel ? cdma_bridge_awready : cdma_mux_awready;
|
||||
assign cdma_s_wready = cdma_axil_wr_sel ? cdma_bridge_wready : cdma_mux_wready;
|
||||
assign cdma_s_bresp = cdma_axil_b_bridge ? cdma_bridge_bresp : cdma_mux_bresp;
|
||||
assign cdma_s_bvalid = cdma_axil_b_bridge ? cdma_bridge_bvalid : cdma_mux_bvalid;
|
||||
assign cdma_s_arready = cdma_axil_rd_bridge ? cdma_bridge_arready : cdma_mux_arready;
|
||||
assign cdma_s_rdata = cdma_axil_r_bridge ? cdma_bridge_rdata : cdma_mux_rdata;
|
||||
assign cdma_s_rresp = cdma_axil_r_bridge ? cdma_bridge_rresp : cdma_mux_rresp;
|
||||
assign cdma_s_rvalid = cdma_axil_r_bridge ? cdma_bridge_rvalid : cdma_mux_rvalid;
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (!sys_resetn) begin
|
||||
cdma_axil_wr_active <= 1'b0;
|
||||
cdma_axil_wr_bridge_hold <= 1'b0;
|
||||
cdma_axil_b_bridge <= 1'b0;
|
||||
cdma_axil_r_bridge <= 1'b0;
|
||||
end else begin
|
||||
if (cdma_s_awvalid && !cdma_axil_wr_active) begin
|
||||
cdma_axil_wr_active <= 1'b1;
|
||||
cdma_axil_wr_bridge_hold <= cdma_axil_wr_bridge;
|
||||
end
|
||||
if (cdma_s_awvalid && cdma_s_awready && cdma_s_wvalid && cdma_s_wready) begin
|
||||
cdma_axil_b_bridge <= cdma_axil_wr_sel;
|
||||
cdma_axil_wr_active <= 1'b0;
|
||||
end
|
||||
if (cdma_s_arvalid && cdma_s_arready)
|
||||
cdma_axil_r_bridge <= cdma_axil_rd_bridge;
|
||||
end
|
||||
end
|
||||
|
||||
axi_axil_adapter #(
|
||||
.ADDR_WIDTH(32),
|
||||
.AXI_DATA_WIDTH(32),
|
||||
@@ -1610,6 +1764,58 @@ u_axi_axil_adapter(
|
||||
.m_axil_rready(cdma_s_rready)
|
||||
);
|
||||
|
||||
cdma_matmul_bridge #(
|
||||
.ADDR_WIDTH (32),
|
||||
.AXIL_ADDR_WIDTH (32),
|
||||
.AXIL_DATA_WIDTH (32)
|
||||
) u_cdma_matmul_bridge (
|
||||
.clk (sys_clk),
|
||||
.rst_n (sys_resetn),
|
||||
|
||||
.s_axil_awaddr (cdma_bridge_awaddr),
|
||||
.s_axil_awvalid (cdma_bridge_awvalid),
|
||||
.s_axil_awready (cdma_bridge_awready),
|
||||
.s_axil_wdata (cdma_bridge_wdata),
|
||||
.s_axil_wstrb (cdma_bridge_wstrb),
|
||||
.s_axil_wvalid (cdma_bridge_wvalid),
|
||||
.s_axil_wready (cdma_bridge_wready),
|
||||
.s_axil_bresp (cdma_bridge_bresp),
|
||||
.s_axil_bvalid (cdma_bridge_bvalid),
|
||||
.s_axil_bready (cdma_bridge_bready),
|
||||
.s_axil_araddr (cdma_bridge_araddr),
|
||||
.s_axil_arvalid (cdma_bridge_arvalid),
|
||||
.s_axil_arready (cdma_bridge_arready),
|
||||
.s_axil_rdata (cdma_bridge_rdata),
|
||||
.s_axil_rresp (cdma_bridge_rresp),
|
||||
.s_axil_rvalid (cdma_bridge_rvalid),
|
||||
.s_axil_rready (cdma_bridge_rready),
|
||||
|
||||
.cdma_rd_req_valid (bridge_cdma_rd_req_valid),
|
||||
.cdma_rd_req_ready (bridge_cdma_rd_req_ready),
|
||||
.cdma_rd_req_src (bridge_cdma_rd_req_src),
|
||||
.cdma_rd_req_bytes (bridge_cdma_rd_req_bytes),
|
||||
.cdma_rd_req_ep_id (bridge_cdma_rd_req_ep_id),
|
||||
.cdma_rd_req_ep_bank (bridge_cdma_rd_req_ep_bank),
|
||||
.cdma_rd_req_ep_word_off(bridge_cdma_rd_req_ep_word_off),
|
||||
.cdma_rd_req_done (bridge_cdma_rd_req_done),
|
||||
|
||||
.cdma_wr_req_valid (bridge_cdma_wr_req_valid),
|
||||
.cdma_wr_req_ready (bridge_cdma_wr_req_ready),
|
||||
.cdma_wr_req_dst (bridge_cdma_wr_req_dst),
|
||||
.cdma_wr_req_bytes (bridge_cdma_wr_req_bytes),
|
||||
.cdma_wr_req_ep_id (bridge_cdma_wr_req_ep_id),
|
||||
.cdma_wr_req_ep_bank (bridge_cdma_wr_req_ep_bank),
|
||||
.cdma_wr_req_ep_word_off(bridge_cdma_wr_req_ep_word_off),
|
||||
.cdma_wr_req_done (bridge_cdma_wr_req_done),
|
||||
|
||||
.mat_start_valid (matmul_direct_start_valid),
|
||||
.mat_start_bank (matmul_direct_start_bank),
|
||||
.mat_done_clear (matmul_direct_done_clear),
|
||||
.mat_crc_clear (matmul_direct_crc_clear),
|
||||
.mat_done (matmul_direct_done),
|
||||
.seq_done_irq (cdma_matmul_seq_irq)
|
||||
);
|
||||
|
||||
// 8 通道 DMA
|
||||
snix_axil_cdma_mux #(
|
||||
.ADDR_WIDTH (32),
|
||||
@@ -1625,23 +1831,23 @@ snix_axil_cdma_mux #(
|
||||
.rst_n (sys_resetn), // 低电平复位
|
||||
|
||||
// AXI-Lite 从机接口 (接 CPU 发来的配置请求)
|
||||
.s_axil_awaddr (cdma_s_awaddr),
|
||||
.s_axil_awvalid (cdma_s_awvalid),
|
||||
.s_axil_awready (cdma_s_awready),
|
||||
.s_axil_wdata (cdma_s_wdata),
|
||||
.s_axil_wstrb (cdma_s_wstrb),
|
||||
.s_axil_wvalid (cdma_s_wvalid),
|
||||
.s_axil_wready (cdma_s_wready),
|
||||
.s_axil_bresp (cdma_s_bresp),
|
||||
.s_axil_bvalid (cdma_s_bvalid),
|
||||
.s_axil_bready (cdma_s_bready),
|
||||
.s_axil_araddr (cdma_s_araddr),
|
||||
.s_axil_arvalid (cdma_s_arvalid),
|
||||
.s_axil_arready (cdma_s_arready),
|
||||
.s_axil_rdata (cdma_s_rdata),
|
||||
.s_axil_rresp (cdma_s_rresp),
|
||||
.s_axil_rvalid (cdma_s_rvalid),
|
||||
.s_axil_rready (cdma_s_rready),
|
||||
.s_axil_awaddr (cdma_mux_awaddr),
|
||||
.s_axil_awvalid (cdma_mux_awvalid),
|
||||
.s_axil_awready (cdma_mux_awready),
|
||||
.s_axil_wdata (cdma_mux_wdata),
|
||||
.s_axil_wstrb (cdma_mux_wstrb),
|
||||
.s_axil_wvalid (cdma_mux_wvalid),
|
||||
.s_axil_wready (cdma_mux_wready),
|
||||
.s_axil_bresp (cdma_mux_bresp),
|
||||
.s_axil_bvalid (cdma_mux_bvalid),
|
||||
.s_axil_bready (cdma_mux_bready),
|
||||
.s_axil_araddr (cdma_mux_araddr),
|
||||
.s_axil_arvalid (cdma_mux_arvalid),
|
||||
.s_axil_arready (cdma_mux_arready),
|
||||
.s_axil_rdata (cdma_mux_rdata),
|
||||
.s_axil_rresp (cdma_mux_rresp),
|
||||
.s_axil_rvalid (cdma_mux_rvalid),
|
||||
.s_axil_rready (cdma_mux_rready),
|
||||
|
||||
// AXI4 主机接口 (接 Crossbar 去搬运数据)
|
||||
.mm2mm_awid (dma_m_awid),
|
||||
@@ -1687,8 +1893,40 @@ snix_axil_cdma_mux #(
|
||||
.mm2mm_rvalid (dma_m_rvalid),
|
||||
.mm2mm_rready (dma_m_rready),
|
||||
|
||||
// 本地直连到 matmul,不经过 AXI crossbar
|
||||
.ep_wr_valid (matmul_ep_wr_valid),
|
||||
.ep_wr_id (matmul_ep_wr_id),
|
||||
.ep_wr_bank (matmul_ep_wr_bank),
|
||||
.ep_wr_word_addr (matmul_ep_wr_word_addr),
|
||||
.ep_wr_data (matmul_ep_wr_data),
|
||||
.ep_wr_ready (matmul_ep_wr_ready),
|
||||
.ep_rd_valid (matmul_ep_rd_valid),
|
||||
.ep_rd_id (matmul_ep_rd_id),
|
||||
.ep_rd_bank (matmul_ep_rd_bank),
|
||||
.ep_rd_word_addr (matmul_ep_rd_word_addr),
|
||||
.ep_rd_data (matmul_ep_rd_data),
|
||||
.ep_rd_ready (matmul_ep_rd_ready),
|
||||
|
||||
.ext_rd_req_valid (bridge_cdma_rd_req_valid),
|
||||
.ext_rd_req_ready (bridge_cdma_rd_req_ready),
|
||||
.ext_rd_req_src (bridge_cdma_rd_req_src),
|
||||
.ext_rd_req_bytes (bridge_cdma_rd_req_bytes),
|
||||
.ext_rd_req_ep_id (bridge_cdma_rd_req_ep_id),
|
||||
.ext_rd_req_ep_bank (bridge_cdma_rd_req_ep_bank),
|
||||
.ext_rd_req_ep_word_off(bridge_cdma_rd_req_ep_word_off),
|
||||
.ext_rd_req_done (bridge_cdma_rd_req_done),
|
||||
|
||||
.ext_wr_req_valid (bridge_cdma_wr_req_valid),
|
||||
.ext_wr_req_ready (bridge_cdma_wr_req_ready),
|
||||
.ext_wr_req_dst (bridge_cdma_wr_req_dst),
|
||||
.ext_wr_req_bytes (bridge_cdma_wr_req_bytes),
|
||||
.ext_wr_req_ep_id (bridge_cdma_wr_req_ep_id),
|
||||
.ext_wr_req_ep_bank (bridge_cdma_wr_req_ep_bank),
|
||||
.ext_wr_req_ep_word_off(bridge_cdma_wr_req_ep_word_off),
|
||||
.ext_wr_req_done (bridge_cdma_wr_req_done),
|
||||
|
||||
// 全局中断输出
|
||||
.dma_finish (dma_finish)
|
||||
.dma_finish (cdma_dma_finish)
|
||||
);
|
||||
|
||||
endmodule
|
||||
10308
sdk/axi_ram.mif
BIN
sdk/fft.bin
BIN
sdk/fft_dma.bin
@@ -19,27 +19,34 @@ CFLAGS += -nostartfiles -nostdlib -nostdinc -static -fno-builtin
|
||||
CFLAGS += -DCLOCKS_PER_SEC=CORE_CLOCKS_PER_SEC -D_CLOCKS_PER_SEC_=CORE_CLOCKS_PER_SEC
|
||||
CFLAGS += -DUSE_CPU_CLOCK_COUNT
|
||||
|
||||
LINKER_SCRIPT ?= $(COMMON_DIR)/env/script.lds
|
||||
BSP_STARTUP ?= $(COMMON_DIR)/env/start.S
|
||||
BSP_USE_TRAP ?= 1
|
||||
BSP_USE_DRIVERS ?= 1
|
||||
|
||||
#若使用 newlib , 将下面的 -lsemihost 替换为 -lgloss
|
||||
LDFLAGS += -T $(LINKER_SCRIPT) \
|
||||
-Wl,--gc-sections -Wl,--check-sections \
|
||||
-lc -lm -lg -lsemihost -lgcc -L$(PICOLIBC_DIR)/lib
|
||||
|
||||
LINKER_SCRIPT := $(COMMON_DIR)/env/script.lds
|
||||
|
||||
ASM_SRCS += $(COMMON_DIR)/env/start.S
|
||||
ASM_SRCS += $(BSP_STARTUP)
|
||||
|
||||
ifeq ($(BSP_USE_TRAP),1)
|
||||
ifeq ($(TARGET), RTThread_Nano)
|
||||
|
||||
else
|
||||
ASM_SRCS += $(COMMON_DIR)/env/trap_handler.S
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(BSP_USE_DRIVERS),1)
|
||||
C_SRCS += $(COMMON_DIR)/drivers/confreg_time.c
|
||||
C_SRCS += $(COMMON_DIR)/drivers/core_time.c
|
||||
C_SRCS += $(COMMON_DIR)/drivers/common_func.c
|
||||
C_SRCS += $(COMMON_DIR)/drivers/dvi.c \
|
||||
$(COMMON_DIR)/drivers/led.c \
|
||||
$(COMMON_DIR)/drivers/seg7.c
|
||||
endif
|
||||
|
||||
INCLUDES += -I./ \
|
||||
-I$(COMMON_DIR)/include \
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#include "fft.h"
|
||||
#include "common_func.h"
|
||||
|
||||
void fft_start() {
|
||||
RegWrite(FFT_CSR_REG, FFT_CTRL_START);
|
||||
}
|
||||
|
||||
void fft_wait() {
|
||||
while ((RegRead(FFT_CSR_REG) & FFT_STAT_DONE) == 0) {}
|
||||
}
|
||||
|
||||
unsigned int fft_get_csr() {
|
||||
return RegRead(FFT_CSR_REG);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
volatile uint32_t SRC_ADDR; // 0x00: 源地址
|
||||
volatile uint32_t DST_ADDR; // 0x04: 目的地址
|
||||
volatile uint32_t LENGTH; // 0x08: 传输总字节数
|
||||
volatile uint32_t TAG; // 0x0C: 软件 Tag (硬件不处理,留给软件标记任务用)
|
||||
volatile uint32_t CTRL; // 0x10: 控制寄存器 (配置 Burst 属性 + 启动)
|
||||
volatile uint32_t STATUS; // 0x14: 状态寄存器 (Busy, Done)
|
||||
volatile uint32_t RESV[10]; // 0x18 ~ 0x3C: 保留空间,凑齐 0x40 字节
|
||||
} dma_ch_regs_t;
|
||||
|
||||
// DMA 控制器基地址
|
||||
#define CDMA_MUX_BASE 0xbf300000
|
||||
#define DMA_CH(i) ((volatile dma_ch_regs_t*)(CDMA_MUX_BASE + (i) * 0x40))
|
||||
|
||||
// CTRL 寄存器位定义
|
||||
#define CTRL_START_BIT (1 << 0)
|
||||
#define CTRL_BURST_SIZE(x) (((x) & 0x7) << 3) // Bits [5:3]: AXI AxSIZE (0=1B, 1=2B, 2=4B, 3=8B)
|
||||
#define CTRL_BURST_LEN(x) (((x) & 0xFF) << 6) // Bits [13:6]: AXI AxLEN (0=1 beat, 15=16 beats)
|
||||
|
||||
// STATUS 寄存器位定义
|
||||
#define STATUS_BUSY_BIT (1 << 0)
|
||||
#define STATUS_DONE_BIT (1 << 1)
|
||||
|
||||
void dma_start_transfer(int ch_id, uint32_t src, uint32_t dst, uint32_t bytes, uint32_t tag);
|
||||
void dma_wait_polling(int ch_id);
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define FFT_BASE 0xbf400000
|
||||
#define FFT_IN_RE_BASE (FFT_BASE + 0x1000)
|
||||
#define FFT_IN_IM_BASE (FFT_BASE + 0x2000)
|
||||
#define FFT_OUT_RE_BASE (FFT_BASE + 0x3000)
|
||||
#define FFT_OUT_IM_BASE (FFT_BASE + 0x4000)
|
||||
#define FFT_CSR_REG (FFT_BASE + 0xF000)
|
||||
#define FFT_CTRL_START (1 << 4)
|
||||
#define FFT_STAT_DONE (1 << 1)
|
||||
#define FFT_STAT_BUSY (1 << 0)
|
||||
#define FFT_POINT_NUM 1024
|
||||
|
||||
void fft_start();
|
||||
void fft_wait();
|
||||
unsigned int fft_get_csr();
|
||||
@@ -1,7 +1,9 @@
|
||||
TARGET = user-sample
|
||||
|
||||
MATMUL_GROUP_NUM ?= 5000
|
||||
CFLAGS += -O3 -g -DMATMUL_GROUP_NUM=$(MATMUL_GROUP_NUM)
|
||||
MATMUL_WRITEBACK_RESULTS ?= 0
|
||||
MATMUL_FAST_START ?= 1
|
||||
CFLAGS += -O3 -g -DMATMUL_GROUP_NUM=$(MATMUL_GROUP_NUM) -DMATMUL_WRITEBACK_RESULTS=$(MATMUL_WRITEBACK_RESULTS) -DMATMUL_FAST_START=$(MATMUL_FAST_START)
|
||||
|
||||
C_SRCS := $(wildcard ./*.c )
|
||||
|
||||
@@ -9,6 +11,14 @@ OBJDIR = obj
|
||||
COMMON_DIR = ../../bsp
|
||||
GCC_DIR=../../../toolchains/loongson-gnu-toolchain-8.3-x86_64-loongarch32r-linux-gnusf-v2.0
|
||||
PICOLIBC_DIR=../../../toolchains/picolibc
|
||||
|
||||
ifeq ($(MATMUL_FAST_START),1)
|
||||
LINKER_SCRIPT := script_matmul_fast.lds
|
||||
BSP_STARTUP := start_matmul_fast.S
|
||||
BSP_USE_TRAP := 0
|
||||
BSP_USE_DRIVERS := 0
|
||||
endif
|
||||
|
||||
include ../../bsp/common.mk
|
||||
|
||||
# Strip picolibc: no -lc -lm -lg -lsemihost, keep -lgcc only
|
||||
|
||||
@@ -9,21 +9,47 @@ typedef struct {
|
||||
volatile u32 TAG; // 0x0C: software tag (ignored by HW)
|
||||
volatile u32 CTRL; // 0x10: control (burst config + start)
|
||||
volatile u32 STATUS; // 0x14: status (busy, done)
|
||||
volatile u32 RESV[10]; // 0x18 ~ 0x3C: padding to 0x40 bytes
|
||||
volatile u32 MODE; // 0x18: 0=mem2mem, 1=mem2ep, 2=ep2mem
|
||||
volatile u32 EP_CFG; // 0x1C: [3:0]=bank, [15:8]=word offset, [19:16]=endpoint id
|
||||
volatile u32 RESV[8]; // 0x20 ~ 0x3C: padding to 0x40 bytes
|
||||
} dma_ch_regs_t;
|
||||
|
||||
// DMA 控制器基地址
|
||||
#define CDMA_MUX_BASE 0xbf300000
|
||||
#define DMA_CH(i) ((volatile dma_ch_regs_t*)(CDMA_MUX_BASE + (i) * 0x40))
|
||||
|
||||
typedef struct {
|
||||
volatile u32 CTRL; // 0x200: bit0 start
|
||||
volatile u32 STATUS; // 0x204: bit0 busy, bit1 done (W1C)
|
||||
volatile u32 SRC_BASE; // 0x208
|
||||
volatile u32 DST_BASE; // 0x20C
|
||||
volatile u32 GROUPS; // 0x210
|
||||
volatile u32 MAT_BASE; // 0x214: reserved for compatibility
|
||||
volatile u32 SRC_STRIDE; // 0x218
|
||||
volatile u32 DST_STRIDE; // 0x21C
|
||||
} dma_seq_regs_t;
|
||||
|
||||
#define DMA_SEQ ((volatile dma_seq_regs_t*)(CDMA_MUX_BASE + 0x200))
|
||||
|
||||
// CTRL 寄存器位定义
|
||||
#define CTRL_START_BIT (1 << 0)
|
||||
#define CTRL_BURST_SIZE(x) (((x) & 0x7) << 3) // Bits [5:3]: AXI AxSIZE (0=1B, 1=2B, 2=4B, 3=8B)
|
||||
#define CTRL_BURST_LEN(x) (((x) & 0xFF) << 6) // Bits [13:6]: AXI AxLEN (0=1 beat, 15=16 beats)
|
||||
|
||||
#define DMA_MODE_MEM2MEM 0
|
||||
#define DMA_MODE_MEM2EP 1
|
||||
#define DMA_MODE_EP2MEM 2
|
||||
#define DMA_EP_CFG(id, bank, word_off) \
|
||||
((((id) & 0xF) << 16) | (((word_off) & 0xFF) << 8) | ((bank) & 0xF))
|
||||
|
||||
// STATUS 寄存器位定义
|
||||
#define STATUS_BUSY_BIT (1 << 0)
|
||||
#define STATUS_DONE_BIT (1 << 1)
|
||||
|
||||
#define SEQ_START_BIT (1 << 0)
|
||||
#define SEQ_SKIP_STORE_BIT (1 << 1)
|
||||
#define SEQ_BUSY_BIT (1 << 0)
|
||||
#define SEQ_DONE_BIT (1 << 1)
|
||||
|
||||
void dma_start_transfer(int ch_id, u32 src, u32 dst, u32 bytes, u32 tag);
|
||||
void dma_wait_polling(int ch_id);
|
||||
90
sdk/software/examples/asm/script_matmul_fast.lds
Normal file
@@ -0,0 +1,90 @@
|
||||
OUTPUT_ARCH(loongarch)
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
isram (rwxai) : ORIGIN = 0x1c000000, LENGTH = 512K
|
||||
dsram (rwxai) : ORIGIN = 0x1c080000, LENGTH = 512K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
__stack_size = DEFINED(__stack_size) ? __stack_size : 4K;
|
||||
|
||||
.init :
|
||||
{
|
||||
KEEP(*(SORT_NONE(.init)))
|
||||
} >isram AT>isram
|
||||
|
||||
. = ALIGN(16);
|
||||
.text :
|
||||
{
|
||||
_ftext = .;
|
||||
*(.text.unlikely .text.unlikely.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text .text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
} >isram AT>isram
|
||||
|
||||
. = ALIGN(16);
|
||||
.rodata :
|
||||
{
|
||||
*(.rdata)
|
||||
*(.rodata .rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.srodata.cst16)
|
||||
*(.srodata.cst8)
|
||||
*(.srodata.cst4)
|
||||
*(.srodata.cst2)
|
||||
*(.srodata .srodata.*)
|
||||
} >isram AT>isram
|
||||
|
||||
. = ALIGN(16);
|
||||
PROVIDE(__etext = .);
|
||||
PROVIDE(_etext = .);
|
||||
PROVIDE(etext = .);
|
||||
PROVIDE(_data_lma = .);
|
||||
|
||||
.data ORIGIN(dsram) :
|
||||
{
|
||||
PROVIDE(_data = .);
|
||||
*(.data .data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
. = ALIGN(16);
|
||||
PROVIDE(__global_pointer$ = . + 0x800);
|
||||
*(.sdata .sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
. = ALIGN(16);
|
||||
PROVIDE(_edata = .);
|
||||
PROVIDE(edata = .);
|
||||
} >dsram AT>isram
|
||||
|
||||
.bss :
|
||||
{
|
||||
PROVIDE(__bss_start = .);
|
||||
*(.sbss*)
|
||||
*(.sbss.*)
|
||||
*(.dynsbss)
|
||||
*(.scommon)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.dynbss)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(16);
|
||||
PROVIDE(_end = .);
|
||||
PROVIDE(end = .);
|
||||
} >dsram AT>dsram
|
||||
|
||||
PROVIDE(__heap_start = _end);
|
||||
|
||||
.stack ORIGIN(dsram) + LENGTH(dsram) - __stack_size :
|
||||
{
|
||||
PROVIDE(_heap_end = .);
|
||||
PROVIDE(__heap_end = _heap_end);
|
||||
PROVIDE(__heap_size = __heap_end - __heap_start);
|
||||
. = __stack_size;
|
||||
PROVIDE(_stack = .);
|
||||
} >dsram AT>dsram
|
||||
}
|
||||
54
sdk/software/examples/asm/start_matmul_fast.S
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "regdef.h"
|
||||
|
||||
.section .init
|
||||
.globl _start
|
||||
.type _start, @function
|
||||
|
||||
_start:
|
||||
/* Enable direct mapped windows used by SRAM and uncached peripherals. */
|
||||
li.w t0, 0x8
|
||||
li.w t1, 0x18
|
||||
csrxchg t0, t1, csr_crmd
|
||||
|
||||
csrwr zero, csr_dmw0
|
||||
csrwr zero, csr_dmw1
|
||||
li.w t0, 0x19
|
||||
csrwr t0, csr_dmw0
|
||||
li.w t0, 0xa0000009
|
||||
csrwr t0, csr_dmw1
|
||||
|
||||
li.w t0, 0x10
|
||||
li.w t1, 0x18
|
||||
csrxchg t0, t1, csr_crmd
|
||||
|
||||
/* Polling-only benchmark: keep interrupts disabled. */
|
||||
li.w t0, 0x4
|
||||
csrxchg zero, t0, csr_crmd
|
||||
csrwr zero, csr_prmd
|
||||
csrwr zero, csr_ecfg
|
||||
|
||||
/* UART0 init, 115200 baud with the same divisor selection as BSP start.S. */
|
||||
li.w t0, 0xbf000000
|
||||
li.w t1, 0x07
|
||||
st.b t1, t0, 2
|
||||
li.w t1, 0x80
|
||||
st.b t1, t0, 3
|
||||
st.b zero, t0, 1
|
||||
li.w t2, 0xbf20f500
|
||||
ld.w t2, t2, 0
|
||||
li.w t1, 0x1b
|
||||
beq zero, t2, 1f
|
||||
li.w t1, 0x1
|
||||
1:
|
||||
st.b t1, t0, 0
|
||||
li.w t1, 0x03
|
||||
st.b t1, t0, 3
|
||||
st.b zero, t0, 4
|
||||
|
||||
la.local sp, _stack
|
||||
li.w a0, 0
|
||||
li.w a1, 0
|
||||
bl main
|
||||
|
||||
1:
|
||||
b 1b
|
||||
@@ -1,213 +1,152 @@
|
||||
/**
|
||||
* user-sample - CIC-IEC 2026 Stage 3 Evaluation Program
|
||||
* user-sample - CICIEC 2026 Stage 3 evaluation program
|
||||
*
|
||||
* (ULTIMATE PERFORMANCE DMA + PING-PONG BUFFER ARCHITECTURE v2)
|
||||
*
|
||||
* Optimizations over v1:
|
||||
* 1. Pre-fire DMA Ch0 load at loop tail → fully overlaps with IP compute
|
||||
* 2. Inlined wait loops → zero function-call overhead in hot path
|
||||
* 3. Inlined DMA start → skips redundant STATUS_BUSY_BIT check
|
||||
* 4. XOR bank toggle → avoids g%2 recomputation per iteration
|
||||
* The CDMA/matmul direct sequencer reads 5000 A/B groups from ExtRAM, writes
|
||||
* the complete C result region, and accumulates the required IEEE CRC32 in
|
||||
* hardware while the C words are streamed out of matmul.
|
||||
*/
|
||||
|
||||
#include <dma.h>
|
||||
|
||||
/* ─── UART 16550 direct access (bypasses slow printf/picolibc) ──────── */
|
||||
#define UART_THR (*(volatile unsigned char *)0xbf000000)
|
||||
#define UART_LSR (*(volatile unsigned char *)0xbf000005)
|
||||
#define LSR_THRE 0x20
|
||||
|
||||
static inline void uart_tx(unsigned char c) {
|
||||
while (!(UART_LSR & LSR_THRE)) {}
|
||||
static inline void uart_tx(unsigned char c)
|
||||
{
|
||||
while ((UART_LSR & LSR_THRE) == 0) {
|
||||
}
|
||||
UART_THR = c;
|
||||
}
|
||||
|
||||
static void uart_puts(const char *s) {
|
||||
while (*s) uart_tx(*s++);
|
||||
}
|
||||
|
||||
static void uart_puthex(unsigned int val) {
|
||||
int i;
|
||||
for (i = 28; i >= 0; i -= 4) {
|
||||
unsigned char nibble = (val >> i) & 0xF;
|
||||
uart_tx(nibble < 10 ? '0' + nibble : 'a' + nibble - 10);
|
||||
static void uart_puts(const char *s)
|
||||
{
|
||||
while (*s) {
|
||||
uart_tx((unsigned char)*s++);
|
||||
}
|
||||
}
|
||||
|
||||
/* ─── Configurable group count (default 5000) ──────────────────────── */
|
||||
static void uart_put_matmul_start_fifo(void)
|
||||
{
|
||||
UART_THR = 'M';
|
||||
UART_THR = 'A';
|
||||
UART_THR = 'T';
|
||||
UART_THR = 'M';
|
||||
UART_THR = 'U';
|
||||
UART_THR = 'L';
|
||||
UART_THR = '_';
|
||||
UART_THR = 'S';
|
||||
UART_THR = 'T';
|
||||
UART_THR = 'A';
|
||||
UART_THR = 'R';
|
||||
UART_THR = 'T';
|
||||
}
|
||||
|
||||
static inline void uart_wait_tx_empty(void)
|
||||
{
|
||||
while ((UART_LSR & LSR_THRE) == 0) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned char hex_digit(unsigned int val, int shift)
|
||||
{
|
||||
unsigned char nibble = (unsigned char)((val >> shift) & 0xf);
|
||||
|
||||
return (unsigned char)(nibble < 10 ? ('0' + nibble) : ('a' + nibble - 10));
|
||||
}
|
||||
|
||||
static void uart_put_result_fifo(unsigned int crc)
|
||||
{
|
||||
uart_wait_tx_empty();
|
||||
UART_THR = 'M';
|
||||
UART_THR = 'A';
|
||||
UART_THR = 'T';
|
||||
UART_THR = 'M';
|
||||
UART_THR = 'U';
|
||||
UART_THR = 'L';
|
||||
UART_THR = '_';
|
||||
UART_THR = 'C';
|
||||
UART_THR = 'R';
|
||||
UART_THR = 'C';
|
||||
UART_THR = '3';
|
||||
UART_THR = '2';
|
||||
UART_THR = '=';
|
||||
UART_THR = hex_digit(crc, 28);
|
||||
UART_THR = hex_digit(crc, 24);
|
||||
UART_THR = hex_digit(crc, 20);
|
||||
|
||||
uart_wait_tx_empty();
|
||||
UART_THR = hex_digit(crc, 16);
|
||||
UART_THR = hex_digit(crc, 12);
|
||||
UART_THR = hex_digit(crc, 8);
|
||||
UART_THR = hex_digit(crc, 4);
|
||||
UART_THR = hex_digit(crc, 0);
|
||||
UART_THR = 'M';
|
||||
UART_THR = 'A';
|
||||
UART_THR = 'T';
|
||||
UART_THR = 'M';
|
||||
UART_THR = 'U';
|
||||
UART_THR = 'L';
|
||||
UART_THR = '_';
|
||||
UART_THR = 'D';
|
||||
UART_THR = 'O';
|
||||
UART_THR = 'N';
|
||||
UART_THR = 'E';
|
||||
}
|
||||
|
||||
#ifndef MATMUL_GROUP_NUM
|
||||
#define MATMUL_GROUP_NUM 5000
|
||||
#endif
|
||||
|
||||
/* ─── BSP globals ─────────────────────────────────────────────────── */
|
||||
unsigned long UART_BASE = 0xbf000000;
|
||||
unsigned long CONFREG_TIMER_BASE = 0xbf20f100;
|
||||
unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L;
|
||||
unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
|
||||
#ifndef MATMUL_WRITEBACK_RESULTS
|
||||
#define MATMUL_WRITEBACK_RESULTS 1
|
||||
#endif
|
||||
|
||||
/* ─── Memory layout ────────────────────────────────────────────────── */
|
||||
#define EXTRAM_BASE_PHYS 0x1c400000
|
||||
#define EXTRAM_BASE_UNCACHED (0xA0000000 | (EXTRAM_BASE_PHYS & 0x1FFFFFFF))
|
||||
#if MATMUL_FAST_START == 0
|
||||
unsigned long UART_BASE = 0xbf000000;
|
||||
#endif
|
||||
|
||||
#define SRC_BASE_WORDS 0
|
||||
#define DST_BASE_WORDS (SRC_BASE_WORDS + MATMUL_GROUP_NUM * 32)
|
||||
#define RESULT_WORDS (MATMUL_GROUP_NUM * 48)
|
||||
#define EXTRAM_BASE_PHYS 0x1c400000u
|
||||
#define SRC_BASE_WORDS 0u
|
||||
#define DST_BASE_WORDS (SRC_BASE_WORDS + MATMUL_GROUP_NUM * 32u)
|
||||
|
||||
/* ExtRAM Physical Addresses for DMA */
|
||||
#define EXTRAM_PHYS_AB(g) (EXTRAM_BASE_PHYS + (SRC_BASE_WORDS * 4) + (g) * 128)
|
||||
#define EXTRAM_PHYS_C(g) (EXTRAM_BASE_PHYS + (DST_BASE_WORDS * 4) + (g) * 192)
|
||||
#define EXTRAM_PHYS_AB(g) (EXTRAM_BASE_PHYS + (SRC_BASE_WORDS * 4u) + (unsigned int)(g) * 128u)
|
||||
#define EXTRAM_PHYS_C(g) (EXTRAM_BASE_PHYS + (DST_BASE_WORDS * 4u) + (unsigned int)(g) * 192u)
|
||||
|
||||
/* ─── MATMUL IP registers (Ping-Pong Memory Map) ──────────────────── */
|
||||
#define MATMUL_BASE_PHYS 0x1f500000
|
||||
#define MATMUL_BASE_UNCACHED 0xbf500000
|
||||
#define MATMUL_BASE_UNCACHED 0xbf500000u
|
||||
#define MATMUL_CRC (*(volatile unsigned int *)(MATMUL_BASE_UNCACHED + 0x010u))
|
||||
|
||||
#define MATMUL_CTRL (MATMUL_BASE_UNCACHED + 0x000)
|
||||
#define MATMUL_STATUS (MATMUL_BASE_UNCACHED + 0x004)
|
||||
#define MATMUL_PHYS_B0_AB (MATMUL_BASE_PHYS + 0x100)
|
||||
#define MATMUL_PHYS_B0_C (MATMUL_BASE_PHYS + 0x180)
|
||||
#define MATMUL_PHYS_B1_AB (MATMUL_BASE_PHYS + 0x300)
|
||||
#define MATMUL_PHYS_B1_C (MATMUL_BASE_PHYS + 0x380)
|
||||
|
||||
#define CTRL_START_B0 0x1
|
||||
#define CTRL_START_B1 0x2
|
||||
#define STATUS_DONE 0x2
|
||||
#define STATUS_ERROR 0x4
|
||||
|
||||
#define MATMUL_CRC (MATMUL_BASE_UNCACHED + 0x010)
|
||||
|
||||
/* ─── Pre-computed DMA burst control word ──────────────────────────── */
|
||||
#define DMA_CTRL_VAL (CTRL_BURST_SIZE(2) | CTRL_BURST_LEN(63) | CTRL_START_BIT)
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════ */
|
||||
int main(void)
|
||||
{
|
||||
if (MATMUL_GROUP_NUM <= 0) return 0;
|
||||
|
||||
/* ── Hot-path local volatile pointers (one-time addr calc) ──────── */
|
||||
volatile unsigned int *mat_status = (volatile unsigned int *)MATMUL_STATUS;
|
||||
volatile unsigned int *mat_ctrl = (volatile unsigned int *)MATMUL_CTRL;
|
||||
volatile unsigned int *mat_crc = (volatile unsigned int *)MATMUL_CRC;
|
||||
volatile dma_ch_regs_t *ch0 = DMA_CH(0);
|
||||
volatile dma_ch_regs_t *ch1 = DMA_CH(1);
|
||||
|
||||
unsigned int crc;
|
||||
int g, bank;
|
||||
unsigned int seq_ctrl;
|
||||
|
||||
// Ping-Pong Register Address Arrays (Physical for DMA)
|
||||
unsigned int phys_bank_AB[2] = {MATMUL_PHYS_B0_AB, MATMUL_PHYS_B1_AB};
|
||||
unsigned int phys_bank_C[2] = {MATMUL_PHYS_B0_C, MATMUL_PHYS_B1_C};
|
||||
unsigned int ctrl_start[2] = {CTRL_START_B0, CTRL_START_B1};
|
||||
|
||||
/* ── Start marker (must be first output) ──────────────────── */
|
||||
uart_puts("MATMUL_START\r\n");
|
||||
|
||||
// Reset IP state
|
||||
*mat_status = STATUS_DONE | STATUS_ERROR;
|
||||
*mat_crc = 0;
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════
|
||||
* PROLOGUE: Load group 0 → Bank 0, start IP, pre-fire group 1
|
||||
* ═══════════════════════════════════════════════════════════════ */
|
||||
|
||||
// DMA Ch0: Load group 0 A+B (128 bytes) → IP Bank 0
|
||||
ch0->SRC_ADDR = EXTRAM_PHYS_AB(0);
|
||||
ch0->DST_ADDR = phys_bank_AB[0];
|
||||
ch0->LENGTH = 128;
|
||||
ch0->CTRL = DMA_CTRL_VAL;
|
||||
while (!(ch0->STATUS & STATUS_DONE_BIT)) {}
|
||||
ch0->STATUS = STATUS_DONE_BIT;
|
||||
|
||||
// Start IP Bank 0 (group 0)
|
||||
*mat_ctrl = ctrl_start[0];
|
||||
|
||||
// Pre-fire: DMA Ch0 load group 1 → Bank 1 (overlaps with IP compute)
|
||||
if (MATMUL_GROUP_NUM > 1) {
|
||||
ch0->SRC_ADDR = EXTRAM_PHYS_AB(1);
|
||||
ch0->DST_ADDR = phys_bank_AB[1];
|
||||
ch0->LENGTH = 128;
|
||||
ch0->CTRL = DMA_CTRL_VAL;
|
||||
if (MATMUL_GROUP_NUM <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════
|
||||
* MAIN LOOP: Fully-pipelined — pre-fire DMA load at loop tail
|
||||
*
|
||||
* At iteration g:
|
||||
* IP is computing group (g-1) on prev_bank
|
||||
* Ch0 loaded group g to cur_bank (pre-fired in iteration g-1)
|
||||
*
|
||||
* Pipeline:
|
||||
* Ch0: | load g+1 | | load g+2 |
|
||||
* Ch1: | store g-1 | | store g |
|
||||
* IP : | compute g | | compute g+1 |
|
||||
* ═══════════════════════════════════════════════════════════════ */
|
||||
bank = 1; // cur_bank for iteration g=1; prev_bank = bank ^ 1
|
||||
DMA_SEQ->STATUS = SEQ_DONE_BIT;
|
||||
DMA_SEQ->SRC_BASE = EXTRAM_PHYS_AB(0);
|
||||
DMA_SEQ->DST_BASE = EXTRAM_PHYS_C(0);
|
||||
DMA_SEQ->GROUPS = MATMUL_GROUP_NUM;
|
||||
DMA_SEQ->MAT_BASE = 0x1f500000u;
|
||||
DMA_SEQ->SRC_STRIDE = 128u;
|
||||
DMA_SEQ->DST_STRIDE = 192u;
|
||||
seq_ctrl = SEQ_START_BIT;
|
||||
#if MATMUL_WRITEBACK_RESULTS == 0
|
||||
seq_ctrl |= SEQ_SKIP_STORE_BIT;
|
||||
#endif
|
||||
|
||||
for (g = 1; g < MATMUL_GROUP_NUM; g++) {
|
||||
int cur_bank = bank;
|
||||
int prev_bank = bank ^ 1;
|
||||
uart_put_matmul_start_fifo();
|
||||
DMA_SEQ->CTRL = seq_ctrl;
|
||||
|
||||
// 1. Wait for previous IP computation (group g-1 on prev_bank)
|
||||
while (!(*mat_status & STATUS_DONE)) {}
|
||||
*mat_status = STATUS_DONE;
|
||||
|
||||
// 2. Ensure previous DMA Ch1 store is done (group g-2)
|
||||
if (g > 1) {
|
||||
while (!(ch1->STATUS & STATUS_DONE_BIT)) {}
|
||||
ch1->STATUS = STATUS_DONE_BIT;
|
||||
}
|
||||
|
||||
// 3. Start DMA Ch1 store: group (g-1) result → ExtRAM
|
||||
ch1->SRC_ADDR = phys_bank_C[prev_bank];
|
||||
ch1->DST_ADDR = EXTRAM_PHYS_C(g - 1);
|
||||
ch1->LENGTH = 192;
|
||||
ch1->CTRL = DMA_CTRL_VAL;
|
||||
|
||||
// 4. Wait for current DMA Ch0 load (group g → cur_bank, pre-fired in iteration g-1)
|
||||
while (!(ch0->STATUS & STATUS_DONE_BIT)) {}
|
||||
ch0->STATUS = STATUS_DONE_BIT;
|
||||
|
||||
// 5. Start IP computation for current group on cur_bank
|
||||
*mat_ctrl = ctrl_start[cur_bank];
|
||||
|
||||
// ★ 6. PRE-FIRE: DMA Ch0 load next group (g+1) → next_bank
|
||||
// This runs CONCURRENTLY with IP computation started in step 5!
|
||||
if (g < MATMUL_GROUP_NUM - 1) {
|
||||
int next_bank = bank ^ 1;
|
||||
ch0->SRC_ADDR = EXTRAM_PHYS_AB(g + 1);
|
||||
ch0->DST_ADDR = phys_bank_AB[next_bank];
|
||||
ch0->LENGTH = 128;
|
||||
ch0->CTRL = DMA_CTRL_VAL;
|
||||
}
|
||||
|
||||
// Toggle bank for next iteration
|
||||
bank ^= 1;
|
||||
while ((DMA_SEQ->STATUS & SEQ_DONE_BIT) == 0u) {
|
||||
}
|
||||
DMA_SEQ->STATUS = SEQ_DONE_BIT;
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════
|
||||
* EPILOGUE: Flush the final group
|
||||
* ═══════════════════════════════════════════════════════════════ */
|
||||
crc = MATMUL_CRC;
|
||||
|
||||
// Wait for last IP computation
|
||||
while (!(*mat_status & STATUS_DONE)) {}
|
||||
*mat_status = STATUS_DONE;
|
||||
|
||||
// Wait for previous DMA store and start/complete final store
|
||||
while (!(ch1->STATUS & STATUS_DONE_BIT)) {}
|
||||
ch1->STATUS = STATUS_DONE_BIT;
|
||||
|
||||
ch1->SRC_ADDR = phys_bank_C[(MATMUL_GROUP_NUM - 1) % 2];
|
||||
ch1->DST_ADDR = EXTRAM_PHYS_C(MATMUL_GROUP_NUM - 1);
|
||||
ch1->LENGTH = 192;
|
||||
ch1->CTRL = DMA_CTRL_VAL;
|
||||
while (!(ch1->STATUS & STATUS_DONE_BIT)) {}
|
||||
ch1->STATUS = STATUS_DONE_BIT;
|
||||
|
||||
/* ── Read hardware CRC32 ──────────────────────────────────── */
|
||||
crc = *mat_crc;
|
||||
|
||||
uart_puts("MATMUL_CRC32=");
|
||||
uart_puthex(crc);
|
||||
uart_puts("\r\nMATMUL_DONE\r\n");
|
||||
uart_put_result_fifo(crc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#define FFT_BASE 0xbf400000
|
||||
#define FFT_IN_RE_BASE (FFT_BASE + 0x1000)
|
||||
#define FFT_IN_IM_BASE (FFT_BASE + 0x2000)
|
||||
#define FFT_OUT_RE_BASE (FFT_BASE + 0x3000)
|
||||
#define FFT_OUT_IM_BASE (FFT_BASE + 0x4000)
|
||||
#define FFT_CSR_REG (FFT_BASE + 0xF000)
|
||||
#define FFT_IN_RE_BASE (FFT_BASE + 0x8000)
|
||||
#define FFT_IN_IM_BASE (FFT_BASE + 0x9000)
|
||||
#define FFT_OUT_RE_BASE (FFT_BASE + 0xA000)
|
||||
#define FFT_OUT_IM_BASE (FFT_BASE + 0xB000)
|
||||
#define FFT_CSR_REG (FFT_BASE + 0xC000)
|
||||
#define FFT_CTRL_START (1 << 4)
|
||||
#define FFT_STAT_DONE (1 << 1)
|
||||
#define FFT_STAT_BUSY (1 << 0)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <common_func.h>
|
||||
#include <confreg_time.h>
|
||||
#include <fft.h>
|
||||
#include "../fft_test_data.h"
|
||||
|
||||
// BSP板级支持包所需全局变量
|
||||
unsigned long UART_BASE = 0xbf000000;
|
||||
@@ -80,12 +81,7 @@ int main(int argc, char** argv)
|
||||
float sw_in_im[FFT_POINT_NUM];
|
||||
|
||||
for (int i = 0; i < FFT_POINT_NUM; i++) {
|
||||
float dc_part = 4000.0f;
|
||||
float f10_part = 8000.0f * cos(2 * PI * 10.0 * i / FFT_POINT_NUM);
|
||||
float f200_part = 6000.0f * sin(2 * PI * 200.0 * i / FFT_POINT_NUM);
|
||||
float f400_part = 3000.0f * sin(2 * PI * 400.0 * i / FFT_POINT_NUM);
|
||||
|
||||
sw_in_re[i] = dc_part + f10_part + f200_part + f400_part;
|
||||
sw_in_re[i] = (float)fft_test_sample((unsigned int)i);
|
||||
sw_in_im[i] = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#define FFT_BASE 0xbf400000
|
||||
#define FFT_IN_RE_BASE (FFT_BASE + 0x1000)
|
||||
#define FFT_IN_IM_BASE (FFT_BASE + 0x2000)
|
||||
#define FFT_OUT_RE_BASE (FFT_BASE + 0x3000)
|
||||
#define FFT_OUT_IM_BASE (FFT_BASE + 0x4000)
|
||||
#define FFT_CSR_REG (FFT_BASE + 0xF000)
|
||||
#define FFT_IN_RE_BASE (FFT_BASE + 0x8000)
|
||||
#define FFT_IN_IM_BASE (FFT_BASE + 0x9000)
|
||||
#define FFT_OUT_RE_BASE (FFT_BASE + 0xA000)
|
||||
#define FFT_OUT_IM_BASE (FFT_BASE + 0xB000)
|
||||
#define FFT_CSR_REG (FFT_BASE + 0xC000)
|
||||
#define FFT_CTRL_START (1 << 4)
|
||||
#define FFT_STAT_DONE (1 << 1)
|
||||
#define FFT_STAT_BUSY (1 << 0)
|
||||
#define FFT_POINT_NUM 1024
|
||||
#define FFT_SAMPLE_BITS 16
|
||||
|
||||
void fft_start();
|
||||
void fft_wait();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <confreg_time.h>
|
||||
#include <dma.h>
|
||||
#include <fft.h>
|
||||
#include "../fft_test_data.h"
|
||||
|
||||
// BSP板级支持包所需全局变量
|
||||
unsigned long UART_BASE = 0xbf000000;
|
||||
@@ -66,7 +67,8 @@ void sw_fft(float re[], float im[], int n) {
|
||||
}
|
||||
}
|
||||
|
||||
// 全局对齐数组:作为 DMA 的源和目的内存
|
||||
// 全局对齐数组:作为 DMA 的源和目的内存。
|
||||
// FFT 外设仍按 32-bit AXI word 编址,每个 word 的低 16 bit 作为一个 signed 样本。
|
||||
int32_t hw_in_re_arr[FFT_POINT_NUM] __attribute__((aligned(64)));
|
||||
int32_t hw_in_im_arr[FFT_POINT_NUM] __attribute__((aligned(64)));
|
||||
int32_t hw_out_re_arr[FFT_POINT_NUM] __attribute__((aligned(64)));
|
||||
@@ -93,18 +95,14 @@ int main(int argc, char** argv)
|
||||
float sw_in_re[FFT_POINT_NUM];
|
||||
float sw_in_im[FFT_POINT_NUM];
|
||||
|
||||
// 初始化测试波形
|
||||
for (int i = 0; i < FFT_POINT_NUM; i++) {
|
||||
float dc_part = 4000.0f;
|
||||
float f10_part = 8000.0f * cos(2 * PI * 10.0 * i / FFT_POINT_NUM);
|
||||
float f200_part = 6000.0f * sin(2 * PI * 200.0 * i / FFT_POINT_NUM);
|
||||
float f400_part = 3000.0f * sin(2 * PI * 400.0 * i / FFT_POINT_NUM);
|
||||
int16_t sample = (int16_t)fft_test_sample((unsigned int)i);
|
||||
|
||||
sw_in_re[i] = dc_part + f10_part + f200_part + f400_part;
|
||||
sw_in_re[i] = (float)sample;
|
||||
sw_in_im[i] = 0.0f;
|
||||
|
||||
// 硬件输入需要转为整数存入无缓存内存
|
||||
uncached_in_re[i] = (int32_t)sw_in_re[i];
|
||||
// 硬件输入为 16-bit signed,写入 32-bit word 的低半字。
|
||||
uncached_in_re[i] = (int32_t)sample;
|
||||
uncached_in_im[i] = 0;
|
||||
|
||||
// 清理输出内存以防干扰
|
||||
@@ -119,7 +117,7 @@ int main(int argc, char** argv)
|
||||
printf("\n--- Starting Hardware FFT with DMA ---\n");
|
||||
tick_start = get_ns(); // 开始计时
|
||||
|
||||
uint32_t transfer_bytes = FFT_POINT_NUM * 4; // 1024个点 * 4字节
|
||||
uint32_t transfer_bytes = FFT_POINT_NUM * 4; // 1024个点 * 4字节,低16位有效
|
||||
|
||||
// MA 将数据从内存搬运到 FFT 输入外设
|
||||
dma_start_transfer(0, ((uint32_t)hw_in_re_arr & 0x1FFFFFFF), phys_fft_in_re, transfer_bytes, 100);
|
||||
@@ -161,19 +159,31 @@ int main(int argc, char** argv)
|
||||
printf("Speedup Ratio : %.2fx\n", (float)sw_time / hw_time);
|
||||
}
|
||||
|
||||
printf("\n--- Verification (Only showing Bins with energy > 10) ---\n");
|
||||
printf("\n--- Verification (%d-bit FFT, only showing bins with energy > 10) ---\n", FFT_SAMPLE_BITS);
|
||||
int max_abs_err_re = 0;
|
||||
int max_abs_err_im = 0;
|
||||
for (int i = 0; i < FFT_POINT_NUM; i++) {
|
||||
// CPU 通过无缓存指针读取 DMA 搬运回来的结果
|
||||
int32_t hw_re = uncached_out_re[i];
|
||||
int32_t hw_im = uncached_out_im[i];
|
||||
int32_t sw_re = (int32_t)sw_in_re[i] / FFT_POINT_NUM;
|
||||
int32_t sw_im = (int32_t)sw_in_im[i] / FFT_POINT_NUM;
|
||||
int err_re = (int)(hw_re - sw_re);
|
||||
int err_im = (int)(hw_im - sw_im);
|
||||
|
||||
if (err_re < 0) err_re = -err_re;
|
||||
if (err_im < 0) err_im = -err_im;
|
||||
if (err_re > max_abs_err_re) max_abs_err_re = err_re;
|
||||
if (err_im > max_abs_err_im) max_abs_err_im = err_im;
|
||||
|
||||
if (fabs((float)hw_re) > 10 || fabs((float)hw_im) > 10) {
|
||||
printf("Bin [%4d] Hz: HW(Re:%6d, Im:%6d) | SW(Re:%6d, Im:%6d)\n",
|
||||
i,
|
||||
hw_re, hw_im,
|
||||
(int)sw_in_re[i] / FFT_POINT_NUM, (int)sw_in_im[i] / FFT_POINT_NUM);
|
||||
sw_re, sw_im);
|
||||
}
|
||||
}
|
||||
printf("Max Abs Error : Re=%d, Im=%d\n", max_abs_err_re, max_abs_err_im);
|
||||
|
||||
return 0;
|
||||
}
|
||||
80
sdk/software/examples/fft_test_data.h
Normal file
@@ -0,0 +1,80 @@
|
||||
#ifndef FFT_TEST_DATA_H
|
||||
#define FFT_TEST_DATA_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define FFT_TEST_INPUT_PERIOD 512u
|
||||
|
||||
static const int16_t fft_test_input[FFT_TEST_INPUT_PERIOD] = {
|
||||
12000, 19537, 12803, 11425, 4727, 9875, 19249, 12733,
|
||||
10880, 4524, 7132, 17935, 12144, 9543, 3839, 3959,
|
||||
15687, 11133, 7594, 2745, 590, 12673, 9827, 5271,
|
||||
1362, -2720, 9126, 8377, 2848, -157, -5714, 5322,
|
||||
6938, 609, -1638, -8154, 1552, 5655, -1182, -2905,
|
||||
-9848, -1895, 4649, -2305, -3793, -10662, -4769, 4007,
|
||||
-2603, -4173, -10534, -6871, 3770, -2002, -3957, -9482,
|
||||
-8072, 3932, -516, -3110, -7598, -8327, 4441, 1752,
|
||||
-1656, -5045, -7670, 5204, 4623, 325, -2039, -6218,
|
||||
6095, 7850, 2707, 1169, -4152, 6970, 11144, 5322,
|
||||
4318, -1704, 7682, 14204, 7982, 7154, 871, 8097,
|
||||
16739, 10488, 9460, 3315, 8107, 18497, 12656, 11071,
|
||||
5391, 7640, 19290, 14327, 11890, 6906, 6674, 19009,
|
||||
15383, 11898, 7730, 5238, 17637, 15758, 11148, 7806,
|
||||
3409, 15251, 15443, 9769, 7155, 1308, 12014, 14483,
|
||||
7945, 5871, -906, 8167, 12976, 5903, 4115, -3061,
|
||||
4000, 11061, 3884, 2096, -4976, -167, 8906, 2128,
|
||||
54, -6483, -4014, 6691, 844, -1769, -7443, -7251,
|
||||
4590, 193, -3148, -7758, -9637, 2761, 269, -3898,
|
||||
-7383, -11009, 1325, 1093, -3890, -6327, -11290, 359,
|
||||
2608, -3071, -4656, -10497, -107, 4684, -1460, -2488,
|
||||
-8739, -97, 7128, 845, 17, -6204, 317, 9704,
|
||||
3681, 2677, -3144, 1029, 12152, 6830, 5292, 149,
|
||||
1904, 14218, 10039, 7674, 3376, 2795, 15670, 13045,
|
||||
9656, 6247, 3558, 16327, 15598, 11110, 8516, 4067,
|
||||
16072, 17482, 11957, 10002, 4229, 14871, 18534, 12173,
|
||||
10603, 3992, 12769, 18662, 11793, 10305, 3350, 9895,
|
||||
17848, 10905, 9182, 2344, 6447, 16154, 9638, 7390,
|
||||
1061, 2677, 13714, 8157, 5151, -377, -1126, 10720,
|
||||
6637, 2728, -1827, -4673, 7409, 5254, 405, -3133,
|
||||
-7687, 4040, 4160, -1543, -4144, -9935, 867, 3475,
|
||||
-2880, -4733, -11249, -1875, 3272, -3425, -4803, -11537,
|
||||
-3999, 3567, -3075, -4303, -10793, -5377, 4321, -1813,
|
||||
-3230, -9097, -5949, 5444, 289, -1630, -6611, -5728,
|
||||
6798, 3076, 400, -3557, -4800, 8216, 6322, 2729,
|
||||
-206, -3309, 9519, 9750, 5196, 3156, -1446, 10527,
|
||||
13061, 7627, 6247, 570, 11084, 15956, 9850, 8817,
|
||||
2519, 11072, 18167, 11711, 10670, 4193, 10422, 19478,
|
||||
13088, 11680, 5421, 9127, 19750, 13899, 11807, 6084,
|
||||
7238, 18929, 14110, 11091, 6125, 4866, 17055, 13739,
|
||||
9656, 5553, 2173, 14256, 12849, 7693, 4444, -643,
|
||||
10739, 11547, 5442, 2933, -3367, 6773, 9967, 3169,
|
||||
1196, -5781, 2663, 8263, 1141, -560, -7688, -1274,
|
||||
6589, -401, -2127, -8927, -4744, 5086, -1264, -3307,
|
||||
-9391, -7489, 3870, -1325, -3935, -9034, -9320, 3020,
|
||||
-539, -3898, -7880, -10128, 2572, 1053, -3142, -6016,
|
||||
-9894, 2517, 3328, -1682, -3589, -8688, 2801, 6090,
|
||||
403, -791, -6665, 3335, 9088, 2974, 2156, -4043,
|
||||
3999, 12043, 5843, 5025, -1088, 4664, 14665, 8791,
|
||||
7596, 1909, 5198, 16688, 11589, 9682, 4671, 5482,
|
||||
17894, 14016, 11142, 6946, 5427, 18128, 15880, 11898,
|
||||
8539, 4979, 17320, 17034, 11935, 9325, 4129, 15489,
|
||||
17391, 11307, 9264, 2913, 12744, 16927, 10127, 8401,
|
||||
1410, 9274, 15688, 8560, 6858, -263, 5336, 13781,
|
||||
6803, 4830, -1967, 1226, 11367, 5066, 2557, -3547,
|
||||
-2739, 8643, 3555, 306, -4849, -6256, 5826, 2446,
|
||||
-1656, -5739, -9055, 3133, 1874, -3091, -6110, -10929,
|
||||
761, 1915, -3807, -5899, -11750, -1127, 2578, -3680,
|
||||
-5088, -11478, -2422, 3806, -2670, -3711, -10167, -3072,
|
||||
5480, -817, -1850, -7956, -3084, 7429, 1752, 372,
|
||||
-5061, -2527, 9446, 4843, 2803, -1750, -1519, 11309,
|
||||
8206, 5270, 1677, -216, 12800, 11557, 7599, 4923,
|
||||
1201, 13728, 14611, 9630, 7710, 2555, 13949, 17097,
|
||||
11230, 9813, 3678, 13377, 18793, 12303, 11075, 4432,
|
||||
};
|
||||
|
||||
static inline int32_t fft_test_sample(unsigned int index)
|
||||
{
|
||||
return (int32_t)fft_test_input[index & (FFT_TEST_INPUT_PERIOD - 1u)];
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,197 +1,88 @@
|
||||
/**
|
||||
* matmul_test - CIC-IEC 2026 Stage 3 Evaluation Program
|
||||
*
|
||||
* Reads 5000 groups of 4x4 unsigned matrix multiplications from ExtRAM,
|
||||
* computes C = A x B via the hardware matmul IP, writes results back,
|
||||
* computes CRC32 over the result region, and outputs the required identifiers.
|
||||
*
|
||||
* Data layout:
|
||||
* Input: ExtRAM word offset 0x00000000, 5000 * 32 = 160000 words
|
||||
* Result: ExtRAM word offset 0x0009C400, 5000 * 48 = 240000 words
|
||||
* CRC32 over result region byte stream (960000 bytes, little-endian)
|
||||
* Uses the CDMA-to-matmul direct endpoint sequencer. The CDMA still owns the
|
||||
* external-memory traffic, while matmul A/B/C transfers use local wires instead
|
||||
* of the AXI crossbar.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <dma.h>
|
||||
|
||||
/* ─── BSP globals ─────────────────────────────────────────────────── */
|
||||
unsigned long UART_BASE = 0xbf000000;
|
||||
unsigned long CONFREG_TIMER_BASE = 0xbf20f100;
|
||||
unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L;
|
||||
unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
|
||||
/* UART 16550 direct access avoids the printf/newlib overhead on the hot path. */
|
||||
#define UART_THR (*(volatile unsigned char *)0xbf000000)
|
||||
#define UART_LSR (*(volatile unsigned char *)0xbf000005)
|
||||
#define LSR_THRE 0x20
|
||||
|
||||
/* ─── Memory layout ────────────────────────────────────────────────── */
|
||||
#define EXTRAM_BASE_PHYS 0x1c400000
|
||||
#define EXTRAM_BASE (0xA0000000 | (EXTRAM_BASE_PHYS & 0x1FFFFFFF))
|
||||
|
||||
#define SRC_BASE 0
|
||||
#define N_GROUPS 5000
|
||||
#define DST_BASE (SRC_BASE + N_GROUPS * 32) /* word offset 160000 */
|
||||
#define RESULT_WORDS (N_GROUPS * 48) /* 240000 words */
|
||||
#define RESULT_BYTES (RESULT_WORDS * 4) /* 960000 bytes */
|
||||
|
||||
/* ─── MATMUL IP registers ─────────────────────────────────────────── */
|
||||
#define MATMUL_BASE 0xbf500000
|
||||
#define MATMUL_CTRL (MATMUL_BASE + 0x000)
|
||||
#define MATMUL_STATUS (MATMUL_BASE + 0x004)
|
||||
#define MATMUL_A_BASE (MATMUL_BASE + 0x020)
|
||||
#define MATMUL_B_BASE (MATMUL_BASE + 0x060)
|
||||
#define MATMUL_C_BASE (MATMUL_BASE + 0x0a0)
|
||||
|
||||
#define CTRL_START 0x1
|
||||
#define STATUS_BUSY 0x1
|
||||
#define STATUS_DONE 0x2
|
||||
#define STATUS_ERROR 0x4
|
||||
|
||||
/* ─── Convenience macros ──────────────────────────────────────────── */
|
||||
#define REG_WR(addr, val) (*(volatile uint32_t *)(addr) = (uint32_t)(val))
|
||||
#define REG_RD(addr) (*(volatile uint32_t *)(addr))
|
||||
|
||||
/* ─── CRC32 table (IEEE 802.3, polynomial 0xEDB88320) ─────────────── */
|
||||
static const uint32_t crc32_table[256] = {
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
|
||||
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
|
||||
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
||||
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
|
||||
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
|
||||
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
||||
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
|
||||
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
|
||||
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
|
||||
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
|
||||
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
||||
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
|
||||
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
|
||||
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
|
||||
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
||||
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
|
||||
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
|
||||
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
||||
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
|
||||
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
|
||||
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
|
||||
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
|
||||
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
||||
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
|
||||
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
|
||||
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
||||
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
|
||||
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
|
||||
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
|
||||
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
||||
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
|
||||
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
||||
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB30A04,
|
||||
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
|
||||
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
|
||||
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
||||
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
|
||||
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
|
||||
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
|
||||
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
||||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
|
||||
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
|
||||
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
||||
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||
};
|
||||
|
||||
/* ─── Read N words from IP register space ─────────────────────────── */
|
||||
static void read_ip(uint32_t base, volatile uint32_t *dst, int n)
|
||||
static inline void uart_tx(unsigned char c)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
dst[i] = REG_RD(base + i * 4);
|
||||
}
|
||||
|
||||
/* ─── Write N words to IP register space ──────────────────────────── */
|
||||
static void write_ip(uint32_t base, const volatile uint32_t *src, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
REG_WR(base + i * 4, src[i]);
|
||||
}
|
||||
|
||||
/* ─── Poll IP STATUS until done or error ──────────────────────────── */
|
||||
static void wait_done(void)
|
||||
{
|
||||
uint32_t status;
|
||||
do {
|
||||
status = REG_RD(MATMUL_STATUS);
|
||||
} while (!(status & (STATUS_DONE | STATUS_ERROR)));
|
||||
}
|
||||
|
||||
/* ─── CRC32 over ExtRAM result region (little-endian word → byte stream) ─ */
|
||||
static uint32_t compute_crc32(volatile uint32_t *extram)
|
||||
{
|
||||
uint32_t crc = 0xFFFFFFFF;
|
||||
uint32_t i, w;
|
||||
|
||||
for (i = 0; i < RESULT_WORDS; i++) {
|
||||
w = extram[DST_BASE + i];
|
||||
crc = crc32_table[(crc ^ (w & 0xFF)) & 0xFF] ^ (crc >> 8);
|
||||
crc = crc32_table[(crc ^ ((w >> 8) & 0xFF)) & 0xFF] ^ (crc >> 8);
|
||||
crc = crc32_table[(crc ^ ((w >> 16) & 0xFF)) & 0xFF] ^ (crc >> 8);
|
||||
crc = crc32_table[(crc ^ (w >> 24) ) & 0xFF] ^ (crc >> 8);
|
||||
while (!(UART_LSR & LSR_THRE)) {
|
||||
}
|
||||
return crc ^ 0xFFFFFFFF;
|
||||
UART_THR = c;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════ */
|
||||
static void uart_puts(const char *s)
|
||||
{
|
||||
while (*s) {
|
||||
uart_tx((unsigned char)*s++);
|
||||
}
|
||||
}
|
||||
|
||||
static void uart_puthex(uint32_t val)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 28; i >= 0; i -= 4) {
|
||||
unsigned char nibble = (unsigned char)((val >> i) & 0xF);
|
||||
uart_tx((unsigned char)(nibble < 10 ? ('0' + nibble) : ('a' + nibble - 10)));
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef MATMUL_GROUP_NUM
|
||||
#define MATMUL_GROUP_NUM 5000
|
||||
#endif
|
||||
|
||||
unsigned long UART_BASE = 0xbf000000;
|
||||
|
||||
#define EXTRAM_BASE_PHYS 0x1c400000u
|
||||
|
||||
#define SRC_BASE_WORDS 0u
|
||||
#define DST_BASE_WORDS (SRC_BASE_WORDS + MATMUL_GROUP_NUM * 32u)
|
||||
|
||||
#define EXTRAM_PHYS_AB(g) (EXTRAM_BASE_PHYS + (SRC_BASE_WORDS * 4u) + (uint32_t)(g) * 128u)
|
||||
#define EXTRAM_PHYS_C(g) (EXTRAM_BASE_PHYS + (DST_BASE_WORDS * 4u) + (uint32_t)(g) * 192u)
|
||||
|
||||
#define MATMUL_BASE_UNCACHED 0xbf500000u
|
||||
#define MATMUL_CRC (*(volatile uint32_t *)(MATMUL_BASE_UNCACHED + 0x010u))
|
||||
|
||||
int main(void)
|
||||
{
|
||||
volatile uint32_t *extram = (volatile uint32_t *)EXTRAM_BASE;
|
||||
uint32_t a_buf[16], b_buf[16], c_buf[48];
|
||||
uint32_t crc;
|
||||
int g, i;
|
||||
|
||||
/* ── Start marker (must be first output) ──────────────────── */
|
||||
printf("MATMUL_START\n");
|
||||
|
||||
/* ── Process all 5000 groups ──────────────────────────────── */
|
||||
for (g = 0; g < N_GROUPS; g++) {
|
||||
/* Read A[16] + B[16] from ExtRAM */
|
||||
for (i = 0; i < 16; i++) {
|
||||
a_buf[i] = extram[SRC_BASE + g * 32 + i];
|
||||
b_buf[i] = extram[SRC_BASE + g * 32 + 16 + i];
|
||||
}
|
||||
/* Load into IP registers */
|
||||
write_ip(MATMUL_A_BASE, a_buf, 16);
|
||||
write_ip(MATMUL_B_BASE, b_buf, 16);
|
||||
/* Clear status flags, start computation */
|
||||
REG_WR(MATMUL_STATUS, STATUS_DONE | STATUS_ERROR);
|
||||
REG_WR(MATMUL_CTRL, CTRL_START);
|
||||
/* Wait for hardware to finish */
|
||||
wait_done();
|
||||
/* Read C[48] from IP, write to ExtRAM result region */
|
||||
read_ip(MATMUL_C_BASE, c_buf, 48);
|
||||
for (i = 0; i < 48; i++)
|
||||
extram[DST_BASE + g * 48 + i] = c_buf[i];
|
||||
if (MATMUL_GROUP_NUM <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ── CRC32 over result region ─────────────────────────────── */
|
||||
crc = compute_crc32(extram);
|
||||
uart_puts("MATMUL_START\n");
|
||||
|
||||
/* ── Final markers ────────────────────────────────────────── */
|
||||
printf("MATMUL_CRC32=%08lx\n", (unsigned long)crc);
|
||||
printf("MATMUL_DONE\n");
|
||||
DMA_SEQ->STATUS = SEQ_DONE_BIT;
|
||||
DMA_SEQ->SRC_BASE = EXTRAM_PHYS_AB(0);
|
||||
DMA_SEQ->DST_BASE = EXTRAM_PHYS_C(0);
|
||||
DMA_SEQ->GROUPS = MATMUL_GROUP_NUM;
|
||||
DMA_SEQ->MAT_BASE = 0x1f500000u;
|
||||
DMA_SEQ->SRC_STRIDE = 128u;
|
||||
DMA_SEQ->DST_STRIDE = 192u;
|
||||
DMA_SEQ->CTRL = SEQ_START_BIT;
|
||||
|
||||
while ((DMA_SEQ->STATUS & SEQ_DONE_BIT) == 0u) {
|
||||
}
|
||||
DMA_SEQ->STATUS = SEQ_DONE_BIT;
|
||||
|
||||
crc = MATMUL_CRC;
|
||||
|
||||
uart_puts("MATMUL_CRC32=");
|
||||
uart_puthex(crc);
|
||||
uart_puts("\nMATMUL_DONE\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
12
sdk/software/examples/mlkem_hello/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
TARGET = mlkem_hello
|
||||
|
||||
CFLAGS += -O2 -g
|
||||
|
||||
C_SRCS := ./main.c
|
||||
|
||||
OBJDIR = obj
|
||||
COMMON_DIR = ../../bsp
|
||||
GCC_DIR=../../../toolchains/loongson-gnu-toolchain-8.3-x86_64-loongarch32r-linux-gnusf-v2.0
|
||||
PICOLIBC_DIR=../../../toolchains/picolibc
|
||||
LA32RSOC_WINDOWS_HOME ?= ../../..
|
||||
include ../../bsp/common.mk
|
||||
236
sdk/software/examples/mlkem_hello/main.c
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* mlkem_hello - one ML-KEM hardware accelerator communication demo.
|
||||
*
|
||||
* Alice generates an ML-KEM keypair, Bob encapsulates a shared secret to
|
||||
* Alice's public key, and Alice decapsulates Bob's ciphertext. The demo uses
|
||||
* fixed KAT count=0 inputs so it is deterministic and does not require a PRNG.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
unsigned long UART_BASE = 0xbf000000;
|
||||
unsigned long CONFREG_TIMER_BASE = 0xbf20f100;
|
||||
unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L;
|
||||
unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
|
||||
|
||||
#define MLKEM_BASE 0xbf400000
|
||||
#define MLKEM_CTRL (MLKEM_BASE + 0x000)
|
||||
#define MLKEM_STATUS (MLKEM_BASE + 0x004)
|
||||
#define MLKEM_CONFIG (MLKEM_BASE + 0x008)
|
||||
#define MLKEM_D (MLKEM_BASE + 0x010)
|
||||
#define MLKEM_Z (MLKEM_BASE + 0x030)
|
||||
#define MLKEM_MSG (MLKEM_BASE + 0x050)
|
||||
#define MLKEM_SS (MLKEM_BASE + 0x070)
|
||||
#define MLKEM_PRE_SEL (MLKEM_BASE + 0x100)
|
||||
#define MLKEM_PRE_ADR (MLKEM_BASE + 0x104)
|
||||
#define MLKEM_PRE_DAT (MLKEM_BASE + 0x108)
|
||||
#define MLKEM_RDB_SEL (MLKEM_BASE + 0x10C)
|
||||
#define MLKEM_RDB_ADR (MLKEM_BASE + 0x110)
|
||||
#define MLKEM_RDB_DAT (MLKEM_BASE + 0x114)
|
||||
|
||||
#define CTRL_START 0x1
|
||||
#define CTRL_SOFT_RESET 0x2
|
||||
#define STATUS_DONE 0x2
|
||||
|
||||
#define OP_KEYGEN 0
|
||||
#define OP_ENCAPS 1
|
||||
#define OP_DECAPS 2
|
||||
|
||||
#define PRE_EK 0
|
||||
#define PRE_DK 1
|
||||
#define PRE_C 2
|
||||
#define RDB_EK 0
|
||||
#define RDB_DK 2
|
||||
#define RDB_CT 3
|
||||
|
||||
#define MLKEM_K 3
|
||||
#define EK_BYTES (384 * MLKEM_K + 32)
|
||||
#define DK_BYTES (768 * MLKEM_K + 96)
|
||||
#define CT_BYTES (32 * 10 * MLKEM_K + 32 * 4)
|
||||
#define SYM_BYTES 32
|
||||
#define APP_MSG "hello_world"
|
||||
#define APP_MSG_BYTES (sizeof(APP_MSG) - 1)
|
||||
|
||||
#define REG_WR(addr, val) (*(volatile uint32_t *)(addr) = (uint32_t)(val))
|
||||
#define REG_RD(addr) (*(volatile uint32_t *)(addr))
|
||||
|
||||
static uint8_t alice_ek[EK_BYTES] __attribute__((aligned(64)));
|
||||
static uint8_t alice_dk[DK_BYTES] __attribute__((aligned(64)));
|
||||
static uint8_t bob_ct[CT_BYTES] __attribute__((aligned(64)));
|
||||
static uint8_t bob_ss[SYM_BYTES];
|
||||
static uint8_t alice_ss[SYM_BYTES];
|
||||
static uint8_t app_cipher[APP_MSG_BYTES];
|
||||
static uint8_t app_plain_out[APP_MSG_BYTES + 1];
|
||||
|
||||
/* Deterministic ML-KEM KAT count=0 inputs. */
|
||||
static const uint8_t SEED_D[SYM_BYTES] = {
|
||||
0x6d, 0xbb, 0xc4, 0x37, 0x51, 0x36, 0xdf, 0x3b,
|
||||
0x07, 0xf7, 0xc7, 0x0e, 0x63, 0x9e, 0x22, 0x3e,
|
||||
0x17, 0x7e, 0x7f, 0xd5, 0x3b, 0x16, 0x1b, 0x3f,
|
||||
0x4d, 0x57, 0x79, 0x17, 0x94, 0xf1, 0x26, 0x24
|
||||
};
|
||||
|
||||
static const uint8_t SEED_Z[SYM_BYTES] = {
|
||||
0xf6, 0x96, 0x48, 0x40, 0x48, 0xec, 0x21, 0xf9,
|
||||
0x6c, 0xf5, 0x0a, 0x56, 0xd0, 0x75, 0x9c, 0x44,
|
||||
0x8f, 0x37, 0x79, 0x75, 0x2f, 0x03, 0x83, 0xd3,
|
||||
0x74, 0x49, 0x69, 0x06, 0x94, 0xcf, 0x7a, 0x68
|
||||
};
|
||||
|
||||
static const uint8_t MSG_M[SYM_BYTES] = {
|
||||
0x20, 0xa7, 0xb7, 0xe1, 0x0f, 0x70, 0x49, 0x6c,
|
||||
0xc3, 0x82, 0x20, 0xb9, 0x44, 0xde, 0xf6, 0x99,
|
||||
0xbf, 0x14, 0xd1, 0x4e, 0x55, 0xcf, 0x4c, 0x90,
|
||||
0xa1, 0x2c, 0x1b, 0x33, 0xfc, 0x80, 0xff, 0xff
|
||||
};
|
||||
|
||||
static void print_hex(const char *label, const uint8_t *buf, int n)
|
||||
{
|
||||
int i;
|
||||
printf("%s", label);
|
||||
for (i = 0; i < n; i++)
|
||||
printf("%02x", buf[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void xor_with_shared_secret(uint8_t *dst, const uint8_t *src, int n,
|
||||
const uint8_t *ss)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
dst[i] = src[i] ^ ss[i % SYM_BYTES];
|
||||
}
|
||||
|
||||
static void write_block32(uint32_t base, const uint8_t *bytes)
|
||||
{
|
||||
int w;
|
||||
for (w = 0; w < 8; w++) {
|
||||
uint32_t v = (uint32_t)bytes[w * 4 + 0]
|
||||
| ((uint32_t)bytes[w * 4 + 1] << 8)
|
||||
| ((uint32_t)bytes[w * 4 + 2] << 16)
|
||||
| ((uint32_t)bytes[w * 4 + 3] << 24);
|
||||
REG_WR(base + w * 4, v);
|
||||
}
|
||||
}
|
||||
|
||||
static void read_block32(uint32_t base, uint8_t *bytes)
|
||||
{
|
||||
int w;
|
||||
for (w = 0; w < 8; w++) {
|
||||
uint32_t v = REG_RD(base + w * 4);
|
||||
bytes[w * 4 + 0] = (uint8_t)(v & 0xFF);
|
||||
bytes[w * 4 + 1] = (uint8_t)((v >> 8) & 0xFF);
|
||||
bytes[w * 4 + 2] = (uint8_t)((v >> 16) & 0xFF);
|
||||
bytes[w * 4 + 3] = (uint8_t)((v >> 24) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_done(void)
|
||||
{
|
||||
REG_WR(MLKEM_STATUS, STATUS_DONE);
|
||||
}
|
||||
|
||||
static void wait_done(void)
|
||||
{
|
||||
while ((REG_RD(MLKEM_STATUS) & STATUS_DONE) == 0)
|
||||
;
|
||||
}
|
||||
|
||||
static void mlkem_soft_reset(void)
|
||||
{
|
||||
REG_WR(MLKEM_CTRL, CTRL_SOFT_RESET);
|
||||
clear_done();
|
||||
}
|
||||
|
||||
static void run_op(uint32_t op)
|
||||
{
|
||||
REG_WR(MLKEM_CONFIG, ((op & 0x3) << 4) | (MLKEM_K & 0x7));
|
||||
clear_done();
|
||||
REG_WR(MLKEM_CTRL, CTRL_START);
|
||||
wait_done();
|
||||
}
|
||||
|
||||
static void preload(uint32_t sel, const uint8_t *buf, int n)
|
||||
{
|
||||
int i;
|
||||
REG_WR(MLKEM_PRE_SEL, sel);
|
||||
REG_WR(MLKEM_PRE_ADR, 0);
|
||||
for (i = 0; i < n; i++)
|
||||
REG_WR(MLKEM_PRE_DAT, buf[i]);
|
||||
}
|
||||
|
||||
static void readback(uint32_t sel, uint8_t *buf, int n)
|
||||
{
|
||||
int i;
|
||||
REG_WR(MLKEM_RDB_SEL, sel);
|
||||
for (i = 0; i < n; i++) {
|
||||
REG_WR(MLKEM_RDB_ADR, i);
|
||||
buf[i] = (uint8_t)(REG_RD(MLKEM_RDB_DAT) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int ok;
|
||||
|
||||
printf("MLKEM_HELLO_START\n");
|
||||
printf("MLKEM_HELLO_LEVEL=ML-KEM-768 k=3\n");
|
||||
printf("MLKEM_HELLO_INPUTS=STATIC_KAT_COUNT_0\n");
|
||||
|
||||
memset(alice_ek, 0, sizeof(alice_ek));
|
||||
memset(alice_dk, 0, sizeof(alice_dk));
|
||||
memset(bob_ct, 0, sizeof(bob_ct));
|
||||
memset(bob_ss, 0, sizeof(bob_ss));
|
||||
memset(alice_ss, 0, sizeof(alice_ss));
|
||||
memset(app_cipher, 0, sizeof(app_cipher));
|
||||
memset(app_plain_out, 0, sizeof(app_plain_out));
|
||||
|
||||
mlkem_soft_reset();
|
||||
|
||||
printf("\n[1] Alice: KeyGen(d,z) -> public key ek, secret key dk\n");
|
||||
write_block32(MLKEM_D, SEED_D);
|
||||
write_block32(MLKEM_Z, SEED_Z);
|
||||
run_op(OP_KEYGEN);
|
||||
readback(RDB_EK, alice_ek, EK_BYTES);
|
||||
readback(RDB_DK, alice_dk, DK_BYTES);
|
||||
print_hex("ALICE_PUBLIC_KEY_EK32=", alice_ek, 32);
|
||||
|
||||
printf("\n[2] Bob: Encaps(ek,m) -> ciphertext ct, shared secret ss_bob\n");
|
||||
preload(PRE_EK, alice_ek, EK_BYTES);
|
||||
write_block32(MLKEM_MSG, MSG_M);
|
||||
run_op(OP_ENCAPS);
|
||||
read_block32(MLKEM_SS, bob_ss);
|
||||
readback(RDB_CT, bob_ct, CT_BYTES);
|
||||
print_hex("BOB_CIPHERTEXT_CT32=", bob_ct, 32);
|
||||
print_hex("BOB_SHARED_SECRET=", bob_ss, 32);
|
||||
|
||||
printf("\n[3] Bob: Encrypt application plaintext with ss_bob\n");
|
||||
printf("APP_PLAINTEXT=\"%s\"\n", APP_MSG);
|
||||
xor_with_shared_secret(app_cipher, (const uint8_t *)APP_MSG,
|
||||
APP_MSG_BYTES, bob_ss);
|
||||
print_hex("APP_CIPHERTEXT=", app_cipher, APP_MSG_BYTES);
|
||||
|
||||
printf("\n[4] Alice: Decaps(dk,ct) -> shared secret ss_alice\n");
|
||||
preload(PRE_DK, alice_dk, DK_BYTES);
|
||||
preload(PRE_C, bob_ct, CT_BYTES);
|
||||
run_op(OP_DECAPS);
|
||||
read_block32(MLKEM_SS, alice_ss);
|
||||
print_hex("ALICE_SHARED_SECRET=", alice_ss, 32);
|
||||
|
||||
printf("\n[5] Alice: Decrypt application ciphertext with ss_alice\n");
|
||||
xor_with_shared_secret(app_plain_out, app_cipher, APP_MSG_BYTES, alice_ss);
|
||||
app_plain_out[APP_MSG_BYTES] = '\0';
|
||||
printf("APP_DECRYPTED=\"%s\"\n", app_plain_out);
|
||||
|
||||
ok = (memcmp(bob_ss, alice_ss, SYM_BYTES) == 0) &&
|
||||
(memcmp(app_plain_out, APP_MSG, APP_MSG_BYTES) == 0);
|
||||
printf("\n[6] Verification\n");
|
||||
printf("SHARED_SECRET_MATCH=%s\n", ok ? "YES" : "NO");
|
||||
printf("PLAINTEXT_RECOVERED=%s\n", ok ? "YES" : "NO");
|
||||
printf("MLKEM_HELLO_RESULT=%s\n", ok ? "PASS" : "FAIL");
|
||||
printf("MLKEM_HELLO_DONE\n");
|
||||
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||