Lesson 7: Loading phase

In this lab you will continue the development of your S3 processor by integrating the loading phase. A first FSM allows you to display an instruction of a program stored in the ROM .

The execution of a program is an infinite loop that executes a sequence of instructions one after the other. Each instruction must be retrieved in the program memory, decoded and executed. The loading phase is common to all the instructions it implements two special registers CO and RI.

Knowledge requirements

Von Neumann models, Adder, registers, FSM, ROM.

Goals

In this lab you will continue the development of your S3 processor by integrating the loading phase. A first FSM allows you to display an instruction of a program stored in the ROM .

The project

In the Von Neumann architecture, I remind you that instructions and data are stored in the same memory. Here the S3 processor offers actually a Harvard-type architecture. We will store instructions and data in two separate memories. The loading phase fetches the next instruction from the program memory to be decoded and then executed. This will be done via an access to the memory from the address contained in the CO register (Ordinal Counter = PC). The instruction is then stored in the RI register (Instruction Register) and can be decoded by the control and command unit (your FSM). CO is incremented by the same time to always point to the next instruction to execute. At a branching phase (JUMP) CO will be updated directly and possibly after an internal calculation of the ALU, you will see that in the following lessons. Therefore, we need to:

    • An instruction memory: ROM is chosen that will be initialized cell by cell with the machine instructions to execute.
    • A CO incrementer
    • An input selector for CO that places either the CO value + 1, or the value conveyed on the internal bus of the processor when it will be a branch.

The TP7 project was created at the end of the previous lesson with a copy of TP6 project. First of all select in the S3 diagram the wire that connects Vcc to CE of RLED, Rsw and R7seg as well as connect of CRsw then delete it! You can also delete the Vcc symbol that was connected to it!

After each modification of S3, do not forget to re-create the S3 symbol and to update this symbol in toplevel !!!

This is true for any Schematic

The incrementer

First create the incrementer. I suggest you to create a new schematic source inc. Once it is created, an instance of the symbol of the ADD16 from Arithmetic Library will be enough for you to realize your inc. After consulting Symbol Information, complete the circuit with an input Din (15:0) connected to A (15:0) and an output Dout (15:0) connected to S (15:0) with their I / O Marker respectively. To achieve Dout = Din + 1 simply place the carry at 1 and add the value X0000 on Din. Place a constant X0000 of length 16 on the input B (15:0), force the carry CI to 1 by Vcc. Other outputs of ADD16 may remain unconnected. You can create the symbol.

Figure 81 16 bits Incrementer

Storing in CO

The value of CO can be produced either by a incrementer to move from one instruction to the next, or from the data bus when we want to force the value of CO for a jump or break sequence. So you have to place a 2-input multiplexer on the 16 wires. There is no such component in the library. You will create your own. Add a new schematic source named mux2x16. Place in the center two buses D0(15:0) and D1(15:0) between the two, place a wire S0, finally, place around a bus in U shape O(15:0). You still have to instantiate 8 times M2_1 from the Mux library to the right of the three buses, and 8 more mirrored M2_1 to the left (copy / paste) by shifting slightly upwards (otherwise Bus Tap will not connect to the bus). Connect the bus to the corresponding ports of M2_1 starting with wires x (15) via Bus Tap. Many wires but it's still fast enough to achieve. Finally place the I / O Marker. You can then create the corresponding symbol. Here is a diagram to guide you.

Figure 2x1 multiplexer 82 for 16-bit words

It was not possible to use your connecteur16 created for the previous lesson because the initial assumption is violated here. Instantiate a symbol Inc and a mux2x16 on the left of CO register. For clarity of the scheme made a mirror on inc. Then connect the input of Inc to the output of CO, the output of Inc to the D0 input of the mux2x16 the data bus bus_data with the input D1 of mux2x16. Two different commands trigger the storage of a value on CO Register: a first one commands the incremented value, the second ranks the value on the bus. One and only one command can be active at a given time. The first B2CO command (Bus to CO) drives mux2x16: when it is active it is D1 and thus the value of the data bus passes, otherwise D0 and thus the value of CO + 1. Place a wire on the S0 port of the mux2x16 and name it B2CO. Both B2CO and COinc commands trigger the loading of the CO register. Place an OR with an input named B2CO and a wire named COinc with input and one appointed stuck thread. The output of the OR must be connected to the input CE of the CO register. I advise you to name your instances incCO selectCO to facilitate the simulation.

Figure 83 CO Update

The program memory

You will build a memory that will contain all the instructions of your program. This memory receives an address from CO and returns the data stored at this address. Then it will be necessary to load it into the RI register. ISE facilitates the creation of such a memory. You will create a ROM by adding a new source in your project. Select this time at the creation IP (CORE ...), naming the symbol insmem.

Figure 84 Creation of the program memory

