推荐顶层模块中只包含模块之间的互连,只例化下一层次的模块。(全部的时序逻辑、组合逻辑等等都置于内部的子模块中)。
实在是情非得已的情况之下,也只能够添加简单的 Glue 逻辑。(Glue 逻辑,指的是胶合逻辑,这是连接复杂逻辑电路的简单逻辑电路的统称)。
模块例化的时候,推荐按照端口名字连接的方式,不推荐按照端口位置连接的方式。
这里,推荐:
- // Connect by port name
- riscv_core_top u_riscv_core_top(
- .clk ( clk ), //i, 1 bits, from ccu
- .rst_n ( rst_n ), //i, 1 bits, from ccu
- .din ( din ), //i, 16 bits, from top
- .dout ( dout ) //o, 32 bits, to mem
- );
这里,不推荐:
- // Connect by port location
- riscv_core_top u_riscv_core_top(i_clk, i_rst_n, din, dout);
不推荐按照字母、输入、输出之类的来分组排序,这是不专业的、较差劲的、不符合设计思维的一种方式。推荐按照功能来分组排序,每一个功能组之上添加注释,不同的功能组之间添加空行。
这里,推荐:
- // Unique IC Design
- module unique_ic_design #(
- parameter FIFO_DATA_WIDTH = 32,
- parameter FIFO_ADDR_WIDTH = 12
- )(
- // DFT Signals
- input wire scan_mode ,
- // -----------------------------------------------------
- // Clock and Reset Signals
- input wire clk ,
- input wire rst_n ,
- // -----------------------------------------------------
- // Enable
- input wire ctrl_en ,
- // -----------------------------------------------------
- // Control
- input wire data_vld ,
- // -----------------------------------------------------
- // Addr
- output reg [11:0] o_mem_addr ,
- // -----------------------------------------------------
- // Data
- input wire signed [1:0] i_mem_din ,
- output reg signed [FIFO_DATA_WIDTH-1:0] o_mem_dout
- );
模块名字要和例化名字保持一致,推荐统一前缀的方式来执行例化,以便于在仿真、综合、STA 的时候查找模块。
这里,推荐:
- //********************
- // 模块名 例化名
- //********************
-
- //********************
- // Single Instance
- //********************
- riscv_core_top u_riscv_core_top( ... );
-
- //********************
- // Multiple Instance
- //********************
- riscv_core_top u0_riscv_core_top( ... );
- riscv_core_top u1_riscv_core_top( ... );
- riscv_core_top u2_riscv_core_top( ... );
- // ...
同一信号的名字在各个子模块之内、各个子模块之间、不同层次之间、整体系统之内推荐尽量保持一致,有利于连接、查找和追踪,这个要求在芯片总体设计的时候,就要清晰地定义好集成的顶层和各个子模块之间的连线的名字。
在模块实例化的时候,实例化端口的顺序要和模块端口声明的顺序保持一致,便于查找、修改和删除。对于不需要的端口,也都要列出来,这就要求前期对于各个 IP 的端口定义是清晰的。
- `define DATA_WIDTH 12'd32
-
- // Unique IC Design
- module unique_ic_design #(
- parameter FIFO_DATA_WIDTH = 32,
- parameter FIFO_ADDR_WIDTH = 12
- )(
- // DFT Signals
- input wire scan_mode ,
- // -----------------------------------------------------
- // Clock and Reset Signals
- input wire clk ,
- input wire rst_n ,
- // -----------------------------------------------------
- // Enable
- input wire ctrl_en ,
- // -----------------------------------------------------
- // Control
- input wire data_vld ,
- // -----------------------------------------------------
- // Addr
- output wire [11:0] o_mem_addr ,
- // -----------------------------------------------------
- // Data
- input wire signed [1:0] din ,
- output wire signed [FIFO_DATA_WIDTH-1:0] dout
- );
-
- parameter ADDR_WIDTH = 12'd16;
-
- //*********************************
- // Instance
- //*********************************
-
- riscv_core_top #(
- .DUAL_CORE ( 1 ),
- .DATA_WIDTH ( `DATA_WIDTH ),
- .ADDR_WIDTH ( ADDR_WIDTH )
- )
- u_riscv_core_top(
- .clk ( clk ), //i, 1 bits, from ccu
- .rst_n ( rst_n ), //i, 1 bits, from ccu
- .din ( din ), //i, 16 bits, from top
- .dout ( dout ) //o, 32 bits, to mem
- );
-
- endmodule