Having written large, complex pieces of software which were bug free, I don't think buggy products are inevitable. As I wrote in a 4 page memo I sent to the 2nd A list OEM. "Bugs in software may be inevitable, but shipping them to customers is unprofessional."
That's true for any product, I think.
But let's step back even further. The previous discussion was all about synthesizing logic and fitting it into the resources available in the target device. That process, which can seem unwieldy because of the tools, is actually straightforward.
There is a significant assumption about it, though. The assumption is that the logic you wish to implement in your chip is
functionally correct. That is, if you take a design which is functionally correct and you synthesize it according to the rules and you constrain it properly and you meet the constraints, it will work.
And the truth is that verifying that your logic design is functionally correct is hard. Simulation is part of the verification process. Writing a comprehensive test bench is not trivial, especially when your FPGA talks to a peripheral as a data source or sink. (This means you need to obtain, or more likely write, bus-functional models of the things you connect to your FPGA, and then you have to verify that the models are correct!) The test bench should do more than generate a clock and reset, and staring at waveform displays isn't verification. It just shows you what is happening for a given set of conditions, and doesn't tell you what it
should be doing for that given set of conditions.
A test bench should apply test vectors and verify that the output is what is expected. Yes, it should be obvious, but it must be stated -- you have to know what you should get out of the circuit for a given input!
Now there are a bunch of people on this forum who are manly men and refuse to do any kind of simulation. Their design skills are clearly impeccable and they don't make even the smallest of typos. Or, they say, "I'll use ChipScope, it's faster than writing a test bench." Except when a place-and-route cycle takes an hour, and if you forget to include a signal to monitor, or make some other omission, then it's another hour wasted. Or, sometimes the case might be that the debugger core makes the design not meet timing, and then you can't trust its output.
You can't do serious FPGA design and development without understanding how to functionally verify a design.
If you know of good discussions of software engineering in the context of HDLs I'd be very grateful if you would post or send me links.
I have not seen any. Hell, given that FPGA design is all text-based design entry these days, you would think that every professional FPGA designer has embraced source-code control for their designs. But you would be wrong.