瀏覽代碼

usb: don't remove "empty" or "last" while a packet is in progress

If we have signalled "empty" or "last", stick to it; apparently
otherwise we get yet another opportunity for data loss.

Clean up the *.qsf files since Quartus likes to mess with them; now
the real content is all in include files.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
H. Peter Anvin 2 年之前
父節點
當前提交
bddbff2298
共有 27 個文件被更改,包括 87 次插入80 次删除
  1. 二進制
      esp32/output/max80.ino.bin
  2. 43 35
      fpga/dcpktfifo.sv
  3. 二進制
      fpga/output/bypass.rbf.gz
  4. 二進制
      fpga/output/bypass.rpd.gz
  5. 二進制
      fpga/output/bypass.sof
  6. 二進制
      fpga/output/bypass.svf.gz
  7. 二進制
      fpga/output/bypass.xsvf.gz
  8. 二進制
      fpga/output/max80.fw
  9. 二進制
      fpga/output/v1.fw
  10. 二進制
      fpga/output/v1.jic
  11. 二進制
      fpga/output/v1.rbf.gz
  12. 二進制
      fpga/output/v1.rpd.gz
  13. 二進制
      fpga/output/v1.sof
  14. 二進制
      fpga/output/v1.svf.gz
  15. 二進制
      fpga/output/v1.xsvf.gz
  16. 二進制
      fpga/output/v2.fw
  17. 二進制
      fpga/output/v2.jic
  18. 二進制
      fpga/output/v2.rbf.gz
  19. 二進制
      fpga/output/v2.rpd.gz
  20. 二進制
      fpga/output/v2.sof
  21. 二進制
      fpga/output/v2.svf.gz
  22. 二進制
      fpga/output/v2.xsvf.gz
  23. 8 9
      fpga/usb/usb_serial/src_v/usb_cdc_core.sv
  24. 5 23
      fpga/v1.qsf
  25. 22 0
      fpga/v1_main.qsf
  26. 5 13
      fpga/v2.qsf
  27. 4 0
      fpga/v2_main.qsf

二進制
esp32/output/max80.ino.bin


+ 43 - 35
fpga/dcpktfifo.sv

@@ -5,20 +5,21 @@
 //
 
 // Parametric synchronous RAM module, dual clock,
-// one read and one write port; output data registered
+// one read and one write port; output data not
+// registered
 module dcqram
 #(
   parameter wbits,		// log2(size in words)
   parameter width = 8
 )
    (
-    input  wclk,
-    input  wstb,
-    input  [wbits-1:0] waddr,
-    input  [width-1:0] wdata,
+    input	       wclk,
+    input	       wstb,
+    input [wbits-1:0]  waddr,
+    input [width-1:0]  wdata,
 
-    input  rclk,
-    input  [wbits-1:0] raddr,
+    input	       rclk,
+    input [wbits-1:0]  raddr,
     output [width-1:0] rdata
     );
 
@@ -32,15 +33,11 @@ module dcqram
        mem[waddr] <= wdata;
 
    reg [wbits-1:0]     raddr_q;
-   reg [width-1:0]     rdata_q;
 
-   assign rdata = rdata_q;
+   assign rdata = mem[raddr_q];
 
    always @(posedge rclk)
-     begin
-	raddr_q <= raddr;
-	rdata_q <= mem[raddr_q];
-     end
+     raddr_q <= raddr;
 endmodule // dcqram
 
 module dcpktfifo
@@ -70,6 +67,8 @@ module dcpktfifo
     output reg [wbits-1:0] rnavail,
     output reg		   rempty,
     output reg		   rlast,
+    output reg		   remptyh, // Cleared only on abort/commit
+    output reg		   rlasth,  // Cleared only on abort/commit
     output reg		   rfull
     );
 
@@ -116,34 +115,34 @@ module dcpktfifo
    wire		    rabort_w  = rtrans ? rabort : 1'b0;
    wire [wbits-1:0] rcaddr_w  = rtrans ? rcaddr : rtaddr;
 
-   wire		    rstb_w    = rstb & ~rempty;
-   wire [wbits-1:0] rnused    = r_wcaddr - (rtaddr + rstb_w);
+   wire		    rstb_w = rstb & ~rempty;
+
+   wire [wbits-1:0] rtaddr_next = (rabort_w & ~rcommit_w)
+		    ? rcaddr : rtaddr + rstb_w;
+   wire [wbits-1:0] rnused_w    = r_wcaddr - rtaddr_next;
 
    always @(negedge rst_n or posedge rclk)
      if (~rst_n)
        begin
-	  rtaddr  <= 'b0;
-	  rcaddr  <= 'b0;
-	  rnavail <= 'b0;
-	  rempty  <= 1'b1;
-	  rlast   <= 1'b1;
-	  rfull   <= 1'b0;
+	  rtaddr   <= 'b0;
+	  rcaddr   <= 'b0;
+	  rnavail  <= 'b0;
+	  rempty   <= 1'b1;
+	  rlast    <= 1'b1;
+	  rfull    <= 1'b0;
        end
      else
        begin
