Our first instruction

A computer executes programs by following instructions. The instructions belong to an an instruction set. As mentioned in Chapter Welcome, we will use a subset of the OR1K instruction set as the instruction set for our computer.

As a first step, we will try to build a computer with only one instruction. Although somewhat restricted, this computer will be able to

  • Read instructions stored in a memory
  • Decode each instruction
  • Take action, based on the instruction read - in this case, it means that the computer will store a value in a register

We will start with deciding on a program to run our our computer. The program will be stored in a memory, and its instructions will be read, one by one, and actions will be taken.

A program

Our computer needs a program in order to run. Before creating the program, we select an instruction to use.

From the OpenRisc Architecture page we can find the OpenRISC 100 Architecture Manual.

We look in the OpenRISC 100 Architecture Manual, and we find the instruction l.movhi rD, K on page 81. This instruction takes a 16-bit value K, and shifts it left by 16-bits, and then places the resulting value in the register rD.

Read more

Addressing a memory

We need to put our instructions in memory.

Design a memory where the program can be stored. A memory implementation in VHDL is shown in Figure 11.

library ieee;
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;

library std;
use std.textio.all;

library work;
use work.string_lib.all;

entity memory is
  generic (address_width: integer := 32;
           data_width: integer := 32;
           size: integer := 256);
  port(
    clk: in std_logic;
    write_enable: in std_logic; 
    address: in std_logic_vector(address_width-1 downto 0); 
    data_in: in std_logic_vector(data_width-1 downto 0);
    data_out: out std_logic_vector(data_width-1 downto 0));

end memory;

architecture rtl of memory is

  type memory_type is array(0 to size-1) of
    std_logic_vector(data_width-1  downto 0); 

  impure function init_memory return memory_type is
    file in_file: text is in "memory_contents.txt";
    variable in_line: line;
    variable s: std_logic_vector(data_width-1 downto 0);
    variable memory: memory_type; 
  begin
    report "length of memory is " & integer'image(memory'length); 
    for i in 1 to integer(memory'length) loop
      if not endfile(in_file) then
        readline(in_file, in_line);
        hread(in_line, s);
        memory(i-1) := s; 
      else
        memory(i-1) := (others => 'X');
      end if; 
    end loop;
    return memory;
  end function;
  
  signal memory: memory_type := init_memory;

begin

  update: process(clk)
  begin
    if rising_edge(clk) then 
      if write_enable = '1' then
        memory(to_integer(unsigned(address))) <= data_in;
      end if;
    end if;
  end process;
  
  data_out <= memory(to_integer(unsigned(address))); 

end rtl; 

Figure 11. A memory in VHDL.

This the VHDL view - other views are Verilog - SystemC-TLM

Create a pc that reads addresses expressed in bytes. Meaning that it increments itself with four for each instruction read. A program counter implementation in VHDL is shown in Figure 12.

library ieee;
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all;

entity pc is
  generic (pc_width: integer := 32); 
  port(
    clk: in std_logic;
    pc_out: out std_logic_vector(pc_width-1 downto 0) := (others => '0'));
  end pc;

architecture rtl of pc is

  signal pc_value: std_logic_vector(pc_width-1 downto 0) := (others => '0');

begin

  update: process(clk)
  begin
    if rising_edge(clk) then
      pc_value <= std_logic_vector(unsigned(pc_value) + 4);
    end if;
  end process; 

  pc_out <= pc_value;

end rtl; 

Figure 12. A program counter in VHDL.

This the VHDL view - other views are Verilog - SystemC-TLM

Read more

Decoding the instruction

We must interpret the instruction. We must take actions, in the form of writing parts of the instruction - the K value - into a register. We make a register bank with a destination register selection, and a data input, and a write enable (feels good to have that).

Read more

Running the program

Here we wire the pieces together, and create a functioning computer, albeit with only one instruction! More to come, continue reading!

Read more