找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3710

积分

1

好友

502

主题
发表于 2026-2-14 06:45:08 | 查看: 32| 回复: 0

在 Verilog 硬件描述语言中,(* keep_hierarchy="yes" *) 是一个非常重要的 层次保留属性。它的核心作用是指示综合工具(如 Vivado、Design Compiler)保持模块的层次结构,防止其在优化过程中被展平或合并到其他模块中。

那么,为什么我们需要特意保留层次呢?这通常是为了便于调试、约束管理以及模块的复用。

一、属性作用与核心含义

添加此属性后,相当于给综合工具下达了一条明确的指令:

  • 保持层次:防止工具打破模块之间的边界。
  • 禁止展平:阻止该模块被“溶解”并优化到其父模块内部。
  • 独立优化:允许综合工具在每个模块内部独立进行优化。
  • 便于调试:使综合后的网表结构与原始 RTL 代码的层次保持一致,极大地方便了前后仿真的对照与问题定位。

二、语法格式

这个属性主要通过注释的形式嵌入在代码中。

// 最常见的用法:在模块定义时声明
(* keep_hierarchy = "yes" *)
module my_module (...);
  // 模块内部代码
endmodule

// 某些工具也支持在模块实例化时使用
(* keep_hierarchy = "yes" *)
module_name instance_name (...);

三、主要使用场景与代码示例

1. 保护 IP 核或专用子模块

当你设计了一个需要映射到专用硬件资源(如 DSP、BRAM)的模块,或者它是一个需要保密的第三方 IP 时,保留其层次至关重要。

(* keep_hierarchy = "yes" *)
module dsp_multiplier (
    input [15:0] a,
    input [15:0] b,
    output [31:0] p
);
    // 这部分逻辑可能会被综合工具映射到 FPGA 的 DSP48E1 等专用乘法器上
    assign p = a * b;
endmodule

module top_design (
    input [15:0] data_a,
    input [15:0] data_b,
    output [31:0] result
);

// 这个实例的层次结构会被保留,便于识别和约束
dsp_multiplier u_mult (
    .a(data_a),
    .b(data_b),
    .p(result)
);

endmodule

2. 保持功能模块的独立性

对于一些通用的功能模块,如 FIFO、仲裁器等,保留层次有利于在不同项目中复用,也使得模块内部的 逻辑 更清晰。

(* keep_hierarchy = "yes" *)
module fifo_controller (
    input clk,
    input rst_n,
    input wr_en,
    input rd_en,
    input [7:0] data_in,
    output [7:0] data_out,
    output full,
    output empty
);

    reg [7:0] mem [0:15];
    reg [3:0] wr_ptr, rd_ptr;
    reg [4:0] count;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            wr_ptr <= 0;
            rd_ptr <= 0;
            count <= 0;
        end else begin
            // FIFO 控制逻辑...
        end
    end

    assign full = (count == 16);
    assign empty = (count == 0);

endmodule

3. 分层设计中的关键模块

在复杂的算法实现(如 AES 加密)中,保留每一轮操作的层次,有助于理解和验证数据流。

(* keep_hierarchy = "yes" *)
module aes_encryption_round (
    input [127:0] data_in,
    input [127:0] round_key,
    output [127:0] data_out
);

    wire [127:0] sub_bytes_out;
    wire [127:0] shift_rows_out;
    wire [127:0] mix_columns_out;

    // AES 轮函数子模块
    sub_bytes u_sub (.data_in(data_in), .data_out(sub_bytes_out));
    shift_rows u_shift (.data_in(sub_bytes_out), .data_out(shift_rows_out));
    mix_columns u_mix (.data_in(shift_rows_out), .data_out(mix_columns_out));

    assign data_out = mix_columns_out ^ round_key;

endmodule

四、一个完整的通信接收机示例

下面这个 UART 接收机例子展示了如何在多个子模块上应用该属性。

// 1. 同步器模块 - 保持层次
(* keep_hierarchy = "yes" *)
module synchronizer (
    input clk,
    input rst_n,
    input async_signal,
    output sync_signal
);

    reg sync_reg1, sync_reg2;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            sync_reg1 <= 1'b0;
            sync_reg2 <= 1'b0;
        end else begin
            sync_reg1 <= async_signal;
            sync_reg2 <= sync_reg1;
        end
    end

    assign sync_signal = sync_reg2;

endmodule

// 2. 解串器模块 - 保持层次
(* keep_hierarchy = "yes" *)
module deserializer (
    input clk,
    input serial_data,
    output [7:0] parallel_data
);

    reg [7:0] shift_reg;

    always @(posedge clk) begin
        shift_reg <= {shift_reg[6:0], serial_data};
    end

    assign parallel_data = shift_reg;

endmodule

