« Previous entry | Next entry » Browse > Images

Skip to comments (15) simple 16bit risc like processor
Posted by Erik on Oct 15 2005 @ 18:06  :: 5126 unique visits

Developer images

This is a simple 16bit processor I developed some time ago.
I also wrote a simple assambler for it.


CPU registers:

   r0        always 0 (even if you write something else to it).
   r1..r12   general registers.
   r13       register reserved for the pre-assembler.
   r14       stack pointer.

CPU flags:

   z   zero
   gt  greater than: a is greater then b
   lt  less than, this is not really a flag, it can be computed with: lt = not (z or gt)

Supported instructions:

   0    add a, b        a = a + b
   1    sub a, b        a = a - b

   2    and a, b (logical)    a = a & b  
   3    or  a, b (logical)    a = a or b  
   4    xor a, b (logical)    a = a xor b
   5    nor a, b (logical)    a = a nor b


   6    mov a, b        a = b
   7    lod a, b        a = memory
   8    sto a, b        memory[a] = b

   9    sll a, b (logical)     a = a << b
   10    srl a, b (logical)    a = a >> b
   11    sla a, b (arithmetic) a = a << b
   12    sra a, b (arithmetic) a = a >> b
   13    rol a, b              a = b times left rotated a
   14    ror a, b              a = b times right rotated a

   15    cmp a, b        z  = (a - b) == 0
                         gt = (a - b) >  0

   16    jmp b     ip = b
   17    jz  b     if (z)         ip = b
   18    jnz b     if (!z)        ip = b
   19    jgt b     if (gt)        ip = b
   20    jlt b     if (!(z & gt)) ip = b

   21    gip a, r0    a = ip

   22    dbg b      send b to the processor debug output.

   23    hlt        stop executing instructions

Instruction encoding:

   15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0

    [    instr     ]  [ opp a  ]  [ opp b  ]  0  0

Opperand types:

   0..14     register
   15        intermidiate

   only opperand b can be an immediate!
   a = 15 will read/write from/to the garbage register


Immediate_Fetch_Unit.Vhd:
CODE: VHDL
library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all; -- for conv_integer and opperations on std_logic_vector
    --use ieee.std_logic_arith.all; -- for conv_std_logic_vector

entity Immediate_Fetch_Unit is
    port( ip   : in  std_logic_vector(15 downto 0);
          need : in  std_logic;

          addr : out std_logic_vector(15 downto 0);
          din  : in  std_logic_vector(15 downto 0);
          oe   : out std_logic;

          imm  : out std_logic_vector(15 downto 0)
    );
end Immediate_Fetch_Unit;

architecture Immediate_Fetch_Unit_Arch of Immediate_Fetch_Unit is

    signal tmp : bit_vector(15 downto 0);

begin
    imm <= din; -- If no immediate is needed (opperand b selector != "1111")
                -- then imm = opp
                -- because opp is still on the memory din bus.

    oe <= need;

    addr <= ip + "1"; -- + 1 because ip currently points to the opp.

end Immediate_Fetch_Unit_Arch;


Instruction_Execution_Unit.Vhd:
CODE: VHDL
library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_signed.all; -- for conv_integer and opperations on std_logic_vector
    --use ieee.std_logic_arith.all; -- for conv_std_logic_vector

entity Instruction_Execution_Unit is
    port( instr : in  std_logic_vector(5  downto 0);

          ip    : in  std_logic_vector(15 downto 0);

          a     : in  std_logic_vector(15 downto 0);
          b     : in  std_logic_vector(15 downto 0);

          d     : out std_logic_vector(15 downto 0);

          dbg   : out std_logic_vector(15 downto 0);

          z     : out std_logic; -- zero flag
          gt    : out std_logic; -- greater than flag

          addr : out std_logic_vector(15 downto 0);
          din  : in  std_logic_vector(15 downto 0);
          dout : out std_logic_vector(15 downto 0);
          oe   : out std_logic;
          we   : out std_logic
    );
end Instruction_Execution_Unit;

architecture Instruction_Execution_Unit_Arch of Instruction_Execution_Unit is

    signal oe_i : std_logic;
    signal d_i  : std_logic_vector(15 downto 0);

begin

    oe <= oe_i;

    -- Multiplexer for selecting the output.
    process(din, d_i, oe_i)
    begin
       if oe_i = '0' then -- output from an opperation.
          d <= d_i;
       else               -- output from memory.
          d <= din;
       end if;
    end process;

    process(instr, a, b, ip)
       variable ta   : integer;
       variable tb   : integer;
       variable sh_i : integer;
       variable sh_b : bit_vector(15 downto 0);
    begin
       if instr = "000111" then            -- 7 lod
          addr <= b;
          we   <= '0';
          oe_i <= '1';
       elsif instr = "001000" then         -- 8 sto
          addr <= a;
          dout <= b;
          we   <= '1';
          oe_i <= '0';
          d_i  <= a; -- a = a
       elsif instr = "001111" then         -- 15 cmp
          we   <= '0';
          oe_i <= '0';
          d_i  <= a; -- a = a

          ta := conv_integer(a);
          tb := conv_integer(b);

          ta := ta - tb;

          if ta = 0 then
             z <= '1';
          else
             z <= '0';
          end if;

          if ta < 0 then
             gt <= '0';
          else
             gt <= '1';
          end if;
       else
          we   <= '0';
          oe_i <= '0';

          if instr = "000000" then         -- 0 add
             d_i <= a + b;
          elsif instr = "000001" then      -- 1 sub
             d_i <= a - b;
          elsif instr = "000010" then      -- 2 and
             d_i <= a and b;
          elsif instr = "000011" then      -- 3 or
             d_i <= a or b;
          elsif instr = "000100" then      -- 4 xor
             d_i <= a xor b;
          elsif instr = "000101" then      -- 5 nor
             d_i <= a nor b;
          elsif instr = "000110" then      -- 6 mov
             d_i <= b;
          elsif instr = "001001" then      -- 9 sll
             sh_i := conv_integer(b);
             sh_b := To_bitvector(a);
             sh_b := sh_b sll sh_i;
             d_i <= To_stdlogicvector(sh_b);
          elsif instr = "001010" then      -- 10 srl
             sh_i := conv_integer(b);
             sh_b := To_bitvector(a);
             sh_b := sh_b srl sh_i;
             d_i <= To_stdlogicvector(sh_b);
          elsif instr = "001011" then      -- 11 sla
             sh_i := conv_integer(b);
             sh_b := To_bitvector(a);
             sh_b := sh_b sla sh_i;
             d_i <= To_stdlogicvector(sh_b);
          elsif instr = "001100" then      -- 12 sra
             sh_i := conv_integer(b);
             sh_b := To_bitvector(a);
             sh_b := sh_b sra sh_i;
             d_i <= To_stdlogicvector(sh_b);
          elsif instr = "001101" then      -- 13 rol
             sh_i := conv_integer(b);
             sh_i := sh_i mod 16;
             sh_b := To_bitvector(a);
             sh_b := sh_b rol sh_i;
             d_i <= To_stdlogicvector(sh_b);
          elsif instr = "001110" then      -- 14 ror
             sh_i := conv_integer(b);
             sh_i := sh_i mod 16;
             sh_b := To_bitvector(a);
             sh_b := sh_b ror sh_i;
             d_i <= To_stdlogicvector(sh_b);
          elsif instr = "010101" then      -- 21 gip
             d_i <= ip;
          elsif instr = "010110" then      -- 22 dbg
             dbg <= b;
             d_i <= a;
          else
             d_i <= a; -- Unknown instruction or instruction is not handled here,
                       -- just move a to a.
          end if;

       end if;
    end process;

end Instruction_Execution_Unit_Arch;


Memory_Control_Unit.Vhd:
CODE: VHDL
library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all; -- for conv_integer and opperations on std_logic_vector
    --use ieee.std_logic_arith.all; -- for conv_std_logic_vector

