模块深层调用-避免端口层层穿出的两种方法

前言

前排提示:xilinx论坛提供了一种更好的方法,我的TCL修改网表的方法,随便看看就好了。
有的时候,比如设计中深层次调用了DDR。DDR控制器的芯片相关的端口需要连接到管脚上,如果一路层层穿出来的话太麻烦。
经过学习发现可以利用TCL修改网表避免层层穿出

XILINX论坛提供的方法

真是大开眼界,xilinx论坛官方给了一个更好的方法。推荐使用这个方法,我上面的回答随便看看就好了。

下面是复制的回答:
在代码侧可以使用hierarchical naming的方式把底层的管脚直接接到顶层,而无需层层改接口.
Ex:
模块层次​clkx_pre_i0/meta_harden_bus_new_i0 , Pin:signal_dst
output my_output,

assign my_output = clkx_pre_i0.meta_harden_bus_new_i0.signal_dst;​

底层的端口如果是输入,只能悬空,否则会形成多驱动.
如果是输出,可以悬空,也可以连接驱动其他信号.
的确,一般不建议这么​写,读底层代码时容易忘记顶层还有连接,可以加注释提醒自己.

TCL修改综合后网表的方法

工程里面的IP 采用的OOC模式综合的,非OOC模式下内部的逻辑会被优化,建议对要层层穿出的模块使用OOC模式综合。
先从一个示例工程看看过程。

代码跳转

顶层代码
Wrapper代码
约束文件

修改前

原理图
在这里插入图片描述
这个图里可以看到两个差分时钟和复位信号都没有接到顶层。
而且顶层设计中也没有相关的端口。下面开始用TCL进行修改

TCL修改网表

  1. 代码中利用(* keep = “true” )避免优化,不能用( dont_touch = “yes” *),dont_touch会导致不能修改网表。
  2. 创建端口
  3. 创建BUFER
  4. 连接net
  5. 上板测试
# 创建端口
create_port -direction IN -diff_pair sys_clk_p sys_clk_n
create_port -direction IN rst
#创建输入BUF,因为时钟输入直接引到PLL上了所以不用加BUF了
create_cell -reference IBUF rst_IBUF_inst
#创建net
create_net rst_net
#移除 图中wrapper里面的3个lut
remove_cell design_1_wrapper_i/i_0
remove_cell design_1_wrapper_i/i_1
remove_cell design_1_wrapper_i/i_2
#连接 net
connect_net -net rst_net -objects [get_ports rst]
connect_net -net rst_net -objects rst_IBUF_inst/I
connect_net -hier -net design_1_wrapper_i/reset_0 -objects rst_IBUF_inst/O
connect_net -hier -net design_1_wrapper_i/CLK_IN1_D_0_clk_p -objects [get_ports sys_clk_p]
connect_net -hier -net design_1_wrapper_i/CLK_IN1_D_0_clk_n -objects [get_ports sys_clk_n]
#约束端口,新的端口只能在创建后进行约束
set_property IOSTANDARD DIFF_SSTL12 [get_ports sys_clk_p]
set_property IOSTANDARD DIFF_SSTL12 [get_ports sys_clk_n]
set_property PACKAGE_PIN G31 [get_ports sys_clk_p]
set_property PACKAGE_PIN F31 [get_ports sys_clk_n]

set_property IOSTANDARD LVCMOS12 [get_ports rst]
set_property PACKAGE_PIN L19 [get_ports rst]

综合流程中插入tcl

把上面的tc脚本插入图中,就可以避免手动运行了。
在这里插入图片描述

上板测试

非OOC模式下

我测试了一下非OOC模式,原理图如图
在这里插入图片描述
对比OOC模式下的原理图

在这里插入图片描述
逻辑还是被优化了。

参考UG901 p55页对keep的解释
在这里插入图片描述
keep能保留对应的信号但是该信号不会驱动任何东西。
参考UG901 P48页对dont_touch的解释,dont_touch可以forward-annotated to place and route阻止相关的逻辑被优化。
在这里插入图片描述
但是用dont_touch就不能tcl修改对应的网表。非OOC模式下这个方法暂时还是不行。

只能建议对要层层穿出的模块使用OOC模式综合。然后再用TCL修改网表。

参考文献

  1. 在Vivado下利用Tcl脚本对综合后的网表进行编辑过程
  2. UG901-Vivado Design Suite User Guide Synthesis

相关文件

1,顶层代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/12/01 16:48:50
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module top
   (
//    input sys_clk_p,
//    input sys_clk_n,
//    input rst,
    (* mark_debug = "true" *)input start,
    output q);

  (* mark_debug = "true" *)wire [15:0]BRAM_PORTA_0_addr;
  wire BRAM_PORTA_0_clk;
  (* mark_debug = "true" *)wire [31:0]BRAM_PORTA_0_din;
  wire [31:0]BRAM_PORTA_0_dout;
  assign BRAM_PORTA_0_dout = 0;
  (* mark_debug = "true" *)wire BRAM_PORTA_0_en;
  wire BRAM_PORTA_0_rst;
  wire [3:0]BRAM_PORTA_0_we;
  (* mark_debug = "true" *)wire clk_out_25;
 (* dont_touch = "yes" *) wire clk_out_50;


  design_1_wrapper design_1_wrapper_i
       (.BRAM_PORTA_0_addr(BRAM_PORTA_0_addr),
        .BRAM_PORTA_0_clk(BRAM_PORTA_0_clk),
        .BRAM_PORTA_0_din(BRAM_PORTA_0_din),
        .BRAM_PORTA_0_dout(BRAM_PORTA_0_dout),
        .BRAM_PORTA_0_en(BRAM_PORTA_0_en),
        .BRAM_PORTA_0_rst(BRAM_PORTA_0_rst),
        .BRAM_PORTA_0_we(BRAM_PORTA_0_we),
//        .CLK_IN1_D_0_clk_n(sys_clk_n),
//        .CLK_IN1_D_0_clk_p(sys_clk_p),
        .clk_out_25(clk_out_25),
        .clk_out_50(clk_out_50)
//        .reset_0(rst)
        );

