ML509: use urjtag's fjmem block as the debug controller (JtagConnectedFpga).
[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 percolate up:    gpio_led_c   1
35 percolate up:    gpio_led_e   1
36 percolate up:    gpio_led_n   1
37 percolate up:    gpio_led_s   1
38 percolate up:    gpio_led_w   1
39 percolate down:  gpio_dip_sw1 1
40
41
42 == TeX ==============================================================
43
44 This ship is used for debugging.  It has only one port, {\tt in}.
45 Programmers should send debug report values to this port.  How such
46 values are reported back to the programmer doing the debugging is left
47 unspecified.
48
49 \subsection*{To Do}
50
51 Provide an {\tt inOp} port and use opcode ports \cite{am25} to
52 effectively allow multiple independent ``debug streams''
53
54 Provide a way to programmatically read back the output of the debug
55 ship.
56
57 == Fleeterpreter ====================================================
58 public void service() {
59   if (box_in.dataReadyForShip())
60     ((Interpreter)getFleet()).debug(new BitVector(37).set(box_in.removeDataForShip()));
61 }
62
63 == FPGA:Bee2 ==============================================================
64
65    wire                        CCLK_int;
66    
67    wire [0:7]                  D_I;
68    wire [0:7]                  D_O;
69    wire [0:7]                  D_T;
70
71    wire                        User_Rst;
72
73    wire [7:0] write_data;
74    wire       write_enable;
75    wire       write_full;
76
77    wire [7:0] read_data;
78    wire       read_empty;
79    wire       read_enable;
80
81    // IO buffers
82    OBUF obuf_cclk( .I( CCLK_int ),     .O( CCLK )         );
83    IOBUF iobuf_d0( .I( D_O[0] ),    .IO( D[0] ),     .O( D_I[0] ),    .T( D_T[0] )    );
84    IOBUF iobuf_d1( .I( D_O[1] ),    .IO( D[1] ),     .O( D_I[1] ),    .T( D_T[1] )    );
85    IOBUF iobuf_d2( .I( D_O[2] ),    .IO( D[2] ),     .O( D_I[2] ),    .T( D_T[2] )    );
86    IOBUF iobuf_d3( .I( D_O[3] ),    .IO( D[3] ),     .O( D_I[3] ),    .T( D_T[3] )    );
87    IOBUF iobuf_d4( .I( D_O[4] ),    .IO( D[4] ),     .O( D_I[4] ),    .T( D_T[4] )    );
88    IOBUF iobuf_d5( .I( D_O[5] ),    .IO( D[5] ),     .O( D_I[5] ),    .T( D_T[5] )    );
89    IOBUF iobuf_d6( .I( D_O[6] ),    .IO( D[6] ),     .O( D_I[6] ),    .T( D_T[6] )    );
90    IOBUF iobuf_d7( .I( D_O[7] ),    .IO( D[7] ),     .O( D_I[7] ),    .T( D_T[7] )    );
91
92    // Clock buffer and reset
93    wire clk_fast;
94    wire clk_half;
95    wire clk_fb;
96    IBUFGDS_LVDS_25 diff_usrclk_buf( .I( Clkin_p ),   .IB( Clkin_m ),  .O( clk_fast )  );
97
98    wire clkdiv0_unbuffered;
99    wire clk0_unbuffered;
100    wire clk0_fb;
101 //   BUFG bufg1 (.I(clkdiv0_unbuffered),  .O(clk_out));
102 //   BUFG bufg1 (.I(clk_fast),  .O(clk_out));
103 //   BUFG bufg1 (.I(clk0_unbuffered),  .O(clk_out));
104    BUFG bufg2 (.I(clk0_unbuffered),     .O(clk0_fb));
105
106
107 reg foo;
108 reg foo2;
109    BUFG bufg1 (.I(foo2),  .O(clk_out));
110
111 always @(posedge clk_fast) begin
112   if (foo)
113     foo2 <= ~foo2;
114   foo <= ~foo;
115 end
116
117    DCM
118     #(
119       .CLKIN_PERIOD          (10.0),
120       .DUTY_CYCLE_CORRECTION ("TRUE"),
121       .DLL_FREQUENCY_MODE    ("LOW"),
122       .STARTUP_WAIT          ("FALSE")
123      ) ddr2_dcm (
124       .CLKIN     (clk_fast),
125       .CLKFB     (clk0_fb),
126       .CLK0      (clk0_unbuffered),
127       .RST       (User_Rst)
128      );
129
130 //   BUFG GBUF_FOR_MUX_CLOCK (.I(clk_half), .O(clk_out));
131 //   BUFG GBUF_FOR_MUX_CLOCK (.I(clk_fast), .O(clk_out));
132
133
134    wire [0:3] rstr;
135    FD rstr0( .D( 1'b0 ),         .Q( rstr[0] ),      .C( clk )   );   defparam rstr0.INIT = 1'b1;
136    FD rstr1( .D( rstr[0] ),      .Q( rstr[1] ),      .C( clk )   );   defparam rstr1.INIT = 1'b1;
137    FD rstr2( .D( rstr[1] ),      .Q( rstr[2] ),      .C( clk )   );   defparam rstr2.INIT = 1'b1;
138    FD rstr3( .D( rstr[2] ),      .Q( rstr[3] ),      .C( clk )   );   defparam rstr3.INIT = 1'b1;
139    assign   User_Rst = |rstr;
140
141    user_fifo test_fifo( 
142                         .WrFifo_Din( write_data ),
143                         .WrFifo_WrEn( write_enable ),
144                         .WrFifo_Full( write_full ),
145                         .WrFifo_WrCnt(  ),
146                         .RdFifo_Dout( read_data ),
147                         .RdFifo_RdEn( read_enable ),
148                         .RdFifo_Empty( read_empty ),
149                         .RdFifo_RdCnt(  ),
150                         .User_Rst( User_Rst ),
151                         .User_Clk( clk ),
152                         .Sys_Rst( User_Rst ),
153                         .Sys_Clk( clk_fast ),
154                         .D_I( D_I ),
155                         .D_O( D_O ),
156                         .D_T( D_T ),                         
157                         .RDWR_B( RDWR_B ),
158                         .CS_B( CS_B ),
159                         .INIT_B( INIT_B ),
160                         .CCLK( CCLK_int )
161                         );
162
163    wire       data_to_host_full;
164    reg  [7:0] data_to_host;
165    wire       data_to_fleet_empty;
166    wire [7:0] data_to_fleet;
167    reg        data_to_host_write_enable;
168    reg        data_to_fleet_read_enable;
169
170    assign data_to_fleet = read_data;
171    assign read_enable = data_to_fleet_read_enable;
172    assign write_enable = data_to_host_write_enable;
173    assign write_data = data_to_host;
174    assign data_to_fleet_empty = read_empty;
175    assign data_to_host_full = write_full;
176
177    initial data_to_fleet_read_enable = 1;
178    initial data_to_host_write_enable = 0;
179
180    reg  [7:0] force_reset;
181    assign rst_out = User_Rst || (force_reset!=0);
182
183    /// Common //////////////////////////////////////////////////////////////////////////////
184
185    reg send_k;
186    initial send_k = 0;
187
188    reg [`WORDWIDTH-1:0] data_to_host_full_word;
189    reg [7:0] count_in;
190    reg [7:0] count_out;
191    reg [49:0] out_d;
192    assign out_d_ = out_d;
193
194    reg [16:0] credits;
195
196    // fpga -> host
197    always @(posedge clk) begin
198      if (/*rst_in*/User_Rst) begin
199        count_in    <= 0;
200        count_out   <= 0;
201        force_reset <= 0;
202        credits      = 0;
203        `reset
204      end else begin
205
206        `cleanup
207
208        // fpga -> host
209        data_to_host_write_enable <= 0;
210        if (force_reset == 1) begin
211          force_reset <= 0;
212          //data_to_host_write_enable <= 1;
213          credits = 0;
214          count_in  <= 0;
215          count_out <= 0;
216          `reset
217        end else if (force_reset != 0) begin
218          force_reset <= force_reset-1;
219        end else if (count_out==0 && `in_full) begin
220          `drain_in
221          data_to_host_full_word <= in_d;
222          count_out <= 8;
223        end else if (count_out!=0 && !data_to_host_full && !data_to_host_write_enable && credits!=0) begin
224          data_to_host <= { 2'b0, data_to_host_full_word[5:0] };
225          data_to_host_full_word <= (data_to_host_full_word >> 6);
226          data_to_host_write_enable <= 1;
227          count_out <= count_out-1;
228          credits = credits - 1;
229        end
230
231        // host -> fpga
232        data_to_fleet_read_enable <= 0;
233        if (!data_to_fleet_empty && !data_to_fleet_read_enable) begin
234
235          // Note: if the switch fabric refuses to accept a new item,
236          // we can get deadlocked in a state where sending a reset
237          // code (2'b11) won't have any effect.  Probably need to go
238          // back to using the break signal.
239
240            // command 0: data
241          if (data_to_fleet[7:6] == 2'b00 && `out_empty) begin
242            data_to_fleet_read_enable <= 1;
243            out_d <= { out_d[43:0], data_to_fleet[5:0] };
244            if (count_in==9) begin
245              count_in <= 0;
246              `fill_out
247            end else begin
248              count_in <= count_in+1;
249            end
250
251            // command 1: flow control credit
252          end else if (data_to_fleet[7:6] == 2'b01) begin
253            data_to_fleet_read_enable <= 1;
254            credits = credits + data_to_fleet[5:0];
255
256            // command 3: reset (and echo back reset code)
257          end else if (data_to_fleet[7:6] == 2'b11) begin
258            data_to_fleet_read_enable <= 1;
259            data_to_host <= data_to_fleet;
260            force_reset <= 255;
261
262          end 
263
264        end
265
266     end
267   end
268
269
270 == UCF:Bee2 =================================================================
271
272 ######################################
273 ## System clock pins
274 ######################################
275
276 NET Clkin_p             LOC = AP21 | IOSTANDARD = LVDS_25;
277 NET Clkin_m             LOC = AN21 | IOSTANDARD = LVDS_25;
278
279 NET rst_in              LOC = H4   | IOSTANDARD = LVCMOS18;
280
281 NET clk_out             PERIOD=50MHz;
282 //NET clk_out             PERIOD=100MHz;
283 //NET clk_fast            PERIOD=100MHz;
284 NET Clkin_p             PERIOD=100MHz;
285 NET Clkin_m             PERIOD=100MHz;
286
287 ######################################
288 ## SelectMAP interface pins
289 ######################################
290
291 NET D<0>                LOC = AU9  | IOSTANDARD = LVCMOS25;
292 NET D<1>                LOC = AV9  | IOSTANDARD = LVCMOS25;
293 NET D<2>                LOC = AY9  | IOSTANDARD = LVCMOS25;
294 NET D<3>                LOC = AW9  | IOSTANDARD = LVCMOS25;
295 NET D<4>                LOC = AW34 | IOSTANDARD = LVCMOS25;
296 NET D<5>                LOC = AY34 | IOSTANDARD = LVCMOS25;
297 NET D<6>                LOC = AV34 | IOSTANDARD = LVCMOS25;
298 NET D<7>                LOC = AU34 | IOSTANDARD = LVCMOS25;
299
300 NET RDWR_B              LOC = AR34 | IOSTANDARD = LVCMOS25;
301 NET CS_B                LOC = AT34 | IOSTANDARD = LVCMOS25;
302 NET INIT_B              LOC = AR9  | IOSTANDARD = LVCMOS25;
303 NET CCLK                LOC = C14  | IOSTANDARD = LVCMOS25;
304
305 #Net rst_pin LOC=E9;
306 #Net rst_pin PULLUP;
307 #Net rst_pin TIG;
308
309 == FPGA:ML509 ==============================================================
310
311   assign gpio_led_n = 0;
312   assign gpio_led_s = 0;
313   assign gpio_led_e = 1;
314   assign gpio_led_w = 1;
315
316   wire tdo;
317   wire update;
318   wire shift;
319   wire reset;
320   wire tdi;
321   wire sel;
322   wire drck; 
323   BSCAN_VIRTEX5 
324     #(.JTAG_CHAIN(1))
325     bscanvirtex(.TDO(tdo), 
326                 .UPDATE(update), 
327                 .SHIFT(shift), 
328                 .RESET(reset), 
329                 .TDI(tdi), 
330                 .SEL(sel), 
331                 .DRCK(drck));
332
333   wire [9:0] dout;
334   reg  [9:0] dout_r;
335   reg  [9:0] din;
336   wire write_o;
337   wire read_o;
338   wire strobe_o;
339   wire ack_i;
340   assign ack_i = 1;
341
342   fjmem_core
343    my_fjmem_core(
344       .clkdr_i  (drck),
345       .trst_i   (reset),
346       .shift_i  (shift),
347       .update_i (update),
348       .tdi_i    (tdi),
349       .tdo_o    (tdo),
350       .clk_i    (clk),
351       .res_i    (rst),
352
353       .strobe_o (strobe_o),
354       .read_o   (read_o),
355       .write_o  (write_o),
356       .ack_i    (ack_i),
357       .cs_o     (),
358       .addr_o   (),
359       .din_i    (din),
360       .dout_o   (dout)
361     );
362
363   wire strobe_write;
364   assign strobe_write = strobe_o & write_o;
365
366   wire strobe_read;
367   assign strobe_read = strobe_o & read_o;
368
369   reg strobe_write_was_high;
370   initial strobe_write_was_high = 0;
371
372   wire break_i;
373   reg send_k;
374   initial send_k = 0;
375
376   reg [`WORDWIDTH-1:0] data_to_host_full_word;
377   reg [7:0] count_in;
378   reg [7:0] count_out;
379   reg [49:0] out_d;
380   assign out_d_ = out_d;
381
382   wire       data_to_host_full;
383   reg  [7:0] data_to_host;
384   wire       data_to_fleet_empty;
385   wire [7:0] data_to_fleet;
386   reg        data_to_host_write_enable;
387   reg        data_to_fleet_read_enable;
388   reg  [7:0] force_reset;
389
390   reg        data_to_host_full_bit;
391   
392   assign clk_out = clk_pin;
393
394   wire sio_ce;
395   wire sio_ce_x4;
396
397   wire break;
398   wire uart_cts;
399   assign uart_cts = 0;
400   assign rst_out = rst_in || (force_reset!=0) /* || break */;
401
402   // fst=3 means clock divider is 3+2=5 for a 50Mhz clock => 10Mhz
403   // using a 33Mhz clock,
404   //   33.333Mhz / 38400hz * 4 = 217.013 => 215+2,1 => 215,1
405   // using a 100Mhz clock,
406   //   100Mhz / 38400hz * 4 = 651.039 => 215+2,3 => 215,3
407   // using a 100Mhz clock, 115200baud
408   //   100Mhz / 115200hz * 4 = 217.013 => 215+2,1 => 215,1
409 //  sasc_brg sasc_brg(clk, !rst_in, 215, 3, sio_ce, sio_ce_x4);
410   sasc_brg sasc_brg(clk, !rst_in, 215, 1, sio_ce, sio_ce_x4);
411   sasc_top sasc_top(clk, !rst_in,
412                     uart_in,
413                     uart_out,
414                     uart_cts,
415                     uart_rts, 
416                     sio_ce,
417                     sio_ce_x4,
418                     data_to_host,
419                     data_to_fleet,
420                     data_to_fleet_read_enable,
421                     data_to_host_write_enable,
422                     data_to_host_full,
423                     data_to_fleet_empty,
424                     break,
425                     break_i);
426
427    reg [16:0] credits;
428
429    // fpga -> host
430    always @(posedge clk) begin
431      if (rst_in /* || break */) begin
432        count_in    <= 0;
433        count_out   <= 0;
434        force_reset <= 0;
435        credits      = 0;
436        data_to_host_full_bit <= 0;
437        `reset
438      end else begin
439
440        `cleanup
441
442        if (strobe_read) begin
443          din <= { 1'b0, data_to_host_full_bit, data_to_host };
444          data_to_host_full_bit <= 0;
445        end
446
447        // fpga -> host
448        data_to_host_write_enable <= 0;
449        if (force_reset == 1) begin
450          force_reset <= 0;
451          data_to_host_write_enable <= 1;
452          credits = 0;
453          count_in  <= 0;
454          count_out <= 0;
455          `reset
456        end else if (force_reset != 0) begin
457          force_reset <= force_reset-1;
458        end else if (count_out==0 && `in_full && data_to_host_full_bit==0) begin
459          `drain_in
460          data_to_host_full_word <= in_d;
461          count_out <= 8;
462        end else if (count_out!=0 && !data_to_host_full && !data_to_host_write_enable && credits!=0 && data_to_host_full_bit==0) begin
463          data_to_host <= { 2'b0, data_to_host_full_word[5:0] };
464          data_to_host_full_word <= (data_to_host_full_word >> 6);
465          data_to_host_full_bit <= 1;
466          count_out <= count_out-1;
467          credits = credits - 1;
468        end
469
470        // host -> fpga
471        data_to_fleet_read_enable <= 0;
472
473        if (!strobe_write && strobe_write_was_high) begin
474           strobe_write_was_high <= 0;
475
476        end else if (strobe_write && !strobe_write_was_high && (force_reset == 0)) begin
477          strobe_write_was_high <= 1;
478            // command 0: data
479          if (dout[7:6] == 2'b00 && `out_empty) begin
480            out_d <= { out_d[43:0], dout[5:0] };
481            if (count_in==9) begin
482              count_in <= 0;
483              `fill_out
484            end else begin
485              count_in <= count_in+1;
486            end
487
488            // command 1: flow control credit
489          end else if (dout[7:6] == 2'b01) begin
490            credits = credits + dout[5:0];
491
492            // command 3: reset (and echo back reset code)
493          end else if (dout[7:6] == 2'b11) begin
494            data_to_host <= dout[7:0];
495            data_to_host_full_bit <= 1;
496            force_reset <= 255;
497
498          end 
499
500        end else
501        if (!data_to_fleet_empty && !data_to_fleet_read_enable) begin
502
503          // Note: if the switch fabric refuses to accept a new item,
504          // we can get deadlocked in a state where sending a reset
505          // code (2'b11) won't have any effect.  Probably need to go
506          // back to using the break signal.
507
508            // command 0: data
509          if (data_to_fleet[7:6] == 2'b00 && `out_empty) begin
510            data_to_fleet_read_enable <= 1;
511            out_d <= { out_d[43:0], data_to_fleet[5:0] };
512            if (count_in==9) begin
513              count_in <= 0;
514              `fill_out
515            end else begin
516              count_in <= count_in+1;
517            end
518
519            // command 1: flow control credit
520          end else if (data_to_fleet[7:6] == 2'b01) begin
521            data_to_fleet_read_enable <= 1;
522            credits = credits + data_to_fleet[5:0];
523
524 /*
525          // uncommenting this requires changing data_to_host_write_enable
526          // to a blocking assignment, and seems to cause data loss whenever
527          // more than four items are in flight.
528            // command 2: echo
529          end else if (data_to_fleet[7:6] == 2'b10 && !data_to_host_full && !data_to_host_write_enable) begin
530            data_to_fleet_read_enable <= 1;
531            data_to_host <= data_to_fleet;
532            data_to_host_write_enable = 1;
533 */
534
535            // command 3: reset (and echo back reset code)
536          end else if (data_to_fleet[7:6] == 2'b11) begin
537            data_to_fleet_read_enable <= 1;
538            data_to_host <= data_to_fleet;
539            force_reset <= 255;
540
541          end 
542
543        end
544
545     end
546   end
547
548 == UCF:ML509 =================================================================
549
550 Net clk_pin LOC=AH15;
551 Net clk_pin  PERIOD = 10 ns HIGH 50%;  # 100Mhz
552
553 # 33mhz clock
554 #Net clk_pin LOC=AH17;
555 #Net clk_pin TNM_NET = clk_pin;
556 #TIMESPEC TS_clk_pin = PERIOD clk_pin 30 ns HIGH 50%;  # 33Mhz
557
558 Net rst_pin LOC=E9;
559 Net rst_pin PULLUP;
560 Net rst_pin TIG;
561
562 #Net uart_cts LOC=G6;
563 #Net uart_cts IOSTANDARD = LVCMOS33;
564 #Net uart_cts TIG;
565
566 #Net uart_rts LOC=F6;
567 #Net uart_rts IOSTANDARD = LVCMOS33;
568 #Net uart_rts TIG;
569
570 Net uart_in LOC=AG15;
571 #Net uart_in IOSTANDARD = LVCMOS33;
572 Net uart_in TIG;
573 Net uart_in PULLUP;
574
575 Net uart_out LOC=AG20;
576 #Net uart_out IOSTANDARD = LVCMOS33;
577 Net uart_out TIG;
578 Net uart_out PULLUP;
579
580 NET  gpio_led_c           LOC="E8";    # Bank 20, Vcco=3.3V, DCI using 49.9 ohm resistors
581 NET  gpio_led_e           LOC="AG23";  # Bank 2, Vcco=3.3V
582 NET  gpio_led_n           LOC="AF13";  # Bank 2, Vcco=3.3V
583 NET  gpio_led_s           LOC="AG12";  # Bank 2, Vcco=3.3V
584 NET  gpio_led_w           LOC="AF23";  # Bank 2, Vcco=3.3V
585 NET  gpio_dip_sw1         LOC="U25";   # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
586
587
588 == Test ================================================================
589 #expect 25
590
591 #ship debug : Debug
592
593 debug.in:
594   set word= 25;
595   deliver;
596
597 == Contributors =========================================================
598 Adam Megacz <megacz@cs.berkeley.edu>