Lesson 10 : Immediate - condition

In this lesson, you will enrich your processor with an input / output instruction that will allow you to control the status of your CO in active standby mode. Additional instruction will allow you to handle immediate addressing: a value is explicitly given in the instruction itself as the source of a register transfer, very useful to manipulate constants. Finally the register transfers will be conditionally calculated by the ALU. This original way of conditioning a register transfer provides all the desired simplicity that the S3 processor aims in carrying out a breaking of a sequence for which there will be no specific instruction (no JUMP, Branch, etc). The instruction set is ultra simplified!

A processor must be able to scan a program. A program consists of calculation instructions executed one after the other. The S3 processor implements an ALU and the FSM sequentially scans the program. It should also be able to perform conditional code blocks as IF THEN ELSE. Finally it should be able to repeat several times the same code under a condition of type WHILE. The S3 processor must be completed to become programmable.

Knowledge requirements

Immediate addressing

Objective

In this lesson, you will enrich your processor with an input / output instruction that will allow you to control the status of your CO in active standby mode. Additional instruction will allow you to handle immediate addressing: a value is explicitly given in the instruction itself as the source of a register transfer, very useful to manipulate constants. Finally the register transfers will be conditionally calculated by the ALU. This original way of conditioning a register transfer provides all the desired simplicity that the S3 processor aims in carrying out a breaking of a sequence for which there will be no specific instruction (no JUMP, Branch, etc). The instruction set is ultra simplified!

The project

Three instructions to develop. The PAUSE instruction will block the advancement of the automaton of your FSM. The MVI instruction allows copying a constant value into a destination register. The instructions MVZ, MVNZ, MIZ and MINZ realize or not a register transfer depending on the value stored at that moment in the Rdest register. You will see that this instruction set enrichment involves only minor changes in the architecture of S3.

The PAUSE instruction

In order to enter or display two successive numbers, we must introduce a hardware mechanism functioning as the "carriage return / enter" of a keyboard. On your card, you have 4 or 5 push buttons, one of them can play this role. After positioning the switches or reading the LEDs or the 7-segment displays, pressing the button should allow the resumption of the program. The associated PAUSE instruction functions as an active wait: the S3 processor stops at this instruction at each clock until the button triggers a continuation signal. Then the processor proceeds to the next instruction. Choose xF as operation code of the PAUSE instruction. All xFzzz instructions are PAUSE.

I propose to use the Eastern button, the rightmost. What you need is to detect the state change of the button: transition from 0 to 1. This detection should be active for 1 cycle while manually pressing the button will activate a signal for a few tenths of a second, the speed of your finger! Detecting the button state change corresponds to produce one pulse. For 2 successive PAUSE instructions, the button must be pressed twice. I suggest you make a small circuit that ensures the generation of this pulse with six D-FFs. First you must debounce the buttons. The button is mechanical and the produced signal is not always clean.

In the first line, place three D flip-flops in series with 190 Hz input frequency in order to validate the pressure on the button to a sample of about 15 ms. If the signal is 1 for these 15ms it is validated on the output of an AND3. The three flip-flops in series function as a shift register. For the other three flip-flops in series, each clock cycle of clk, of the processor now, the three flip-flops store the last three values of the sampled signal. If these three values are 110, there is a new button press, you generate thus the pulse. Any other combination of the three last values of the button signal will not release the PAUSE instruction.

Open the project TP10 copied at the end of lesson 9. Add a schematic named pulse. Place 6 D flip-flops on two lines 3 in each. Add two wires clk and clk190 with their I / O Markers. Clk190 is connected to the C of the first 3 flip-flops, clk to the last three. An inp wire and its I / O Marker is connected to the D input of the first latch. The Q outputs of the first and second flip-flops are connected to the D input of the following flip-flops. The three outputs Q are connected by an AND3. The output of the AND3 becomes the input of the 4th flip-flop.

The last three flip flops are cascaded also. Here the output of the last passes through an INV before being connected to AND3 to detect the sequence b110. Finally the output of this AND3 is named outp. Add to it an I / O Marker. Name your wires for simulation: q0, q1, q2, q3, q4, q5 and o1 for the output of the first AND3. Here is a diagram to guide you.

