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

Reply via email to