Commits

Benoît Allard committed e247edd

Reorganize everything

Comments (0)

Files changed (55)

Core.py

-"""
-This is the Core of the MARS.
-
-This is the central memory storage for the Warriors, the "Hill"
-"""
-
-from myhdl import *
-
-import MARSparam
-from MARSparam import InstrWidth
-
-def RAM(raddr, dout, waddr, din, we, clk, rst_n, width, depth):
-    """ Basic RAM model """
-    
-    mem = [Signal(intbv(0)[width:]) for i in range(depth)]
-
-    @always(clk.posedge)
-    def write():
-        if we:
-            mem[int(waddr)].next = din
-
-    @always_comb
-    def read():
-        dout.next = mem[int(raddr)]
-
-    return read, write
-
-def Fold(PC, Offset, Address, limit, maxSize):
-
-    Ofs_fold, Ofs_limit = [Signal(MARSparam.Addr()) for i in range(2)]
-
-    @always_comb
-    def comb1():
-        Ofs_limit.next = Offset % limit
-
-    @always_comb
-    def comb2():
-        if (Ofs_limit) > (limit/2):
-            Ofs_fold.next = (Ofs_limit) + maxSize - limit
-        else:
-            Ofs_fold.next = Ofs_limit
-
-    @always_comb
-    def comb3():
-        Address.next = (PC + Ofs_fold) % maxSize
-
-    return comb1, comb2, comb3
-
-def Core(pc, WOfs, din, ROfs, dout, we, clk, rst_n, maxSize):
-    """ Our Core """
-
-    raddr_i, waddr_i = [Signal(MARSparam.Addr()) for i in range(2)]
-
-    opcode_we, modif_we, amode_we, anumber_we, bmode_we, bnumber_we = [Signal(bool()) for i in range (6)]
-
-    opcode_out = Signal(intbv(0)[5:])
-    modif_out = Signal(intbv(0)[3:])
-    amode_out = Signal(intbv(0)[3:])
-    anumber_out = Signal(intbv(0)[MARSparam.AddrWidth:])
-    bmode_out = Signal(intbv(0)[3:])
-    bnumber_out = Signal(intbv(0)[MARSparam.AddrWidth:])
-
-    opcode_in = Signal(intbv(0)[5:])
-    modif_in = Signal(intbv(0)[3:])
-    amode_in = Signal(intbv(0)[3:])
-    anumber_in = Signal(intbv(0)[MARSparam.AddrWidth:])
-    bmode_in = Signal(intbv(0)[3:])
-    bnumber_in = Signal(intbv(0)[MARSparam.AddrWidth:])
-
-    # Those are VHDL Aliases
-    @always_comb
-    def split():
-        opcode_in.next = din[InstrWidth:InstrWidth-5]
-        dout.next[InstrWidth:InstrWidth-5] = opcode_out
-
-        modif_in.next = din[InstrWidth-5:InstrWidth-8]
-        dout.next[InstrWidth-5:InstrWidth-8] = modif_out
-
-        amode_in.next = din[InstrWidth-8:InstrWidth-11]
-        dout.next[InstrWidth-8:InstrWidth-11] = amode_out
-
-        anumber_in.next = din[InstrWidth-11:InstrWidth-11-MARSparam.AddrWidth]
-        dout.next[InstrWidth-11:InstrWidth-11-MARSparam.AddrWidth] = anumber_out
-
-        bmode_in.next = din[MARSparam.AddrWidth+3:MARSparam.AddrWidth]
-        dout.next[MARSparam.AddrWidth+3:MARSparam.AddrWidth] = bmode_out
-
-        bnumber_in.next = din[MARSparam.AddrWidth:0]
-        dout.next[MARSparam.AddrWidth:0] = bnumber_out
-
-        opcode_we.next = we[5]
-        modif_we.next = we[4]
-        amode_we.next = we[3]
-        anumber_we.next = we[2]
-        bmode_we.next = we[1]
-        bnumber_we.next = we[0]
-
-    @always(raddr_i, waddr_i)
-    def verbose():
-        print "R: PC: %d, Ofs: %d ==> %d" % (pc, ROfs, raddr_i)
-        print "W: PC: %d, Ofs: %d ==> %d" % (pc, WOfs, waddr_i)
-
-    ReadFold = Fold(pc, ROfs, raddr_i, MARSparam.ReadRange, MARSparam.CORESIZE)
-    WriteFold = Fold(pc, WOfs, waddr_i, MARSparam.WriteRange, MARSparam.CORESIZE)
-
-
-    # My RAMs
-    OpCode = RAM(raddr_i, opcode_out, waddr_i, opcode_in, opcode_we , clk, rst_n, 5, maxSize)
-    Modif = RAM(raddr_i, modif_out, waddr_i, modif_in, modif_we, clk, rst_n, 3, maxSize)
-    AMode = RAM(raddr_i, amode_out, waddr_i, amode_in, amode_we, clk, rst_n, 3, maxSize)
-    ANumber = RAM(raddr_i, anumber_out, waddr_i, anumber_in, anumber_we, clk, rst_n, MARSparam.AddrWidth, maxSize)
-    BMode = RAM(raddr_i, bmode_out, waddr_i, bmode_in, bmode_we, clk, rst_n, 3, maxSize)
-    BNumber = RAM(raddr_i, bnumber_out, waddr_i, bnumber_in, bnumber_we, clk, rst_n, MARSparam.AddrWidth, maxSize)
-
-    return OpCode, Modif, AMode, ANumber, BMode, BNumber, ReadFold, WriteFold, split, verbose

EMI94.c

