vivado 对高阻z和不定态x信号的处理

声明

实验较为简单,考虑到的情况不多。经验仅供参考。如果发现反例,欢迎评论一起探讨

引言

最近在做关于FPGA原型验证,不清楚代码中的高阻z和不定态x会被映射成什么样的电路。会不会导致前仿真和综合后仿真的结果不一致。所以自己做了个验证。

1,高阻z

代码

先附上用来验证的源代码和仿真代码。
代码结构比较简单, e n _ z en\_z en_z信号就是我们要验证的信号。
源代码

module top(
input clk,
input rst_n,
input en,
output wire[2:0] led,
output wire[1:0] cnt  
);
chip rita(
    .clk(clk),
    .rst_n(rst_n),
    .en(en),
    .led(led)
);
endmodule

module chip(
input clk,
input rst_n,
input en,
inout pad,
output reg [2:0]led,
output reg [1:0]cnt
    );
    wire en_z;
    assign pad=1'bz;
    assign en_z=1'bz;

    always@(posedge clk or negedge rst_n)begin
        if(!rst_n) led <= 0;
        else led <= {en_z, en, en_z & en};
    end 
    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n) cnt <= 0;
        else cnt <= cnt+~en_z;
    end
endmodule

仿真代码

module tb_top( );
reg clk = 0;
always #10 clk = ~clk;
reg rst_n;
reg en;
initial begin
    rst_n = 0;
    en = 0;
    #50 rst_n =1;
    #50 en = 1;
end
wire [2:0]led;
wire [1:0]cnt;
top u_top(
.clk(clk),
.rst_n(rst_n),
.en(en),
.led(led),
.cnt(cnt)
);
endmodule

综合后的原理图


电路内信号的状态只有0或1,看 l e d [ 2 ] _ I N S T _ 0 led[2]\_INST\_0 led[2]_INST_0 e n z _ 0 _ I N S T _ 0 enz\_0\_INST\_0 enz_0_INST_0 信号直接接地,此处信号被综合成0;但是后面, l e d _ O B U F [ 2 ] _ i n s t led\_OBUF[2]\_inst led_OBUF[2]_inst这是一个三态输出BUF。
至于 c n t cnt cnt寄存器因为忘了引出来则直接被优化掉了,通过输出BUF直接输出。

前仿真结果

前仿真结果
注意 l e d [ 0 ] led[0] led[0]是不定态。后面要对比。

后仿真结果

后仿真结果
对比两次仿真的结果,可以发现后仿真中不存在不定态。可以理解,毕竟要生成具体的电路所有的信号都要确定下来。
此时 l e d [ 0 ] led[0] led[0]变为1。结合代码,高组态和高电平想与,综合后的结果是高电平。
cnt寄存器因为被优化,默认高阻态。

结论

所有vivado 对于高阻态的优化是非常智能的。前仿真中确定是高阻态的输出的,会直接优化相关逻辑输出高阻态。前仿真时不定态的,会在综合后确定电路的状态,但是这个不定态如何确定请看第二节。

2,不定态

代码

和前面的代码相比,主要增加了与或非几个不同的操作。
源代码

module top(
input clk,
input rst_n,
input en,
output wire[6:0] led,
output wire[1:0] cnt  
);
chip rita(
    .clk(clk),
    .rst_n(rst_n),
    .en(en),
    .led(led)
);
endmodule

module chip(
input clk,
input rst_n,
input en,
inout pad,
output reg [6:0]led,
output reg [1:0]cnt
    );
    wire en_z;
    assign pad=1'bz;
    assign en_z=1'bx;

    always@(posedge clk or negedge rst_n)begin
        if(!rst_n) led <= 0;
        else led <= {en_z,en, en_z&en,en_z|en, en_z & ~en, en_z|~en,~en_z};
    end 
    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n) cnt <= 0;
        else cnt <= cnt+~en_z;
    end
endmodule

仿真代码

module tb_top(

    );
reg clk = 0;
always #10 clk = ~clk;
reg rst_n;
reg en;
initial begin
    rst_n = 0;
    en = 0;
    #50 rst_n =1;
    #50 en = 1;
    #50 en = 0;
    #50 en = 1;
end
wire [6:0]led;
wire [1:0]cnt;
top u_top(
.clk(clk),
.rst_n(rst_n),
.en(en),
.led(led),
.cnt(cnt)
);

endmodule

综合后的原理图

在这里插入图片描述

前仿真结果

在这里插入图片描述
前仿真,含有大量的不定态,符合预期。

后仿真结果

在这里插入图片描述
后仿真不包含不定态,也符合预期。关键是不定态怎么消失的。
根据代码
在这里插入图片描述
可知,假定不定态和信号a进行逻辑操作。如果a不变化,结果为0保持不变。
当a变化后,结果发生变化。单独游逻辑X导致的,例如led[6]和led[0]会输出0;
x和信号a进行&和|操作,结果会和x信号a保持一致,就相当于没有进行&和|操作。

结论

不定态在后仿真中会被消除。单纯由不定态导致的输出,会变成0;和其他信号进行逻辑操作后的结果和其他信号保持一致。
后面又做了其他的实验,高阻态和其他逻辑操作的结果也是和其他信号保持一致。

3,cnt的情况说明

上面两个实验的代码中除了led外,还有cnt。cnt的行为似乎不符合我说的逻辑,其实是因为我代码写的时候。top里面例化chip的时候忘记把cnt引出来。。。。。。。大家无视它就好。

  • 9
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值