//****************************************************************************************** //* COMPANY : TERASIC. www.terasic.com (c) 2005 all rights reserved. * //* NAME : ITU-R BT.656 YCrCb 4:2:2 DECODER * //* Created : 7/5/2005 * //* Author : Joe Yang * //****************************************************************************************** `define sync 8'd101 module itu_r656_decoder ( CLOCK, //system clock TD_D, //4:2:2 video data stream TD_HS, //Decoder_hs TD_VS, //Decoder_vs Y, //4:4:4 Y Cb, //4:4:4 Cb Cr, //4:4:4 Cr Ypix_clock, //Y pixel clock HSx2, VSx1, Y_check, START, COUNTER, R,G,B, h_tr, SW0,SW1, blank ); input CLOCK; input [7:0]TD_D; input TD_HS; input TD_VS; input SW0; input SW1; output [7:0]Y; output [7:0]Cb; output [7:0]Cr; output HSx2; output VSx1; output Ypix_clock; //test output Y_check; output START; output [1:0]COUNTER; output [9:0]R; output [9:0]G; output [9:0]B; output h_tr; output blank; reg [7:0]YY; reg [7:0]CCb,Cbb; reg [7:0]CCr,Crr; reg HSx2 ;//TD_HS; wire VSx1=TD_VS; reg[7:0]R1,R2,R3; reg[7:0]RR1,RR2,RR3; wire [7:0]cr={2'b0,Cr[6:1]}; wire [7:0]cb={3'b0,Cb[6:2]}; wire [7:0]Rr=(Y-16)-{1'b0,Cr[7:0]}; wire [7:0]Gg=(Y-16)-cr -cb; wire [7:0]Bb=(Y-16)-{1'b0,Cb[7:0]}; wire [9:0]R={Rr,2'b00}; wire [9:0]G={Gg,2'b00}; wire [9:0]B={Bb,2'b00}; // wire Y_check=( (R3==8'hff) && (R2==8'h00) && (R1==8'h00) )?1:0; always @(posedge CLOCK) begin RR1=TD_D; RR2=R1; RR3=R2; end always @(negedge CLOCK) begin R1=RR1; R2=RR2; R3=RR3; end reg START,Field; always @(posedge CLOCK) begin if (Y_check==1) begin START=~TD_D[4]; Field= TD_D[6]; end end reg [1:0]COUNTER; always @(posedge CLOCK) begin if (!START) COUNTER=0; else COUNTER=COUNTER+1; end reg Ypix_clock; always @(posedge CLOCK) begin case (COUNTER) 0:begin Cbb=TD_D; Ypix_clock =0;end 1:begin YY =TD_D;CCr=Crr;CCb=Cbb; Ypix_clock =1;end 2:begin Crr=TD_D; Ypix_clock =0;end 3:begin YY =TD_D;CCr=Crr;CCb=Cbb; Ypix_clock =1;end endcase end reg [10:0]H_COUNTER; reg [10:0]RH_COUNTER; always @(posedge CLOCK) begin if (TD_HS) H_COUNTER=0; else H_COUNTER=H_COUNTER+1; end always @(posedge TD_HS) begin RH_COUNTER=H_COUNTER; end always @(posedge CLOCK) begin if ( ((H_COUNTER >= 0) && (H_COUNTER < `sync)) || ((H_COUNTER >= RH_COUNTER[10:1]) && (H_COUNTER < (RH_COUNTER[10:1]+`sync+1))) ) HSx2=0; else HSx2=1; end reg [10:0]h; reg h_tr; reg h_tr_h; always @(posedge CLOCK) begin if(!HSx2) h=0; else h=h+1; end always @(posedge CLOCK) begin if ((h< 51) || (h > 771)) h_tr=0; else h_tr=1; end always @(posedge CLOCK) begin if ((h< 41) || (h > 781)) h_tr_h=0; else h_tr_h=1; end wire [7:0]Yw,YYw; wire [7:0]Cwr,CCwr; wire [7:0]Cwb,CCwb; reg [10:0]pcounter_h; reg [10:0]pcounter_v; always @(posedge CLOCK) begin if (!h_tr) pcounter_h=0; else pcounter_h=pcounter_h+1; end always @(posedge h_tr) begin if (!TD_VS) pcounter_v=0; else pcounter_v=pcounter_v+1; end wire t=( // ((pcounter_h >=0) && (pcounter_h < 45) && (pcounter_v[9:5]==5'b00000)) || ((pcounter_h >=0) && (pcounter_h < 90) && (pcounter_v[9:5]==5'b00001)) || ((pcounter_h >=0) && (pcounter_h < 135) && (pcounter_v[9:5]==5'b00010)) || ((pcounter_h >=0) && (pcounter_h < 180) && (pcounter_v[9:5]==5'b00011)) || ((pcounter_h >=0) && (pcounter_h < 225) && (pcounter_v[9:5]==5'b00100)) || ((pcounter_h >=0) && (pcounter_h < 270) && (pcounter_v[9:5]==5'b00101)) || ((pcounter_h >=0) && (pcounter_h < 315) && (pcounter_v[9:5]==5'b00110)) || //((pcounter_h >=0) && (pcounter_h < 360) && (pcounter_v[9:5]==5'b00111)) || ((pcounter_h >=0) && (pcounter_h < 405) && (pcounter_v[9:5]==5'b01000)) || ((pcounter_h >=0) && (pcounter_h < 450) && (pcounter_v[9:5]==5'b01001)) || ((pcounter_h >=0) && (pcounter_h < 495) && (pcounter_v[9:5]==5'b01010)) || ((pcounter_h >=0) && (pcounter_h < 540) && (pcounter_v[9:5]==5'b01011)) || ((pcounter_h >=0) && (pcounter_h < 585) && (pcounter_v[9:5]==5'b01100)) || // ((pcounter_h >=0) && (pcounter_h < 630) && (pcounter_v[9:5]==5'b01101)) || ((pcounter_h >=0) && (pcounter_h < 675) && (pcounter_v[9:5]==5'b01110)) || ((pcounter_h >=0) && (pcounter_h < 720) && (pcounter_v[9:5]==5'b01111)) )?1:0; wire [7:0]ym= t? 8'hff:8'h80; wire [7:0]crm=t? 8'h80:8'h80; wire [7:0]cbm=t? 8'h80:8'h80; assign YYw =((h_tr==1) && (VSx1==1))?Yw : 8'h10;//current set assign CCwr =((h_tr==1) && (VSx1==1))?Cwr: 8'h80; assign CCwb =((h_tr==1) && (VSx1==1))?Cwb: 8'h80; wire [7:0]Ymm =SW1? ym :Yw ; wire [7:0]Crmm =SW1? crm:Cwr; wire [7:0]Cbmm =SW1? cbm:Cwb; reg[10:0]Hde_counter; reg[10:0]Vde_counter; always @(posedge CLOCK)begin if(HSx2==0) Hde_counter=0; else Hde_counter=Hde_counter+1; end always@(posedge HSx2)begin if (TD_VS==0) Vde_counter=0; else Vde_counter=Vde_counter+1; end wire hde=((Hde_counter > 51) && (Hde_counter < 691)) ? 1:0;//720 wire vde=((Vde_counter > 31) && (Vde_counter < 511)) ? 1:0;//480 wire blank_h = h_tr & vde; wire blank = h_tr_h & vde; wire [7:0]Y = (blank_h)?Ymm :8'h10; wire [7:0]Cr = (blank_h)?Crmm :8'h80; wire [7:0]Cb = (blank_h)?Cbmm :8'h80; dul_port_c1024 YYYR( .iDATA(YY[7:0]), .iHSYNC(TD_HS), // .iHSYNCx2(HSx2), .iHSYNCx2(blank), .Y_CLOCK(Ypix_clock), .Y_CLOCKx2(CLOCK), .oDATA(Yw[7:0]), .field(Field), .VS(TD_VS) ); dul_port_c1024 CBB( .iDATA(CCb[7:0]), .iHSYNC(TD_HS), // .iHSYNCx2(HSx2), .iHSYNCx2(blank), .Y_CLOCK(Ypix_clock), .Y_CLOCKx2(CLOCK), .oDATA(Cwb[7:0]), .field(Field), .VS(TD_VS) ); dul_port_c1024 CRR( .iDATA(CCr[7:0]), .iHSYNC(TD_HS), // .iHSYNCx2(HSx2), .iHSYNCx2(blank), .Y_CLOCK(Ypix_clock), .Y_CLOCKx2(CLOCK), .oDATA(Cwr[7:0]), .field(Field), .VS(TD_VS) ); endmodule