// // H/V Synchronization signal generator // // by Daniel Rozsnyo // module sync_gen_2d( inClock, inReset, inData, inAddr, inWrite, outX, outY, outActive, outHSync, outVSync ); // -------------------------------------------------- interface // inputs input inClock; // L->H change internal state // H->L changing the outputs input inReset; // active H, asynchronous input[11:0] inData; input[2:0] inAddr; input inWrite; // active L, #WE signal // outputs output[11:0] outX; output[11:0] outY; output outActive; // active H - updated on clock H->L output outHSync; // active L - updated on clock H->L output outVSync; // active L - updated on clock H->L // -------------------------------------------------- internal state // timing settings reg [11:0] cfgXActive; reg [11:0] cfgXFront; reg [11:0] cfgXSync; reg [11:0] cfgXBack; reg [11:0] cfgYActive; reg [11:0] cfgYFront; reg [11:0] cfgYSync; reg [11:0] cfgYBack; // internal counters reg [11:0] cntXPosition; reg [1:0] cntXState; reg [11:0] cntYPosition; reg [1:0] cntYState; // output buffers reg [11:0] outX; reg [11:0] outY; reg outActive; reg outHSync; reg outVSync; // -------------------------------------------------- internal signals reg intLastX; reg intLastY; // -------------------------------------------------- loading of config registers always @( inAddr or inWrite ) begin if ( !inWrite ) begin case( inAddr ) 0 : cfgXActive = inData; 1 : cfgXFront = inData; 2 : cfgXSync = inData; 3 : cfgXBack = inData; 4 : cfgYActive = inData; 5 : cfgYFront = inData; 6 : cfgYSync = inData; 7 : cfgYBack = inData; endcase end end // -------------------------------------------------- combinatorial internal signals always @( cntXPosition or cntXState ) begin case( cntXState ) 0 : intLastX = cntXPosition == cfgXActive; 1 : intLastX = cntXPosition == cfgXFront; 2 : intLastX = cntXPosition == cfgXSync; 3 : intLastX = cntXPosition == cfgXBack; endcase end always @( cntYPosition or cntYState ) begin case( cntYState ) 0 : intLastY = cntYPosition == cfgYActive; 1 : intLastY = cntYPosition == cfgYFront; 2 : intLastY = cntYPosition == cfgYSync; 3 : intLastY = cntYPosition == cfgYBack; endcase end // -------------------------------------------------- asynchronous reset signal always @( inReset ) begin if ( inReset ) begin cntXPosition = 0; cntXState = 0; cntYPosition = 0; cntYState = 0; end end // -------------------------------------------------- making an iteration always @( posedge inClock ) begin cntXPosition <= cntXPosition + 1; if ( intLastX ) begin cntXState <= cntXState + 1; end if (( intLastX & (cntXState==3) ) | inReset ) begin cntXState <= 0; cntXPosition <= 0; end if ( intLastX & ( cntXState == 1 ) ) begin cntYPosition <= cntYPosition + 1; if ( intLastY ) begin cntYState <= cntYState + 1; end if (( intLastY & (cntYState==3) ) | inReset ) begin cntYState <= 0; cntYPosition <= 0; end end end // -------------------------------------------------- buffered output signals always @( negedge inClock ) begin outX <= cntXPosition; outY <= cntYPosition; outActive <= (cntXState == 0) & (cntYState == 0); outHSync <= cntXState != 2; outVSync <= cntYState != 2; end endmodule