ECAD and Architecture Practical Classes

# Add fixed point multiply to TTC

## Introduction

As seen at the end of the first lab, doing multiplication on the current version of TTC is rather slow, taking 32 iterations of a many instruction loop. Calculating the Mandelbrot set involves many multiplications and so before writing a version of the Mandelbrot set for TTC a multiply ALU function will be added.

Another issue is that the Mandelbrot set is a plot using complex numbers, meaning the real and imaginary parts are real numbers, not integers. In this implementation we will use 32 bit words as 4.28 fixed point numbers to approximate real numbers. Two real numbers x and y are represented by two integers i and j.

i := floor(x * 2^28) j := floor(y * 2^28)

Then if z = x * y, and k is to represent z.

k := floor(z * 2^28) ((k + c_0) / 2^28) = ((i + c_1) / 2^28) * ((j + c_2) / 2^28), 0 <= c_i < 1 k ~= (i * j) / 2^28

Therefore to multiply two 4.28 numbers and get a 4.28 number a binary point adjustment must be performed using divide by 2^28 which can be achieved efficiently using a right shift by 28 bits. Constant shifts are just wiring in hardware so basically take no space.

## Add fixed-point multiply

Copy ttc.sv over from the first lab's project. Import it into the new
project. Look at the alu function. Currently there are only 7 ALU
functions in the 3 bit ALU function field. To add an 8^{th}
you will first need to add a FPMUL ALU function to the Func struct
then add an extra case for FPMUL in the ALU function itself. The
Cyclone IV FPGA on the tPad contains many digital signal processing
blocks (DSP blocks) which contain high performance multipliers in hard
logic. If you use the multiply operator ("*") in SystemVerilog the
synthesis tool knows that it can make use of these DSP blocks to make
a fast design.

Tips: remember that you will need to ensure that you get a 64-bit result from the multiplication so that when you shift right by 28-bits to correct the position of the decimal point you will have sufficient bits of accuracy. You will also need to work with signed numbers.

## Modify the assembler

Now corresponding changes in the assembler must be made. Open up Asm.java in the text editor of your choice and add FPMUL to the Func enum. Note that you should add FPMUL in the same position as you added it to the corresponding enum in ttc.sv.

## Test in simulation

Test your new instruction in simulation.

## Discussion

Embedded microprocessors (including the Nios II) often permit custom instructions to be added to speed up particular embedded code. But this does raise the issue of backward compatibility.

Early microprocessors such as the 6502 contained many undocumented opcodes. Software hackers on the Apple II quickly reverse engineered many of these and began using them in their demos and programs. When Apple released the Apple IIc it came with a 65C02 rather than a 6502. As well as containing a couple of bugfixes and new opcodes, many of the undocumented opcodes now had entirely different results breaking compatibility with some previous software. The undocumented opcodes correspond to "don't care" states. Modern CPUs trap on reserved opcodes to ensure forwards compatibility. Special instructions that are missing from an implementation will, therefore, cause an exception and the OS is then in a position to emulate the instruction as an alternative to failure.