Your question is a little confused, but perhaps this will help clear it up.
There are two areas to consider:
- whether the execution core can directly operate on items in memory
- the speed of operations on memory
Small embedded microcontrollers
These small microcontrollers have no external RAM. All RAM is internal, but some of it is used for specific things like registers.
For example, the Microchip PICs you mention have a "W" register. This is just in normal RAM like everything else, but instructions with two operands usually require one of them to be in the W register.
This greatly simplifies the design of the microcontroller at the electronics level and keeps costs/power low. It also has other benefits like predictable timing (in cycles) for instructions.
This is why you will see instructions that load W with a value, operate on it and then copy it back from W to elsewhere in memory. The compiler uses the register because it has to.
Larger processors
Other processors (CPUs) such as x86/64 have external RAM which is a big difference. Notice now a "register" means something very different because we have different types of memory.
External to the CPU is large quantities of RAM, internal to the CPU are a number of smaller blocks of memory. Some of these are storage registers that hold an amount of data, usually the same as the data width of the architecture. So for a 32 bit Intel processor the registers (such as EAX, EBX etc) are 32 bits wide.
These processors have more complicated instructions that can often operate on either registers or external RAM. Data for an instruction does not always need to be in a register. Therefore why would we bother? The answer is speed. Where there is a choice the compiler will use registers to reduce execution time.
These complicated processors have different access times for different types of memory. Registers that are on the CPU die are very quick to access. So if you have a variable which is in constant use throughout some code it makes sense to load it into a register, operate on it repeatedly and then copy it back to external RAM when finished.
Instead of AND gates you need to use tristate drivers. These drivers go to a high-impedance state when they are not enabled, which allows some other device on the bus to control the bus signal voltages. Presumably, the control logic allows only one register output to be enabled at any given time.
Logisim calls these drivers a "controlled buffer", by the way.
Best Answer
First let me define a simple Register
INPUTS: Write,Data_in[16],CLK
OUTPUTS: Data_out[16]
IF the Write pin is HIGH, the data in the Data_in[16] will be stored in this register the next clock cycle (Rising or falling edge)
The Write pin is connected to the DMUX outputs so you can choose one of the 8 registers to write by providing the proper select value[SEL pin] and a '1' on the Dmux input
So for example if i want to write data in R5
1- Put the data in regval[16]
Since regval[16] is connected to all the 8 registers, we need to select only one of the 8 registers to store this value
How can we make this !
By using a DMUX
2- I`ll set dsel[ 3] to '101' to make sure that the DMUX is selecting the 5th register
3- Then i`ll set dwrite to '1' to make sure that the 5th register 'Write' pin is triggered HIGH and the data in regval will be stored only in this register the next clock cycle edge
Now we are able to Select one of the 8 registers and write the data only to it even though all the registers Data_in[16] pin are connected to the same bus (regval)
Same idea when reading
Connect all the registers Data_out[16] pin to the Mux inputs, then output only one of them by providing the proper value on the select (sel) pin
For example if i want to read the value of R5
1-I`ll put '101' on dsel[ 3]
2- read the register stored value from the Mux output
Why dsel,ssel,tsel
when making an ALU operation for example adding two numbers and storing them in a register
R[d] = R[s] + R[t]
D is the destination register where the result is stored
S and T are the two operands