Hades logoHades applet banner
TinyMips - multiplication

applet icon

The image above shows a thumbnail of the interactive Java applet embedded into this page. Unfortunately, your browser is not Java-aware or Java is disabled in the browser preferences. To start the applet, please enable Java and reload this page. (You might have to restart the browser.)

Circuit Description

This applet demonstrates the multiplication instructions and access to the HI and LO registers of the MIPS-I architecture on the TinyMips microprocessor.

Please check the introductory applet and the MIPS overview pages for an overview of the MIPS architecture and the TinyMips processor. Again, the hardware structure used here consists of the processor, some glue logic, and a single RAM component that stores both the program and the data generated during program execution.

The multiplication demo

One of the principles that defines RISC-style processor architectures is a simple and regular instruction set, where instructions are supposed to execute as efficiently as possible on an an instruction pipeline. As a result of this principle, some RISC architectures leave out integer multiplication and division instructions, because those operations will usually execute much slower than simple operations like addition, subtraction, or shifts, even if an dedicated hardware multiplier is used. Naturally, multiplication and division can be replaced by sequences of adds/subs and shifts.

The MIPS designers decided to include multiplication and division instructions, but to decouple those instructions from the main instruction pipeline. Instead, two separate processor registers called HI and LO are provided as the target registers for multiplication and division instructions. A processor designer is free to either use a fast expensive multiplier or cheap and slow serial arithmetic to calculate the results. To guarantee software compatibility between different implementations of the instruction set, programs that attempt to use the result of an ongoing multiplication or division will stall the whole processor until the result is ready. The compiler is expected to reorder instructions whenever possible to avoid losing too much performance while waiting for a slow multiplier.

The program shown in this applet delibaretely uses integer multiplication and remainder operations to test the corresponding instructions and access to the HI and LO registers. As the hardware still lacks an easy means of debugging output, we again store silly hardcoded data values into the main memory to indicate the progress of the algorithm. The program first stores the arbitrary value 0xcafebabe into the memory location specified by 0x3fffc (BASE-4), and then writes the multiplication table for values between 0 and 15 starting at memory adress 0x400. Afterwards, a few operations with larger operands are performed to check the TinyMips simulation models.

Usage

Wait until the applet is loaded. You can now open the memory-editor (via popup > edit) The memory editor highlights the last read operation in green color, and the last write operation in cyan color, which allows you to easily watch the program execution.

If you want to change the simulation speed, just select 'edit' on the clock-generator component, then edit the value of the clock-generator 'period' property, and select 'apply' (and 'ok' to close the clock-generator config dialog).

Similarly, open the TinyMips user-interface window (via popup > edit) to watch the current register values.

The binary program running on the processor was compiled and linked with the GNU gcc (2.7.2.3) and binutils cross-compiler toolchain on a Linux x86 host, with the final ELF loading and relocation done via the Hades Elf2rom tool. We compile with optimizations turned off (-O0 flag) to avoid that the compiler replaces most multiplcations with adds and shifts. See

for details. The following listing shows the actual C source code of the program:

/* test multiplication instruction on the Hades TinyMips
 */


#define BASE  0x00000400


int main( int argc, char** argv ) {
  unsigned int i,j;
  unsigned int a,b,c,d;
  unsigned int *ptr; 

  ptr = (int*) BASE;
  *(ptr-1) = 0xcafebabe;

  // multiplication table 0..15
  for( i = 0; i < 16; i++ ) {
    for( j = 0; j < 16; j++ ) {
      a = i*j;
      *(ptr+16*i+j) = a;
    }
  }

  // some extra checks
  a = 0x0000ffff;
  b = 0x0000fffd;
  *(ptr-4) = (a * b);  // fffc0003

  a = 0xabcdef01;
  b = 0x0030441d;
  c = a / b;           // 0000038f
  d = a % b;           // 000b86ce  
  *(ptr-5) = c;
  *(ptr-6) = d;
  

  // endless loop
  for( i = 0; ; i++ ) {
    *(ptr-2) = 0xcafe0000 + i;
  }
}


Print version | Run this demo in the Hades editor (via Java WebStart)
Usage | FAQ | About | License | Feedback | Tutorial (PDF) | Referenzkarte (PDF, in German)
Impressum http://tams.informatik.uni-hamburg.de/applets/hades/webdemos/76-mips/14-mult/mult.html