插入IO寄存器和位置约束---lattice&diamond
设计意图:违例得到更好的时序,在IO端口插入寄存器和约束逻辑资源摆放的位置。
为了做延时,写了个很简单的工程案例,如下:
module fpga_top (
i_clk ,
i_din ,
o_dout
);
input i_clk ;
input i_din ;
output o_dout ;
/******************************************************
为了将寄存器约束到指定的位置
******************************************************/
reg din1 /* synthesis loc = "R2C2A" */;
reg din2 ;
/******************************************************
为了将寄存器约束到指定的位置
******************************************************/
always @(posedge i_clk) begin
din1 <= i_din;
end
always @(posedge i_clk) begin
din2 <= din1;
end
assign o_dout = din2 ;
endmodule
MAP之后打开floorplan view,如下图,看图可以发现,位置约束没有成功(/* synthesis loc = "R2C2A"*/)
找原因的过程就不告诉大家,在此把原因告诉大家:因为软件在默认情况下,是插入IO寄存器的,证据是help,如下图。
既然都插入了寄存器,也就是说din1被软件当做IO寄存器用掉了,那自然就不会被MAP(映射或者摆放)到R2C2A的寄存器中了,我们可以打开Physical view检查猜测是否正确,如下图,有图有真相。旁边用红色圈起来的就是IO寄存器,被使用的时候显示是蓝色的,通过红色的名称net(din1)也可以知道, din1被软件当做IO寄存器用掉了.
软件的默认设置的Auto,如下图
接下来,我尝试将他修改为none,就是没有IO寄存器,那么我就肯定可以把din1 MAP(映射或者摆放)到R2C2A,因为我做了约束嘛。修改如下图
然后打开floorplan view,查看din1是否MAP(映射或者摆放)到了R2C2A上,如下图,有他有真相,蓝色表示用到的资源,通过旁边的标注可以看到他是R2C2A
还有一件事情,就是none了之后,就应该没有IO寄存器,所以我们还有看看是不是符合事实,打开Physical view看看,如下图.旁边被红色圈起来的就是IO寄存器,没有被使用,呈现的不是蓝色,通过线的名称Net(din_c)也可以知道他直接跑到R2C2A去了,它旁边是IO口是被使用的,呈现蓝色。
有的人就提出了疑问,这样的设计不是很SB吗,假如我要一些IO假如寄存器,一些IO不加入寄存器,不是不可以操作了吗?非也,非也,首先我们看看软件的设置选项,如下图,他可以设置,仅仅输入IO有寄存器,或者仅仅输出IO有寄存器,或者输入和输出都有IO寄存器。
但是你可能还会想,那么我想在输出的IO中只是部分需要IO寄存器呢?或者输入的部分(这种设计需求不是不存在的,比如DDR设计的时候,硬件RD没有经验没有把数据线画等长,这就需要通过它来去做补偿,到底能不能达到理想的效果就看命了),这个设计也是经过考虑的,所以也是可以实现的。通过IC设计的MAP语法去做,如下加两个语句就好
/**************************************************************/
/* synthesis syn_useioff = 0*/;表示不使用IO寄存器
/* synthesis syn_useioff = 1*/;表示使用IO寄存器
下面的例子是输入加IO reg,输出不加
/**************************************************************/
input i_din /* synthesis syn_useioff = 1 */;
output o_dout /* synthesis syn_useioff = 0*/;
然后我们看看实际的结果吧,如下图,完全正确,nice.
但是要记住,做局部约束的时候,要改为AUTO,如下图。不然就没法做局部约束,Auto意为自动,然后我在Verilog中加了语法,那么就是自动按我的加的语法去MAP
不信的话,我们把他修改为none去看看,如下图。好玩吧,none就是都不加,所有下图两个都没有IO寄存器,这也侧面说明了,软件界面约束优先级高于语法约束。
其中help还提供了另外一种方法,如下截图
我做了尝试,但是是不行的,真操蛋。
代码改成
input i_din ;
output o_dout ;
lpf中假如约束
USE DIN FALSE CELL "i_din";
USE DOUT FALSE CELL "o_dout";
改为AUTO
得到的结果如下图,都是加了IO 寄存器,好坑爹。