📄 usbf_utmi_ls.v
字号:
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.5uS
always @(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.5mS
always @(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 Counter
always @(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 uS
always @(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 mS
always @(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 mS
always @(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 Counter
always @(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);
///////////////////////////////////////////////////////////////////
//
// Main State Machine
//
`ifdef USBF_ASYNC_RESET
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
if(!rst) state <= POR;
else
if(usb_vbus) state <= 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; // Default don't change 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;
case(state) // synopsys full_case parallel_case
POR: // Power On/Reset
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: // Normal Operation
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 // Switch to FS mode, and decide
// if it's a RESET or SUSPEND
me_cnt_clr = 1'b1;
xcv_set_fs = 1'b1;
fs_term_on = 1'b1;
next_state = RES_SUSP;
end
end
RES_SUSP: // Decide if it's a Reset or Suspend Signaling
begin // We are now in FS mode, wait 100uS first
if(T2_gt_100_uS && se0_long)
begin
me_cnt_clr = 1'b1;
next_state = RESET;
end
else
if(T2_gt_100_uS && j_long)
begin
idle_cnt_clr = 1'b1;
suspend_set = 1'b1;
next_state = SUSPEND;
end
end
SUSPEND: // In Suspend
begin
if(T1_gt_2_5_uS && se0_long)
begin
suspend_clr = 1'b1;
me_cnt_clr = 1'b1;
next_state = RESET;
end
else
if(k_long) // Start Resuming
next_state = RESUME;
else
if(T1_gt_5_0_mS && resume_req_s)
next_state = RESUME_REQUEST;
end
RESUME:
begin
suspend_clr = 1'b1;
if(ls_se0)
begin
if(mode_hs)
begin // Switch Back to HS mode
xcv_set_hs = 1'b1;
fs_term_off = 1'b1;
end
bit_stuff_on = 1'b1; // Enable Bit Stuffing and NRZI encoding
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: // Function Resume Request
begin
suspend_clr = 1'b1;
// Wait for internal wake up
if(T2_wakeup)
begin
fs_term_on = 1'b1; // Switch Termination to Full Speed
bit_stuff_off = 1'b1; // disable Bit Stuffing and NRZI encoding
me_cnt_clr = 1'b1;
next_state = RESUME_SIG;
end
end
RESUME_SIG: // Signal resume
begin
// Drive Resume ('K') for 1-15 mS
drive_k_d = 1'b1;
// Stop driving after 1.5 mS
if(T2_gt_1_0_mS) next_state = RESUME;
end
ATTACH: // Attach To USB Detected
begin
idle_cnt_clr = 1'b1;
if(me_cnt_100_ms)
//if(me_cnt_100_ms && j_long)
begin
attached_set = 1'b1;
next_state = NORMAL;
end
/*
if(me_cnt_100_ms && se0_long)
begin
attached_set = 1'b1;
me_cnt_clr = 1'b1;
next_state = RESET;
end
*/
end
RESET: // In Reset
begin
usb_reset_d = 1'b1; // Assert Internal USB Reset
xcv_set_hs = 1'b1; // Switch xcvr to HS mode
fs_term_on = 1'b1; // Turn FS termination On
mode_set_fs = 1'b1; // Change mode to FS
bit_stuff_off = 1'b1; // disable Bit Stuffing and NRZI encoding
// Get out of reset after 1.5 mS
if(T2_gt_1_0_mS)
begin
me_cnt_clr = 1'b1;
next_state = SPEED_NEG;
end
end
SPEED_NEG: // Speed Negotiation
begin
drive_k_d = 1'b1;
chirp_cnt_clr = 1'b1;
// Start looking for 'K' after 1.5 mS
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; // Enable Bit Stuffing and NRZI encoding
xcv_set_hs = 1'b1; // Switch xcvr to HS mode
fs_term_off = 1'b1; // Turn FS termination Off
mode_set_hs = 1'b1; // Change mode to HS
if(se0_long) next_state = NORMAL;
end
SPEED_NEG_FS:
begin
bit_stuff_on = 1'b1; // Enable Bit Stuffing and NRZI encoding
xcv_set_fs = 1'b1; // Switch xcvr to FS mode
fs_term_on = 1'b1; // Turn FS termination On
mode_set_fs = 1'b1; // Change mode to FS
next_state = NORMAL;
end
endcase
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -