Lesson 8: The MOV instruction

You will implement the first instruction of your S3 processor. Only access to input and output registers will be solicited. You will have to set up your FSM which ensures not only loading your instruction to execute but also triggering commands for the realization of this statement to all possible register transfers. Building your FSM as we introduced it in TP5, provides a pipeline operation in two stages. You may have noticed in Question 2 of the previous lesson. The first stage decodes the next instruction to execute, while the second stage executes the instruction under execution. This pipeline allows two instructions under processing simultaneously in two different states of progress.

The data transfer from one register to another results in duplication of information in the destination register. For your S3 processor this instruction is essential. Operation of S3 is so simple that you should always generate the register transfer instructions before you start a calculation or memory access. The register transfer as tested in the previous lesson can be generalized for all registers. It is then necessary to propose an instruction that triggers these transfers: it's the MOV instruction that will establish it!

Knowledge requirements

Register, buses, automata, addressing modes

Objective

You will implement the first instruction of your S3 processor. Only access to input and output registers will be solicited. You will have to set up your FSM which ensures not only loading your instruction to execute but also triggering commands for the realization of this statement to all possible register transfers. Building your FSM as we introduced it in TP5, provides a pipeline operation in two stages. You may have noticed in Question 2 of the previous lesson. The first stage decodes the next instruction to execute, while the second stage executes the instruction under execution. This pipeline allows two instructions under processing simultaneously in two different states of progress.

The project

After choosing a codification for the MOV instruction, you will decode the instruction in your FSM. If this instruction is a MOV, you have to open the right source register on the data bus and the proper destination register to write the data from this same bus. Only some registers accept writes from the bus. On the contrary, all registers can be opened to the bus, if none is opened, the constant X0000 is then conveyed on the bus and eventually copied into the destination register. This is equivalent to a register reset.

The connections to the bus

Open the TP8 you copied at the end of the previous lesson. To begin, select all GND that you placed on connecteur16 entries and delete them.

On each input so released, place a wire and name them in order from top to bottom carefully without any mistake (Register_name to Bus): R12B, R22B, R32B, R42B, R52B, Rled2B, Rsw2B, R7seg2B, Rsrc12B, Rsrc22B, Rdest2B, Ram2B, RDM2B, CO2B. RI2B is already created. On the registers, you must add a wire on the CE not yet connected. Here are the names to place on these wires and in the same order: B2R1, B2R2, B2R3, B2R4, B2R5, B2Rled, Rswload, B2Rsrc1, B2Rsrc2, Rdestload, B2Ram, Rdmload. The CEs of CO RI and R7seg are already connected. Here are some of the connections you should get.

Figure 97 The controls Buses to register and register to bus

The MOV instruction

The instructions of the processor S3 are coded on 16 bits. The first 4 bits are used to encode the code operation. There are three 4 bit fields for operands or also to specialize an opcode.

The MOV instructions will have b0000 as operation code. The second field is not used, the third field codes the address of the source register, the fourth field codes the address of the destination register. The coding of the registers will be in the order of their position in the diagram:

For example the instruction b0000_0000_0011_1100 or x003C corresponds to MOV R3 Ram. The registers Rsw RI and Rdest can not be the destination of a MOV. They are not connected to the input data bus. For Rsw register, place a Vcc (= 1) on the CE port to force the load at each clock tick. This register provides a copy of the switches at every clock tick....

It is your FSM that will decode the next instruction to execute. Therefore the next instruction to be executed is an input to the FSM. On the output, the FSM must produce the register number to transfer on the bus and the register number to be loaded from the bus. The number b0000 allows to not trigger anything, that's why the S3 processor has only 15 registers. To go from the number produced by the FSM to the selection wires you have just added, you should use two decoders 4 x 16 which activate the wire whose number is placed at the input: b0101 activate the wire 5 which is R52B in source or B2R5 in destination.

Modifying your FSM

To start you need to change the ports of the FSM. open the file Fsm.vhd . You will first do a cleaning.

    1. Delete in entity the ports out B2CO, B2R7seg and RI2B, keeping only the post clk and the ports COinc and RIload.
    2. Remove the 3 internal signals B2CO_i, B2R7seg_i and RI2B_i.
    3. Delete the values of state_type type only keep chargement.
    4. In Next_output, remove the initializations of the two internal signals B2R7seg_i and RI2B_i as well as what is contained in the case.
    5. In Next_node delete the contents of the case.
    6. In Synchro remove the update of the 2 output ports B2R7seg and RI2B.

You are ready for the construction of the new FSM. Start by adding the ports in the entity. It takes an input port to receive instruction and two output ports for the selection of source and destination registers of MOV. I propose to name them Instr (15:0), source (3:0) and dest (3:0).

Declare the two internal signals for the two new output ports, source and dest.

You must have one element in the enumerate type declaration. It remains chargement. In the process Next_output, you must initialize your two internal signals source_i and dest_i to B0000. Then there remains only one state in your FSM. It should trigger the CO increment and the storage of the current instruction in RI. Also if the instruction is a MOV you must store the source number obtained from the first operand of the instruction and the destination number from the second operand of the instruction. The register transfer will be effective at the same time as storing the increment of CO and the storage of the instruction in RI. For the time being, the storage in RI is not used much and you do not need to load it. As the instr input signal is in a predicate if it must be added to the sensitivity list.

Regarding the process Next_node, simply update the case. Here the automaton loops on the single loading node. You could simply delete the case .. Keep it, you will use it in the future …

For process Synchro, simply update the new ports from the new internal signals.

You are ready to generate the symbol associated with this FSM. Once generated, you need to update it in S3, it will replace the symbol created in the previous lab. ISE should ask you automatically. Check that clk, COinc and RIload are still connected. Connect the input instr(15:0) to the output bus of insmem on the Port spo(15:0). Add two horizontal buses on the source and dest ports and name them source (3:0) and dest (3:0). We need now to decode the numbers carried by sources and dest to activate the corresponding wire that is connected either to connect of connecteur16 or to the CE of the registers. Of course we must respect the previously selected codification. ISE offers a D4_16E decoder that will establish the decoding for you. Place a first D4_16E under the FSM after rotating it 90 °. Add 16 small wires on the outputs. At this time make a copy and paste to create a second D4_16E that you will place on its right. With 4 Bus Taps you must connect dest (3:0) on the 4 inputs A3 A2 A1 A0 respecting the weight of the wires. Do the same with the second decoder and source (3:0).

You just still need to name the outputs of your two D4_16E. No error is permitted. Help yourself by the following diagram to follow the order of our registers R12B, R22B ... on outputs 1, 2, … of the source decoder, B2R1, B2R2 .... on the outputs 1, 2 ... of dest decoder. Finally place a Vcc at both inputs E of the decoders to make them active.

Figure 98 FSM connected to RI and its two decoders

Figure 99 Zoom on the destination decoder

Figure 100 Zoom on the source decoder

Your S3 processor is ready to execute its first program.

The first program will retrieve the value entered on switches, which is automatically copied to the Rsw register. To test a few registers transfers, first copy it in register R3 then R3 is copied to R4 finally R4 is copied R7seg for display. If the source of a MOV is not selected (b0000 code) by our assumption on the connectors, the value conveyed on the data bus is X0000. MOV 0 R5 copies the value X0000 in the register R5.

Just put this program in your insmem instruction memory. For this you need to edit the file prog.coe and copy the first 4 hex following instructions. you must always place a first instruction b0000 0000 0000 0000 at the beginning of the program. The reason for this limitation is related to the simplicity of the S3 processor: no reset signal that initializes the processor. Thereafter we shall call it NOP instruction: it does not transfer and does not trigger any operation. You can also leave other instruction than MOV at the end of the program. Normally, your case will not take it into account.

Once the file is updated and saved, open the IP_Core insmem and update the initialization file on the third entry screen. Make a show to be sure that you entered the right file. Finally, we must rebuild the component by Generate. Once this ISE task is completed, update the diagram S3 by clicking on the diagram, as symbols had changed, recreate component S3 and update it in toplevel.

You can simulate toplevel using toplevel_tb without changing. Choose the ports q (15 0) of the registers you want to watch (RI, CO, R3, R4, R7seg in order on the simulation window). X12 value is always initialized to switches in toplevel_tb.

Figure 101 Simulation of your first program

Start the final generation and test the program on the board. Make a copy of the project and name it TP9.

An assembler in two minutes

Actually copying hexadecimal codes in a file is tedious and might generate errors. From S3 processor instruction set is fairly simple to create a very simple assembler with the sed command. This linux command is also available under Windows. Simply install the latest version. Here is the one I used when writing these labs.

http://sourceforge.net/projects/gnuwin32/files/sed/4.2.1/sed-4.2.1-setup.exe/download

Then simply Create an S3asm.bat file that contains all your sed commands. S / xxx / yyy / produces substitutions of each strings xxx by a yyy string.

In a dos window run then the command on a text file containing the assembly code of your program. Change your path if necessary.

sed -f S3asm.bat my_file.S3 >my_file.coe.

The format of my_file.S3 must only use keywords existing in your S3asm.bat file or hexadecimals all between a begin and an end. You may notice that the first X0000 instruction is automatically generated by the translation of begin. No need to rewrite in your assembly code. All keywords are uppercase, but the first command of S3asm.bat converts all lowercase letters to uppercase ones, both are thus equivalent. The second sed command removes lines beginning with --, these are comment lines. Here is the code my_file.s3 your first S3 program.

Your turn

Question 1: Modify the program to also display the value on the LEDs (RLED is the register 6).

Question 2: Why the program runs infinitely and not once? What does your CO do ???

.