Increase the USB core frequency by 50%. While the TX side needs just simple clock enable tweaks, the RX side needs additional states in the DPLL and EOP state machine.
The two DPLL main transitions paths (1,3,2,0) and (5,7,6,4) are both extended by two states - (9,a) and (d,e). The state encoding has been chosen to match the dpll_ce logic (eg. bit 1 is 0 for clock low and bit 1 is 1 for clock high). The EOP SM just need two additional SE0 sample states. For further information please refer to the USB whitepaper Designing a robust USB serial interface engine Signed-off-by: Michael Walle <mich...@walle.cc> --- boards/milkymist-one/rtl/system.v | 2 +- cores/softusb/rtl/softusb_rx.v | 46 +++++++++++++++++++++++++------------ cores/softusb/rtl/softusb_tx.v | 12 ++++++--- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/boards/milkymist-one/rtl/system.v b/boards/milkymist-one/rtl/system.v index df9839e..d2087a2 100644 --- a/boards/milkymist-one/rtl/system.v +++ b/boards/milkymist-one/rtl/system.v @@ -215,7 +215,7 @@ wire clkgen720_fb; PLL_BASE #( .COMPENSATION("INTERNAL"), .BANDWIDTH("OPTIMIZED"), - .CLKOUT0_DIVIDE(15), // 48 MHz + .CLKOUT0_DIVIDE(10), // 72 MHz .CLKOUT1_DIVIDE(9), // 80 MHz .CLKOUT2_DIVIDE(9), // 80 MHz, 180deg phase shift .CLKOUT3_DIVIDE(1), diff --git a/cores/softusb/rtl/softusb_rx.v b/cores/softusb/rtl/softusb_rx.v index 9867469..261dc42 100644 --- a/cores/softusb/rtl/softusb_rx.v +++ b/cores/softusb/rtl/softusb_rx.v @@ -87,16 +87,28 @@ always @(*) begin end 3'd3: begin if(se0) - eop_next_state = 3'd3; + eop_next_state = 3'd4; + else + eop_next_state = 3'd0; + end + 3'd4: begin + if(se0) + eop_next_state = 3'd5; + else + eop_next_state = 3'd0; + end + 3'd5: begin + if(se0) + eop_next_state = 3'd5; else begin if(rx_corrected) begin eop_detected = 1'b1; eop_next_state = 3'd0; end else - eop_next_state = 3'd4; + eop_next_state = 3'd6; end end - 3'd4: begin + 3'd6: begin if(rx_corrected) eop_detected = 1'b1; eop_next_state = 3'd0; @@ -128,16 +140,20 @@ end always @(*) begin dpll_next_state = dpll_state; case(dpll_state) - 4'h5: dpll_next_state = 4'h7; - 4'h7: if( rx_corrected) dpll_next_state = 4'h6; else dpll_next_state = 4'hb; + 4'h5: dpll_next_state = 4'hd; + 4'hd: dpll_next_state = 4'h7; + 4'h7: if( rx_corrected) dpll_next_state = 4'he; else dpll_next_state = 4'hb; + 4'he: dpll_next_state = 4'h6; 4'h6: if( rx_corrected) dpll_next_state = 4'h4; else dpll_next_state = 4'h1; 4'h4: if( rx_corrected) dpll_next_state = 4'h5; else dpll_next_state = 4'h1; - 4'h1: dpll_next_state = 4'h3; - 4'h3: if(~rx_corrected) dpll_next_state = 4'h2; else dpll_next_state = 4'hf; + 4'h1: dpll_next_state = 4'h9; + 4'h9: dpll_next_state = 4'h3; + 4'h3: if(~rx_corrected) dpll_next_state = 4'ha; else dpll_next_state = 4'hf; + 4'ha: dpll_next_state = 4'h2; 4'h2: if(~rx_corrected) dpll_next_state = 4'h0; else dpll_next_state = 4'h5; 4'h0: if(~rx_corrected) dpll_next_state = 4'h1; else dpll_next_state = 4'h5; - 4'hb: dpll_next_state = 4'h2; - 4'hf: dpll_next_state = 4'h6; + 4'hb: dpll_next_state = 4'ha; + 4'hf: dpll_next_state = 4'he; endcase end @@ -214,21 +230,21 @@ parameter K5 = 4'h8; reg [3:0] fs_state; reg [3:0] fs_next_state; -reg [5:0] fs_timeout_counter; +reg [6:0] fs_timeout_counter; reg fs_timeout; always @(posedge usb_clk) begin if(rxreset|eop_detected) begin - fs_timeout_counter <= 6'd0; + fs_timeout_counter <= 7'd0; fs_timeout <= 1'b0; end else begin if((fs_state != fs_next_state) | (fs_state == FS_IDLE)) - fs_timeout_counter <= 6'd0; + fs_timeout_counter <= 7'd0; else - fs_timeout_counter <= fs_timeout_counter + 6'd1; + fs_timeout_counter <= fs_timeout_counter + 7'd1; if(low_speed) - fs_timeout <= fs_timeout_counter == 6'd63; + fs_timeout <= fs_timeout_counter == 7'd95; else - fs_timeout <= fs_timeout_counter == 6'd7; + fs_timeout <= fs_timeout_counter == 7'd11; end end diff --git a/cores/softusb/rtl/softusb_tx.v b/cores/softusb/rtl/softusb_tx.v index edb809d..11b4b11 100644 --- a/cores/softusb/rtl/softusb_tx.v +++ b/cores/softusb/rtl/softusb_tx.v @@ -43,14 +43,18 @@ end /* Clock 'divider' */ reg gce; /* global clock enable */ -reg [4:0] gce_counter; +reg [5:0] gce_counter; always @(posedge usb_clk) begin if(usb_rst) begin gce <= 1'b0; - gce_counter <= 5'd0; + gce_counter <= 6'd0; end else begin - gce <= low_speed ? (gce_counter == 5'd31) : (gce_counter[1:0] == 2'd3); - gce_counter <= gce_counter + 5'd1; + gce <= 1'b0; + gce_counter <= gce_counter + 6'd1; + if((low_speed & gce_counter == 6'd47) | (~low_speed & gce_counter == 6'd5)) begin + gce <= 1'b1; + gce_counter <= 6'd0; + end end end -- 1.7.2.5 _______________________________________________ http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org IRC: #milkymist@Freenode