Building the CPU

A project log for From bit-slice to Basic (and symbolic tracing)

Step by step from micro-coded Intel 8080 compatible CPU based on Am2901 slices to small system running Tiny Basic from the Disco Era.

zpekiczpekic 03/26/2023 at 05:100 Comments


Given that this CPU implementation is an almost canonical example of microcoded design as envisioned by AMD - and a showcase of their Am29XX and Am25XX ICs - it is very helpful to go over at least chapters I and II of the "Bit-slice microprocessor design" book for better understanding. After that, the application note provides a great explanation of this specific CPU implementation. All source files to implement the CPU are under this folder.

General notes

In this CPU re-creation I attempted to follow the original application note as closely as possible. The description there is very detailed but also sufficiently clear to allow not just the understanding of this implementation, but how it can be adapted to other similar processors. The schema of the CPU is in figures 3-5 in the application note, and the VHDL top-level file is organized to follow those figures, and IC names/id so that the code can easily be mapped to schema and vice versa. 

VHDL has the ability to describe circuits in both structural and behavioral ways, and in any source files these can be freely mixed. In this case, top-level is mostly structural (building blocks), for example:

-- data bus register (FLAGS)
-- 7 6 5 4  3 2 1 0 --------
-- S Z 0 AC 0 P 1 C --------
        u102: Am2918 port map (     clk => CLK,
                    nOE => db(3),
                    d(3) => '1', 
                    d(2) => '0', 
                    d(1) => '0', 
                    d(0) => u92_pin7,
                    o(3) => open, 
                    o(2) => open, 
                    o(1) => open, 
                    o(0) => flag_cy,
                    y(3) => DBUS(1), 
                    y(2) => DBUS(3), 
                    y(1) => DBUS(5), 
                    y(0) => DBUS(0)
      u101: Am2918 port map (     clk => CLK,
                    nOE => db(3),
                    d(3) => u91_pin4, 
                    d(2) => u91_pin7, 
                    d(1) => u91_pin9, 
                    d(0) => u91_pin12,
                    o(3) => flag_z, 
                    o(2) => flag_p, 
                    o(1) => flag_s, 
                    o(0) => flag_ac,
                    y(3) => DBUS(6), 
                    y(2) => DBUS(2), 
                    y(1) => DBUS(7), 
                    y(0) => DBUS(4)

 While the implementation of individual components in mostly behavioral (description of functionality):

entity Am2918 is
    Port ( clk : in STD_LOGIC;
           nOE : in STD_LOGIC;
           d : in STD_LOGIC_VECTOR (3 downto 0);
           o : buffer STD_LOGIC_VECTOR (3 downto 0);
           y : out STD_LOGIC_VECTOR (3 downto 0));
end Am2918;

architecture Behavioral of Am2918 is


y <= o when (nOE = '0') else "ZZZZ";

load_q: process(clk, d)
    if (rising_edge(clk)) then
        o <= d;
    end if;
end process;

end Behavioral;


The parts list in the original design (59 ICs) closely matches the component list from the FPGA project:

However, there are some differences for sake of simplification: