HDLs have familiar syntax that makes it seem like you can just program algorithms imperatively (for loops, if statements, functions etc) but it's all just a mean trick to catch software people out, and generally won't give the results you expect.
On top there's then the fact everything happens at the same time, the faff of making everything synchronised and making sure it meets timing and fighting the frankly awful tooling every step of the way.
Once you get it, it's fine, but you have to unlearn a lot of software muscle memory and keep the actual design work (boxes and lines) almost entirely separate from the implementation (typing your boxes and lines into a text editor).
The biggest issues are really:
1. The tooling is generally awful. Open source tooling is very primitive and not usable. Commercial tooling is unaffordable to hobbyists. There are a couple of exceptions:
a) Vivado which I haven't used extensively but seems fairly nice. Unfortunately the FPGAs it works with are not cheap.
b) I discovered that Intel provides a free version of ModelSim. I've used Questa a lot (the "pro" version of ModelSim more or less; their branding is confusing) and it's great.
It also doesn't help that all the tools use TCL which is also awful.
2. SystemVerilog is just a really bad, ancient language. It wasn't even designed for synthesising ASICs, let alone FPGAs! You're writing a simulation of an ASIC, and then some other tool tries to infer how it should run that simulation on an FPGA. It's a completely bonkers system.
It's not just the system that is bonkers. The language is too. Implicit casts all over the place, undefined values as part of the language (though not in Verilator!), multiple assignment types, ridiculously flexible array indexing.
Maybe VHDL is better... but unfortunately SystemVerilog won the language war in the ASIC space so that's what I know.
It also doesn't seem like we'll get a replacement any time soon. You'd need buy-in from the big vendors otherwise debugging will always be a total nightmare.
Though it would be nice if there was something like Typescript for SystemVerilog - something that fixed all the very rough edges and footguns but didn't change the code so much that debugging is painful.
Maybe you're working off old information, but the FOSS tooling (ghdl, yosys, nextpnr) is completely sufficient for hobbyists. If you're doing huge, high-speed designs on expensive FPGAs, sure, use the vendor tools, but for your average iCE40/ECP5-scale design, FOSS is the way to go.
Maybe in time they'll move on from the "here's a bunch of random poorly documented tools, you only have to do all of the integration work!" stage, but they aren't there yet.
In high-level languages you got functions, variables and scopes while in assembly you need to build them yourself using more primitive units, i.e. instructions and registers.
In assembly you got many helpful instructions and easy memory access while in FPGAs and ASICs you have... nothing. Only wires and boolean logic.
It allows you to build some things extremely efficiently, e.g.: Press button 1 and 2 to activate LED 1. No clocks, no memory accesses, no I/O polling or interrupts, just a direct connection from some inputs to others with some logic in between.
Although there are many modern tools, libraries and IP blocks to make FPGA programming easier or even possible with languages like Scala or C++, it usually takes way more time to build anything compared to doing it with the help of a CPU.
This seems like a mad science. Is there a recommended entry point like a book or learning resource?
The only exposure I have is from the FPGA stereo disparity module on the Mars Rover. And sadly I left before I could really pick any brains. Or ASIC Bitcoin mining.
FPGAs usually clock much lower than CPUs. If you want to beat a modern multicore CPU running at 5GHz with a 100MHz FPGA, you need to do a lot more per cycle to win. Your optimal problem is either highly parallel or solvable using a deep pipeline that gives you crazy throughput.
Since accessing external RAM is much more complicated on a FPGA and you don't have all the nice prefetching and caching levels of a CPU, you better make do with the limited on-board memory.
Usually this limits you to real-time stream processing like audio, video, packet filtering or I/O muxing.
But if you have an interesting problem in these spaces, FPGAs can be crazy power efficient and fun.
At my university, we used a ZynqBerry (Raspberry Pi format and only around $100) with the Vivado tools, so maybe that would be a good start for you as well.
https://www.waterstones.com/book/digital-design-and-computer...
There is this new book: https://nostarch.com/gettingstartedwithfpgas
The hard parts are...
a) the "fuzzy" bits -- timing, propagation delays, etc. the tool will warn you about it but it's not always easy to understand. It's easy to end up with a mess that makes perfect sense "logically" and works in your sim, etc. but actually only sorta works in meatspace.
b) the tools. They all want to ram you into their shitty 1000lb IDEs which are forks of Eclipse from 15 years ago with a heaping dose of Tcl on the side and only work in some specific version of RedHat or whatever. Forget about using your preferred editor or IDE or build tool, they want to ram you through their GUI. You can sometimes route around it, by reverse engineering their Tcl and figuring out what command line invocations rae actually happening behind the heap of wizards they want to herd you through... but you'll always end up back in Quartus or whatever at some point. HW Engineers seem to be suckers for this kind of punishment.
It's great for stuff like driving LED matrixes, offloading crypto operations, or signal processing. Anywhere you want low latency, but simple processing.
With typical programming, you're describing software. With VHDL / Verilog, you're describing hardware. When Verilog/VHDL "runs", its just the hardware existing, ready to react to whatever happens later. There's no code that "steps" through if-statements or loops... there's instead state-machines that get stored into memory... with their outputs being directed upon physical wires you name.
As far as a "language" goes, I'd say its close to C++ Template Metaprogramming, though the syntax is very different. But the concepts are surprisingly close. C++ Templates do not compile into code, they compile into concepts and layouts... so to speak.
Well, of course C++ Templates eventually turn into C++ code. But imagine if the end result were flipflops, wires, and 1-bit memory instead. Maybe I'm describing it wrong... or maybe the only way to really know is to try it yourself.