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

📄 usb1_ctrl.v

📁 USB v1.1 RTL and design specification
💻 V
📖 第 1 页 / 共 2 页
字号:
always @(posedge clk)
	ep0_we <= #1 fifo_we_d | fifo_we_rom;

always @(posedge clk)
	if(in_size_0)	ep0_size <= #1 8'h0;
	else
	if(in_size_1)	ep0_size <= #1 8'h1;
	else
	if(in_size_2)	ep0_size <= #1 8'h2;
	else
	if(rom_sel)	ep0_size <= #1 {1'b0, rom_size_d};


always @(posedge clk)
	write_done_r <= #1 in_size_2 & !fifo_full & fifo_we_d &
				!write_done_r & !write_done;

always @(posedge clk)
	write_done <= #1 in_size_2 & !fifo_full & fifo_we_d &
				write_done_r & !write_done;

///////////////////////////////////////////////////////////////////
//
// Decode Header
//

// Valid bRequest Codes
parameter	GET_STATUS	=	8'h00,
		CLEAR_FEATURE	=	8'h01,
		SET_FEATURE	=	8'h03,
		SET_ADDRESS	=	8'h05,
		GET_DESCRIPTOR	=	8'h06,
		SET_DESCRIPTOR	=	8'h07,
		GET_CONFIG	=	8'h08,
		SET_CONFIG	=	8'h09,
		GET_INTERFACE	=	8'h0a,
		SET_INTERFACE	=	8'h0b,
		SYNCH_FRAME	=	8'h0c;

parameter	V_SET_INT	=	8'h0f;

parameter	C_SET_REPORT =	8'h09,
			C_SET_IDLE	=	8'h0a;

assign bmReqType = hdr0;
assign bm_req_dir = bmReqType[7];	// 0-Host to device; 1-device to host 
assign bm_req_type = bmReqType[6:5];	// 0-standard; 1-class; 2-vendor; 3-RESERVED
assign bm_req_recp = bmReqType[4:0];	// 0-device; 1-interface; 2-endpoint; 3-other
					// 4..31-reserved
assign bRequest =  hdr1;
assign wValue   = {hdr3, hdr2};
assign wIndex   = {hdr5, hdr4};
assign wLength  = {hdr7, hdr6};

always @(posedge clk)
	hdr_done_r <= #1 hdr_done;

