module IS42VM16400K_Cmd(
	input clk,
	input rst_n,
	input FV,
	input LV,
	output reg WR_EN,
	output RD_EN,
	output Prech_EN,
	output Active_EN,
	output [11:0] Row_Addr,
	input  init_done,
	output RD_FIFO_n,
	output Frame_V
  );

//parameter ODD=0;
//parameter EVEN=1;
reg [15:0] pixel_cnt, pixel_cnt_1;
reg [11:0] rd_row_addr, wr_row_addr;
wire w_clk;
assign w_clk=clk;
reg [1:0] line_cnt, line_cnt_1;
reg q_lv, q_fv, frame_v;
reg q_wr_en, q_wr_en_1, q_rd_en;
reg [7:0] q_wr_setup_cnt, q_rd_setup_cnt;
reg [4:0] q_idle_cnt; 
reg q_rd_fifo_n, q_rd_fifo_n_1;

always@(posedge clk or negedge rst_n) begin
   if(!rst_n) begin
   		frame_v <= 0;
		line_cnt			<=	0;
		line_cnt_1			<=	0;
		q_lv				<=  0;
		q_fv				<=  0;
		pixel_cnt			<=  0;
		pixel_cnt_1			<=  0;
		wr_row_addr		<=  0;
		rd_row_addr		<=  0;
		q_wr_en			<=  0;
		q_wr_en_1		<=  0;
		WR_EN			<=  0;
		q_rd_en			<=  0;		
		q_wr_setup_cnt	<=  0;
		q_rd_setup_cnt	<=  0;
		q_idle_cnt		<=  0;
		q_rd_fifo_n		<=  0;
		q_rd_fifo_n_1	<=  0;
   end
   else begin 
		//clk_cnt			<= init_done							?	clk_cnt + 1'b1 : 0;
		if(init_done && FV && !q_fv)
			frame_v <= 1;
		else if(init_done && !FV && q_fv)
			frame_v <= 0;
		else
			frame_v <= frame_v;	
		line_cnt		<= (frame_v)			?   (!LV && (q_wr_en_1 && !q_wr_en && q_wr_setup_cnt==0 || !RD_EN && q_rd_en && q_rd_setup_cnt==0))	?	line_cnt+1	: line_cnt	: 0;
		line_cnt_1		<= line_cnt;
		q_lv			<= LV;
		q_fv			<= FV;
		pixel_cnt		<= (frame_v)			?	((LV || !LV && (q_wr_setup_cnt!=0 || q_rd_setup_cnt!=0)) && ((pixel_cnt!=134 && line_cnt<2) || (pixel_cnt!=262 && line_cnt>=2)))	?	pixel_cnt+1	:	0	:	0;
		pixel_cnt_1		<= pixel_cnt;
		wr_row_addr	<=  frame_v	?	(pixel_cnt==255 && line_cnt>=2)	?	wr_row_addr+1	:	wr_row_addr	:	0;
		rd_row_addr	<=  frame_v	?	(pixel_cnt==127 && line_cnt<2)	?	rd_row_addr+1	:	rd_row_addr	:	0;
		q_wr_en		<=  n_wr_en;
		q_wr_en_1	<=  q_wr_en;
		WR_EN		<=  q_wr_en_1;
		q_rd_en		<=  RD_EN;
		q_wr_setup_cnt <=	//(LV && !q_lv && WR_EN)				? 3					 :
							(row_setup && line_cnt>=2 && LV)	? q_wr_setup_cnt + 1 : 
							(q_wr_setup_cnt!=0 && !LV)			? q_wr_setup_cnt - 1 : q_wr_setup_cnt;
		q_rd_setup_cnt <=	(row_setup && line_cnt<2 && LV)	? q_rd_setup_cnt + 1 : 
							(q_rd_setup_cnt!=0 && !LV)			? q_rd_setup_cnt - 1 : q_rd_setup_cnt;
		q_idle_cnt		<=  (q_wr_en || RD_EN || !init_done)	? 0	:
							(q_idle_cnt<=13)	? q_idle_cnt+1	: q_idle_cnt;		
		q_rd_fifo_n		<=  row_setup;
		q_rd_fifo_n_1	<=  q_rd_fifo_n;
   end    
end

	 assign			n_wr_en =	frame_v		?	(!LV && q_wr_setup_cnt!=0 || LV && line_cnt>=2  && !row_setup && frame_v ) ? 1:0	:	0;
	 assign			RD_EN  =	frame_v		?	(!LV && q_rd_setup_cnt!=0 || LV && line_cnt<2   && !row_setup && frame_v ) ? 1:0	:	0;
	 

	 //last column pixel_cnt=127; must precharge and activate next row
	assign	row_setup = frame_v		?	
						(line_cnt<2) ? (pixel_cnt>=128&&pixel_cnt<=134) :
						(line_cnt>=2)  ? (pixel_cnt>=256&&pixel_cnt<=262) : 0	: 0;
	
	assign	Prech_EN  =  (q_idle_cnt==10)  ?	1	:
						(line_cnt<2 && frame_v)   ? (pixel_cnt_1==128) :
						(line_cnt>=2 && frame_v)   ? (pixel_cnt_1==259) : 0;
	
	assign  Active_EN = (q_idle_cnt==13)  ?	1	:
						(line_cnt<2  && frame_v)  ? (pixel_cnt==131) :
						(line_cnt>=2 && frame_v)   ? (pixel_cnt==262) : 0;
						
	
	assign  Row_Addr  = line_cnt<2		? rd_row_addr : wr_row_addr;
	
	assign RD_FIFO_n = q_rd_fifo_n_1;
	
	assign Frame_V = frame_v;
	
	
endmodule