marcinas / LC2200Simulator

LC2200 simulator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

372Project

LC2200 Simulator Manual

/* *****************************************************************************

  • littlecomputer2200 (LC2200) i.e., control unit

  • Functioning like the control unit, the LC2200 oversees all aspects of the
  • system and, like a conductor, tells them what to do by flipping signals in
  • each component. Everything the actual LC2200 computer contains--defined as very
  • modularized as simply the computer's logic circuits (struct), not the main,
  • the graphicaluserinterface (gui), or the assemblymachinereader (asm), or
  • anything else consisting or I/O--communicates through the LC2200 control unit
  • and not through each other.
  • The control unit is responsible for setting the machine in its initial ready-
  • to-start stage. This consists of every possible value in the varous
  • components being set to 0 or equivalent (false, which in C is 0)--off.
  • This is, in all respects, the brain of the machine. Each of the subcomponents
  • have mostly skeletal code: primitive types (see instructionsetarchitecture
  • (bit) for more info), and very short functions that simply update the struct
  • values from the bus or vice versa. This is the handshake that the machine
  • makes with its parts: you are to do nothing unless instructed--and then
  • you are only responsible for exchanging data. The only component that
  • vary slightly from this is the alu, although it is simply comprised on a few
  • very short functions following the handshake rules as well. */

/* SIGNAL ENUM


  • Used in the three macro-stage cycle to emulate drive, load, and write. */ typedef enum { Dr, Ld, Wr } signalx;

/* COMPONENT ENUM


  • The current component that the control unit is sending signals to. */ typedef enum { _pc, _aluA, _aluB, _reg, _mem, _ir } componentx;

/* littlecomputer (LC2200) struct


  • The setup of the LC2200, including all of the components and several bit
  • switches for operations and debugging. */ typedef struct { bit safetydebug; bit statedebug; bit microdebug; bit clock; bit z; word cycle; fsm_ fsm; pc_ pc; alu_ alu; reg_ reg; mem_ mem; ir_ ir; } littlecomputer2200;

/* POINTER */ typedef littlecomputer2200 *LC2200_;

/* CONSTRUCTOR/DESTRUCTOR */ LC2200_ LC2200_ctor(); void LC2200_kill(LC2200_);

/* METHODS */ void start(LC2200_, char); //starts the system under certain conditions void setupcycle(LC2200_); //cycle phase i void switchstate(LC2200_); //cycle phase ii void microstate(LC2200_); //cycle phase iii void calleesave(LC2200_); //unimplemented void debug(LC2200_); //for testing

/* KILL


  • Kills every one of its components and then falls on the sword itself. */

/* START


  • Starts the system. Upon start, the machine will run until it reaches a halt,
  • hits a predefined safety limit, a certain amount of steps, or a jumping or
  • branching instruction. */

/* CYCLE PHASE I


  • Reads the next state in the finitestatemachine (fsm) and flips every signal
  • in the computer's components to what it will need to be for the next
  • microstate. This ensures that when the load, drive, and write signals are
  • fired, the appropriate parts of the system will be primed to write to and
  • read from the bus. */

/* CYCLE PHASE II


  • Depending on the last four bits of the ROM state, the control unit will
  • a series of elaborate check to determine what the next microstate will be.
  • The factors effecting its decision are the instructionregister (ir)'s opcode
  • value, the current state's 10 bits of state information, the z-value attached
  • to the value of the bus, and additional constraints on the micro cycle. See
  • the finitestatemachine (fsm) for more information. */

/* CYCLE PHASE III


  • For each stage in the drive-load-write progression, sends out an activation
  • signal to each component. If that component's respective signal is flipped
  • true, then the component performs its indicated action, either pushing a word
  • onto the bus or reading from the bus and storing or writing the information. */

/* DEBUG OUTPUT


  • Prints to console the state of every struct data piece of every component.
  • Will omit finitestatemachine (fsm)'s ROM, registerfile (reg)'s reserved and
  • callee-save bits, and randomaccessmemory (mem)'s MEM to a certain limit
  • based on the LC2200's header file. */

/* *****************************************************************************

  • instructionsetarchitecture (bit)

  • The bit file contains definitions for the actual data types underlying the
  • LC2200 and all of its components and accessories. The reason for typedef-ing
  • a data type was so that it could be changed relatively quickly if was needed
  • --by having all of its data types coded this way (and having all of the
  • conversion of data types be handled through the .c version of bit), we were
  • enabled to try several formats. Ultimately, it was decided that:
  • data type internal underlying purpose
  • boolean bit _Bool simple 2-value switch, or bit
  • 32-bit long word uint32_t 4 byte values for registers, memory
  • signed long aluw int32_t special signed 4 byte word for alu
  • 32-bit long bus word connecting the system dialogues */