-	  if (rabort_w)
-	    rtaddr <= rcaddr_w;
-	  else
-	    begin
-	       rtaddr <= rtaddr + rstb_w;
-	       if (rcommit_w)
-		 rcaddr <= rtaddr + rstb_w;
-	    end // else: !if(rabort_w)
-
-	  rnavail <= rnused;
-	  rempty  <= ~|rnused;
-	  rlast   <= rnused < 2;
-	  rfull   <= &rnused;
+	  rtaddr <= rtaddr_next;
+	  if (rcommit_w)
+	    rcaddr <= rtaddr_next;
+
+	  rnavail <= rnused_w;
+	  rempty  <= ~|rnused_w;
+	  remptyh <= ~|rnused_w | (remptyh & ~(rcommit_w|rabort_w));
+	  rlast   <= ~|rnused_w[wbits-1:1];
+	  rlasth  <= ~|rnused_w[wbits-1:1] | (rlasth & ~(rcommit_w|rabort_w));
+	  rfull   <= &rnused_w;
        end // else: !if(~rst_n)
 
    // Address pointer synchronizers.
@@ -175,8 +174,17 @@ module dcpktfifo
 	.wdata (wdata),
 
 	.rclk  (rclk),
-	.raddr (rtaddr),
+	.raddr (rtaddr_next),
 	.rdata (rdata)
 	);
 
+   // For debugging
+   (* preserve, noprune *) reg wflag;
+   always @(posedge wclk)
+     wflag <= (wflag | wstb_w) & ~(wcommit|wabort);
+
+   (* preserve, noprune *) reg rflag;
+   always @(posedge rclk)
+     rflag <= (rflag | rstb) & ~(rcommit|rabort);
+
 endmodule // dcpktfifo

二進制
fpga/output/bypass.rbf.gz


二進制
fpga/output/bypass.rpd.gz


二進制
fpga/output/bypass.sof


二進制
fpga/output/bypass.svf.gz


二進制
fpga/output/bypass.xsvf.gz


二進制
fpga/output/max80.fw


二進制
fpga/output/v1.fw


二進制
fpga/output/v1.jic


二進制
fpga/output/v1.rbf.gz


二進制
fpga/output/v1.rpd.gz


二進制
fpga/output/v1.sof


二進制
fpga/output/v1.svf.gz


二進制
fpga/output/v1.xsvf.gz


二進制
fpga/output/v2.fw


二進制
fpga/output/v2.jic


二進制
fpga/output/v2.rbf.gz


二進制
fpga/output/v2.rpd.gz


二進制
fpga/output/v2.sof


二進制
fpga/output/v2.svf.gz


二進制
fpga/output/v2.xsvf.gz


+ 8 - 9
fpga/usb/usb_serial/src_v/usb_cdc_core.sv

@@ -128,8 +128,8 @@ module usb_cdc_channel
    wire		        txfull;
    wire [fifo_bits-1:0]  txfree;
    wire [water_bits-1:0] txused_msb = ~txfree[fifo_bits-1:fifo_bits-water_bits];
-   wire		        inport_empty_w;
    wire		        inport_last_w;
+   wire			inport_empty_w;
    reg			flush_tx_data;
 
    dcpktfifo #(
@@ -155,9 +155,8 @@ module usb_cdc_channel
 	   .rstb    ( data_ep.u.tx_data_accept ),
 	   .rcommit ( data_ep.u.tx_ack ),
 	   .rabort  ( data_ep.u.tx_init ),
-	   .rnavail ( ),
-	   .rempty  ( inport_empty_w ),
-	   .rlast   ( inport_last_w )
+	   .remptyh ( inport_empty_w ),
+	   .rlasth  ( inport_last_w )
 	   );
 
    // If RTS is not asserted, suspend data transmit
@@ -172,7 +171,6 @@ module usb_cdc_channel
    wire		        rxempty;
    reg			flush_rx_data;
    wire [fifo_bits-1:0] rxused;
-   wire			rxfull = &rxused;
    wire [water_bits-1:0] rxused_msb = rxused[fifo_bits-1:fifo_bits-water_bits];
    wire [fifo_bits-1:0] outport_free_w;
    wire			outport_full_w;
@@ -194,6 +192,7 @@ module usb_cdc_channel
 	   .rclk    ( sys_clk ),
 	   .rdata   ( rdata_fifo ),
 	   .rstb    ( ~fifo_access & fifo_read_q ),
+	   .rfull   ( rxfull ),
 	   .rempty  ( rxempty ),
 	   .rnavail ( rxused ),
 