// Standard commands that MUST support
always @(posedge clk)
	get_status <= #1	hdr_done & (bRequest == GET_STATUS) &
								(bm_req_type==2'h0);

always @(posedge clk)
	clear_feature <= #1	hdr_done & (bRequest == CLEAR_FEATURE) &
								(bm_req_type==2'h0);

always @(posedge clk)
	set_feature <= #1	hdr_done & (bRequest == SET_FEATURE) &
								(bm_req_type==2'h0);

always @(posedge clk)
	set_address <= #1	hdr_done & (bRequest == SET_ADDRESS) &
								(bm_req_type==2'h0);

always @(posedge clk)
	get_descriptor <= #1	hdr_done & (bRequest == GET_DESCRIPTOR) &
								(bm_req_type==2'h0);

always @(posedge clk)
	set_descriptor <= #1	hdr_done & (bRequest == SET_DESCRIPTOR) &
								(bm_req_type==2'h0);

always @(posedge clk)
	get_config <= #1	hdr_done & (bRequest == GET_CONFIG) &
								(bm_req_type==2'h0);

always @(posedge clk)
	set_config <= #1	hdr_done & (bRequest == SET_CONFIG) &
								(bm_req_type==2'h0);

always @(posedge clk)
	get_interface <= #1	hdr_done & (bRequest == GET_INTERFACE) &
								(bm_req_type==2'h0);

always @(posedge clk)
	set_interface <= #1	hdr_done & (bRequest == SET_INTERFACE) &
								(bm_req_type==2'h0);

always @(posedge clk)
	synch_frame <= #1	hdr_done & (bRequest == SYNCH_FRAME) &
								(bm_req_type==2'h0);

always @(posedge clk)
	v_set_int <= #1		hdr_done & (bRequest == V_SET_INT) &
								(bm_req_type==2'h2);

always @(posedge clk)
	v_set_feature <= #1	hdr_done & (bRequest == SET_FEATURE) &
								(bm_req_type==2'h2);

always @(posedge clk)
	v_get_status <= #1	hdr_done & (bRequest == GET_STATUS) &
								(bm_req_type==2'h2);

always @(posedge clk)
	c_set_report <= #1	hdr_done & (bRequest == C_SET_REPORT) &
								(bm_req_type==2'h1);

always @(posedge clk)
	c_set_idle <= #1	hdr_done & (bRequest == C_SET_IDLE) &
								(bm_req_type==2'h1);

// A config err must cause the device to send a STALL for an ACK
always @(posedge clk)
	config_err <= #1 hdr_done_r & !(get_status | clear_feature |
			set_feature | set_address | get_descriptor |
			set_descriptor | get_config | set_config |
			get_interface | set_interface | synch_frame |
			v_set_int | v_set_feature | v_get_status |
			c_set_report | c_set_idle);

always @(posedge clk)
	send_stall <= #1 config_err;

///////////////////////////////////////////////////////////////////
//
// Set address
//

always @(posedge clk)
	if(!rst)				set_adr_pending <= #1 1'b0;
	else
	if(ctrl_in | ctrl_out | ctrl_setup)	set_adr_pending <= #1 1'b0;
	else
	if(set_address)				set_adr_pending <= #1 1'b1;

always @(posedge clk)
	if(!rst)			funct_adr_tmp <= #1 7'h0;
	else
	if(set_address)			funct_adr_tmp <= #1 wValue[6:0];

always @(posedge clk)
	if(!rst)			funct_adr <= #1 7'h0;
	else
	if(set_adr_pending & ctrl_in)	funct_adr <= #1 funct_adr_tmp;

///////////////////////////////////////////////////////////////////
//
// Main FSM
//

always @(posedge clk)
	if(!rst)	state <= #1 IDLE;
	else		state <= next_state;

always @(state or ctrl_setup or ctrl_in or ctrl_out or hdr_done or
	fifo_full or rom_done or write_done_r or wValue or bm_req_recp or
	get_status or clear_feature or set_feature or set_address or
	get_descriptor or set_descriptor or get_config or set_config or
	get_interface or set_interface or synch_frame or v_set_int or
	v_set_feature or v_get_status or c_set_report or c_set_idle or
	fifo_empty
	)
   begin
	next_state = state;
	get_hdr  = 1'b0;
	get_report = 1'b0;
	data_sel = ZERO_DATA;
	fifo_we_d = 1'b0;
	in_size_0 = 1'b0;
	in_size_1 = 1'b0;
	in_size_2 = 1'b0;
	rom_sel = 1'b0;

	case(state)	// synopsys full_case parallel_case

		// Wait for Setup token
	   IDLE:
		   begin
			if(ctrl_setup)		next_state = GET_HDR;
			if(get_status)		next_state = GET_STATUS_S;
			if(clear_feature)	next_state = CLEAR_FEATURE_S;
			if(set_feature)		next_state = SET_FEATURE_S;
			if(set_address)		next_state = SET_ADDRESS_S;
			if(get_descriptor)	next_state = GET_DESCRIPTOR_S;
			if(set_descriptor)	next_state = SET_DESCRIPTOR_S;
			if(get_config)		next_state = GET_CONFIG_S;
			if(set_config)		next_state = SET_CONFIG_S;
			if(get_interface)	next_state = GET_INTERFACE_S;
			if(set_interface)	next_state = SET_INTERFACE_S;
			if(synch_frame)		next_state = SYNCH_FRAME_S;
			if(v_set_int)		next_state = V_SET_INT_S;
			if(v_set_feature)	next_state = V_SET_INT_S;
			if(v_get_status)	next_state = V_GET_STATUS_S;
			if(c_set_report)	next_state = C_SET_REPORT_S;
			if(c_set_idle)		next_state = STATUS_IN;
		   end

		// Retrieve Setup Header
	   GET_HDR:
		   begin
			get_hdr = 1'b1;
			if(hdr_done)	next_state = IDLE;
		   end


		// Actions for supported commands
	   GET_STATUS_S:
		   begin
			// Returns to host
			// 16'h0001 for device
			// 16'h0000 for interface
			// 16'h0000 for endpoint
			if(bm_req_recp == 5'h00)	data_sel = ZERO_ONE_DATA;
			else				data_sel = ZERO_DATA;

			in_size_2 = 1'b1;
			if(!fifo_full)
			   begin
				fifo_we_d = 1'b1;
				if(write_done_r)	next_state = WAIT_IN_DATA;
			   end

		   end
	   V_GET_STATUS_S:
		   begin
			data_sel = VEND_DATA;
			in_size_2 = 1'b1;
			if(!fifo_full)
			   begin
				fifo_we_d = 1'b1;
				if(write_done_r)	next_state = WAIT_IN_DATA;
			   end
		   end

	   CLEAR_FEATURE_S:
		   begin
			// just ignore this for now
			next_state = STATUS_IN;
		   end

	   SET_FEATURE_S:
		   begin
			// just ignore this for now
			next_state = STATUS_IN;
		   end

	   SET_ADDRESS_S:
		   begin
			// done elsewhere ....
			next_state = STATUS_IN;
		   end

	   GET_DESCRIPTOR_S:
		   begin
			if(	wValue[15:8] == 8'h01 |
				wValue[15:8] == 8'h02 | 
				wValue[15:8] == 8'h03 |
				wValue[15:8] == 8'h22	)
				rom_sel = 1'b1;
			else
				next_state = IDLE;

			if(rom_done)
				next_state = IDLE;
		   end

	   SET_DESCRIPTOR_S:
		   begin
			// This doesn't do anything since we do not support
			// setting the descriptor
			next_state = IDLE;
		   end

	   GET_CONFIG_S:
		   begin
			// Send one byte back that indicates current status
			in_size_1 = 1'b1;
			data_sel = CONFIG_DATA;
			if(!fifo_full)
			   begin
				fifo_we_d = 1'b1;
				next_state = WAIT_IN_DATA;
			   end
		   end

	   SET_CONFIG_S:
		   begin
			// done elsewhere ....
			next_state = STATUS_IN;
		   end

	   GET_INTERFACE_S:
		   begin
			// Return interface '0'
			in_size_1 = 1'b1;
			if(!fifo_full)
			   begin
				fifo_we_d = 1'b1;
				next_state = WAIT_IN_DATA;
			   end
		   end

	   SET_INTERFACE_S:
		   begin
			// just ignore this for now
			next_state = STATUS_IN;
		   end

	   SYNCH_FRAME_S:
		   begin
			// Return Frame current frame number
			data_sel = SYNC_FRAME_DATA;
			in_size_2 = 1'b1;
			if(!fifo_full)
			   begin
				fifo_we_d = 1'b1;
				if(write_done_r)	next_state = WAIT_IN_DATA;
			   end
		   end

	   V_SET_INT_S:
		   begin
			// done elsewhere ....
			next_state = STATUS_IN;
		   end

	   C_SET_REPORT_S:
	   	   begin
			next_state = WAIT_OUT_DATA;
	   	   end

	   WAIT_OUT_DATA:
		   begin
			if(!fifo_empty) begin
				get_report = 1'b1;
				next_state = STATUS_IN;
			end
		   end
	   	
	   WAIT_IN_DATA:
		   begin
			if(ctrl_in)	next_state = STATUS_OUT;
		   end

	   STATUS_IN:
		   begin
			in_size_0 = 1'b1;
			if(ctrl_in)	next_state = IDLE;
		   end

	   STATUS_OUT:
		   begin
			if(ctrl_out)	next_state = IDLE;
		   end
	endcase
   end

endmodule

⌨️ 快捷键说明

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