ISE opens a window that allows you to create the component automatically for predefined configurable functions. Choose Basic Elements> Memory Elements> Distributed Memory Generator. Click Next and Finish.

Figure 85 Memory IP generator

S3 processor manipulates 16-bit words for both data and instructions. You will create a ROM of 256 16-bit words by clicking Generate. 256 will be the maximum size of a program for yours exprimentations while CO could address a memory of 64K words. You could expand this memory for other usages later. For now this ROM contains no instruction we will return later to this ROM to initialize the contain from a file. The insmem symbol is automatically created by ISE in IPcore_dir library, you can instantiate the symbol in your S3 diagram on the left of the RI register.

Figure 86 A 256 16-bit words ROM

The ismem component has a 8 bit input bus (256 locations) and 16 wires at the output (16-bit words). This component is quite simple, it returns the output contained in the memory cell that corresponds to the input address. You will send him the value of CO to retrieve the next instruction to execute and to store in RI. For this I suggest you rename the output of CO register Cobus (15:0) and then via a Bus Tap connect 8 LSBs Cobus (7:0) to the input (7:0) of insmem. Finally the output spo(15:0) is connected to the input of RI. You can for the clarity of the diagram reduce the size of insmem symbol. Simply select the symbol and right-click> Symbol> Edit Symbol, you have access to the graphical representation of the symbol. Reduce its height and save the changes. Returning in the diagram S3, ISE will ask you to update the symbol insmem as amended. Do it. You have to control the loading of the RI register, for now just add a RIload wire on the CE registry.

Figure 87 instruction memory Connection

ROM Initialization

Now you will put some 16-bit words in this ROM. For this create a new source in your project of type User Document.

Figure 88 Creating the binary program

You will initialize this prog.coe file with the following content:

The first command specifies the number of bits per word, the second the 16-bit values in hexadecimal one behind the other with one word per line, a semicolon after each command.

Into the design mode click on insmem to open the operator of IP_core. Pressing next twice, you can attach the file you just created and also visualize it. After Generate the first four addresses in this memory will be initialized

Figure 89 program storage in the program memory

FSM and control

Your S3 processor is ready for the loading phase. You only still need to trigger the loading and increment signals of CO and RI registers but also the selection signal of the multiplexer CO. For this you will use an FSM!

To view the function behavior on the board, I suggest you view the first instruction in the memory insmem at the address X0000. So you need to run once the loading phase: loading RI register and increment CO register. Then on the next clock top, you must transfer the contents of the RI register to the R7seg register for display. To achieve this loading, add a B2R7seg signal to the input CE of the R7seg register and a signal RI2B to the connect input of connecteur16 associated with the register RI. These two signals will achieve the register transfer like it was done in the previous lesson.

Figure 90 R7seg Control

Figure 91 RI Control

Back to the FSM! You will take the FSM defined in Lesson 5. Project> Add Copy of Source, add the fsm.vhd File of TP5. The three processes will be kept. However, you need to change the ports of the FSM and the automaton itself. Here you only have two states Chg for loading and TRf for transfer . Transitions trigger signals shown.

Figure 92 CCU Automaton

Modifications to the fsm.vhd code are as follows.

    1. Change the input and output ports. Here there are 5 outputs that triggers actions on registers CO, RI and R7seg. Then declare the internal signals for each xxx_i output. Finally, the enumerated type must be updated, it contains two loading and transfer values.
    1. The Next_output process must also be changed. After initializing xxx_i internal signals, it is necessary for each state of the FSM to define the active outputs.
    1. For process Next_node is simply passing from the first state to the second. Transfer loop on itself.
    1. Finally for the last process Synchro simply position the internal signals on the FSM output ports at each clock tick.

You can now create the symbol associated with fsm. Once the symbol available, place an instantiation below the RI register. The clk input can immediately be connected to the wire clk of your diagram. For the four outputs, ISE lets you draw two separate wires while it is in fact a single wire. It is sufficient that both wires have the same name. ISE brings together the wires by naming. This approach allows to build connect wires without being visible and without overloading the diagram.

Figure 93 Connection of the FSM

You can then compile and execute, you can simulate the behavior with Isim by retrieving, if it is not present, by a Project> Add ... Copy, the code toplevel_tb of TP6. In simulation mode check that the CO value has been incremented and the RI and R7seg registers are loaded correctly. Just slide into the simulation window the outputs q(15:0) for each of these registers. Once verified, make a copy of the project as TP8 for the future.

Figure 94 Simulation of the loading phase

Your turn

Question 1: By adding two states after of your automaton chargement2 (Load2) and Transfer2, you should be able to view the second value. Here is the result of simulation. The first value goes through the register R7seg but not long enough to be displayed.

Figure 95 Simulation of the 2 loading phases

Question 2: We may even make it in 3 cycles instead of 4!

Figure 96 A pipe line operation!

.