/* SYSTEM WIDE CASTS DEFINITIONS */ typedef _Bool bit; //boolean signal/switch/bit typedef uint32_t word; //four bytes, system basis typedef int32_t aluw; //special signed word for the alu

/* GLOBAL DECLARATION OF BUS */ extern word bus;

/* BIT, WORD, STRING, and SPECIAL CONVERSION METHODS */ word bits(word, int, int); //returns subarray of word as word bit bitt(word, int); //returns single bit in word as bit word stow(char *); //returns binary string as word char *wtos(word); //returns word as binary string word sigx(word, bit); //returns sign-extended word at given bit on

/* EXTRACT BITS


  • Given a word and a starting and ending bit, extracts the bits from start to
  • end inclusive and converts them to a word (least-significant bit aligned)
  • and returns that word. */

/* EXTRACT BIT


  • Given a word and bit position, extracts the boolean value from that bit and
  • returns it as a bit. */

/* CONVERT STRING TO WORD


  • Given a binary string (with any number of other characters), extracts the 1s
  • and 0s in sequential order and converts them to a word (least-significant bit
  • aligned) which is returned. */

/* CONVERT WORD TO STRING


  • Given a word, converts it into a binary string representation of 1s and 0s. */

/* SIGN EXTENSION


  • Given a word and a final bit position, extends the value of the final bit
  • towards the most-significant bit, filling in all bits with that value and
  • returning the resulting word. */

/* *****************************************************************************

  • systembus (bus)

  • The bus acts as the system bus in the LC2200 (see LC2200 for control usage).
  • The bus can be read from and written to by all components, and is used in
  • this manner to simulate the transportation of information in 32 wires (one
  • word, as defined in bit's header file) when triggered by the control unit.
  • Almost every microstage involves the driving of a word onto the bus and the
  • reading and/or storage of that word elsewhere. */

/* GLOBAL DECLARATION OF BUS


  • The bus acts as the system bus in the LC2200, responsible for carrying almost
  • all of its data. It is an external variable as declared by the
  • instructionsetarchitecture (bit)'s header file. With this usage, it is
  • immediate accessible to all components of the LC2200. It can be read from or
  • written to by any part of the system when signaled by the control unit (the
  • LC2200). See bit (.h) for more info.
  • The bus/control-unit/component communicaiton is only broken for two reasons.
  • The LC2200 control unit can interact with the instructionregister (ir) and
  • the arithmeticlogicunit (alu) directly for purposes of determining the next
  • microstate to advance to using bits 28-31 of the finitestatemachine (fsm)'s
  • current state. */

/* *****************************************************************************

  • finitestatemachine (fsm)

  • The finite state machine, containing an array of all possible microstates the
  • computer can be in. Apart from containing the ROM of microstates, relies on
  • external control by the LC2200 to progress to the next finite state. Used for
  • state transition by flipping the appropriate load, drive, and write switches
  • and updating the state to be next executed. The fsm is organized with the
  • first 10 bits representing the current state's opcode, z-value, and state--
  • these are used for finding the next appropriate state later. The next 13 bits
  • tell the control unit what drive, load, and write signals should be on or
  • off. The next 5 bits tell the control unit what function the alu should
  • execute and which of the three registers the ir should drive.
  • Layout of FSM by line:
  • sig opcode z-value state drive load write alufunc irreg nextstate
  • com - - - PARMO PABMIZ MR - - -
  • idx 0123 4 56789 01234 567890 12 345 67 8901
  • bin 0000 0 00000 00000 000000 00 000 00 0000
  • For bit flipping and signaling, when updating, the fsm will provide bit
  • switches to explain how each current state should determine the next
  • sequential state by using the last four bits in the microstate line. It is
  • expected that the control unit take care of the following conditions: if the
  • current state is ifetch3, the bit sequence 1000 will search only opcodes
  • using the opcode in the ir; if the current state is beq3, the control unit
  • reads primes the z-value by triggering the alu. The default starting state
  • upon boot-up is at ifetch1. */

/* finitestatemachine (fsm) struct


  • Contains a word state, which is where in the ROM the current microstate is,
  • and the ROM itself, which provides for the control unit information on what
  • signals to send out for every microstate. */

typedef struct { word state; word ROM[ROM_SIZE]; } finitestatemachine;

/* POINTER */ typedef finitestatemachine *fsm_;

/* CONSTRUCTOR/DESTRUCTOR */ fsm_ fsm_ctor(); void fsm_kill(fsm_);

