rewrite Debug.ship to include both ML509 and Bee2 support
[fleet.git] / ships / Debug.ship
1 ship: Debug
2
3 == Ports:Interpreter ===========================================================
4 data  in:     in
5 dockless out: out
6
7 == Ports:Bee2 ===========================================================
8 data  in:     in
9 dockless out: out
10
11 percolate down:  Clkin_p          1
12 percolate down:  Clkin_m          1
13 percolate up:    clk_out          1
14 percolate inout: D                8
15 percolate down:  RDWR_B           1
16 percolate down:  CS_B             1
17 percolate up:    CCLK             1
18 percolate up:    INIT_B           1
19
20 percolate up:    rst_out          1
21 percolate down:  rst_in           1
22
23 == Ports:ML509 ===========================================================
24 data  in:     in
25 dockless out: out
26
27 percolate down: uart_in     1
28 percolate up:   uart_out    1
29 percolate up:   rst_out     1
30 percolate down: rst_in      1
31 percolate down: clk_pin     1
32 percolate up:   clk_out     1
33
34 == TeX ==============================================================
35
36 This ship is used for debugging.  It has only one port, {\tt in}.
37 Programmers should send debug report values to this port.  How such
38 values are reported back to the programmer doing the debugging is left
39 unspecified.
40
41 \subsection*{To Do}
42
43 Provide an {\tt inOp} port and use opcode ports \cite{am25} to
44 effectively allow multiple independent ``debug streams''
45
46 Provide a way to programmatically read back the output of the debug
47 ship.
48
49 == Fleeterpreter ====================================================
50 public void service() {
51   if (box_in.dataReadyForShip())
52     ((Interpreter)getFleet()).debug(new BitVector(37).set(box_in.removeDataForShip()));
53 }
54
55 == FPGA:Bee2 ==============================================================
56
57    wire                        CCLK_int;
58    
59    wire [0:7]                  D_I;
60    wire [0:7]                  D_O;
61    wire [0:7]                  D_T;
62
63    wire                        User_Rst;
64
65    wire [7:0] write_data;
66    wire       write_enable;
67    wire       write_full;
68
69    wire [7:0] read_data;
70    wire       read_empty;
71    wire       read_enable;
72
73    // IO buffers
74    OBUF obuf_cclk( .I( CCLK_int ),     .O( CCLK )         );
75    IOBUF iobuf_d0( .I( D_O[0] ),    .IO( D[0] ),     .O( D_I[0] ),    .T( D_T[0] )    );
76    IOBUF iobuf_d1( .I( D_O[1] ),    .IO( D[1] ),     .O( D_I[1] ),    .T( D_T[1] )    );
77    IOBUF iobuf_d2( .I( D_O[2] ),    .IO( D[2] ),     .O( D_I[2] ),    .T( D_T[2] )    );
78    IOBUF iobuf_d3( .I( D_O[3] ),    .IO( D[3] ),     .O( D_I[3] ),    .T( D_T[3] )    );
79    IOBUF iobuf_d4( .I( D_O[4] ),    .IO( D[4] ),     .O( D_I[4] ),    .T( D_T[4] )    );
80    IOBUF iobuf_d5( .I( D_O[5] ),    .IO( D[5] ),     .O( D_I[5] ),    .T( D_T[5] )    );
81    IOBUF iobuf_d6( .I( D_O[6] ),    .IO( D[6] ),     .O( D_I[6] ),    .T( D_T[6] )    );
82    IOBUF iobuf_d7( .I( D_O[7] ),    .IO( D[7] ),     .O( D_I[7] ),    .T( D_T[7] )    );
83
84    // Clock buffer and reset
85    wire clk_fast;
86    wire clk_half;
87    wire clk_fb;
88    IBUFGDS_LVDS_25 diff_usrclk_buf( .I( Clkin_p ),   .IB( Clkin_m ),  .O( clk_fast )  );
89
90    wire clkdiv0_unbuffered;
91    wire clk0_unbuffered;
92    wire clk0_fb;
93 //   BUFG bufg1 (.I(clkdiv0_unbuffered),  .O(clk_out));
94 //   BUFG bufg1 (.I(clk_fast),  .O(clk_out));
95 //   BUFG bufg1 (.I(clk0_unbuffered),  .O(clk_out));
96    BUFG bufg2 (.I(clk0_unbuffered),     .O(clk0_fb));
97
98
99 reg foo;
100 reg foo2;
101    BUFG bufg1 (.I(foo2),  .O(clk_out));
102
103 always @(posedge clk_fast) begin
104   if (foo)
105     foo2 <= ~foo2;
106   foo <= ~foo;
107 end
108
109    DCM
110     #(
111       .CLKIN_PERIOD          (10.0),
112       .DUTY_CYCLE_CORRECTION ("TRUE"),
113       .DLL_FREQUENCY_MODE    ("LOW"),
114       .STARTUP_WAIT          ("FALSE")
115      ) ddr2_dcm (
116       .CLKIN     (clk_fast),
117       .CLKFB     (clk0_fb),
118       .CLK0      (clk0_unbuffered),
119       .RST       (User_Rst)
120      );
121
122 //   BUFG GBUF_FOR_MUX_CLOCK (.I(clk_half), .O(clk_out));
123 //   BUFG GBUF_FOR_MUX_CLOCK (.I(clk_fast), .O(clk_out));
124
125
126    wire [0:3] rstr;
127    FD rstr0( .D( 1'b0 ),         .Q( rstr[0] ),      .C( clk )   );   defparam rstr0.INIT = 1'b1;
128    FD rstr1( .D( rstr[0] ),      .Q( rstr[1] ),      .C( clk )   );   defparam rstr1.INIT = 1'b1;
129    FD rstr2( .D( rstr[1] ),      .Q( rstr[2] ),      .C( clk )   );   defparam rstr2.INIT = 1'b1;
130    FD rstr3( .D( rstr[2] ),      .Q( rstr[3] ),      .C( clk )   );   defparam rstr3.INIT = 1'b1;
131    assign   User_Rst = |rstr;
132
133    user_fifo test_fifo( 
134                         .WrFifo_Din( write_data ),
135                         .WrFifo_WrEn( write_enable ),
136                         .WrFifo_Full( write_full ),
137                         .WrFifo_WrCnt(  ),
138                         .RdFifo_Dout( read_data ),
139                         .RdFifo_RdEn( read_enable ),
140                         .RdFifo_Empty( read_empty ),
141                         .RdFifo_RdCnt(  ),
142                         .User_Rst( User_Rst ),
143                         .User_Clk( clk ),
144                         .Sys_Rst( User_Rst ),
145                         .Sys_Clk( clk_fast ),
146                         .D_I( D_I ),
147                         .D_O( D_O ),
148                         .D_T( D_T ),                         
149                         .RDWR_B( RDWR_B ),
150                         .CS_B( CS_B ),
151                         .INIT_B( INIT_B ),
152                         .CCLK( CCLK_int )
153                         );
154
155    wire       data_to_host_full;
156    reg  [7:0] data_to_host;
157    wire       data_to_fleet_empty;
158    wire [7:0] data_to_fleet;
159    reg        data_to_host_write_enable;
160    reg        data_to_fleet_read_enable;
161
162    assign data_to_fleet = read_data;
163    assign read_enable = data_to_fleet_read_enable;
164    assign write_enable = data_to_host_write_enable;
165    assign write_data = data_to_host;
166    assign data_to_fleet_empty = read_empty;
167    assign data_to_host_full = write_full;
168
169    initial data_to_fleet_read_enable = 1;
170    initial data_to_host_write_enable = 0;
171
172    reg  [7:0] force_reset;
173    assign rst_out = User_Rst || (force_reset!=0);
174
175    /// Common //////////////////////////////////////////////////////////////////////////////
176
177    reg send_k;
178    initial send_k = 0;
179
180    reg [`WORDWIDTH-1:0] data_to_host_full_word;
181    reg [7:0] count_in;
182    reg [7:0] count_out;
183    reg [49:0] out_d;
184    assign out_d_ = out_d;
185
186    reg [16:0] credits;
187
188    // fpga -> host
189    always @(posedge clk) begin
190      if (/*rst_in*/User_Rst) begin
191        count_in    <= 0;
192        count_out   <= 0;
193        force_reset <= 0;
194        credits      = 0;
195        `reset
196      end else begin
197
198        `cleanup
199
200        // fpga -> host
201        data_to_host_write_enable <= 0;
202        if (force_reset == 1) begin
203          force_reset <= 0;
204          data_to_host_write_enable <= 1;
205          credits = 0;
206          count_in  <= 0;
207          count_out <= 0;
208          `reset
209        end else if (force_reset != 0) begin
210          force_reset <= force_reset-1;
211        end else if (count_out==0 && `in_full) begin
212          `drain_in
213          data_to_host_full_word <= in_d;
214          count_out <= 8;
215        end else if (count_out!=0 && !data_to_host_full && !data_to_host_write_enable && credits!=0) begin
216          data_to_host <= { 2'b0, data_to_host_full_word[5:0] };
217          data_to_host_full_word <= (data_to_host_full_word >> 6);
218          data_to_host_write_enable <= 1;
219          count_out <= count_out-1;
220          credits = credits - 1;
221        end
222
223        // host -> fpga
224        data_to_fleet_read_enable <= 0;
225        if (!data_to_fleet_empty && !data_to_fleet_read_enable) begin
226
227          // Note: if the switch fabric refuses to accept a new item,
228          // we can get deadlocked in a state where sending a reset
229          // code (2'b11) won't have any effect.  Probably need to go
230          // back to using the break signal.
231
232            // command 0: data
233          if (data_to_fleet[7:6] == 2'b00 && `out_empty) begin
234            data_to_fleet_read_enable <= 1;
235            out_d <= { out_d[43:0], data_to_fleet[5:0] };
236            if (count_in==9) begin
237              count_in <= 0;
238              `fill_out
239            end else begin
240              count_in <= count_in+1;
241            end
242
243            // command 1: flow control credit
244          end else if (data_to_fleet[7:6] == 2'b01) begin
245            data_to_fleet_read_enable <= 1;
246            credits = credits + data_to_fleet[5:0];
247
248            // command 3: reset (and echo back reset code)
249          end else if (data_to_fleet[7:6] == 2'b11) begin
250            data_to_fleet_read_enable <= 1;
251            data_to_host <= data_to_fleet;
252            force_reset <= 255;
253
254          end 
255
256        end
257
258     end
259   end
260
261
262 == UCF:Bee2 =================================================================
263
264 ######################################
265 ## System clock pins
266 ######################################
267
268 NET Clkin_p             LOC = AP21 | IOSTANDARD = LVDS_25;
269 NET Clkin_m             LOC = AN21 | IOSTANDARD = LVDS_25;
270
271 NET rst_in              LOC = H4   | IOSTANDARD = LVCMOS18;
272
273 NET clk_out             PERIOD=50MHz;
274 //NET clk_out             PERIOD=100MHz;
275 //NET clk_fast            PERIOD=100MHz;
276 NET Clkin_p             PERIOD=100MHz;
277 NET Clkin_m             PERIOD=100MHz;
278
279 ######################################
280 ## SelectMAP interface pins
281 ######################################
282
283 NET D<0>                LOC = AU9  | IOSTANDARD = LVCMOS25;
284 NET D<1>                LOC = AV9  | IOSTANDARD = LVCMOS25;
285 NET D<2>                LOC = AY9  | IOSTANDARD = LVCMOS25;
286 NET D<3>                LOC = AW9  | IOSTANDARD = LVCMOS25;
287 NET D<4>                LOC = AW34 | IOSTANDARD = LVCMOS25;
288 NET D<5>                LOC = AY34 | IOSTANDARD = LVCMOS25;
289 NET D<6>                LOC = AV34 | IOSTANDARD = LVCMOS25;
290 NET D<7>                LOC = AU34 | IOSTANDARD = LVCMOS25;
291
292 NET RDWR_B              LOC = AR34 | IOSTANDARD = LVCMOS25;
293 NET CS_B                LOC = AT34 | IOSTANDARD = LVCMOS25;
294 NET INIT_B              LOC = AR9  | IOSTANDARD = LVCMOS25;
295 NET CCLK                LOC = C14  | IOSTANDARD = LVCMOS25;
296
297 #Net rst_pin LOC=E9;
298 #Net rst_pin PULLUP;
299 #Net rst_pin TIG;
300
301 == FPGA:ML509 ==============================================================
302
303   wire break_i;
304   reg send_k;
305   initial send_k = 0;
306
307   reg [`WORDWIDTH-1:0] data_to_host_full_word;
308   reg [7:0] count_in;
309   reg [7:0] count_out;
310   reg [49:0] out_d;
311   assign out_d_ = out_d;
312
313   wire       data_to_host_full;
314   reg  [7:0] data_to_host;
315   wire       data_to_fleet_empty;
316   wire [7:0] data_to_fleet;
317   reg        data_to_host_write_enable;
318   reg        data_to_fleet_read_enable;
319   reg  [7:0] force_reset;
320
321   assign clk_out = clk_pin;
322
323   wire sio_ce;
324   wire sio_ce_x4;
325
326   wire break;
327   wire uart_cts;
328   assign uart_cts = 0;
329   assign rst_out = rst_in || (force_reset!=0) /* || break */;
330
331   // fst=3 means clock divider is 3+2=5 for a 50Mhz clock => 10Mhz
332   // using a 33Mhz clock,
333   //   33.333Mhz / 38400hz * 4 = 217.013 => 215+2,1 => 215,1
334   // using a 100Mhz clock,
335   //   100Mhz / 38400hz * 4 = 651.039 => 215+2,3 => 215,3
336   // using a 100Mhz clock, 115200baud
337   //   100Mhz / 115200hz * 4 = 217.013 => 215+2,1 => 215,1
338 //  sasc_brg sasc_brg(clk, !rst_in, 215, 3, sio_ce, sio_ce_x4);
339   sasc_brg sasc_brg(clk, !rst_in, 215, 1, sio_ce, sio_ce_x4);
340   sasc_top sasc_top(clk, !rst_in,
341                     uart_in,
342                     uart_out,
343                     uart_cts,
344                     uart_rts, 
345                     sio_ce,
346                     sio_ce_x4,
347                     data_to_host,
348                     data_to_fleet,
349                     data_to_fleet_read_enable,
350                     data_to_host_write_enable,
351                     data_to_host_full,
352                     data_to_fleet_empty,
353                     break,
354                     break_i);
355
356    reg [16:0] credits;
357
358    // fpga -> host
359    always @(posedge clk) begin
360      if (rst_in /* || break */) begin
361        count_in    <= 0;
362        count_out   <= 0;
363        force_reset <= 0;
364        credits      = 0;
365        `reset
366      end else begin
367
368        `cleanup
369
370        // fpga -> host
371        data_to_host_write_enable <= 0;
372        if (force_reset == 1) begin
373          force_reset <= 0;
374          data_to_host_write_enable <= 1;
375          credits = 0;
376          count_in  <= 0;
377          count_out <= 0;
378          `reset
379        end else if (force_reset != 0) begin
380          force_reset <= force_reset-1;
381        end else if (count_out==0 && `in_full) begin
382          `drain_in
383          data_to_host_full_word <= in_d;
384          count_out <= 8;
385        end else if (count_out!=0 && !data_to_host_full && !data_to_host_write_enable && credits!=0) begin
386          data_to_host <= { 2'b0, data_to_host_full_word[5:0] };
387          data_to_host_full_word <= (data_to_host_full_word >> 6);
388          data_to_host_write_enable <= 1;
389          count_out <= count_out-1;
390          credits = credits - 1;
391        end
392
393        // host -> fpga
394        data_to_fleet_read_enable <= 0;
395        if (!data_to_fleet_empty && !data_to_fleet_read_enable) begin
396
397          // Note: if the switch fabric refuses to accept a new item,
398          // we can get deadlocked in a state where sending a reset
399          // code (2'b11) won't have any effect.  Probably need to go
400          // back to using the break signal.
401
402            // command 0: data
403          if (data_to_fleet[7:6] == 2'b00 && `out_empty) begin
404            data_to_fleet_read_enable <= 1;
405            out_d <= { out_d[43:0], data_to_fleet[5:0] };
406            if (count_in==9) begin
407              count_in <= 0;
408              `fill_out
409            end else begin
410              count_in <= count_in+1;
411            end
412
413            // command 1: flow control credit
414          end else if (data_to_fleet[7:6] == 2'b01) begin
415            data_to_fleet_read_enable <= 1;
416            credits = credits + data_to_fleet[5:0];
417
418 /*
419          // uncommenting this requires changing data_to_host_write_enable
420          // to a blocking assignment, and seems to cause data loss whenever
421          // more than four items are in flight.
422            // command 2: echo
423          end else if (data_to_fleet[7:6] == 2'b10 && !data_to_host_full && !data_to_host_write_enable) begin
424            data_to_fleet_read_enable <= 1;
425            data_to_host <= data_to_fleet;
426            data_to_host_write_enable = 1;
427 */
428
429            // command 3: reset (and echo back reset code)
430          end else if (data_to_fleet[7:6] == 2'b11) begin
431            data_to_fleet_read_enable <= 1;
432            data_to_host <= data_to_fleet;
433            force_reset <= 255;
434
435          end 
436
437        end
438
439     end
440   end
441
442 == UCF:ML509 =================================================================
443
444 Net clk_pin LOC=AH15;
445 Net clk_pin  PERIOD = 10 ns HIGH 50%;  # 100Mhz
446
447 # 33mhz clock
448 #Net clk_pin LOC=AH17;
449 #Net clk_pin TNM_NET = clk_pin;
450 #TIMESPEC TS_clk_pin = PERIOD clk_pin 30 ns HIGH 50%;  # 33Mhz
451
452 Net rst_pin LOC=E9;
453 Net rst_pin PULLUP;
454 Net rst_pin TIG;
455
456 #Net uart_cts LOC=G6;
457 #Net uart_cts IOSTANDARD = LVCMOS33;
458 #Net uart_cts TIG;
459
460 #Net uart_rts LOC=F6;
461 #Net uart_rts IOSTANDARD = LVCMOS33;
462 #Net uart_rts TIG;
463
464 Net uart_in LOC=AG15;
465 #Net uart_in IOSTANDARD = LVCMOS33;
466 Net uart_in TIG;
467 Net uart_in PULLUP;
468
469 Net uart_out LOC=AG20;
470 #Net uart_out IOSTANDARD = LVCMOS33;
471 Net uart_out TIG;
472 Net uart_out PULLUP;
473
474
475
476
477 == Test ================================================================
478 #expect 25
479
480 #ship debug : Debug
481
482 debug.in:
483   set word= 25;
484   deliver;
485
486 == Contributors =========================================================
487 Adam Megacz <megacz@cs.berkeley.edu>