Whole-CPU Simulation and Pipelining

CS 441 Lecture, Dr. Lawlor

First, some sources for VHDL sample code:
Using these as a reference, it's pretty easy to build a little CPU:
-- nanoproc, a very small CPU + RAM 
-- by Dr. Orion Sky Lawlor, olawlor@acm.org, 2007-09-19 (Public Domain)
use std.textio.all;
library IEEE; use IEEE.numeric_bit.all;

entity foo is end entity;
architecture behaviour of foo is
-- Data type used throughout; a 16-bit number
subtype NREG is UNSIGNED(15 downto 0); -- IEEE.numeric_bit datatype
function MAKEREG(V: in integer) return NREG is
begin return to_unsigned(V,16); end;

-- Debugging printout function
procedure print(S: in string; V : in NREG) is
variable L : line;
begin
write(L,S);
write(L, to_integer(V));
writeline(output,L);
end;

begin -- architecture of nanoproc
main: process
-- 16 32-bit registers.
type regarray is array(0 to 15) of NREG;
variable r : regarray;
-- Register 15 is the program counter.
alias pc : NREG is r(15);

-- 256 32-bit memory locations
type memarray is array(0 to 255) of NREG;
variable m : memarray;

variable inst : NREG;
variable setup : NREG;
begin -- main process
-- Initialize registers
pc := MAKEREG(0); -- Start executing at address zero
r(0) := MAKEREG(0); -- register zero is always equal to zero

-- Initialize RAM with some instructions
m(0) := x"1107"; -- load 0x07 into register 1
m(1) := x"1203"; -- load 0x03 into register 2
m(2) := x"a112"; -- add regs 1 and 2
m(3) := x"b001"; -- magic print-reg-1 instruction
m(4) := x"e000"; -- magic Exit instruction

-- Main execution loop
loop
inst := m(to_integer(pc)); -- fetch next instruction
pc := pc + MAKEREG(1); -- increment program counter
case inst(15 downto 12) is
--------------- Table of Instruction Opcodes ---------------
when x"1" => -- Load-immediate instruction: 0x1 dest <8-bit immed>
r(to_integer(inst(11 downto 8)))
:= MAKEREG(to_integer(inst(7 downto 0)));
when x"a" => -- Addition instruction: 0xA dest src1 src2
r(to_integer(inst(11 downto 8)))
:= r(to_integer(inst(7 downto 4)))
+ r(to_integer(inst(3 downto 0)));
when x"b" => -- Output instruction
print(string'("Value in r(1)="),r(to_integer(inst(3 downto 0))));
when x"e" => -- Execution complete
print(string'("End of execution at pc="),pc-1);
wait; -- exits simulator
when others => -- Illegal instruction!
print(string'("Invalid instruction at pc="),pc-1);
print(string'("Instruction value="),inst);
wait; -- exits simulator

--------------- End Table of Instructions ---------------
end case;
end loop;

end process; -- main

end architecture;
(executable NetRun link)