Figure 114 Schematic of you pulse

By simulating this component, you will get the following timing which effectively guarantees the creation of the pulse signal. To simulate you can create a pulse_tb with stimuli clk, clk190 and the button to 1 after some time. You can also start Isim on pulse.sch in this case you have to use force and constant force clock to boost your entries. To reduce simulation time, I chose a clk190 two times slower than clk. You can create the corresponding symbol.

Figure 115 Simulation of pulse

You must then change the FSM to take into account this new instruction. The controller will have to add a node to which the FSM will loop as long as the pulse is not be detected.

Figure 116 Idea of the FSM automaton

    1. Add an input port that I propose to name continue.
    1. Add a pause value in the state_type type definition.
    1. Modify the process Next_node to take into account the new state Pause in your automaton. If an instruction pause is detected while decoding, your automaton will be positioned in the Pause state. He will leave this state when the signal continue beomes active. This signal will be produced by your pulse. continue must be added in the sensitivity list because it appears in a test of your process.
    1. We must also modify the process Next_Output since the PAUSE instruction should not trigger the transition to the next instruction as long as the signal continue is not active, the pause instruction will be decoded as long as the CO register has not been incremented. Continue appears in a predicate, it must also be placed in the sensitivity of the process list.

You can save and create fsm.vhd symbol. Update it in S3. You just need to put a wire on the output continue, name it continue and place an I/O Marker. Save and recreate the S3 symbol. The remainder is to be done in toplevel.

Figure 117 pulse connection on the new FSM

Update the S3 instance in toplevel. Place an instance of pulse under S3. Connect the output of pulse to the input continue of your S3. You still have to connect the clk input to the output wire of BUFG. Collect the output clk190 of clkdiv (or testclk) to feed the input clk190 of pulse. Finally place a wire and its I / O Marker on the input inp of pulse, name it btn0.

Figure 119 toplevel with a button

Same for toplevel_tb, add a btn0 port in the declaration of the toplevel component, a btn0 internal signal, in the component instantiation the btn0 port must be taken into account and finally we must stimulate this internal signal. Here is an example of the stimulation signal in simulation mode with the after command.

The btn0 button must be added in the S3.ucf file. We must also modify the S3asm.bat assembler by adding the PAUSE code.

Now you can create a program that adds two 8-bit numbers entered successively on the switches and displays the value on the display. Here is the assembly program and its binary code generated. It is your job to generate insmem with this code. View the code in the third screen before clicking on generate.

Here is the timing diagram that you would get with the clk signals, the stimuli BTN0 and the q(15:0) of registers CO then RI and finally the three q(15:0) of the registers Rsrc1, Rsrc2 and R7seg. You can notice that about fifteen ms are needed before the pulse is generated.

You can test this program on the card. If you want to test the other functions of your ALU, you need particularly to realize a CONCAT function after entering two 8 bit words, just change the ADD code and recreate toplevel.bit after updating insmem and S3.

The MVI instruction

The immediate addressing allows you to manipulate a constant value stored in the instruction itself. The execution of this instruction is carried out by the transfer of part of the IR register containing the instruction being executed, and therefore the immediate value to a destination register. The width of instructions is 16 bits, we can keep 8 bits to codify this immediate value, 4 bits for the operation code and 4 bits for the destination. In order to keep the overall size of your instructions, I propose the following format: operation = b0010 code, 8 bits for value, 4 bits for the destination register number. The source register RI is implicit for this MVI instruction, no coding is needed for the source number. Using this format, we have to extract the middle RI register 8 bits of Q(11: 4) and force the other bits to 0 before placing them on the data bus. To do this, remove in S3.sch the bus between the RI register output Q(15:0) and its CRI connector16 input R(15:0). Create a new schematic type source called immediat. Place there a vertical bus a(15: 0) with its I / O Marker to the left. Place a bus b(15: 0) with its I / O Marker to the right.

