I think I have some fundamental problem understanding the whole gate-logic or something...

I did the whole of project 1 by looking at the truth tables and figuring out which combination of gates I should use. For the multiplexer I used the disjunctive normal form to determine how to connect the gates though I find the de-multiplexer a little "eh..".

For chips like DMux that have multiple outputs, first think of them as N independent circuits. After you have equations for them, then look for common subcircuits chared between 2 or more of the outputs.

And I don't really understand how if-else statements could be translated to connections via chips and so on.

Sounds like you have some programming experience. Are you familar with "const" or "final" variables? Hardware is like writing code with

**only const variables**. So The comments in ALU translate to something like

final int x1;
if (zx == 1) {
x1 = 0;
} else {
x1 = x;
}
final int x2;
if (nx == 1) {
x2 = ~x1;
} else {
x2 = x1;
}
...

As Ivan said, hardware makes you think different.

Another approach is to think backwards. For the ALU:

out = function output or not function output, depending no 'no'.

function output = And16 output or Add16 output, depending on 'f'.

...

You can even write the HDL in that order since it is a set of wiring instructions, not a linearly executing script.

I have no idea which chips to use when and more importantly WHY to use them.

I don't really understand the contribution of each one of them (I mean, if I see some requirement, I don't have that "ohh! I should use that and that chips" thinking ).

For chips like Bit where a diagram is presented, it makes sense to write the HDL from the diagram, leaving blanks for unknown / unnamed parts.

PARTS:
// Put your implementation here.
Mux(_a_or_b_=out1, _a_or_b_=in, sel=load, out=dffIn);
DFF(in=dffIn, out=out, out=out1);

Note that this is hardware and you can solder more than one wire to "out=".

Then by thinking about how the Mux's "sel" works and when the Bit should load a new value, you can assign "a" and "b" inputs correctly.

If you have trouble conceptualizing how the synchronous sequential logic works, ask and I'll post a follow up.

I second Logisim and Code. Also useful may be

play-hookey--Mark