Jump to content
  • 0

Arty A7-35T IPs for communication with a Linux PC


Mayur

Question

I wish to transfer some data from a Linux computer to the Arty A7, do some computation*, say number crunching, and get the results back. What are the ways to do it?

(*For simplicity, imagine I want to send 10 integers to fpga into an array, do things like finding average or sum etc and return the results.)

The ones I saw till now:

- Xilinx JTAG IP:  https://www.xilinx.com/support/documentation/ip_documentation/jtag_axi/v1_2/pg174-jtag-axi.pdf

- Xilinx usb device IP https://www.xilinx.com/support/documentation/ip_documentation/axi_usb2_device/v5_0/pg137-axi-usb2-device.pdf

- Digilent IP digilentinc.com:ip:usb2device:1.0 (This seems to be for Microblaze which I don't plan to use)

- Saw some sample projects with Arty A7 board that implement own communication logic instead of using any IPs

Please advise. I would prefer an IP to save time.

Link to comment
Share on other sites

4 answers to this question

Recommended Posts

12 minutes ago, xc6lx45 said:

in 99 % of applications, a UART would do the job (via "USB-UART Bridge").

Thanks. I noticed IPs such as the the below one to set up a UART. But the baud rates appear much lower than what USB 2.0 is capable of supporting.

https://www.xilinx.com/support/documentation/ip_documentation/axi_uartlite/v2_0/pg142-axi-uartlite.pdf

Could some of the IPs listed in the OP be used to get a better speed?

 

Link to comment
Share on other sites

Hi @Mayur,

I agree with @xc6lx45 about the uart communications. The IP's you have linked to are geared to work with the AXI bus that is used with Microblaze and Zynq processors. To use the IP's without Microblaze you would need to facilitate the AXI bus communication. I believe it would be easier to either use all HDL(verilog/VHDL) or use Microblaze for your project. If you choose to do an all HDL project then the HDL demo Arty General I/O Demo does not use Microblaze and should be helpful with the UART_TX part of the bridge.  The UART_RX part of the bridge can be easily found online.

thank you,

Jon

Link to comment
Share on other sites

Hi,

using AXI without a processor is unnecessarily complex. In comparison, the UART functionality is almost trivial.
You should be able to reach maybe 2 MBits / second. For comparison, JTAG goes up to 30 MBits / second but it's not as easy.

Below some very old code from a very dusty corner of my hard drive. You have to set "nBitCycles" to the length of one bit in clock cycles, e.g. for 9600 baud and 100 MHz clock it's 100e6 / 9600.

The easiest way to test is to link serialRx/out_byte to serialTx/inByte, serialRx/in_strobe to serialTx/inStrobe. Then it'll echo back all data.

// note: if rx is an external (asynchronous) input, it must be registered first
module sk61_serialRx(clk, in_rx, out_byte, out_strobe);
   input clk;
   input in_rx;
   parameter nBitCycles = 0;
   reg [31:0] 	    count;   
   reg [3:0] 	    state = 0;
   reg [7:0] 	    data;
   output reg	    out_strobe;   
   output [7:0]     out_byte;
   
   assign out_byte = out_strobe ? data : 'bx;   
   
   always @(posedge clk) begin
      out_strobe <= 1'b0; // non-final
      
      if (state == 0) begin
	 if (!in_rx) begin
	    state <= 1;
	    count <= $floor(nBitCycles/2+0.5);
	 end
      end else if (state == 10) begin
	 // stop bit
	 // wait for nominal sampling instant
	 if (count != 0)
	   count <= count - 1;  
	 else if (in_rx) begin
	    // after nominal sampling instant, wait for line to go high
	    // => ready to signal next byte with falling edge
	    // => restart
	    state <= 0;
	    count <= 'bx;
	    data <= 'bx;
	 end
      end else begin
	 if (count != 0) begin
	    // start bit
	    count <= count - 1;  
	 end else begin
	    // data bits
	    data <= {in_rx, data[7:1]};
	    state <= state + 1;
	    count <= nBitCycles;
	    if (state == 9) begin
	       // final data bit
	       out_strobe <= 1'b1;
	    end
	 end
      end
   end
endmodule

module sk61_serialTx(clk, out_tx, in_byte, in_strobe, out_busy);
   parameter nBitCycles = 0;

   input clk;
   output out_tx;
   input [7:0] in_byte;
   input       in_strobe;
   output      out_busy;
   
   reg [31:0] count;   
   reg [3:0]  state = 0;   
   reg [7:0]  data;   
   
   assign out_tx = (state == 0) ? 1'b1:    // ready
		   (state == 1) ? 1'b0:    // start bit
		   (state == 10) ? 1'b1:    // stop bit
		   data[0];                // data bits    
   assign out_busy = (state != 0);   
   
   always @(posedge clk) begin
      // correctly timed, in_strobe appears only during idle state (0)
      // however, if echoing data from a UART, small timing error may cause 
      // a new byte to start already during the stop bit
      // This implementation does not prevent retriggering at any time,
      // but this will cause garbled data.
      if (in_strobe) begin
	 count <= nBitCycles;
	 state <= 1;
	 data <= in_byte;
      end else if (state != 0) begin
	 if (count == 0) begin
	    count <= nBitCycles; // (non-final)
	    state <= state + 1; // (non-final)
	    case (state)
	      1: begin 
		 // startbit
	      end
	      default: begin 
		 // data bits
		 data <= {1'bx, data[7:1]};	       
	      end
	      10: begin
		 // stop bit
		 state <= 0;
		 count <= 'bx;
		 data <= 'bx;		 
	      end
	    endcase
	 end else begin
	    count <= count - 1;
	 end
      end
   end
endmodule             

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...