Instantiate 8 BUFs between the two buses. With Bus Taps connect the inputs of BUFs to the wires a(11: 4) then the outputs of the BUFs to wires b(7: 0). Place a constant changing its value to x00 then changing its length to 8. Connect the constant by a Bus Tap to b(15: 8). Save and create the associated symbol.

Figure 120 Immediat from 8-bit to 16-bit

Back to S3, place an instance of immediat below the CRI connecteur16. Connect its output to the input R of the connecteur. Connect the output q(15: 0) and immediat input. Each opening of the RI register on the bus (active RI2B) will produce a 16-bit word composed of 8-bit immediate value on low significant and completed by b00000000 on high significant bits.

Figure 121 immediat connection between RI and CRI

Finally, you only still need to modify the FSM to decode and control the MVI instruction. This instruction is encoded by b0010 vvvv vvvv dddd: the 8 v give you the immediate value and the 4 d the destination register number. There is no additional port on the FSM. Simply complete the decoding of instructions in the Next_Output process for the node chargement.

Save, create the symbol and update it in S3. You must also add that instruction in your assembler, just add the keyword MVI. You can rebuild a sample program to test your new instruction, it generates the .coe file to load into insmem. Update symbols in S3 then in toplevel. Are you ready for simulation and synthesis.

The instructions MZ and MNZ

To establish conditions in the S3 processor, you have to be able to test the result of an operation. This result is necessarily in Rdest. A generic and simple solution is to validate the conditional register transfers under a condition related to the content of Rdest. Both instructions that I propose MZ and MNZ, function as MOV, except that the transfer will be valid only if the value of Rdest is respectively is 0 or not 0 when running. It will be very simple to implement. The FSM decodes these instructions as it did for the MOV but during the actual execution of the instruction, the destination dest(3: 0) is only valid if the associated condition is true at the time. The D4_16E decoder has an input E to Enable. Just invalidate that input when the condition is false during this execution. To do so create a schematic called testeur that returns true if:

    • MZ instruction and all the bits in Rdest are 0.
    • MNZ instruction and at least one bit of Rdest is 1.
    • Any other statement.

In this schematic, place a bus a(15: 0) with its I / O Marker. Place an OR16 before the bus and with 16 successive bus Taps connect the 16 bus wires to the OR16. Place two wires with I / O Marker named test_Z and test_NZ. Simply place the circuit performing the following logic function. Once done, save and generate the symbol.

The final circuit is similar to the following.

Figure 122 Circuit testeur of Rdest

Now you need to to modify the FSM. Two output ports must be added, name them test_Z and test_NZ.

    1. Declare the ports and the associated internal signals test_Z_i and test_NZ_i.
    1. In the process Next_Output after initializing the two internal signals, add the decoding of the two instructions MZ and MNZ behind the decoding MVI. The operation codes are chosen respectively b0011 and b0100.
    1. On the Sync process, it is necessary to update the two output ports from internal signals.

You can save and create the associated symbol. Update this symbol in S3. The component has two more output ports. You can edit the symbol for clarity of the diagram if necessary. Place two pieces of wires named test_Z and test_NZ on the corresponding ports. Place a testeur symbol under insmem. Place on the three input ports wires named respectively dest_bus(15: 0), test_Z and test_NZ. You still have to delete the VCC on the input E of D4_16E decoder associated with the bus dest(3: 0). Replace it by a connection with the output s of your testeur.

Figure 123 Inserting testeur with the new FSM

Finally name the output bus of the register Rdest dest_bus(15: 0). Save S3 recreate the symbol and confirm the update in toplevel.

Figure 124 Renaming Rdest output bus

You have to change the S3asm.bat assembler and test a program. I propose the following program. This program is a game of hidden numbers. Enter a number on switches (1 chance in 256), if the number is found the display processor 0000 otherwise it displays 00FF.

The instructions MIZ and MINZ

As for the MOV, MVI can be conditioned by the results contained in Rdest. Just modify the FSM to achieve decoding of these new instructions. Choose b0101 and b0110 codes. The code that must be modified is in the Process Next_Ouput.

Also add these two codes in your S3asm.bat assembler.

Your turn

Question 1: Rewrite the hidden number game using the MIZ and MINZ instructions.

.