My Microprocessor



      Design Specifications:

      1) RISC Architecture.

      2) Fixed length instruction code.

      3) 16 bit instruction size.

      4) 16 bit data word size

      5) 16 bit internal architecture

      6) Data Bus size = 16 bit

      7) Instruction address bus size = Data address bus size=16 bit

      8) lO address bus size = 4 bit



      Instruction Format:

      A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15

      Registers:

      Ds: Data Segment Register : 4 Bit.
      CS: Instruction Segment Register : 4 Bit.
      IOR: IO Address Register : 4 Bit.
      13 General Purpose Registers: 16 Bit.



      Memory Addressing:

      Addressing Modes:


      The address is divided into two parts:

      Segment: where the address is strored in the data segment register DS, Instruction segment register CS).
      Size: 4 Bit.
      Offset : where the address is supplied to store the store and load instructions.
      Size : 12 Bit.


      Memory instructions:


      Instructions:

      1)Memory transfer class:
      While the Flag Data/mem = 0 the memory operations are done on the data memory, otherwise it is done on the Instruction memory.

    A0 A1 A2 A3 A4 à A15
    0 Load/Store  Reg. Address Mem. Offset Address
      A0 = 1
      A1 = 1 à load data from the register to the memory.
      A2 A3 àAddress of source or destination register.
    A2 A3
    Register
    0 0
    A
    0 1 
    B
    1 0 
    C
    1 1
    D
      A4 à A15 àData Offset Address.

      Data segment can be set by using the following instructions:

      The code segment can be set with the same way

      If the next instruction needs new data from memory while this data is not available, the compiler can use Nop instruction to delay the execution.

      2) Logical & arithmetic instructions:

      These instuctions do not have memory operands.

      A0 = 0
      A1 =0
      A2 A3 Not used
      A4 A5 A6 A7 è Opcode
      A8 A9 A10 A11 è source register
      A12 A13 A14 A15 è destination register

    A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15
    0 0 Not Used Opcode Source register Destination reg.
    A4 A5 A6 A7 Symbolic opcode Description
    0 0 0 0 ADD ADD
    0 0 0 1 ADDC ADD with Carry
    0 0 1 0 SUB SUBtract
    0 0 1 1 SUBB SUBtract with Borrow
    0 1 0 0 MUL MULtiply
    0 1 0 1 DIV DIVide
    0 1 1 0 XOR XOR
    0 1 1 1 OR OR
    1 0 0 0 AND AND
    1 0 0 1 SHL SHift Left
    1 0 1 0 SHR SHift Right
    1 0 1 1 ROL ROtate Left
    1 1 0 0 ROR ROtate Right
    1 1 0 1 NOT NOT
    1 1 1 0 MOV MOVe
    1 1 1 1 NOP No Operation
      When Xor CS,CS is executed the Data/mem flag is complemented.

      3) IO instructions:
      I have only 16 port with 16 bit word for each one.

    A0 A1 A2 A3 A4 A5 A6 A7 A8 -- A11 A12 -- A15
    0 1 1  Address Mode In/Out not used Port Address Word Address
      Port Address is stored in IO Address reg. IOR.

      A0 = 0
      A1 A2 =2
      A3 = 0 à immediate address stored in the source bits.
      A3 = 1 à address is stored in IOR.
      A4 = 0 à get word from port & store it in data field.
      A4 = 1 à send word to port from data field.
      A5 A6 A7 not used.
      A8 A9 A10 A11 à Immediate Address of the port
      ( This type of addressing violates the RISC Machine concept)

      A12 A13 A14 A15 à The address of the register that contains the word.

      Examples:

      IN A è get a word from port addressed by IOR, and store it in reg. A.

      IN 10,A è get a word from port 10 and store it in reg. A

      Out A è send the stored word in reg. A to the port addressed by IOR.

      Out 10,A è send the stored word in reg. A to port 10.

      4)Branch instructions:

      A0 = 0
      A1 A2 = 1 0
      A3 A4 A5 A6 à Opcode.
      A7 à Far or Near branch ( change the contents of CS or not).
      A8 A9 àAddress of the register that contains the branch address.
      A10 – A15 ànot used.
       

    A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 –A15
    0 1 0  Opcode Far/Near Branch Reg. Address Not used


      Fetch Unit:
      This Unit fetches either the instruction from the Instruction memory Unit, data from the data memory Unit or Data from IO port.

      Unsolved Problems:

        1. Data transfer to Instruction memory.
        2. Decoding Branch Instructions.
        3. Decoding IO Instructions.
        4. Execute ALU Instructions.
        5. Data Bus sharing conflux between Memory Instructions and IO instructions.
        6. Error during transferring data to the data memory.
        7. Problem with incrementing the program counter due to unsolved problem with the VHDL langauge.




     
      The VHDL program:

      ---------------------------------------------------------------------------------------------------------------------------

      Entity UProcessor is

      Port ( clk :In Bit;

      --InstructionBus :Inout Bit_Vector( 0 to 15 ) ;

      DataBus :Inout Bit_Vector( 0 to 15 ) ;

      InstructionAddressBus :out Bit_Vector( 0 to 15 ) ;

      DataAddressBus :out Bit_Vector( 0 to 15 ) ;

      IOAddressBus :out Bit_Vector( 0 to 3 ) ;

      WriteMem :out Bit

      );

      end UProcessor;

      --------------------------------------------------------------------------- Architecture UProcessorBehavior of UProcessor IS

      --logical & arithmetic opcodes

      constant OP_ADD : bit_vector(0 to 3) := "0000";constant OP_ADDC: bit_vector(0 to 3) := "0001";

      constant OP_SUB : bit_vector(0 to 3) := "0010";constant OP_SUBB: bit_vector(0 to 3) := "0011";

      constant OP_MUL : bit_vector(0 to 3) := "0100";constant OP_DIV : bit_vector(0 to 3) := "0101";

      constant OP_XOR : bit_vector(0 to 3) := "0110";constant OP_OR : bit_vector(0 to 3) := "0111";

      constant OP_AND : bit_vector(0 to 3) := "1000";constant OP_SHL : bit_vector(0 to 3) := "1001";

      constant OP_SHR : bit_vector(0 to 3) := "1010";constant OP_ROL : bit_vector(0 to 3) := "1011";

      constant OP_ROR : bit_vector(0 to 3) := "1100";constant OP_NOT : bit_vector(0 to 3) := "1101";

      constant OP_MOV : bit_vector(0 to 3) := "1110";constant OP_NOP : bit_vector(0 to 3) := "1111";

      --Registers

      Signal A : Bit_vector(15 downto 0);Signal B : Bit_vector(15 downto 0);

      Signal C : Bit_vector(15 downto 0);Signal D : Bit_vector(15 downto 0);

      Signal E : Bit_vector(15 downto 0);Signal F : Bit_vector(15 downto 0);

      Signal G : Bit_vector(15 downto 0);Signal H : Bit_vector(15 downto 0);

      Signal I : Bit_vector(15 downto 0);Signal J : Bit_vector(15 downto 0);

      Signal K : Bit_vector(15 downto 0);Signal L : Bit_vector(15 downto 0);

      Signal M : Bit_vector(15 downto 0);Signal IOR : Bit_vector(3 downto 0);

      Signal DS : Bit_vector(3 downto 0);Signal CS: Bit_vector(3 downto 0);
       
       

      Signal PreIR : Bit_Vector(0 to 15) ;

      Signal PC : Bit_Vector(0 to 11) ;

      --This Register where the fitched data is stored

      Signal DataReg : Bit_Vector(0 to 15);

      --This flag determines which memroy to access ( data or Instruction)

      --1 Memory Operation

      --0 ALU Operation

      Signal OpsType : Bit;

      --1 Load from memory to register

      --0 Store from register to memory

      Signal MemOpCode : Bit;

      --Address of the destination or source register

      Signal MemOperand : Bit_vector(0 to 1);

      --ALU Opcode

      Signal ALUOpcode :Bit_vector(0 to 3);

      Signal ReadWriteMem :Bit;

      Begin

      --------------------------------------------------------------------------- Fetch : Process

      --variable PC : Integer;

      Begin

      wait until clk = '1';

      -- if the last decoded instruction was an ALU instruction

      if( OpsType ='0' ) then -- I can not check it now because the memory instruction is no executing now

      PreIR <= DataBus;

      --Program counter must be incremented here.!!!?

      --ProgramCounter := PC + 1;

      --InstructionAddressbus(3 to 13)<= ProgramCounter ;

      --InstructionAddressbus(0 to 2)<= InstructionSegment ;

      elsif ( ReadWriteMem ='1' ) then

      DataReg <= DataBus;

      end if;

      End process Fetch;

      ----------------------------------------------------------------------------------------------

      Decode: Process Begin

      wait until clk = '1';

      if PreIR(0) = '1' then

      --I have a memory transfer Instruction

      -- Can I load it here or before executing the instrution

      --Load the Data Address bus with the address

      DataAddressBus(4 to 15 ) <= PreIR(4 to 15);

      DataAddressBus(0 to 3 ) <= DS;

      OpsType <= '1'; --memory transfer Operation

      --Can I set the here?

      MemOpCode <= PreIR(1);

      MemOperand <= PreIR(2 to 3 );

      --Non Memory transfer Instruction

      else

      --Arithmetic and logical Instructions

      case PreIR(1 to 2) is

      when "00" | "01" =>

      opsType <= '0';

      case PreIR(4 to 7 ) is

      when OP_ADD => ALUOpcode <= OP_ADD;

      when OP_ADDC => ALUOpcode <= OP_ADDC;

      when OP_SUB => ALUOpcode <= OP_SUB;

      when OP_SUBB => ALUOpcode <= OP_SUBB;

      when OP_MUL => ALUOpcode <= OP_MUL;

      when OP_DIV => ALUOpcode <= OP_DIV;

      when OP_XOR => ALUOpcode <= OP_XOR;

      when OP_OR => ALUOpcode <= OP_OR;

      when OP_AND => ALUOpcode <= OP_AND;

      when OP_SHL => ALUOpcode <= OP_SHL;

      when OP_SHR => ALUOpcode <= OP_SHR;

      when OP_ROL => ALUOpcode <= OP_ROL;

      when OP_ROR => ALUOpcode <= OP_ROR;

      when OP_NOT => ALUOpcode <= OP_NOT;

      when OP_MOV => ALUOpcode <= OP_MOV;

      when OP_NOP => ALUOpcode <= OP_NOP;

      end case;

      --Jump Instructions

      when "10" => ALUOpcode(0 to 1) <= "10";

      --IO Instructions

      when "11" => ALUOpcode(0 to 1) <= "11";

      end case;

      end if;

      end Process decode;

      -----------------------------------------------------------------------------

      ExecuteALU : Process ( clk, OpsType)

      Begin

      if( (clk ='1') and (OpsType = '0')) then

      A <= B;

      end if;

      End Process ExecuteALU;

      ------------------------------------------------------------------------------

      ExecuteMemory :Process ( clk , OpsType)

      Begin

      if( (clk ='1') and (OpsType = '1')) then

      -- load instruction

      if( MemOpCode = '0') then

      WriteMem <='1';

      ReadWriteMem <= '1';

      case MemOperand is

      when "00" => A <= DataReg;

      when "01" => B <= DataReg;

      when "10" => C <= DataReg;

      when "11" => D <= DataReg;

      end case;

      --Store Instruction

      else

      WriteMem <= '0';

      ReadWriteMem <= '0';

      case MemOperand is

      when "00" => Datareg <= A;

      when "01" => DataReg <= B;

      when "10" => DataReg <= C;

      when "11" => DataReg <= D;

      end case;

      end if;

      end if;

      End Process ExecuteMemory;

      end UprocessorBehavior;