Jump to content
  • 0

How to add own logic to Arty board flow?


Paul_kimelman

Question

The Arty board examples and tutorials use the Vidado drag and drop editor. But, there is no example how one would add their own custom logic. I have hacked this so far by dropping a peripheral and then replacing the stub verilog file, but it would help to show how this should be done. The natural would be to drop in a custom bus i/f file (e.g. using the AXI to AHB or AXI to APB bridge to a stub) and also how you add pins to the port list. Hacking away at it seems just wrong - if there is some intended flow, it is not apparent. The old way of editing the .ucf file and adding the ports to the top file does not seem like a fit for this SDK/Microblaze environment. 

Thanks, Paul

Link to comment
Share on other sites

Recommended Posts

1 hour ago, zygot said:

I've written my own IP and added it to the Vivado IP. It's quite an undertaking. I suggest that you pore through Xilinx documentation and tutorials to see how this is done.

I avoid MicroBlaze as much as possible but when I use a Zynq I'm pretty much tied to the normal flow. What I do in this case is build my board design and have Vivado create an HDL toplevel... making sure that I DON"T let Vivado manage it. I can then write a wrapper as a new toplevel HDL that instantiates the old board design and my own HDL modules.

Hi Zygote. I found that when I used MicroblazeMCS, I was able to do so in a very normal flow. It creates what ISE called a "core" which I get to instantiate into my top. This is unlike the craziness of the designer which makes it very hard to integrate into the system since it will not do external properly and it will not accept an incomplete system - they want you to import your IP as a package or set of. You have to match naming and ports and their whole packager is a disaster (I found it would not forget a port I had deleted nor a param I had removed, and its auto association only seems to work for AXI names if you follow their exact names - gets clock wrong, etc.

But, the MBlazeMCS was fine - I did not need more than it supplies and I wrote a simple IO bus to APB bridge (all of 8 lines).

On your point about modifying the wrapper (or using your own), then you have to never make a change to the "designed" system. The MCS model at least allows you to update it (e.g. change memory, add more peripherals, etc) with no issues (other than SDK not updating the memory size - has to be done manually). You can also add other peripherals as cores like normal. 

Link to comment
Share on other sites

42 minutes ago, Paul_kimelman said:

But, the MBlazeMCS was fine - I did not need more than it supplies and I wrote a simple IO bus to APB bridge (all of 8 lines).

I would add that this MCS uses about 1k LUTs and 1k FFs, so you can add more cores - up to 4 (since there are only 4 JTAG debug registers available). You will have to create a separate core for each instance though as debug register needs to be redefined in each of them.

Link to comment
Share on other sites

3 hours ago, asmi said:

I would add that this MCS uses about 1k LUTs and 1k FFs, so you can add more cores - up to 4 (since there are only 4 JTAG debug registers available). You will have to create a separate core for each instance though as debug register needs to be redefined in each of them.

This is an interesting point. I don't need the extra horsepower since my focus is on the digital IP (which is of course being developed for use in Si chips), but it is an interesting point. Of course multi-core is kind of a hassle to program. I have not bothered connecting the debug up by the way; I suppose i ought to, but I have only been running test code on the MB that stimulates the HW. I might want to if I connect up some of the Pmod devices I got (for fun).

Link to comment
Share on other sites

17 hours ago, Paul_kimelman said:

This is an interesting point. I don't need the extra horsepower since my focus is on the digital IP (which is of course being developed for use in Si chips), but it is an interesting point. Of course multi-core is kind of a hassle to program. I have not bothered connecting the debug up by the way; I suppose i ought to, but I have only been running test code on the MB that stimulates the HW. I might want to if I connect up some of the Pmod devices I got (for fun).

You don't have to connect them into multiprocessor system - for example you can use them to control different submodules, which may of may not interconnect with other parts of the system. And if you connect them to different pins, you can essentially have several independent MCUs inside a single package - can be handy if your system does not require many IO pins so that you can fit several of them into a single chip. Or you can use one MCU that is running on low frequency to gate clock (or hold in reset) to others and this way power them down to save power - useful for battery-powered systems. Or you can combine them into a sort of SIMD system. There is a lot of possibilities if approached creatively.

Link to comment
Share on other sites

1 hour ago, asmi said:

You don't have to connect them into multiprocessor system - for example you can use them to control different submodules, which may of may not interconnect with other parts of the system. And if you connect them to different pins, you can essentially have several independent MCUs inside a single package - can be handy if your system does not require many IO pins so that you can fit several of them into a single chip. Or you can use one MCU that is running on low frequency to gate clock (or hold in reset) to others and this way power them down to save power - useful for battery-powered systems. Or you can combine them into a sort of SIMD system. There is a lot of possibilities if approached creatively.

interesting. One obvious use would be to have one running a Pmod display, so the other(s) simply write into a frame buffer and then trigger an interrupt into it to update. 
I suppose I could also add a serial port mux/demux, so you can use an input char to select different MCUs to speak with. That could be interesting. I would need to buffer the output, but that is OK. I need to think about that, as it could add an interesting use model for certain types of tests. 
Thanks, Paul

Link to comment
Share on other sites

Hi Paul,

1. The block RAM picture was conceptial. More details are in the picture. GPIOs are on the left.

2. You can create the new port on the block diagram by clicking right mouse button (or Ctrl+K) and then defining its direction, etc.

3. Constraints file in Vivado has .xdc extention. Digilent supplies definition .xdc for their boards which makes life easier.

Capture.PNG

Link to comment
Share on other sites

Hi @Paul_kimelman,

In Vivado 2016.x there is a new feature called add a block. you right click on empty part of block design and click and add a block. you can add your vhdl or verilog file to that and then use an axi gpio block to connect it. You will also need touse the xdc to constrain the pins from the add a block. I have attached a project that does that for some vhdl code working with the PmodAD1(not our IP core).  If you are wanting to make your own IP then here and here are some tutorials that deal with that. 

GPIO_add_a_block.zip

Link to comment
Share on other sites

Hi Jpeyron, thanks. I saw add a block but I did not realize it would allow me to add my own. I will look at your example for the pins since that was unclear. I have plenty of my own IP so it was more about moving it from a Spartan6 and ISE to this Artix env while also using Microbiaze for some SW.

Link to comment
Share on other sites

Don, I should have been more clear about this. The ZipCPU or whatever it is called is a GPL license. if you mix your own IP with that you have contaminated it. I would have been really happy if it was a BSD licensed core. But, I will never mix my "commercial" IP with GPL IP as that is forbidden in most companies.
That said, I wish there was a normal flow project with a core. The Vivado MBlaze thing is a disaster. It horrible. They make everything hard and they do not seem to even release the sources to their GPIO driver, not even the top level stub, so it makes it impossible to use it as a launching off point. I do not know what Xilinx is doing here, but this makes normal use of an FPGA to trial out some ASIC logic pre-tapeout much harder and that is a shame.

I am also saddened that Diligent has not pushed back on this mess. If you want to use MBlaze, there should be a "core" block you can just instantiate into your normal Verilog (or VHDL) flow, instead of this mess. If there is, I would love to see how; in ISE it would have just been a core generator and done. So, what would have taken me a couple hours in ISE is taking hours in Vivado because I have to package up things and I have to guess at the interface ports since it does not even expose the templates or anything. Crazy and Sad.

Link to comment
Share on other sites

Hi Paul,

Let me try to relive your frustration. I had myself similar feelings when I started my project on Zybo board. My past experience was limited to small VHDL projects on Xilinx and Actel FPGAs. For a while I had a hard time understanding interactions between PL and PS. Learning curve was steep but in the end I came to realization that introduction of block design can simplify integration of various IP modules.

You don't need to know all Xilinx code to implement interfaces. You can get sufficient info from the HDL wrapper. In case of GPIO if you don't use AXI you don't need it at all.

Take a look at
https://forum.digilentinc.com/topic/3822-what-is-the-fastest-way-to-save-pl-data/?do=findComment&comment=14413

Following this approach I was able to integrate several custom VHDL modules into the system. PL receives control signals from the processor, sends interrupts to the processor and share data. There several benefits of this :

1. No effort is needed on SDK side for obtaining addresses because they are supplied by Vivado automatically with the bitstream.

2. No effort is needed for instantiation of Xilnx modules because when you connect blocks it is done by Vivado behind the scene. You only need to have the necessary interface signals and can call them anyway you want.

3. SDK programming is a piece of cake because you can reuse a plenty of examples available in Xilinx documentation.

4. It is easier to debug HDL because if you expose a signal (wire) on a block diagram you can use JTAG logic analyzer which is now included for free with Vivado. I used it for checking interrupts and for GPIO and was happy with how much time it saved me.

It is clear to me that without the new Xilinx programming paradigm I would never accomplished my goals and that short time. Also I developed very high opinion about the Zynq processor. Adding two ARM cores increased productivity manifold. It is easier to document and most important to review the project by peers. 

Hope you find it useful, good luck to you!

 

Link to comment
Share on other sites

Hi Notarobot. Thanks, I will check this out. I agree the designer is fine for throwing together pre-built IP blocks into the equivalent of a hard-macro. It was the next steps that I find very irritating. I tried the AXI to APB bridge and they give you no help and it does not even expose the nets and so you cannot just hook them up (you have to figure out the interface and then replicate it by exact name and then hope they recognize it). I am glad if there is a better way, although it still looks like this create a package thing and I will need to see what the block-RAM interface looks like. This is what is so unnatural about this. I tried to pump the AXI 2 APB as external, but I do not see where it does - it does not seem to come out of the system.v file which is what I would expect (so I could just dump my custom instantiation into the system_wrapper.v). I do not understand why this has to be this hard, most systems with these builders at least allow you to "externalize" nets like the output of the AXI APB bridge and then you can just connect them the normal way in the top.v type file. They seem way too enamored of this flow - quite painful for development.

I will compare the page you sent me and my completion of the AXI to APB bridge since I have it connected. I will need to change my package since I had not considered that I cannot tie off ports easily with the designer (no 0 or 1 to attach to). So, I will layer one more level and only expose what I have to.

Also, I got burned by a parameter defined in a wrapper as: "parameter name = other_name[1] & other_name2[0]" which their tool freaked out with since it removes the [ and ] and then blows up with errors that other_name1 does not exist and so on. If you tell it to skip that param, it then fails when building the package with no explanation. 

Link to comment
Share on other sites

Hi Paul,

Unfortunately, I can't advice you on AXI-APB since know nothing about it. But I've learned that Digilent forum is the most helpful/useful/friendly. You will find help here. Unlike Xilinx forum which I find arrogant and just a waste of time in 90% of cases.

BTW, BRAM on my Zybo dev board works well and serves the purpose. I like that very little code is required for its implementaion.

You might know already but when you click on a "+' sign on the IP module, it will list all interface wires and you can connect to each one without declaration or any other extra code. They should be of the same type and proper direction only.

For the AXI interface you can check Youtube examples made by Mohammad Sadri. He also showed utilization of HDL wrapper for embedding a custom code.

 

Link to comment
Share on other sites

As one follow up, does anyone know how to simply get the block designer to port out nets of interest? This makes no sense. See below (not in system or system_wrapper). The system wrapper does not export the APB signals it says are there, nor the LED and other GPIO pins. So, where do they go? I am assuming this means some non-standard "magic" to get them to the FPGA pins, but it makes things much harder.

Further, if I try to locally connect, I get the below garbage error. You can see every pin of the APB bridge is connected, yet I get this error. This whole designer things very fragile and very buggy. The only things that work are to follow very narrow rules. So how did you get past this with your idea of a block RAM connector? Does it export the nets?

 

 

Screen Shot 2017-04-16 at 12.20.51 PM.png

Screen Shot 2017-04-16 at 12.31.34 PM.png

Link to comment
Share on other sites

@Paul_kimelman,

I'm not sure I can thank you enough for your honest feedback regarding the ZipCPU and its related cores.  Thank you, and thank you again.  :)

Unlike many other open source products, the ZipCPU and its related cores are not the result of a community of effort.  Instead, they have been the result of two years of hard and at times painstaking work on my part--work that has not been paid for, and hence the GPLv3 license with all of its "viral" problems. 

I guess what I'm trying to say is that, with the exception of the tool chain (GCC, binutils, and newlib), the license for the rest of the ZipCPU and any other products I have put together is subject to negotiation.  While I have tried to place a notice to this effect on the various project pages, I may not have been clear enough.  Please feel free to name your terms, and I will be glad to name a price.  Indeed, I'd be glad to release all of this work under a BSD type of license, but I would want to be paid for my work first. 

If you think this solution would be of value to you under a different license, then lets talk off of the forum.  Tell me what value it would have to you, and what license you would need me to offer it to you under, and I'm sure we could come to an arrangement.  :)

Either way, thank you for your honest, open, willing, and frank feedback.  It is much appreciated.

Dan

Link to comment
Share on other sites

Hi D@n, I am an architect and ASIC designer inside a Si company, so I only use FPGAs for pre-Si validation, demos, and some prototype work. So, I would not be the right person to discuss terms since whatever I use, it is only hit and run. 
I understand your views on this, but I am unclear how GPL helps your goals or finances? BSD would require attribution if used in a product, but does not require funds any more than GPL does.

This is always a tough area. There may be scope for a licensable low cost core, but you would be competing with whatever Xilinx/Altera throws on anyway. I do not know if RISC/V has done an FPGA version. I know when I was at ARM, we did the Cortex-M1 for FPGA and real ASIC cores do not perform as well on FPGA due to the difference between cost factors (e.g. fan-in/fan-out vs. flop cost). But, I have no idea if there is scope for more especially with the modern crop of FPGAs. Good luck!

Regards, Paul
 

Link to comment
Share on other sites

Hi Asmi and Notarobot. I will note that I have slowly worked out how to get this working. But, that was my point. This is a painful and complex flow with a lot of steps. You can make it work (you can always make anything work) but it takes way too much trial an error. The Diligent site is far friendlier and more helpful, but I am just shocked at how hard it is to do something simple. The Block-RAM page was conceptual unless I missed something? A lot of things are way harder than they should be, and so you always have to find weird tricks. For example, the board file features from the Diligent board cannot just be picked up and used except as pre-built blocks. So, I had to add these as GPIOs and then steal their wires and then connect them to my design after changing my port to exactly match since you cannot split up such nets. That does not seem very friendly. 

I think Xilinx has gone overboard on this IP-XACT model. If they had at least better considered hybrid models so I could just create a custom "block" which I could wire up and then they provide the port list, that would be perfect. That is how Altera does it (or used to, have not used their stuff in a while). It is very backwards and very painful to do this since they are not even using the SystemVerilog modport/interface scheme which would have been easier - instead you have to use these mapping dialogs in the packagers. 

Thanks for help from all of you.

Link to comment
Share on other sites

47 minutes ago, Paul_kimelman said:

I think Xilinx has gone overboard on this IP-XACT model. If they had at least better considered hybrid models so I could just create a custom "block" which I could wire up and then they provide the port list, that would be perfect. That is how Altera does it (or used to, have not used their stuff in a while). It is very backwards and very painful to do this since they are not even using the SystemVerilog modport/interface scheme which would have been easier - instead you have to use these mapping dialogs in the packagers. 

You can absolutely do that - there is a wizard that allows you to generate AXI-wrapper for whatever interface (or interfaces, as it's commonly the case). It's somewhat hidden (Tools -> Create or Package New IP, then pick "Create a new AXI peripheral" option, the rest is pretty self-explanatory). This will generate a separate Vivado project which you can customize to your heart's content, after that you wire your own modules to generated wrappers, package IP - and you're good to go! Here is the video which shows this flow and explains the steps (he does just what you want - creates an AXI-lite wrapper and wires his own custom module to it):

 

As for the general approach - it seems that Xilinx's idea for how design process is set up is this:

1. Modules are developed much more rarely than they are used in designs.

2. Engineer who integrates modules into the system, and engineer who develops custom modules - are two separate persons. Hence separate Vivado projects for the module and the system, and the concept of "packages".

A agree it's not very user-friendly, but once you understand the logic behind it it starts to make some sense. I was very apprehensive to it as well in the beginning, but than after realizing that Xilinx is the only FPGA vendor that gives so much IP cores for free, I took my time to learn it, and more or less learnt to love it :) 

Good luck with your designs!

Link to comment
Share on other sites

11 hours ago, Paul_kimelman said:

If the Microblaze MCS then allows use of the SDK to build the SW, of course I would be interested. I will try it then because I have given up on this designer thing. I have wasted a lot of time on trying to use their tool but it is just broken. I did not the only way to use it was to follow some narrow use to the letter (including not using their IP catalog to use their provided IP since it was too unreliable). This should have been a 2 hour job - anything I have done with ISE in the past has been 2 hours. Thanks, Paul

I've posted detailed step-by-step instructions here: http://thingselectronic.blogspot.ca/2017/04/creating-vivado-project-with-microblaze.html

Please let me know if you made it to work, or if you have any questions.

Link to comment
Share on other sites

HI Asmi, thans for the response. Be aware that you still have to create your own package and then keep playing with that and repackaging and so on. In a normal flow, I could edit my source file and generate the bit file. One click and done. Instead, I have to keep messing with the "package". It looks like the best bet is to make a copy of the system wrapper and then edit in place, but then you cannot use the designer to change anything. That is probably OK. I am just saying it is a cumbersome flow that is much messier and less obvious than it needs to be. I just do not understand the reasoning.

Link to comment
Share on other sites

37 minutes ago, Paul_kimelman said:

HI Asmi, thans for the response. Be aware that you still have to create your own package and then keep playing with that and repackaging and so on. In a normal flow, I could edit my source file and generate the bit file. One click and done. Instead, I have to keep messing with the "package". It looks like the best bet is to make a copy of the system wrapper and then edit in place, but then you cannot use the designer to change anything. That is probably OK. I am just saying it is a cumbersome flow that is much messier and less obvious than it needs to be. I just do not understand the reasoning.

Hmmm I see what is the problem. I always work on components first, and only once complete & verified, integrate them into the main system. Because components use standard AXI bus, there is no need to debug the actual communications as if they both follow spec, it will just work. This is obviously the flow that Xilinx wants us to use, so I chose to adapt it in my design process (and I used similar flow before anyways, because debugging system with several half-implemented pieces is much harder as there are too many moving parts, and often it's not clear where the problem is). 

But what do I know - I'm just a hobbyist who loves building things just for the heck of it. I've studied this stuff in the university 10 years ago, but then went for a somewhat different career (software development) :) So maybe it's different in professional environment, but I use the same approach in my professional software development, so it seems very natural to me.

Link to comment
Share on other sites

Asmi, I understand. If you end goal is this FPGA, then following their flow is OK. I do verify blocks in sim before bringing them to FPGA, but I would not be using AXI ever. I may find it easier in the end to create my own bridge since that is half the problem. Xilinx clearly did not consider that not everyone uses AXI and their flow when not is a joke. 
It still seems to me that this is more of a hobbyist flow though, so maybe it makes more sense for you. I am just using these boards as an engine to run things and this interface is in the way. I only went this way to try out the notion of using MicroBlaze for simple Firmware vs. having to use fly wire from an MCU as I normally do. If I can get one custom wrapper and then insert different RTL under it, that may still work out. That is how I would do things on Spartan 3 and then 6. I have a standard top and then insert different instantiations and just reuse the .ucf file for the pin mappings. But, in this flow it would still mean going through constant repackaging. Worse, it seems determined to copy files vs. leaving them in my standard SVN source control locations, which is not helpful. It is a shame, but I can see why you are OK with it. Regards, paul

Link to comment
Share on other sites

Archived

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

×
×
  • Create New...