-/************************************/
-/*                                  */
-/*            EMI94.c               */
-/*                                  */
-/* Execute MARS Instruction ala     */
-/* ICWS'94 Draft Standard.          */
-/*                                  */
-/* Last Update: November 8, 1995    */
-/*                                  */
-/************************************/
-
-/* This ANSI C function is the benchmark MARS instruction   */
-/* interpreter for the ICWS'94 Draft Standard.              */
-
-
-/* The design philosophy of this function is to mirror the  */
-/* standard as closely as possible, illuminate the meaning  */
-/* of the standard, and provide the definitive answers to   */
-/* questions of the "well, does the standard mean this or   */
-/* that?" variety.  Although other, different implemen-     */
-/* tations are definitely possible and encouraged; those    */
-/* implementations should produce the same results as this  */
-/* one does.                                                */
-
-
-/* The function returns the state of the system.  What the  */
-/* main program does with this information is not defined   */
-/* by the standard.                                         */
-
-enum SystemState {
-   UNDEFINED,
-   SUCCESS
-};
-
-
-/* Any number of warriors may be executing in core at one   */
-/* time, depending on the run-time variable set and how     */
-/* many warriors have failed during execution.  For this    */
-/* implementation, warriors are identified by the order in  */
-/* which they were loaded into core.                        */
-
-typedef unsigned int Warrior;
-
-
-/* An Address in Core War can be any number from 0 to the   */
-/* size of core minus one, relative to the current          */
-/* instruction.  In this implementation, core is an array   */
-/* of instructions; therefore any variable types which      */
-/* contain an Address can be considered to be of type       */
-/* unsigned int.  One caveat: for the purposes of this      */
-/* standard, unsigned int must be considered to have no     */
-/* upper limit.  Depending on the size of core, it may be   */
-/* necessary to take precautions against overflow.          */
-
-typedef unsigned int Address;
-
-
-/* The FIFO task queues and supporting functions are not    */
-/* presented.   The function Queue() attempts to add a task */
-/* pointer to the back of the currently executing warrior's */
-/* task queue.  No special actions are to be taken if       */
-/* Queue() is unsuccessful, which it will be if the warrior */
-/* has already reached the task limit (maximum allowable    */
-/* number of tasks).                                        */
-
-extern void Queue(
-   Warrior  W,
-   Address  TaskPointer
-);
-
-
-/* There is one support function used to limit the range of */
-/* reading from Core and writing to Core relative to the    */
-/* current instruction.  Behaviour is as expected (a small  */
-/* core within Core) only if the limits are factors of the  */
-/* size of Core.                                            */
-
-static Address Fold(
-   Address  pointer,    /* The pointer to fold into the desired range.  */
-   Address  limit,      /* The range limit.                             */
-   Address  M           /* The size of Core.                            */
-) {
-   Address  result;
-
-   result = pointer % limit;
-   if ( result > (limit/2) ) {
-      result += M - limit;
-   };
-   return(result);
-}
-
-
-/* Instructions are the principle data type.  Core is an    */
-/* array of instructions, and there are three instruction   */
-/* registers used by the MARS executive.                    */
-
-enum Opcode {
-   DAT,
-   MOV,
-   ADD,
-   SUB,
-   MUL,
-   DIV,
-   MOD,
-   JMP,
-   JMZ,
-   JMN,
-   DJN,
-   CMP, /* aka SEQ */
-   SNE,
-   SLT,
-   SPL,
-   NOP,
-};
-
-enum Modifier {
-   A,
-   B,
-   AB,
-   BA,
-   F,
-   X,
-   I
-};
-
-enum Mode {
-   IMMEDIATE,
-   DIRECT,
-   A_INDIRECT,
-   B_INDIRECT,
-   A_DECREMENT,
-   B_DECREMENT,
-   A_INCREMENT,
-   B_INCREMENT,
-};
-
-typedef struct Instruction {
-   enum Opcode    Opcode;
-   enum Modifier  Modifier;
-   enum Mode      AMode;
-   Address        ANumber;
-   enum Mode      BMode;
-   Address        BNumber;
-} Instruction;
-
-
-/* The function is passed which warrior is currently        */
-/* executing, the address of the warrior's current task's   */
-/* current instruction, a pointer to the Core, the size of  */
-/* the Core, and the read and write limits.  It returns the */
-/* system's state after attempting instruction execution.   */
-
-enum SystemState EMI94(
-
-/* W indicates which warrior's code is executing.           */
-
-   Warrior  W,
-
-/* PC is the address of this warrior's current task's       */
-/* current instruction.                                     */
-
-   Address  PC,
-
-/* Core is just an array of Instructions.  Core has been    */
-/* initialized and the warriors have been loaded before     */
-/* calling this function.                                   */
-
-   Instruction Core[],
-
-/* M is the size of Core.                                   */
-
-   Address     M,
-
-/* ReadLimit is the limitation on read distances.           */
-
-   Address     ReadLimit,
-
-/* WriteLimit is the limitation on write distances.         */
-
-   Address     WriteLimit
-
-
-) {
-
-
-/* This MARS stores the currently executing instruction in  */
-/* the instruction register IR.                             */
-
-   Instruction IR;
-
-/* This MARS stores the instruction referenced by the       */
-/* A-operand in the instruction register IRA.               */
-
-   Instruction IRA;
-
-/* This MARS stores the instruction referenced by the       */
-/* B-operand in the instruction Register IRB.               */
-
-   Instruction IRB;
-
-/* All four of the following pointers are PC-relative       */
-/* (relative to the Program Counter).  Actual access of     */
-/* core must add-in the Program Counter (mod core size).    */
-
-/* The offset to the instruction referred to by the         */
-/* A-operand for reading is Read Pointer A (RPA).           */
-
-   Address     RPA;
-
-/* The offset to the instruction referred to by the         */
-/* A-operand for writing is Write Pointer A (WPA).          */
-
-   Address     WPA;
-
-/* The offset to the instruction referred to by the         */
-/* B-operand for reading is Read Pointer B (RPB).           */
-
-   Address     RPB;
-
-/* The offset to the instruction referred to by the         */
-/* A-operand for writing is Write Pointer B (WPB).          */
-
-   Address     WPB;
-
-/* Post-increment operands need to keep track of which      */
-/* instruction to increment.                                */
-
-   Address     PIP;
-
-/* Before execution begins, the current instruction is      */
-/* copied into the Instruction Register.                    */
-
-   IR = Core[PC];
-
-
-/* Next, the A-operand is completely evaluated.             */
-
-/* For instructions with an Immediate A-mode, the Pointer A */
-/* points to the source of the current instruction.         */
-
-   if (IR.AMode == IMMEDIATE) {
-      RPA = WPA = 0;
-   } else {
-
-/* For instructions with a Direct A-mode, the Pointer A     */
-/* points to the instruction IR.ANumber away, relative to   */
-/* the Program Counter.                                     */
-/* Note that implementing Core as an array necessitates     */
-/* doing all Address arithmetic modulus the size of Core.   */
-
-      RPA = Fold(IR.ANumber, ReadLimit, M);
-      WPA = Fold(IR.ANumber, WriteLimit, M);
-
-/* For instructions with A-indirection in the A-operand     */
-/* (A-number Indirect, A-number Predecrement,               */
-/* and A-number Postincrement A-modes):                     */
-
-      if (IR.AMode == A_INDIRECT
-          || IR.AMode == A_DECREMENT
-          || IR.AMode == A_INCREMENT) {
-
-/* For instructions with Predecrement A-mode, the A-Field   */
-/* of the instruction in Core currently pointed to by the   */
-/* Pointer A is decremented (M - 1 is added).               */
-
-         if (IR.AMode == A_DECREMENT) {
-            Core[((PC + WPA) % M)].ANumber =
-               (Core[((PC + WPA) % M)].ANumber + M - 1) % M;
-         };
-
-/* For instructions with Postincrement A-mode, the A-Field  */
-/* of the instruction in Core currently pointed to by the   */
-/* Pointer A will be incremented.                           */
-
-         if (IR.AMode == A_INCREMENT) {
-            PIP = (PC + WPA) % M;
-         };
-
-/* For instructions with A-indirection in the A-operand,    */
-/* Pointer A ultimately points to the instruction           */
-/* Core[((PC + PCA) % M)].ANumber away, relative to the     */
-/* instruction pointed to by Pointer A.                     */
-
-         RPA = Fold(
-            (RPA + Core[((PC + RPA) % M)].ANumber), ReadLimit, M
-         );
-         WPA = Fold(
-            (WPA + Core[((PC + WPA) % M)].ANumber), WriteLimit, M
-         );
-
-      };
-
-/* For instructions with B-indirection in the A-operand     */
-/* (B-number Indirect, B-number Predecrement,               */
-/* and B-number Postincrement A-modes):                     */
-
-      if (IR.AMode == B_INDIRECT
-          || IR.AMode == B_DECREMENT
-          || IR.AMode == B_INCREMENT) {
-
-/* For instructions with Predecrement A-mode, the B-Field   */
-/* of the instruction in Core currently pointed to by the   */
-/* Pointer A is decremented (M - 1 is added).               */
-
-         if (IR.AMode == DECREMENT) {
-            Core[((PC + WPA) % M)].BNumber =
-               (Core[((PC + WPA) % M)].BNumber + M - 1) % M;
-         };
-
-/* For instructions with Postincrement A-mode, the B-Field  */
-/* of the instruction in Core currently pointed to by the   */
-/* Pointer A will be incremented.                           */
-
-         if (IR.AMode == INCREMENT) {
-            PIP = (PC + WPA) % M;
-         };
-
-/* For instructions with B-indirection in the A-operand,    */
-/* Pointer A ultimately points to the instruction           */
-/* Core[((PC + PCA) % M)].BNumber away, relative to the     */
-/* instruction pointed to by Pointer A.                     */
-
-         RPA = Fold(
-            (RPA + Core[((PC + RPA) % M)].BNumber), ReadLimit, M
-         );
-         WPA = Fold(
-            (WPA + Core[((PC + WPA) % M)].BNumber), WriteLimit, M
-         );
-
-      };
-   };
-
-/* The Instruction Register A is a copy of the instruction  */
-/* pointed to by Pointer A.                                 */
-
-   IRA = Core[((PC + RPA) % M)];
-
-/* If the A-mode was post-increment, now is the time to     */
-/* increment the instruction in core.                       */
-
-   if (IR.AMode == A_INCREMENT) {
-           Core[PIP].ANumber = (Core[PIP].ANumber + 1) % M;
-           }
-   else if (IR.AMode == B_INCREMENT) {
-           Core[PIP].BNumber = (Core[PIP].BNumber + 1) % M;
-           };
-
-/* The Pointer B and the Instruction Register B are         */
-/* evaluated in the same manner as their A counterparts.    */
-
-   if (IR.BMode == IMMEDIATE) {
-      RPB = WPB = 0;
-   } else {
-      RPB = Fold(IR.BNumber, ReadLimit, M);
-      WPB = Fold(IR.BNumber, WriteLimit, M);
-      if (IR.BMode == A_INDIRECT
-          || IR.BMode == A_DECREMENT
-          || IR.BMode == A_INCREMENT) {
-         if (IR.BMode == A_DECREMENT) {
-            Core[((PC + WPB) % M)].ANumber =
-               (Core[((PC + WPB) % M)].ANumber + M - 1) % M
-            ;
-         } else if (IR.BMode == A_INCREMENT) {
-            PIP = (PC + WPB) % M;
-         };
-         RPB = Fold(
-            (RPB + Core[((PC + RPB) % M)].ANumber), ReadLimit, M
-         );
-         WPB = Fold(
-            (WPB + Core[((PC + WPB) % M)].ANumber), WriteLimit, M
-         );
-      };
-      if (IR.BMode == B_INDIRECT
-          || IR.BMode == B_DECREMENT
-          || IR.BMode == B_INCREMENT) {
-         if (IR.BMode == B_DECREMENT) {
-            Core[((PC + WPB) % M)].BNumber =
-               (Core[((PC + WPB) % M)].BNumber + M - 1) % M
-            ;
-         } else if (IR.BMode == B_INCREMENT) {
-            PIP = (PC + WPB) % M;
-         };
-         RPB = Fold(
-            (RPB + Core[((PC + RPB) % M)].BNumber), ReadLimit, M
-         );
-         WPB = Fold(
-            (WPB + Core[((PC + WPB) % M)].BNumber), WriteLimit, M
-         );
-      };
-   };
-   IRB = Core[((PC + RPB) % M)];
-
-   if (IR.BMode == A_INCREMENT) {
-           Core[PIP].ANumber = (Core[PIP].ANumber + 1) % M;
-           }
-   else if (IR.BMode == INCREMENT) {
-           Core[PIP].BNumber = (Core[PIP].BNumber + 1) % M;
-           };
-
-/* Execution of the instruction can now proceed.            */
-
-   switch (IR.Opcode) {
-
-/* Instructions with a DAT opcode have no further function. */
-/* The current task's Program Counter is not updated and is */
-/* not returned to the task queue, effectively removing the */
-/* task.                                                    */
-
-   case DAT: noqueue:
-      break;
-
-
-/* MOV replaces the B-target with the A-value and queues    */
-/* the next instruction.                                    */
-
-   case MOV:
-      switch (IR.Modifier) {
-
-/* Replaces A-number with A-number.                         */
-
-      case A:
-         Core[((PC + WPB) % M)].ANumber = IRA.ANumber;
-         break;
-
-/* Replaces B-number with B-number.                         */
-
-      case B:
-         Core[((PC + WPB) % M)].BNumber = IRA.BNumber;
-         break;
-
-/* Replaces B-number with A-number.                         */
-
-      case AB:
-         Core[((PC + WPB) % M)].BNumber = IRA.ANumber;
-         break;
-
-/* Replaces A-number with B-number.                         */
-
-      case BA:
-         Core[((PC + WPB) % M)].ANumber = IRA.BNumber;
-         break;
-
-/* Replaces A-number with A-number and B-number with        */
-/* B-number.                                                */
-
-      case F:
-         Core[((PC + WPB) % M)].ANumber = IRA.ANumber;
-         Core[((PC + WPB) % M)].BNumber = IRA.BNumber;
-         break;
-
-/* Replaces B-number with A-number and A-number with        */
-/* B-number.                                                */
-
-      case X:
-         Core[((PC + WPB) % M)].BNumber = IRA.ANumber;
-         Core[((PC + WPB) % M)].ANumber = IRA.BNumber;
-         break;
-
-/* Copies entire instruction.                               */
-
-      case I:
-         Core[((PC + WPB) % M)] = IRA;
-         break;
-
-      default:
-         return(UNDEFINED);
-         break;
-      };
-
-/* Queue up next instruction.                               */
-      Queue(W, ((PC + 1) % M));
-      break;
-
-/* Arithmetic instructions replace the B-target with the    */
-/* "op" of the A-value and B-value, and queue the next      */
-/* instruction.  "op" can be the sum, the difference, or    */
-/* the product.                                             */
-
-#define ARITH(op) \
-      switch (IR.Modifier) { \
-      case A: \
-         Core[((PC + WPB) % M)].ANumber = \
-            (IRB.ANumber op IRA.ANumber) % M \
-         ; \
-         break; \
-      case B: \
-         Core[((PC + WPB) % M)].BNumber = \
-            (IRB.BNumber op IRA.BNumber) % M \
-         ; \
-         break; \
-      case AB: \
-         Core[((PC + WPB) % M)].BNumber = \
-            (IRB.ANumber op IRA.BNumber) % M \
-         ; \
-         break; \
-      case BA: \
-         Core[((PC + WPB) % M)].ANumber = \
-            (IRB.BNumber op IRA.ANumber) % M \
-         ; \
-         break; \
-      case F: \
-      case I: \
-         Core[((PC + WPB) % M)].ANumber = \
-            (IRB.ANumber op IRA.ANumber) % M \
-         ; \
-         Core[((PC + WPB) % M)].BNumber = \
-            (IRB.BNumber op IRA.BNumber) % M \
-         ; \
-         break; \
-      case X: \
-         Core[((PC + WPB) % M)].BNumber = \
-            (IRB.ANumber op IRA.BNumber) % M \
-         ; \
-         Core[((PC + WPB) % M)].ANumber = \
-            (IRB.BNumber op IRA.ANumber) % M \
-         ; \
-         break; \
-      default: \
-         return(UNDEFINED); \
-         break; \
-      }; \
-      Queue(W, ((PC + 1) % M)); \
-      break;
-
-   case ADD: ARITH(+)
-   case SUB: ARITH(+ M -)
-   case MUL: ARITH(*)
-
-/* DIV and MOD replace the B-target with the integral       */
-/* quotient (for DIV) or remainder (for MOD) of the B-value */
-/* by the A-value, and queues the next instruction.         */
-/* Process is removed from task queue if A-value is zero.   */
-
-#define ARITH_DIV(op) \
-      switch (IR.Modifier) { \
-      case A: \
-         if (IRA.ANumber != 0) \
-            Core[((PC + WPB) % M)].ANumber = IRB.ANumber op IRA.ANumber; \
-         break; \
-      case B: \
-         if (IRA.BNumber != 0) \
-            Core[((PC + WPB) % M)].BNumber = IRB.BNumber op IRA.BNumber; \
-         else goto noqueue; \
-         break; \
-      case AB: \
-         if (IRA.ANumber != 0) \
-            Core[((PC + WPB) % M)].BNumber = IRB.BNumber op IRA.ANumber; \
-         else goto noqueue; \
-         break; \
-      case BA: \
-         if (IRA.BNumber != 0) \
-            Core[((PC + WPB) % M)].ANumber = IRB.ANumber op IRA.BNumber; \
-         else goto noqueue; \
-         break; \
-      case F: \
-      case I: \
-         if (IRA.ANumber != 0) \
-            Core[((PC + WPB) % M)].ANumber = IRB.ANumber op IRA.ANumber; \
-         if (IRA.BNumber != 0) \
-            Core[((PC + WPB) % M)].BNumber = IRB.BNumber op IRA.BNumber; \
-         if ((IRA.ANumber == 0) || (IRA.BNumber == 0)) \
-            goto noqueue; \
-         break; \
-      case X: \
-         if (IRA.ANumber != 0) \
-            Core[((PC + WPB) % M)].BNumber = IRB.BNumber op IRA.ANumber; \
-         if (IRA.BNumber != 0) \
-            Core[((PC + WPB) % M)].ANumber = IRB.ANumber op IRA.BNumber; \
-         if ((IRA.ANumber == 0) || (IRA.BNumber == 0)) \
-            goto noqueue; \
-         break; \
-      default: \
-         return(UNDEFINED); \
-         break; \
-      }; \
-      Queue(W, ((PC + 1) % M)); \
-      break;
-
-   case DIV: ARITH_DIV(/)
-   case MOD: ARITH_DIV(%)
-
-/* JMP queues the sum of the Program Counter and the        */
-/* A-pointer.                                               */
-
-   case JMP:
-      Queue(W, RPA);
-      break;
-
-
-/* JMZ queues the sum of the Program Counter and Pointer A  */
-/* if the B-value is zero.  Otherwise, it queues the next   */
-/* instruction.                                             */
-
-   case JMZ:
-      switch (IR.Modifier) {
-      case A:
-      case BA:
-         if (IRB.ANumber == 0) {
-            Queue(W, RPA);
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case B:
-      case AB:
-         if (IRB.BNumber == 0) {
-            Queue(W, RPA);
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case F:
-      case X:
-      case I:
-         if ( (IRB.ANumber == 0) && (IRB.BNumber == 0) ) {
-            Queue(W, RPA);
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      default:
-         return(UNDEFINED);
-         break;
-      };
-      break;
-
-
-/* JMN queues the sum of the Program Counter and Pointer A  */
-/* if the B-value is not zero.  Otherwise, it queues the    */
-/* next instruction.                                        */
-
-   case JMN:
-      switch (IR.Modifier) {
-      case A:
-      case BA:
-         if (IRB.ANumber != 0) {
-            Queue(W, RPA);
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case B:
-      case AB:
-         if (IRB.BNumber != 0) {
-            Queue(W, RPA);
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case F:
-      case X:
-      case I:
-         if ( (IRB.ANumber != 0) || (IRB.BNumber != 0) ) {
-            Queue(W, RPA);
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      default:
-         return(UNDEFINED);
-         break;
-      };
-      break;
-
-
-/* DJN (Decrement Jump if Not zero) decrements the B-value  */
-/* and the B-target, then tests if the B-value is zero.  If */
-/* the result is not zero, the sum of the Program Counter   */
-/* and Pointer A is queued.  Otherwise, the next            */
-/* instruction is queued.                                   */
-
-   case DJN:
-      switch (IR.Modifier) {
-      case A:
-      case BA:
-         Core[((PC + WPB) % M)].ANumber =
-            (Core[((PC + WPB) % M)].ANumber + M - 1) % M
-         ;
-         IRB.ANumber -= 1;
-         if (IRB.ANumber != 0) {
-            Queue(W, RPA);
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case B:
-      case AB:
-         Core[((PC + WPB) % M)].BNumber =
-            (Core[((PC + WPB) % M)].BNumber + M - 1) % M
-         ;
-         IRB.BNumber -= 1;
-         if (IRB.BNumber != 0) {
-            Queue(W, RPA);
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case F:
-      case X:
-      case I:
-         Core[((PC + WPB) % M)].ANumber =
-            (Core[((PC + WPB) % M)].ANumber + M - 1) % M
-         ;
-         IRB.ANumber -= 1;
-         Core[((PC + WPB) % M)].BNumber =
-            (Core[((PC + WPB) % M)].BNumber + M - 1) % M
-         ;
-         IRB.BNumber -= 1;
-         if ( (IRB.ANumber != 0) || (IRB.BNumber != 0) ) {
-            Queue(W, RPA);
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      default:
-         return(UNDEFINED);
-         break;
-      };
-      break;
-
-
-/* SEQ/CMP compares the A-value and the B-value. If there   */
-/* are no differences, then the instruction after the next  */
-/* instruction is queued.  Otherwise, the next instrution   */
-/* is queued.                                               */
-
-   case CMP:
-      switch (IR.Modifier) {
-      case A:
-         if (IRA.ANumber == IRB.ANumber) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case B:
-         if (IRA.BNumber == IRB.BNumber) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case AB:
-         if (IRA.ANumber == IRB.BNumber) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case BA:
-         if (IRA.BNumber == IRB.ANumber) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case F:
-         if ( (IRA.ANumber == IRB.ANumber) &&
-              (IRA.BNumber == IRB.BNumber)
-         ) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case X:
-         if ( (IRA.ANumber == IRB.BNumber) &&
-              (IRA.BNumber == IRB.ANumber)
-         ) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case I:
-         if ( (IRA.Opcode == IRB.Opcode) &&
-              (IRA.Modifier == IRB.Modifier) &&
-              (IRA.AMode == IRB.AMode) &&
-              (IRA.ANumber == IRB.ANumber) &&
-              (IRA.BMode == IRB.BMode) &&
-              (IRA.BNumber == IRB.BNumber)
-         ) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      default:
-         return(UNDEFINED);
-         break;
-      };
-      break;
-
-
-/* SNE compares the A-value and the B-value. If there       */
-/* is a difference, then the instruction after the next     */
-/* instruction is queued.  Otherwise, the next instrution   */
-/* is queued.                                               */
-
-   case SNE:
-      switch (IR.Modifier) {
-      case A:
-         if (IRA.ANumber != IRB.ANumber) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case B:
-         if (IRA.BNumber != IRB.BNumber) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case AB:
-         if (IRA.ANumber != IRB.BNumber) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case BA:
-         if (IRA.BNumber != IRB.ANumber) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case F:
-         if ( (IRA.ANumber != IRB.ANumber) ||
-              (IRA.BNumber != IRB.BNumber)
-         ) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case X:
-         if ( (IRA.ANumber != IRB.BNumber) ||
-              (IRA.BNumber != IRB.ANumber)
-         ) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case I:
-         if ( (IRA.Opcode != IRB.Opcode) ||
-              (IRA.Modifier != IRB.Modifier) ||
-              (IRA.AMode != IRB.AMode) ||
-              (IRA.ANumber != IRB.ANumber) ||
-              (IRA.BMode != IRB.BMode) ||
-              (IRA.BNumber != IRB.BNumber)
-         ) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      default:
-         return(UNDEFINED);
-         break;
-      };
-      break;
-
-
-/* SLT (Skip if Less Than) queues the instruction after the */
-/* next instruction if A-value is less than B-value.        */
-/* Otherwise, the next instruction is queued.  Note that no */
-/* value is less than zero because only positive values can */
-/* be represented in core.                                  */
-
-   case SLT :
-      switch (IR.Modifier) {
-      case A:
-         if (IRA.ANumber < IRB.ANumber) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case B:
-         if (IRA.BNumber < IRB.BNumber) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case AB:
-         if (IRA.ANumber < IRB.BNumber) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case BA:
-         if (IRA.BNumber < IRB.ANumber) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case F:
-      case I:
-         if ( (IRA.ANumber < IRB.ANumber) &&
-              (IRA.BNumber < IRB.BNumber)
-         ) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      case X:
-         if ( (IRA.ANumber < IRB.BNumber) &&
-              (IRA.BNumber < IRB.ANumber)
-         ) {
-            Queue(W, ((PC + 2) % M));
-         } else {
-            Queue(W, ((PC + 1) % M));
-         };
-         break;
-      default:
-         return(UNDEFINED);
-         break;
-      };
-      break;
-
-
-/* SPL queues the next instruction and also queues the sum  */
-/* of the Program Counter and Pointer A.                    */
-
-   case SPL:
-      Queue(W, ((PC + 1) % M));
-      Queue(W, RPA);
-      break;
-
-
-/* NOP queues the next instruction.                         */
-
-   case NOP:
-      Queue(W, ((PC + 1) % M));
-      break;
-
-
-/* Any other opcode is undefined.                           */
-
-   default:
-      return(UNDEFINED);
-   };
-
-
-/* We are finished.                                         */
-
-   return(SUCCESS);
-}

Loader.py

-"""
-
-Ok, let's load the warriors from a serial line,
-
-and generate the Random position through a LFSR
-
-"""
-
-import MARSparam
-
-class ASCII:
-    NULL = 0x00
-    SOH  = 0x01
-    STX  = 0x02
-    ETX  = 0x03
-    EOT  = 0x04 # End of transmission
-    ENQ  = 0x05
-    ACK  = 0x06
-    BEL  = 0x07
-    BS   = 0x08
-    TAB  = 0x09
-    LF   = 0x0A
-    VT   = 0x0B
-    FF   = 0x0C
-    CR   = 0x0D
-    SO   = 0x0E
-    SI   = 0x0F
-    DLE  = 0x10
-    DC1  = 0x11
-    DC2  = 0x12
-    DC3  = 0x13
-    DC4  = 0x14
-    NAK  = 0x15
-    SYN  = 0x16
-    ETB  = 0x17
-    CAN  = 0x18
-    EM   = 0x19
-    SUB  = 0x1A
-    ESC  = 0x1B
-    FS   = 0x1C
-    GS   = 0x1D
-    RS   = 0x1E
-    US   = 0x1F
-
-from myhdl import *
-
-t_Parity = enum("EVEN", "ODD", "MARK", "SPACE", "NO")
-
-def Rx(Rx, data, clk, ack, rst_n, nbBits, baudrate, parity, clkrate):
-    """
-    My serial line
-    """
-
-    t_State = enum("WAIT", "DELAY", "RECEIVE")
-    sampling_time =  int(clkrate / baudrate)
-
-    state = Signal(t_State.WAIT)
-
-    data_i = Signal(intbv(0)[nbBits:])
-
-    bitReceived = Signal(intbv(0, min=0, max=nbBits+4))
-    time = Signal(intbv(0,min=0, max=sampling_time+2))
-
-    parity_bit = Signal(bool())
-    parity_ok = Signal(bool())
-
-
-    @always(clk.posedge, rst_n.negedge)
-    def rx():
-        if not rst_n:
-            state.next = t_State.WAIT
-            ack.next = False
-        elif clk:
-            if state == t_State.WAIT:
-                parity_ok.next = False
-                if Rx == False:
-                    # start bit
-                    state.next = t_State.DELAY
-                    bitReceived.next = 0
-                    time.next = sampling_time // 2
-                    if parity == t_Parity.EVEN:
-                        parity_bit.next = True
-                    elif parity == t_Parity.ODD:
-                        parity_bit.next = False
-
-            elif state == t_State.DELAY:
-                time.next = time + 1
-                if time == sampling_time-1:
-                    time.next = 0
-                    state.next = t_State.RECEIVE
-
-            elif state == t_State.RECEIVE:
-                ack.next = False
-                time.next = time + 1
-                state.next = t_State.DELAY
-                bitReceived.next = bitReceived + 1
-                if bitReceived == 0:
-                    # start bit
-                    pass
-
-                elif (bitReceived == nbBits+1) and (parity != t_Parity.NO): # parity bit
-                    if parity == t_Parity.MARK:
-                        parity_ok.next = Rx
-                    elif parity == t_Parity.SPACE:
-                        parity_ok.next = not Rx
-                    else:
-                        parity_ok.next = (parity_bit == Rx)
-
-                elif (((bitReceived == nbBits + 1) and (parity == t_Parity.NO)) or 
-                      ((bitReceived == nbBits + 2) and (parity != t_Parity.NO))):
-                    # stop bit
-                    state.next = t_State.WAIT
-                    if Rx:
-                        ack.next = (parity == t_Parity.NO) or parity_ok
-                        data.next = data_i
-                        data_i.next = 0
-                    else:
-                        ack.next = False
-                else: # usual communication
-                    parity_bit.next = parity_bit ^ Rx 
-                    data_i.next = int(Rx) * (2**(nbBits-1)) +  data_i[nbBits:1]
-            #                        data_i.next = concat(intbv(Rx.val)[1:], data_i.val[nbBits-1:])
-            
-
-    return rx
-
-
-def Tx(Tx, data, clk, req, ack, rst_n, nbBits, baudrate, parity, clkrate):
-    """ RS232 Transmitor """
-    t_State = enum("WAIT", "DELAY", "SEND")
-    sampling_time =  int(clkrate / baudrate)
-
-    state = Signal(t_State.WAIT)
-    
-    data_i = Signal(intbv()[nbBits:])
-
-    bitSent = Signal(intbv(0, min=0, max=nbBits+4))
-    time = Signal(intbv(0,min=0, max=sampling_time+2))
-
-    parity_bit = Signal(bool())
-    
-    @always(clk.posedge, rst_n.negedge)
-    def tx():
-        if not rst_n:
-            state.next = t_State.WAIT
-        elif clk:
-            if state == t_State.WAIT:
-                if req:
-                    data_i.next = data
-                    bitSent.next = 0
-                    state.next = t_State.SEND
-                    Tx.next = False
-                    time.next = 0
-                    if parity == t_Parity.EVEN:
-                        parity_bit.next = True
-                    elif parity == t_Parity.ODD:
-                        parity_bit.next = False
-
-            elif state == t_State.DELAY:
-                time.next = time + 1
-                if time == sampling_time-1:
-                    time.next = 0
-                    state.next = t_State.SEND
-
-            elif state == t_State.SEND:
-                ack.next = False
-                time.next = time + 1
-                state.next = t_State.DELAY
-                bitSent.next = bitSent + 1
-                if bitSent == 0:
-                    # start bit
-                    Tx.next = False
-
-                elif (bitSent == nbBits+1) and (parity != t_Parity.NO): 
-                    # parity bit
-                    if parity == t_Parity.MARK:
-                        Tx.next = True
-                    elif parity == t_Parity.SPACE:
-                        Tx.next = False
-                    else:
-                        Tx.next = parity_bit
-
-                elif  (((bitSent == nbBits+1) and (parity == t_Parity.NO)) or 
-                       ((bitSent == nbBits + 2) and (parity != t_Parity.NO))): 
-                       # stop bit
-                    state.next = t_State.WAIT
-                    Tx.next = True
-                    ack.next = True
-
-                else: # usual communication
-                    Tx.next = data_i[bitSent - 1]
-                    parity_bit.next = parity_bit ^ Tx.next 
-                    
-    return tx
-
-def RNG(out, clk, rst_n):
-    """
-    My LFSR
-
-    20 bits LFSR XNOR(20, 17)
-    """
-
-    @always(clk.posedge, rst_n.negedge)
-    def generate():
-        if not rst_n:
-            out.next = 0xa9e1b
-        elif clk:
-            out.next = out[19:] * 2 + (out[19] ^ out[16])
-
-    return generate
-
-def Loader(rs232_Rx, Warrior, we, Dout, we1, IP1, clk, rst_n, req, ack, baudrate):
-    """
-    The loader will be called once for all Warriors, then the Warriors will be sent over RS232.
-    """
-
-    random = Signal(intbv(0)[20:])
-
-    t_State = enum("IDLE","THINK", "RECEIVE", "WRITE")
-
-    state = Signal(t_State.IDLE)
-
-    @always(clk.posedge, rst_n.negedge)
-    def ctrl():
-        if not rst_n:
-            state.next = t_State.IDLE
-
-        elif clk:
-            if state == t_State.IDLE:
-                pass
-
-            elif state == t_State.THINK:
-                if Warrior != maxWarriors:
-                    state.next = t_State.RECEIVE
-                else:
-                    state.next = IDLE
-
-            elif state == t_State.RECEIVE:
-                pass
-
-            elif state == t_State.WRITE:
-                if data_i != ASCII.EOT:
-                    state.next = t_State.RECEIVE
-                else:
-                    state.next = t_State.THINK
-
-    @always(state)
-    def state():
-        we.next = False
-        we1.next = False
-        if state == t_State.IDLE:
-            pass
-        elif state == t_State.THINK:
-            we1.next = Address_i
-        elif state == t_State.RECEIVE:
-            pass
-        elif state == t_State.WRITE:
-            we.next = True
-            Dout.next = data_i
-
-    data_i = Signal(intbv(0)[MARSparam.InstrWidth:])
-
-
-    RNG_i = RNG(random, clk, rst_n)
-    # 1e9: ns;  10: clk @ 10 ns
-    Rx_i = Rx(rs232_Rx, data_i, clk, ack, rst_n, MARSparam.InstrWidth, baudrate, t_Parity.NO, 1e9/10 )
-
-    return ctrl, state, RNG_i, Rx_i

MARS.py

-
-from myhdl import *
-
-import MARSparam
-from MARSparam import *
-
-from Proc import Proc
-from Core import Core
-from Task import TaskQueue
-from Loader import Loader
-
-InstrEmpty = Instr(t_OpCode.DAT, t_Modifier.F, t_Mode.DIRECT, Addr(), t_Mode.DIRECT, Addr())
-
-def MARS(clk, rst_n, req, ack, RX_load, draw, Winner, nbWarriors, maxTime):
-    """ MARS is the reunion of the modules """  
-
-    t_State=enum("IDLE", "LOAD", "FETCH", "PROC")
-
-    state = Signal(t_State.IDLE)
-    prevWarrior, Warrior = [Signal(intbv(0, min=0, max=nbWarriors)) for i in range(2)]
-    Time = Signal(intbv(0, min=0, max=maxTime))
-
-    IP1_i, IP1_proc, IP1_load, PC_i, IP2_i, WOfs_i, ROfs = [Signal(Addr(0)) for i in range (7)]
-    we1_i, we1_load, we1_proc, we2_i, req_proc, ack_proc, req_load, ack_load, re_i, empty_i = [Signal(bool()) for i in range(10)]
-    Instr_i = Signal(Instr())
-    WData_i, RData_i, Dout_load, Dout_proc = [Signal(intbv(0)[MARSparam.InstrWidth:]) for i in range (4)]
-    we_i = Signal(intbv(0))
-
-    @always(clk.posedge, rst_n.negedge)
-    def fsm():
-        if not rst_n:
-            state.next = t_State.IDLE
-            ack.next = 0 
-            Warrior.next = 0
-            draw.next = True
-        elif clk:
-            if state == t_State.IDLE:
-                ack.next = False
-                if req:
-                    state.next = t_State.LOAD
-                    Warrior.next = 0
-                    req_load.next = True
-
-            elif state == t_State.LOAD:
-                req_load.next = False
-
-                # Here, we should do something about incrementing Warrior
-
-                if Warrior + 1 == nbWarriors:
-                    if ack_load:
-                        state.next = t_State.FETCH
-
-            elif state == t_State.FETCH:
-
-                # Increment the Current Warrior
-                if Warrior + 1 == nbWarriors:
-                    # We rounded: Increment the time, and start from 0 again
-                    Warrior.next = 0
-                    Time.next = Time + 1
-                else:
-                    Warrior.next = Warrior + 1
-
-                if Warrior.next == prevWarrior:
-                    # Only one Warrior left, he won !
-                    Winner.next = prevWarrior
-                    state.next = t_State.IDLE
-                    ack.next = True
-                elif not empty_i:
-                    # Current Warrior still has Task(s)
-                    draw.next = False
-                    state.next = t_State.PROC
-                    Instr_i.next = RData
-                    req_proc.next = True
-            elif state == t_State.PROC:
-                req_proc.next = False
-                if ack_proc:
-                    if Time < maxTime:
-                        t_State.next = t_State.FETCH
-                    else:
-                        print "Time is over"
-                        state.next = IDLE
-                        draw.next = True
-                        ack.next = True
-                        
-    @always(state)
-    def ctrl():
-        if state == t_State.IDLE:
-            pass
-        elif state == t_State.FETCH:
-            prevWarrior.next = Warrior
-        elif state == t_State.PROC:
-            pass
-
-    @always_comb
-    def updateval():
-        """ At loading time, we have different input than at processing time. """
-        IP1_i.next = IP1_proc
-        we1_i.next = we1_proc
-        WData_i.next = Dout_proc
-        if state == t_State.LOAD:
-            IP1_i.next = IP1_load
-            we1_i.next = we1_load
-            WData_i.next = Dout_load
-
-    Proc_i = Proc(Instr=Instr_i, PC=PC_i, IPOut1=IP1_proc, we1=we1_proc, IPOut2=IP2_i, we2=we2_i, WOfs=WOfs_i, WData=Dout_proc, we=we_i, ROfs=ROfs, RData=RData_i, clk=clk, rst_n=rst_n, req=req_proc, ack=ack_proc)
-
-    Loader_i = Loader(RX_load, Warrior, we1_load, Dout_load, we1_load, IP1_load, clk, rst_n, req_load, ack_load, 9600)
-    Core_i = Core(pc=PC_i, WOfs=WOfs_i, din=WData_i, ROfs=ROfs, dout=RData_i, we=we_i, clk=clk, rst_n=rst_n, maxSize=CORESIZE)
-
-    Queue_i = TaskQueue(Warrior=Warrior,IPin1=IP1_i, IPin2=IP2_i, IPout=PC_i, re=re_i, we1=we1_i, we2=we2_i, empty=empty_i, clk=clk, rst_n=rst_n, maxWarriors=nbWarriors)
-     
-    return Proc_i, Loader_i, Core_i, Queue_i, fsm, ctrl, updateval

MARSparam.py

-"""
-MARS Parameters
-"""
-
-from myhdl import intbv, enum
-
-CORESIZE = 8000
-
-AddrWidth = len(intbv(min=0, max=CORESIZE))
-
-MAXPROCESSES = CORESIZE/16
-
-# Constant for the Size of an Instruction
-# usefull for slicing
-InstrWidth = 14 + 2 * AddrWidth
-
-ReadRange = 400
-WriteRange = 400
-
-class we:
-    OpCode = intbv("100000")
-    Modif  = intbv("010000")
-    AMod   = intbv("001000")
-    ANum   = intbv("000100")
-    BMod   = intbv("000010")
-    BNum   = intbv("000001")
-    Full   = OpCode | Modif | AMod | ANum | BMod | BNum
-    A      = ANum
-    B      = BNum
-    AB     = BNum
-    BA     = ANum
-    F      = ANum | BNum
-    X      = ANum | BNum
-    I      = Full
-
-class t_OpCode:
-    DAT, MOV, ADD, SUB, MUL, DIV, MOD, JMP, JMZ, JMN, DJN, CMP, SNE, SLT, SPL, NOP = [intbv(i)[5:] for i in range(16)]
-    SEQ = CMP
-
-class t_Modifier:
-    A, B, AB, BA, F, X, I = [intbv(i)[3:] for i in range(7)]
-
-class t_Mode:
-    IMMEDIATE, DIRECT, A_INDIRECT, A_DECREMENT, A_INCREMENT, B_INDIRECT, B_DECREMENT, B_INCREMENT = [intbv(i)[3:] for i in range(8)]
-
-
-    @classmethod
-    def __getitem__(key):
-
-        if (type(key) != "str")  or (len(key) != 1):
-            raise TypeError("Wrong type")
-
-        if key == '#':
-            return IMMEDIATE
-        elif key == '$':
-            return DIRECT
-        elif key == '*':
-            return A_INIDRECT
-        elif key == '@':
-            return B_INDIRECT
-        elif key == '{':
-            return A_DECREMENT
-        elif key == '<':
-            return B_DECREMENT
-        elif key == '}':
-            return A_INCREMENT
-        elif key == '>':
-            return B_INCREMENT
-        else:
-            raise KeyError("Modifier %s not defined" % name)
-
-
-class Addr(intbv):
-    def __init__(self, val=0):
-        if val < 0:
-            val = (val + CORESIZE) % CORESIZE
-        intbv.__init__(self, val, min=0, max=CORESIZE)
-
-class Instr(intbv):
-    def __init__(self, OpCode=None, Modifier=None, AMode=None, ANumber=None, BMode=None, BNumber=None, val=None):
-        if not val:
-            val = 0
-        intbv.__init__(self, val, _nrbits=InstrWidth)
-        if OpCode:
-            self[InstrWidth:InstrWidth-5] = OpCode
-        if Modifier:
-            self[InstrWidth-5:InstrWidth-8] = Modifier
-        if AMode:
-            self[InstrWidth-8:InstrWidth-11] = AMode
-        if ANumber:
-            self[InstrWidth-11:InstrWidth-11-AddrWidth] = ANumber
-        if BMode:
-            self[AddrWidth+3:AddrWidth] = BMode
-        if BNumber:
-            self[AddrWidth:] = BNumber
-
-    def __getattr__(self, name):
-        if name == "OpCode":
-            return self[InstrWidth:InstrWidth-5]
-        elif name == "Modifier":
-            return self[InstrWidth-5:InstrWidth-8]
-        elif name == "AMode":
-            return self[InstrWidth-8:InstrWidth-11]
-        elif name == "ANumber":
-            return self[InstrWidth-11:InstrWidth-11-AddrWidth]
-        elif name == "BMode":
-            return self[AddrWidth+3:AddrWidth]
-        elif name == "BNumber":
-            return self[AddrWidth:0]
-        else:
-            return intbv.__getattr__(name)
-
-    def __setattr__(self, name, value):
-        if name == "OpCode":
-            self[InstrWidth:InstrWidth-5] = value
-        elif name == "Modifier":
-            self[InstrWidth-5:InstrWidth-8] = value
-        elif name == "AMode":
-            self[InstrWidth-8:InstrWidth-11] = value
-        elif name == "ANumber":
-            self[InstrWidth-11:InstrWidth-11-AddrWidth] = value
-        elif name == "BMode":
-            self[AddrWidth+3:AddrWidth] = value
-        elif name == "BNumber":
-            self[AddrWidth:0] = value
-        else:
-            intbv.__setattr__(self, name,value)
-
-    def __str__(self):
-        return "%s_%s_%s_%s_%s_%s" % (self.OpCode, self.Modifier, self.AMode, self.ANumber, self.BMode, self.BNumber)
-
-    def __copy__(self):
-        return Instr(val=self)
-
-    def __deepcopy__(self, visit):
-        return Instr(val=self)

Proc.py

-"""
-This is the processor of the MARS
-
-We will try to keep it as quick as possible ...
-"""
-
-from myhdl import *
-
-import MARSparam
-from MARSparam import t_OpCode, t_Modifier, t_Mode
-from MARSparam import InstrWidth
-
-def EvalOp(Mod, Number, Ptr, WData, we, ROfs, RData, clk, rst_n, req, ack):
-    """
-    Eval A operand (Or actually B operand)
-
-    assumption:
-    WOfs == Number
-
-
-    """
-
-    t_State = enum("IDLE", "SET", "COMPUTE", "READ")
-    state = Signal(t_State.IDLE)
-
-    @always(clk.posedge, rst_n)
-    def fsm():
-        if not rst_n:
-            state.next = t_State.IDLE
-        elif clk:
-            if state == t_State.IDLE:
-                if req:
-                    if Mod in (t_Mode.IMMEDIATE,
-                               t_Mode.DIRECT):
-                        state.next = t_State.COMPUTE
-                    else:
-                        state.next = t_State.SET
-            elif state == t_State.SET:
-                state.next = t_State.COMPUTE
-            elif state == t_State.COMPUTE:
-                state.next = t_State.READ
-            elif state == t_State.READ:
-                state.next = t_State.IDLE
-
-    @always(state)
-    def out():
-        we.next = 0
-        if state == t_State.SET:
-            ROfs.next = Number
-        if state == t_State.COMPUTE:
-            if Mod == t_Mode.IMMEDIATE:
-                Ptr.next = 0
-            elif Mod == t_Mode.DIRECT:
-                Ptr.next = Number
-
-            elif Mod == t_Mode.A_INDIRECT:
-                Ptr.next = (MARSparam.Instr(val=int(RData)).ANumber + Number) % MARSparam.CORESIZE
-            elif Mod == t_Mode.A_INCREMENT:
-                Ptr.next = (MARSparam.Instr(val=int(RData)).ANumber + Number + 1) % MARSparam.CORESIZE
-                we.next = MARSparam.we.ANum
-                WData.next = (MARSparam.Instr(val=int(RData)).ANumber + 1) % MARSparam.CORESIZE
-            elif Mod == t_Mode.A_DECREMENT:
-                Ptr.next = (MARSparam.Instr(val=int(RData)).ANumber + Number - 1) % MARSparam.CORESIZE
-                we.next = MARSparam.we.ANum
-                WData.next = (MARSparam.Instr(val=int(RData)).ANumber - 1) % MARSparam.CORESIZE
-
-            elif Mod == t_Mode.B_INDIRECT:
-                Ptr.next = (MARSparam.Instr(val=int(RData)).BNumber + Number) % MARSparam.CORESIZE
-            elif Mod == t_Mode.B_INCREMENT:
-                Ptr.next = (MARSparam.Instr(val=int(RData)).BNumber + Number + 1) % MARSparam.CORESIZE
-                we.next = MARSparam.we.BNum
-                WData.next = (MARSparam.Instr(val=int(RData)).BNumber + 1) % MARSparam.CORESIZE
-            elif Mod == t_Mode.B_DECREMENT:
-                Ptr.next = (MARSparam.Instr(val=int(RData)).BNumber + Number - 1) % MARSparam.CORESIZE
-                we.next = MARSparam.we.BNum
-                WData.next = (MARSparam.Instr(val=int(RData)).BNumber - 1) % MARSparam.CORESIZE
-            else:
-                raise ValueError("Mod: %d not understood" % Mod)
-        elif state == t_State.READ:
-            # setting ack works here because our RAM has an asynchronous read bus.
-            ack.next = True
-            ROfs.next = Ptr
-        elif state == t_State.IDLE:
-            ack.next = False
-
-    return fsm, out
-
-def OutQueue(OpCode, Modifier, IRA, IRB, RPA, PC, IPout1, we1, IPout2, we2, clk):
-    """
-    The Exec part that output to the TaskQueue
-
-    output: IPout1, IPout2, we1, we2
-
-    """
-
-    @always(clk.posedge)
-    def Out1():
-        """ output IPout1 and we1 """
-        PC1 = (PC + 1) % MARSparam.CORESIZE
-        PC2 = (PC + 2) % MARSparam.CORESIZE
-        PCRPA = (PC + RPA) % MARSparam.CORESIZE
-        we1.next = True
-        if OpCode == t_OpCode.DAT:
-            we1.next = False
-        elif OpCode in (t_OpCode.MOV,
-                        t_OpCode.ADD,
-                        t_OpCode.SUB,
-                        t_OpCode.MUL,
-                        t_OpCode.SPL,
-                        t_OpCode.NOP):
-            IPout1.next = PC1
-        elif OpCode == t_OpCode.JMP:
-            IPout1.next = PCRPA
-        elif OpCode in (t_OpCode.JMZ,
-                        t_OpCode.JMN,
-                        t_OpCode.DJN):
-
-            def test(Number):
-                if OpCode == t_OpCode.JMZ:
-                    return Number == 0
-                elif OpCode == t_OpCode.JMN:
-                    return Number != 0
-                elif OpCode == t_OpCode.DJN:
-                    return (Number - 1) != 0
-
-            if Modifier in (t_Modifier.A,
-                            t_Modifier.BA):
-                if test(IRB.ANumber):
-                    IPout1.next = PCRPA
-                else:
-                    IPout1.next = PC1
-            elif Modifier in (t_Modifier.B,
-                              t_Modifier.AB):
-                if test(IRB.BNumber):
-                    IPout1.next = PCRPA
-                else:
-                    IPout1.next = PC1
-            elif Modifier in (t_Modifier.F,
-                              t_Modifier.X,
-                              t_Modifier.I):
-                if test(IRB.ANumber) and test(IRB.BNumber):
-                    IPout1.next = PCRPA
-                else:
-                    IPout1.next = PC1
-
-        elif OpCode == t_OpCode.CMP:
-            if Modifier == t_Modifier.A:
-                if IRA.ANumber == IRB.ANumber:
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-            elif Modifier == t_Modifier.B:
-                if IRA.BNumber == IRB.BNumber:
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-            elif Modifier == t_Modifier.AB:
-                if IRA.ANumber == IRB.BNumber:
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-            elif Modifier == t_Modifier.BA:
-                if IRA.BNumber == IRB.ANumber:
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-            elif Modifier == t_Modifier.F:
-                if (IRA.ANumber == IRB.ANumber) and (IRA.BNumber == IRB.BNumber):
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-            elif Modifier == t_Modifier.X:
-                if (IRA.ANumber == IRB.BNumber) and (IRA.BNumber == IRB.ANumber):
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-            elif Modifier == t_Modifier.I:
-                if IRA == IRB:
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-
-        elif OpCode == t_OpCode.SNE:
-            if Modifier == t_Modifier.A:
-                if IRA.ANumber != IRB.ANumber:
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-            elif Modifier == t_Modifier.B:
-                if IRA.BNumber != IRB.BNumber:
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-            elif Modifier == t_Modifier.AB:
-                if IRA.ANumber != IRB.BNumber:
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-            elif Modifier == t_Modifier.BA:
-                if IRA.BNumber != IRB.ANumber:
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-            elif Modifier == t_Modifier.F:
-                if (IRA.ANumber != IRB.ANumber) or (IRA.BNumber != IRB.BNumber):
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-            elif Modifier == t_Modifier.X:
-                if (IRA.ANumber != IRB.BNumber) or (IRA.BNumber != IRB.ANumber):
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-            elif Modifier == t_Modifier.I:
-                if IRA != IRB:
-                    IPout1.next = PC2
-                else:
-                    IPout1.next = PC1
-
-        elif OpCode in (t_OpCode.DIV,
-                        t_OpCode.MOD):
-            if Modifier in (t_Modifier.A,
-                            t_Modifier.AB,
-                            t_Modifier.F,
-                            t_Modifier.I,
-                            t_Modifier.X):
-                if IRA.ANumber == 0:
-                    we1.next = False
-            if Modifier in (t_Modifier.B,
-                            t_Modifier.BA,
-                            t_Modifier.F,
-                            t_Modifier.I,
-                            t_Modifier.X):
-                if IRA.BNumber == 0:
-                    we1.next = False
-
-        else:
-            raise NotImplementedError("Queue: Only few OpCode are Implemented: not %s" % OpCode)
-
-    @always(clk.posedge)
-    def Out2():
-        """ output IPout2 and we2 """
-        we2.next = False
-        if OpCode == t_OpCode.SPL:
-            IPout2.next = (PC + RPA) % MARSparam.CORESIZE
-            we2.next = True
-
-    return Out1, Out2
-
-def OutCore(OpCode, Modifier, IRA, IRB, we, WData, clk):
-    """
-    WPA is not used anymore at this stage
-    RPA is only used to Queue
-
-    RPB is not used any more at this stage
-    WPB is used for every write
-
-    assumption:
-    WOfs == BPtr
-
-    Any division by Zero is killing the current task
-    """
-
-    @always(clk.posedge)
-    def comb():
-
-        def op(OpCode, Num1, Num2):
-            if OpCode == t_OpCode.ADD:
-                return (Num1 + Num2) % MARSparam.CORESIZE
-            elif OpCode == t_OpCode.SUB:
-                return (Num1 + MARSparam.CORESIZE - Num2) % MARSparam.CORESIZE
-            elif OpCode == t_OpCode.MUL:
-                return (Num1 * Num2)  % MARSparam.CORESIZE
-            elif OpCode == t_OpCode.DIV:
-                return Num1 / Num2
-            elif OpCode == t_OpCode.MOD:
-                return Num1 % Num2
-            else:
-                raise ValueError("OpCode %s is not arithmetic" % OpCode)
-
-        we.next = 0
-        if OpCode in (t_OpCode.DAT,
-                      t_OpCode.JMP,
-                      t_OpCode.JMZ,
-                      t_OpCode.JMN,
-                      t_OpCode.CMP,
-                      t_OpCode.SNE,
-                      t_OpCode.SLT,
-                      t_OpCode.SPL,
-                      t_OpCode.NOP):
-            # Those don't touch the Core
-            pass
-
-        elif OpCode == t_OpCode.MOV:
-            if Modifier == t_Modifier.A:
-                WData.next = MARSparam.Instr(ANumber=IRA.Anumber)
-                we.next = MARSparam.we.A
-            elif Modifier == t_Modifier.B:
-                WData.next = MARSparam.Instr(BNumber=IRA.BNumber)
-                we.next = MARSparam.we.B
-            elif Modifier == t_Modifier.AB:
-                WData.next = MARSparam.Instr(BNumber=IRA.ANumber)
-                we.next = MARSparam.we.AB
-            elif Modifier == t_Modifier.BA:
-                WData.next = MARSparam.Instr(ANumber=IRA.Bnumber)
-                we.next = MARSparam.we.BA
-            elif Modifier == t_Modifier.F:
-                WData.next = MARSparam.Instr(ANumber=IRA.ANumber,
-                                             BNumber=IRA.BNumber)
-                we.next = MARSparam.we.F
-            elif Modifier == t_Modifier.X:
-                WData.next = MARSparam.Instr(ANumber=IRA.Bnumber, 
-                                             BNumber=IRA.ANumber)
-                we.next = MARSparam.we.X
-            elif Modifier == t_Modifier.I:
-                WData.next = IRA
-                we.next = MARSparam.we.I
-            else:
-                raise ValueError("Modifier %d not supported" % Modifier)
-
-        elif OpCode in (t_OpCode.ADD,
-                        t_OpCode.SUB,
-                        t_OpCode.MUL):
-            if Modifier == t_Modifier.A:
-                WData.next = MARSparam.Instr(ANumber = op(OpCode, IRB.ANumber, IRA.ANumber))
-                we.next = MARSparam.we.A
-            elif Modifier == t_Modifier.B:
-                WData.next = MARSparam.Instr(BNumber = op(OpCode, IRB.BNumber, IRA.BNumber))
-                we.next = MARSparam.we.B
-            elif Modifier == t_Modifier.AB:
-                WData.next = MARSparam.Instr(BNumber = op(OpCode,  IRB.BNumber, IRA.ANumber))
-                we.next = MARSparam.we.AB
-            elif Modifier == t_Modifier.BA:
-                WData.next = MARSparam.Instr(ANumber = op(OpCode, IRB.ANumber, IRA.BNumber))
-                we.next = MARSparam.we.BA
-            elif Modifier in (t_Modifier.F, 
-                           t_Modifier.I):
-                WData.next = MARSparam.Instr(ANumber = op(OpCode, IRB.ANumber, IRA.ANumber),
-                                             BNumber = op(OpCode, IRB.BNumber, IRA.BNumber))
-                we.next = MARSparam.we.F
-            elif Modifier == t_Modifier.X:
-                WData.next = MARSparam.Instr(BNumber = op(OpCode, IRB.ANumber, IRA.BNumber),
-                                             ANumber = op(OpCode, IRB.BNumber, IRA.ANumber))
-                we.next = MARSparam.we.F
-            else:
-                raise ValueError(Modifier)
-
-        elif OpCode == t_OpCode.DJN:
-            if Modifier in (t_Modifier.A, 
-                            t_Modifier.BA):
-                Num = (IRB.ANumber + MARSparam.CORESIZE - 1) % MARSparam.CORESIZE
-                WData.next = MARSparam.Instr(ANumber=Num)
-                IRB.next = MARSparam.Instr(val=int(IRB), ANumber=Num)
-                we.next = MARSparam.we.A
-            elif Modifier in (t_Modifier.B,
-                              t_Modifier.AB):
-                Num = (IRB.BNumber + MARSparam.CORESIZE - 1) % MARSparam.CORESIZE
-                WData.next = MARSparam.Instr(BNumber=Num)
-                IRB.next = MARSparam.Instr(val=int(IRB), BNumber=Num)
-                we.next = MARSparam.we.B
-            elif Modifier in (t_Modifier.F,
-                              t_Modifier.X,
-                              t_Modifier.I):
-                ANum = (IRB.ANumber + MARSparam.CORESIZE - 1) % MARSparam.CORESIZE
-                BNum = (IRB.BNumber + MARSparam.CORESIZE - 1) % MARSparam.CORESIZE
-                WData.next = MARSparam.Instr(ANumber=ANum, BNumber=BNum)
-                IRB.next = MARSparam.Instr(val=int(IRB), ANumber=Num, BNumber=BNum)
-                we.next = MARSparam.we.F
-
-        else:
-            raise NotImplementedError("Core: Only few OpCode are implemented ; not %s" % OpCode)
-
-    return comb
-
-def Proc(Instr, PC, IPOut1, we1, IPOut2, we2, WOfs, WData, we, ROfs, RData, clk, rst_n, req, ack):
-    """
-    We have here  three state fsm: EvalA, EvalB, The rest
-    Thus we have state, thus, we need a rst(_n)
-    
-    """
-
-    t_State = enum("IDLE", "EVALOPA", "EVALOPB", "REST")
-
-    state = Signal(t_State.IDLE)
-
-    OpCode = Signal(intbv(0)[5:])
-    Modifier = Signal(intbv(0)[3:])
-    AMode = Signal(intbv(0)[3:])
-    ANumber = Signal(MARSparam.Addr())
-    BMode = Signal(intbv(0)[3:])
-    BNumber = Signal(MARSparam.Addr())
-
-    APtr, BPtr, ROfs_evalopa, ROfs_evalopb = [Signal(MARSparam.Addr()) for i in range(4)]
-
-    IRA, IRB = [Signal(MARSparam.Instr()) for i in range(2)]
-
-    WData_evalopa, WData_evalopb, WData_outcore = [Signal(intbv(0)[MARSparam.InstrWidth:]) for i in range(3)]
-
-    we_evalopa, we_evalopb, we_outcore = [Signal(intbv(0)[6:]) for i in range(3)]
-    
-    req_evalopa, ack_evalopa, req_evalopb, ack_evalopb = [Signal(bool()) for i in range(4)]
-
-    we1_outqueue, we2_outqueue = [Signal(bool()) for i in range(2)]
-
-    EvalAOp = EvalOp(AMode, ANumber, APtr, WData_evalopa, we_evalopa, ROfs_evalopa, RData, clk, rst_n, req_evalopa, ack_evalopa)
-    EvalBOp = EvalOp(BMode, BNumber, BPtr, WData_evalopb, we_evalopb, ROfs_evalopb, RData, clk, rst_n, req_evalopb, ack_evalopb)
-    OutQueue_i = OutQueue(OpCode, Modifier, IRA, IRB, APtr, PC, IPOut1, we1_outqueue, IPOut2, we2_outqueue, clk)
-    OutCore_i = OutCore(OpCode, Modifier, IRA, IRB, we_outcore, WData_outcore, clk)
-
-    @always_comb
-    def link():
-        OpCode.next = Instr.OpCode
-        Modifier.next = Instr.Modifier
-        AMode.next = Instr.AMode
-        ANumber.next = Instr.ANumber
-        BMode.next = Instr.BMode
-        BNumber.next = Instr.BNumber
-        req_evalopb.next = ack_evalopa
-        req_evalopa.next = req
-
-    @always(clk.posedge, rst_n.negedge)
-    def fsm():
-        if rst_n == False:
-            state.next = t_State.IDLE
-        elif clk:
-            if state == t_State.IDLE:
-                ack.next = False
-                if req:
-                    state.next = t_State.EVALOPA
-            elif state == t_State.EVALOPA:
-                # we could jump to REST if evalopa and evalopb 
-                # both don't write and if B is not dependant 
-                # on A's output
-                if ack_evalopa:
-                    state.next = t_State.EVALOPB
-            elif state == t_State.EVALOPB:
-                if ack_evalopb:
-                    #IRB.next = MARSparam.Instr(val=int(RData))
-                    state.next = t_State.REST
-            elif state == t_State.REST:
-                state.next = t_State.IDLE
-                ack.next = True
-            else:
-                raise ValueError("state value not allowed: %s" % state)
-            
-    @always(state)
-    def fsmcore():
-        """
-        Output Signals for the Core
-        actually: a few big MUX
-        """
-
-        we1.next = False
-        we2.next = False
-        if state == t_State.IDLE:
-            pass
-        elif state == t_State.EVALOPA:
-            WOfs.next = ANumber
-        elif state == t_State.EVALOPB:
-            WOfs.next = BNumber
-        elif state == t_State.REST:
-            WOfs.next = BPtr
-            # We are lucky here as REST is a one shoot process ... 
-            we1.next = we1_outqueue
-            we2.next = we2_outqueue
-
-    @always_comb
-    def updateROfs():
-        if state == t_State.EVALOPA:
-            ROfs.next = ROfs_evalopa
-        elif state == t_State.EVALOPB:
-            ROfs.next = ROfs_evalopb
-        elif state == t_State.IDLE:
-            ROfs.next = 0
-
-    @always_comb
-    def updateIRX():
-        if state == t_State.EVALOPA:
-            IRA.next = MARSparam.Instr(val=int(RData))
-        elif state == t_State.EVALOPB:
-            IRB.next = MARSparam.Instr(val=int(RData))
-
-    @always_comb
-    def updatewe():
-        if state == t_State.IDLE:
-            we.next = 0
-        if state == t_State.EVALOPA:
-            we.next = we_evalopa
-        elif state == t_State.EVALOPB:
-            we.next = we_evalopb
-        elif state == t_State.REST:
-            we.next = we_outcore
-
-    @always_comb
-    def updatewdata():
-        if state == t_State.IDLE:
-            pass
-        elif state == t_State.EVALOPA:
-            WData.next = WData_evalopa
-        elif state == t_State.EVALOPB:
-            WData.next = WData_evalopb
-        elif state == t_State.REST:
-            WData.next = WData_outcore
-
-
-    return EvalAOp, EvalBOp, OutQueue_i, OutCore_i, link, fsm, fsmcore, updateROfs, updateIRX, updatewe, updatewdata

Task.py

-"""
-This is the Task Queue of the MARS
-"""
-
-from myhdl import *
-
-import MARSparam
-
-def FIFO(dout, din1, we1, din2, we2, re, empty, clk, rst_n, maxFilling, ID = None):
-    """ Fifo that fits our need: without full flag """
-
-    content = []
-
-    @always(clk.posedge, rst_n.negedge)
-    def access():
-        if rst_n == False:
-            del content[:] # that one is tricky ...
-        elif clk == True:
-            if ID != None:
-                print "FIFO::%d (%d) we1:%s we2:%s re:%s " % (ID, len(content), we1, we2, re)
-            if we1:
-                if (len(content) < maxFilling):
-                    content.insert(0, din1.val)
-            if we2:
-                if not we1:
-                    raise ValueError("Writing to second channel when First one not used")
-                if (len(content) < maxFilling):
-                    content.insert(0, din2.val)
-
-            if re:
-                dout.next = content.pop()
-        empty.next = (len(content) == 0)
-
-    return access
-
-def TaskQueue(Warrior, IPin1, IPin2, IPout, re, we1, we2, empty, clk, rst_n, maxWarriors, maxFilling=MARSparam.MAXPROCESSES):
-    
-    dout_i = [Signal(intbv(0)[MARSparam.AddrWidth:]) for i in range(maxWarriors)]
-    din1_i, din2_i = [[Signal(intbv(0)[MARSparam.AddrWidth:]) for i in range(maxWarriors)]for i in range(2)]
-    re_i = [Signal(bool(False)) for i in range(maxWarriors)]
-    we1_i, we2_i = [[Signal(bool(False)) for i in range(maxWarriors)] for i in range (2)]
-    empty_i = [Signal(bool(True)) for i in range(maxWarriors)]
-    clk_i = [Signal(bool(False)) for i in range(maxWarriors)]
-    queue = [FIFO(dout=dout_i[i],
-                  din1=din1_i[i],
-                  din2=din2_i[i],
-                  re=re_i[i],
-                  we1=we1_i[i],
-                  we2=we2_i[i],
-                  empty=empty_i[i],
-                  clk=clk_i[i],
-                  rst_n=rst_n,
-                  maxFilling=maxFilling,
-                  ID=i)
-             for i in range(maxWarriors)]
-
-    @always_comb
-    def comb():
-        """ Combinationnal part
-            That basically is a big MUX
-
-        in:
-          - dout_i
-          - IPin
-          - re
-          - we
-          - empty_i
-          - Warrior
-        out:
-          - IPout
-          - din_i
-          - re_i
-          - we_i
-          - empty
-        """
-        IPout.next = dout_i[int(Warrior)]
-        din1_i[int(Warrior)].next = IPin1
-        din2_i[int(Warrior)].next = IPin2
-        re_i[int(Warrior)].next = re
-        we1_i[int(Warrior)].next = we1
-        we2_i[int(Warrior)].next = we2
-        empty.next = empty_i[int(Warrior)]
-        clk_i[int(Warrior)].next = clk
-
-    @always(clk)
-    def shooter():
-        clk_i[int(Warrior)].next = clk 
-
-    return queue, comb
+/************************************/
+/*                                  */
+/*            EMI94.c               */
+/*                                  */
+/* Execute MARS Instruction ala     */
+/* ICWS'94 Draft Standard.          */
+/*                                  */
+/* Last Update: November 8, 1995    */
+/*                                  */
+/************************************/
+
+/* This ANSI C function is the benchmark MARS instruction   */
+/* interpreter for the ICWS'94 Draft Standard.              */
+
+
+/* The design philosophy of this function is to mirror the  */
+/* standard as closely as possible, illuminate the meaning  */
+/* of the standard, and provide the definitive answers to   */
+/* questions of the "well, does the standard mean this or   */
+/* that?" variety.  Although other, different implemen-     */
+/* tations are definitely possible and encouraged; those    */
+/* implementations should produce the same results as this  */
+/* one does.                                                */
+
+
+/* The function returns the state of the system.  What the  */
+/* main program does with this information is not defined   */
+/* by the standard.                                         */
+
+enum SystemState {
+   UNDEFINED,
+   SUCCESS
+};
+
+
+/* Any number of warriors may be executing in core at one   */
+/* time, depending on the run-time variable set and how     */
+/* many warriors have failed during execution.  For this    */
+/* implementation, warriors are identified by the order in  */
+/* which they were loaded into core.                        */
+
+typedef unsigned int Warrior;
+
+
+/* An Address in Core War can be any number from 0 to the   */
+/* size of core minus one, relative to the current          */
+/* instruction.  In this implementation, core is an array   */
+/* of instructions; therefore any variable types which      */
+/* contain an Address can be considered to be of type       */
+/* unsigned int.  One caveat: for the purposes of this      */
+/* standard, unsigned int must be considered to have no     */
+/* upper limit.  Depending on the size of core, it may be   */
+/* necessary to take precautions against overflow.          */
+
+typedef unsigned int Address;
+
+
+/* The FIFO task queues and supporting functions are not    */
+/* presented.   The function Queue() attempts to add a task */
+/* pointer to the back of the currently executing warrior's */
+/* task queue.  No special actions are to be taken if       */
+/* Queue() is unsuccessful, which it will be if the warrior */
+/* has already reached the task limit (maximum allowable    */
+/* number of tasks).                                        */
+
+extern void Queue(
+   Warrior  W,
+   Address  TaskPointer
+);