// 3. 顶层接收机
module uart_receiver (
    input clk,
    input rst_n,
    input rx_data,
    output [7:0] received_data,
    output data_valid
);

    wire synchronized_rx;

    // 这些被标记的子模块在综合后层次依然清晰
    synchronizer u_sync (
        .clk(clk),
        .rst_n(rst_n),
        .async_signal(rx_data),
        .sync_signal(synchronized_rx)
    );

    deserializer u_deser (
        .clk(clk),
        .serial_data(synchronized_rx),
        .parallel_data(received_data)
    );

    // 其他控制逻辑...
endmodule

五、深入理解应用场景

  1. 便于时序约束:对于跨时钟域(CDC)模块,保留层次后,可以方便地对整个模块添加特定的时序约束(如 set_false_path),而不是对分散的逻辑进行约束。
  2. 模块复用和团队协作:在大型项目中,明确的模块边界有利于不同团队并行开发。被保留层次的模块就像一个封装好的“黑盒”,接口清晰,易于集成和复用。
  3. 物理规划保留:在物理实现阶段,工具可以根据保留的层次信息进行更好的布局规划(Floorplanning),例如将某个关键模块约束在芯片的特定区域。

六、相关综合属性对比

属性 描述 作用层次
keep_hierarchy="yes" 保持模块层次结构 模块级别
dont_touch="true" 禁止对逻辑进行优化 模块、实例、信号级别
black_box="true" 将模块视为黑盒,不进行综合 模块级别
buffer_type="none" 禁止在端口插入缓冲器 端口级别

七、不同工具的具体语法

  • Xilinx Vivado:
    (* keep_hierarchy = "yes" *)   // 硬约束,强制保留
    (* keep_hierarchy = "soft" *)  // 软约束,工具在必要时可能展平
    (* keep_hierarchy = "no" *)    // 允许展平(默认行为)
  • Synopsys Design Compiler:
    (* syn_hier = "hard" *) // 硬层次保留
    (* syn_hier = "soft" *) // 软层次保留

八、属性组合使用

有时我们需要对关键模块施加多重保护。

(* keep_hierarchy = "yes", dont_touch = "true" *)
module critical_submodule (
    input clk,
    input [15:0] data_in,
    output [15:0] data_out
);
    // 这个模块既不会被展平,其内部的逻辑也不会被优化掉
    // ...
endmodule

九、使用注意事项

  1. 性能影响:过度使用可能会限制综合工具的跨模块优化能力,从而影响最终设计的面积和时序。
  2. 面积代价:阻止了资源共享等优化,可能会稍微增加资源使用量。
  3. 时序考虑:保持层次可能会影响工具进行全局的时序优化。
  4. 调试优势:这是最大的好处,能显著改善网表调试和分析的便利性。

十、典型工作流程

  1. 在关键模块的定义处添加 (* keep_hierarchy = "yes" *) 属性。
  2. 运行综合,工具会识别该属性并保持模块边界。
  3. 在实现(Implementation)阶段,布局布线工具会参考这个层次信息。
  4. 在验证阶段,你可以轻松地对特定模块进行时序约束、功耗分析或调试。

十一、在大型 SoC 设计中的应用

在复杂的系统级芯片设计中,对核心模块保留层次是常见做法。

(* keep_hierarchy = "yes" *)
module cpu_core (
    input clk,
    input rst_n,
    input [31:0] instruction,
    output [31:0] result
);
// ...
endmodule

(* keep_hierarchy = "yes" *)
module dma_controller (
    input clk,
    input [31:0] src_addr,
    input [31:0] dst_addr
);
// ...
endmodule

module soc_top (
    input system_clk,
    input system_rst_n
);

    cpu_core u_cpu (.clk(system_clk), .rst_n(system_rst_n), ...);
    dma_controller u_dma (.clk(system_clk), ...);
    // 其他模块...

endmodule

总结

(* keep_hierarchy="yes" *) 属性是 Verilog 数字电路设计 中一项非常实用的功能,它平衡了综合优化与设计可维护性之间的关系。在以下场景中,你应该考虑使用它:

  • 大型分层设计项目。
  • IP核集成与复用。
  • 需要清晰模块边界以便进行团队协作。
  • 需要对特定模块施加独立时序约束。
  • 物理规划驱动的设计。
  • 调试和分析复杂系统时,希望网表与 RTL 结构高度对应。

掌握这个属性,能让你在追求电路性能的同时,更好地掌控设计的结构和流程。如果你对这类硬件描述语言的深层应用感兴趣,欢迎在 云栈社区 与其他开发者交流探讨。




上一篇:Kubernetes面试精讲:网络服务、Ingress配置与存储管理实战
下一篇:Stambaugh–Yuan四因子模型解读:行为金融中的错误定价因子与A股量化实战
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-23 14:18 , Processed in 0.954521 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表