You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何每17个时钟周期实例化Verilog的padder模块?

问题解答

可行性判断

完全可行,这是利用重叠执行/流水线调度提升哈希吞吐量的标准思路——padder耗时17周期,f_permutation仅需12周期,两者的周期差刚好允许padder提前启动下一轮填充,让硬件资源持续处于工作状态,避免空闲浪费。

为什么你之前的尝试失败

Verilog是硬件描述语言,模块实例化是静态硬件结构定义,必须在模块顶层(always块之外)完成,不能在always这种动态行为描述块内实例化模块。你需要做的不是动态生成模块,而是通过控制信号调度已有模块的工作时序。

具体实现方法(附简便方案)

1. 核心方案:静态实例化+周期计数器调度

这是最简便的实现方式,仅需给模块添加基础的启动/完成握手信号(如果原模块没有的话):

  • 步骤1:静态实例化模块
    在顶层模块中直接实例化padder和f_permutation,这是Verilog语法要求,所有硬件结构必须在编译阶段确定。
  • 步骤2:用17周期循环计数器触发padder启动
    设计一个从0到16的计数器,每计数到0时,给padder发送一个单周期的启动信号,同时送入下一轮哈希的输入数据。因为padder刚好耗时17周期,下一次启动信号到来时,上一轮填充刚好完成,padder可以持续满负荷运行。
  • 步骤3:握手信号同步数据流转
    当padder完成填充时(输出pad_done信号),自动触发f_permutation启动,接收填充后的数据。由于f_permutation仅需12周期,它会在padder下一次输出前提前完成,不会阻塞后续数据。

2. 代码示例(关键片段)

module shake256_top(
    input         clk,
    input         rst_n,
    input  [511:0] next_hash_input,
    output [255:0] hash_result,
    output        hash_valid
);

// 17周期循环计数器:触发padder启动
reg [4:0] cycle_cnt;
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        cycle_cnt <= 5'd0;
    else
        cycle_cnt <= (cycle_cnt == 5'd16) ? 5'd0 : cycle_cnt + 1'b1;
end
wire pad_start = (cycle_cnt == 5'd0);  // 每17周期启动一次padder

// 静态实例化padder模块(假设已添加start/done信号)
wire [1023:0] padded_data;
wire          pad_done;
padder u_padder(
    .clk      (clk),
    .rst_n    (rst_n),
    .start    (pad_start),
    .data_in  (next_hash_input),
    .data_out (padded_data),
    .done     (pad_done)
);

// 静态实例化f_permutation模块(假设已添加start/done信号)
wire          f_start = pad_done;
wire [255:0]  f_result;
wire          f_done;
f_permutation u_f_perm(
    .clk      (clk),
    .rst_n    (rst_n),
    .start    (f_start),
    .data_in  (padded_data),
    .data_out (f_result),
    .done     (f_done)
);

// 哈希结果输出逻辑
reg [255:0] hash_reg;
reg         valid_reg;
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        hash_reg  <= 256'd0;
        valid_reg <= 1'b0;
    end else begin
        if(f_done) begin
            hash_reg  <= f_result;
            valid_reg <= 1'b1;
        end else begin
            valid_reg <= 1'b0;
        end
    end
end
assign hash_result = hash_reg;
assign hash_valid  = valid_reg;

endmodule

3. 特殊情况处理:乒乓缓冲(可选)

如果后续调整参数后,padder的输出速率高于f_permutation的处理速率,可以在两者之间添加双端口乒乓缓冲:

  • 当padder完成填充,将数据写入缓冲A;当f_permutation空闲时,从缓冲B读取数据。
  • 切换逻辑:缓冲A写满后切换到缓冲B写入,缓冲B读完后切换到缓冲A读取,避免数据丢失,同时保证padder持续运行。

关键注意事项

  • 模块握手信号:如果原padder/f_permutation没有start和done信号,需要给模块添加简单的状态机控制,比如用启动寄存器触发内部流水线,用计数器计数周期数生成done信号。
  • 时序约束:需要确保padder输出到f_permutation输入的路径满足时钟周期要求,避免时序违例。
  • 复位同步:所有模块的复位信号要保持同步,防止异步复位导致的逻辑混乱。

内容的提问来源于stack exchange,提问作者Thearqi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 08:47:51