// This is a SyReC-file describing the control unit of a RISC CPU as specified in [WSG+:2011].
// This file has been taken from RevLib (www.revlib.org). 

module control_unit( in instr(16), in reset(1), in cZero(1), in cCarry(1),
                     out write(1), out dest(3), out aluEnable(1), out oprt(4), out oprd1(16), out oprd2(16), out memWrite(1), out memDest(16), out enable(1), out jump(11), 
                     inout r[8](16), inout memData(16) )

  wire tmp(16)

  ~= enable;
  if !instr.1 then
    ~= write;
    dest ^= instr.5:7;
    ~= aluEnable;
    oprd1 ^= r[instr.10:12];
    if ( instr.0:2 = 1 ) then
      oprd2.0:2 ^= instr.15:13;
      oprd2.3 ^= instr.9
    else
      oprd2 ^= r[instr.13:15]
    fi ( instr.0:2 = 1 );
    oprt.0:2 ^= instr.4:2;
    oprt.3 ^= instr.0
  else
    if ( instr.0:4 = 2 ) then
      ~= write;
      dest ^= instr.5:7;
      oprd1.0:7 ^= instr.15:8;
      tmp ^= r[instr.5:7];
      oprd1.8:15 ^= tmp.8:15
    else
      skip
    fi ( instr.0:4 = 2 );
    if ( instr.0:4 = 18 ) then
      ~= write;
      dest ^= instr.5:7;
      tmp ^= r[instr.5:7];
      oprd1.0:7 ^= tmp.0:7;       
      oprd1.8:15 ^= instr.15:8
    else
      skip
    fi ( instr.0:4 = 18 );
    if ( instr.0:4 = 26) then
      ~= write;
      dest ^= instr.5:7;
      oprd1 ^= memData
    else
      skip
    fi ( instr.0:4 = 26 );
    if ( instr.0:4 = 10 ) then
      ~= memWrite;
      memWrite ^= reset;
      memDest ^= r[instr.10:12];
      memData ^= r[instr.13:15]
    else
      skip
    fi ( instr.0:4 = 10 );
    if ( ( ( ( instr.0:4 = 6 ) && !cZero ) ||
           ( ( instr.0:4 = 22 ) && !cCarry ) 
         ) || ( 
           ( ( instr.0:4 = 15 ) || ( ( instr.0:4 = 23 ) && cCarry ) ) ||
           ( ( instr.0:4 = 7 ) && cZero ) )
       ) then
      ~= enable;
      jump.0:10 ^= instr.15:5
    else
      skip
    fi ( ( ( ( instr.0:4 = 6 ) && !cZero ) || ( ( instr.0:4 = 22 ) && !cCarry ) ) || ( ( ( instr.0:4 = 15 ) || ( ( instr.0:4 = 23 ) && cCarry ) ) || ( ( instr.0:4 = 7 ) && cZero ) ) ) 
  fi !instr.1
       
