0

Specifically, if the assembly instruction has a constant as one of the operands, how would instruction decoder pass it to the ALU? So far I thought of three ways to do it.

  • Pass the constant into a free register and then pass the address of that register to the ALU.
  • Pass the constant in the same bus as the address would go and separately trigger some enable 1-bit bus to signify its a constant.
  • Have a completely separate bus for a constant, and a 1-bit enable bus.

So far I see drawbacks for all three of the abovementioned methods.

  • First one forces to keep track of "busy" registers, and requires more clock edges per cycle making CPU slower.

  • Second one limits the size of the constant to the size of address bus.

  • Third one increases the complexity of the internal circuitry.

Do real CPU's in the microcontrollers use any of those ways? Or are there other solutions? What are they if so?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Nikolai Savulkin
  • 697
  • 5
  • 12
  • 2
    Block diagrams of simple MIPS CPUs typically mux the ALU's input to select between a register-file fetch result vs. bits decoded from the instruction work. (Which will be the immediate for an I-type instruction.) e.g. [this question about something else](https://stackoverflow.com/questions/48743787/pipeline-memmemory-and-ifinstruction-fetch) happens to show one, which looks like a non-pipelined version of MIPS. (With unconditional sign-extension, or zeroing again is part of the mux for bitwise instructions.) A non-pipelined MIPS removes the complexity of bypass forwarding. – Peter Cordes Mar 21 '22 at 18:51
  • @PeterCordes thank you very much for the info, sadly a bit too much of terminology you use is unclear to me. Afaik MIPS is the chip architecture, but I'm not sure if mux stands for multiplex and what is meant by unconditional in unconditional sign extension or what are I-type instructions. Is it possible to explain it a bit more beginner friendly? – Nikolai Savulkin Mar 21 '22 at 19:10
  • 1
    MIPS machine code is intentionally designed to use a few simple formats (unlike 8-bit microcontrollers which often need more decoding.) All opcodes that use an immediate are "I type", with the 16 immediate bits in the same place in the instruction word. Google it if you want. A few of those instructions use the immediate zero-extended instead of sign-extended (unlike RISC-V), so I found it odd that the block diagram just has a "sign extend" block on that path with no apparent control signal to make it conditional on which instruction. (And yes, a mux is a multiplexer in circuit terminology.) – Peter Cordes Mar 21 '22 at 19:59
  • no such thing as a free register, not possible for the processor to know. bottom line you simply design it in. you are already muxing in the registers and for some architectures memory based operands, so what mux in an immediate or three as well... – old_timer Mar 21 '22 at 23:39

1 Answers1

3

Pass the constant in the same bus as the address would go and separately trigger some enable 1-bit bus to signify its a constant.

What you're describing as a 1-bit indication is called a control signal, and it is used by MUXes to select the proper input when more than one is potentially available.  A MUX is a selector — it selects between two (or more) choices.

In C language expressions, we might write that ALUIn2 = Signal ? RegData2 : immediate, which says, under control of the 1-bit boolean Signal, choose either some register data value or the immediate.  We would have preceded that with RegData2 = reg[source2Field] and immediate = signExtend(immField).  That ?: operation is what MUXes do: select one from two (or more) choices.

In choice made in MUXes, often one input is totally inapplicable and the other is totally appropriate.  While the control signal is dynamic, what the hardware is doing is computing, in parallel, multiple options.  It doesn't wait until it knows which one is the right choice for the current instruction, instead it computes many possible things, and then chooses the right one later.  So, a number of parallel computations are being ignored/discarded every cycle.

However, the address bus would probably be bypassed, so as to send these data items directly to the ALU (directly modulo the MUXes and other logic, lookup and/or sign extension).  When a data item is sent between two components, we usually don't think of that as a bus, but rather wiring.  It could meet some definition of bus, however.

The limitation on width of constant would still be present though, but that would be apparent in the instruction set architecture and machine code encodings, and an issue for programs to work with/around.  The hardware would simply have to accommodate the instruction set's largest constant size, which would usually be the same as data size (which is usually the same as address size).


Have a completely separate bus for a constant, and a 1-bit enable bus.

Some processors will already have a bus for one or the other of the ALU inputs.  The constant would be given access to this bus.

Other processors will have simpler wiring feeding to the ALU inputs, but this wiring will choose between several options, and like I said above could be seen as a bus-like entity of sorts.


Pass the constant into a free register and then pass the address of that register to the ALU.

  • The processor doesn't really keep track of free/busy registers — that is the (machine code) program's job.  (this applies to architectural registers, not rename registers; also some CPUs do broadly mark whether any of the floating point registers were in-use, to help speed context switching for processes that don't use floats).
Erik Eidt
  • 23,049
  • 2
  • 29
  • 53