====== Executable Instruction Opcodes ====== /* * Copyright (c) 2001-2003 Stephen Williams (steve@icarus.com) * * $Id: opcodes.txt,v 1.69 2005/11/26 17:16:05 steve Exp $ */ EXECUTABLE INSTRUCTION OPCODES Instruction opcodes all start with a % character and have 0 or more operands. In no case are there more then 3 operands. This chapter describes the specific behavior of each opcode, in enough detail (I hope) that its complete effect can be predicted. General principles of Arithmetic: The binary arithmetic instruction in general take three parameters, the left operand, the right operand, and the base. The left operand is replaced with the result, which is the same width as the left and right operands. * %add , , This instruction adds the right vector into the left vector, the vectors having the width . If any of the bits of either vector are x or z, the result is x. Otherwise, the result is the arithmetic sum. See also the %sub instruction. * %add/wr , This is the real valued version of the %add instruction. The arguments are word indices of the operands. The right operand is added into the left operand. See also the %sub/wr instruction. * %addi , , This instruction adds the immediate value (no x or z bits) into the left vector. The imm value is limited to 16 significant bits, but it is zero extended to match any width. * %and , , Perform the bitwise AND of the two vectors, and store the result in the left vector. Each bit is calculated independent of other bits. AND means the following: 0 and ? --> 0 ? and 0 --> 0 1 and 1 --> 1 otherwise x * %assign/m , , (OBSOLETE) This instruction does a non-blocking assignment to a bit in a memory from the specified thread register . The memory bit is addressed by index register 3. Bit address zero is the LSB of the first memory word. * %assign/mv , , the %assign/mv instruction assigns a vector value to a word in the labeled memory. The is the delay in simulation time to the assignment (0 for non-blocking assignment) and the is the base of the vector to write. The width of the word is retrieved from index register 0. The address of the word in the memory is from index register 3. The address is canonical form. * %assign/v0 , , * %assign/v0/d , , The %assign/v0 instruction is a vector version of non-blocking assignment. The is the number of clock ticks in the future where the assignment should be schedule, and the is the base of the vector to be assigned to the destination. The vector width is in index register 0. The %assign/v0/d variation puts the delay instead into an integer register that is given by the value. This should not be 0, of course, because integer 0 is taken with the vector width. The references a .var object that can receive non-blocking assignments. For blocking assignments, see %set/v. * %assign/v0x1 , , This is similar to the %assign/v0 instruction, but adds the index-1 index register with the canonical index of the destination where the vector is to be written. This allows for part writes into the vector. * %assign/wr , , This instruction causes a non-blocking assign of the indexed value to the real object addressed by the label. * %assign/x0 , , (OBSOLETE -- See %assign/v0x) This does a non-blocking assignment to a functor, similar to the %assign instruction. The identifies the base functor of the affected variable, and the gives the delay when the assignment takes place. The delay may be 0. The actual functor used is calculated by using as a base, and indexing with the index[0] index register. This supports indexed assignment. The is the address of the thread register that contains the bit value to assign. * %blend , , This instruction blends the bits of a vector into the destination in a manner like the expression (x ? : ). The truth table is: 1 1 --> 1 0 0 --> 0 z z --> z x x --> x .... --> x In other words, if the bits are identical, then take that value. Otherwise, the value is x. * %breakpoint This instruction unconditionally breaks the simulator into the interactive debugger. The idea is to stop the simulator here and give the user a chance to display the state of the simulation using debugger commands. This may not work on all platforms. If run-time debugging is compiled out, then this function is a no-op. * %cassign/v , , Perform a continuous assign of a constant value to the target variable. This is similar to %set, but it uses the cassign port (port-1) of the signal functor instead of the normal assign, so the signal responds differently. See "VARIABLE STATEMENTS" in the README.txt file. * %cmp/u , , * %cmp/s , , These instructions perform a generic comparison of two vectors of equal size. The and numbers address the least-significant bit of each vector, and is the width. If either operand is 0, 1, 2 or 3 then it is taken to be a constant replicated to the selected width. The results of the comparison go into bits 4, 5, 6 and 7: 4: eq (equal) 5: lt (less than) 6: eeq (case equal) The eeq bit is set to 1 if all the bits in the vectors are exactly the same, or 0 otherwise. The eq bit is true if the values are logically the same. That is, x and z are considered equal. In other words the eq bit is the same as ``=='' and the eeq bit ``===''. The lt bit is 1 if the left vector is less then the right vector, or 0 if greater then or equal to the right vector. It is the equivalent of the Verilog < operator. Combinations of these three bits can be used to implement all the Verilog comparison operators. The %cmp/u and %cmp/s differ only in the handling of the lt bit. The %cmp/u does an unsigned compare, whereas the %cmp/s does a signed compare. In either case, if either operand contains x or z, then lt bit gets the x value. * %cmp/wr , [compare real values.] * %cmp/ws , * %cmp/wu , [compare signed/unsigned integer words.] * %cmp/z , , * %cmp/x , , These instructions are for implementing the casez and casex comparisons. These work similar to the %cmp/u instructions, except only an eq bit is calculated. These comparisons both treat z values in the left or right operand as don't care positions. The %cmp/x instruction will also treat x values in either operand as don't care. Only bit 4 is set by these instructions. * %cvt/ir , * %cvt/ri , * %cvt/vr , , Copy a word from r to l, converting it from real to integer (ir) or integer to real (ri) in the process. The source and destination may be the same word address, leading to a convert in place. The %cvt/vr opcode converts a real word to a thread vector starting at and with the width . Non-integer precision is lost in the conversion. * %deassign Deactivate and disconnect a procedural continuous assignment to a variable. The identifies the affected variable. * %delay This opcode pauses the thread, and causes it to be rescheduled for a time in the future. The is the number of the ticks in the future to reschedule, and is >= 0. If the %delay is zero, then the thread yields the processor for another thread, but will be resumed in the current time step. * %delayx This is similar to the %delay opcode, except that the parameter selects an index register, which contains the actual delay. This supports run-time calculated delays. * %disable This instruction terminates threads that are part of a specific scope. The label identifies the scope in question, and the threads are the threads that are currently within that scope. * %div , , * %div/s , , This instruction arithmetically divides the vector by the vector, and leaves the result in the vector. IF any of the bits in either vector are x or z, the entire result is x. The %div/s instruction is the same as %div, but does signed division. * %div/wr , This opcode divides the left operand by the right operand. If the right operand is 0, then the result is NaN. * %force/v