Hi,
This is my first post so please be gentle.
Keep in mind that:
- FPGA is not software. You do not write "programs" for FPGA, you write schematic, with flip-flops and logic gates and so on, except you'll use text to describe the schematic, instead of drawing lines like you do with other electronic schematics.
- you'll need to know/learn digital design, meaning logic gates, flip-flops, multiplexers, counters, state machines, Mealy Moore state machines, synchronous design techniques (e.g. clock domain crossing, metastability, etc.) and so on. It's not software, it's hardware. It's all digital schematics written in text, and called HDL (Hardware Design Language). For example, Quartus still retains a graphic editor, where you draw flip-flops, and logic gates, and circuits from the 400 TTL family to design your schematic instead of describing your schematic wit VHDL or Verilog "code".
For my first meaningful FPGA program, I chose to add more functionality to an open source oscilloscope project. Being a long-time firmware programmer, I am used to programming in C, and toggling GPIOs and viewing on a logic analyzer to debug.
I needed to do the following, which I could figure out how to do like a programmer, but I had no idea of how this could be done writing a schematic:
Use 1 to 10 4K BRAMs, (which allows up to 8KB samples if using 4 channels, or 40KB if using one channel.
Turn the BRAMs on and off at the appropriate time, and from experiments it seemed I had to turn on the BRAM one clock cycle before I actually wanted to store to it.
If doing peak detect, use two BRAMs per channel, one for high voltage, and one for low voltage.
If doing hi-res, average multiple samples per interval.
In addition, since I was acquiring samples at 100 MHz, looking for trigger, storing samples to BRAM each cycle, and then sending all the data out over a serial port, it seemed much easier to use GPIO toggles to debug rather than figure out how to create a simulation to do all this. Also, most of my bugs seemed to occur when I was switching from one BRAM to another, or the samples to store before the trigger occurred in a different BRAM in the linked list of BRAMs.
Since verilog looks so much like C, I just relied on the compiler to turn it into hardware, which seemed to work fine in most cases. The only real problem I had was that it seemed that when I saved the offset and BRAM number of when the trigger occurred, sometimes it did not get saved correctly, but when I added a GPIO toggle when this occurred, it worked (kind of like it was getting optimized out). I tried looking at the netlist RTL viewer, but it is gigantic and hard for me to follow.
Could someone tell me why thinking of the flow as a programmer would instead of how a hardware engineer would is so bad? (I did trigger almost all actions to occur on the clock edge, and used <= for non-blocking assignment, so timing was not an issue.)