module sys_sync_gen (
// clock reset
input wire sys_clk ,
input wire rstb ,
// sync , de
output reg hsync ,
output reg vsync ,
output reg de
);
// parameter define
localparam HS_IDLE = 2'd0 ;
localparam HS_BP = 2'd1 ;
localparam HS_ACTV = 2'd2 ;
localparam HS_FP = 2'd3 ;
localparam VS_IDLE = 2'd0 ;
localparam VS_BP = 2'd1 ;
localparam VS_ACTV = 2'd2 ;
localparam VS_FP = 2'd3 ;
localparam HBP = 183 ;
localparam HFP = 16 ;
localparam VBP = 18 ;
localparam VFP = 1 ;
localparam V_TOTAL = 500 ;
localparam H_TOTAL = 840 ;
// internal register
reg [1:0] h_cst;
reg [1:0] h_nst;
reg [1:0] v_cst;
reg [1:0] v_nst;
reg [9:0] count;
reg [9:0] h_cnt;
reg [8:0] v_cnt;
reg h_de ;
reg v_de ;
//internal wire
wire hsync_str = ((h_cst == HS_IDLE) && (count == 0 ));
wire hs_ac_str = ((h_cst == HS_BP ) && (count == HBP));
wire hs_fp_str = ((h_cst == HS_ACTV) && (count == 640));
wire hs_bp_str = ((h_cst == HS_FP ) && (count == HFP));
wire vsync_str = ((h_cnt == V_TOTAL) && hs_bp_str);
wire vs_ac_str = ((v_nst == VS_BP ) && (h_cnt == VBP));
wire vs_fp_str = ((v_nst == VS_ACTV) && (h_cnt == 480));
wire vs_bp_str = ((v_nst == VS_FP ) && (h_cnt == VFP));
wire h_cnt_clr = vsync_str;
// state transfer
always@(posedge sys_clk, negedge rstb) begin
if(!rstb) begin
h_cst <= HS_IDLE;
v_cst <= VS_IDLE;
end
else begin
h_cst <= h_nst;
v_cst <= v_nst;
end
end
// hsync next state logic
always@(*) begin
h_nst = h_cst;
case(h_cst)
HS_IDLE : h_nst = (hsync_str) ? HS_BP : HS_IDLE;
HS_BP : h_nst = (hs_ac_str) ? HS_ACTV : HS_BP ;
HS_ACTV : h_nst = (hs_fp_str) ? HS_FP : HS_ACTV;
HS_FP : h_nst = (hs_bp_str) ? HS_BP : HS_FP ;
default : h_nst = HS_IDLE;
endcase
end
// counter logic
always@(posedge sys_clk, negedge rstb) begin
if(!rstb)
count <= 0;
else
case(h_cst)
HS_IDLE : count = (hsync_str) ? 0 : count + 1;
HS_BP : count = (hs_ac_str) ? 0 : count + 1;
HS_ACTV : count = (hs_fp_str) ? 0 : count + 1;
HS_FP : count = (hs_bp_str) ? 0 : count + 1;
default : count = 9'bx;
endcase
end
// hsync output
always@(posedge sys_clk, negedge rstb) begin
if(!rstb)
hsync <= 1;
else if(hsync_str)
hsync <= 0;
else if(hs_bp_str)
hsync <= 0;
else
hsync <= 1;
end
// hsync counter
always@(posedge sys_clk, negedge rstb) begin
if(!rstb)
h_cnt <= 0;
else if(hsync_str)
h_cnt <= 1;
else if(h_cnt_clr)
h_cnt <= 1;
else if(hs_bp_str)
h_cnt <= h_cnt + 1;
else
h_cnt <= h_cnt;
end
// vsync next state logic
always@(*) begin
v_nst = v_cst;
case(v_cst)
VS_IDLE : v_nst = (vsync_str) ? VS_BP : VS_IDLE;
VS_BP : v_nst = (vs_ac_str) ? VS_ACTV : VS_BP ;
VS_ACTV : v_nst = (vs_fp_str) ? VS_FP : VS_ACTV;
VS_FP : v_nst = (vs_bp_str) ? VS_BP : VS_FP ;
default : v_nst = VS_IDLE;
endcase
end
// vsync output
always@(posedge sys_clk, negedge rstb) begin
if(!rstb)
vsync <= 1;
else if(vsync_str)
vsync <= 0;
else
vsync <= 1;
end
// hsync data enable
always@(*) begin
case(h_cst)
HS_IDLE : h_de = 0;
HS_BP : h_de = 0;
HS_ACTV : h_de = 1;
HS_FP : h_de = 0;
default : h_de = 0;
endcase
end
// vsync data enable
always@(*) begin
case(v_cst)
VS_IDLE : v_de = 0;
VS_BP : v_de = 0;
VS_ACTV : v_de = 1;
VS_FP : v_de = 0;
default : v_de = 0;
endcase
end
assign de = h_de & v_de;
endmodule