DDR2: remember to check if out_empty before attempting an operation
[fleet.git] / ships / Debug.ship
index 0fbb9e0..7b4c7b6 100644 (file)
@@ -40,7 +40,6 @@ public void service() {
 == FPGA ==============================================================
 
   wire break_i;
-  reg break_last;
   reg send_k;
   initial send_k = 0;
 
@@ -56,6 +55,7 @@ public void service() {
   wire [7:0] data_to_fleet;
   reg        data_to_host_write_enable;
   reg        data_to_fleet_read_enable;
+  reg  [7:0] force_reset;
 
   wire sio_ce;
   wire sio_ce_x4;
@@ -63,12 +63,14 @@ public void service() {
   wire break;
   wire uart_cts;
   assign uart_cts = 0;
-  assign rst_out = rst_in || break;
+  assign rst_out = rst_in || (force_reset!=0) || break;
 
   // fst=3 means clock divider is 3+2=5 for a 50Mhz clock => 10Mhz
   // using a 33Mhz clock,
-  //   33.333Mhz / 38400hz * 4 = 217.013 => 215+2,1
-  sasc_brg sasc_brg(clk, !rst_in, 215, 1, sio_ce, sio_ce_x4);
+  //   33.333Mhz / 38400hz * 4 = 217.013 => 215+2,1 => 215,1
+  // using a 100Mhz clock,
+  //   100Mhz / 38400hz * 4 = 651.039 => 215+2,3 => 215,3
+  sasc_brg sasc_brg(clk, !rst_in, 215, 3, sio_ce, sio_ce_x4);
   sasc_top sasc_top(clk, !rst_in,
                     uart_in,
                     uart_out,
@@ -85,16 +87,15 @@ public void service() {
                     break,
                     break_i);
 
-   // break and break are _active high_
-   always @(posedge clk) break_last <= break;
-   assign break_i    =  break && !break_last;
-   assign break_done = !break &&  break_last;
+   reg [16:0] credits;
 
    // fpga -> host
    always @(posedge clk) begin
-     if (rst) begin
-       count_in  <= 0;
-       count_out <= 0;
+     if (rst_in || break) begin
+       count_in    <= 0;
+       count_out   <= 0;
+       force_reset <= 0;
+       credits      = 0;
        `reset
      end else begin
 
@@ -102,42 +103,112 @@ public void service() {
 
        // fpga -> host
        data_to_host_write_enable <= 0;
-       if (break_i) begin
-       end else if (break_done) begin
+       if (force_reset == 1) begin
+         force_reset <= 0;
          data_to_host_write_enable <= 1;
-         data_to_host <= 111;
-         send_k <= 1;
-       end else if (send_k) begin
-         data_to_host_write_enable <= 1;
-         data_to_host <= 107;
-         send_k <= 0;
+         credits = 0;
+         count_in  <= 0;
+         count_out <= 0;
+         `reset
+       end else if (force_reset != 0) begin
+         force_reset <= force_reset-1;
        end else if (count_out==0 && `in_full) begin
          `drain_in
          data_to_host_full_word <= in_d;
          count_out <= 8;
-       end else if (count_out!=0 && !data_to_host_full && !data_to_host_write_enable) begin
+       end else if (count_out!=0 && !data_to_host_full && !data_to_host_write_enable && credits!=0) begin
          data_to_host <= { 2'b0, data_to_host_full_word[5:0] };
          data_to_host_full_word <= (data_to_host_full_word >> 6);
          data_to_host_write_enable <= 1;
          count_out <= count_out-1;
+         credits = credits - 1;
        end
 
        // host -> fpga
        data_to_fleet_read_enable <= 0;
-       if (!data_to_fleet_empty && `out_empty && !data_to_fleet_read_enable) begin
-         out_d <= { out_d[43:0], data_to_fleet[5:0] };
-         data_to_fleet_read_enable <= 1;
-         if (count_in==9) begin
-           count_in <= 0;
-           `fill_out
-         end else begin
-           count_in <= count_in+1;
-         end
+       if (!data_to_fleet_empty && !data_to_fleet_read_enable) begin
+
+         // Note: if the switch fabric refuses to accept a new item,
+         // we can get deadlocked in a state where sending a reset
+         // code (2'b11) won't have any effect.  Probably need to go
+         // back to using the break signal.
+
+           // command 0: data
+         if (data_to_fleet[7:6] == 2'b00 && `out_empty) begin
+           data_to_fleet_read_enable <= 1;
+           out_d <= { out_d[43:0], data_to_fleet[5:0] };
+           if (count_in==9) begin
+             count_in <= 0;
+             `fill_out
+           end else begin
+             count_in <= count_in+1;
+           end
+
+           // command 1: flow control credit
+         end else if (data_to_fleet[7:6] == 2'b01) begin
+           data_to_fleet_read_enable <= 1;
+           credits = credits + data_to_fleet[5:0];
+
+/*
+         // uncommenting this requires changing data_to_host_write_enable
+         // to a blocking assignment, and seems to cause data loss whenever
+         // more than four items are in flight.
+           // command 2: echo
+         end else if (data_to_fleet[7:6] == 2'b10 && !data_to_host_full && !data_to_host_write_enable) begin
+           data_to_fleet_read_enable <= 1;
+           data_to_host <= data_to_fleet;
+           data_to_host_write_enable = 1;
+*/
+
+           // command 3: reset (and echo back reset code)
+         end else if (data_to_fleet[7:6] == 2'b11) begin
+           data_to_fleet_read_enable <= 1;
+           data_to_host <= data_to_fleet;
+           force_reset <= 255;
+
+         end 
+
        end
 
     end
   end
 
+== UCF =================================================================
+
+Net clk_pin LOC=AH15;
+Net clk_pin  PERIOD = 10 ns HIGH 50%;  # 100Mhz
+
+# 33mhz clock
+#Net clk_pin LOC=AH17;
+#Net clk_pin TNM_NET = clk_pin;
+#TIMESPEC TS_clk_pin = PERIOD clk_pin 30 ns HIGH 50%;  # 33Mhz
+
+Net rst_pin LOC=E9;
+Net rst_pin PULLUP;
+Net rst_pin TIG;
+
+#Net uart_cts LOC=G6;
+#Net uart_cts IOSTANDARD = LVCMOS33;
+#Net uart_cts TIG;
+
+#Net uart_rts LOC=F6;
+#Net uart_rts IOSTANDARD = LVCMOS33;
+#Net uart_rts TIG;
+
+Net uart_in LOC=AG15;
+#Net uart_in IOSTANDARD = LVCMOS33;
+Net uart_in TIG;
+Net uart_in PULLUP;
+
+Net uart_out LOC=AG20;
+#Net uart_out IOSTANDARD = LVCMOS33;
+Net uart_out TIG;
+Net uart_out PULLUP;
+
+
+
+
+
 == Test ================================================================
 #expect 25