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

📄 usb1_pe.v

📁 usb1.1 ip核
💻 V
📖 第 1 页 / 共 3 页
字号:
	if(uc_dpd_set & (ep_sel == 4'h1))	ep1_dpid <= next_dpid;always @(posedge clk or negedge rst)	if(!rst)				ep2_dpid <= 2'b00;	else	if(uc_dpd_set & (ep_sel == 4'h2))	ep2_dpid <= next_dpid;always @(posedge clk or negedge rst)	if(!rst)				ep3_dpid <= 2'b00;	else	if(uc_dpd_set & (ep_sel == 4'h3))	ep3_dpid <= next_dpid;always @(posedge clk or negedge rst)	if(!rst)				ep4_dpid <= 2'b00;	else	if(uc_dpd_set & (ep_sel == 4'h4))	ep4_dpid <= next_dpid;always @(posedge clk or negedge rst)	if(!rst)				ep5_dpid <= 2'b00;	else	if(uc_dpd_set & (ep_sel == 4'h5))	ep5_dpid <= next_dpid;always @(posedge clk or negedge rst)	if(!rst)				ep6_dpid <= 2'b00;	else	if(uc_dpd_set & (ep_sel == 4'h6))	ep6_dpid <= next_dpid;always @(posedge clk or negedge rst)	if(!rst)				ep7_dpid <= 2'b00;	else	if(uc_dpd_set & (ep_sel == 4'h7))	ep7_dpid <= next_dpid;always @(posedge clk)//uc_dpd是什么东西??,当前传输的data包的pid,	case(ep_sel)	   4'h0: uc_dpd <= ep0_dpid;	   4'h1: uc_dpd <= ep1_dpid;	   4'h2: uc_dpd <= ep2_dpid;	   4'h3: uc_dpd <= ep3_dpid;	   4'h4: uc_dpd <= ep4_dpid;	   4'h5: uc_dpd <= ep5_dpid;	   4'h6: uc_dpd <= ep6_dpid;	   4'h7: uc_dpd <= ep7_dpid; 	endcase/////////////////////////////////////////////////////////////////////// Data Pid Sequencer//assign tr_fr_d = 2'h0;//岂不是tr_fr_d一直为00??这可是持续赋值啊!!正是!always @(posedge clk)	// tr/mf:ep/type:tr/type:last dpd	casex({tr_fr_d,ep_type,txfr_type,uc_dpd})	// synopsys full_case parallel_case	   8'b0?_01_01_??: next_dpid <= #1 2'b00;	// ISO txfr. IN, 1 tr/mf,设备到主机,data0                                                   	   8'b10_01_01_?0: next_dpid <= #1 2'b01;	// ISO txfr. IN, 2 tr/mf不必看	   8'b10_01_01_?1: next_dpid <= #1 2'b00;	// ISO txfr. IN, 2 tr/mf不必看	   8'b11_01_01_00: next_dpid <= #1 2'b01;	// ISO txfr. IN, 3 tr/mf不必看	   8'b11_01_01_01: next_dpid <= #1 2'b10;	// ISO txfr. IN, 3 tr/mf不必看	   8'b11_01_01_10: next_dpid <= #1 2'b00;	// ISO txfr. IN, 3 tr/mf不必看	   8'b0?_10_01_??: next_dpid <= #1 2'b00;	// ISO txfr. OUT, 1 tr/mf,主机到设备,data0	   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 <= #1 2'b01;				  2'b01: next_dpid <= #1 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 <= #1 2'b01;				  2'b01: next_dpid <= #1 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 <= #1 2'b10;				  2'b01: next_dpid <= #1 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 <= #1 2'b01;				  2'b01: next_dpid <= #1 2'b00;				endcase			   end                                    //当前用的是data0,则下次切换成data1	   8'b??_01_00_?0,				// IN/OUT endpoint only下面是中断传输,满足data0,data1轮换	   8'b??_10_00_?0: next_dpid <= #1 2'b01;	// INT transfers为什么不明写??_10_00_00呢                                    //当前用的是data1,则下次切换成data0	   8'b??_01_00_?1,				// IN/OUT endpoint only	   8'b??_10_00_?1: next_dpid <= #1 2'b00;	// INT transfers                                    //当前是data0,下次切换为data1	   8'b??_01_10_?0,				// IN/OUT endpoint only下面是批量传输,满足data0,data1轮换	   8'b??_10_10_?0: next_dpid <= #1 2'b01;	// BULK transfers                                    //当前是data1,下次切换为data0	   8'b??_01_10_?1,				// IN/OUT endpoint only	   8'b??_10_10_?1: next_dpid <= #1 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 <= #1 2'b11;	// SETUP operation   永远记住,next_dpid只是一个中间变量		   5'b0_10_0?: next_dpid <= #1 2'b11;	// IN operation		   5'b0_10_1?: next_dpid <= #1 2'b01;	// IN operation		   5'b0_01_?0: next_dpid <= #1 2'b11;	// OUT operation		   5'b0_01_?1: next_dpid <= #1 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这部分也有严重的理解问题,420	casex({tr_fr_d,ep_type,txfr_type,uc_dpd})	// synopsys full_case parallel_case	   8'b0?_01_01_??: this_dpid <= #1 2'b00;	// ISO txfr. IN, 1 tr/mf仅data0,如果没有意外,基本符合协议规定	   8'b10_01_01_?0: this_dpid <= #1 2'b01;	// ISO txfr. IN, 2 tr/mf不必看	   8'b10_01_01_?1: this_dpid <= #1 2'b00;	// ISO txfr. IN, 2 tr/mf不必看	   8'b11_01_01_00: this_dpid <= #1 2'b10;	// ISO txfr. IN, 3 tr/mf不必看	   8'b11_01_01_01: this_dpid <= #1 2'b01;	// ISO txfr. IN, 3 tr/mf不必看	   8'b11_01_01_10: this_dpid <= #1 2'b00;	// ISO txfr. IN, 3 tr/mf不必看	   8'b00_10_01_??: this_dpid <= #1 allow_pid;	// ISO txfr. OUT, 0 tr/mf符合输出时的协议规定	   8'b01_10_01_??: this_dpid <= #1 2'b00;	// ISO txfr. OUT, 1 tr/mf它也用不到的	   8'b10_10_01_?0: this_dpid <= #1 2'b11;	// ISO txfr. OUT, 2 tr/mf不必看	   8'b10_10_01_?1: this_dpid <= #1 2'b01;	// ISO txfr. OUT, 2 tr/mf不必看	   8'b11_10_01_00: this_dpid <= #1 2'b11;	// ISO txfr. OUT, 3 tr/mf不必看	   8'b11_10_01_01: this_dpid <= #1 2'b11;	// ISO txfr. OUT, 3 tr/mf不必看	   8'b11_10_01_10: this_dpid <= #1 2'b10;	// ISO txfr. OUT, 3 tr/mf不必看	   8'b??_01_00_?0,				// IN/OUT endpoint only中断传输的场合	   8'b??_10_00_?0: this_dpid <= #1 2'b00;	// INT transfers	   8'b??_01_00_?1,				// IN/OUT endpoint only	   8'b??_10_00_?1: this_dpid <= #1 2'b01;	// INT transfers	   8'b??_01_10_?0,				// IN/OUT endpoint only批量传输的场合	   8'b??_10_10_?0: this_dpid <= #1 2'b00;	// BULK transfers	   8'b??_01_10_?1,				// IN/OUT endpoint only	   8'b??_10_10_?1: this_dpid <= #1 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 <= #1 2'b00;	// SETUP operation,data0包,正确		   5'b0_10_0?: this_dpid <= #1 2'b00;	// IN operation我觉得与协议有出入!事实上没有一点问题,我已明白		   5'b0_10_1?: this_dpid <= #1 2'b01;	// IN operation很严重的理解问题,已解决		   5'b0_01_?0: this_dpid <= #1 2'b00;	// OUT operation主机输出		   5'b0_01_?1: this_dpid <= #1 2'b01;	// OUT operation		endcase	endcase// Assign PID for outgoing packets,为输出数据包加包标识符assign data_pid_sel = this_dpid;// Verify PID for incoming data packets,要注意:这里的incoming是从设备的角度说的,自然交给pd处理always @(posedge clk)	pid_seq_err <= #1 !(	(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 endpointsalways @(posedge clk or negedge rst)//对in_token赋值,很清晰,in_token,reg型	if(!rst)		in_token <= #1 1'b0;	else	if(pid_IN)		in_token <= #1 1'b1;	else	if(pid_OUT | pid_SETUP)	in_token <= #1 1'b0;always @(posedge clk or negedge rst)//对out_token赋值,也很清晰	if(!rst)		out_token <= #1 1'b0;	else	if(pid_OUT | pid_SETUP)	out_token <= #1 1'b1;//特别提醒:包含了setup事务,因为setup也是主机发送数据到设备	else	if(pid_IN)		out_token <= #1 1'b0;always @(posedge clk or negedge rst)//给setup_token赋值	if(!rst)		setup_token <= #1 1'b0;	else	if(pid_SETUP)		setup_token <= #1 1'b1;	else	if(pid_OUT | pid_IN)	setup_token <= #1 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);//输出端点输出,或控制端点的输出事务/////////////////////////////////////////////////////////////////////// Determine if packet is to small or to large// This is used to NACK and ignore packet for OUT endpoints///////////////////////////////////////////////////////////////////////// Register File Update Logic//always @(posedge clk)	uc_dpd_set <= #1 uc_stat_set_d;//uc_stat_set_d是来自状态机的是否切换data0,data1的标志,                                   //而uc_dpd_set是是否允许改变epN_dpid的标志,很显然,如果epN_dpid得不到修改// Abort signal                    //那么uc_dpd也不会变化的always @(posedge clk)	abort <= #1 match & fsel & (state != IDLE);//还不明白,不空闲??/////////////////////////////////////////////////////////////////////// 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 <= #1 tx_valid | rx_ack_to_clr_d;//tx_valid产生于包组装模块                                                   //传输有效即正在传输就不计数always @(posedge clk)	if(rx_ack_to_clr)	rx_ack_to_cnt <= #1 8'h0;//计数器清零了	else			rx_ack_to_cnt <= #1 rx_ack_to_cnt + 8'h1;//否则计数always @(posedge clk)//给rx_ack_to赋值	rx_ack_to <= #1 (rx_ack_to_cnt == rx_ack_to_val);assign rx_ack_to_val = `USBF_RX_ACK_TO_VAL_FS;//从usb1_defines.v中取了预定值// 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;//注意这个持续赋值,这里的与上面的rx_ack_to一致                                   //能检测到同步头就不计数,说明收到数据always @(posedge clk)	if(tx_data_to_clr)	tx_data_to_cnt <= #1 8'h0;	else			tx_data_to_cnt <= #1 tx_data_to_cnt + 8'h1;always @(posedge clk)	tx_data_to <= #1 (tx_data_to_cnt == tx_data_to_val);assign tx_data_to_val = `USBF_TX_DATA_TO_VAL_FS;/////////////////////////////////////////////////////////////////////// Interrupts//

⌨️ 快捷键说明

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