⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbf_pe.v

📁 USB2.0 chip的一部分verilog源码。opencore上下的
💻 V
📖 第 1 页 / 共 2 页
字号:
// Size from Bufferassign buf_size = buf_sel ? buf1_sz  : buf0_sz;// Determine which is smaller: buffer or max_pl_szassign buf_smaller = buf_size < {3'h0, max_pl_sz};// Determine actual size for this transfer (for IDMA) IN endpoint only// (OUT endpoint uses sizeu_c from IDMA)assign size_next = buf_smaller ? buf_size : max_pl_sz;assign size = size_next;	// "size" is an output for IDMA// Buffer Full (only for OUT endpoints)// Indicates that there is not enough space in the buffer for one// more max_pl_sz packetalways @(posedge clk)	buffer_full <= new_size < {3'h0, max_pl_sz};// Buffer Empty (only for IN endpoints)// Indicates that there are zero bytes left in the bufferalways @(posedge clk)	buffer_empty <= (new_size == 14'h0);// Joint buffer full/empty flag This is the "USED" flagalways @(posedge clk)	buffer_done <= in_op ? buffer_empty : buffer_full;// No More buffer space at all (For high speed out - issue NYET)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;// New Size (to be written to register file)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;// New Buffer Address (to be written to register file)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]}));// Buffer Overflowalways @(posedge clk)	buffer_overflow <= ( {3'h0, sizu_c} > buf_size) & rx_data_valid;// OUT packet smaller than MAX_PL_SZ in DMA operationalways @(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;/////////////////////////////////////////////////////////////////////// Determine if packet is to small or to large// This is used to NACK and ignore packet for OUT endpoints//always @(posedge clk)	to_small <= !sml_ok & (sizu_c < max_pl_sz);always @(posedge clk)	to_large <= !lrg_ok & (sizu_c > max_pl_sz);/////////////////////////////////////////////////////////////////////// Register File Update Logic//assign next_bsel = dma_en ? 2'h0 : buffer_done ? uc_bsel + 2'h1 : uc_bsel;	// FIX_MEalways @(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;// Abort signalalways @(posedge clk)	abort <= buffer_overflow | (match & (state != IDLE) ) | (match_r & to_large);/////////////////////////////////////////////////////////////////////// TIME OUT TIMERS//// After sending Data in response to an IN token from host, the// host must reply with an ack. The host has 622nS in Full Speed// mode and 400nS in High Speed mode to reply.// "rx_ack_to" indicates when this time has expired.// rx_ack_to_clr, clears the timeralways @(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;// After sending a OUT token the host must send a data packet.// The host has 622nS in Full Speed mode and 400nS in High Speed// mode to send the data packet.// "tx_data_to" indicates when this time has expired.// "tx_data_to_clr" clears the timerassign	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;/////////////////////////////////////////////////////////////////////// Interrupts//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;/////////////////////////////////////////////////////////////////////// Main Protocol State Machine//`ifdef USBF_ASYNC_RESETalways @(posedge clk or negedge rst)`elsealways @(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)	// synopsys full_case parallel_case	   IDLE:		   begin// synopsys translate_off`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// synopsys translate_on			if(match_r && !ep_disabled && !pid_SOF)			   begin				if(ep_stall)		// Halt Forced send 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		// No buffers send NAK					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// synopsys translate_off`ifdef USBF_VERBOSE_DEBUG		$display("PE: Entered state TOKEN (%t)", $time);`endif// synopsys translate_on			next_state = IDLE;		   end	   IN:		   begin// synopsys translate_off`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// synopsys translate_on			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// synopsys translate_off`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// synopsys translate_on			rx_ack_to_clr_d = 1'b0;			// Wait for ACK from HOST or Timeout			if(rx_ack_to)	next_state = IDLE;			else			if(token_valid && pid_ACK)			   begin				next_state = UPDATE;			   end		   end	   OUT:		   begin// synopsys translate_off`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// synopsys translate_on			if(tx_data_to || crc16_err || abort )				next_state = IDLE;			else			if(rx_data_done)			   begin		// Send Ack				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	// This is a delay State to NACK to small or to				// large packets. this state could be skipped// synopsys translate_off`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// synopsys translate_on			if(abort)	next_state = IDLE;			else		next_state = OUT2B;		   end	   OUT2B:		   begin	// Send ACK/NACK/NYET// synopsys translate_off`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// synopsys translate_on			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// synopsys translate_off`ifdef USBF_VERBOSE_DEBUG		$display("PE: Entered state UPDATEW (%t)", $time);`endif// synopsys translate_on			next_state = UPDATE;		   end	   UPDATE:		   begin// synopsys translate_off`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// synopsys translate_on			// Interrupts			int_set_en = 1'b1;			// Buffer (used, size, adr) set or reload			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:	// Update Register File & state		   begin// synopsys translate_off`ifdef USBF_VERBOSE_DEBUG		$display("PE: Entered state UPDATE2 (%t)", $time);`endif// synopsys translate_on			// pid sequence & buffer usage			uc_stat_set_d = 1'b1;			next_state = IDLE;		   end	endcase   endendmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -