I have recently started seriously coding in Verilog HDL. Although I am still to get a grip of FPGAs and CPLDs, I am curious about the levels of abstractions used in these codes. I understand I have 3 options right now, Behavioral, Register Transfer and Gate level modeling. But I cannot decide which is the most suited for good synthesis. For example, when making smaller circuits I dabbled in Gate level modeling, but later on when I moved to describing my own ALUs I used behavioral level modeling. But Behavioral modeling feels like just concurrent programming and not exactly hardware description. So what is the best way to write code which will ensure proper synthesis?
You should completely ignore the terms "behavioral", "Register Transfer", and "Gate level". I think these terms were invented by professors or people writing text books and have little or no relevance to "actually getting work done". It's like scientists and professors inventing Latin names just for the sake of making them sound smart.
Write your code (Verilog, VHDL, or whatever) so that you get the results you want and your code is readable and understandable. After you have done this a while you will settle into a style that works for you.
I should mention that the only way this can happen is if you learn everything about Verilog (or whatever). Often there are features of the language that are not covered very well by books or professors but really help you efficiently write code that is easy to read.
No one should write at "gate level". There isn't any need for that outside of learning. It's just too low-level to be productive.
The most common level is Register Transfer level. However when you are inferring an adder, for example, that is "behavioral" in that you aren't telling the tools how to do it.