`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 19:03:41 12/15/2007 // Design Name: // Module Name: NTSC // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module NTSC(signal, trigger, clk); output reg [7:0] signal; output reg trigger; input clk; //////////////////////////////// // states //////////////////////////////// reg [1:0] lineState; parameter sFP = 0, sHSYNC = 1, sBP = 2, sLINE = 3; reg [0:0] syncState; parameter sIMAGE = 0, sVSYNC = 1; reg [1:0] vbiState; parameter sPRE = 0, sVERT = 1, sPOST = 2, sBLANK = 3; reg [0:0] fieldState; parameter sEVEN = 0, sODD = 1; initial begin lineState = sFP; syncState = sIMAGE; fieldState = sEVEN; end //////////////////////////////// // signal //////////////////////////////// parameter nBLACK = 77, nSYNC = 0; reg [7:0] pixel, level; reg [9:0] line; //////////////////////////////// // timers //////////////////////////////// // timer counts must be 1 less than calculated because timer starts at 0!!! // clkFreq = 25000000; reg [31:0] lineTimer; reg [63:0] posTimer; reg [6:0] xpos; reg [7:0] ypos; reg [6:0] xpos2; reg [7:0] ypos2; reg [3:0] xvel; reg [3:0] yvel; reg [3:0] xvel2; reg [3:0] yvel2; reg odd; reg resetTimer; initial begin lineTimer = 0; resetTimer = 0; xpos = 12; ypos = 68; xvel = 7;//0-10; 5 is no velocity yvel = 6;//0-10; 5 is no velocity xpos2 = 112; ypos2 = 38; xvel2 = 3;//0-10; 5 is no velocity yvel = 8;//0-10; 5 is no velocity end //////////////////////////////// // the thing //////////////////////////////// always @(posedge posTimer[20]) begin if (odd) begin xpos = xpos+(xvel-5);//0-127 ypos = ypos+2*(yvel-5);//0-255 if (((xpos+(xvel-5))>125)|((xpos+(xvel-5))<2)) begin case (xvel) 0: xvel=10; 1: xvel=9; 2: xvel=8; 3: xvel=7; 4: xvel=6; 6: xvel=4; 7: xvel=3; 8: xvel=2; 9: xvel=1; 10: xvel=0; endcase end if (((ypos+2*(yvel-5))>252)|((ypos+2*(yvel-5))<4)) begin case (yvel) 0: yvel=10; 1: yvel=9; 2: yvel=8; 3: yvel=7; 4: yvel=6; 6: yvel=4; 7: yvel=3; 8: yvel=2; 9: yvel=1; 10: yvel=0; endcase end xpos2 = xpos2+(xvel2-5);//0-127 ypos2 = ypos2+2*(yvel2-5);//0-255 if (((xpos2+(xvel2-5))>127)|((xpos2+(xvel2-5))<2)) begin //(((xpos+xvel-xpos2-xvel2)<2)&&((xpos+xvel-xpos2-xvel2)>2)) thids is a thought... forget it case (xvel2) 0: xvel2=10; 1: xvel2=9; 2: xvel2=8; 3: xvel2=7; 4: xvel2=6; 6: xvel2=4; 7: xvel2=3; 8: xvel2=2; 9: xvel2=1; 10: xvel2=0; endcase end if (((ypos2+2*(yvel2-5))>256)|((ypos2+2*(yvel2-5))<4)) begin case (yvel2) 0: yvel2=10; 1: yvel2=9; 2: yvel2=8; 3: yvel2=7; 4: yvel2=6; 6: yvel2=4; 7: yvel2=3; 8: yvel2=2; 9: yvel2=1; 10: yvel2=0; endcase end end end always @(posedge clk) begin if (resetTimer) begin lineTimer = 0; resetTimer = 0; odd=odd+1; end else begin lineTimer = lineTimer + 1; end posTimer = posTimer + 1; case (syncState) ////////////////////////////// // image ////////////////////////////// sIMAGE: begin trigger = 0; case (lineState) sFP: begin signal = nBLACK; if (lineTimer >= 34) begin // 1.4 us lineState = sHSYNC; resetTimer = 1; end end sHSYNC: begin signal = nSYNC; if (lineTimer >= 117) begin // 4.7 us lineState = sBP; resetTimer = 1; // set up the pixel address pixel = 0; // address = line * 256 + pixel; end end sBP: begin signal = nBLACK; if (lineTimer >= 146) begin // 5.9 us lineState = sLINE; resetTimer = 1; end end sLINE: begin if (pixel < 255) begin signal = level; if (lineTimer >= 4) begin // 200 ns per pixel if (pixel<48||pixel>128+48||line<128||line>128+256) begin level = 128; end else begin if (line<128+ypos-4||line>128+ypos+4||pixel<48+xpos-2||pixel>48+xpos+2) begin //make square at pos. if (line<128+ypos2-2||line>128+ypos2+2||pixel<48+xpos2-1||pixel>48+xpos2+1) begin level = 255; end else begin level = 128; end end else begin level = nBLACK; end end pixel = pixel + 1; resetTimer = 1; end end else begin line = line + 2; lineState = sFP; if (line >= 483) begin syncState = sVSYNC; vbiState = sPRE; line = 0; resetTimer = 1; end end end endcase end ////////////////////////////// // vertical synchronization ////////////////////////////// sVSYNC: begin if (fieldState == sEVEN) begin trigger = 1; end case (vbiState) sPRE: begin case (lineState) sFP: begin signal = nSYNC; if (lineTimer >= 34) begin // 1.4 us lineState = sLINE; resetTimer = 1; end end sLINE: begin signal = nBLACK; if (lineTimer >= 758) begin // 63.5/2 - 1.4 us lineState = sFP; resetTimer = 1; line = line + 1; if ((fieldState == sEVEN && line >= 7) || (fieldState == sODD && line >= 6)) begin vbiState = sVERT; line = 0; end end end endcase end sVERT: begin case (lineState) sFP: begin signal = nSYNC; if (lineTimer >= 675) begin // 63.5/2 - 4.7 us lineState = sHSYNC; resetTimer = 1; end end sHSYNC: begin signal = nBLACK; if (lineTimer >= 117) begin // 4.7 us lineState = sFP; resetTimer = 1; line = line + 1; if (line >= 6) begin vbiState = sPOST; line = 0; end end end endcase end sPOST: begin case (lineState) sFP: begin signal = nSYNC; if (lineTimer >= 34) begin // 1.4 us lineState = sLINE; resetTimer = 1; end end sLINE: begin signal = nBLACK; if (lineTimer >= 758) begin // 63.5/2 - 1.4 us lineState = sFP; resetTimer = 1; line = line + 1; if ((fieldState == sEVEN && line >= 5) || (fieldState == sODD && line >= 6)) begin vbiState = sBLANK; line = 0; end end end endcase end sBLANK: begin case (lineState) sFP: begin signal = nSYNC; if (lineTimer >= 117) begin // 4.7 us lineState = sLINE; resetTimer = 1; end end sLINE: begin signal = nBLACK; if (lineTimer >= 1469) begin // 63.5 - 4.7 us lineState = sFP; resetTimer = 1; line = line + 1; if ((fieldState == sEVEN && line >= 12) || (fieldState == sODD && line >= 11)) begin lineState = sFP; syncState = sIMAGE; fieldState = !fieldState; // start on line 0 if sODD, line 1 if sEVEN line = fieldState; end end end endcase end endcase end endcase end endmodule