?? usb1_ctrl.v
字號:
/////////////////////////////////////////////////////////////////////
//// ////
//// 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: usb1_ctrl.v,v $
// Revision 1.2 2002/09/25 06:06:49 rudi
// - Added New Top Level
// - Remove old top level and associated files
// - Moved FIFOs to "Generic FIFOs" project
//
// Revision 1.1.1.1 2002/09/19 12:07:09 rudi
// Initial Checkin
//
//
//
//
//
//
`include "usb1_defines.v"
module usb1_ctrl( clk, rst,
rom_adr, rom_data,
ctrl_setup, ctrl_in, ctrl_out,
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,
report_data
);
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] 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;
output [7 : 0] report_data;
reg [7 : 0] report_data;
///////////////////////////////////////////////////////////////////
//
// 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,
C_SET_REPORT_S = 20'b0100_0000_0000_0000_0000,
WAIT_OUT_DATA = 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 c_set_report;
reg c_set_idle;
wire fifo_re1, fifo_full, fifo_empty;
reg fifo_we_d;
reg [4: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;
wire high_sel;
reg write_done, write_done_r;
reg get_report;
reg get_report_l0;
///////////////////////////////////////////////////////////////////
//
// 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[13:8]) // synopsys full_case parallel_case
6'h01: rom_start_d = `ROM_START0;
6'h02: rom_start_d = `ROM_START1;
6'h03:
case(wValue[3:0]) // synopsys full_case parallel_case
4'h00: rom_start_d = `ROM_START2A;
4'h01: rom_start_d = `ROM_START2B;
4'h02: rom_start_d = `ROM_START2C;
default: rom_start_d = `ROM_START2A;
endcase
6'h22: rom_start_d = `ROM_START3;
default: rom_start_d = 7'h00;
endcase
always @(wValue)
case(wValue[13:8]) // synopsys full_case parallel_case
6'h01: rom_size_dd = `ROM_SIZE0;
6'h02: rom_size_dd = `ROM_SIZE1;
6'h03:
case(wValue[3:0]) // synopsys full_case parallel_case
4'h00: rom_size_dd = `ROM_SIZE2A;
4'h01: rom_size_dd = `ROM_SIZE2B;
4'h02: rom_size_dd = `ROM_SIZE2C;
default: rom_size_dd = `ROM_SIZE2A;
endcase
6'h22: rom_size_dd = `ROM_SIZE3;
default: rom_size_dd = 7'h01;
endcase
assign rom_size_d = ({3'h0, rom_size_dd} > wLength[9:0]) ? (|wLength[9:7] ? rom_size_dd : 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 | get_report) & !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(adv) 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] & adv;
always @(posedge clk)
if(!rst) get_report_l0 <= 1'b0;
else get_report_l0 <= get_report;
always @(posedge clk)
if(!rst) report_data <= #1 8'h5a;
else if(get_report_l0) report_data <= #1 ep0_din;
///////////////////////////////////////////////////////////////////
//
// Send Data to Host
//
parameter ZERO_DATA = 5'b00001,
ZERO_ONE_DATA = 5'b00010,
CONFIG_DATA = 5'b00100,
SYNC_FRAME_DATA = 5'b01000,
VEND_DATA = 5'b10000;
assign high_sel = write_done_r;
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];
endcase
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -