data/full_repos/permissive/137416811/openfpga_flow/benchmarks/iwls2005/usb_funct/rtl/usbf_pe.v
1: b'%Error: data/full_repos/permissive/137416811/openfpga_flow/benchmarks/iwls2005/usb_funct/rtl/usbf_pe.v:116: Cannot find include file: usbf_defines.v\n`include "usbf_defines.v" \n         ^~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/137416811/openfpga_flow/benchmarks/iwls2005/usb_funct/rtl,data/full_repos/permissive/137416811/usbf_defines.v\n             data/full_repos/permissive/137416811/openfpga_flow/benchmarks/iwls2005/usb_funct/rtl,data/full_repos/permissive/137416811/usbf_defines.v.v\n             data/full_repos/permissive/137416811/openfpga_flow/benchmarks/iwls2005/usb_funct/rtl,data/full_repos/permissive/137416811/usbf_defines.v.sv\n             usbf_defines.v\n             usbf_defines.v.v\n             usbf_defines.v.sv\n             obj_dir/usbf_defines.v\n             obj_dir/usbf_defines.v.v\n             obj_dir/usbf_defines.v.sv\n%Error: data/full_repos/permissive/137416811/openfpga_flow/benchmarks/iwls2005/usb_funct/rtl/usbf_pe.v:756: Define or directive not defined: \'`USBF_RX_ACK_TO_VAL_HS\'\nassign rx_ack_to_val = mode_hs ? `USBF_RX_ACK_TO_VAL_HS : `USBF_RX_ACK_TO_VAL_FS;\n                                 ^~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/137416811/openfpga_flow/benchmarks/iwls2005/usb_funct/rtl/usbf_pe.v:756: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\nassign rx_ack_to_val = mode_hs ? `USBF_RX_ACK_TO_VAL_HS : `USBF_RX_ACK_TO_VAL_FS;\n                                                        ^\n%Error: data/full_repos/permissive/137416811/openfpga_flow/benchmarks/iwls2005/usb_funct/rtl/usbf_pe.v:756: Define or directive not defined: \'`USBF_RX_ACK_TO_VAL_FS\'\nassign rx_ack_to_val = mode_hs ? `USBF_RX_ACK_TO_VAL_HS : `USBF_RX_ACK_TO_VAL_FS;\n                                                          ^~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/137416811/openfpga_flow/benchmarks/iwls2005/usb_funct/rtl/usbf_pe.v:773: Define or directive not defined: \'`USBF_TX_DATA_TO_VAL_HS\'\nassign tx_data_to_val = mode_hs ? `USBF_TX_DATA_TO_VAL_HS : `USBF_TX_DATA_TO_VAL_FS;\n                                  ^~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/137416811/openfpga_flow/benchmarks/iwls2005/usb_funct/rtl/usbf_pe.v:773: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\nassign tx_data_to_val = mode_hs ? `USBF_TX_DATA_TO_VAL_HS : `USBF_TX_DATA_TO_VAL_FS;\n                                                          ^\n%Error: data/full_repos/permissive/137416811/openfpga_flow/benchmarks/iwls2005/usb_funct/rtl/usbf_pe.v:773: Define or directive not defined: \'`USBF_TX_DATA_TO_VAL_FS\'\nassign tx_data_to_val = mode_hs ? `USBF_TX_DATA_TO_VAL_HS : `USBF_TX_DATA_TO_VAL_FS;\n                                                            ^~~~~~~~~~~~~~~~~~~~~~~\n%Error: Exiting due to 7 error(s)\n'
module usbf_pe(	clk, rst,


		tx_valid, rx_active,


		pid_OUT, pid_IN, pid_SOF, pid_SETUP,
		pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA,
		pid_ACK, pid_NACK, pid_STALL, pid_NYET,
		pid_PRE, pid_ERR, pid_SPLIT, pid_PING,


		mode_hs,


		token_valid, crc5_err,


		rx_data_valid, rx_data_done, crc16_err,


		send_token, token_pid_sel,
		data_pid_sel, send_zero_length,


		rx_dma_en, tx_dma_en,
		abort, idma_done,
		adr, size, buf_size,
		sizu_c, dma_en,


		fsel, idin,
		dma_in_buf_sz1, dma_out_buf_avail,
		ep_sel, match, nse_err,
		buf0_rl, buf0_set, buf1_set,
		uc_bsel_set, uc_dpd_set,

		int_buf1_set, int_buf0_set, int_upid_set,
		int_crc16_set, int_to_set, int_seqerr_set,
		out_to_small,

		csr, buf0, buf1

		);

parameter	SSRAM_HADR = 14;

input		clk, rst;
input		tx_valid, rx_active;



input		pid_OUT, pid_IN, pid_SOF, pid_SETUP;
input		pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA;
input		pid_ACK, pid_NACK, pid_STALL, pid_NYET;
input		pid_PRE, pid_ERR, pid_SPLIT, pid_PING;

input		mode_hs;
input		token_valid;
input		crc5_err;

input		rx_data_valid;
input		rx_data_done;
input		crc16_err;


output		send_token;
output	[1:0]	token_pid_sel;
output	[1:0]	data_pid_sel;
output		send_zero_length;


output		rx_dma_en;
output		tx_dma_en;
output		abort;
input		idma_done;
output	[SSRAM_HADR + 2:0]	adr;
output	[13:0]	size;
output	[13:0]	buf_size;
input	[10:0]	sizu_c;
output		dma_en;


input		fsel;
output	[31:0]	idin;
input	[3:0]	ep_sel;
input		match;
output		nse_err;
input		dma_in_buf_sz1, dma_out_buf_avail;

output		buf0_rl;
output		buf0_set;
output		buf1_set;
output		uc_bsel_set;
output		uc_dpd_set;
output		int_buf1_set;
output		int_buf0_set;
output		int_upid_set;
output		int_crc16_set;
output		int_to_set;
output		int_seqerr_set;
output		out_to_small;

input	[31:0]	csr;
input	[31:0]	buf0;
input	[31:0]	buf1;









parameter	ACK   = 0,
		NACK  = 1,
		STALL = 2,
		NYET  = 3;


parameter	[9:0]
		IDLE	= 10'b000000_0001,
		TOKEN	= 10'b000000_0010,
		IN	= 10'b000000_0100,
		IN2	= 10'b000000_1000,
		OUT	= 10'b000001_0000,
		OUT2A	= 10'b000010_0000,
		OUT2B	= 10'b000100_0000,
		UPDATEW	= 10'b001000_0000,
		UPDATE	= 10'b010000_0000,
		UPDATE2	= 10'b100000_0000;

reg	[1:0]	token_pid_sel;
reg	[1:0]	token_pid_sel_d;
reg		send_token;
reg		send_token_d;
reg		rx_dma_en, tx_dma_en;
reg		int_seqerr_set_d;
reg		int_seqerr_set;
reg		int_upid_set;

reg		match_r;


wire		IN_ep, OUT_ep, CTRL_ep;
wire		txfr_iso, txfr_bulk;
wire		ep_disabled, ep_stall;

wire		lrg_ok, sml_ok;
wire	[1:0]	tr_fr;
wire	[10:0]	max_pl_sz;

wire	[1:0]	uc_dpd, uc_bsel;


wire		buf_sel;
reg		buf0_na, buf1_na;
wire	[SSRAM_HADR + 2:0]	buf0_adr, buf1_adr;
wire	[13:0]	buf0_sz, buf1_sz;
reg	[9:0]state, next_state;



reg	[1:0]	next_dpid;
reg	[1:0]	this_dpid;
reg		pid_seq_err;
wire	[1:0]	tr_fr_d;

wire	[13:0]	size_next;
wire		buf_smaller;

reg	[SSRAM_HADR + 2:0]	adr;
reg	[13:0]	new_size;
reg	[13:0]	new_sizeb;
reg		buffer_full;
reg		buffer_empty;
wire	[SSRAM_HADR + 2:0]	new_adr;
reg		buffer_done;

reg		no_bufs0, no_bufs1;
wire		no_bufs;





reg		rx_ack_to_clr;
reg		rx_ack_to_clr_d;
reg		rx_ack_to;
reg	[7:0]	rx_ack_to_cnt;





wire		tx_data_to_clr;
reg		tx_data_to;
reg	[7:0]	tx_data_to_cnt;

wire	[7:0]	rx_ack_to_val, tx_data_to_val;

reg		int_set_en;

wire	[1:0]	next_bsel;
reg		buf_set_d;
reg		uc_stat_set_d;
reg	[31:0]	idin;
reg		buf0_set, buf1_set;
reg		uc_bsel_set;
reg		uc_dpd_set;
reg		buf0_rl_d;
reg		buf0_rl;
wire		no_buf0_dma;
reg		buf0_st_max;
reg		buf1_st_max;

reg	[SSRAM_HADR + 2:0]	adr_r;
reg	[13:0]	size_next_r;

reg		in_token;
reg		out_token;
reg		setup_token;

wire		in_op, out_op;
reg		to_small;
reg		to_large;

reg		buffer_overflow;
reg	[1:0]	allow_pid;

reg		nse_err;
reg		out_to_small, out_to_small_r;
reg		abort;

reg		buf0_not_aloc, buf1_not_aloc;

reg		send_zero_length;







assign IN_ep   = csr[27:26]==2'b01;
assign OUT_ep  = csr[27:26]==2'b10;
assign CTRL_ep = csr[27:26]==2'b00;

assign txfr_iso  = csr[25:24]==2'b01;
assign txfr_bulk = csr[25:24]==2'b10;

assign ep_disabled = csr[23:22]==2'b01;
assign ep_stall    = csr[23:22]==2'b10;

assign lrg_ok = csr[17];
assign sml_ok = csr[16];
assign dma_en = csr[15] & !CTRL_ep;

assign tr_fr = csr[12:11];
assign max_pl_sz = csr[10:0];

assign uc_dpd = csr[29:28];
assign uc_bsel = csr[31:30];


assign buf0_adr = buf0[SSRAM_HADR + 2:0];
assign buf1_adr = buf1[SSRAM_HADR + 2:0];
assign buf0_sz  = buf0[30:17];
assign buf1_sz  = buf1[30:17];


always @(posedge clk)
	buf0_na <= buf0[31] | ( &buf0_adr );

always @(posedge clk)
	buf1_na <= buf1[31] | ( &buf1_adr );


always @(posedge clk)
	buf0_not_aloc <= &buf0_adr;

always @(posedge clk)
	buf1_not_aloc <= &buf1_adr;

always @(posedge clk)
	match_r <= match;


always @(posedge clk)
	nse_err <= token_valid & (pid_OUT | pid_IN | pid_SETUP) & !match;

always @(posedge clk)
	send_token <= send_token_d;

always @(posedge clk)
	token_pid_sel <= token_pid_sel_d;






assign tr_fr_d = mode_hs ? tr_fr : 2'h0;

always @(posedge clk)
	casex({tr_fr_d,csr[27:26],csr[25:24],uc_dpd})
	   8'b0?_01_01_??: next_dpid <= 2'b00;

	   8'b10_01_01_?0: next_dpid <= 2'b01;
	   8'b10_01_01_?1: next_dpid <= 2'b00;

	   8'b11_01_01_00: next_dpid <= 2'b01;
	   8'b11_01_01_01: next_dpid <= 2'b10;
	   8'b11_01_01_10: next_dpid <= 2'b00;

	   8'b0?_10_01_??: next_dpid <= 2'b00;

	   8'b10_10_01_??:
			   begin
				case({pid_MDATA, pid_DATA1})
				  2'b10: next_dpid <= 2'b01;
				  2'b01: next_dpid <= 2'b00;
				endcase
			   end

	   8'b11_10_01_00:
			   begin
				case({pid_MDATA, pid_DATA2})
				  2'b10: next_dpid <= 2'b01;
				  2'b01: next_dpid <= 2'b00;
				endcase
			   end
	   8'b11_10_01_01:
			   begin
				case({pid_MDATA, pid_DATA2})
				  2'b10: next_dpid <= 2'b10;
				  2'b01: next_dpid <= 2'b00;
				endcase
			   end
	   8'b11_10_01_10:
			   begin
				case({pid_MDATA, pid_DATA2})
				  2'b10: next_dpid <= 2'b01;
				  2'b01: next_dpid <= 2'b00;
				endcase
			   end

	   8'b??_01_00_?0,
	   8'b??_10_00_?0: next_dpid <= 2'b01;

	   8'b??_01_00_?1,
	   8'b??_10_00_?1: next_dpid <= 2'b00;

	   8'b??_01_10_?0,
	   8'b??_10_10_?0: next_dpid <= 2'b01;

	   8'b??_01_10_?1,
	   8'b??_10_10_?1: next_dpid <= 2'b00;

	   8'b??_00_??_??:
		casex({setup_token, in_op, out_op, uc_dpd})
		   5'b1_??_??: next_dpid <= 2'b11;
		   5'b0_10_0?: next_dpid <= 2'b11;
		   5'b0_10_1?: next_dpid <= 2'b01;
		   5'b0_01_?0: next_dpid <= 2'b11;
		   5'b0_01_?1: next_dpid <= 2'b10;
		endcase

	endcase




always @(pid_DATA0 or pid_DATA1 or pid_DATA2 or pid_MDATA)
	case({pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA} )
	   4'b1000: allow_pid = 2'b00;
	   4'b0100: allow_pid = 2'b01;
	   4'b0010: allow_pid = 2'b10;
	   4'b0001: allow_pid = 2'b11;
	endcase

always @(posedge clk)
	casex({tr_fr_d,csr[27:26],csr[25:24],uc_dpd})
	   8'b0?_01_01_??: this_dpid <= 2'b00;

	   8'b10_01_01_?0: this_dpid <= 2'b01;
	   8'b10_01_01_?1: this_dpid <= 2'b00;

	   8'b11_01_01_00: this_dpid <= 2'b10;
	   8'b11_01_01_01: this_dpid <= 2'b01;
	   8'b11_01_01_10: this_dpid <= 2'b00;

	   8'b00_10_01_??: this_dpid <= allow_pid;
	   8'b01_10_01_??: this_dpid <= 2'b00;

	   8'b10_10_01_?0: this_dpid <= 2'b11;
	   8'b10_10_01_?1: this_dpid <= 2'b01;

	   8'b11_10_01_00: this_dpid <= 2'b11;
	   8'b11_10_01_01: this_dpid <= 2'b11;
	   8'b11_10_01_10: this_dpid <= 2'b10;

	   8'b??_01_00_?0,
	   8'b??_10_00_?0: this_dpid <= 2'b00;
	   8'b??_01_00_?1,
	   8'b??_10_00_?1: this_dpid <= 2'b01;

	   8'b??_01_10_?0,
	   8'b??_10_10_?0: this_dpid <= 2'b00;
	   8'b??_01_10_?1,
	   8'b??_10_10_?1: this_dpid <= 2'b01;

	   8'b??_00_??_??:
		casex({setup_token,in_op, out_op, uc_dpd})
		   5'b1_??_??: this_dpid <= 2'b00;
		   5'b0_10_0?: this_dpid <= 2'b00;
		   5'b0_10_1?: this_dpid <= 2'b01;
		   5'b0_01_?0: this_dpid <= 2'b00;
		   5'b0_01_?1: this_dpid <= 2'b01;
		endcase
	endcase