(* mark_debug = "true" *) reg [13:0] addrb;    
(* mark_debug = "true" *) wire [31:0] doutb;  

(* mark_debug = "true" *) wire [15:0] BRAM_PORTA_0_addr_rshift2;
assign BRAM_PORTA_0_addr_rshift2 = BRAM_PORTA_0_addr>>2;
blk_mem_gen_0 usr_bram (
  .clka(BRAM_PORTA_0_clk),    // input wire clka
  .ena(BRAM_PORTA_0_en),      // input wire ena
  .wea(BRAM_PORTA_0_we),      // input wire [0 : 0] wea
  .addra(BRAM_PORTA_0_addr_rshift2),  // input wire [13 : 0] addra
  .dina(BRAM_PORTA_0_din),    // input wire [31 : 0] dina
  .clkb(clk_out_25),    // input wire clkb
  .enb(1'b1),      // input wire enb
  .addrb(addrb),  // input wire [13 : 0] addrb
  .doutb(doutb)  // output wire [31 : 0] doutb
);
assign q = |doutb;
 always@(posedge clk_out_25)begin
    if(start)addrb <= 0;
    else if(addrb == {14{1'b1}}) addrb <= addrb;
    else addrb <= addrb + 1;
 end
endmodule

2, design_1_wrapper 代码

//Copyright 1986-2020 Xilinx, Inc. All Rights Reserved.
//--------------------------------------------------------------------------------
//Tool Version: Vivado v.2020.2 (win64) Build 3064766 Wed Nov 18 09:12:45 MST 2020
//Date        : Thu Dec  2 17:42:39 2021
//Host        : DESKTOP-9H6R9V9 running 64-bit major release  (build 9200)
//Command     : generate_target design_1_wrapper.bd
//Design      : design_1_wrapper
//Purpose     : IP block netlist
//--------------------------------------------------------------------------------
`timescale 1 ps / 1 ps

module design_1_wrapper
   (BRAM_PORTA_0_addr,
    BRAM_PORTA_0_clk,
    BRAM_PORTA_0_din,
    BRAM_PORTA_0_dout,
    BRAM_PORTA_0_en,
    BRAM_PORTA_0_rst,
    BRAM_PORTA_0_we,
//    CLK_IN1_D_0_clk_n,
//    CLK_IN1_D_0_clk_p,
    clk_out_25,
    clk_out_50,
//    reset_0
    );
  output [15:0]BRAM_PORTA_0_addr;
  output BRAM_PORTA_0_clk;
  output [31:0]BRAM_PORTA_0_din;
  input [31:0]BRAM_PORTA_0_dout;
  output BRAM_PORTA_0_en;
  output BRAM_PORTA_0_rst;
  output [3:0]BRAM_PORTA_0_we;
//  input CLK_IN1_D_0_clk_n;
//  input CLK_IN1_D_0_clk_p;
  output clk_out_25;
  output clk_out_50;
//  input reset_0;

  wire [15:0]BRAM_PORTA_0_addr;
  wire BRAM_PORTA_0_clk;
  wire [31:0]BRAM_PORTA_0_din;
  wire [31:0]BRAM_PORTA_0_dout;
  wire BRAM_PORTA_0_en;
  wire BRAM_PORTA_0_rst;
  wire [3:0]BRAM_PORTA_0_we;
  (* keep = "true" *)wire CLK_IN1_D_0_clk_n;
  (* keep = "true" *)wire CLK_IN1_D_0_clk_p;
  wire clk_out_25;
  wire clk_out_50;
  (* keep = "true" *)wire reset_0;

  design_1 design_1_i
       (.BRAM_PORTA_0_addr(BRAM_PORTA_0_addr),
        .BRAM_PORTA_0_clk(BRAM_PORTA_0_clk),
        .BRAM_PORTA_0_din(BRAM_PORTA_0_din),
        .BRAM_PORTA_0_dout(BRAM_PORTA_0_dout),
        .BRAM_PORTA_0_en(BRAM_PORTA_0_en),
        .BRAM_PORTA_0_rst(BRAM_PORTA_0_rst),
        .BRAM_PORTA_0_we(BRAM_PORTA_0_we),
        .CLK_IN1_D_0_clk_n(CLK_IN1_D_0_clk_n),
        .CLK_IN1_D_0_clk_p(CLK_IN1_D_0_clk_p),
        .clk_out_25(clk_out_25),
        .clk_out_50(clk_out_50),
        .reset_0(reset_0));
endmodule

3, 约束文件

set_property IOSTANDARD DIFF_SSTL12 [get_nets sys_clk_p]
set_property IOSTANDARD DIFF_SSTL12 [get_nets sys_clk_n]
set_property PACKAGE_PIN G31 [get_nets sys_clk_p]
set_property PACKAGE_PIN F31 [get_nets sys_clk_n]

set_property IOSTANDARD LVCMOS12 [get_nets rst]
set_property PACKAGE_PIN L19 [get_nets rst]
#------------------------------------------------------------
set_property IOSTANDARD LVCMOS18 [get_ports start]
set_property PACKAGE_PIN BE23 [get_ports start]

set_property IOSTANDARD LVCMOS12 [get_ports q]
set_property PACKAGE_PIN AT32 [get_ports q]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值