entity Memory_Control_Unit is
    port( addr  : in  std_logic_vector(15 downto 0);
          din   : out std_logic_vector(15 downto 0);
          dout  : in  std_logic_vector(15 downto 0);
          oe    : in  std_logic;
          we    : in  std_logic;

          rom_addr : out std_logic_vector( 7 downto 0);
          rom_data : in  std_logic_vector(15 downto 0);

          ram_addr : out std_logic_vector( 9 downto 0);
          ram_we   : out std_logic;
          ram_din  : in  std_logic_vector(15 downto 0);
          ram_dout : out std_logic_vector(15 downto 0)
    );
end Memory_Control_Unit;

architecture Memory_Control_Unit_Arch of Memory_Control_Unit is

    signal rf : std_logic; -- 0 = rom, 1 = ram

begin

    process(addr, oe, we, dout)
    begin
       if oe = '1' then
        ram_we   <= '0';

          if addr < "0000000100000000" then -- memory below 256 is mapped to the program rom
             rom_addr <= addr(7 downto 0);
             rf       <= '0';
             -- rom doesn't need a oe signal to enable output.
          else
             ram_addr <= addr(9 downto 0) - "0100000000";
             rf       <= '1';
          end if;
       elsif we = '1' then
          if addr >= "0000000100000000" then -- we can only write to memory
             ram_addr <= addr(9 downto 0) - "0100000000";
             ram_dout <= dout;
             ram_we   <= '1';
          end if;
       end if;
    end process;

    process(oe, rom_data, ram_din, rf)
    begin
       if oe = '1' then
          if rf = '0' then -- rom
             din <= rom_data;
          else -- ram
             din <= ram_din;
          end if;
       end if;
    end process;

end Memory_Control_Unit_Arch;


Registers.Vhd:
CODE: VHDL
library ieee;
    use ieee.std_logic_1164.all;
    --use ieee.std_logic_unsigned.all; -- for conv_integer and opperations on std_logic_vector
    --use ieee.std_logic_arith.all; -- for conv_std_logic_vector

entity Registers is
    port( as  : in std_logic_vector(3  downto 0);
          bs  : in std_logic_vector(3  downto 0);
          ds  : in std_logic_vector(3  downto 0);

          we  : in std_logic;

          addra : out std_logic_vector(3 downto 0);
          addrb : out std_logic_vector(3 downto 0)
    );
end Registers;

architecture Registers_Arch of Registers is

begin

    process(as, ds, we)
    begin
       if we = '1' then
          if ds = "0000" then -- Trying to write to r0
             addra <= "1111"; -- write to the dummy register
          else
             addra <= ds;
          end if;
       else
          addra <= as;
       end if;
    end process;

    process(bs, ds, we)
    begin
       if we = '1' then
          if ds = "0000" then -- Trying to write to r0
             addrb <= "1111"; -- write to the dummy register
          else
             addrb <= ds;
          end if;
       else
          addrb <= bs;
       end if;
    end process;

end Registers_Arch;


ROM.Vhd:
CODE: VHDL
library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all; -- for conv_integer and opperations on std_logic_vector
    --use ieee.std_logic_arith.all; -- for conv_std_logic_vector

entity ROM is
    port( addr : in  std_logic_vector(7  downto 0);
          data : out std_logic_vector(15 downto 0)
    );
end ROM;

architecture ROM_Arch of ROM is

    type opps is array (natural range <>) of std_logic_vector(15 downto 0);

    constant prog : opps := (

--[ins][a ][b ]00
"0000000000000000", -- instructions here

                            );

begin

    process(addr)
       variable i : integer;
    begin
       i    := conv_integer(addr);
       data <= prog(i);
    end process;

end ROM_Arch;


Memory_Mux.Vhd:
CODE: VHDL
library ieee;
    use ieee.std_logic_1164.all;
    --use ieee.std_logic_unsigned.all; -- for conv_integer and opperations on std_logic_vector
    --use ieee.std_logic_arith.all; -- for conv_std_logic_vector

entity Memory_Mux is
    port( stage    : in  std_logic_vector(2 downto 0);
          stage_io : in  std_logic_vector(2 downto 0);

          -- stage 0
          stage_a_addr : in  std_logic_vector(15 downto 0);
          stage_a_din  : out std_logic_vector(15 downto 0);

          -- stage 1
          stage_b_addr : in  std_logic_vector(15 downto 0);
          stage_b_din  : out std_logic_vector(15 downto 0);
          stage_b_oe   : in  std_logic;

          -- stage 2
          stage_c_addr : in  std_logic_vector(15 downto 0);
          stage_c_din  : out std_logic_vector(15 downto 0);
          stage_c_dout : in  std_logic_vector(15 downto 0);
          stage_c_oe   : in  std_logic;
          stage_c_we   : in  std_logic;

          -- to the Memory Control Unit
          addr : out std_logic_vector(15 downto 0);
          din  : in  std_logic_vector(15 downto 0);
          dout : out std_logic_vector(15 downto 0);
          oe   : out std_logic;
          we   : out std_logic
    );
end Memory_Mux;

architecture Memory_Mux_Arch of Memory_Mux is
begin

    process(stage,
             stage_a_addr,
             stage_b_addr,
             stage_c_addr, stage_c_dout)
    begin
       if stage(0) = '1' then
          addr <= stage_a_addr;
       elsif stage(1) = '1' then
          addr <= stage_b_addr;
       elsif stage(2) = '1' then
          addr <= stage_c_addr;
          dout <= stage_c_dout;
       end if;
    end process;

    process(stage_io, din,
             stage_a_din,
             stage_b_din, stage_b_oe,
             stage_c_din, stage_c_oe, stage_c_we)
    begin
       if stage_io(0) = '1' then
          stage_a_din <= din;
          oe <= '1';
          we <= '0';
       elsif stage_io(1) = '1' then
          stage_b_din <= din;
          oe <= stage_b_oe;
          we <= '0';
       elsif stage_io(2) = '1' then
          stage_c_din <= din;
          oe <= stage_c_oe;
          we <= stage_c_we;
       else
        oe <= '0';
          we <= '0';
       end if;
    end process;

end Memory_Mux_Arch;


Process_Flow_Control_Unit.Vhd:
CODE: VHDL
library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all; -- for conv_integer and opperations on std_logic_vector
    --use ieee.std_logic_arith.all; -- for conv_std_logic_vector

entity Process_Flow_Control_Unit is
    port( ip    : in  std_logic_vector(15 downto 0);

          instr : in  std_logic_vector(5  downto 0);

          imm   : in  std_logic;

          b     : in  std_logic_vector(15 downto 0);

          z     : in  std_logic; -- zero flag
          gt    : in  std_logic; -- greater than flag

          nip   : out std_logic_vector(15 downto 0)
    );
end Process_Flow_Control_Unit;

architecture Process_Flow_Control_Unit_Arch of Process_Flow_Control_Unit is

begin

    process(ip, instr, b, z, gt, imm)
    begin
       if instr = "010000" then                           -- 16 jmp
          nip <= b;
       elsif instr = "010001" and z = '1' then            -- 17 jz (if z = '0' we will continue executing after this instruction).
          nip <= b;
       elsif instr = "010010" and z = '0' then            -- 18 jnz
          nip <= b;
       elsif instr = "010011" and gt = '1' then           -- 19 jgt
          nip <= b;
       elsif instr = "010100" and (z or gt) = '0' then    -- 20 jlt
          nip <= b;
       elsif instr = "010111" then                        -- 23 hlt
          nip <= ip;
       else -- normal instruction
          if imm = '1' then -- is this instruction followed by an immediate?
             nip <= ip + 2;
          else
             nip <= ip + 1;
          end if;
       end if;
    end process;

end Process_Flow_Control_Unit_Arch;

15 comments posted so far
Add your own »

1. On Oct 20 2005 @ 06:21 Vorlath wrote:

I like this.  Very clean.  As far as the instruction set is concerned.  Haven't done circuit design in quite a while.  I especially like the 0 register.  This is something too often overlooked and too useful in my opinion.

2. On Nov 21 2007 @ 16:35 guest wrote:

