data/full_repos/permissive/104504209/PGM8755/src/programmer.v
data/verilator_xmls/0420d440-0505-41e4-ae05-8e6c726308a7.xml
module programmer(input clk, rst, mode, en, tx_busy, input [7:0] data_in, output reg tx_block, rdy, 
				  ale, data_latch, ce, rd, output reg[10:0] addr_dat);
				  
	localparam PROGRAM = 2'b01, VERIFY = 2'b10, IDLE = 2'b00;

	reg[1:0] state;
	reg[10:0] address;
	wire delay_rdy;
	wire ale_rdy;
	wire rd_wr_rdy;
	wire prg_end;
	

	reg start, addr_state, tx_state, prg_fall;
	

	delay_cycles #(.WAIT_CYCLES(1000100)) prg_dly(.clk(clk), .rst(rst), .rdy(delay_rdy), .en(start));
	

	delay_cycles #(.WAIT_CYCLES(3)) ale_dly(.clk(clk), .rst(rst), .rdy(ale_rdy), .en(ale));	
	

	delay_cycles #(.WAIT_CYCLES(100)) prg_fall_dly(.clk(clk), .rst(rst), .rdy(prg_end), .en(rd));
	

	always@(posedge clk)begin
		if(rst) begin
			rdy <= 1'b0;
			data_latch <= 1'b1;
			addr_dat <= 11'b0;
			state <= IDLE;
			addr_state <= 1'b0;
			addr_state <= 1'b1;
			address <= 11'hFF0;
			rd <= 1'b1;
			tx_state <= 0;
			prg_fall <= 0;
		end
		else begin

			if(state == IDLE && ~en) begin
				start <= 0;
				rdy <= 0;
				addr_dat <= 11'b0;
				data_latch <= 0;
			end

			else if(state == IDLE && en) state <= (mode) ? PROGRAM:VERIFY;

			else if(state == PROGRAM && en) begin

				if(addr_state) begin
					ce <= 1'b0;
					addr_dat <= address;
					ale <= 1;
					if(ale_rdy) begin
						addr_state <= 1'b0;
						data_latch <= 1'b1;
						ale <= 0;
					end
				end
				else begin
					start <= 1'b1;
					rd <= 1'b1;
					if(~delay_rdy) begin
						ce <= 1'b1;
						addr_dat[7:0] <= data_in;

						data_latch <= 1'b0;
						prg_fall <= 1'b1;
					end
					else begin
						if(prg_end) begin
							addr_state <= 1'b1;
							address <= address - 1'b1;
							start <= 1'b0;
							prg_fall <= 1'b0;
						end
					end
				end
			end

			else if(state == VERIFY && en) begin
				ce <= 1'b0;
				if(~tx_state && ~tx_busy) begin
					rdy <= 1'b0;
					ale <= 1'b1;
					addr_dat <= address;
					tx_state <= 1'b1;
					rd <= 1'b1;
					tx_block <= 1'b1;
				end
				else begin
					tx_block <= 1'b0;
					rd <= 1'b0;
					rdy <= 1'b1;
				end
			end
			else state <= IDLE;
		end
	end

endmodule
module programmer(input clk, rst, mode, en, tx_busy, input [7:0] data_in, output reg tx_block, rdy, 
				  ale, data_latch, ce, rd, output reg[10:0] addr_dat);

				  
	localparam PROGRAM = 2'b01, VERIFY = 2'b10, IDLE = 2'b00;

	reg[1:0] state;
	reg[10:0] address;
	wire delay_rdy;
	wire ale_rdy;
	wire rd_wr_rdy;
	wire prg_end;
	

	reg start, addr_state, tx_state, prg_fall;
	

	delay_cycles #(.WAIT_CYCLES(1000100)) prg_dly(.clk(clk), .rst(rst), .rdy(delay_rdy), .en(start));
	

	delay_cycles #(.WAIT_CYCLES(3)) ale_dly(.clk(clk), .rst(rst), .rdy(ale_rdy), .en(ale));	
	

	delay_cycles #(.WAIT_CYCLES(100)) prg_fall_dly(.clk(clk), .rst(rst), .rdy(prg_end), .en(rd));
	

	always@(posedge clk)begin
		if(rst) begin
			rdy <= 1'b0;
			data_latch <= 1'b1;
			addr_dat <= 11'b0;
			state <= IDLE;
			addr_state <= 1'b0;
			addr_state <= 1'b1;
			address <= 11'hFF0;
			rd <= 1'b1;
			tx_state <= 0;
			prg_fall <= 0;
		end
		else begin

			if(state == IDLE && ~en) begin
				start <= 0;
				rdy <= 0;
				addr_dat <= 11'b0;
				data_latch <= 0;
			end

			else if(state == IDLE && en) state <= (mode) ? PROGRAM:VERIFY;

			else if(state == PROGRAM && en) begin

				if(addr_state) begin
					ce <= 1'b0;
					addr_dat <= address;
					ale <= 1;
					if(ale_rdy) begin
						addr_state <= 1'b0;
						data_latch <= 1'b1;
						ale <= 0;
					end
				end
				else begin
					start <= 1'b1;
					rd <= 1'b1;
					if(~delay_rdy) begin
						ce <= 1'b1;
						addr_dat[7:0] <= data_in;

						data_latch <= 1'b0;
						prg_fall <= 1'b1;
					end
					else begin
						if(prg_end) begin
							addr_state <= 1'b1;
							address <= address - 1'b1;
							start <= 1'b0;
							prg_fall <= 1'b0;
						end
					end
				end
			end

			else if(state == VERIFY && en) begin
				ce <= 1'b0;
				if(~tx_state && ~tx_busy) begin
					rdy <= 1'b0;
					ale <= 1'b1;
					addr_dat <= address;
					tx_state <= 1'b1;
					rd <= 1'b1;
					tx_block <= 1'b1;
				end
				else begin
					tx_block <= 1'b0;
					rd <= 1'b0;
					rdy <= 1'b1;
				end
			end
			else state <= IDLE;
		end
	end

endmodule