//----------------------------------------------------------------------- // // Video Decoder // // Author: Alex Krasnov // Date: 07.14.2003 // Edit: Greg Gibeling // Date: 10.15.2003 // //----------------------------------------------------------------------- module vid_dec (CLK, RST, EN, P, RST_OUT_, ISO, SCLK, SDA, SOF, SEF, EAV, SAV, VALID, DATA_OUT); //--------------------------------------------------------------- // General Control Inputs //--------------------------------------------------------------- input CLK; // Clock input RST; // Reset input EN; // Enable //--------------------------------------------------------------- //--------------------------------------------------------------- // Raw Video Input //--------------------------------------------------------------- input [9:0] P; // This is the video data from the decoder chip //--------------------------------------------------------------- //--------------------------------------------------------------- // General Control Outputs //--------------------------------------------------------------- output RST_OUT_; // Decoder Reset output ISO; // Decoder Sync output SCLK; // I2C Clock out to the decoder chip output SDA; // I2C Data out to the decoder chip //--------------------------------------------------------------- //--------------------------------------------------------------- // Decoded Video Outputs //--------------------------------------------------------------- output SOF; // Start of odd field (coincides with SAV) output SEF; // Start of even field (coincides with SAV) output EAV; // End of active video output SAV; // Start of active video output VALID; // Indicates that decoded data is valid output [31:0] DATA_OUT; // Video Data in {Cb,Y,Cr,Y} //--------------------------------------------------------------- //--------------------------------------------------------------- // Reg declarations for outputs //--------------------------------------------------------------- reg EAV, SAV; reg VALID; reg [31:0] DATA_OUT; //--------------------------------------------------------------- //--------------------------------------------------------------- // Internal Regs //--------------------------------------------------------------- reg ACTIVE; reg _F, _V; reg COUNT_RST; reg [1:0] COUNT; //--------------------------------------------------------------- //--------------------------------------------------------------- // Wires //--------------------------------------------------------------- wire [7:0] DATA_IN; wire M, F, V, H; // Sync signals wire [3:0] E; // Sync signal error detection codes wire E_VALID; wire EAV_VALID, SAV_VALID; // Delimiter sample valid //--------------------------------------------------------------- // Parameters/Constants //--------------------------------------------------------------- parameter sampleDAV0 = 8'hff, // Delimiter samples sampleDAV1 = 8'h00, sampleDAV2 = 8'h00; //--------------------------------------------------------------- //--------------------------------------------------------------- // Sequential Logic (Registers) //--------------------------------------------------------------- always @ (posedge CLK) begin if (RST) ACTIVE <= 1'b0; else if (EN & SOF) ACTIVE <= 1'b1; end always @ (posedge CLK) begin if (RST) begin _F <= 1'b1; _V <= 1'b1; end else if (SAV) begin _F <= F; _V <= V; end end // Counter always @ (posedge CLK) begin if (COUNT_RST) COUNT <= 2'b00; else COUNT <= (COUNT + 2'b01); end // Shift Register always @ (posedge CLK) DATA_OUT <= { DATA_OUT[23:0], DATA_IN }; //--------------------------------------------------------------- //--------------------------------------------------------------- // Simple Combinational Logic //--------------------------------------------------------------- assign RST_OUT_ = ~RST; assign ISO = 1'b0; assign SCLK = 1'b0; // Decoder doesn't need I2C assign SDA = 1'b1; assign SOF = (SAV & ~_F & F); assign SEF = (SAV & _F & ~F); assign DATA_IN = P[9:2]; assign {M,F,V,H,E} = DATA_IN; assign E_VALID = ((E[3] == (V ^ H)) && (E[2] == (F ^ H)) && (E[1] == (F ^ V)) && (E[0] == (F ^ V ^ H))); assign EAV_VALID = (M & H & E_VALID); assign SAV_VALID = (M & ~H & E_VALID); //--------------------------------------------------------------- //--------------------------------------------------------------- // State machine //--------------------------------------------------------------- reg [3:0] CS, NS; // Current state and next state //--------------------------------------------------------------- //--------------------------------------------------------------- // State Encodings //--------------------------------------------------------------- parameter stateEAV0 = 4'b0000, stateEAV1 = 4'b0001, stateEAV2 = 4'b0010, stateEAV3 = 4'b0011, stateSAV0 = 4'b0100, stateSAV1 = 4'b0101, stateSAV2 = 4'b0110, stateSAV3 = 4'b0111, stateSkip = 4'b1000; //--------------------------------------------------------------- //--------------------------------------------------------------- // Current State Register //--------------------------------------------------------------- always @(posedge CLK) begin if (RST) CS <= stateEAV0; else CS <= NS; end //--------------------------------------------------------------- //--------------------------------------------------------------- // Next State and Output Combinational Logic //--------------------------------------------------------------- always @ (CS or ACTIVE or _V or COUNT or DATA_IN or EAV_VALID or SAV_VALID) begin COUNT_RST = 1'b0; EAV = 1'b0; SAV = 1'b0; VALID = 1'b0; NS = CS; case (CS) stateEAV0: begin VALID = (ACTIVE && ~_V && (COUNT == 2'b00)); if (DATA_IN == sampleDAV0) NS = stateEAV1; end stateEAV1: begin if (DATA_IN == sampleDAV1) NS = stateEAV2; else NS = stateEAV0; end stateEAV2: begin if (DATA_IN == sampleDAV2) NS = stateEAV3; else NS = stateEAV0; end stateEAV3: begin if (EAV_VALID) begin EAV = 1'b1; NS = stateSAV0; end else NS = stateEAV0; end stateSAV0: begin if (DATA_IN == sampleDAV0) NS = stateSAV1; end stateSAV1: begin if (DATA_IN == sampleDAV1) NS = stateSAV2; else NS = stateSAV0; end stateSAV2: begin if (DATA_IN == sampleDAV2) NS = stateSAV3; else NS = stateSAV0; end stateSAV3: begin if (SAV_VALID) begin COUNT_RST = 1'b1; SAV = 1'b1; NS = stateSkip; end else NS = stateSAV0; end stateSkip: begin // skip first data word NS = stateEAV0; end endcase end //--------------------------------------------------------------- endmodule