?? 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 + -