data/full_repos/permissive/507203156/01-Fuxi_sift_hw_sim/src/sift/EPP.v
data/verilator_xmls/524797f4-ffee-4a77-96b9-26f5c5f5fd31.xml
module EPP(EPP_Write0, EPP_Data, EPP_Interrupt, EPP_Wait, EPP_DataStrobe0, EPP_Reset0, EPP_AddressStrobe0, 
	write_b, raddr, dout, clk, div_clk, rst, eos_frame, data2ram,waddr,flag_read,read_grad,read_dir,
	read_kp, raddr_kp,kp_addr, raddr_main_dir, main_dir,read_main_dir,read_canny
	);



	input rst;
	input clk;
	input div_clk;




	input EPP_Write0;
	inout [7:0] EPP_Data;
	input EPP_DataStrobe0;
	input EPP_Reset0;
	input EPP_AddressStrobe0;
	output EPP_Interrupt;
	output EPP_Wait;
	

  



	input eos_frame;




	output reg [7:0] data2ram;
	output reg [22:0] waddr;

	output reg write_b ;
	output reg read_grad;
	output reg read_dir;
	output reg read_kp;
	output reg flag_read;
	output reg read_main_dir;

	output reg [22:0] raddr;
	output reg [22:0] raddr_kp;
	output reg [9:0] raddr_main_dir;
	output reg read_canny;
	
	input [7:0] dout;
	input [23:0] kp_addr; 
	input [7:0] main_dir;
	


	reg read_L8;

	reg read_H8;
	
	wire [7:0] tmp1;
	wire [7:0] sent_kp;
	
	assign tmp1=read_L8?kp_addr[7:0]:kp_addr[15:8];
	assign sent_kp=read_H8?kp_addr[23:16]:tmp1;


	reg EPP_Interrupt,EPP_Wait;
	reg EPP_Write,EPP_DataStrobe,EPP_AddressStrobe,EPP_Reset;
	reg [7:0] epp_dataout;



	reg [2:0] epp_state;
	reg [2:0] cmd_state;
	reg needread;
	
   reg [2:0] counter_eos;
	
	parameter DLY_EOS=3'b001;



	parameter EPP_IDLE=3'b000,EPP_WAIT_ADDRREAD=3'b001,EPP_WAIT_ADDRWRITE=3'b010,
		EPP_WAIT_DATAREAD=3'b011,EPP_WAIT_DATAWRITE=3'b100;

	parameter CMD_IDLE=3'b000,CMD_WAIT_EOS_FRAME=3'b001,CMD_PC_READ=3'b010,EOS_WAIT=3'b011;

	parameter  PIC_LENGTH = 512;
	parameter  [22:0] TOTAL_PIXEL = 512 * 512-1;



always @ (posedge clk or negedge rst)
begin
	if(!rst)
	begin
		write_b<=0;
		cmd_state<=CMD_IDLE;
		EPP_Interrupt<=0;


      counter_eos<=DLY_EOS;

	end
	else
		case(cmd_state)
			CMD_IDLE:
			begin

				write_b<=0;
				counter_eos<=DLY_EOS;
				cmd_state<=CMD_IDLE;
				EPP_Interrupt<=0;
				if(!needread)
				begin

					write_b<=0;

						cmd_state<=CMD_WAIT_EOS_FRAME;

				end
				else
				begin


					write_b<=1;
					EPP_Interrupt<=1;
					cmd_state<=CMD_PC_READ;
				end
			end
		
			CMD_WAIT_EOS_FRAME:
			begin

				write_b<=0;


        	   if(eos_frame)
				begin


                                       
					         cmd_state<=EOS_WAIT;
						
				end			
			end
         EOS_WAIT:
			begin
            if(counter_eos[2])
				begin
				    cmd_state<=CMD_IDLE;
					 counter_eos<=DLY_EOS;
				end					
				else
			      		 counter_eos<=counter_eos-1;
			 end
			CMD_PC_READ:
			begin
				write_b<=1;
				cmd_state<=CMD_PC_READ;
				if(!needread)
				begin
					write_b<=0;
					EPP_Interrupt<=0;
					cmd_state<=CMD_IDLE;
				end
			end
			default:
				cmd_state<=CMD_IDLE;
		endcase		
end














always @ (posedge div_clk)
begin
	if (!rst)
		EPP_Reset<=0;
	else
		EPP_Reset<=EPP_Reset0;
end

always @ (posedge div_clk)
begin
	if(!rst)
		EPP_Write<=1;
	else
		EPP_Write<=EPP_Write0;
end

always @ (posedge div_clk)
begin
	if(!rst)
		EPP_DataStrobe<=1;
	else
		EPP_DataStrobe<=EPP_DataStrobe0;
end

always @ (posedge div_clk)
begin
	if(!rst)
		EPP_AddressStrobe<=1;
	else
		EPP_AddressStrobe<=EPP_AddressStrobe0;
end


























always @ (posedge div_clk or negedge rst)
begin
	if(!rst)
	begin
		epp_state <= EPP_IDLE;
		EPP_Wait <= 0;
		epp_dataout <= 0;
		needread <= 0;
		raddr <= 0;
		raddr_kp <=0;
		raddr_main_dir<=0;

		waddr<=0;
		data2ram<=0;

		flag_read<=0;
		read_grad<=0;
		read_dir<=0;
		read_kp<=0;
		read_L8<=0;
		read_H8<=0;
		read_main_dir<=0;
		read_canny<=0;
	end
	else
	begin
		if(!needread)
			raddr<=0;
		if(!flag_read)
			waddr<=0;
		
		case(epp_state)
			EPP_IDLE:
			begin
				EPP_Wait<=0;
				if(!EPP_AddressStrobe)
				begin
					if(EPP_Write)
					begin

						EPP_Wait<=1;
						epp_state<=EPP_WAIT_ADDRREAD;
					end
					else
					begin


				   	needread<=EPP_Data[0];
						flag_read<=(!EPP_Data[0])&EPP_Data[1];
						read_grad<=(EPP_Data==5);
						read_dir<=(EPP_Data==9);
						read_kp<=EPP_Data[4];
						read_L8<=(EPP_Data==21);
						read_H8<=(EPP_Data==25);
						read_main_dir<=(EPP_Data==13);
						read_canny<=(EPP_Data==33);
						EPP_Wait<=1;
						epp_state<=EPP_WAIT_ADDRWRITE;
					end
				end
				else if(!EPP_DataStrobe)
				begin
					if(EPP_Write)
					begin
					


					










						case({read_kp,read_main_dir})
							2'b00:epp_dataout<=dout;
							2'b01:epp_dataout<=main_dir;
							2'b10:epp_dataout<=sent_kp;
							default:epp_dataout<=dout;
						endcase
						
						EPP_Wait<=1;
						epp_state<=EPP_WAIT_DATAREAD;
					end
					else
					begin


						data2ram<=EPP_Data;
						EPP_Wait<=1;
						epp_state<=EPP_WAIT_DATAWRITE;
						if(flag_read)
						begin
						if(waddr< TOTAL_PIXEL)
							waddr<=waddr+1;
						else
							waddr<=0;
						end
					end
				end
			end
			EPP_WAIT_ADDRREAD:
			begin
				if(EPP_AddressStrobe)
				begin
					EPP_Wait<=0;
					epp_state<=EPP_IDLE;
				end
			end
			EPP_WAIT_ADDRWRITE:
			begin
				if(EPP_AddressStrobe)
				begin
					EPP_Wait<=0;
					epp_state<=EPP_IDLE;
				end
			end
			EPP_WAIT_DATAREAD:
			begin
				if(EPP_DataStrobe)
				begin
					EPP_Wait<=0;
					epp_state<=EPP_IDLE;
					if(needread)
					begin
						if(raddr<TOTAL_PIXEL)
							raddr<=raddr+1;
						else
							raddr<=0;
					end
					
					if(needread && read_kp)
					begin
						if(raddr_kp<1023)
							raddr_kp<=raddr_kp+1;
						else
							raddr_kp<=0;
					end


					if(needread && read_main_dir)
					begin
						if(raddr_main_dir<1023)
							raddr_main_dir<=raddr_main_dir+1;
						else
							raddr_main_dir<=0;
					end
					
				end
			end
			EPP_WAIT_DATAWRITE:
			begin
				if(EPP_DataStrobe)
				begin
					EPP_Wait<=0;
					epp_state<=EPP_IDLE;

				end
			end
			default: epp_state<=EPP_IDLE;
		endcase
	end
