2013-01-23 20 views
0

我有以下Verilog代碼:的Verilog:阻塞和非阻塞賦值到的混合可變<inc_data_int>不是推薦的編碼實踐

////////////////////////////////////////////////////////////////////////////// 
// 
// Xilinx, Inc. 2010     www.xilinx.com 
// 
// XAPP xxx - 1:5 Differential Data De-serializer 
// 
////////////////////////////////////////////////////////////////////////////// 
// 
// File name :  serdes_1_to_5_diff_data.v 
// 
// Description :  This module instantiates IODELAY2 and ISERDES2 primitives 
//     to receive TMDS differential data in 1:5 format 
// 
// Note:    
// 
// Author : Bob Feng 
////////////////////////////////////////////////////////////////////////////// 
// 
// Disclaimer: 
// 
// This disclaimer is not a license and does not grant any rights to the materials 
// distributed herewith. Except as otherwise provided in a valid license issued to you 
// by Xilinx, and to the maximum extent permitted by applicable law: 
// (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, 
// AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, 
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR 
// FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract 
// or tort, including negligence, or under any other theory of liability) for any loss or damage 
// of any kind or nature related to, arising under or in connection with these materials, 
// including for any direct, or any indirect, special, incidental, or consequential loss 
// or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered 
// as a result of any action brought by a third party) even if such damage or loss was 
// reasonably foreseeable or Xilinx had been advised of the possibility of the same. 
// 
// Critical Applications: 
// 
// Xilinx products are not designed or intended to be fail-safe, or for use in any application 
// requiring fail-safe performance, such as life-support or safety devices or systems, 
// Class III medical devices, nuclear facilities, applications related to the deployment of airbags, 
// or any other applications that could lead to death, personal injury, or severe property or 
// environmental damage (individually and collectively, "Critical Applications"). Customer assumes 
// the sole risk and liability of any use of Xilinx products in Critical Applications, subject only 
// to applicable laws and regulations governing limitations on product liability. 
// 
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES. 
// 
////////////////////////////////////////////////////////////////////////////// 

