The LC-2200 Instruction-Set Architecture

The LC-2200 (Little Computer 2200). The LC-2200 is very simple, but it is general enough to solve complex problems. For this homework, you will need to know the instruction set and instruction format of the LC-2200.

The LC-2200 is a 16-register, 32-bit computer. All addresses are word-addresses. By assembly-language convention, register 0 will always contain 0 (i.e. the machine will not enforce this, but no assembly-language program should ever change register 0 from its initial value of 0).

Assembly-Language Conventions

Instructions

There are 4 instruction formats (bit 0 is the least-significant bit).

    R-type instructions (add, nand):
        bits 19-16: opcode
        bits 15-12: reg A
        bits 11-8:  reg B
        bits 7-4:   unused (should all be 0)
        bits 3-0:   reg D

    I-type instructions (lw, sw, beq):
        bits 19-16: opcode
        bits 15-12: reg A
        bits 11-8:  reg B
        bits 7-0:   offsetField (an 8-bit, 2's complement number with
                                 a range of -128 to 127)

    J-type instructions (jalr):
        bits 19-16: opcode
        bits 15-12: reg A
        bits 11-8:  reg B
        bits 7-0:   unused (should all be 0)

    O-type instructions (halt, noop):
        bits 19-16: opcode
        bits 15-0:  unused (should all be 0)

    S-type instructions (inc, dec, addm, addi)
	bits 19-16: opcode
	bits 13-0 : determined by opcode (see below)
Symbolic instructions should follow the same layout.
For example, the add instructions is written in assembly as: add <regA> <regB> <regD>
    ------------------------------------------------------------------
    Table 1: Description of Machine Instructions
    ------------------------------------------------------------------
    Assembly language       Opcode in binary           Action
    name for instruction    (bits 19, 18, 17, 16)
    ------------------------------------------------------------------
    add (R-type format)     0000                  add contents of regA 
                                                  with contents of regB,
                                                  store results in regD.


    nand (R-type format)    0001                  nand contents of regA 
                                                  with contents of regB,
                                                  store results in regD.


    lw (I-type format)      0010                  load regB from memory. 
                                                  Memory address is formed
                                                  by adding offsetField 
                                                  with the contents of
                                                  regA.


    sw (I-type format)      0011                  store regB into memory. 
                                                  Memory address is formed
                                                  by adding offsetField 
                                                  with the contents of
                                                  regA.


    beq (I-type format)     0100                  compare the contents of 
                                                  regA and regB;  if they
                                                  are the same, then 
                                                  branch to the address
                                                  PC+1+offsetField, where
                                                  PC is the address of the 
                                                  beq instruction.

    
    jalr (J-type format)    0101                  First store PC+1 into
                                                  regB, where PC is the 
                                                  address of the jalr
                                                  instruction.  Then 
                                                  branch to the address
                                                  now contained in regA. 
                                                  Note that if regA is the
                                                  same as regB, the 
                                                  processor will first
                                                  store PC+1 into that 
                                                  register, then end up
                                                  branching to PC+1.


    halt (O-type format)    0110                  halt the machine (do 
                                                  nothing and let the
                                                  simulator notice that 
                                                  the machine halted).

    
    noop (O-type format)    0111                  do nothing.


    inc (S-type format)     1000                  Add 1 to regA and
                                                  store the result in
                                                  regD. Format:
                                                  
                                                  bits 19-16: opcode
                                                  bits 15-12: regA
                                                  bits 11-4 : unused
                                                  bits 3-0  : regD


    dec (S-type format)     1001                  Subtract 1 from regA 
                                                  and store the result
                                                  in regD. Format:

                                                  bits 19-16: opcode
                                                  bits 15-12: regA
                                                  bits 11-4 : unused
                                                  bits 3-0  : regD


    addi (S-type format)    1010                  Add contents of regA
                                                  to immediate and
                                                  store the result in
                                                  regB. Format:

                                                  bits 19-16: opcode
                                                  bits 15-12: regA
                                                  bits 11-8 : regB
                                                  bits 7-0  : immediate


    addm (S-type format)    1011                  Add contents of regB
                                                  with contents of the
                                                  memory address
                                                  formed by adding
                                                  regA to offsetField.
                                                  store the result in
                                                  regB. Format:

                                                  bits 19-16: opcode
                                                  bits 15-12: regA
                                                  bits 11-8 : regB
                                                  bits 7-0  : offsetField
   -----------------------------------------------------------------------
