Remember, HDLs were intended to model hardware. With hardware everything happens at once. By hardware, I mean a collection of logic gates connected to inputs and to the outputs of other logic gates in some fashion. This is essentially what an FPGA or an ASIC is (in an FPGA those connections are programmable). Wiggle an input and the effects ripple through the chain of logic gates - think of every logic gate as a little processor that's constantly evaluating it's inputs.
So in an HDL the first thing you need to consider is that all assignments are happening at the same time. The only place things happen in the "normal" sense (one statement following another as in a regular programming language) is inside of a process block (in VHDL, or an always block in Verilog). But then you have to realize that all of the process blocks (or always blocks in Verilog) are also executing concurrently.
HDLs are just trying to model the concurrency of hardware.
As far as books that try to teach HDLs to software developers... I don't think there are any. Most are aimed at Hardware Engineers.
You mentioned that you've done some Ruby programming. If you want to play with an HDL written in Ruby you can try out RHDL: http://rhdl.rubyforge.org/ The basic HDL concepts are there and it looks a lot like VHDL, but it's Ruby so you can experiment a bit more with the innards. You can write models and then simulate them. There are some examples included.
I like the Arduino, easy to use, open source and a great community!
Good to get started with, and uses a subset of C/C++.
Also, has alot of addon hardware available, like GPS, Bluetooth, Wifi etc
My experiences with Arduino have been nothing but good, from the point you get it out of it's box (and install the free compiler on either Windows / Mac / Linux), to building your first 'sketch' (a project or application for the Arduino).
Making an application is easy, you have a Setup
Method, which is called on startup, and then a loop
method which is looped while the Arduino is running.
Then all you have to do is hook either inputs or outputs up to the pins on the Arduino board, tell the code what they are and hopefully you'll get the desired output.
One other really good thing about the Arduino (and others I'm sure) is that you now have a use for those old broken printers, or 2x CD-Rom's that no one wants, and every other little bit of out dated technology. It's amazing what you can find in a server room!
Now, I have only worked on small projects, like plugging in an LCD, and reading the room temp and various projects like that. But based on what I have done, I am happy with the Ardunio, it gives a good base to embedded programming and if it's not enough, you can always go bigger!
My 2 cents!
Best Answer
Serial interfaces are fairly simple to work with. But they do require some sort of a decoder on the other end (such as a UART.) Another option would be using the parellel port. The advantage of using a parallel port is you start with a break out of the I/O pins. You can typically control 8 devices with a very simple to build interface.
Most platforms gave a simple way to gain access to the LPT ports without too much effort and again they are very easy to interface.
Quick results for tutorials...
LPT Port Info...