add Button.ship
[fleet.git] / ships / Debug.ship
index a2076f1..e912f92 100644 (file)
@@ -1,15 +1,11 @@
 ship: Debug
 
 == Ports ===========================================================
-data  in:   in
+data  in:     in
+dockless out: out
 
-percolate up:   root_in_r   1
-percolate down: root_in_a   1
-percolate up:   root_in_d   8
 percolate down: uart_in     1
 percolate up:   uart_out    1
-percolate up:   uart_rts    1
-percolate down: uart_cts    1
 percolate up:   rst_out     1
 percolate down: rst_in      1
 
@@ -17,6 +13,9 @@ percolate down: rst_in      1
 
 == TeX ==============================================================
 
+percolate up:   uart_rts    1
+percolate down: uart_cts    1
+
 This ship is used for debugging.  It has only one port, {\tt in}.
 Programmers should send debug report values to this port.  How such
 values are reported back to the programmer doing the debugging is left
@@ -41,35 +40,41 @@ public void service() {
 == FPGA ==============================================================
 
   wire break_i;
-  reg break_last;
-  reg send_k;                initial send_k = 0;
+  reg send_k;
+  initial send_k = 0;
 
-  wire       data_to_host_full;
-  wire       data_to_host_write_enable;
-  wire [7:0] data_to_host;
+  reg [`WORDWIDTH-1:0] data_to_host_full_word;
+  reg [7:0] count_in;
+  reg [7:0] count_out;
+  reg [49:0] out_d;
+  assign out_d_ = out_d;
 
+  wire       data_to_host_full;
+  reg  [7:0] data_to_host;
   wire       data_to_fleet_empty;
-  wire       data_to_fleet_read_enable;
   wire [7:0] data_to_fleet;
-
-  reg we;
-  reg re;
-  reg [7:0] data_to_host_r;
-  assign data_to_host = data_to_host_r;
-
-  wire ser_rst;
-  reg ser_rst_r;
-  initial ser_rst_r = 0;
-  assign ser_rst = (rst_in & ser_rst_r);
+  reg        data_to_host_write_enable;
+  reg        data_to_fleet_read_enable;
+  reg  [7:0] force_reset;
 
   wire sio_ce;
   wire sio_ce_x4;
 
   wire break;
-  assign rst_out = rst_in && !break;
-
-  sasc_brg sasc_brg(clk, ser_rst, 3, 65, sio_ce, sio_ce_x4);
-  sasc_top sasc_top(clk, ser_rst,
+  wire uart_cts;
+  assign uart_cts = 0;
+  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 => 215,1
+  // using a 100Mhz clock,
+  //   100Mhz / 38400hz * 4 = 651.039 => 215+2,3 => 215,3
+  // using a 100Mhz clock, 115200baud
+  //   100Mhz / 115200hz * 4 = 217.013 => 215+2,1 => 215,1
+//  sasc_brg sasc_brg(clk, !rst_in, 215, 3, sio_ce, sio_ce_x4);
+  sasc_brg sasc_brg(clk, !rst_in, 215, 1, sio_ce, sio_ce_x4);
+  sasc_top sasc_top(clk, !rst_in,
                     uart_in,
                     uart_out,
                     uart_cts,
@@ -85,108 +90,128 @@ 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 data_to_host_write_enable_reg;
-   reg data_to_fleet_read_enable_reg;
-
-   reg [`WORDWIDTH-1:0] root_out_d;
-   reg root_out_r; initial root_out_r = 0;
-   wire root_out_a;
-
-   reg root_out_a_reg;
-   reg root_in_r_reg;
-   reg [7:0] root_in_d_reg;
-   initial root_in_r_reg = 0;
-   initial root_in_d_reg = 0;
-   initial root_out_a_reg = 0;
-   initial data_to_fleet_read_enable_reg = 0;
-   initial data_to_host_write_enable_reg = 0;
-
-   assign root_out_a                = root_out_a_reg;                
-   assign root_in_r                 = root_in_r_reg;
-   assign data_to_fleet_read_enable = data_to_fleet_read_enable_reg;
-   assign data_to_host_write_enable = data_to_host_write_enable_reg;
-   assign root_in_d                 = root_in_d_reg;
+   reg [16:0] credits;
 
    // fpga -> host
-   always @(posedge clk)
-   begin
-     if (break_i) begin
-       root_out_a_reg = 0;
-       data_to_host_write_enable_reg <= 0;
-
-     end else if (break_done) begin
-       data_to_host_write_enable_reg <= 1;
-       data_to_host_r <= 111;
-       send_k <= 1;
-     end else if (send_k) begin
-       data_to_host_write_enable_reg <= 1;
-       data_to_host_r <= 107;
-       send_k <= 0;
-
-
-     end else if (root_out_r && !root_out_a_reg && !data_to_host_full) begin
-       data_to_host_write_enable_reg <= 1;
-       data_to_host_r <= root_out_d[7:0];
-       root_out_a_reg = 1;
-     end else if (root_out_a_reg && !root_out_r) begin
-       data_to_host_write_enable_reg <= 0;
-       root_out_a_reg = 0;
+   always @(posedge clk) begin
+     if (rst_in /* || break */) begin
+       count_in    <= 0;
+       count_out   <= 0;
+       force_reset <= 0;
+       credits      = 0;
+       `reset
      end else begin
-       data_to_host_write_enable_reg <= 0;
-     end
-   end
-
-   // host -> fpga
-   always @(posedge clk)
-   begin
-     ser_rst_r <= 1;
-     if (break_i) begin
-       root_in_r_reg <= 0;
-       root_in_d_reg <= 0;
-       data_to_fleet_read_enable_reg <= 0;
-     end else
-  
-     if (!data_to_fleet_empty && !root_in_r_reg && !root_in_a) begin
-        root_in_r_reg <= 1;
-        root_in_d_reg <= data_to_fleet;
-        data_to_fleet_read_enable_reg <= 1;
-     end else begin
-       data_to_fleet_read_enable_reg <= 0;
-        if (root_in_a) begin
-          root_in_r_reg <= 0;
-        end
-     end
-   end
-
-  reg [7:0] count;
-  initial count = 0;
-
-  always @(posedge clk) begin
-    if (!rst) begin
-      `reset
-    end else begin
-      `flush
-      `cleanup
-      if (root_out_r && root_out_a) root_out_r <= 0;
-      if (`in_full && !root_out_r && !root_out_a && count==0) begin
-        `drain_in
-        root_out_d <= in_d;
-        root_out_r <= 1;
-        count <= 5;
-      end
-      if (count!=0 && !root_out_r && !root_out_a) begin
-        count <= count-1;
-        root_out_r <= 1;
-        root_out_d <= (root_out_d >> 8);
-      end
+
+       `cleanup
+
+       // fpga -> host
+       data_to_host_write_enable <= 0;
+       if (force_reset == 1) begin
+         force_reset <= 0;
+         data_to_host_write_enable <= 1;
+         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 && 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 && !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