`timescale 1ps/1ps 

module serdes_1_to_5_diff_data # (
    parameter DIFF_TERM = "TRUE", 
    parameter SIM_TAP_DELAY = 49, 
    parameter BITSLIP_ENABLE = "FALSE" 
)(
    input wire  use_phase_detector, // '1' enables the phase detector logic 
    input wire  datain_p,   // Input from LVDS receiver pin 
    input wire  datain_n,   // Input from LVDS receiver pin 
    input wire  rxioclk,    // IO Clock network 
    input wire  rxserdesstrobe,  // Parallel data capture strobe 
    input wire  reset,    // Reset line 
    input wire  gclk,    // Global clock 
    input wire  bitslip,    // Bitslip control line 
    output wire [4:0] data_out    // Output data 
); 

    wire  ddly_m; 
    wire  ddly_s; 
    wire  busys; 
    wire  rx_data_in; 
    wire  cascade; 
    wire  pd_edge; 
    reg [8:0] counter; 
    reg [3:0] state; 
    reg  cal_data_sint; 
    wire  busy_data; 
    reg  busy_data_d; 
    wire  cal_data_slave; 
    reg  enable; 
    reg  cal_data_master; 
    reg  rst_data; 
    reg  inc_data_int; //THIS LINE (81) IS CAUSING THE ERROR 
    wire  inc_data; 
    reg  ce_data; 
    reg  valid_data_d; 
    reg  incdec_data_d; 
    reg [4:0] pdcounter; 
    wire  valid_data; 
    wire  incdec_data; 
    reg  flag; 
    reg  mux; 
    reg  ce_data_inta ; 
    wire [1:0] incdec_data_or; 
    wire  incdec_data_im; 
    wire [1:0] valid_data_or; 
    wire  valid_data_im; 
    wire [1:0] busy_data_or; 
    wire  all_ce; 

    wire [1:0] debug_in = 2'b00; 

    assign busy_data = busys ; 

    assign cal_data_slave = cal_data_sint ; 

    ///////////////////////////////////////////////// 
    // 
    // IDELAY Calibration FSM 
    // 
    ///////////////////////////////////////////////// 
    always @ (posedge gclk or posedge reset) 
    begin 
    if (reset == 1'b1) begin 
    state <= 0 ; 
    cal_data_master <= 1'b0 ; 
    cal_data_sint <= 1'b0 ; 
    counter <= 9'h000 ; 
    enable <= 1'b0 ; 
    mux <= 1'h1 ; 
    end 
    else begin 
     counter <= counter + 9'h001 ; 
     if (counter[8] == 1'b1) begin 
     counter <= 9'h000 ; 
     end 
     if (counter[5] == 1'b1) begin 
     enable <= 1'b1 ; 
     end 
     if (state == 0 && enable == 1'b1) begin  // Wait for IODELAY to be available 
     cal_data_master <= 1'b0 ; 
     cal_data_sint <= 1'b0 ; 
     rst_data <= 1'b0 ; 
     if (busy_data_d == 1'b0) begin 
     state <= 1 ; 
     end 
     end 
     else if (state == 1) begin   // Issue calibrate command to both master and slave, needed for simulation, not for the silicon 
     cal_data_master <= 1'b1 ; 
     cal_data_sint <= 1'b1 ; 
     if (busy_data_d == 1'b1) begin  // and wait for command to be accepted 
      state <= 2 ; 
     end 
     end 
     else if (state == 2) begin   // Now RST master and slave IODELAYs needed for simulation, not for the silicon 
     cal_data_master <= 1'b0 ; 
     cal_data_sint <= 1'b0 ; 
     if (busy_data_d == 1'b0) begin 
      rst_data <= 1'b1 ; 
      state <= 3 ; 
     end 
     end 
     else if (state == 3) begin   // Wait for IODELAY to be available 
     rst_data <= 1'b0 ; 
     if (busy_data_d == 1'b0) begin 
      state <= 4 ; 
     end 
     end 
     else if (state == 4) begin   // Wait for occasional enable 
     if (counter[8] == 1'b1) begin 
      state <= 5 ; 
     end 
     end 
     else if (state == 5) begin   // Calibrate slave only 
     if (busy_data_d == 1'b0) begin 
      cal_data_sint <= 1'b1 ; 
      state <= 6 ; 
     end 
     end 
     else if (state == 6) begin   // Wait for command to be accepted 
     cal_data_sint <= 1'b0 ; 
     if (busy_data_d == 1'b1) begin 
      state <= 7 ; 
     end 
     end 
     else if (state == 7) begin   // Wait for all IODELAYs to be available, ie CAL command finished 
      cal_data_sint <= 1'b0 ; 
     if (busy_data_d == 1'b0) begin 
      state <= 4 ; 
     end 
     end 
    end 
    end 

always @ (posedge gclk or posedge reset)  // Per-bit phase detection state machine 
begin 
if (reset == 1'b1) begin 
    pdcounter <= 5'b1000 ; 
    ce_data_inta <= 1'b0 ; 
    flag <= 1'b0 ;    // flag is there to only allow one inc or dec per cal (test) 
end 
else begin 
    busy_data_d <= busy_data_or[1] ; 
    if (use_phase_detector == 1'b1) begin  // decide whther pd is used 
    incdec_data_d <= incdec_data_or[1] ; 
    valid_data_d <= valid_data_or[1] ; 
    if (ce_data_inta == 1'b1) begin 
     ce_data = mux ; 
    end 
    else begin 
     ce_data = 64'h0000000000000000 ; 
    end 
     if (state == 7) begin 
     flag <= 1'b0 ; 
    end 
     else if (state != 4 || busy_data_d == 1'b1) begin // Reset filter if state machine issues a cal command or unit is busy 
     pdcounter <= 5'b10000 ; 
     ce_data_inta <= 1'b0 ; 
     end 
     else if (pdcounter == 5'b11111 && flag == 1'b0) begin // Filter has reached positive max - increment the tap count 
     ce_data_inta <= 1'b1 ; 
     inc_data_int <= 1'b1 ; 
     pdcounter <= 5'b10000 ; 
     flag <= 1'b1 ; 
    end 
     else if (pdcounter == 5'b00000 && flag == 1'b0) begin // Filter has reached negative max - decrement the tap count 
     ce_data_inta <= 1'b1 ; 
     inc_data_int <= 1'b0 ; 
     pdcounter <= 5'b10000 ; 
     flag <= 1'b1 ; 
     end 
    else if (valid_data_d == 1'b1) begin  // increment filter 
     ce_data_inta <= 1'b0 ; 
     if (incdec_data_d == 1'b1 && pdcounter != 5'b11111) begin 
     pdcounter <= pdcounter + 5'b00001 ; 
     end 
     else if (incdec_data_d == 1'b0 && pdcounter != 5'b00000) begin // decrement filter 
     pdcounter <= pdcounter + 5'b11111 ; 
     end 
     end 
     else begin 
     ce_data_inta <= 1'b0 ; 
     end 
    end 
    else begin 
    ce_data = all_ce ; 
    inc_data_int = debug_in[1] ; 
    end 
end 
end 

assign inc_data = inc_data_int ; 

assign incdec_data_or[0] = 1'b0 ;    // Input Mux - Initialise generate loop OR gates 
assign valid_data_or[0] = 1'b0 ; 
assign busy_data_or[0] = 1'b0 ; 

assign incdec_data_im = incdec_data & mux;   // Input muxes 
assign incdec_data_or[1] = incdec_data_im | incdec_data_or;  // AND gates to allow just one signal through at a tome 
assign valid_data_im = valid_data & mux;   // followed by an OR 
assign valid_data_or[1] = valid_data_im | valid_data_or;  // for the three inputs from each PD 
assign busy_data_or[1] = busy_data | busy_data_or;  // The busy signals just need an OR gate 

assign all_ce = debug_in[0] ; 

IBUFDS #(
    .DIFF_TERM (DIFF_TERM)) 
data_in (
    .I   (datain_p), 
    .IB   (datain_n), 
    .O   (rx_data_in) 
); 

// 
// Master IDELAY 
// 
IODELAY2 #(
    .DATA_RATE   ("SDR"), 
    .IDELAY_VALUE   (0), 
    .IDELAY2_VALUE  (0), 
    .IDELAY_MODE   ("NORMAL"), 
    .ODELAY_VALUE   (0), 
    .IDELAY_TYPE   ("DIFF_PHASE_DETECTOR"), 
    .COUNTER_WRAPAROUND ("STAY_AT_LIMIT"), //("WRAPAROUND"), 
    .DELAY_SRC   ("IDATAIN"), 
    .SERDES_MODE   ("MASTER"), 
    .SIM_TAPDELAY_VALUE (SIM_TAP_DELAY) 
) iodelay_m (
    .IDATAIN    (rx_data_in),  // data from IBUFDS 
    .TOUT    (),    // tri-state signal to IOB 
    .DOUT    (),    // output data to IOB 
    .T     (1'b1),   // tri-state control from OLOGIC/OSERDES2 
    .ODATAIN    (1'b0),   // data from OLOGIC/OSERDES2 
    .DATAOUT    (ddly_m),   // Output data 1 to ILOGIC/ISERDES2 
    .DATAOUT2   (),    // Output data 2 to ILOGIC/ISERDES2 
    .IOCLK0    (rxioclk),   // High speed clock for calibration 
    .IOCLK1    (1'b0),   // High speed clock for calibration 
    .CLK     (gclk),   // Fabric clock (GCLK) for control signals 
    .CAL     (cal_data_master), // Calibrate control signal 
    .INC     (inc_data),  // Increment counter 
    .CE     (ce_data),   // Clock Enable 
    .RST     (rst_data),  // Reset delay line 
    .BUSY    ()     // output signal indicating sync circuit has finished/calibration has finished 
); 

// 
// Slave IDELAY 
// 
IODELAY2 #(
    .DATA_RATE   ("SDR"), 
    .IDELAY_VALUE   (0), 
    .IDELAY2_VALUE  (0), 
    .IDELAY_MODE   ("NORMAL"), 
    .ODELAY_VALUE   (0), 
    .IDELAY_TYPE   ("DIFF_PHASE_DETECTOR"), 
    .COUNTER_WRAPAROUND ("WRAPAROUND"), 
    .DELAY_SRC   ("IDATAIN"), 
    .SERDES_MODE   ("SLAVE"), 
    .SIM_TAPDELAY_VALUE (SIM_TAP_DELAY) 
) iodelay_s (
    .IDATAIN    (rx_data_in), // data from IBUFDS 
    .TOUT    (),   // tri-state signal to IOB 
    .DOUT    (),   // output data to IOB 
    .T     (1'b1),  // tri-state control from OLOGIC/OSERDES2 
    .ODATAIN    (1'b0),  // data from OLOGIC/OSERDES2 
    .DATAOUT    (ddly_s),  // Slave output data to ILOGIC/ISERDES2 
    .DATAOUT2   (),   // 
    .IOCLK0    (rxioclk),  // High speed IO clock for calibration 
    .IOCLK1    (1'b0), 
    .CLK     (gclk),  // Fabric clock (GCLK) for control signals 
    .CAL     (cal_data_slave), // Calibrate control signal 
    .INC     (inc_data),  // Increment counter 
    .CE     (ce_data),  // Clock Enable 
    .RST     (rst_data),  // Reset delay line 
    .BUSY     (busys)  // output signal indicating sync circuit has finished/calibration has finished 
); 

// 
// Master ISERDES 
// 

ISERDES2 #(
    .DATA_WIDTH  (5), 
    .DATA_RATE  ("SDR"), 
    .BITSLIP_ENABLE (BITSLIP_ENABLE), 
    .SERDES_MODE  ("MASTER"), 
    .INTERFACE_TYPE ("RETIMED")) 
iserdes_m (
    .D    (ddly_m), 
    .CE0    (1'b1), 
    .CLK0    (rxioclk), 
    .CLK1    (1'b0), 
    .IOCE    (rxserdesstrobe), 
    .RST    (reset), 
    .CLKDIV   (gclk), 
    .SHIFTIN   (pd_edge), 
    .BITSLIP   (bitslip), 
    .FABRICOUT  (), 
    .Q4    (data_out[4]), 
    .Q3    (data_out[3]), 
    .Q2    (data_out[2]), 
    .Q1    (data_out[1]), 
    .DFB    (), 
    .CFB0   (), 
    .CFB1   (), 
    .VALID   (valid_data), 
    .INCDEC   (incdec_data), 
    .SHIFTOUT   (cascade)); 

// 
// Slave ISERDES 
// 

ISERDES2 #(
    .DATA_WIDTH  (5), 
    .DATA_RATE  ("SDR"), 
    .BITSLIP_ENABLE (BITSLIP_ENABLE), 
    .SERDES_MODE  ("SLAVE"), 
    .INTERFACE_TYPE ("RETIMED") 
) iserdes_s (
    .D    (ddly_s), 
    .CE0    (1'b1), 
    .CLK0    (rxioclk), 
    .CLK1    (1'b0), 
    .IOCE    (rxserdesstrobe), 
    .RST    (reset), 
    .CLKDIV   (gclk), 
    .SHIFTIN   (cascade), 
    .BITSLIP   (bitslip), 
    .FABRICOUT  (), 
    .Q4    (data_out[0]), 
    .Q3    (), 
    .Q2    (), 
    .Q1    (), 
    .DFB    (), 
    .CFB0   (), 
    .CFB1   (), 
    .VALID   (), 
    .INCDEC   (), 
    .SHIFTOUT   (pd_edge)); 


reg [7:0] rxpdcntr = 8'h7f; 
always @ (posedge gclk or posedge reset) begin 
    if (reset) 
    rxpdcntr <= 8'h7f; 
    else if (ce_data) 
    if (inc_data) 
     rxpdcntr <= rxpdcntr + 1'b1; 
    else 
     rxpdcntr <= rxpdcntr - 1'b1; 
end 

endmodule 

我一直得到以下錯誤,當我嘗試以產生Xilinx Platform Studio中此設計的網表:

ERROR:HDLCompiler:1511 - "/home/eamorr/Desktop/Dropbox/UCD/digitalEye/Atlys_HDMI_PLB_demo/project/pcores/hdmi_in_v1_00_a/hdl/verilog/serdes_1_to_5_diff_data.v" Line 82: Mix of blocking and non-blocking assignments to variable <inc_data_int> is not a recommended coding practice. 
ERROR:EDK:546 - Aborting XST flow execution! 
ERROR:EDK:440 - platgen failed with errors! 
make: *** [implementation/system_microblaze_0_wrapper.ngc] Error 2 

我完全卡住了,不知道該怎麼做。

+1

看到這個答案的啓示(恕我直言)http://stackoverflow.com/questions/4653284/how-to-interpret-blocking-vs-non-blocking -assignments-in-verilog/4774450#4774450 –

回答

3

爲了推斷合成的時序邏輯,您應該使用nonblocking賦值(<=)而不是blocking賦值(=)。例如,使用:

ce_data <= mux ; 
+0

嗨,非常感謝您的回覆。我擔心我只能掌握Xilinx工具。我應該修改哪一行號碼?非常感謝, – Eamorr

+0

修改具有'ce_data = mux;'的行。您還必須修改使用'='的'always'塊中的每一行。 – toolic

+0

我和以前一樣困惑......你介意發佈修改過的代碼嗎?非常感謝, – Eamorr

0

這是從網站digilentic我假設的HDMI例子。

看所有的inc_data_int分配:

inc_data_int <= 1'b1 ; 
inc_data_int <= 1'b0 ; 
inc_data_int = debug_in[1] ; 

我註釋掉最後一個,因爲我認爲它是用於調試目的。

(我得到了HDMI那樣工作。)