There are two extra symbolic constructs which you may use

.fill <value> places value in the current address

Example:
      (address 0):  .fill 5 
      (address 1):  .fill -2 
becomes
      (address 0): 0x00000005 
      (address 1): 0xfffffffe 
<label> <instruction> allows you to refers to the address of <instruction> as <label>.
If a label is used in a beq instruction, it will evaluate to the the relative offset.

Example 1:
      
      (address 0):       .fill start 
      (address 1): start add   0 0 0 
      (address 2): end   add   0 0 0 
      (address 3):       beq   0 0 end
         becomes 
      (address 0): 0x00000001 
      (address 1): 0x00000000 
      (address 2): 0x00000000 
      (address 3): 0x000400fe


Example 2:
LC-2200 Instructions:

      (address 100):        lw    0   1   one       # r1 = 1
      (address 101):        lw    0   7   ten       # r7 = 10
      (address 102):        add   1   0   6         # r6 = 1
      (address 103):  loop  beq   1   7   end       # loop while r1 != r7
      (address 104):        add   2   1   2         # r2 += r1
      (address 105):        add   1   6   1         # r1++
      (address 106):        beq   0   0   loop      # goto loop
      (address 107):  end   add   2   0   15        # return r2
      (address 108):        jalr  14  1             # jump to the callee
      ...
      (address 125)   one   .fill 1
      (address 126)   ten   .fill 10


Instruction Format:

     (address 100):   2  0  0  125  [offset]
     (address 101):   2  0  7  126  [offset]
     (address 102):   0  1  0  6    [reg]
     (address 103):   4  1  7  3    [offset]
     (address 104):   0  2  1  2    [reg]
     (address 105):   0  1  6  1    [reg]
     (address 106):   4  0  0  -4   [offset]
     (address 107):   0  2  0  15   [reg]
     (address 108):   5  14 1  0    [---]
     ...
     (address 125):   0  0  0  1    [offset]
     (address 126):   0  0  0  10   [offset]

Binary and Hex:

     (address 100)    0010 0000 0000 0111 1101 = 0x0002007d
     (address 101)    0010 0000 0111 0111 1110 = 0x0002077e
     (address 102)    0000 0001 0000 0000 0110 = 0x00001006
     (address 103)    0100 0001 0111 0000 0011 = 0x00041703
     (address 104)    0000 0010 0001 0000 0010 = 0x00002102
     (address 105)    0000 0001 0110 0000 0001 = 0x00001601
     (address 106)    0100 0000 0000 1111 1100 = 0x000400fc
     (address 107)    0000 0010 0000 0000 1111 = 0x0000200f
     (address 108)    0101 1110 0001 0000 0000 = 0x0005e100
     ...
     (address 125)    0000 0000 0000 0000 0001 = 0x00000001
     (address 126)    0000 0000 0000 0000 1010 = 0x0000000a

LC-2002 Machine Code

Translating the LC-2002 symbolic instructions into machine code is fairly straightfoward:

             lw      0   1   five    load reg1 with 5 (uses symbolic address)
             lw      1   2   3       load reg2 with -1 (uses numeric address)
     start   add     1   2   1       decrement reg1
             beq     0   1   2       goto end of program when reg1==0
             beq     0   0   start   go back to the beginning of the loop
             noop
     done    halt                    end of program
     five    .fill   5
     neg1    .fill   -1
     stAddr  .fill   start           will contain the address of start (2)
     1) Replace the symbolic labels with their numerical values

             2      0   1   7      load reg1 with 5 (uses symbolic address)
             2      1   2   3      load reg2 with -1 (uses numeric address)
             0      1   2   1      decrement reg1
             4      0   1   2      goto end of program when reg1==0
             4      0   0   -3     go back to the beginning of the loop
             7      0   0   0 
             6      0   0   0      end of program
                            5
                            -1
                            2
     2)  Translate into hexadecimal 
             
     (address 0):  0x00020107
     (address 1):  0x00021203
     (address 2):  0x00001201
     (address 3):  0x00040102
     (address 4):  0x000400fd
     (address 5):  0x00070000
     (address 6):  0x00060000
     (address 7):  0x00000005
     (address 8):  0xffffffff
     (address 9):  0x00000002

