////////////////////////////////////////////////////////////////////////////// // // Xilinx, Inc. 2007 www.xilinx.com // // XAPP xxx // ////////////////////////////////////////////////////////////////////////////// // // File name : chnlbond.v // // Description : Channel Bonding Logic // TMDS channel de-skew // // Author : Bob Feng // // Disclaimer: LIMITED WARRANTY AND DISCLAMER. These designs are // provided to you "as is". Xilinx and its licensors makeand you // receive no warranties or conditions, express, implied, // statutory or otherwise, and Xilinx specificallydisclaims any // implied warranties of merchantability, non-infringement,or // fitness for a particular purpose. Xilinx does notwarrant that // the functions contained in these designs will meet your // requirements, or that the operation of these designswill be // uninterrupted or error free, or that defects in theDesigns // will be corrected. Furthermore, Xilinx does not warrantor // make any representations regarding use or the results ofthe // use of the designs in terms of correctness, accuracy, // reliability, or otherwise. // // LIMITATION OF LIABILITY. In no event will Xilinx or its // licensors be liable for any loss of data, lost profits,cost // or procurement of substitute goods or services, or forany // special, incidental, consequential, or indirect damages // arising from the use or operation of the designs or // accompanying documentation, however caused and on anytheory // of liability. This limitation will apply even if Xilinx // has been advised of the possibility of such damage. This // limitation shall apply not-withstanding the failure ofthe // essential purpose of any limited remedies herein. // // Copyright © 2004 Xilinx, Inc. // All rights reserved // ////////////////////////////////////////////////////////////////////////////// `timescale 1 ns / 1ps module chnlbond ( input wire clk, input wire [9:0] rawdata, input wire iamvld, input wire other_ch0_vld, input wire other_ch1_vld, input wire other_ch0_rdy, input wire other_ch1_rdy, output reg iamrdy, output reg [9:0] sdata ); parameter CTRLTOKEN0 = 10'b1101010100; parameter CTRLTOKEN1 = 10'b0010101011; parameter CTRLTOKEN2 = 10'b0101010100; parameter CTRLTOKEN3 = 10'b1010101011; wire rawdata_vld; assign rawdata_vld = other_ch0_vld & other_ch1_vld & iamvld; reg [3:0] wa, ra; reg we; //////////////////////////////////////////////////////// // FIFO Write Control Logic //////////////////////////////////////////////////////// always @ (posedge clk) begin we <=#1 rawdata_vld; end always @ (posedge clk) begin if(rawdata_vld) wa <=#1 wa + 1'b1; else wa <=#1 4'h0; end wire [9:0] dpfo_dout; DRAM16XN #(.data_width(10)) cbfifo_i ( .DATA_IN(rawdata), .ADDRESS(wa), .ADDRESS_DP(ra), .WRITE_EN(we), .CLK(clk), .O_DATA_OUT(), .O_DATA_OUT_DP(dpfo_dout)); always @ (posedge clk) begin sdata <=#1 dpfo_dout; end //////////////////////////////////////////////////////// // FIFO read Control Logic //////////////////////////////////////////////////////// //////////////////////////////// // Use blank period beginning // as a speical marker to // align all channel together //////////////////////////////// reg rcvd_ctkn, rcvd_ctkn_q; //received control token reg blnkbgn; //blank period begins always @ (posedge clk) begin rcvd_ctkn <=#1 ((sdata == CTRLTOKEN0) || (sdata == CTRLTOKEN1) || (sdata == CTRLTOKEN2) || (sdata == CTRLTOKEN3)); rcvd_ctkn_q <=#1 rcvd_ctkn; blnkbgn <=#1 !rcvd_ctkn_q & rcvd_ctkn; end ///////////////////////////// //skip the current line ///////////////////////////// wire next_blnkbgn; reg skip_line; always @ (posedge clk) begin if(!rawdata_vld) skip_line <=#1 1'b0; else if(blnkbgn) skip_line <=#1 1'b1; end assign next_blnkbgn = skip_line & blnkbgn; ////////////////////////////// //Declare my own readiness ////////////////////////////// always @ (posedge clk) begin if(!rawdata_vld) iamrdy <=#1 1'b0; else if(next_blnkbgn) iamrdy <=#1 1'b1; end reg rawdata_vld_q; reg rawdata_vld_rising; always @ (posedge clk) begin rawdata_vld_q <=#1 rawdata_vld; rawdata_vld_rising <=#1 rawdata_vld & !rawdata_vld_q; end ////////////////////////////////////////////////////////////////////////////////////////// // 1. FIFO flow through first when all channels are found valid(phase aligned) // 2. When the speical marker on my channel is found, the fifo read is hold // 3. Until the same markers are found across all three channels, the fifo read resumes ////////////////////////////////////////////////////////////////////////////////////////// reg ra_en = 1'b0; always @ (posedge clk) begin if(rawdata_vld_rising || (other_ch0_rdy & other_ch1_rdy & iamrdy)) ra_en <=#1 1'b1; else if(next_blnkbgn && !(other_ch0_rdy & other_ch1_rdy & iamrdy)) ra_en <=#1 1'b0; end ///////////////////////////////////////// //FIFO Read Address Counter ///////////////////////////////////////// always @ (posedge clk) begin if(!rawdata_vld) ra <=#1 4'h0; else if(ra_en) ra <=#1 ra + 1'b1; end endmodule