/* MICROSTATE BIT DETAIL *

  •  	 MICROSTATE ROM LAYOUT
    
  •       op   z st    dr    ld     wr fn  rg +
    
  •       code - ##### PARMO PABMIZ MR ### ## OZ+S
    
  •  	 0123 4 56789 01234 567890 12 345 67 8901
    
  • op 0123 the opcode address of the command
  • z 4 the z address of the command
  • st 56789 the state address of the command
  • dr 01234 drive bits in order: PC,ALU,REG,MEM,OFF
  • ld 567890 load bits in order: PC,ALU-A,ALU-B,MAR,IR,Z
  • wr 12 write bits in order: MEM,REG
  • fn 345 function bits to ALU
  • rg 67 register bits to IR
    • 8901 how to go to the next step:
  •  			O 27: use opcode in address
    
  •  			Z 28: use z-val in address 
    
  •  			+ 29: increment and use state in address
    
  •  			S 30: whether to invoke callee-save
    

*/

/* KILL


  • Frees and nullifies the fsm. */

/* *****************************************************************************

  • programcounter (pc)

  • Holds the value of the next instruction to be processed--if its drive or load
  • signal is enable, can push or replace this value. Used by the LC2200 as a
  • marker indicated where in the code it currently is and where to go next. */

/* programcounter (pc) struct


  • Contains the drive and load bits as well as a register for holding the
  • current program counter. */ typedef struct { bit DrPC; bit LdPC; word pc; } programcounter;

/* POINTER */ typedef programcounter *pc_;

/* CONSTRUCTOR/DESTRUCTOR */ pc_ pc_ctor(); void pc_kill(pc_);

/* BUS METHODS */ void pc_Dr(pc_); void pc_Ld(pc_);

/* KILL


  • Frees and nullifies the pc. */

/* DRIVE


  • If the drive signal is enabled, pushes the current pc onto the bus. */

/* LOAD


  • If the load signal is enabled, replaces the current pc with the bus value. */

/* *****************************************************************************

  • arithmeticlogicunit (alu)

  • Responsible for performing all of the mathematical operations in the entire
  • computer. The alu contains two dedicated special purpose signed word
  • registers for use in these calculations and a three-bit function multiplexor
  • for determining which calculation to do. */

/* arithmeticlogicunit (alu) struct


  • Contains the drive and both load bits (one for register A and B) as well as
  • two special signed registers for holding the operands, A and B, and a bit
  • switch array for determining what mathematical operator to use on A and B.
  • current program counter. */ typedef struct { bit DrALU; bit LdA; bit LdB; aluw A; aluw B; bit func[NUM_FUNC]; } arithmeticlogicunit;

/* POINTER */ typedef arithmeticlogicunit *alu_;

/* CONSTRUCTOR/DESTRUCTOR */ alu_ alu_ctor(); void alu_kill(alu_);

/* BUS METHODS */ void alu_Dr(alu_); void alu_LdA(alu_); void alu_LdB(alu_);

/* SPECIAL METHODS */ //note: last four functions unimplemented in fsm void alu_addb(alu_); //000 a + b void alu_nand(alu_); //001 a nand b void alu_asub(alu_); //010 a - b void alu_ainc(alu_); //011 a + 1 void alu_aorb(alu_); //100 a or b void alu_andb(alu_); //101 a and b void alu_axrb(alu_); //110 a xor b void alu_nota(alu_); //111 not a

/* KILL


  • Frees and nullifies the alu. */

/* DRIVE


  • If the drive signal is enabled, performs the operation indicated by regno
  • and pushes the result to the bus. */

/* LOAD A


  • If the load A signal is enabled, updates the A register with the bus value. */

/* LOAD B


  • If the load B signal is enabled, updates the B register with the bus value. */

/* *****************************************************************************

  • registerfile (reg)

  • The heart of the LC2200 is the registerfile, a group of 16 registers that
  • are the only components the cpu can interact with. Each of the registers has
  • a specific index, name, and write and read controls. The parallel arrays
  • of reserved bits and callee-save bits indicate which registers are
  • write-protected and save-protected respectively. The index of the current
  • register activated is determined by a regno multiplexor. */

/* SYSTEM WIDE DECLARATION OF REGISTER NAMES */ const char *REG_NAMES[] = { 0 1 2 3 4 5 6 7 "$zero","$at", "$v0", "$a0", "$a1", "$a2", "$t0", "$t1",

8 9 10 11 12 13 14 15 "$t2", "$s0", "$s1", "$s2", "$k0", "$sp", "$fp", "$ra" };

  • registerfile (reg) struct

  • Contains the drive and write bits as well as a register for holding the
  • the currently selected register, two parallel arrays of bit switches for
  • determining writability and callee-save status, which are parallel to the
  • registers themselves, REG. */ typedef struct { bit DrREG; bit WrREG; word regno; bit reserved[REG_NUM]; bit calleesave[REG_NUM]; word REG[REG_NUM]; } registerfile;

