大家好,我是数字小熊饼干,一个练习时长两年半的ic打工人。我在两年前通过自学跨行社招加入了IC行业。现在我打算将这两年的工作经验和当初面试时最常问的一些问题进行总结,并通过汇总成文章的形式进行输出,相信无论你是在职的还是已经还准备入行,看过之后都会有有一些收获,如果看完后喜欢的话就请关注我吧~谢谢~
我们在编写XDC约束文件时,需要将我们的约束命令和相应的对象联系起来,如果是刚入门fpga的新人经常会被一堆信号弄混了头,例如当初的我~ 因此我会在这篇文章中对常用的几个查找对象的命令进行说明介绍,便于新人理解如何查找到所需的对象。
一、ins/ports/cells/nets/clocks的区别
先上一张图以便说明:
结合上图,我们可以知道:
cell 是指的我们例化的模块,例如RAM、LUT、PLL、MMCM、还包括我们自己设计的模块和寄存器等等。
- pin是指的每个cell的输入输出信号,比如模块的输入输出信号,寄存器的D端、C端和Q端,注意一下,如果是顶层模块的输入输出信号则不能使用pin定义。
- port 顶层模块的输入输出信号,也是FPGA与外界通信的管脚。
- net 是指pin与pin之间的连线。
- clock当然就是指的我们所设置的时钟了。
下面我们再给出实际的代码,进一步对上述概念加深理解:
module test_top(
input wire clk_ref , //clock
input wire rst_n , //port
input wire a , //port
output reg b //port
);
wire pll_lock, clk_pll; //net
clk_wiz_0 ana_pll_inst( //cell
.clk_out1(clk_pll ), //pin
.reset (!rst_n ), //pin
.locked (pll_lock ), //pin
.clk_in1 (clk_ref ) //pin
);
always @(posedge clk_pll or negedge rst_n) begin //b_reg is a cell
if (!rst_n) begin
b <= 1'b0;
end else begin
b <= a;
end
end
endmodule
提示一下,如果是寄存器的话,需要在寄存器名字后加上_reg的后缀才能找到对应的对象哦,例如上面代码中的b,需要加上后缀,就变成了b_reg。
二 、get_*命令的使用
接下来我们会利用vivado中的Tcl Console 功能,将在该窗口下输入一些get_*查找命令来举例说明该如何查找我们设计中的对象,
假设我们的fpga项目中有以下代码:
inout wire
clk_wiz_0 ana_pll_inst(
.clk_out1(clk_osc_src),
.clk_out2(clk_pll ),
.reset (!rst_n ),
.locked (pll_locked),
.clk_in1 (clk_ref_in)
);
always @(posedge clk_osc_src or negedge rst_n) begin
if (!rst_n) begin
clk_osc <= 1'b0;
end else begin
clk_osc <= ~clk_osc;
end
end
那么我们该如何找到这些对象呢?
查找对象的命令的基本格式都是get_* pattern_name, 我们可以使用以下命令:
- get_ports patterns :用于查找指定模式的端口(输入或输出)的集合
例如:
get_ports scl
- get_cells patterns :用于查找设计中匹配指定模式的单元的集合
例如:
get_cells ana_pll_inst
get_cells clk_osc_reg
- get_pins patterns :用于查找指定模式的引脚的集合
例如:
get_pins clk_osc_reg/D
get_pins clk_osc_reg/C
get_pins clk_osc_reg/Q
get_pins ana_pll_inst/clk_out1
- get_nets patterns :用于查找匹配指定模式的线的集合
例如:
get_nets scl
get_nets clk_ref_in
- get_clocks patterns :用于查找匹配指定模式的时钟的集合
例如:
get_clocks clk_sys
下图是以上示例命令在vivado中的TCL Console 窗口中的输出结果:
除了上面举例的使用方式之外,这些get_*命令还有以下可选项:
下面进行说明:
-hierarchical: 是用于递归查找所有层次,返回匹配的对象
举例说明:
如果我想查找一个名为ctrl_inst里的a寄存器的D端
我如果不使用-hierarchical的话,就只能是:
get_pins ctrl_inst/a_reg/D
如果使用-hierarchical,则是:
get_pins -hierarchical a_reg/D
可见,通过-hierarchical,可免于写具体的例化模块名称。
-of_objects:用于在-of后面的结果中寻找匹配的对象
举个栗子:
如果我想在名为a的寄存器找寻与之相连的net,使用下面的命令即可:
get_nets -of [get_cells a_reg]
可见,pins/ports/cells/nets/clocks这些命令及其对应的对象并不是泾渭分明的,他们之间也有密切的关系,下图所示的箭头方向表示已知箭头末端对象可获取箭头指向的对象。
再次举例说明:
已知网线名查找对应时钟名
get_clocks -of [get_nets clk_osc]
已知引脚名查找对应的模块名
get_cells -of [get_pins */clk_out2]
已知模块名查找对应的引脚名
get_pins -of [get_cells ana_pll_inst]
已知模块名查找连接的网线名
get_nets -of [get_cells ana_pll_inst]
已知引脚名查找对应的网线名
get_nets -of [get_pins ana_pll_inst/clk_out1]
已知引脚名查找对应的时钟名
get_clocks -of [get_pins clk_osc_reg/C]
TCL Console 窗口中的查找结果如下图所示:
-filter: 用于查找满足条件的对象
有如下选项:
-
可使用 directionin / directionout 选择端口输入输出不同方向的信号
-
还可以使用以下逻辑:
-
等于 ==
-
不等于 !=
-
匹配 =~
-
不匹配 !~
若有多个表达式,其返回值为bool类型时,支持逻辑操作:
- 与 &&
- 或 ||
再次举例说明:
get_ports * -f {direction==in}
get_ports * -f {direction==out}
输出结果如下所示:
最后再提一下,在使用get_*命令时,还有以下符号需要注意:
- [ ]:在中括号命令中的代码会被当做表达式执行
- *: 可以使用*指示任意对象,
如果你喜欢这篇文章的话,请关注我的公众号-熊熊的ic车间,里面还有ic设计和ic验证的学习资料和书籍等着你呢~欢迎您的关注!