I know Verilog isn't the best option around, and I'm planning on moving onto something better but for now it was easy to get started, and from what I could see many of those better tools end up generating Verilog so would be nice to be able to debug that.
If you know how to think in logic-gate-terms then FPGAs won't be that difficult I suspect. Essentially either you have plain logic gates where the output is purely a function of the inputs, or you have edge-triggered logic thanks to flip-flops.
Just think of it as writing code that specifies how to wire up set of logic gates, muliplexers and flip-flops.
As a brief example, here's an excerpt from my very first ALU:
wire [8:0] res_and;
wire [8:0] res_xor;
wire [8:0] res_add;
assign res_and = (bus_a & bus_b);
assign res_xor = (bus_a ^ bus_b);
assign res_add = (bus_a + bus_b);
always @(posedge clk)
case (op_sel)
OP_AND: result <= res_and;
OP_XOR: result <= res_xor;
OP_ADD: result <= res_add;
default: result <= 0;
endcase
Here "bus_a" and "bus_b" are wires (which may come from registers), while "result" is a register.The wires don't hold state, while registers can. The <= means to latch the right side into the left side, in this case on a positive edge of clk. The case statement is just a multiplexer.
At least to me, it feels very much like "writing a circuit".
[1]: https://www.latticesemi.com/en/Products/DevelopmentBoardsAnd...