📄 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 );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;/////////////////////////////////////////////////////////////////////// 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;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;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;/////////////////////////////////////////////////////////////////////// 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'h00: rom_start_d = `ROM_START2A; 4'h01: rom_start_d = `ROM_START2B; 4'h02: rom_start_d = `ROM_START2C; 4'h03: rom_start_d = `ROM_START2D; default: rom_start_d = `ROM_START2A; endcase default: rom_start_d = 7'h00; endcasealways @(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'h00: rom_size_dd = `ROM_SIZE2A; 4'h01: rom_size_dd = `ROM_SIZE2B; 4'h02: rom_size_dd = `ROM_SIZE2C; 4'h03: rom_size_dd = `ROM_SIZE2D; default: rom_size_dd = `ROM_SIZE2A; endcase default: rom_size_dd = 7'h01; endcaseassign 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 & !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;/////////////////////////////////////////////////////////////////////// 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -