///////////////////////////////////////////////////////////////////////////////////// // // // Video Encoder // // Decimated Version // // // // Author: Alex Krasnov // // Date: 09.19.2003 // // Notes: This version is *untested* // // // ///////////////////////////////////////////////////////////////////////////////////// module vid_enc (CLK, RST, EN, DATA_IN, RST_OUT_, PAL_NTSC, HSYNC_, VSYNC_, BLANK_, SCRESET, P, SCLK, SDA, SOF, SEF, EAV, SAV, MB, DATA_EN); // Inputs input CLK; input RST; input EN; input [7:0] DATA_IN; // Outputs output RST_OUT_; output PAL_NTSC; output HSYNC_; output VSYNC_; output BLANK_; output SCRESET; output [9:0] P; // video data output SCLK; // I2C interface output SDA; output SOF; // start of odd field (coincides with MB) output SEF; // start of even field (coincides with MB) output EAV; // end of active video output SAV; // start of active video output MB; // middle of horizontal blanking output DATA_EN; // data acknowledge // Registers reg H; reg [7:0] DATA_OUT; // Wires wire _SCLK; wire STOP; wire ACTIVE; wire _F; wire [12:0] HCOUNT; wire [9:0] VCOUNT; wire HCOUNT_TC, VCOUNT_TC; wire _EAV, _SAV; wire F, V, B; wire [3:0] E; wire [7:0] DAV3; wire DATA_LD, DATA_SH; wire [31:0] SH_DATA; // Parameters parameter hcntEAV = 9'd0, hcntMB = 11'd136, hcntSAV = 9'd68, hcntSV = 9'd75, hcntEV = 9'd386, hcnt320 = 9'd388, hcntEnd = 11'd1715; parameter vcntSOdd = 10'd2, vcntSAOdd = 10'd19, vcntSVOdd = 10'd23, vcntEVOdd = 10'd254, vcntEAO240 = 10'd259, vcntEAOdd = 10'd262, vcntEOdd = 10'd265, vcntSAEven = 10'd282, vcntSVEven = 10'd286, vcntEVEven = 10'd517, vcntEAE240 = 10'd522, vcntEAEven = 10'd524; // Sequential Logic rsff #(1) rsff(.C(CLK), .R(RST), .S(STOP), .Q(ACTIVE)); dff #(1) dff0(.C(CLK), .R(RST), .E(MB), .D(F), .Q(_F)); counter #(13) hc(.C(CLK), .R(RST | (ACTIVE & HCOUNT_TC)), .E(EN), .O(HCOUNT), .TC(), .EO()); counter #(10) vc(.C(CLK), .R(RST | (VCOUNT_TC & HCOUNT_TC)), .E(EN & HCOUNT_TC), .O(VCOUNT), .TC(), .EO()); dff #(1) dff1(.C(CLK), .R(RST), .E(1'b1), .D(DATA_EN), .Q(DATA_LD)); dff #(8) dff2(.C(CLK), .R(RST), .E(DATA_LD), .D(DATA_IN), .Q(SH_DATA)); SRL64E srl(.C(_SCLK), .E(1'b1), .D(SDA), .Q(SDA)); defparam srl.INIT_00 = 16'b0000000000111111; defparam srl.INIT_01 = 16'b0110000001111000; defparam srl.INIT_02 = 16'b0000000000000000; defparam srl.INIT_03 = 16'b1100011001100110; always @(HCOUNT or _EAV or _SAV or B or DAV3 or SH_DATA) begin if (_EAV | _SAV) begin H = _EAV; DATA_OUT = ((HCOUNT[1:0] == 2'b11) ? DAV3 : { 8 { (HCOUNT[1:0] == 2'b00) } }); end else begin H = 1'bx; DATA_OUT = ((B | ~HCOUNT[0]) ? 8'h80 : SH_DATA[31:24]); end end assign RST_OUT_ = ~(RST & EN); assign PAL_NTSC = 1'b0; assign HSYNC_ = 1'b1; assign VSYNC_ = 1'b1; assign BLANK_ = 1'b1; assign SCRESET = 1'b0; assign P = { DATA_OUT, 2'b00 }; assign SCLK = (EN & ~ACTIVE & HCOUNT[6]); // use shared counter assign _SCLK = (EN & ~ACTIVE & HCOUNT[5]); assign SOF = (MB & ~_F & F); assign SEF = (MB & _F & ~F); assign EAV = (_EAV && (HCOUNT[1:0] == 2'b11)); assign SAV = (_SAV && (HCOUNT[1:0] == 2'b11)); assign MB = (HCOUNT[10:0] == hcntMB); assign STOP = (HCOUNT[12:6] == 7'd64); assign HCOUNT_TC = (HCOUNT[10:0] == hcntEnd); assign VCOUNT_TC = (VCOUNT == vcntEAEven); assign _EAV = (HCOUNT[10:2] == hcntEAV); assign _SAV = (HCOUNT[10:2] == hcntSAV); assign F = ~((VCOUNT > vcntSOdd) && (VCOUNT < vcntEOdd)); assign V = ((VCOUNT < vcntSAOdd) || ((VCOUNT > vcntEAOdd) && (VCOUNT < vcntSAEven))); assign B = (V || (HCOUNT[10:2] < hcntSAV)); assign E[3] = (V ^ H); assign E[2] = (F ^ H); assign E[1] = (F ^ V); assign E[0] = (F ^ V ^ H); assign DAV3 = { 1'b1, F, V, H, E }; assign DATA_EN = (!B && (F ? (VCOUNT < vcntEAE240) : (VCOUNT < vcntEAO240)) && (HCOUNT[1:0] == 2'b10) && (HCOUNT[10:2] < hcnt320)); endmodule