blob: 6f1a66c58daea588725a85dd90349642d09b7a80 [file] [log] [blame]
/**********************************************************************
* Ported to USB2UART project
* Author: Dinesh Annayya
* Email:- dinesha@opencores.org
*
* Date: 4th Feb 2013
* Changes:
* A. Warning Clean Up
*
**********************************************************************/
/////////////////////////////////////////////////////////////////////
//// ////
//// Internal Setup Engine ////
//// ////
//// ////
//// Author: Rudolf Usselmann ////
//// rudi@asics.ws ////
//// ////
//// ////
//// Downloaded from: http://www.opencores.org/cores/usb1_funct/////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
//// www.asics.ws ////
//// rudi@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
// CVS Log
//
// $Id: usb1_ctrl.v,v 1.2 2002-09-25 06:06:49 rudi Exp $
//
// $Date: 2002-09-25 06:06:49 $
// $Revision: 1.2 $
// $Author: rudi $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2002/09/19 12:07:09 rudi
// Initial Checkin
//
//
//
//
//
//
`include "usb1d_defines.v"
module usb1d_ctrl( clk, rst,
rom_adr, rom_data,
ctrl_setup, ctrl_in, ctrl_out,
rx_ctrl_data, rx_ctrl_dvalid,rx_ctrl_ddone,
ep0_din, ep0_dout, ep0_re, ep0_we, ep0_stat,
ep0_size,
send_stall, frame_no,
funct_adr, configured, halt,
v_set_int, v_set_feature, wValue, wIndex, vendor_data,
// Register Interface
reg_addr,
reg_rdwrn,
reg_req,
reg_wdata,
reg_rdata,
reg_ack
);
input clk, rst;
output [6:0] rom_adr;
input [7:0] rom_data;
input ctrl_setup;
input ctrl_in;
input ctrl_out;
input [7:0] rx_ctrl_data;
input rx_ctrl_dvalid;
input rx_ctrl_ddone;
input [7:0] ep0_din;
output [7:0] ep0_dout;
output ep0_re, ep0_we;
input [3:0] ep0_stat;
output [7:0] ep0_size;
output send_stall;
input [10:0] frame_no;
output [6:0] funct_adr;
output configured, halt;
output v_set_int;
output v_set_feature;
output [15:0] wValue;
output [15:0] wIndex;
input [15:0] vendor_data;
//-----------------------------------
// Register Interface
// ----------------------------------
output [31:0] reg_addr; // Register Address
output reg_rdwrn; // 0 -> write, 1-> read
output reg_req; // Register Req
output [31:0] reg_wdata; // Register write data
input [31:0] reg_rdata; // Register Read Data
input reg_ack; // Register Ack
///////////////////////////////////////////////////////////////////
//
// Local Wires and Registers
//
parameter IDLE = 20'b0000_0000_0000_0000_0001,
GET_HDR = 20'b0000_0000_0000_0000_0010,
GET_STATUS_S = 20'b0000_0000_0000_0000_0100,
CLEAR_FEATURE_S = 20'b0000_0000_0000_0000_1000,
SET_FEATURE_S = 20'b0000_0000_0000_0001_0000,
SET_ADDRESS_S = 20'b0000_0000_0000_0010_0000,
GET_DESCRIPTOR_S = 20'b0000_0000_0000_0100_0000,
SET_DESCRIPTOR_S = 20'b0000_0000_0000_1000_0000,
GET_CONFIG_S = 20'b0000_0000_0001_0000_0000,
SET_CONFIG_S = 20'b0000_0000_0010_0000_0000,
GET_INTERFACE_S = 20'b0000_0000_0100_0000_0000,
SET_INTERFACE_S = 20'b0000_0000_1000_0000_0000,
SYNCH_FRAME_S = 20'b0000_0001_0000_0000_0000,
WAIT_IN_DATA = 20'b0000_0010_0000_0000_0000,
STATUS_IN = 20'b0000_0100_0000_0000_0000,
STATUS_OUT = 20'b0000_1000_0000_0000_0000,
V_SET_INT_S = 20'b0001_0000_0000_0000_0000,
V_GET_STATUS_S = 20'b0010_0000_0000_0000_0000,
V_GET_REG_RDATA_S = 20'b0100_0000_0000_0000_0000,
V_WAIT_RDATA_DONE_S = 20'b1000_0000_0000_0000_0000;
wire [7:0] bmReqType, bRequest;
wire [15:0] wValue, wIndex, wLength;
wire bm_req_dir;
wire [1:0] bm_req_type;
wire [4:0] bm_req_recp;
reg get_status, clear_feature, set_feature, set_address;
reg get_descriptor, set_descriptor, get_config, set_config;
reg get_interface, set_interface, synch_frame;
reg hdr_done_r, config_err;
reg v_set_int, v_set_feature, v_get_status;
reg v_set_reg_waddr; // Set the Reg Bus Address
reg v_set_reg_raddr; // Set the Reg Bus Address
wire fifo_re1, fifo_full, fifo_empty;
reg fifo_we_d;
reg [5:0] data_sel;
reg ep0_we;
reg [7:0] ep0_dout;
reg [7:0] ep0_size;
reg send_stall;
reg [19:0] state, next_state;
reg get_hdr;
reg [7:0] le;
wire hdr_done;
reg adv;
reg [7:0] hdr0, hdr1, hdr2, hdr3, hdr4, hdr5, hdr6, hdr7;
reg [6:0] funct_adr;
reg set_adr_pending;
reg [6:0] funct_adr_tmp;
reg in_size_0;
reg in_size_1;
reg in_size_2;
reg in_size_4;
wire high_sel;
reg write_done;
//----------------------------
// Register Interface
// ----------------------------
reg [31:0] reg_addr;
reg [31:0] reg_wdata;
reg [31:0] reg_rdata_r;
reg reg_req;
reg reg_rdwrn; // 0 - write, 1 -> read
reg reg_wphase; // register write phase
reg reg_rphase; // register read phase
reg [3:0] tx_bcnt; // transmit byte count
///////////////////////////////////////////////////////////////////
//
// FIFO interface
//
assign ep0_re = fifo_re1;
assign fifo_empty = ep0_stat[1];
assign fifo_full = ep0_stat[2];
///////////////////////////////////////////////////////////////////
//
// Current States
//
reg addressed;
reg configured;
reg halt;
wire clr_halt;
wire set_halt=0; // FIX_ME
// For this implementation we do not implement HALT for the
// device nor for any of the endpoints. This is useless for
// this device, but can be added here later ...
// FYI, we report device/endpoint errors via interrupts,
// instead of halting the entire or part of the device, much
// nicer for non-critical errors.
assign clr_halt = ctrl_setup;
always @(posedge clk)
if(!rst) addressed <= #1 1'b0;
else
if(set_address) addressed <= #1 1'b1;
always @(posedge clk)
if(!rst) configured <= #1 1'b0;
else
if(set_config) configured <= #1 1'b1;
always @(posedge clk)
if(!rst) halt <= #1 1'b0;
else
if(clr_halt) halt <= #1 1'b0;
else
if(set_halt) halt <= #1 1'b1;
///////////////////////////////////////////////////////////////////
//
// Descriptor ROM
//
reg [6:0] rom_adr;
reg rom_sel, rom_sel_r;
wire rom_done;
reg [6:0] rom_size;
reg fifo_we_rom_r;
reg fifo_we_rom_r2;
wire fifo_we_rom;
reg [7:0] rom_start_d;
reg [6:0] rom_size_dd;
wire [6:0] rom_size_d;
always @(wValue)
case(wValue[11:8]) // synopsys full_case parallel_case
4'h1: rom_start_d = `ROM_START0;
4'h2: rom_start_d = `ROM_START1;
4'h3:
case(wValue[3:0]) // synopsys full_case parallel_case
4'h0: rom_start_d = `ROM_START2A;
4'h1: rom_start_d = `ROM_START2B;
4'h2: rom_start_d = `ROM_START2C;
4'h3: rom_start_d = `ROM_START2D;
default: rom_start_d = `ROM_START2A;
endcase
default: rom_start_d = 7'h00;
endcase
always @(wValue)
case(wValue[11:8]) // synopsys full_case parallel_case
4'h1: rom_size_dd = `ROM_SIZE0;
4'h2: rom_size_dd = `ROM_SIZE1;
4'h3:
case(wValue[3:0]) // synopsys full_case parallel_case
4'h0: rom_size_dd = `ROM_SIZE2A;
4'h1: rom_size_dd = `ROM_SIZE2B;
4'h2: rom_size_dd = `ROM_SIZE2C;
4'h3: rom_size_dd = `ROM_SIZE2D;
default: rom_size_dd = `ROM_SIZE2A;
endcase
default: rom_size_dd = 7'h01;
endcase
assign rom_size_d = (rom_size_dd > wLength[6:0]) ? wLength[6:0] : rom_size_dd;
always @(posedge clk)
rom_sel_r <= #1 rom_sel;
always @(posedge clk)
if(!rst) rom_adr <= #1 7'h0;
else
if(rom_sel & !rom_sel_r) rom_adr <= #1 rom_start_d;
else
if(rom_sel & !fifo_full) rom_adr <= #1 rom_adr + 7'h1;
always @(posedge clk)
if(!rst) rom_size <= #1 7'h0;
else
if(rom_sel & !rom_sel_r) rom_size <= #1 rom_size_d;
else
if(rom_sel & !fifo_full) rom_size <= #1 rom_size - 7'h01;
always @(posedge clk)
fifo_we_rom_r <= #1 rom_sel;
always @(posedge clk)
fifo_we_rom_r2 <= #1 fifo_we_rom_r;
assign fifo_we_rom = rom_sel & fifo_we_rom_r2;
assign rom_done = (rom_size == 7'h0) & !(rom_sel & !rom_sel_r);
///////////////////////////////////////////////////////////////////
//
// Get Header
//
assign fifo_re1 = (get_hdr | reg_wphase) & !fifo_empty;
always @(posedge clk)
adv <= #1 get_hdr & !fifo_empty & !adv;
always @(posedge clk)
if(!rst) le <= #1 8'h0;
else
if(!get_hdr) le <= #1 8'h0;
else
if(!(|le)) le <= #1 8'h1;
else
if(fifo_re1 && get_hdr) le <= #1 {le[6:0], 1'b0};
always @(posedge clk)
if(le[0]) hdr0 <= #1 ep0_din;
always @(posedge clk)
if(le[1]) hdr1 <= #1 ep0_din;
always @(posedge clk)
if(le[2]) hdr2 <= #1 ep0_din;
always @(posedge clk)
if(le[3]) hdr3 <= #1 ep0_din;
always @(posedge clk)
if(le[4]) hdr4 <= #1 ep0_din;
always @(posedge clk)
if(le[5]) hdr5 <= #1 ep0_din;
always @(posedge clk)
if(le[6]) hdr6 <= #1 ep0_din;
always @(posedge clk)
if(le[7]) hdr7 <= #1 ep0_din;
assign hdr_done = le[7] & fifo_re1 & get_hdr;
///////////////////////////////////////////////////////////////////
//
// Send Data to Host
//
parameter ZERO_DATA = 6'b000001,
ZERO_ONE_DATA = 6'b000010,
CONFIG_DATA = 6'b000100,
SYNC_FRAME_DATA = 6'b001000,
VEND_DATA = 6'b010000,
REG_RDATA = 6'b100000;
assign high_sel = write_done;
always @(posedge clk)
case(data_sel) // synopsys full_case parallel_case
ZERO_DATA: ep0_dout <= #1 rom_sel ? rom_data : 8'h0;
ZERO_ONE_DATA: ep0_dout <= #1 high_sel ? 8'h1 : 8'h0;
CONFIG_DATA: ep0_dout <= #1 {7'h0, configured}; // return configuration
SYNC_FRAME_DATA: ep0_dout <= #1 high_sel ? {5'h0, frame_no[10:8]} : frame_no[7:0];
VEND_DATA: ep0_dout <= #1 high_sel ? vendor_data[15:8] : vendor_data[7:0];
REG_RDATA: ep0_dout <= #1 (tx_bcnt==0) ? reg_rdata_r[31:24] :
(tx_bcnt==1) ? reg_rdata_r[23:16] :
(tx_bcnt==2) ? reg_rdata_r[15:8] : reg_rdata_r[7:0];
endcase
always @(posedge clk)
ep0_we <= #1 (fifo_we_d & !write_done) | 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(in_size_4) ep0_size <= #1 8'h4;
else
if(rom_sel) ep0_size <= #1 {1'b0, rom_size_d};
always @(posedge clk) begin
if(!rst) begin
tx_bcnt <= 0;
write_done <= 0;
end else begin
if(state == IDLE) begin
tx_bcnt <= 0;
write_done <= 0;
end else if((ep0_size == (tx_bcnt+1)) && (!fifo_full && fifo_we_d))
write_done <= 1;
else if(!fifo_full && fifo_we_d )
tx_bcnt <= tx_bcnt+1;
else
write_done <= 0;
end
end
///////////////////////////////////////////////////////////////////
//
// 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,
CUSTOM_REG_WADDR= 8'h10, // Added by Dinesh-A, 19th Feb 2013
CUSTOM_REG_RADDR= 8'h11; // Added by Dinesh-A, 19th Feb 2013
parameter V_SET_INT = 8'h0f;
/*************************************************
* Author: Dinesh-A: 18th Feb 2013
* Setup Byte Details
Byte Field Description
0 bmRequest Type
Bit 7: Request direction (0=Host to device – Out, 1=Device to host – In).
Bits 5-6: Request type (0=standard, 1=class, 2=vendor, 3=reserved).
Bits 0-4: Recipient (0=device, 1=interface, 2=endpoint,3=other).
1 bRequest The actual request (see the Standard Device Request Codes table [9.2.1.5].
2 wValueL A word-size value that varies according to the request. For example,
in the CLEAR_FEATURE request the value is used to select the feature,
in the GET_DESCRIPTOR request the value indicates the descriptor type and in the
SET_ADDRESS request the value contains the device address.
3 wValueH The upper byte of the Value word.
4 wIndexL A word-size value that varies according to the request.
The index is generally used to specify an endpoint or an interface.
5 wIndexH The upper byte of the Index word.
6 wLengthL A word-size value that indicates the number of bytes to be transferred if there is a data stage.
7 wLengthH The upper byte of the Length word.
**************************************************/
/*******
bRequest Value
GET_STATUS 0
CLEAR_FEATURE 1
Reserved for future use 2
SET_FEATURE 3
Reserved for future use 4
SET_ADDRESS 5
GET_DESCRIPTOR 6
SET_DESCRIPTOR 7
GET_CONFIGURATION 8
SET_CONFIGURATION 9
GET_INTERFACE 10
SET_INTERFACE 11
SYNCH_FRAME 12
*******************************/
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)
v_set_reg_waddr <= #1 hdr_done & (bRequest == CUSTOM_REG_WADDR) & (bm_req_type==2'h2);
always @(posedge clk)
v_set_reg_raddr <= #1 hdr_done & (bRequest == CUSTOM_REG_RADDR) & (bm_req_type==2'h2);
always @(posedge clk)
if(v_set_reg_waddr || v_set_reg_raddr) reg_addr <= {hdr2,hdr3,hdr4,hdr5};
reg [1:0] reg_byte_cnt;
always @(posedge clk) begin
if(!rst) begin
reg_byte_cnt <= 2'b0;
end else begin
if(v_set_reg_waddr) begin
reg_wphase <= 1;
reg_byte_cnt <= 0;
end else if(reg_byte_cnt == 2'b11 && fifo_re1) begin
reg_wphase <= 0;
reg_byte_cnt <= 0;
end else if(reg_wphase && fifo_re1) begin
reg_byte_cnt <= reg_byte_cnt+1;
end
end
end
always @(posedge clk)
if(reg_wphase && fifo_re1) reg_wdata <= {reg_wdata[23:0],ep0_din[7:0]};
always @(posedge clk)
if(reg_rdwrn && reg_ack) reg_rdata_r <= {reg_rdata};
always @(posedge clk) begin
if(!rst) begin
reg_req <= 0;
end else begin
if(fifo_re1 && reg_wphase && reg_byte_cnt== 2'b11) reg_req <= 1;
else if(v_set_reg_raddr) reg_req <= 1;
else reg_req <= 0;
end
end
always @(posedge clk)
if(v_set_reg_raddr) reg_rdwrn <= 1'b1 ;
else if(v_set_reg_waddr) reg_rdwrn <= 1'b0 ;
// 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 | v_set_reg_waddr | v_set_reg_raddr);
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 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 v_set_reg_waddr or v_set_reg_raddr, reg_ack
)
begin
next_state = state;
get_hdr = 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;
in_size_4 = 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(v_set_reg_waddr) next_state = STATUS_IN;
if(v_set_reg_raddr) next_state = V_WAIT_RDATA_DONE_S;
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) 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) next_state = WAIT_IN_DATA;
end
end
V_WAIT_RDATA_DONE_S: begin // Wait for Register Read Access Completion
if(reg_ack)
next_state = V_GET_REG_RDATA_S;
end
V_GET_REG_RDATA_S: // Register Access Read Data
begin
data_sel = REG_RDATA;
in_size_4 = 1'b1;
if(!fifo_full)
begin
fifo_we_d = 1'b1;
if(write_done) 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 )
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) next_state = WAIT_IN_DATA;
end
end
V_SET_INT_S:
begin
// done elsewhere ....
next_state = STATUS_IN;
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