@@ -306,13 +305,13 @@ module usb_cdc_channel
 
    tri0 [15:0] status;
    assign status[0]     = txempty;
-   assign status[1]     = txempty | (txused_msb <= water_ctl[3:4-water_bits]);
-   assign status[2]     = txfull  | (txused_msb >= water_ctl[7:8-water_bits]);
+   assign status[1]     = txused_msb <= water_ctl[3:4-water_bits];
+   assign status[2]     = txused_msb >= water_ctl[7:8-water_bits];
    assign status[3]     = txfull;
 
    assign status[4]     = rxempty;
-   assign status[5]     = rxempty | (rxused_msb <= water_ctl[11:12-water_bits]);
-   assign status[6]     = rxfull  | (rxused_msb >= water_ctl[15:16-water_bits]);
+   assign status[5]     = rxused_msb <= water_ctl[11:12-water_bits];
+   assign status[6]     = rxused_msb >= water_ctl[15:16-water_bits];
    assign status[7]     = rxfull;
 
    assign status[8]     = had_rxdata[1];

+ 5 - 23
fpga/v1.qsf

@@ -1,25 +1,7 @@
 # -*- tcl -*-
+#
+# This file contains no real content, so when Quartus messes it up it
+# can just be reset.
+#
 
-set_global_assignment -name TOP_LEVEL_ENTITY v1
-set_global_assignment -name SOURCE_FILE v1.pins
-set_global_assignment -name SYSTEMVERILOG_FILE v1.sv
-set_global_assignment -name VERILOG_FILE ip/pll2_48.v
-set_global_assignment -name QIP_FILE ip/pll2_48.qip
-set_global_assignment -name SOURCE_FILE "output/v1.jic.cof"
-
-set_global_assignment -name SOURCE_TCL_SCRIPT_FILE max80.qsf
-
-set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to gpio[1]
-set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to gpio[3]
-set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to gpio[5]
-set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_clk
-set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_inp_n[1]
-set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_a[13]
-set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_a[2]
-set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_a[6]
-set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_a[0]
-set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_a[1]
-set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to tty_txd
-
-# Quartus insists on this line...
-set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
+set_global_assignment -name SOURCE_TCL_SCRIPT_FILE v1_main.qsf

+ 22 - 0
fpga/v1_main.qsf

@@ -0,0 +1,22 @@
+# -*- tcl -*-
+
+set_global_assignment -name TOP_LEVEL_ENTITY v1
+set_global_assignment -name SOURCE_FILE v1.pins
+set_global_assignment -name SYSTEMVERILOG_FILE v1.sv
+set_global_assignment -name VERILOG_FILE ip/pll2_48.v
+set_global_assignment -name QIP_FILE ip/pll2_48.qip
+set_global_assignment -name SOURCE_FILE "output/v1.jic.cof"
+
+set_global_assignment -name SOURCE_TCL_SCRIPT_FILE max80.qsf
+
+set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to gpio[1]
+set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to gpio[3]
+set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to gpio[5]
+set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_clk
+set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_inp_n[1]
+set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_a[13]
+set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_a[2]
+set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_a[6]
+set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_a[0]
+set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to abc_a[1]
+set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to tty_txd

+ 5 - 13
fpga/v2.qsf

@@ -1,15 +1,7 @@
 # -*- tcl -*-
+#
+# This file contains no real content, so when Quartus messes it up it
+# can just be reset.
+#
 
-set_global_assignment -name TOP_LEVEL_ENTITY v2
-set_global_assignment -name SOURCE_FILE output/v2.jic.cof
-set_global_assignment -name SYSTEMVERILOG_FILE v2.sv
-
-set_global_assignment -name SOURCE_TCL_SCRIPT_FILE v2_common.qsf
-set_global_assignment -name SOURCE_FILE v2.pins
-set_global_assignment -name VERILOG_FILE ip/pll2_16.v
-set_global_assignment -name QIP_FILE ip/pll2_16.qip
-set_global_assignment -name VERILOG_INCLUDE_FILE v2.vh
-set_global_assignment -name SOURCE_TCL_SCRIPT_FILE max80.qsf
-
-# Quartus insists on this line...
-set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
+set_global_assignment -name SOURCE_TCL_SCRIPT_FILE v2_main.qsf

+ 4 - 0
fpga/v2_common.qsf → fpga/v2_main.qsf

@@ -1,5 +1,9 @@
 # -*- tcl -*-
 
+set_global_assignment -name TOP_LEVEL_ENTITY v2
+set_global_assignment -name SOURCE_FILE output/v2.jic.cof
+set_global_assignment -name SYSTEMVERILOG_FILE v2.sv
+
 set_global_assignment -name SOURCE_FILE v2.pins
 set_global_assignment -name VERILOG_FILE ip/pll2_16.v
 set_global_assignment -name QIP_FILE ip/pll2_16.qip