Lesson 9: ALU

You will realize an ALU offering up to 16 different functions. In the mean time, just a few will be implemented. This ALU is inserted between the registers Rsrc1, Rsrc2 and Rdest. In advance register transfers must bring the data to be manipulated by the ALU in the two source registers and the result will be stored by another transfer of data in the destination register. Consequently there is no operand for your ALU functions which will greatly simplify the realization of the FSM.

Data transfer is only useful if in a way or another the system can change it. It is the ALU (Arithmetic & Logic Unit ) that will play this role.

knowledge requirements

Register, bus, integer number, 2's complement.

Objective

You will realize an ALU offering up to 16 different functions. In the mean time, just a few will be implemented. This ALU is inserted between the registers Rsrc1, Rsrc2 and Rdest. In advance register transfers must bring the data to be manipulated by the ALU in the two source registers and the result will be stored by another transfer of data in the destination register. Consequently there is no operand for your ALU functions which will greatly simplify the realization of the FSM.

The project

You will instantiate an ALU skeleton that can instantiate up to 16 elementary functions. For each of these functions a binary code must be associated in order to achieve the control by the FSM during decoding of the instruction. The mini assembler will also support these new instructions.

The ALU

Open the project TP9 from the copy of the previous TP8. Add a new schematic source named ALU. The operation of the ALU is simple. You will place in parallel all circuits that perform a function, here you will build an ALU with maximum 16 functions. The ALU produces at any time 16 results in parallel, it is necessary then to select the right result according to the code of the function. To operate the ALU, the FSM will have to generate control signals when an ALU instruction is decoded. First, let us define the format of an ALU instruction. I suggest as a first field b0001 which means an ALU operation. We still have then 12 bits which gives the ability to choose one function from 4096. Only the second 4-bit field will be used here. It will allow you to select one function from a maximum of 16, it is this one that will produce the result on the output of the ALU. You can modify the FSM later depending on this coding.

Use the mux2x16 that you have already defined. Place two buses a(15:0) and b(15:0) with their I / O Markers vertically on the left side, and a bus OP(3:0) at the top, its 4-bits code the number of the function to be realized. Place a first column of 8 mux2x16 then a column of 4 and a column of 2 and finally a column of 1. Connect the outputs to the inputs to create your mux2x16 tree. Immediately remove the subtree of the 3 mux2x16 on the top left, they will not be used. Then with Bus Taps, OP(0) is connected to the selectors in the first column, OP(1) for the second etc ... on the output of the last mux2x16 you can place a bus and its I / O Marker named s(15:0)

Your ALU skeleton should look like this diagram, missing only the two input buses a and b.

Figure 102 1 out of 16 selector based on OP(3: 0)

You still have to put from top to bottom, with function codes from b0000 to b1111, the functions you want to instantiate. Here is a first list of 11 features that you can complete yourself afterwards.

SUBC, ADD, SUB, ADDC: these four functions are realized by the component ADSU16 from the Arithmetic library. That's why you have removed 3 mux2x16. Point to this component and read Symbol Info. This component allows alone to realize 4 different functions here are their S3 code.

SUBC : A – B – 1 code 0000

ADD : A + B code 0001

SUB : A – B code 0010

ADDC : A + B + 1 code 0011

You will notice in the proposed encoding that the LSB to allows to select either ADD or SUB. As for the next bit, it is used for selecting a function with or without carry (equals to 1) for both types of operation. The next two bits having the value b00 select your ADSU16 as producer of the final output of the ALU, they will each control a 2x1 multiplexer of 16 bits wide. So instantiate a component ADSU16, connect the buses a and b to the inputs A and B of the component. On the ADD wire of the component simply connect the wire OP(0) to select ADD or SUB type. connect on the wire CI the wire OP(1) to select with or without carry. The output of ADDSU16 is directly connected to D0 of mux2x16 of the third layer.

Figure 103 4 functions ALU in a single component

INV: this function converts bit to bit the 16 bits from 0 => 1 and from 1=> 0. Place an INV16 on the bus a. Connect the output of the inverter on the first mux2x16 of layer 0, on its D0 port. By this positioning its function code is actually b0100.

Figure 104 The inverter on bus a

AND, OR: These operators perform an AND or an OR bit to bit on 16-bit inputs. Create the schematic andor. Lay out in the center two vertical buses as inputs a(15:0) and b(15:0) and two vertical output buses on each side of the inputs. Name them sand(15:0) and sor(15:0). Place 16 AND2 beside the bus sand and 16 OR2 beside the bus sor slightly shifted. Place the Bus Taps between the buses a and b and the inputs of the gates, then to sand and sor from the outputs of the gates. Create the symbol and place it in the ALU.

Figure 105 AND and OR on 16 bit words

Figure 106 AND and OR in the ALU

INC: You could realize an increment by an addition with carry by placing x0000 in one of the two ALU source registers. In order to win a register transfer and thus a cycle, you will instantiate the symbol inc that you created to increment the CO Register. Then simply connect the input of inc to the bus a, its output will be connected to the next D1. The function code of INC is b0111.

CPL2: To calculate the two's complement of a number simply invert and add 1. Place both components as one after the other between the bus and the input of the next D0 selector. Its code corresponding to the b1000 selection.

Figure 107 Increment and 2's complement

CONCAT: The switches allow you to enter 8-bit words. To enter a 16-bit word there must be two successive inputs on the switches then the 8 bits of the first entry should be concatenated with the 8 bits of the second, the order must be chosen by example first the least significant bits then the most significant bits. Create a new schematic source named concat. Place there two buses and I / O Marker respectively a(15:0) and b(15:0). Place a bus named s(15:0) vertically to the right and with its I / O Marker. You still have to place the first 16 BUF The first 8 are connected to a(7:0), the second 8 to b(7:0). the 16 BUF are connected to s(15:0) output. Respect the indexes !!

Figure 108 Concatenation of two 8-bit words to a 16-bit word

You can generate the symbol and go back and place it in ALU. The output is connected to the following port of mux2x16.

Figure 109 Concatenation in the ALU

ID: The identity function copies the input a(15:0) on the output s(15:0). This is the simplest function just connect the bus a(15:0) on the following mux2x16.

You could further place 5 functions in this ALU. For more than 16 functions, the size of the code must be increased to 8 bits for example with thus 256 possible functions. It's pretty easy to implement. For the time being, it is sufficient.

Figure 110 Overview of the ALU

Your ALU is ready, generate the symbol and just instantiate it in S3 to the left of the register Rdest. Just connect the input a to the output of the register Rsrc1, the input b to the output of the register Rsrc2, the output s to the input of register Rdest. Add a wire on the port OP(3:0) and give it the same name. You also need to add the Rdestload signal on the output 11 of the destinations decoder D4_16E and on the CE of the register Rdest.

Figure 111 Consideration of Rdestload signal

Figure 112 Insertion of the ALU in the S3 processor

Modifying the FSM

Add an output port OP(3:0) in the entity in order to select the appropriate function in the ALU.

Declare an internal signal OP_I(3:0).

Modify the Next_output process by initializing the internal signal OP_i. Then if the instruction is not a MOV, test if it is an ALU function. If so , modify the decoding of the instruction to identify the function of the ALU instruction. In this case, you must also trigger the loading of Rdest register by activating the port dest(3:0) with the value associated with Rdest which is b1011.

Add in the process Synchro the validation of output OP from OP_i.

You can then recreate the FSM symbol and update the S3 diagram. Now simply connect the output OP of the FSM with the input OP of the ALU. To do so create a wire on the output with the same name OP(3:0), by associating the names, the ports are connected. You always have the option to edit the symbol to move for example a port on the symbol.

Figure 113 FSM controlling the ALU

In order to test your processor, I propose the following program: entering a value on the switches, adding this value to itself, display the result on the display.

Here is the program to generate an initialization file of the instruction memory insmem, modify the prog.coe file by replacing the instructions according to the following hexadecimal code.

You need then to reload it into the ROM by reopening the IP_Core and on the third screen select Generate once the file is loaded and displayed. If IP_core does not find the old file prog.coe it may deny opening it, I advise you to remove insmem (right click> remove) from your project and recreate it.

Update the instances of symbols modified in S3. Recreate the symbol S3 and update it in toplevel. Run a simulation on toplevel_tb. By observing the output Q(15: 0) of the register R7seg, you should get the value x24 since in toplevel_tb you initialized the switches to x12. (the q(15: 0) of R7seg, CO, RI, Rsrc1, Rsrc2, Rdest in order)

You can generate the toplevel.bit and test it on the board. To complete the lesson, make a copy of the project on TP10 for the following lessons.

Your turn

Question 1: Replace the ADD instruction by all other ALU instructions one by one and recompile at each change. Check thus the semantics of your ALU.

Question 2: Update the S3asm.bat file to support the new instructions ADD ... CONCAT.

Question 3: Construct an ALU that does the same thing but in VHDL. You will see that sometimes it's easier to use VHDL (A 16 bit alu in VHDL) particularly here. You can then use either one. You will have the ability later to add functions for the unused codes.

Question 4: Add the function DEC for decrement.

Question 5: Add the MUL function that multiplies two 8-bit unsigned numbers.

.