This is meer ,,
can you please send me the detail description of your 16 bit RISC microprocessor... i am working on the same project ..
my e-mail is ........ mail4meer@gamil.com.

ITS URGENT.....

3. On Jan 24 2008 @ 09:33 guest wrote:

do u have vhdl or verilog code for Viterbi encoder/decoder or Manchester encoder/decoder......
If so could you please do me a favor and send it to >>>
                 
                      Webster_dev@yahoo.com
I would really appreciate it..!!

4. On Mar 20 2008 @ 19:03 guest wrote:

cool shit!

5. On Apr 10 2008 @ 12:20 guest wrote:

hi i m alok from pune.i m in urgent need of 16 bit risc code.i would be very thankful 2 u if u send me this code on my email alok.kr11@gmail.com which i require urgently 4 my project.i hav lost my project due 2 hard disk faliure & there is no back-up & time is also less.plz send me the code.plz...

6. On Apr 24 2008 @ 09:23 guest wrote:

can someone help me and provide me with risc code for 24 instructions, with test bench also, thanx


ielhassa@yahoo.com

7. On Aug 14 2008 @ 10:12 guest wrote:

its really very much upto the mark.could u please send me the code at kaproor@gmail.com.

8. On Nov 01 2008 @ 18:07 guest wrote:

hello  
can u plz send me the code at vyas.anki@gmail.com and also ur project details plz its urgent

9. On Jan 20 2009 @ 06:40 guest wrote:

hi ,
this is teju i want code and description of 16 bit risc processor(tejakatari@gmail.com).

10. On Jan 23 2009 @ 15:28 guest wrote:

hello  
can u plz send me the code at "umashankarkurmi@yahoo.co.in" and also ur project details plz its urgent

11. On May 19 2009 @ 09:48 guest wrote:

Find louis vuitton handbag and louis  Louis Vuitton Handbags , louis vuitton wallet and louis vuitton purse items on Louis Vuitton Store Browse a huge selection of LV Handbags Louis Vuitton is luxury gifts, French fashion, the replica Louis Vuitton Store is woman best friend. With Louis Vuitton Discover real Louis Vuitton bags, Vuitton accessories and the latest handbag lines. Join the biggest active Louis Vuitton enthusiast community on the web today

UGGs is a brand that is all about luxury and comfort for everyday life. Only the finest quality materials are used to create UGG Boots. Provide UGG Women Boots,UGG Man Boots,UGG Kids Boots.
UGG Australia is the largest distributor of Grade-A sheepskin.
Find Women's UGGs, Men's UGG Boots, and Kids UGGs on Sale all made with ... UGG Store include Discount UGG  UGG Classic Tall,UGG Classic Short

Louis Vuitton is luxury gifts, French fashion, the replica Louis Vuitton Handbag is woman best friend.Monogram Groom.
Offers Discount Louis Vuitton handbags and Louis Vuitton bags and all other designer handbags,free global fast shipping,low price and top quality.Monogram Jokes,Monogram Suede cheap Louis Vuitton
Louis Vuitton.

Looking For Gucci Shoes ? Gucci Store provide gucci Mens shoes,gucci Womens shoes
Wonderful Gucci shoes sale Gucci men's shoes and Gucci women's shoes at discount Gucci Shoes prices.
cheap gucci Shoes
Gucci Shoes and gucci clothing Spring - Summer 2009, Prada Shoes and prada clothing from the Latest Collection 2009 and Dolce Gabbana Clothing 2009
Gucci Loafers
Gucci Sneakers

UGGs
Louis Vuitton Handbags
Gucci Shoes
Louis Vuitton
UGG Boots
Louis Vuitton Handbags
gucci shoes
Monogram Groom
Discount Louis Vuitton
UGG Boots
Louis Vuitton handbags

15. On Aug 26 2009 @ 10:02 guest wrote:

hi ,
this is atiq, i want your assembler and description of 16 bit risc processor(hokage_87@hotmail.com).   It's URGENT....i do the same project.

Add a new comment

Name:
Password: (leave empty for anonymous comment)
 
View formatting tags Comment: