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

📄 usbf_pe.v

📁 USB2.0 chip的一部分verilog源码。opencore上下的
💻 V
📖 第 1 页 / 共 2 页
字号:
`include "usbf_defines.v"module usbf_pe(	clk, rst,		// UTMI Interfaces		tx_valid, rx_active,		// PID Information		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,		// Speed Mode		mode_hs,		// Token Information		token_valid, crc5_err,		// Receive Data Output		rx_data_valid, rx_data_done, crc16_err,		// Packet Assembler Interface		send_token, token_pid_sel,		data_pid_sel, send_zero_length,		// IDMA Interface		rx_dma_en, tx_dma_en,		abort, idma_done,		adr, size, buf_size,		sizu_c, dma_en,		// Register File Interface		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;// Packet Disassembler Interface		// Decoded PIDs (used when token_valid is asserted)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;		// Token is validinput		crc5_err;		// Token crc5 errorinput		rx_data_valid;		// Data on rx_data_st is validinput		rx_data_done;		// Indicates end of a transferinput		crc16_err;		// Data packet CRC 16 error// Packet Assembler Interfaceoutput		send_token;output	[1:0]	token_pid_sel;output	[1:0]	data_pid_sel;output		send_zero_length;// IDMA Interfaceoutput		rx_dma_en;	// Allows the data to be storedoutput		tx_dma_en;	// Allows for data to be retrievedoutput		abort;		// Abort Transfer (time_out, crc_err or rx_error)input		idma_done;	// DMA is done indicatoroutput	[SSRAM_HADR + 2:0]	adr;		// Byte Addressoutput	[13:0]	size;		// Size in bytesoutput	[13:0]	buf_size;	// Actual buffer sizeinput	[10:0]	sizu_c;		// Up and Down counting size registers, used to updateoutput		dma_en;		// USB external DMA mode enabled// Register File interfaceinput		fsel;		// This function is selectedoutput	[31:0]	idin;		// Data Outputinput	[3:0]	ep_sel;		// Endpoint Number Inputinput		match;		// Endpoint Matchedoutput		nse_err;	// no such endpoint errorinput		dma_in_buf_sz1, dma_out_buf_avail;output		buf0_rl;	// Reload Buf 0 with original valuesoutput		buf0_set;	// Write to buf 0output		buf1_set;	// Write to buf 1output		uc_bsel_set;	// Write to the uc_bsel fieldoutput		uc_dpd_set;	// Write to the uc_dpd fieldoutput		int_buf1_set;	// Set buf1 full/empty interruptoutput		int_buf0_set;	// Set buf0 full/empty interruptoutput		int_upid_set;	// Set unsupported PID interruptoutput		int_crc16_set;	// Set CRC16 error interruptoutput		int_to_set;	// Set time out interruptoutput		int_seqerr_set;	// Set PID sequence error interruptoutput		out_to_small;	// OUT packet was to small for DMA operationinput	[31:0]	csr;		// Internal CSR Outputinput	[31:0]	buf0;		// Internal Buf 0 Outputinput	[31:0]	buf1;		// Internal Buf 1 Output/////////////////////////////////////////////////////////////////////// Local Wires and Registers//// tx token decodingparameter	ACK   = 0,		NACK  = 1,		STALL = 2,		NYET  = 3;// State decodingparameter	[9:0]	// synopsys enum state		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;// Endpoint Decodingwire		IN_ep, OUT_ep, CTRL_ep;		// Endpoint Typeswire		txfr_iso, txfr_bulk;		// Transfer Typeswire		ep_disabled, ep_stall;		// Endpoint forced conditionswire		lrg_ok, sml_ok;		// Packet size acceptancewire	[1:0]	tr_fr;			// Number of transfers per micro-framewire	[10:0]	max_pl_sz;		// Max payload sizewire	[1:0]	uc_dpd, uc_bsel;// Buffer checkswire		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]	/* synopsys enum state */ state, next_state;// synopsys state_vector state// PID next and current decodersreg	[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;// After sending Data in response to an IN token from host, the// host must reply with an ack. The host has XXXnS to reply.// "rx_ack_to" indicates when this time has expired.// rx_ack_to_clr, clears the timerreg		rx_ack_to_clr;reg		rx_ack_to_clr_d;reg		rx_ack_to;reg	[7:0]	rx_ack_to_cnt;// After sending a OUT token the host must send a data packet.// The host has XX nS to send the packet. "tx_data_to" indicates// when this time has expired.// tx_data_to_clr, clears the timerwire		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;	// Indicate a IN or OUT operationreg		to_small;	// Indicates a "to small packer" errorreg		to_large;	// Indicates a "to large packer" errorreg		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;/////////////////////////////////////////////////////////////////////// Misc Logic//// Endpoint/CSR Decodingassign 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];// Buffer decoding and allocation checksassign 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];// Buffers Not Availablealways @(posedge clk)	buf0_na <= buf0[31] | ( &buf0_adr );always @(posedge clk)	buf1_na <= buf1[31] | ( &buf1_adr );// Buffer Not Allocatedalways @(posedge clk)	buf0_not_aloc <= &buf0_adr;always @(posedge clk)	buf1_not_aloc <= &buf1_adr;always @(posedge clk)	match_r <= match;// No Such Endpoint Indicatoralways @(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;/////////////////////////////////////////////////////////////////////// Data Pid Sequencer//assign tr_fr_d = mode_hs ? tr_fr : 2'h0;always @(posedge clk)	// tr/mf:ep/type:tr/type:last dpd	casex({tr_fr_d,csr[27:26],csr[25:24],uc_dpd})	// synopsys full_case parallel_case	   8'b0?_01_01_??: next_dpid <= 2'b00;	// ISO txfr. IN, 1 tr/mf	   8'b10_01_01_?0: next_dpid <= 2'b01;	// ISO txfr. IN, 2 tr/mf	   8'b10_01_01_?1: next_dpid <= 2'b00;	// ISO txfr. IN, 2 tr/mf	   8'b11_01_01_00: next_dpid <= 2'b01;	// ISO txfr. IN, 3 tr/mf	   8'b11_01_01_01: next_dpid <= 2'b10;	// ISO txfr. IN, 3 tr/mf	   8'b11_01_01_10: next_dpid <= 2'b00;	// ISO txfr. IN, 3 tr/mf	   8'b0?_10_01_??: next_dpid <= 2'b00;	// ISO txfr. OUT, 1 tr/mf	   8'b10_10_01_??: 				// ISO txfr. OUT, 2 tr/mf			   begin	// Resynchronize in case of PID error				case({pid_MDATA, pid_DATA1})	// synopsys full_case parallel_case				  2'b10: next_dpid <= 2'b01;				  2'b01: next_dpid <= 2'b00;				endcase			   end	   8'b11_10_01_00: 				// ISO txfr. OUT, 3 tr/mf			   begin	// Resynchronize in case of PID error				case({pid_MDATA, pid_DATA2})	// synopsys full_case parallel_case				  2'b10: next_dpid <= 2'b01;				  2'b01: next_dpid <= 2'b00;				endcase			   end	   8'b11_10_01_01: 				// ISO txfr. OUT, 3 tr/mf			   begin	// Resynchronize in case of PID error				case({pid_MDATA, pid_DATA2})	// synopsys full_case parallel_case				  2'b10: next_dpid <= 2'b10;				  2'b01: next_dpid <= 2'b00;				endcase			   end	   8'b11_10_01_10: 				// ISO txfr. OUT, 3 tr/mf			   begin	// Resynchronize in case of PID error				case({pid_MDATA, pid_DATA2})	// synopsys full_case parallel_case				  2'b10: next_dpid <= 2'b01;				  2'b01: next_dpid <= 2'b00;				endcase			   end	   8'b??_01_00_?0,				// IN/OUT endpoint only	   8'b??_10_00_?0: next_dpid <= 2'b01;	// INT transfers	   8'b??_01_00_?1,				// IN/OUT endpoint only	   8'b??_10_00_?1: next_dpid <= 2'b00;	// INT transfers	   8'b??_01_10_?0,				// IN/OUT endpoint only	   8'b??_10_10_?0: next_dpid <= 2'b01;	// BULK transfers	   8'b??_01_10_?1,				// IN/OUT endpoint only	   8'b??_10_10_?1: next_dpid <= 2'b00;	// BULK transfers	   8'b??_00_??_??:				// CTRL Endpoint		casex({setup_token, in_op, out_op, uc_dpd})	// synopsys full_case parallel_case		   5'b1_??_??: next_dpid <= 2'b11;	// SETUP operation		   5'b0_10_0?: next_dpid <= 2'b11;	// IN operation		   5'b0_10_1?: next_dpid <= 2'b01;	// IN operation		   5'b0_01_?0: next_dpid <= 2'b11;	// OUT operation		   5'b0_01_?1: next_dpid <= 2'b10;	// OUT operation		endcase	endcase// Current PID decoder// Allow any PID for ISO. transfers when mode full speed or tr_fr is zeroalways @(pid_DATA0 or pid_DATA1 or pid_DATA2 or pid_MDATA)	case({pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA} ) // synopsys full_case parallel_case	   4'b1000: allow_pid = 2'b00;	   4'b0100: allow_pid = 2'b01;	   4'b0010: allow_pid = 2'b10;	   4'b0001: allow_pid = 2'b11;	endcasealways @(posedge clk)	// tf/mf:ep/type:tr/type:last dpd	casex({tr_fr_d,csr[27:26],csr[25:24],uc_dpd})	// synopsys full_case parallel_case	   8'b0?_01_01_??: this_dpid <= 2'b00;	// ISO txfr. IN, 1 tr/mf	   8'b10_01_01_?0: this_dpid <= 2'b01;	// ISO txfr. IN, 2 tr/mf	   8'b10_01_01_?1: this_dpid <= 2'b00;	// ISO txfr. IN, 2 tr/mf	   8'b11_01_01_00: this_dpid <= 2'b10;	// ISO txfr. IN, 3 tr/mf	   8'b11_01_01_01: this_dpid <= 2'b01;	// ISO txfr. IN, 3 tr/mf	   8'b11_01_01_10: this_dpid <= 2'b00;	// ISO txfr. IN, 3 tr/mf	   8'b00_10_01_??: this_dpid <= allow_pid;	// ISO txfr. OUT, 0 tr/mf	   8'b01_10_01_??: this_dpid <= 2'b00;	// ISO txfr. OUT, 1 tr/mf	   8'b10_10_01_?0: this_dpid <= 2'b11;	// ISO txfr. OUT, 2 tr/mf	   8'b10_10_01_?1: this_dpid <= 2'b01;	// ISO txfr. OUT, 2 tr/mf	   8'b11_10_01_00: this_dpid <= 2'b11;	// ISO txfr. OUT, 3 tr/mf	   8'b11_10_01_01: this_dpid <= 2'b11;	// ISO txfr. OUT, 3 tr/mf	   8'b11_10_01_10: this_dpid <= 2'b10;	// ISO txfr. OUT, 3 tr/mf	   8'b??_01_00_?0,				// IN/OUT endpoint only	   8'b??_10_00_?0: this_dpid <= 2'b00;	// INT transfers	   8'b??_01_00_?1,				// IN/OUT endpoint only	   8'b??_10_00_?1: this_dpid <= 2'b01;	// INT transfers	   8'b??_01_10_?0,				// IN/OUT endpoint only	   8'b??_10_10_?0: this_dpid <= 2'b00;	// BULK transfers	   8'b??_01_10_?1,				// IN/OUT endpoint only	   8'b??_10_10_?1: this_dpid <= 2'b01;	// BULK transfers	   8'b??_00_??_??:				// CTRL Endpoint		casex({setup_token,in_op, out_op, uc_dpd})	// synopsys full_case parallel_case		   5'b1_??_??: this_dpid <= 2'b00;	// SETUP operation		   5'b0_10_0?: this_dpid <= 2'b00;	// IN operation		   5'b0_10_1?: this_dpid <= 2'b01;	// IN operation		   5'b0_01_?0: this_dpid <= 2'b00;	// OUT operation		   5'b0_01_?1: this_dpid <= 2'b01;	// OUT operation		endcase	endcase// Assign PID for outgoing packetsassign data_pid_sel = this_dpid;// Verify PID for incoming data packetsalways @(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)	);/////////////////////////////////////////////////////////////////////// IDMA Setup & src/dst buffer select//// For Control endpoints things are different:// buffer0 is used for OUT (incoming) data packets// buffer1 is used for IN (outgoing) data packets// Keep track of last token for control endpoints`ifdef USBF_ASYNC_RESETalways @(posedge clk or negedge rst)`elsealways @(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_RESETalways @(posedge clk or negedge rst)`elsealways @(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_RESETalways @(posedge clk or negedge rst)`elsealways @(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;// Indicates if we are performing an IN operationassign	in_op = IN_ep | (CTRL_ep & in_token);// Indicates if we are performing an OUT operationassign	out_op = OUT_ep | (CTRL_ep & out_token);// Select buffer: buf_sel==0 buffer0; buf_sel==1 buffer1assign buf_sel =  dma_en ? 1'b0 : CTRL_ep ? in_token : ((uc_bsel[0] | buf0_na) & !buf1_na);// Select Address for IDMAalways @(posedge clk)	adr <= buf_sel ? buf1_adr : buf0_adr;

⌨️ 快捷键说明

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