📄 usbf_utmi_ls.v
字号:
`include "usbf_defines.v"module usbf_utmi_ls( clk, rst, resume_req, // UTMI Interface rx_active, tx_ready, drive_k, XcvSelect, TermSel, SuspendM, LineState, OpMode, usb_vbus, // Misc Interfaces mode_hs, usb_reset, usb_suspend, usb_attached, suspend_clr );input clk;//input wclk;input rst;input resume_req;input rx_active, tx_ready;output drive_k;output XcvSelect;output TermSel;output SuspendM;input [1:0] LineState;output [1:0] OpMode;input usb_vbus;output mode_hs; // High Speed Modeoutput usb_reset; // USB Resetoutput usb_suspend; // USB Suspendoutput usb_attached; // Attached to USBoutput suspend_clr;/////////////////////////////////////////////////////////////////////// Parameters//parameter [14:0] // synopsys enum state POR = 15'b000_0000_0000_0001, NORMAL = 15'b000_0000_0000_0010, RES_SUSP = 15'b000_0000_0000_0100, SUSPEND = 15'b000_0000_0000_1000, RESUME = 15'b000_0000_0001_0000, RESUME_REQUEST = 15'b000_0000_0010_0000, RESUME_WAIT = 15'b000_0000_0100_0000, RESUME_SIG = 15'b000_0000_1000_0000, ATTACH = 15'b000_0001_0000_0000, RESET = 15'b000_0010_0000_0000, SPEED_NEG = 15'b000_0100_0000_0000, SPEED_NEG_K = 15'b000_1000_0000_0000, SPEED_NEG_J = 15'b001_0000_0000_0000, SPEED_NEG_HS = 15'b010_0000_0000_0000, SPEED_NEG_FS = 15'b100_0000_0000_0000;/////////////////////////////////////////////////////////////////////// Local Wires and Registers//reg [14:0] /* synopsys enum state */ state, next_state;// synopsys state_vector statereg [1:0] line_state_r;reg mode_hs, mode_set_hs, mode_set_fs;reg usb_suspend, suspend_set, suspend_clr;reg usb_attached, attached_set, attached_clr;reg TermSel, fs_term_on, fs_term_off;reg XcvSelect, xcv_set_hs, xcv_set_fs;reg [1:0] OpMode;reg bit_stuff_on, bit_stuff_off;reg usb_reset, usb_reset_d;wire ls_se0, ls_j, ls_k, ls_se1;reg ls_k_r, ls_j_r, ls_se0_r;reg ls_idle_r;wire ls_idle;reg idle_long;wire idle_long_set, idle_long_clr;wire k_long, j_long, se0_long;reg drive_k, drive_k_d;reg [3:0] ps_cnt;reg ps_cnt_clr;reg idle_cnt_clr;reg idle_cnt1_clr;reg [7:0] idle_cnt1, idle_cnt1_next;reg T1_gt_2_5_uS, T1_st_3_0_mS, T1_gt_3_0_mS;reg T1_gt_3_125_mS, T1_gt_5_0_mS;reg [7:0] me_ps;reg me_cnt_clr;reg me_ps_2_5_us;reg [7:0] me_ps2;reg me_ps2_0_5_ms;reg [7:0] me_cnt;reg me_cnt_100_ms;reg T2_gt_100_uS, T2_wakeup, T2_gt_1_0_mS, T2_gt_1_2_mS;reg [2:0] chirp_cnt;reg chirp_cnt_clr, chirp_cnt_inc;reg chirp_cnt_is_6;reg resume_req_s1;reg resume_req_s;/////////////////////////////////////////////////////////////////////// Misc Logic//always @(posedge clk) drive_k <= drive_k_d;assign SuspendM = (usb_suspend & !resume_req_s) | (LineState == 2'b10);always @(posedge clk) resume_req_s1 <= resume_req;always @(posedge clk) resume_req_s <= resume_req_s1;// ---------------------------------------------------------// USB State/Operation Mode JK Flopsalways @(posedge clk) if(mode_set_fs) mode_hs <= 1'b0; else if(mode_set_hs) mode_hs <= 1'b1;always @(posedge clk) if(suspend_clr) usb_suspend <= 1'b0; else if(suspend_set) usb_suspend <= 1'b1;always @(posedge clk) if(attached_clr) usb_attached <= 1'b0; else if(attached_set) usb_attached <= 1'b1;always @(posedge clk) if(fs_term_off) TermSel <= 1'b0; else if(fs_term_on) TermSel <= 1'b1;always @(posedge clk) if(xcv_set_fs) XcvSelect <= 1'b1; else if(xcv_set_hs) XcvSelect <= 1'b0;always @(posedge clk) if(bit_stuff_off) OpMode <= 2'b10; else if(bit_stuff_on) OpMode <= 2'b00;always @(posedge clk) usb_reset <= usb_reset_d;// ---------------------------------------------------------// Line State Detectoralways @(posedge clk) line_state_r <= LineState;assign ls_se0 = (line_state_r == 2'b00);assign ls_j = (line_state_r == 2'b01);assign ls_k = (line_state_r == 2'b10);assign ls_se1 = (line_state_r == 2'b11);assign ls_idle = mode_hs ? ls_se0 : ls_j;// Idle Detection// Idle Has to persist for at least two cycles in a roe in the// same state to recognizedalways @(posedge clk) ls_idle_r <= ls_idle;assign idle_long_set = ls_idle & ls_idle_r;assign idle_long_clr = !ls_idle & !ls_idle_r;`ifdef USBF_ASYNC_RESETalways @(posedge clk or negedge rst)`elsealways @(posedge clk)`endif if(!rst) idle_long <= 1'b0; else if(idle_long_clr) idle_long <= 1'b0; else if(idle_long_set) idle_long <= 1'b1;// Detect Signals for two cycles ina row before making a transaction ...always @(posedge clk) ls_k_r <= ls_k;always @(posedge clk) ls_j_r <= ls_j;always @(posedge clk) ls_se0_r <= ls_se0;assign k_long = ls_k & ls_k_r;assign j_long = ls_j & ls_j_r;assign se0_long = ls_se0 & ls_se0_r;/////////////////////////////////////////////////////////////////////// Counters//// ---------------------------------------------------------// idle Counter// Pre-Scaler// Generates a 0.25 uS Count Enable (ps_cnt_clr)always @(posedge clk) if(!idle_long || idle_cnt_clr || ps_cnt_clr) ps_cnt <= 4'd0; else ps_cnt <= ps_cnt + 4'd1;always @(posedge clk) // Clear the pre-scaler in 250 nS intervals ps_cnt_clr <= (ps_cnt == `USBF_T1_PS_250_NS);// Count uSalways @(posedge clk) if(!idle_long || idle_cnt1_clr || idle_cnt_clr) idle_cnt1 <= 8'h0; else if(!T1_gt_5_0_mS && ps_cnt_clr) idle_cnt1 <= idle_cnt1_next;always @(posedge clk) idle_cnt1_next <= idle_cnt1 + 8'h1;always @(posedge clk) // Clear the uS counter every 62.5 uS idle_cnt1_clr <= idle_cnt1 == `USBF_T1_C_62_5_US;always @(posedge clk) // Greater Than 2.5uS (Actual Time will be T0+2.75uS) T1_gt_2_5_uS <= !idle_cnt_clr & (idle_cnt1 > `USBF_T1_C_2_5_US);always @(posedge clk) // Smaller Than 3 mS (Actual Time will be 0-2.9375mS) T1_st_3_0_mS <= !idle_cnt_clr & (idle_cnt1 < `USBF_T1_C_3_0_MS);always @(posedge clk) // Greater Than 3 mS (Actual Time will be T0+3.0625mS) T1_gt_3_0_mS <= !idle_cnt_clr & (idle_cnt1 > `USBF_T1_C_3_0_MS);always @(posedge clk) // Greater Than 3.125 mS (Actual Time will be T0+3.1875uS) T1_gt_3_125_mS <= !idle_cnt_clr & (idle_cnt1 > `USBF_T1_C_3_125_MS);always @(posedge clk) // Greater Than 3.125 mS (Actual Time will be T0+3.1875uS) T1_gt_5_0_mS <= !idle_cnt_clr & (idle_cnt1 > `USBF_T1_C_5_MS);// ---------------------------------------------------------// Misc Events Counter// Pre-scaler - 2.5uSalways @(posedge clk) if(me_cnt_clr || me_ps_2_5_us) me_ps <= 8'h0; else me_ps <= me_ps + 8'h1;always @(posedge clk) // Generate a pulse every 2.5 uS me_ps_2_5_us <= (me_ps == `USBF_T2_C_2_5_US);// Second Pre-scaler - 0.5mSalways @(posedge clk) if(me_cnt_clr || me_ps2_0_5_ms ) me_ps2 <= 8'h0; else if(me_ps_2_5_us) me_ps2 <= me_ps2 + 8'h1;always @(posedge clk) // Generate a pulse every 0.5 mS me_ps2_0_5_ms <= (me_ps2 == `USBF_T2_C_0_5_MS) & !me_ps2_0_5_ms;// final misc Counteralways @(posedge clk) if(me_cnt_clr) me_cnt <= 8'h0; else if(!me_cnt_100_ms && me_ps2_0_5_ms) me_cnt <= me_cnt + 8'h1;always @(posedge clk) // Indicate when 100uS have passed T2_gt_100_uS <= !me_cnt_clr & (me_ps2 > `USBF_T2_C_100_US); // Actual Time: 102.5 uSalways @(posedge clk) // Indicate when wakeup period has passed T2_wakeup <= !me_cnt_clr & (me_cnt > `USBF_T2_C_WAKEUP);always @(posedge clk) // Indicate when 1 mS has passed T2_gt_1_0_mS <= !me_cnt_clr & (me_cnt > `USBF_T2_C_1_0_MS); // Actual Time: 1.5 mSalways @(posedge clk) // Indicate when 1.2 mS has passed T2_gt_1_2_mS <= !me_cnt_clr & (me_cnt > `USBF_T2_C_1_2_MS); // Actual Time: 1.5 mSalways @(posedge clk) // Generate a pulse after 100 mS me_cnt_100_ms <= !me_cnt_clr & (me_cnt == `USBF_T2_C_100_MS); // Actual Time: 100 mS// ---------------------------------------------------------// Chirp Counteralways @(posedge clk) if(chirp_cnt_clr) chirp_cnt <= 3'h0; else if(chirp_cnt_inc) chirp_cnt <= chirp_cnt + 3'h1;always @(posedge clk) chirp_cnt_is_6 <= (chirp_cnt == 3'h6);`ifdef USBF_ASYNC_RESETalways @(posedge clk or negedge rst)`elsealways @(posedge clk)`endif if(!rst) state <= POR; //复位后的初始状态 else if(usb_vbus) state <= POR; //POR表示上电/复位状态 else state <= next_state;always @(state or mode_hs or idle_long or resume_req_s or me_cnt_100_ms or j_long or k_long or se0_long or ls_se0 or T1_gt_2_5_uS or T1_st_3_0_mS or T1_gt_3_0_mS or T1_gt_5_0_mS or T2_gt_100_uS or T2_wakeup or T2_gt_1_0_mS or T2_gt_1_2_mS or chirp_cnt_is_6) begin next_state = state; // 定义状态机的状态初值 mode_set_hs = 1'b0; //高速模式 mode_set_fs = 1'b0; //全速模式 suspend_set = 1'b0; //挂起状态标志 suspend_clr = 1'b0; //挂起清除 attached_set = 1'b0; //设备连接上节点 attached_clr = 1'b0; //设备断开连接 usb_reset_d = 1'b0; //芯片复位 fs_term_on = 1'b0; //高速通信模式开启状态 fs_term_off = 1'b0; //高速通信模式关闭状态 xcv_set_hs = 1'b0; //通信接口的高速模式 xcv_set_fs = 1'b0; //通信接口的全速模式 bit_stuff_on = 1'b0; bit_stuff_off = 1'b0; idle_cnt_clr = 1'b0; //空闲计数器清除标志 me_cnt_clr = 1'b0; //存储器接口计数器清除标志 drive_k_d = 1'b0; //强制输出 chirp_cnt_clr = 1'b0; //脉冲计数器复位标志 chirp_cnt_inc = 1'b0; //脉冲计数器加1标志 case(state) POR: //初值状态是上电/复位状态 begin //各状态、控制信号的更新 me_cnt_clr = 1'b1; xcv_set_fs = 1'b1; fs_term_on = 1'b1; mode_set_fs = 1'b1; attached_clr = 1'b1; bit_stuff_on = 1'b0; suspend_clr = 1'b1; next_state = ATTACH; //下一状态:器件连接上节点 end NORMAL: //常规操作状态 begin if(!mode_hs && T1_gt_2_5_uS && T1_st_3_0_mS && !idle_long) begin me_cnt_clr = 1'b1; //若等待超时,计数器清零 next_state = RESET; //下一状态:复位 end else if(!mode_hs && T1_gt_3_0_mS) begin idle_cnt_clr = 1'b1; suspend_set = 1'b1; next_state = SUSPEND; //下一状态:挂起 end else if(mode_hs && T1_gt_3_0_mS) begin //转换至全速模式,并判定芯片处在复位或挂起状态 me_cnt_clr = 1'b1; xcv_set_fs = 1'b1; fs_term_on = 1'b1; next_state = RES_SUSP; //下一状态:复位/挂起 end end RES_SUSP: //判定当前的真实状态:复位或挂起? begin //芯片工作在全速模式下,等待100us if(T2_gt_100_uS && se0_long) //等待100us后, begin me_cnt_clr = 1'b1; next_state = RESET; //下一状态:复位 end else if(T2_gt_100_uS && j_long) //等待100us后, begin idle_cnt_clr = 1'b1; suspend_set = 1'b1; next_state = SUSPEND; //下一状态:挂起 end end SUSPEND: //芯片处在挂起状态 begin if(T1_gt_2_5_uS && se0_long) //等待2.5us begin suspend_clr = 1'b1; //挂起清除 me_cnt_clr = 1'b1; next_state = RESET; //进入到复位状态 end else if(k_long) //如果出现恢复请求,则进入到恢复状态 next_state = RESUME; else if(T1_gt_5_0_mS && resume_req_s) //若等待了5ms,且收到恢复请求信号 next_state = RESUME_REQUEST; end RESUME: //芯片进入到恢复状态 begin suspend_clr = 1'b1; if(ls_se0) begin if(mode_hs) begin //转换至高速模式 xcv_set_hs = 1'b1; fs_term_off = 1'b1; end bit_stuff_on = 1'b1; //允许比特填充 me_cnt_clr = 1'b1; next_state = RESUME_WAIT; //恢复等待 end end RESUME_WAIT: //芯片进入到恢复等待状态后,重新进入正常工作状态 begin if(T2_gt_100_uS) next_state = NORMAL; end RESUME_REQUEST: //芯片恢复请求状态 begin suspend_clr = 1'b1; if(T2_wakeup) //等待芯片内部的唤起信号 begin fs_term_on = 1'b1; //转换至全速模式下的数据通信停止操作 bit_stuff_off = 1'b1; //屏蔽比特填充 me_cnt_clr = 1'b1; next_state = RESUME_SIG; //芯片进入到恢复信号等待状态 end end RESUME_SIG: //芯片收到了恢复信号 begin drive_k_d = 1'b1; //器件在1~1.5ms期间启动 if(T2_gt_1_0_mS) //1.5ms后,芯片自动进入到恢复状态 next_state = RESUME; end ATTACH: //设备连接到节点上 begin idle_cnt_clr = 1'b1; //计数空闲时间长度 if(me_cnt_100_ms) begin attached_set = 1'b1; next_state = NORMAL; //芯片进入到正常操作的状态 end end RESET: //芯片进入到复位状态 begin usb_reset_d = 1'b1; //USB芯片复位 xcv_set_hs = 1'b1; //将外部数据收发转换至高速模式 fs_term_on = 1'b1; //开启全速通信停止 mode_set_fs = 1'b1; //芯片的通信模式改为全速模式 bit_stuff_off = 1'b1; //不允许比特填充 if(T2_gt_1_0_mS) begin me_cnt_clr = 1'b1; next_state = SPEED_NEG; //通信速率判定 end end SPEED_NEG: //通信速率判定 begin drive_k_d = 1'b1; chirp_cnt_clr = 1'b1; if(T2_gt_1_2_mS) next_state = SPEED_NEG_K; end SPEED_NEG_K: begin if(chirp_cnt_is_6) next_state = SPEED_NEG_HS; else begin if(k_long) begin chirp_cnt_inc = 1'b1; next_state = SPEED_NEG_J; end if(se0_long) next_state = SPEED_NEG_FS; end end SPEED_NEG_J: begin if(chirp_cnt_is_6) next_state = SPEED_NEG_HS; else begin if(j_long) begin chirp_cnt_inc = 1'b1; next_state = SPEED_NEG_K; end if(se0_long) next_state = SPEED_NEG_FS; end end SPEED_NEG_HS: //高速通信 begin bit_stuff_on = 1'b1; //允许比特填充 xcv_set_hs = 1'b1; //外部数据收发转换至高速模式 fs_term_off = 1'b1; //关闭全速停止操作 mode_set_hs = 1'b1; //芯片变为高速模式 if(se0_long) next_state = NORMAL; end SPEED_NEG_FS: begin bit_stuff_on = 1'b1; //允许比特填充 xcv_set_fs = 1'b1; //外部数据收发转换至全速模式 fs_term_on = 1'b1; //关闭全速停止操作 mode_set_fs = 1'b1; //芯片变为全速模式 next_state = NORMAL; end endcase endendmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -