summaryrefslogtreecommitdiffstats
path: root/videotest.v
blob: 653b1291f89b3fc412ea8ac041350c66ca872287 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//
// videotest.v
//
// Simple VGA graphics generator
//
// We use the standard VGA "text" monitor timings mode,
// htime = 31.77 us (31.47 kHz), vtime = 14.27 ms (70 Hz)
// The standard VGA uses a pixel clock of 25.175 MHz, we use 25 MHz,
// and round to multiples of 8.  The error is about 0.8%, which
// is far, far less than the margin of error in real systems.
//
// This gives us the following timings:
// Horizontal:  96 pixels (12 char) sync
//              48 pixels ( 6 char) back porch/border
//             640 pixels (80 char) graphics
//              16 pixels ( 2 char) front porch
// Vertical:     2 lines sync
//              41 lines back porch/border
//             384 lines graphics (24 rows @ 16 pixels)
//              22 lines front porch
//
// The DAC used introduced in the Lancelot card introduces
// 8 cycles of delay.
//

module videotest (
		  clkin,	// PLL input clock
		  pld_clkout,	// Clock to Lancelot board
		  vga_m1,
		  vga_m2,
		  vga_r,
		  vga_g,
		  vga_b,
		  vga_sync_n,
		  vga_sync_t,
		  vga_blank_n,
		  vga_hs,
		  vga_vs,

		  led
		  );

   input        clkin;
   output 	pld_clkout;
   
   output [7:0] vga_r;
   output [7:0] vga_g;
   output [7:0] vga_b;
   output 	vga_m1;
   output 	vga_m2;
   output 	vga_sync_n;
   output 	vga_sync_t;
   output 	vga_blank_n;
   output 	vga_hs;
   output 	vga_vs;

   output [7:0] led;

   wire 	clk;		// 25 MHz clock from PLL
   
   wire [9:0] 	x_blank = 640+8;
   wire [9:0]	x_sync = x_blank+24;
   wire [9:0]   x_back = x_sync+96;
   wire [9:0]	x_max = x_back+40;
   wire [8:0]	y_blank = 384;
   wire [8:0]	y_sync = y_blank+22;
   wire [8:0]   y_back = y_sync+2;
   wire [8:0]	y_max = y_back+41;

   wire 	hsync_neg = 1;	// Negative hsync
   wire 	vsync_neg = 0;	// Positive vsync
   
   reg [9:0] 	x;
   reg [8:0] 	y;
   reg [7:0] 	frame_ctr;
   
   wire 	xvideo = (x < x_blank);
   wire 	yvideo = (y < y_blank);
   
   assign vga_sync_t = 0;		// No sync-on-RGB
   assign vga_sync_n = 1;

   assign vga_m1 = 0;			// Color space configuration: GBR
   assign vga_m2 = 0;

   wire 	pll_clk0;	// 200 MHz clock (unused)

   // e0 and c1 are both 25 MHz clocks with the same phase, but pld_clkout
   // is a dedicated pin for pll1.e0
   mypll1 my_pll1 (
	       .inclk0( clkin ),
	       .pllena( 1 ),
	       .areset( 0 ),
	       .c0( pll_clk0 ),
	       .c1( clk ),
	       .e0( pld_clkout )
	       );
   
   always @( posedge clk )
     begin
	if ( xvideo & yvideo )
	  begin
	     vga_r <= x[7:0];
	     vga_g[7:6] <= x[9:8];
	     vga_b <= y[7:0];
	     vga_g[5] <= y[8];
	     vga_g[4:0] <= 0;

	     vga_blank_n <= 1;	// Inverse logic
	  end
	else
	  begin
	     vga_r <= 8'bx;
	     vga_g <= 8'bx;
	     vga_b <= 8'bx;
	     
	     vga_blank_n <= 0;
	  end

	vga_hs <= ( x >= x_sync && x < x_back ) ^ vsync_neg;
	vga_vs <= ( y >= y_sync && y < y_back ) ^ hsync_neg;
	
	if ( x == x_max-1 )
	  begin
	     x <= 0;
	     if ( y == y_max-1 )
	       begin
		  y <= 0;
		  frame_ctr <= frame_ctr + 1;
	       end
	     else
	       y <= y+1;
	  end
	else
	  x <= x+1;
     end // always @ ( posedge clk )

   // Flash LEDs for the hell of it
   always @( posedge clk )
     led <= (1 << frame_ctr[7:5]);
	
endmodule // videotest