ship: Debug == Ports:Interpreter =========================================================== data in: in dockless out: out == Ports:Bee2 =========================================================== data in: in dockless out: out percolate down: Clkin_p 1 percolate down: Clkin_m 1 percolate up: clk_out 1 percolate inout: D 8 percolate down: RDWR_B 1 percolate down: CS_B 1 percolate up: CCLK 1 percolate up: INIT_B 1 percolate up: rst_out 1 percolate down: rst_in 1 == Ports:ML509 =========================================================== data in: in dockless out: out percolate down: uart_in 1 percolate up: uart_out 1 percolate up: rst_out 1 percolate down: rst_in 1 percolate down: clk_pin 1 percolate up: clk_out 1 percolate up: gpio_led_c 1 percolate up: gpio_led_e 1 percolate up: gpio_led_n 1 percolate up: gpio_led_s 1 percolate up: gpio_led_w 1 percolate down: gpio_dip_sw1 1 == TeX ============================================================== 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 unspecified. \subsection*{To Do} Provide an {\tt inOp} port and use opcode ports \cite{am25} to effectively allow multiple independent ``debug streams'' Provide a way to programmatically read back the output of the debug ship. == Fleeterpreter ==================================================== public void service() { if (box_in.dataReadyForShip()) ((Interpreter)getFleet()).debug(new BitVector(37).set(box_in.removeDataForShip())); } == FPGA:Bee2 ============================================================== wire CCLK_int; wire [0:7] D_I; wire [0:7] D_O; wire [0:7] D_T; wire User_Rst; wire [7:0] write_data; wire write_enable; wire write_full; wire [7:0] read_data; wire read_empty; wire read_enable; // IO buffers OBUF obuf_cclk( .I( CCLK_int ), .O( CCLK ) ); IOBUF iobuf_d0( .I( D_O[0] ), .IO( D[0] ), .O( D_I[0] ), .T( D_T[0] ) ); IOBUF iobuf_d1( .I( D_O[1] ), .IO( D[1] ), .O( D_I[1] ), .T( D_T[1] ) ); IOBUF iobuf_d2( .I( D_O[2] ), .IO( D[2] ), .O( D_I[2] ), .T( D_T[2] ) ); IOBUF iobuf_d3( .I( D_O[3] ), .IO( D[3] ), .O( D_I[3] ), .T( D_T[3] ) ); IOBUF iobuf_d4( .I( D_O[4] ), .IO( D[4] ), .O( D_I[4] ), .T( D_T[4] ) ); IOBUF iobuf_d5( .I( D_O[5] ), .IO( D[5] ), .O( D_I[5] ), .T( D_T[5] ) ); IOBUF iobuf_d6( .I( D_O[6] ), .IO( D[6] ), .O( D_I[6] ), .T( D_T[6] ) ); IOBUF iobuf_d7( .I( D_O[7] ), .IO( D[7] ), .O( D_I[7] ), .T( D_T[7] ) ); // Clock buffer and reset wire clk_fast; wire clk_half; wire clk_fb; IBUFGDS_LVDS_25 diff_usrclk_buf( .I( Clkin_p ), .IB( Clkin_m ), .O( clk_fast ) ); wire clkdiv0_unbuffered; wire clk0_unbuffered; wire clk0_fb; // BUFG bufg1 (.I(clkdiv0_unbuffered), .O(clk_out)); // BUFG bufg1 (.I(clk_fast), .O(clk_out)); // BUFG bufg1 (.I(clk0_unbuffered), .O(clk_out)); BUFG bufg2 (.I(clk0_unbuffered), .O(clk0_fb)); reg foo; reg foo2; BUFG bufg1 (.I(foo2), .O(clk_out)); always @(posedge clk_fast) begin if (foo) foo2 <= ~foo2; foo <= ~foo; end DCM #( .CLKIN_PERIOD (10.0), .DUTY_CYCLE_CORRECTION ("TRUE"), .DLL_FREQUENCY_MODE ("LOW"), .STARTUP_WAIT ("FALSE") ) ddr2_dcm ( .CLKIN (clk_fast), .CLKFB (clk0_fb), .CLK0 (clk0_unbuffered), .RST (User_Rst) ); // BUFG GBUF_FOR_MUX_CLOCK (.I(clk_half), .O(clk_out)); // BUFG GBUF_FOR_MUX_CLOCK (.I(clk_fast), .O(clk_out)); wire [0:3] rstr; FD rstr0( .D( 1'b0 ), .Q( rstr[0] ), .C( clk ) ); defparam rstr0.INIT = 1'b1; FD rstr1( .D( rstr[0] ), .Q( rstr[1] ), .C( clk ) ); defparam rstr1.INIT = 1'b1; FD rstr2( .D( rstr[1] ), .Q( rstr[2] ), .C( clk ) ); defparam rstr2.INIT = 1'b1; FD rstr3( .D( rstr[2] ), .Q( rstr[3] ), .C( clk ) ); defparam rstr3.INIT = 1'b1; assign User_Rst = |rstr; user_fifo test_fifo( .WrFifo_Din( write_data ), .WrFifo_WrEn( write_enable ), .WrFifo_Full( write_full ), .WrFifo_WrCnt( ), .RdFifo_Dout( read_data ), .RdFifo_RdEn( read_enable ), .RdFifo_Empty( read_empty ), .RdFifo_RdCnt( ), .User_Rst( User_Rst ), .User_Clk( clk ), .Sys_Rst( User_Rst ), .Sys_Clk( clk_fast ), .D_I( D_I ), .D_O( D_O ), .D_T( D_T ), .RDWR_B( RDWR_B ), .CS_B( CS_B ), .INIT_B( INIT_B ), .CCLK( CCLK_int ) ); wire data_to_host_full; reg [7:0] data_to_host; wire data_to_fleet_empty; wire [7:0] data_to_fleet; reg data_to_host_write_enable; reg data_to_fleet_read_enable; assign data_to_fleet = read_data; assign read_enable = data_to_fleet_read_enable; assign write_enable = data_to_host_write_enable; assign write_data = data_to_host; assign data_to_fleet_empty = read_empty; assign data_to_host_full = write_full; initial data_to_fleet_read_enable = 1; initial data_to_host_write_enable = 0; reg [7:0] force_reset; assign rst_out = User_Rst || (force_reset!=0); /// Common ////////////////////////////////////////////////////////////////////////////// reg send_k; initial send_k = 0; 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; reg [16:0] credits; // fpga -> host always @(posedge clk) begin if (/*rst_in*/User_Rst) begin count_in <= 0; count_out <= 0; force_reset <= 0; credits = 0; `reset end else begin `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]; // 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:Bee2 ================================================================= ###################################### ## System clock pins ###################################### NET Clkin_p LOC = AP21 | IOSTANDARD = LVDS_25; NET Clkin_m LOC = AN21 | IOSTANDARD = LVDS_25; NET rst_in LOC = H4 | IOSTANDARD = LVCMOS18; NET clk_out PERIOD=50MHz; //NET clk_out PERIOD=100MHz; //NET clk_fast PERIOD=100MHz; NET Clkin_p PERIOD=100MHz; NET Clkin_m PERIOD=100MHz; ###################################### ## SelectMAP interface pins ###################################### NET D<0> LOC = AU9 | IOSTANDARD = LVCMOS25; NET D<1> LOC = AV9 | IOSTANDARD = LVCMOS25; NET D<2> LOC = AY9 | IOSTANDARD = LVCMOS25; NET D<3> LOC = AW9 | IOSTANDARD = LVCMOS25; NET D<4> LOC = AW34 | IOSTANDARD = LVCMOS25; NET D<5> LOC = AY34 | IOSTANDARD = LVCMOS25; NET D<6> LOC = AV34 | IOSTANDARD = LVCMOS25; NET D<7> LOC = AU34 | IOSTANDARD = LVCMOS25; NET RDWR_B LOC = AR34 | IOSTANDARD = LVCMOS25; NET CS_B LOC = AT34 | IOSTANDARD = LVCMOS25; NET INIT_B LOC = AR9 | IOSTANDARD = LVCMOS25; NET CCLK LOC = C14 | IOSTANDARD = LVCMOS25; #Net rst_pin LOC=E9; #Net rst_pin PULLUP; #Net rst_pin TIG; == FPGA:ML509 ============================================================== assign gpio_led_n = 0; assign gpio_led_s = 0; assign gpio_led_e = 1; assign gpio_led_w = 1; wire tdo; wire update; wire shift; wire reset; wire tdi; wire sel; wire drck; BSCAN_VIRTEX5 #(.JTAG_CHAIN(1)) bscanvirtex(.TDO(tdo), .UPDATE(update), .SHIFT(shift), .RESET(reset), .TDI(tdi), .SEL(sel), .DRCK(drck)); wire [9:0] din; wire [9:0] dout; reg [9:0] dout_r; wire strobe_o; assign din = 10'h71; wire ack_i; assign ack_i = 1; fjmem_core my_fjmem_core( .clkdr_i (drck), .trst_i (reset), .shift_i (shift), .update_i (update), .tdi_i (tdi), .tdo_o (tdo), .clk_i (clk), .res_i (rst), .strobe_o (strobe_o), .read_o (), .write_o (write_o), .ack_i (ack_i), .cs_o (), .addr_o (), .din_i (dout_r), .dout_o (dout) ); always @(posedge clk) begin if (strobe_o) dout_r <= dout; end wire break_i; reg send_k; initial send_k = 0; 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 [7:0] data_to_fleet; reg data_to_host_write_enable; reg data_to_fleet_read_enable; reg [7:0] force_reset; assign clk_out = clk_pin; wire sio_ce; wire sio_ce_x4; wire break; 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, uart_rts, sio_ce, sio_ce_x4, data_to_host, data_to_fleet, data_to_fleet_read_enable, data_to_host_write_enable, data_to_host_full, data_to_fleet_empty, break, break_i); reg [16:0] credits; // fpga -> host always @(posedge clk) begin if (rst_in /* || break */) begin count_in <= 0; count_out <= 0; force_reset <= 0; credits = 0; `reset end else begin `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:ML509 ================================================================= 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; NET gpio_led_c LOC="E8"; # Bank 20, Vcco=3.3V, DCI using 49.9 ohm resistors NET gpio_led_e LOC="AG23"; # Bank 2, Vcco=3.3V NET gpio_led_n LOC="AF13"; # Bank 2, Vcco=3.3V NET gpio_led_s LOC="AG12"; # Bank 2, Vcco=3.3V NET gpio_led_w LOC="AF23"; # Bank 2, Vcco=3.3V NET gpio_dip_sw1 LOC="U25"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors == Test ================================================================ #expect 25 #ship debug : Debug debug.in: set word= 25; deliver; == Contributors ========================================================= Adam Megacz