end

  assign EPP_Data=((epp_state==EPP_WAIT_DATAREAD)||(epp_state==EPP_WAIT_ADDRREAD))?epp_dataout:8'bz;


endmodule
module EPP(EPP_Write0, EPP_Data, EPP_Interrupt, EPP_Wait, EPP_DataStrobe0, EPP_Reset0, EPP_AddressStrobe0, 
	write_b, raddr, dout, clk, div_clk, rst, eos_frame, data2ram,waddr,flag_read,read_grad,read_dir,
	read_kp, raddr_kp,kp_addr, raddr_main_dir, main_dir,read_main_dir,read_canny
	);




	input rst;
	input clk;
	input div_clk;




	input EPP_Write0;
	inout [7:0] EPP_Data;
	input EPP_DataStrobe0;
	input EPP_Reset0;
	input EPP_AddressStrobe0;
	output EPP_Interrupt;
	output EPP_Wait;
	

  



	input eos_frame;




	output reg [7:0] data2ram;
	output reg [22:0] waddr;

	output reg write_b ;
	output reg read_grad;
	output reg read_dir;
	output reg read_kp;
	output reg flag_read;
	output reg read_main_dir;

	output reg [22:0] raddr;
	output reg [22:0] raddr_kp;
	output reg [9:0] raddr_main_dir;
	output reg read_canny;
	
	input [7:0] dout;
	input [23:0] kp_addr; 
	input [7:0] main_dir;
	


	reg read_L8;

	reg read_H8;
	
	wire [7:0] tmp1;
	wire [7:0] sent_kp;
	
	assign tmp1=read_L8?kp_addr[7:0]:kp_addr[15:8];
	assign sent_kp=read_H8?kp_addr[23:16]:tmp1;


	reg EPP_Interrupt,EPP_Wait;
	reg EPP_Write,EPP_DataStrobe,EPP_AddressStrobe,EPP_Reset;
	reg [7:0] epp_dataout;



	reg [2:0] epp_state;
	reg [2:0] cmd_state;
	reg needread;
	
   reg [2:0] counter_eos;
	
	parameter DLY_EOS=3'b001;



	parameter EPP_IDLE=3'b000,EPP_WAIT_ADDRREAD=3'b001,EPP_WAIT_ADDRWRITE=3'b010,
		EPP_WAIT_DATAREAD=3'b011,EPP_WAIT_DATAWRITE=3'b100;

	parameter CMD_IDLE=3'b000,CMD_WAIT_EOS_FRAME=3'b001,CMD_PC_READ=3'b010,EOS_WAIT=3'b011;

	parameter  PIC_LENGTH = 512;
	parameter  [22:0] TOTAL_PIXEL = 512 * 512-1;



always @ (posedge clk or negedge rst)
begin
	if(!rst)
	begin
		write_b<=0;
		cmd_state<=CMD_IDLE;
		EPP_Interrupt<=0;


      counter_eos<=DLY_EOS;

	end
	else
		case(cmd_state)
			CMD_IDLE:
			begin

				write_b<=0;
				counter_eos<=DLY_EOS;
				cmd_state<=CMD_IDLE;
				EPP_Interrupt<=0;
				if(!needread)
				begin

					write_b<=0;

						cmd_state<=CMD_WAIT_EOS_FRAME;

				end
				else
				begin


					write_b<=1;
					EPP_Interrupt<=1;
					cmd_state<=CMD_PC_READ;
				end
			end
		
			CMD_WAIT_EOS_FRAME:
			begin

				write_b<=0;


        	   if(eos_frame)
				begin


                                       
					         cmd_state<=EOS_WAIT;
						
				end			
			end
         EOS_WAIT:
			begin
            if(counter_eos[2])
				begin
				    cmd_state<=CMD_IDLE;
					 counter_eos<=DLY_EOS;
				end					
				else
			      		 counter_eos<=counter_eos-1;
			 end
			CMD_PC_READ:
			begin
				write_b<=1;
				cmd_state<=CMD_PC_READ;
				if(!needread)
				begin
					write_b<=0;
					EPP_Interrupt<=0;
					cmd_state<=CMD_IDLE;
				end
			end
			default:
				cmd_state<=CMD_IDLE;
		endcase		
end














always @ (posedge div_clk)
begin
	if (!rst)
		EPP_Reset<=0;
	else
		EPP_Reset<=EPP_Reset0;
end