LC-2002 Datapath Signals (not used in Homework 1)

    
  PCWr:           If enabled, causes PCWE to be enabled (due to the
                  OR gate).
                 

  PCWrC:          If the bit in the condReg is zero AND this is
                  enabled, the PCWE is enabled.
                   

  PCdriveData:    If enabled, drives the current value of the PC to
                  the databus.
                 

  PCdriveAddr:    If enabled, drives the current value of the PC to
                  the address bus.
                  

  IRWE:           "Instruction Register Write-Enable".  If enabled,
                  the value driven to the data bus from some
                  resource in this cycle is "latched" into the IR by
                  the end of the current cycle.
                      

  IRdrive:        If enabled, drives the current value of the IR to
                  the databus (through the AND gate, thus driving
                  only the value of the 8 bit offset field).
                  

  ALURWE:         "ALU Result Write-Enable".  If enabled, the value
                  calculated by the ALU during this cycle is "latched"
                  into the ALU result register by the end of the
                  current cycle.
                  
  ALURdriveData:  If enabled, drives the current value of the ALU
                  result register to the databus.
                  

  ALURdriveAddr:  If enabled, drives the current value of the ALU
                  result register to the address bus.
                  

  CRWE:           "Condition Register Write-Enable".  If enabled,
                  the value calculated by the ALU during this cycle
                  and "piped" through the 32-bit OR gate to become
                  a single bit is "latched" into the CR by the end
                  of the current cycle.


  MemWr:          If enabled (a write to RAM is desired), the
                  value driven to the address bus from some
                  resource in this cycle is "latched" into the
                  memory_addr_buffer and the value driven to the
                  databus from some resource in this cycle is
                  "latched" into the memory_data_buffer by the
                  end of the current cycle.  (This causes the
                  actual write to occur during the NEXT cycle,
                  during which NO memory device control signals
                  may be enabled).
                 

  MemRd:          If enabled (a read from RAM is desired), the
                  value driven to the address bus from some
                  resource in this cycle is "latched" into the
                  memory_addr_buffer by the end of the current
                  cycle, causing the memory device to start
                  the read operation (note that the RAM device
                  is slow, and the actual datum requested is
                  available on the NEXT cycle for driving to the
                  data bus (see below).

  MemDriveData:   If enabled, causes the memory datum at the
                  address indicated by memory_addr_buffer to
                  be driven onto the databus.  Be careful not
                  to violate the memory latency limitation.


  MemDriveAddr:   If enabled, causes the memory datum at the
                  address indicated by memory_addr_buffer to
                  be driven onto the addrbus.  Be careful not
                  to violate the memory latency limitation.

  RegRdPE1:       "Register File Enable Read From Port 1".  If
                  enabled, causes the register indexed by RdPA1
                  ("Read Port Address 1") to drive its value to
                  the "Read Data 1" port (to the databus).


  RegRdPE2:       "Register File Enable Read From Port 2".  If
                  enabled, causes the register indexed by RdPA2
                  ("Read Port Address 2") to drive its value to
                  the "Read Data 2" port (to the address bus).


  RegWE:          "Register File Write-Enable".  If enabled,
                  the value driven to the data bus from some
                  resource in this cycle is "latched" into the
                  register indexed by WrPA ("Write Port Address")
                  by the end of the current cycle.
                  

  ALUop:          "ALU operation".  Specifies which arithmetic
                  operation will be performed by the ALU during
                  this cycle (can be: ALUnoOp, ALUaddOp, ALUsubOP,
                  or ALUnandOp).
                   

  ALUMUXC:        "ALU MUX control".  Determines the left-hand
                  operand of the ALU for the ALU operation performed
                  during this cycle (can be: ALUMUXCone, ALUMUXCbus,
                  or ALUMUXCsignExtend).  If it is ALUMUXCsignExtend,
                  the left-hand operand should be determined by
                  sign-extending the value driven to the data bus
                  from some resource in this cycle.  If it is
                  ALUMUXCbus, simply use the full 32 bit value directly
                  off the databus.  If it is ALUMUXCone, use the
                  value 1 as the left-hand operand.


  RdMUXC:         "Register File Read Port Address 1 MUX control".
                  Determines which "field" of the instruction register
                  to use as the index RdPA1 (can be: RdMUXCregA or
                  RdMUXCregB).
                 

  WrMUXC:         "Register File Write Port Address MUX control".
                  Determines which "field" of the instruction register
                  to use as the index WrPA (can be: WrMUXCregB or
                  WrMUXCregD).