I successfully built the RP source from git and I'm able to use the BSP. But the lack of "xil_io.h" remains. I searched for it and found it here: RedPitaya/OS/linux/linux-xlnx/drivers.
That's slightly odd, since the SDK should set up the include paths correctly for you - maybe some detail about how you configured the bsp. But if it's not a problem for you anymore, we'll let it slide.
Anyway, the main reason I'm doing this, is to send data and recieve it from my design on the fpga inside a linux application. So my main question is:
How am I able to do this? So far I built the bitstream file of my design.
The method commonly applied throughout the Red Pitaya design is to define a memory region on the AXI GP bus and map that memory on /dev/mem on the linux side.
To do that, you would connect your module to the system bus with these signals in red_pitaya_top.v:
Code: Select all
// System bus
.sys_clk_i ( sys_clk ), // clock
.sys_rstn_i ( sys_rstn ), // reset - active low
.sys_addr_i ( sys_addr ), // address
.sys_wdata_i ( sys_wdata ), // write data
.sys_sel_i ( sys_sel ), // write byte select
.sys_wen_i ( sys_wen[6] ), // write enable
.sys_ren_i ( sys_ren[6] ), // read enable
.sys_rdata_o ( sys_rdata[ 6*32+31: 6*32] ), // read data
.sys_err_o ( sys_err[6] ), // error indicator
.sys_ack_o ( sys_ack[6] ) // acknowledge signal
(I used the only free slot in the original design, nr 6)
Additionally, comment out the placeholder signal assignment, also in red_pitaya_top.v:
Code: Select all
//assign sys_rdata[ 6*32+31: 6*32] = 32'h0;
//assign sys_err[6] = {1{1'b0}} ;
//assign sys_ack[6] = {1{1'b1}} ;
Your module declaration needs to define the following signals (<your module>.v):
Code: Select all
// System bus
input sys_clk_i , //!< bus clock
input sys_rstn_i , //!< bus reset - active low
input [ 32-1: 0] sys_addr_i , //!< bus saddress
input [ 32-1: 0] sys_wdata_i , //!< bus write data
input [ 4-1: 0] sys_sel_i , //!< bus write byte select
input sys_wen_i , //!< bus write enable
input sys_ren_i , //!< bus read enable
output [ 32-1: 0] sys_rdata_o , //!< bus read data
output sys_err_o , //!< bus error indicator
output sys_ack_o //!< bus acknowledge signal
, declare the following sysbus signals:
Code: Select all
wire [ 32-1: 0] addr ;
wire [ 32-1: 0] wdata ;
wire wen ;
wire ren ;
reg [ 32-1: 0] rdata ;
reg err ;
reg ack ;
, and instantiate a bus synchronizer:
Code: Select all
// bridge between <your module> and sys clock
bus_clk_bridge i_bridge
(
.sys_clk_i ( sys_clk_i ),
.sys_rstn_i ( sys_rstn_i ),
.sys_addr_i ( sys_addr_i ),
.sys_wdata_i ( sys_wdata_i ),
.sys_sel_i ( sys_sel_i ),
.sys_wen_i ( sys_wen_i ),
.sys_ren_i ( sys_ren_i ),
.sys_rdata_o ( sys_rdata_o ),
.sys_err_o ( sys_err_o ),
.sys_ack_o ( sys_ack_o ),
.clk_i ( adc_clk_i ),
.rstn_i ( adc_rstn_i ),
.addr_o ( addr ),
.wdata_o ( wdata ),
.wen_o ( wen ),
.ren_o ( ren ),
.rdata_i ( rdata ),
.err_i ( err ),
.ack_i ( ack )
);
To enable reading data from your module, put in something like:
Code: Select all
always @(*) begin
err <= 1'b0 ;
casez (addr[19:0])
20'h00000 : begin ack <= 1'b1; rdata <= <your output register 0> ; end
20'h..... : ...
20'h1???? : begin ack <= <your BRAM data valid signal>; rdata <= <your BRAM block at address ????> ; end // (optional)
default : begin ack <= 1'b1; rdata <= 32'h0 ; end
endcase
end
If you need to write to your module from linux, put in something like:
Code: Select all
reg [32-1:0] your_reg;
always @(posedge adc_clk_i) begin
if (adc_rstn_i == 1'b0) begin
your_reg <= 32'h0 ;
end
else begin
if (wen) begin
if (addr[19:0]==20'h0) your_reg <= wdata[32-1:0] ;
if (addr[19:0]==20'h.....) ...
end
end
end
In linux, you then need to mmap() the memory region 0x40600000 - 0x406fffff on /dev/mem (see /Test/monitor/monitor.c for example). The pointer that you obtain from mmap() will allow you access to your FPGA logic by simple dereferencing.
I'm assuming in all this that your module runs on the adc_clk which is the clock that all ADC/DAC 14bit datapaths run on.