always @ (posedge div_clk)
begin
	if(!rst)
		EPP_Write<=1;
	else
		EPP_Write<=EPP_Write0;
end

always @ (posedge div_clk)
begin
	if(!rst)
		EPP_DataStrobe<=1;
	else
		EPP_DataStrobe<=EPP_DataStrobe0;
end

always @ (posedge div_clk)
begin
	if(!rst)
		EPP_AddressStrobe<=1;
	else
		EPP_AddressStrobe<=EPP_AddressStrobe0;
end


























always @ (posedge div_clk or negedge rst)
begin
	if(!rst)
	begin
		epp_state <= EPP_IDLE;
		EPP_Wait <= 0;
		epp_dataout <= 0;
		needread <= 0;
		raddr <= 0;
		raddr_kp <=0;
		raddr_main_dir<=0;

		waddr<=0;
		data2ram<=0;

		flag_read<=0;
		read_grad<=0;
		read_dir<=0;
		read_kp<=0;
		read_L8<=0;
		read_H8<=0;
		read_main_dir<=0;
		read_canny<=0;
	end
	else
	begin
		if(!needread)
			raddr<=0;
		if(!flag_read)
			waddr<=0;
		
		case(epp_state)
			EPP_IDLE:
			begin
				EPP_Wait<=0;
				if(!EPP_AddressStrobe)
				begin
					if(EPP_Write)
					begin

						EPP_Wait<=1;
						epp_state<=EPP_WAIT_ADDRREAD;
					end
					else
					begin


				   	needread<=EPP_Data[0];
						flag_read<=(!EPP_Data[0])&EPP_Data[1];
						read_grad<=(EPP_Data==5);
						read_dir<=(EPP_Data==9);
						read_kp<=EPP_Data[4];
						read_L8<=(EPP_Data==21);
						read_H8<=(EPP_Data==25);
						read_main_dir<=(EPP_Data==13);
						read_canny<=(EPP_Data==33);
						EPP_Wait<=1;
						epp_state<=EPP_WAIT_ADDRWRITE;
					end
				end
				else if(!EPP_DataStrobe)
				begin
					if(EPP_Write)
					begin
					


					










						case({read_kp,read_main_dir})
							2'b00:epp_dataout<=dout;
							2'b01:epp_dataout<=main_dir;
							2'b10:epp_dataout<=sent_kp;
							default:epp_dataout<=dout;
						endcase
						
						EPP_Wait<=1;
						epp_state<=EPP_WAIT_DATAREAD;
					end
					else
					begin


						data2ram<=EPP_Data;
						EPP_Wait<=1;
						epp_state<=EPP_WAIT_DATAWRITE;
						if(flag_read)
						begin
						if(waddr< TOTAL_PIXEL)
							waddr<=waddr+1;
						else
							waddr<=0;
						end
					end
				end
			end
			EPP_WAIT_ADDRREAD:
			begin
				if(EPP_AddressStrobe)
				begin
					EPP_Wait<=0;
					epp_state<=EPP_IDLE;
				end
			end
			EPP_WAIT_ADDRWRITE:
			begin
				if(EPP_AddressStrobe)
				begin
					EPP_Wait<=0;
					epp_state<=EPP_IDLE;
				end
			end
			EPP_WAIT_DATAREAD:
			begin
				if(EPP_DataStrobe)
				begin
					EPP_Wait<=0;
					epp_state<=EPP_IDLE;
					if(needread)
					begin
						if(raddr<TOTAL_PIXEL)
							raddr<=raddr+1;
						else
							raddr<=0;
					end
					
					if(needread && read_kp)
					begin
						if(raddr_kp<1023)
							raddr_kp<=raddr_kp+1;
						else
							raddr_kp<=0;
					end


					if(needread && read_main_dir)
					begin
						if(raddr_main_dir<1023)
							raddr_main_dir<=raddr_main_dir+1;
						else
							raddr_main_dir<=0;
					end
					
				end
			end
			EPP_WAIT_DATAWRITE:
			begin
				if(EPP_DataStrobe)
				begin
					EPP_Wait<=0;
					epp_state<=EPP_IDLE;

				end
			end
			default: epp_state<=EPP_IDLE;
		endcase
	end
end

  assign EPP_Data=((epp_state==EPP_WAIT_DATAREAD)||(epp_state==EPP_WAIT_ADDRREAD))?epp_dataout:8'bz;


endmodule