gateware

A collection of little open source FPGA hobby projects
git clone http://frotz.net/git/gateware.git
Log | Files | Refs | README

display-timing.sv (4519B)


      1 // Copyright 2020, Brian Swetland <swetland@frotz.net>
      2 // Licensed under the Apache License, Version 2.0.
      3 
      4 `default_nettype none
      5 
      6 module display_timing #(
      7 	// horizontal timing (all values -1)
      8 	parameter HZNT_FRONT = 15,
      9 	parameter HZNT_SYNC = 95,
     10 	parameter HZNT_BACK = 47,
     11 	parameter HZNT_ACTIVE = 639,
     12 
     13 	// vertical timing (all values -1)
     14 	parameter VERT_FRONT = 11,
     15 	parameter VERT_SYNC = 1,
     16 	parameter VERT_BACK = 29,
     17 	parameter VERT_ACTIVE = 479
     18 )(
     19 	input wire clk,
     20 
     21 	output wire hsync,
     22 	output wire vsync,
     23 	output wire start_frame,
     24 	output wire start_line,
     25 	output wire pxl_accept,
     26 	output wire [9:0] pxl_x,
     27 	output wire [9:0] pxl_y
     28 );
     29 
     30 localparam HS_FRONT = 2'd0;
     31 localparam HS_SYNC = 2'd1;
     32 localparam HS_BACK = 2'd2;
     33 localparam HS_ACTIVE = 2'd3;
     34 
     35 localparam VS_FRONT = 2'd0;
     36 localparam VS_SYNC = 2'd1;
     37 localparam VS_BACK = 2'd2;
     38 localparam VS_ACTIVE = 2'd3;
     39 
     40 reg [1:0] v_state = VS_FRONT;
     41 reg [1:0] v_state_next;
     42 reg v_sync = 1'b1;
     43 reg v_sync_next;
     44 reg v_active = 1'b0;
     45 reg v_active_next;
     46 reg [9:0] v_count = 10'b0;
     47 reg [9:0] v_count_next;
     48 wire [9:0] v_count_add1;
     49 reg [7:0] v_countdown = VERT_FRONT;
     50 reg [7:0] v_countdown_next;
     51 wire [7:0] v_countdown_sub1;
     52 wire v_countdown_done;
     53 
     54 reg [1:0] h_state = HS_FRONT;
     55 reg [1:0] h_state_next;
     56 reg h_sync = 1'b1;
     57 reg h_sync_next;
     58 reg h_active = 1'b0;
     59 reg h_active_next;
     60 reg [9:0] h_count = 10'b0;
     61 reg [9:0] h_count_next;
     62 wire [9:0] h_count_add1;
     63 reg [7:0] h_countdown = HZNT_FRONT;
     64 reg [7:0] h_countdown_next;
     65 wire [7:0] h_countdown_sub1;
     66 wire h_countdown_done;
     67 
     68 reg new_line = 1'b0;
     69 reg new_frame = 1'b0;
     70 reg new_line_next;
     71 reg new_frame_next;
     72 
     73 assign v_count_add1 = v_count + 9'd1;
     74 assign h_count_add1 = h_count + 9'd1;
     75 
     76 assign { h_countdown_done, h_countdown_sub1 } = { 1'b0, h_countdown } - 9'd1;
     77 assign { v_countdown_done, v_countdown_sub1 } = { 1'b0, v_countdown } - 9'd1;
     78 
     79 // outputs
     80 assign hsync = h_sync;
     81 assign vsync = v_sync;
     82 assign start_frame = new_frame;
     83 assign start_line = new_line & v_active;
     84 assign pxl_accept = h_active & v_active;
     85 assign pxl_x = h_count;
     86 assign pxl_y = v_count;
     87 
     88 always_comb begin
     89 	h_state_next = h_state;
     90 	h_count_next = h_count;
     91 	h_countdown_next = h_countdown;
     92 	h_active_next = h_active;
     93 	h_sync_next = h_sync;
     94 	new_line_next = 1'b0;
     95 
     96 	case (h_state)
     97 	HS_FRONT: begin
     98 		if (h_countdown_done) begin
     99 			h_state_next = HS_SYNC;
    100 			h_countdown_next = HZNT_SYNC;
    101 			h_sync_next = 1'b0;
    102 		end else begin
    103 			h_countdown_next = h_countdown_sub1;
    104 		end
    105 	end
    106 	HS_SYNC: begin
    107 		if (h_countdown_done) begin
    108 			h_state_next = HS_BACK;
    109 			h_countdown_next = HZNT_BACK;
    110 			h_sync_next = 1'b1;
    111 		end else begin
    112 			h_countdown_next = h_countdown_sub1;
    113 		end
    114 	end
    115 	HS_BACK: begin
    116 		if (h_countdown_done) begin
    117 			h_state_next = HS_ACTIVE;
    118 			h_countdown_next = HZNT_FRONT;
    119 			h_active_next = 1'b1;
    120 		end else begin
    121 			h_countdown_next = h_countdown_sub1;
    122 		end
    123 	end
    124 	HS_ACTIVE: begin
    125 		if (h_count == HZNT_ACTIVE) begin
    126 			h_state_next = HS_FRONT;
    127 			h_count_next = 0;
    128 			new_line_next = 1'b1;
    129 			h_active_next = 1'b0;
    130 		end else begin
    131 			h_count_next = h_count_add1;
    132 		end
    133 	end
    134 	endcase	
    135 end
    136 
    137 always_comb begin
    138 	v_state_next = v_state;
    139 	v_count_next = v_count;
    140 	v_countdown_next = v_countdown;
    141 	v_active_next = v_active;
    142 	v_sync_next = v_sync;
    143 	new_frame_next = 1'b0;
    144 
    145 	case (v_state)
    146 	VS_FRONT: begin
    147 		if (v_countdown_done) begin
    148 			v_state_next = VS_SYNC;
    149 			v_countdown_next = VERT_SYNC;
    150 			v_sync_next = 1'b0;
    151 		end else begin
    152 			v_countdown_next = v_countdown_sub1;
    153 		end
    154 	end
    155 	VS_SYNC: begin
    156 		if (v_countdown_done) begin
    157 			v_state_next = VS_BACK;
    158 			v_countdown_next = VERT_BACK;
    159 			v_sync_next = 1'b1;
    160 		end else begin
    161 			v_countdown_next = v_countdown_sub1;
    162 		end
    163 	end
    164 	VS_BACK: begin
    165 		if (v_countdown_done) begin
    166 			v_state_next = VS_ACTIVE;
    167 			v_countdown_next = VERT_FRONT;
    168 			v_active_next = 1'b1;
    169 		end else begin
    170 			v_countdown_next = v_countdown_sub1;
    171 		end
    172 	end
    173 	VS_ACTIVE: begin
    174 		if (v_count == VERT_ACTIVE) begin
    175 			v_state_next = VS_FRONT;
    176 			v_count_next = 0;
    177 			v_active_next = 1'b0;
    178 			new_frame_next = 1'b1;
    179 		end else begin
    180 			v_count_next = v_count_add1;
    181 		end
    182 	end
    183 	endcase	
    184 end
    185 
    186 always_ff @(posedge clk) begin
    187 	h_state <= h_state_next;
    188 	h_sync <= h_sync_next;
    189 	h_count <= h_count_next;
    190 	h_countdown <= h_countdown_next;
    191 	h_active <= h_active_next;
    192 
    193 	new_line <= new_line_next;
    194 	new_frame <= new_frame_next & new_line_next;
    195 
    196 	if (new_line_next) begin
    197 		v_state <= v_state_next;
    198 		v_sync <= v_sync_next;
    199 		v_count <= v_count_next;
    200 		v_countdown <= v_countdown_next;
    201 		v_active <= v_active_next;
    202 	end
    203 end
    204 
    205 endmodule