assign data_pid_sel = this_dpid;


always @(posedge clk)
	pid_seq_err <= !(	(this_dpid==2'b00 & pid_DATA0) |
				(this_dpid==2'b01 & pid_DATA1) |
				(this_dpid==2'b10 & pid_DATA2) |
				(this_dpid==2'b11 & pid_MDATA)	);











`ifdef USBF_ASYNC_RESET
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
	if(!rst)			in_token <= 1'b0;
	else
	if(pid_IN)			in_token <= 1'b1;
	else
	if(pid_OUT || pid_SETUP)	in_token <= 1'b0;

`ifdef USBF_ASYNC_RESET
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
	if(!rst)			out_token <= 1'b0;
	else
	if(pid_OUT || pid_SETUP)	out_token <= 1'b1;
	else
	if(pid_IN)			out_token <= 1'b0;

`ifdef USBF_ASYNC_RESET
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
	if(!rst)			setup_token <= 1'b0;
	else
	if(pid_SETUP)			setup_token <= 1'b1;
	else
	if(pid_OUT || pid_IN)		setup_token <= 1'b0;


assign	in_op = IN_ep | (CTRL_ep & in_token);


assign	out_op = OUT_ep | (CTRL_ep & out_token);


assign buf_sel =  dma_en ? 1'b0 : CTRL_ep ? in_token : ((uc_bsel[0] | buf0_na) & !buf1_na);


always @(posedge clk)
	adr <= buf_sel ? buf1_adr : buf0_adr;


assign buf_size = buf_sel ? buf1_sz  : buf0_sz;


assign buf_smaller = buf_size < {3'h0, max_pl_sz};



assign size_next = buf_smaller ? buf_size : max_pl_sz;
assign size = size_next;




always @(posedge clk)
	buffer_full <= new_size < {3'h0, max_pl_sz};



always @(posedge clk)
	buffer_empty <= (new_size == 14'h0);


always @(posedge clk)
	buffer_done <= in_op ? buffer_empty : buffer_full;


assign no_buf0_dma = dma_en &
		((IN_ep & !dma_in_buf_sz1) | (OUT_ep & !dma_out_buf_avail));

always @(posedge clk)
	buf0_st_max <= (buf0_sz < {3'h0, max_pl_sz});

always @(posedge clk)
	buf1_st_max <= (buf1_sz < {3'h0, max_pl_sz});

always @(posedge clk)
	no_bufs0 <= buf0_na | no_buf0_dma |
			(buf_sel ? buf0_st_max : (buffer_full & !dma_en));

always @(posedge clk)
	no_bufs1 <= buf1_na | (buf_sel ? buffer_full : buf1_st_max);

assign no_bufs = no_bufs0 & no_bufs1;


always @(posedge clk)
	new_sizeb <= (out_op && dma_en) ? max_pl_sz : (in_op ? size_next : sizu_c);

always @(posedge clk)
	new_size <= buf_size - new_sizeb;



always @(posedge clk)
	adr_r <= adr;

always @(posedge clk)
	size_next_r <= size_next;

assign new_adr = adr_r[SSRAM_HADR + 2:0] +
		((out_op && dma_en) ? {{SSRAM_HADR + 2-10{1'b0}}, max_pl_sz[10:0]} :
		(in_op ? {{SSRAM_HADR + 2-13{1'b0}}, size_next_r[13:0] } :
		{ {SSRAM_HADR + 2-10{1'b0}}, sizu_c[10:0]}));


always @(posedge clk)
	buffer_overflow <= ( {3'h0, sizu_c} > buf_size) & rx_data_valid;



always @(posedge clk)
	out_to_small_r <= uc_stat_set_d & out_op & dma_en & (sizu_c != max_pl_sz);

always @(posedge clk)
	out_to_small <= out_to_small_r;







always @(posedge clk)
	to_small <= !sml_ok & (sizu_c < max_pl_sz);

always @(posedge clk)
	to_large <= !lrg_ok & (sizu_c > max_pl_sz);






assign next_bsel = dma_en ? 2'h0 : buffer_done ? uc_bsel + 2'h1 : uc_bsel;

always @(posedge clk)
	idin[31:17] <= out_to_small_r ? {4'h0,sizu_c} : {buffer_done,new_size};

always @(posedge clk)
	idin[SSRAM_HADR + 2:4] <= out_to_small_r ?	buf0_adr[SSRAM_HADR + 2:4] :
							new_adr[SSRAM_HADR + 2:4];

always @(posedge clk)
	if(buf_set_d)			idin[3:0] <= new_adr[3:0];
	else
	if(out_to_small_r)		idin[3:0] <= buf0_adr[3:0];
	else				idin[3:0] <= {next_dpid, next_bsel};

always @(posedge clk)
	buf0_set <= !buf_sel & buf_set_d;

always @(posedge clk)
	buf1_set <= buf_sel & buf_set_d;

always @(posedge clk)
	uc_bsel_set <= uc_stat_set_d;

always @(posedge clk)
	uc_dpd_set <= uc_stat_set_d;

always @(posedge clk)
	buf0_rl <= buf0_rl_d;


always @(posedge clk)
	abort <= buffer_overflow | (match & (state != IDLE) ) | (match_r & to_large);












always @(posedge clk)
	rx_ack_to_clr <= tx_valid | rx_ack_to_clr_d;

always @(posedge clk)
	if(rx_ack_to_clr)	rx_ack_to_cnt <= 8'h0;
	else			rx_ack_to_cnt <= rx_ack_to_cnt + 8'h1;

always @(posedge clk)
	rx_ack_to <= (rx_ack_to_cnt == rx_ack_to_val);

assign rx_ack_to_val = mode_hs ? `USBF_RX_ACK_TO_VAL_HS : `USBF_RX_ACK_TO_VAL_FS;







assign	tx_data_to_clr = rx_active;

always @(posedge clk)
	if(tx_data_to_clr)	tx_data_to_cnt <= 8'h0;
	else			tx_data_to_cnt <= tx_data_to_cnt + 8'h1;

always @(posedge clk)
	tx_data_to <= (tx_data_to_cnt == tx_data_to_val);

assign tx_data_to_val = mode_hs ? `USBF_TX_DATA_TO_VAL_HS : `USBF_TX_DATA_TO_VAL_FS;





reg	pid_OUT_r, pid_IN_r, pid_PING_r, pid_SETUP_r;

assign int_buf1_set = !buf_sel & buffer_done & int_set_en & !buf1_not_aloc;
assign int_buf0_set =  buf_sel & buffer_done & int_set_en & !buf0_not_aloc;

always @(posedge clk)
	pid_OUT_r <= pid_OUT;

always @(posedge clk)
	pid_IN_r <= pid_IN;

always @(posedge clk)
	pid_PING_r <= pid_PING;

always @(posedge clk)
	pid_SETUP_r <= pid_SETUP;

always @(posedge clk)
	int_upid_set <= match_r & !pid_SOF & (
				( OUT_ep & !(pid_OUT_r | pid_PING_r))		|
				(  IN_ep &  !pid_IN_r)				|
				(CTRL_ep & !(pid_IN_r | pid_OUT_r | pid_PING_r | pid_SETUP_r))
					);

assign int_to_set  = ((state == IN2) & rx_ack_to) | ((state == OUT) & tx_data_to);

assign int_crc16_set = rx_data_done & crc16_err;

always @(posedge clk)
	int_seqerr_set <= int_seqerr_set_d;






`ifdef USBF_ASYNC_RESET
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
	if(!rst)	state <= IDLE;
	else
	if(match)	state <= IDLE;
	else		state <= next_state;

always @(state or ep_stall or buf0_na or buf1_na or
	pid_seq_err or idma_done or token_valid or pid_ACK or rx_data_done or
	tx_data_to or crc16_err or ep_disabled or no_bufs or mode_hs
	or dma_en or rx_ack_to or pid_PING or txfr_iso or to_small or to_large or
	CTRL_ep or pid_IN or pid_OUT or IN_ep or OUT_ep or pid_SETUP or pid_SOF
	or match_r or abort or buffer_done or no_buf0_dma or max_pl_sz)
   begin
	next_state = state;
	token_pid_sel_d = ACK;
	send_token_d = 1'b0;
	rx_dma_en = 1'b0;
	tx_dma_en = 1'b0;
	buf_set_d = 1'b0;
	uc_stat_set_d = 1'b0;
	buf0_rl_d = 1'b0;
	int_set_en = 1'b0;
	rx_ack_to_clr_d = 1'b1;
	int_seqerr_set_d = 1'b0;
	send_zero_length = 1'b0;

	case(state)
	   IDLE:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state IDLE (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(rst && match_r && !ep_disabled && !pid_SOF)
		begin
		if(match_r === 1'bx)	$display("ERROR: IDLE: match_r is unknown. (%t)", $time);
		if(ep_disabled === 1'bx)$display("ERROR: IDLE: ep_disabled is unknown. (%t)", $time);
		if(pid_SOF === 1'bx)	$display("ERROR: IDLE: pid_SOF is unknown. (%t)", $time);
		if(ep_stall === 1'bx)	$display("ERROR: IDLE: ep_stall is unknown. (%t)", $time);
		if(buf0_na === 1'bx)	$display("ERROR: IDLE: buf0_na is unknown. (%t)", $time);
		if(buf1_na === 1'bx)	$display("ERROR: IDLE: buf1_na is unknown. (%t)", $time);
		if(no_buf0_dma === 1'bx)$display("ERROR: IDLE: no_buf0_dma is unknown. (%t)", $time);
		if(CTRL_ep === 1'bx)	$display("ERROR: IDLE: CTRL_ep is unknown. (%t)", $time);
		if(pid_IN === 1'bx)	$display("ERROR: IDLE: pid_IN is unknown. (%t)", $time);
		if(pid_OUT === 1'bx)	$display("ERROR: IDLE: pid_OUT is unknown. (%t)", $time);
		if(pid_SETUP === 1'bx)	$display("ERROR: IDLE: pid_SETUP is unknown. (%t)", $time);
		if(pid_PING === 1'bx)	$display("ERROR: IDLE: pid_PING is unknown. (%t)", $time);
		if(mode_hs === 1'bx)	$display("ERROR: IDLE: mode_hs is unknown. (%t)", $time);
		if(IN_ep === 1'bx)	$display("ERROR: IDLE: IN_ep is unknown. (%t)", $time);
		if(OUT_ep === 1'bx)	$display("ERROR: IDLE: OUT_ep is unknown. (%t)", $time);
		end
`endif


			if(match_r && !ep_disabled && !pid_SOF)
			   begin
				if(ep_stall)
				   begin
					token_pid_sel_d = STALL;
					send_token_d = 1'b1;
					next_state = TOKEN;
				   end
				else
				if(	(buf0_na && buf1_na) || no_buf0_dma ||
					(CTRL_ep && pid_IN   && buf1_na) ||
					(CTRL_ep && pid_OUT  && buf0_na) 
					)
				   begin
					token_pid_sel_d = NACK;
					send_token_d = 1'b1;
					next_state = TOKEN;
				   end
				else
				if(pid_PING && mode_hs)
				   begin
					token_pid_sel_d = ACK;
					send_token_d = 1'b1;
					next_state = TOKEN;
				   end
				else
				if(IN_ep || (CTRL_ep && pid_IN))
				   begin
					if(max_pl_sz == 11'h0)	send_zero_length = 1'b1;
					tx_dma_en = 1'b1;
					next_state = IN;
				   end
				else
				if(OUT_ep || (CTRL_ep && (pid_OUT || pid_SETUP)))
				   begin
					rx_dma_en = 1'b1;
					next_state = OUT;
				   end
			   end
		   end

	   TOKEN:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state TOKEN (%t)", $time);
`endif

			next_state = IDLE;
		   end

	   IN:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state IN (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(idma_done === 1'bx)	$display("ERROR: IN: idma_done is unknown. (%t)", $time);
		if(txfr_iso === 1'bx)	$display("ERROR: IN: txfr_iso is unknown. (%t)", $time);
`endif

			rx_ack_to_clr_d = 1'b0;
			if(idma_done)
			   begin
				if(txfr_iso)	next_state = UPDATE;
				else		next_state = IN2;
			   end

		   end
	   IN2:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state IN2 (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(rx_ack_to === 1'bx)	$display("ERROR: IN2: rx_ack_to is unknown. (%t)", $time);
		if(token_valid === 1'bx)$display("ERROR: IN2: token_valid is unknown. (%t)", $time);
		if(pid_ACK === 1'bx)	$display("ERROR: IN2: pid_ACK is unknown. (%t)", $time);
`endif

			rx_ack_to_clr_d = 1'b0;

			if(rx_ack_to)	next_state = IDLE;
			else
			if(token_valid && pid_ACK)
			   begin
				next_state = UPDATE;
			   end
		   end

	   OUT:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state OUT (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(tx_data_to === 1'bx)	$display("ERROR: OUT: tx_data_to is unknown. (%t)", $time);
		if(crc16_err === 1'bx)	$display("ERROR: OUT: crc16_err is unknown. (%t)", $time);
		if(abort === 1'bx)	$display("ERROR: OUT: abort is unknown. (%t)", $time);
		if(rx_data_done === 1'bx)$display("ERROR: OUT: rx_data_done is unknown. (%t)", $time);
		if(txfr_iso === 1'bx)	$display("ERROR: OUT: txfr_iso is unknown. (%t)", $time);
		if(pid_seq_err === 1'bx)$display("ERROR: OUT: rx_data_done is unknown. (%t)", $time);
`endif

			if(tx_data_to || crc16_err || abort )
				next_state = IDLE;
			else
			if(rx_data_done)
			   begin
				if(txfr_iso)
				   begin
					if(pid_seq_err)		int_seqerr_set_d = 1'b1;
					next_state = UPDATEW;
				   end
				else		next_state = OUT2A;
			   end
		   end

	   OUT2A:
		   begin


`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state OUT2A (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(abort === 1'bx)	$display("ERROR: OUT2A: abort is unknown. (%t)", $time);
`endif

			if(abort)	next_state = IDLE;
			else		next_state = OUT2B;
		   end
	   OUT2B:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state OUT2B (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(abort === 1'bx)	$display("ERROR: OUT2B: abort is unknown. (%t)", $time);
		if(to_small === 1'bx)	$display("ERROR: OUT2B: to_small is unknown. (%t)", $time);
		if(to_large === 1'bx)	$display("ERROR: OUT2B: to_large is unknown. (%t)", $time);
		if(pid_seq_err === 1'bx)$display("ERROR: OUT2B: rx_data_done is unknown. (%t)", $time);
		if(mode_hs === 1'bx)	$display("ERROR: OUT2B: mode_hs is unknown. (%t)", $time);
		if(no_bufs === 1'bx)	$display("ERROR: OUT2B: no_bufs is unknown. (%t)", $time);
`endif

			if(abort)	next_state = IDLE;
			else
			if(to_small || to_large)
			   begin
				token_pid_sel_d = NACK;
				next_state = IDLE;
			   end
			else
			if(pid_seq_err)	
			   begin
				token_pid_sel_d = ACK;
				send_token_d = 1'b1;
				next_state = IDLE;
			   end
			else
			   begin
				if(mode_hs && no_bufs)	token_pid_sel_d = NYET;
				else			token_pid_sel_d = ACK;
				send_token_d = 1'b1;
				next_state = UPDATE;
			   end
		   end

	   UPDATEW:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state UPDATEW (%t)", $time);
`endif

			next_state = UPDATE;
		   end
	   UPDATE:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state UPDATE (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(buffer_done === 1'bx)	$display("ERROR: UPDATE: buffer_done is unknown. (%t)", $time);
		if(dma_en === 1'bx)	$display("ERROR: UPDATE: dma_en is unknown. (%t)", $time);
`endif


			int_set_en = 1'b1;

			if(buffer_done && dma_en)
			   begin
				buf0_rl_d = 1'b1;
			   end
			else
			   begin
				buf_set_d = 1'b1;
			   end
			next_state = UPDATE2;
		   end
	   UPDATE2:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state UPDATE2 (%t)", $time);
`endif


			uc_stat_set_d = 1'b1;
			next_state = IDLE;
		   end
	endcase
   end

endmodule
module usbf_pe(	clk, rst,


		tx_valid, rx_active,


		pid_OUT, pid_IN, pid_SOF, pid_SETUP,
		pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA,
		pid_ACK, pid_NACK, pid_STALL, pid_NYET,
		pid_PRE, pid_ERR, pid_SPLIT, pid_PING,


		mode_hs,


		token_valid, crc5_err,


		rx_data_valid, rx_data_done, crc16_err,


		send_token, token_pid_sel,
		data_pid_sel, send_zero_length,


		rx_dma_en, tx_dma_en,
		abort, idma_done,
		adr, size, buf_size,
		sizu_c, dma_en,


		fsel, idin,
		dma_in_buf_sz1, dma_out_buf_avail,
		ep_sel, match, nse_err,
		buf0_rl, buf0_set, buf1_set,
		uc_bsel_set, uc_dpd_set,

		int_buf1_set, int_buf0_set, int_upid_set,
		int_crc16_set, int_to_set, int_seqerr_set,
		out_to_small,

		csr, buf0, buf1

		);


parameter	SSRAM_HADR = 14;

input		clk, rst;
input		tx_valid, rx_active;



input		pid_OUT, pid_IN, pid_SOF, pid_SETUP;
input		pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA;
input		pid_ACK, pid_NACK, pid_STALL, pid_NYET;
input		pid_PRE, pid_ERR, pid_SPLIT, pid_PING;

input		mode_hs;
input		token_valid;
input		crc5_err;

input		rx_data_valid;
input		rx_data_done;
input		crc16_err;


output		send_token;
output	[1:0]	token_pid_sel;
output	[1:0]	data_pid_sel;
output		send_zero_length;


output		rx_dma_en;
output		tx_dma_en;
output		abort;
input		idma_done;
output	[SSRAM_HADR + 2:0]	adr;
output	[13:0]	size;
output	[13:0]	buf_size;
input	[10:0]	sizu_c;
output		dma_en;


input		fsel;
output	[31:0]	idin;
input	[3:0]	ep_sel;
input		match;
output		nse_err;
input		dma_in_buf_sz1, dma_out_buf_avail;

output		buf0_rl;
output		buf0_set;
output		buf1_set;
output		uc_bsel_set;
output		uc_dpd_set;
output		int_buf1_set;
output		int_buf0_set;
output		int_upid_set;
output		int_crc16_set;
output		int_to_set;
output		int_seqerr_set;
output		out_to_small;

input	[31:0]	csr;
input	[31:0]	buf0;
input	[31:0]	buf1;









parameter	ACK   = 0,
		NACK  = 1,
		STALL = 2,
		NYET  = 3;


parameter	[9:0]
		IDLE	= 10'b000000_0001,
		TOKEN	= 10'b000000_0010,
		IN	= 10'b000000_0100,
		IN2	= 10'b000000_1000,
		OUT	= 10'b000001_0000,
		OUT2A	= 10'b000010_0000,
		OUT2B	= 10'b000100_0000,
		UPDATEW	= 10'b001000_0000,
		UPDATE	= 10'b010000_0000,
		UPDATE2	= 10'b100000_0000;

reg	[1:0]	token_pid_sel;
reg	[1:0]	token_pid_sel_d;
reg		send_token;
reg		send_token_d;
reg		rx_dma_en, tx_dma_en;
reg		int_seqerr_set_d;
reg		int_seqerr_set;
reg		int_upid_set;

reg		match_r;


wire		IN_ep, OUT_ep, CTRL_ep;
wire		txfr_iso, txfr_bulk;
wire		ep_disabled, ep_stall;

wire		lrg_ok, sml_ok;
wire	[1:0]	tr_fr;
wire	[10:0]	max_pl_sz;

wire	[1:0]	uc_dpd, uc_bsel;


wire		buf_sel;
reg		buf0_na, buf1_na;
wire	[SSRAM_HADR + 2:0]	buf0_adr, buf1_adr;
wire	[13:0]	buf0_sz, buf1_sz;
reg	[9:0]state, next_state;



reg	[1:0]	next_dpid;
reg	[1:0]	this_dpid;
reg		pid_seq_err;
wire	[1:0]	tr_fr_d;

wire	[13:0]	size_next;
wire		buf_smaller;

reg	[SSRAM_HADR + 2:0]	adr;
reg	[13:0]	new_size;
reg	[13:0]	new_sizeb;
reg		buffer_full;
reg		buffer_empty;
wire	[SSRAM_HADR + 2:0]	new_adr;
reg		buffer_done;

reg		no_bufs0, no_bufs1;
wire		no_bufs;





reg		rx_ack_to_clr;
reg		rx_ack_to_clr_d;
reg		rx_ack_to;
reg	[7:0]	rx_ack_to_cnt;





wire		tx_data_to_clr;
reg		tx_data_to;
reg	[7:0]	tx_data_to_cnt;

wire	[7:0]	rx_ack_to_val, tx_data_to_val;

reg		int_set_en;

wire	[1:0]	next_bsel;
reg		buf_set_d;
reg		uc_stat_set_d;
reg	[31:0]	idin;
reg		buf0_set, buf1_set;
reg		uc_bsel_set;
reg		uc_dpd_set;
reg		buf0_rl_d;
reg		buf0_rl;
wire		no_buf0_dma;
reg		buf0_st_max;
reg		buf1_st_max;

reg	[SSRAM_HADR + 2:0]	adr_r;
reg	[13:0]	size_next_r;

reg		in_token;
reg		out_token;
reg		setup_token;

wire		in_op, out_op;
reg		to_small;
reg		to_large;

reg		buffer_overflow;
reg	[1:0]	allow_pid;

reg		nse_err;
reg		out_to_small, out_to_small_r;
reg		abort;

reg		buf0_not_aloc, buf1_not_aloc;

reg		send_zero_length;







assign IN_ep   = csr[27:26]==2'b01;
assign OUT_ep  = csr[27:26]==2'b10;
assign CTRL_ep = csr[27:26]==2'b00;

assign txfr_iso  = csr[25:24]==2'b01;
assign txfr_bulk = csr[25:24]==2'b10;

assign ep_disabled = csr[23:22]==2'b01;
assign ep_stall    = csr[23:22]==2'b10;

assign lrg_ok = csr[17];
assign sml_ok = csr[16];
assign dma_en = csr[15] & !CTRL_ep;

assign tr_fr = csr[12:11];
assign max_pl_sz = csr[10:0];

assign uc_dpd = csr[29:28];
assign uc_bsel = csr[31:30];


assign buf0_adr = buf0[SSRAM_HADR + 2:0];
assign buf1_adr = buf1[SSRAM_HADR + 2:0];
assign buf0_sz  = buf0[30:17];
assign buf1_sz  = buf1[30:17];


always @(posedge clk)
	buf0_na <= buf0[31] | ( &buf0_adr );

always @(posedge clk)
	buf1_na <= buf1[31] | ( &buf1_adr );


always @(posedge clk)
	buf0_not_aloc <= &buf0_adr;

always @(posedge clk)
	buf1_not_aloc <= &buf1_adr;

always @(posedge clk)
	match_r <= match;


always @(posedge clk)
	nse_err <= token_valid & (pid_OUT | pid_IN | pid_SETUP) & !match;

always @(posedge clk)
	send_token <= send_token_d;

always @(posedge clk)
	token_pid_sel <= token_pid_sel_d;






assign tr_fr_d = mode_hs ? tr_fr : 2'h0;

always @(posedge clk)
	casex({tr_fr_d,csr[27:26],csr[25:24],uc_dpd})
	   8'b0?_01_01_??: next_dpid <= 2'b00;

	   8'b10_01_01_?0: next_dpid <= 2'b01;
	   8'b10_01_01_?1: next_dpid <= 2'b00;

	   8'b11_01_01_00: next_dpid <= 2'b01;
	   8'b11_01_01_01: next_dpid <= 2'b10;
	   8'b11_01_01_10: next_dpid <= 2'b00;

	   8'b0?_10_01_??: next_dpid <= 2'b00;

	   8'b10_10_01_??:
			   begin
				case({pid_MDATA, pid_DATA1})
				  2'b10: next_dpid <= 2'b01;
				  2'b01: next_dpid <= 2'b00;
				endcase
			   end

	   8'b11_10_01_00:
			   begin
				case({pid_MDATA, pid_DATA2})
				  2'b10: next_dpid <= 2'b01;
				  2'b01: next_dpid <= 2'b00;
				endcase
			   end
	   8'b11_10_01_01:
			   begin
				case({pid_MDATA, pid_DATA2})
				  2'b10: next_dpid <= 2'b10;
				  2'b01: next_dpid <= 2'b00;
				endcase
			   end
	   8'b11_10_01_10:
			   begin
				case({pid_MDATA, pid_DATA2})
				  2'b10: next_dpid <= 2'b01;
				  2'b01: next_dpid <= 2'b00;
				endcase
			   end

	   8'b??_01_00_?0,
	   8'b??_10_00_?0: next_dpid <= 2'b01;

	   8'b??_01_00_?1,
	   8'b??_10_00_?1: next_dpid <= 2'b00;

	   8'b??_01_10_?0,
	   8'b??_10_10_?0: next_dpid <= 2'b01;

	   8'b??_01_10_?1,
	   8'b??_10_10_?1: next_dpid <= 2'b00;

	   8'b??_00_??_??:
		casex({setup_token, in_op, out_op, uc_dpd})
		   5'b1_??_??: next_dpid <= 2'b11;
		   5'b0_10_0?: next_dpid <= 2'b11;
		   5'b0_10_1?: next_dpid <= 2'b01;
		   5'b0_01_?0: next_dpid <= 2'b11;
		   5'b0_01_?1: next_dpid <= 2'b10;
		endcase

	endcase




always @(pid_DATA0 or pid_DATA1 or pid_DATA2 or pid_MDATA)
	case({pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA} )
	   4'b1000: allow_pid = 2'b00;
	   4'b0100: allow_pid = 2'b01;
	   4'b0010: allow_pid = 2'b10;
	   4'b0001: allow_pid = 2'b11;
	endcase

always @(posedge clk)
	casex({tr_fr_d,csr[27:26],csr[25:24],uc_dpd})
	   8'b0?_01_01_??: this_dpid <= 2'b00;

	   8'b10_01_01_?0: this_dpid <= 2'b01;
	   8'b10_01_01_?1: this_dpid <= 2'b00;

	   8'b11_01_01_00: this_dpid <= 2'b10;
	   8'b11_01_01_01: this_dpid <= 2'b01;
	   8'b11_01_01_10: this_dpid <= 2'b00;

	   8'b00_10_01_??: this_dpid <= allow_pid;
	   8'b01_10_01_??: this_dpid <= 2'b00;

	   8'b10_10_01_?0: this_dpid <= 2'b11;
	   8'b10_10_01_?1: this_dpid <= 2'b01;

	   8'b11_10_01_00: this_dpid <= 2'b11;
	   8'b11_10_01_01: this_dpid <= 2'b11;
	   8'b11_10_01_10: this_dpid <= 2'b10;

	   8'b??_01_00_?0,
	   8'b??_10_00_?0: this_dpid <= 2'b00;
	   8'b??_01_00_?1,
	   8'b??_10_00_?1: this_dpid <= 2'b01;

	   8'b??_01_10_?0,
	   8'b??_10_10_?0: this_dpid <= 2'b00;
	   8'b??_01_10_?1,
	   8'b??_10_10_?1: this_dpid <= 2'b01;

	   8'b??_00_??_??:
		casex({setup_token,in_op, out_op, uc_dpd})
		   5'b1_??_??: this_dpid <= 2'b00;
		   5'b0_10_0?: this_dpid <= 2'b00;
		   5'b0_10_1?: this_dpid <= 2'b01;
		   5'b0_01_?0: this_dpid <= 2'b00;
		   5'b0_01_?1: this_dpid <= 2'b01;
		endcase
	endcase


assign data_pid_sel = this_dpid;


always @(posedge clk)
	pid_seq_err <= !(	(this_dpid==2'b00 & pid_DATA0) |
				(this_dpid==2'b01 & pid_DATA1) |
				(this_dpid==2'b10 & pid_DATA2) |
				(this_dpid==2'b11 & pid_MDATA)	);











`ifdef USBF_ASYNC_RESET
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
	if(!rst)			in_token <= 1'b0;
	else
	if(pid_IN)			in_token <= 1'b1;
	else
	if(pid_OUT || pid_SETUP)	in_token <= 1'b0;

`ifdef USBF_ASYNC_RESET
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
	if(!rst)			out_token <= 1'b0;
	else
	if(pid_OUT || pid_SETUP)	out_token <= 1'b1;
	else
	if(pid_IN)			out_token <= 1'b0;

`ifdef USBF_ASYNC_RESET
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
	if(!rst)			setup_token <= 1'b0;
	else
	if(pid_SETUP)			setup_token <= 1'b1;
	else
	if(pid_OUT || pid_IN)		setup_token <= 1'b0;


assign	in_op = IN_ep | (CTRL_ep & in_token);


assign	out_op = OUT_ep | (CTRL_ep & out_token);


assign buf_sel =  dma_en ? 1'b0 : CTRL_ep ? in_token : ((uc_bsel[0] | buf0_na) & !buf1_na);


always @(posedge clk)
	adr <= buf_sel ? buf1_adr : buf0_adr;


assign buf_size = buf_sel ? buf1_sz  : buf0_sz;


assign buf_smaller = buf_size < {3'h0, max_pl_sz};



assign size_next = buf_smaller ? buf_size : max_pl_sz;
assign size = size_next;




always @(posedge clk)
	buffer_full <= new_size < {3'h0, max_pl_sz};



always @(posedge clk)
	buffer_empty <= (new_size == 14'h0);


always @(posedge clk)
	buffer_done <= in_op ? buffer_empty : buffer_full;


assign no_buf0_dma = dma_en &
		((IN_ep & !dma_in_buf_sz1) | (OUT_ep & !dma_out_buf_avail));

always @(posedge clk)
	buf0_st_max <= (buf0_sz < {3'h0, max_pl_sz});

always @(posedge clk)
	buf1_st_max <= (buf1_sz < {3'h0, max_pl_sz});

always @(posedge clk)
	no_bufs0 <= buf0_na | no_buf0_dma |
			(buf_sel ? buf0_st_max : (buffer_full & !dma_en));

always @(posedge clk)
	no_bufs1 <= buf1_na | (buf_sel ? buffer_full : buf1_st_max);

assign no_bufs = no_bufs0 & no_bufs1;


always @(posedge clk)
	new_sizeb <= (out_op && dma_en) ? max_pl_sz : (in_op ? size_next : sizu_c);

always @(posedge clk)
	new_size <= buf_size - new_sizeb;



always @(posedge clk)
	adr_r <= adr;

always @(posedge clk)
	size_next_r <= size_next;

assign new_adr = adr_r[SSRAM_HADR + 2:0] +
		((out_op && dma_en) ? {{SSRAM_HADR + 2-10{1'b0}}, max_pl_sz[10:0]} :
		(in_op ? {{SSRAM_HADR + 2-13{1'b0}}, size_next_r[13:0] } :
		{ {SSRAM_HADR + 2-10{1'b0}}, sizu_c[10:0]}));


always @(posedge clk)
	buffer_overflow <= ( {3'h0, sizu_c} > buf_size) & rx_data_valid;



always @(posedge clk)
	out_to_small_r <= uc_stat_set_d & out_op & dma_en & (sizu_c != max_pl_sz);

always @(posedge clk)
	out_to_small <= out_to_small_r;







always @(posedge clk)
	to_small <= !sml_ok & (sizu_c < max_pl_sz);

always @(posedge clk)
	to_large <= !lrg_ok & (sizu_c > max_pl_sz);






assign next_bsel = dma_en ? 2'h0 : buffer_done ? uc_bsel + 2'h1 : uc_bsel;

always @(posedge clk)
	idin[31:17] <= out_to_small_r ? {4'h0,sizu_c} : {buffer_done,new_size};

always @(posedge clk)
	idin[SSRAM_HADR + 2:4] <= out_to_small_r ?	buf0_adr[SSRAM_HADR + 2:4] :
							new_adr[SSRAM_HADR + 2:4];

always @(posedge clk)
	if(buf_set_d)			idin[3:0] <= new_adr[3:0];
	else
	if(out_to_small_r)		idin[3:0] <= buf0_adr[3:0];
	else				idin[3:0] <= {next_dpid, next_bsel};

always @(posedge clk)
	buf0_set <= !buf_sel & buf_set_d;

always @(posedge clk)
	buf1_set <= buf_sel & buf_set_d;

always @(posedge clk)
	uc_bsel_set <= uc_stat_set_d;

always @(posedge clk)
	uc_dpd_set <= uc_stat_set_d;

always @(posedge clk)
	buf0_rl <= buf0_rl_d;


always @(posedge clk)
	abort <= buffer_overflow | (match & (state != IDLE) ) | (match_r & to_large);












always @(posedge clk)
	rx_ack_to_clr <= tx_valid | rx_ack_to_clr_d;

always @(posedge clk)
	if(rx_ack_to_clr)	rx_ack_to_cnt <= 8'h0;
	else			rx_ack_to_cnt <= rx_ack_to_cnt + 8'h1;

always @(posedge clk)
	rx_ack_to <= (rx_ack_to_cnt == rx_ack_to_val);

assign rx_ack_to_val = mode_hs ? `USBF_RX_ACK_TO_VAL_HS : `USBF_RX_ACK_TO_VAL_FS;







assign	tx_data_to_clr = rx_active;

always @(posedge clk)
	if(tx_data_to_clr)	tx_data_to_cnt <= 8'h0;
	else			tx_data_to_cnt <= tx_data_to_cnt + 8'h1;

always @(posedge clk)
	tx_data_to <= (tx_data_to_cnt == tx_data_to_val);

assign tx_data_to_val = mode_hs ? `USBF_TX_DATA_TO_VAL_HS : `USBF_TX_DATA_TO_VAL_FS;





reg	pid_OUT_r, pid_IN_r, pid_PING_r, pid_SETUP_r;

assign int_buf1_set = !buf_sel & buffer_done & int_set_en & !buf1_not_aloc;
assign int_buf0_set =  buf_sel & buffer_done & int_set_en & !buf0_not_aloc;

always @(posedge clk)
	pid_OUT_r <= pid_OUT;

always @(posedge clk)
	pid_IN_r <= pid_IN;

always @(posedge clk)
	pid_PING_r <= pid_PING;

always @(posedge clk)
	pid_SETUP_r <= pid_SETUP;

always @(posedge clk)
	int_upid_set <= match_r & !pid_SOF & (
				( OUT_ep & !(pid_OUT_r | pid_PING_r))		|
				(  IN_ep &  !pid_IN_r)				|
				(CTRL_ep & !(pid_IN_r | pid_OUT_r | pid_PING_r | pid_SETUP_r))
					);

assign int_to_set  = ((state == IN2) & rx_ack_to) | ((state == OUT) & tx_data_to);

assign int_crc16_set = rx_data_done & crc16_err;

always @(posedge clk)
	int_seqerr_set <= int_seqerr_set_d;






`ifdef USBF_ASYNC_RESET
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
	if(!rst)	state <= IDLE;
	else
	if(match)	state <= IDLE;
	else		state <= next_state;

always @(state or ep_stall or buf0_na or buf1_na or
	pid_seq_err or idma_done or token_valid or pid_ACK or rx_data_done or
	tx_data_to or crc16_err or ep_disabled or no_bufs or mode_hs
	or dma_en or rx_ack_to or pid_PING or txfr_iso or to_small or to_large or
	CTRL_ep or pid_IN or pid_OUT or IN_ep or OUT_ep or pid_SETUP or pid_SOF
	or match_r or abort or buffer_done or no_buf0_dma or max_pl_sz)
   begin
	next_state = state;
	token_pid_sel_d = ACK;
	send_token_d = 1'b0;
	rx_dma_en = 1'b0;
	tx_dma_en = 1'b0;
	buf_set_d = 1'b0;
	uc_stat_set_d = 1'b0;
	buf0_rl_d = 1'b0;
	int_set_en = 1'b0;
	rx_ack_to_clr_d = 1'b1;
	int_seqerr_set_d = 1'b0;
	send_zero_length = 1'b0;

	case(state)
	   IDLE:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state IDLE (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(rst && match_r && !ep_disabled && !pid_SOF)
		begin
		if(match_r === 1'bx)	$display("ERROR: IDLE: match_r is unknown. (%t)", $time);
		if(ep_disabled === 1'bx)$display("ERROR: IDLE: ep_disabled is unknown. (%t)", $time);
		if(pid_SOF === 1'bx)	$display("ERROR: IDLE: pid_SOF is unknown. (%t)", $time);
		if(ep_stall === 1'bx)	$display("ERROR: IDLE: ep_stall is unknown. (%t)", $time);
		if(buf0_na === 1'bx)	$display("ERROR: IDLE: buf0_na is unknown. (%t)", $time);
		if(buf1_na === 1'bx)	$display("ERROR: IDLE: buf1_na is unknown. (%t)", $time);
		if(no_buf0_dma === 1'bx)$display("ERROR: IDLE: no_buf0_dma is unknown. (%t)", $time);
		if(CTRL_ep === 1'bx)	$display("ERROR: IDLE: CTRL_ep is unknown. (%t)", $time);
		if(pid_IN === 1'bx)	$display("ERROR: IDLE: pid_IN is unknown. (%t)", $time);
		if(pid_OUT === 1'bx)	$display("ERROR: IDLE: pid_OUT is unknown. (%t)", $time);
		if(pid_SETUP === 1'bx)	$display("ERROR: IDLE: pid_SETUP is unknown. (%t)", $time);
		if(pid_PING === 1'bx)	$display("ERROR: IDLE: pid_PING is unknown. (%t)", $time);
		if(mode_hs === 1'bx)	$display("ERROR: IDLE: mode_hs is unknown. (%t)", $time);
		if(IN_ep === 1'bx)	$display("ERROR: IDLE: IN_ep is unknown. (%t)", $time);
		if(OUT_ep === 1'bx)	$display("ERROR: IDLE: OUT_ep is unknown. (%t)", $time);
		end
`endif


			if(match_r && !ep_disabled && !pid_SOF)
			   begin
				if(ep_stall)
				   begin
					token_pid_sel_d = STALL;
					send_token_d = 1'b1;
					next_state = TOKEN;
				   end
				else
				if(	(buf0_na && buf1_na) || no_buf0_dma ||
					(CTRL_ep && pid_IN   && buf1_na) ||
					(CTRL_ep && pid_OUT  && buf0_na) 
					)
				   begin
					token_pid_sel_d = NACK;
					send_token_d = 1'b1;
					next_state = TOKEN;
				   end
				else
				if(pid_PING && mode_hs)
				   begin
					token_pid_sel_d = ACK;
					send_token_d = 1'b1;
					next_state = TOKEN;
				   end
				else
				if(IN_ep || (CTRL_ep && pid_IN))
				   begin
					if(max_pl_sz == 11'h0)	send_zero_length = 1'b1;
					tx_dma_en = 1'b1;
					next_state = IN;
				   end
				else
				if(OUT_ep || (CTRL_ep && (pid_OUT || pid_SETUP)))
				   begin
					rx_dma_en = 1'b1;
					next_state = OUT;
				   end
			   end
		   end

	   TOKEN:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state TOKEN (%t)", $time);
`endif

			next_state = IDLE;
		   end

	   IN:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state IN (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(idma_done === 1'bx)	$display("ERROR: IN: idma_done is unknown. (%t)", $time);
		if(txfr_iso === 1'bx)	$display("ERROR: IN: txfr_iso is unknown. (%t)", $time);
`endif

			rx_ack_to_clr_d = 1'b0;
			if(idma_done)
			   begin
				if(txfr_iso)	next_state = UPDATE;
				else		next_state = IN2;
			   end

		   end
	   IN2:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state IN2 (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(rx_ack_to === 1'bx)	$display("ERROR: IN2: rx_ack_to is unknown. (%t)", $time);
		if(token_valid === 1'bx)$display("ERROR: IN2: token_valid is unknown. (%t)", $time);
		if(pid_ACK === 1'bx)	$display("ERROR: IN2: pid_ACK is unknown. (%t)", $time);
`endif

			rx_ack_to_clr_d = 1'b0;

			if(rx_ack_to)	next_state = IDLE;
			else
			if(token_valid && pid_ACK)
			   begin
				next_state = UPDATE;
			   end
		   end

	   OUT:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state OUT (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(tx_data_to === 1'bx)	$display("ERROR: OUT: tx_data_to is unknown. (%t)", $time);
		if(crc16_err === 1'bx)	$display("ERROR: OUT: crc16_err is unknown. (%t)", $time);
		if(abort === 1'bx)	$display("ERROR: OUT: abort is unknown. (%t)", $time);
		if(rx_data_done === 1'bx)$display("ERROR: OUT: rx_data_done is unknown. (%t)", $time);
		if(txfr_iso === 1'bx)	$display("ERROR: OUT: txfr_iso is unknown. (%t)", $time);
		if(pid_seq_err === 1'bx)$display("ERROR: OUT: rx_data_done is unknown. (%t)", $time);
`endif

			if(tx_data_to || crc16_err || abort )
				next_state = IDLE;
			else
			if(rx_data_done)
			   begin
				if(txfr_iso)
				   begin
					if(pid_seq_err)		int_seqerr_set_d = 1'b1;
					next_state = UPDATEW;
				   end
				else		next_state = OUT2A;
			   end
		   end

	   OUT2A:
		   begin


`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state OUT2A (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(abort === 1'bx)	$display("ERROR: OUT2A: abort is unknown. (%t)", $time);
`endif

			if(abort)	next_state = IDLE;
			else		next_state = OUT2B;
		   end
	   OUT2B:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state OUT2B (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(abort === 1'bx)	$display("ERROR: OUT2B: abort is unknown. (%t)", $time);
		if(to_small === 1'bx)	$display("ERROR: OUT2B: to_small is unknown. (%t)", $time);
		if(to_large === 1'bx)	$display("ERROR: OUT2B: to_large is unknown. (%t)", $time);
		if(pid_seq_err === 1'bx)$display("ERROR: OUT2B: rx_data_done is unknown. (%t)", $time);
		if(mode_hs === 1'bx)	$display("ERROR: OUT2B: mode_hs is unknown. (%t)", $time);
		if(no_bufs === 1'bx)	$display("ERROR: OUT2B: no_bufs is unknown. (%t)", $time);
`endif

			if(abort)	next_state = IDLE;
			else
			if(to_small || to_large)
			   begin
				token_pid_sel_d = NACK;
				next_state = IDLE;
			   end
			else
			if(pid_seq_err)	
			   begin
				token_pid_sel_d = ACK;
				send_token_d = 1'b1;
				next_state = IDLE;
			   end
			else
			   begin
				if(mode_hs && no_bufs)	token_pid_sel_d = NYET;
				else			token_pid_sel_d = ACK;
				send_token_d = 1'b1;
				next_state = UPDATE;
			   end
		   end

	   UPDATEW:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state UPDATEW (%t)", $time);
`endif

			next_state = UPDATE;
		   end
	   UPDATE:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state UPDATE (%t)", $time);
`endif
`ifdef USBF_DEBUG
		if(buffer_done === 1'bx)	$display("ERROR: UPDATE: buffer_done is unknown. (%t)", $time);
		if(dma_en === 1'bx)	$display("ERROR: UPDATE: dma_en is unknown. (%t)", $time);
`endif


			int_set_en = 1'b1;

			if(buffer_done && dma_en)
			   begin
				buf0_rl_d = 1'b1;
			   end
			else
			   begin
				buf_set_d = 1'b1;
			   end
			next_state = UPDATE2;
		   end
	   UPDATE2:
		   begin

`ifdef USBF_VERBOSE_DEBUG
		$display("PE: Entered state UPDATE2 (%t)", $time);
`endif


			uc_stat_set_d = 1'b1;
			next_state = IDLE;
		   end
	endcase
   end

endmodule