2009年9月16日星期三

verilog综合时序仿真出现X状态解决一例

软件版本:ISE webpack 11.1 + Synplify Pro 9.6.1 + Modelsim SE 6.5
CPLD:xilinx XC9500系列
 
 
模块代码:
module rs485_fiber(clk, rs485_rx,fiber_rx, fiber_sd, 
                    rs485_tx, rs485_en, fiber_tx, led_tx, led_rx);
                    
    output rs485_tx, rs485_en, fiber_tx, led_tx, led_rx; 
    input  clk, rs485_rx, fiber_rx, fiber_sd;
    
    reg [2:0] delay;
    
    initial begin
        delay = 3'b000;
    end
    
   assign rs485_tx = ~fiber_rx;
   assign fiber_tx = ~rs485_rx;
   assign led_tx = rs485_rx;
   assign led_rx = rs485_tx & fiber_sd; 
   assign rs485_en = (~delay[2]) | (~delay[1]) | (~delay[0]);
 
   always @ (posedge clk )         //always @ (posedge clk or posedge fiber_rx)
        
       if (fiber_rx == 1)  
           delay <= 0;                           
       else
           if (delay == 7)
               delay <= 7;
           else
               delay <= delay + 1;            
endmodule
 
顶层测试代码:
module RS485_fiber_t;
// Inputs
reg clk;
reg rs485_rx;
reg fiber_rx;
reg fiber_sd;
// Outputs
wire rs485_tx;
wire rs485_en;
wire fiber_tx;
wire led_tx;
wire led_rx;
// Instantiate the Unit Under Test (UUT)
rs485_fiber uut (
.clk(clk), 
.rs485_rx(rs485_rx), 
.fiber_rx(fiber_rx), 
.fiber_sd(fiber_sd), 
.rs485_tx(rs485_tx), 
.rs485_en(rs485_en), 
.fiber_tx(fiber_tx), 
.led_tx(led_tx), 
.led_rx(led_rx)
);
 
always #15 clk <= ~clk; //15ns反转一次
always #5000 fiber_rx <= ~fiber_rx;  //5us反转一次
 
initial begin
// Initialize Inputs
clk = 0;
rs485_rx = 1;  
fiber_rx = 0;  
fiber_sd = 1;  
// Wait 100 ns for global reset to finish
#100;
        
// Add stimulus here
end
      
endmodule
 
 
synplify综合RTL图:
 
 
modelsim 前仿真没有问题,后仿真结果有问题:
 
 
 
修改模块代码,always @ (posedge clk )   为always @ (posedge clk or posedge fiber_rx)   则综合RTL图为:
modelsim 前仿真没有问题,后仿真结果也没有问题:
 
 
原因分析:
 
从代码1可以看出,综合的RTL图中有多个控制端的多路数据选择器,如果多个控制端同时动作(由于延时等),可能会冲突,导致逻辑短路,从而形成X状态。
 
而代码2综合生成的RTL图中多个控制端的多路数据选择器被简化为单个控制端的两路选择器,则不会有该问题。

没有评论: