Page 1 of 1

Integrating a Custom FPGA Module with PS/AXI bus

Posted: Fri Jul 15, 2022 4:45 am
by coreyb
I am new to FPGA programming and am struggling to integrate a custom module with the PS of the RedPitaya. All I need to be able to do is read and write registers (within CS[6] 0x40600000 to 0x406FFFFF). I have 32 data outputs that I would like written to the memory so that I can read them on the console. Ideally, I would like to get the data out at about 500Hz or so (so 64 KB/s). As I understand it, a custom AXI slave interface has been made for this purpose of reading and writing to memory, but I am unsure how to use it.

So far, I have wired my module to the system bus interface (removed the stub for sys[6] and connected those pins to my module). Within my module, I have put together the following code, based upon what I found in other modules in the source code:

Code: Select all

            if(rising_edge(clk_i)) then
                if(rstn_i = '0') then
                    err_o <= '0';
                    ack_o <= '0';      
                    err_o <= '0';
                    case (addr_i(19 downto 0)) is
                        when "00000000000000000000" =>
                            ack_o    <=  wen_i OR ren_i;
                            rdata_o  <=  "00000000" & MYDATA;
                        ...other when statements
                    end case;
                 end if;
               end if;
end process;
Now, a lot of this feels to be more guesswork than science. And I'm not sure how to interface my module on the other (PS) side. Could anyone share any resources or guidance in integrating my module with the greater system? Any help would be much appreciated.

Thank you,

Edit: I have also tried a different approach - using the block diagram. However, I am still unsure how to connect the module. I am not married to direct RTL programming or using the BD, whatever works best. I've tried attaching a screenshot of the block diagram, but I got the message: "ERROR Sorry, the board attachment quota has been reached."

Re: Integrating a Custom FPGA Module with PS/AXI bus

Posted: Fri Jul 15, 2022 9:29 pm
by M0JPI
Hi Corey,

I'm new to FPGA development as well, I found the Stopwatch and Frequency Counter examples from Anton Poto─Źnik that are now part of the Red Pitaya Knowledge Base useful.

They show how to use AXI GPIO memory mapped interfaces from the PL to PS sides to the Zynq chip on the Red Pitaya. The examples use block diagrams, but you can see the RTL behind some of the Frequency Counter blocks that Anton created. The C programs are included as well.

John M0JPI

Re: Integrating a Custom FPGA Module with PS/AXI bus

Posted: Sat Jul 16, 2022 5:12 pm
by coreyb
Hi John,

Thanks for the suggestions. I've looked at those two examples but am still unsure how to proceed. All I want to understand is how to write and read to registers on the FPGA side in the 0x40600000 block. I can use the 'monitor' command to read and write on the PC side, but I just can't get data sent to those addresses. I get "bus errors" when I try reading them. (Am I right in assuming that 'monitor' should work for this 0x406... region?)

I'm having some trouble understanding how the system bus interface actually works. There is rdata_o, which I take it is the data output. There is also an address in. In my module, I have code that can put the right data on rdata_o when an address is given to it, but I'm not sure how the addresses are being generated. How do I get the bus to read data into one of the registers? Internally to my module, I can easily get the right data put on rdata_o for an address in, but I'm still at a slight loss how to get it to work on the other side. I guess my question really is, how do I get the system bus to read data into certain addresses?

Re: Integrating a Custom FPGA Module with PS/AXI bus

Posted: Mon Jul 18, 2022 2:09 pm
by coreyb
After playing around more, I was able to figure it out, and so I just want to post the solution in case anyone else experiences the same confusion.

My first issue was an incorrect understanding of how the system bus works. When different regions of memory are mapped, ie 0x401, 0x402 ... 0x406 etc, that does not meet that the memory registers already exist. When you use the bus system, you are not reading and writing into already-instantiated registers. Rather, you must create the registers for your data, and then connect a certain register to rdata_o when the address is 0x40600000, another register to rdata_o when the address is 0x40600004, etc.

My second issue was a little more subtle. The RedPitaya fpga is programmed in Verilog. However, I wrote my module in VHDL since it is the language that I am more familiar with. It is fine to write a module in VHDL, then instantiate it into a Verilog top. However, there are some slight nuances that I missed. I had originally programmed it so when an address was received by the module, it would output the sought data on rdata_o. However, this output would be of type STD_LOGIC_VECTOR, not REG. Thus, I needed to write a Verilog wrapper for the module, in which I connected each data output logic vector to a data output REG. With that change, the system worked wonderfully.

I appreciate the suggestions John, and I hope this conversation can be useful to others as well!


Re: Integrating a Custom FPGA Module with PS/AXI bus

Posted: Mon Jul 18, 2022 10:13 pm
by M0JPI
Thanks Corey,
I've only got experience of extending the examples. I was happy that I managed to follow the example of transferring one value at a time.
My aim is to be able how to modify the SDR designs, and maybe use the Red Pitaya as a DAQ board.

I was going to see if I could find a DMA example to answer your question. I'm glad you got your project working.

John M0JPI

Re: Integrating a Custom FPGA Module with PS/AXI bus

Posted: Mon Jul 25, 2022 8:35 am
by juretrn
Hi guys, I will try to explain the inner workings of the system bus and the intended usage.

The bus consists of the following signals:
sys_addr - 32 bit address line
sys_wdata - 32 bit write data
sys_rdata - 32 bit read data
sys_wen - write enable pulse
sys_ren - read enable pulse
sys_ack - acknowledge pulse; used to indicate read is ready
sys_err - indicates an error on the bus

The address line, write data, write enable and read enable come from the AXI bus / software.
Read data, error and acknowledge are outputs from the FPGA logic.

In address decoding we only use the lower 20 bits, as the top 12 bits give us the address region.
Of course, the registers should be declared first, and it is a good idea to always give them a sensible initial value.
When writing from the bus to internal registers, we need to check the address and the write enable pulse. We only enable writing when sys_wen is 1.
When reading data to the bus, a similar operation is required, but this time we need to somehow handle the sys_ren pulse and return a sys_ack pulse when the read data output is ready. If a sys_ack pulse is not received when reading, the bus WILL hang.