• 精通 Verilog HDL 设计之编码风格(5)顶层简洁化


    一、顶层仅互连

            推荐顶层模块中只包含模块之间的互连,只例化下一层次的模块。(全部的时序逻辑、组合逻辑等等都置于内部的子模块中)。

            实在是情非得已的情况之下,也只能够添加简单的 Glue 逻辑。(Glue 逻辑,指的是胶合逻辑,这是连接复杂逻辑电路的简单逻辑电路的统称)。


    二、按照端口名字连接

            模块例化的时候,推荐按照端口名字连接的方式,不推荐按照端口位置连接的方式

            这里,推荐:

    1. // Connect by port name
    2. riscv_core_top u_riscv_core_top(
    3. .clk ( clk ), //i, 1 bits, from ccu
    4. .rst_n ( rst_n ), //i, 1 bits, from ccu
    5. .din ( din ), //i, 16 bits, from top
    6. .dout ( dout ) //o, 32 bits, to mem
    7. );

            这里,不推荐:

    1. // Connect by port location
    2. riscv_core_top u_riscv_core_top(i_clk, i_rst_n, din, dout);

    三、排版注意

    • 推荐尽量声明每一个信号,即使是单比特的线网信号;
    • 未知的、无用的、冗余的信号尽量不要引入模块内部中;
    • 每行只声明一个端口,注释于其上或者其后。

    四、功能分组排序

            不推荐按照字母、输入、输出之类的来分组排序,这是不专业的、较差劲的、不符合设计思维的一种方式。推荐按照功能来分组排序,每一个功能组之上添加注释,不同的功能组之间添加空行

            这里,推荐:

    1. DFT 信号
    2. 时钟、复位
    3. 总线
    4. 使能、控制、配置、反馈、响应信号等等
    5. 地址
    6. 数据
    1. // Unique IC Design
    2. module unique_ic_design #(
    3. parameter FIFO_DATA_WIDTH = 32,
    4. parameter FIFO_ADDR_WIDTH = 12
    5. )(
    6. // DFT Signals
    7. input wire scan_mode ,
    8. // -----------------------------------------------------
    9. // Clock and Reset Signals
    10. input wire clk ,
    11. input wire rst_n ,
    12. // -----------------------------------------------------
    13. // Enable
    14. input wire ctrl_en ,
    15. // -----------------------------------------------------
    16. // Control
    17. input wire data_vld ,
    18. // -----------------------------------------------------
    19. // Addr
    20. output reg [11:0] o_mem_addr ,
    21. // -----------------------------------------------------
    22. // Data
    23. input wire signed [1:0] i_mem_din ,
    24. output reg signed [FIFO_DATA_WIDTH-1:0] o_mem_dout
    25. );

    五、例化命名要求

            模块名字要和例化名字保持一致,推荐统一前缀的方式来执行例化,以便于在仿真、综合、STA 的时候查找模块。

            这里,推荐:

    1. //********************
    2. // 模块名 例化名
    3. //********************
    4. //********************
    5. // Single Instance
    6. //********************
    7. riscv_core_top u_riscv_core_top( ... );
    8. //********************
    9. // Multiple Instance
    10. //********************
    11. riscv_core_top u0_riscv_core_top( ... );
    12. riscv_core_top u1_riscv_core_top( ... );
    13. riscv_core_top u2_riscv_core_top( ... );
    14. // ...

    六、信号名字统一

            同一信号的名字在各个子模块之内、各个子模块之间、不同层次之间、整体系统之内推荐尽量保持一致,有利于连接、查找和追踪,这个要求在芯片总体设计的时候,就要清晰地定义好集成的顶层各个子模块之间的连线的名字。


    七、信号位置统一

            在模块实例化的时候,实例化端口的顺序要和模块端口声明的顺序保持一致,便于查找、修改和删除。对于不需要的端口,也都要列出来,这就要求前期对于各个 IP 的端口定义是清晰的。


    八、其它注意

    • 信号命名推荐前缀 > 后缀,这在 Verdi 等波形工具里面容易区分;
    • 实例保持端口对齐,清晰明了;
    • 例化的上方可以添加清晰注释。

    九、标准的、规范的、简洁的顶层设计如下

    1. `define DATA_WIDTH 12'd32
    2. // Unique IC Design
    3. module unique_ic_design #(
    4. parameter FIFO_DATA_WIDTH = 32,
    5. parameter FIFO_ADDR_WIDTH = 12
    6. )(
    7. // DFT Signals
    8. input wire scan_mode ,
    9. // -----------------------------------------------------
    10. // Clock and Reset Signals
    11. input wire clk ,
    12. input wire rst_n ,
    13. // -----------------------------------------------------
    14. // Enable
    15. input wire ctrl_en ,
    16. // -----------------------------------------------------
    17. // Control
    18. input wire data_vld ,
    19. // -----------------------------------------------------
    20. // Addr
    21. output wire [11:0] o_mem_addr ,
    22. // -----------------------------------------------------
    23. // Data
    24. input wire signed [1:0] din ,
    25. output wire signed [FIFO_DATA_WIDTH-1:0] dout
    26. );
    27. parameter ADDR_WIDTH = 12'd16;
    28. //*********************************
    29. // Instance
    30. //*********************************
    31. riscv_core_top #(
    32. .DUAL_CORE ( 1 ),
    33. .DATA_WIDTH ( `DATA_WIDTH ),
    34. .ADDR_WIDTH ( ADDR_WIDTH )
    35. )
    36. u_riscv_core_top(
    37. .clk ( clk ), //i, 1 bits, from ccu
    38. .rst_n ( rst_n ), //i, 1 bits, from ccu
    39. .din ( din ), //i, 16 bits, from top
    40. .dout ( dout ) //o, 32 bits, to mem
    41. );
    42. endmodule
  • 相关阅读:
    TRex学习之旅八
    计算机基本工作原理
    【nowcoder】统计回文、连续最大和
    高数中值定理总结
    RHCE之HTTP搭建
    linux 安装openssl 命令
    vue中 el-tab-plane 如何显示使用el-badge显示小红点
    C语言航路外传之输入输出函数及输入缓冲区的那点事
    JMeter—(二)如何做接口测试入门篇
    SuperMap iServer 重置密码
  • 原文地址:https://blog.csdn.net/MicroTalent12/article/details/124953779