Forum Discussion
Altera_Forum
Honored Contributor
17 years agoQuestions regarding interfacing of & accessing custom hardware blocks
Hello,
Firstly, before you read the rest - i'm pretty "green" with FPGAs, but i do know how to set up a Nios II soft-core processor system with IP blocks using the SOPC builder, and instantiating it in Quartus II using the top-level hdl files (vhdl). And it works fine with the C code i have written to execute on it. Now I want to implement a certain, often executed, part of the C code as a hardware block ("IP block" i guess), to work as a pheripheral with the Nios II. From what i have gathered i obviously need the VHDL code for the hardware block that i want to create, but i'm in doubt regarding three things (mainly): - Does this VHDL code need to take anything special into account regarding the Avalon switch fabric? i.e. new port/signal names, etc.? I have read http://www.altera.com/literature/hb/qts/qts_qii5v4_01.pdf but i'm not sure if this means i shouldn't think of the Avalon Switch fabric in any way in my HDL. - How do I communicate between my C code executing on the Nios II and the hardware accelerator? By using addresses? Could someone show me an example on how this should be done? Does a tutorial on this exist, covering just a really simple example, like a multiplier as a hardware accelerator, and how this is "interfaced" both regarding calls from a C code and in SOPC builder? Basically what i want to do is what C2H can do for me, but i'd like to learn by doing it manually. I don't care if i can't do it as well as C2H. Thanks for any help.12 Replies
- Altera_Forum
Honored Contributor
Hello again,
First and foremost - Thank you very much for the very detailed reply, it was much appreciated! In the meanwhile i have been studying the Avalon specifications, and i now agree, it is not the first thing to focus at right now - the VHDL code describing my component is the difficult part. It is not done yet, but at that point i might have a few questions regarding the Avalon interfacing, if it turns out not to be working with it. The hardware is supposed to return the logarithm of an input, x, using the jacobian logarithm algorithm. Thanks, you made the communication between the program executing on the soft-core processor and the hardware block sound easy, and it also seems to be. If i want to read/write 4 bytes in a row i would use IORD_32DIRECT(base_addr, addr_incr) and IOWR_32DIRECT(base_addr,addr_incr,data). You mentioned that one needs to keep track of where in the address space that the values that the hardware accelerator are located at, and by that i'm not sure of. If we say that this basic full-adder is my "hardware block" - http://www.planet-source-code.com/vb/scripts/showcode.asp?txtcodeid=10203&lngwid=3, and pretend that it is interfaced correctly with the Avalon bus, and let's pretend that the SOPC builder gives me a base address for the full-adder at 0x00101000 - Since Cin is stated as the first port, would that then have zero increment, i.e. base address 0x00101000, increment 0? - Considerering that the Cin was in std_logic(31 downto 0), and x was also in std_logic(31 downto 0), should i, in order to "assign" a value to these inputs just write it as: IOWR_32DIRECT(0x00101000,0,0x12341234); to write in the decimal value corresponding to 0x12341234 hex? To write the same hex value to input x, would it then be: IOWR_32DIRECT(0x00101000,1,0x12341234); ? It would be nice if it worked that way, but i am unsure if the port declarations are kept in that order when imported into SOPC builder - or if i have to modify VHDL code in some other way. - Altera_Forum
Honored Contributor
You should probably tell us what it is your implementing in the custom peripheral so we know exactly what you're component is going to need.
You'll need to refer to this: http://www.altera.com/literature/manual/mnl_avalon_spec.pdf That is the specification for the Avalon memory-mapped and Avalon streaming specifications. You will be using the memory-mapped specification. 1 - You are at the very least going to have to put an Avalon memory-mapped slave port on your custom peripheral. Yes you must obey the rules of the Avalon memory-mapped specification. Don't worry, the avalon bus is extremely easy to interface to. 2 - Depending on what you are doing, you may also need an Avalon memory-mapped master (or two). For example, is your custom component going to directly access memory that the processor has written to or is going to read? Here is the basic flow. 1 - Create your Verilog or VHDL description of the peripheral. This is really the only difficult part. Make sure you obey all the rules for Avalon slaves and masters. Everything after this is easy. 2 - Use the "Component Editor" in SoPC builder to create a new SoPC component from your HDL code. This involves telling the component editor what each signal in your port list is so that it knows how to connect things to the Avalon fabric. If you need specific help here, we'll help you. 3 - After you generate your SoPC system, and get into the software world, the "system.h" file will contain information about your custom component. Primarily it will contain a macro indicating the base address in the NIOS processor's memory map. You can then use this macro to access your component. You of course are responsible for knowing what the significance of each address is in your component's address map. Typically people use the IOWR and IORD macros to access the registers in their custom component. Hope this gets you started. Don't hesitate to ask for more detail as you get further along. Jake