/* POINTER */ typedef registerfile *reg_;

/* CONSTRUCTOR/DESTRUCTOR */ reg_ reg_ctor(); void reg_kill(reg_);

/* BUS METHODS */ void reg_Dr(reg_); void reg_Wr(reg_);

/* SPECIAL METHODS */ //note: both methods unimplemented void reg_writeReserved(reg_); word save(reg_);

/* KILL


  • Frees and nullifies the reg. */

/* DRIVE


  • If the drive signal is enabled, the bus is updated to contain the register
  • value indicated by regno. */

/* WRITE


  • If the write signal is enabled and the respective reserved array indicates
  • the register at regno is write-enabled, updates that regsiter with the bus. */

/* *****************************************************************************

  • randomaccessmemory (mem)

  • The memory is the largest component of the LC2200, acting as the storage
  • behind the entire system. Although the book's LC2200 contained 2^32 memory
  • addresses, this would constitute > 17gb worth of data--far too large for
  • a regular computer to run efficiently. Thus, the actual size of memory is
  • determined in the mem header file and runs from a minimum of 2^20 memory
  • addresses (a little over a million), which shouldn't take up more than a
  • little over 4mb of actual ram size, to a reliable maximum of 2^28 memory
  • addresses (about 256 million), which would take up over 1gb of ram size.
  • The mem has drive, load, and write components. All three utilized the value
  • stored in the memory address register (MAR) to choose which memory cell to
  • interact with the bus. */

/* randomaccessmemory (mem) struct


  • Contains the drive, load, and write bits, the memory address register (MAR)
  • which is used for address lookup, and the memory itself (MEM), which is the
  • actual memory contents. */ typedef struct { bit DrMEM; bit LdMAR; bit WrMEM; word MAR; word MEM[]; //unspecified array length so compiler uses heap and not stack } randomaccessmemory;

/* POINTER */ typedef randomaccessmemory *mem_;

/* CONSTRUCTOR/DESTRUCTOR */ mem_ mem_ctor(); void mem_kill(mem_);

/* BUS METHODS */ void mem_Dr(mem_); void mem_Ld(mem_); void mem_Wr(mem_);

/* KILL


  • Frees and nullifies the mem. */

/* DRIVE


  • If the drive signal is enabled, pushes MEM[MAR] onto the bus. */

/* LOAD


  • If the load signal is enabled, sets MAR to bus contents. */

/* WRITE


  • If the write signal is enabled, writes to MEM[MAR] from the bus. */

/* *****************************************************************************

  • instructionregister (ir)

  • Contains the register for holding the current instruction and drive and load
  • bits. The LC2200 uses the ir for determining what opcode to set the fsm to,
  • pulling the registers need for calculations, and for sign-extended the */

/* instructionregister (ir) struct


  • Contains the drive and load bits as well as a register for holding the
  • current instruction. */ typedef struct { bit DrOFF; bit LdIR; word instruction; } instructionregister;

/* POINTER */ typedef instructionregister *ir_;

/* CONSTRUCTOR/DESTRUCTOR */ ir_ ir_ctor(); void ir_kill(ir_);

/* BUS METHODS */ void ir_Dr(ir_); void ir_Ld(ir_);

/* SPECIAL METHODS */ word ir_opc(ir_); word ir_reg(ir_, word);

/* KILL


  • Frees and nullifies the ir. */

/* DRIVE


  • If the drive signal is enabled, sign-extends the last 20 bits of the
  • instruction and pushes them onto the bus. */

/* LOAD


  • If the load signal is enabled, updates the register with bus value. */

/* OPCODE RETRIEVE


  • Returns as a word the opcode (first 4 bits) of the current instruction. */

/* REGISTER RETRIEVE


  • Given the positional register desired, returns as a word that register's
  • number. Each possible register storage space in the instruction is four bits
  • long, or 2^4, the exact amount of registers there are in the registerfile
  • (reg). Setup as follows:
  • reg OPCODE REGX/1 REGY/2 IMMEDIATE/UNUSED REGZ/3/IMMEDIATE/UNUSED
  • bit 0123 4567 8901 2345678901234567 8901 */

About

LC2200 simulator


Languages

Language:C 94.7%Language:Assembly 5.0%Language:Batchfile 0.2%