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
== 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
== 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,
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