声明

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


文章目录

  • 声明
  • 引言
  • 1,高阻z
  • 代码
  • 综合后的原理图
  • 前仿真结果
  • 后仿真结果
  • 结论
  • 2,不定态
  • 代码
  • 综合后的原理图
  • 前仿真结果
  • 后仿真结果
  • 结论
  • 3,cnt的情况说明


引言

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

1,高阻z

代码

先附上用来验证的源代码和仿真代码。
代码结构比较简单,vivado block design 配置输入输出端口 vivado输出为z_sed信号就是我们要验证的信号。
源代码

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

综合后的原理图

vivado block design 配置输入输出端口 vivado输出为z_经验分享_02


电路内信号的状态只有0或1,看vivado block design 配置输入输出端口 vivado输出为z_经验分享_03vivado block design 配置输入输出端口 vivado输出为z_verilog_04 信号直接接地,此处信号被综合成0;但是后面,vivado block design 配置输入输出端口 vivado输出为z_其他_05这是一个三态输出BUF。

至于vivado block design 配置输入输出端口 vivado输出为z_sed_06寄存器因为忘了引出来则直接被优化掉了,通过输出BUF直接输出。

前仿真结果

vivado block design 配置输入输出端口 vivado输出为z_经验分享_07


注意vivado block design 配置输入输出端口 vivado输出为z_fpga_08是不定态。后面要对比。

后仿真结果

vivado block design 配置输入输出端口 vivado输出为z_经验分享_09


对比两次仿真的结果,可以发现后仿真中不存在不定态。可以理解,毕竟要生成具体的电路所有的信号都要确定下来。

此时vivado block design 配置输入输出端口 vivado输出为z_fpga_08变为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

综合后的原理图

vivado block design 配置输入输出端口 vivado输出为z_fpga_11

前仿真结果

vivado block design 配置输入输出端口 vivado输出为z_其他_12


前仿真,含有大量的不定态,符合预期。

后仿真结果

vivado block design 配置输入输出端口 vivado输出为z_sed_13


后仿真不包含不定态,也符合预期。关键是不定态怎么消失的。

根据代码

vivado block design 配置输入输出端口 vivado输出为z_其他_14


可知,假定不定态和信号a进行逻辑操作。如果a不变化,结果为0保持不变。

当a变化后,结果发生变化。单独游逻辑X导致的,例如led[6]和led[0]会输出0;

x和信号a进行&和|操作,结果会和x信号a保持一致,就相当于没有进行&和|操作。

结论

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

3,cnt的情况说明

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