in HDL, some parts of the code can work at the same time, for example, two lines of code "can work" at the same time, this is an advantage to use wisely. this is something that a programmer, accustomed to linear languages, can hardly understand:
- Long and specific conveyors must be created.
- You can make your large modules at the same time.
- instead of performing a repeat action for different data, you can create multiple units and do the work in parallel.
Particular attention should be paid to the boot process - once your chip is operational, you have come a long way.
Debugging on hardware is usually much more complicated than debugging software, so:
Simple code is preferable, sometimes there are other ways to speed up your code, after it is already running, for example, using a chip with a higher speed, etc. "
Avoid smart protocols between components.
The working code in HDL is more valuable than on other software, since the hardware is so difficult to debug to reuse, as well as consider the possibility of using "libraries" of modules, some of which are free, while others are sold.
designing should take into account not only errors in the HDL code, but also errors on the chip you are programming and on other hardware devices that interact with the chip, so you really need to think about a design that is easy to verify.
Some debugging tips:
If a project includes several building blocks, it would probably be possible to create lines from the interfaces between these blocks to test points outside the chip.
You want to keep enough lines in your project to distract interesting data that needs to be checked using external devices. you can also use these lines, and your code as a way to tell you about the current state of execution - for example, if you get data at some points, you write some value for the lines, at a later stage of execution you write another value, etc.
If your chip is reconfigurable, it will become even more convenient, since you can adapt specific tests and reprogram the outputs for each test as you go (it looks very good with LEDs :). )
Edit:
By smart protocols, I meant that if two of your physical devices are connected, they must exchange data with the simplest communication protocol. those. Do not use any complicated home protocols between them.
The reason is - The fixed bugs "inside" the FPGA / ASIC are fairly simple, since you have simulators. Therefore, if you are sure that the data arrives the way you want and goes out when your program sends it, you have reached Hardware utopia - the ability to work at the software level :) (using the simulator). But if your data does not reach you, how you want it, and you need to find out why ... you have to connect to the lines, and it's not so simple.
Finding errors on the lines is difficult, because you need to connect to the lines with special equipment that records the status of the lines at different times, and you will need to make sure that your lines are operating in accordance with the protocol.
If you need to connect your two physical devices, make the “protocol” as simple as possible, to the extent that it will not be called a protocol :) For example, if the units share the clock, add x lines of data between them and make one block, in order to write them down, and another block read, thus transmitting, for example, one “word”, which has x bits between them at each clock drop. If you have an FPGA, if the original clock speed is too fast for parallel data - you can control the speed of this, according to your experiments, for example, so that the data remains on the lines for at least 't' clock cycles, etc. '. I assume that parallel data transfer is easier, since you can work with lower clock speeds and get the same characteristics, without having to split your words on one device and reassemble on another. (I hope that between the "hours" there is no delay between each hour). Even this is probably too complicated :)
Regarding SPI, I2C, etc. I have not implemented any of them, I can say that I connected the legs of two FPGAs coming from the same clock (I do not remember the exact formation of resistors in the middle), at much higher speeds, so I really can not come up with good reasons for use them as the main way to transfer data between your FPGAs if the FPGAs are not very far apart, which is one reason to use a serial rather than a parallel bus.
JTAG is used by some FPGA companies to test / program their products, but I'm not sure that it was used as a way to transport data at high speeds, and this is a protocol ... (another that may have built-in chip support).
If you need to implement any known protocol, consider using pre-made HDL code for this - which you can find or buy.