file: spitest.vhd
--
-- Motorola HC11 VHDL model SPI test bench
-- Copyright (C) Green Mountain Computing Systems, 1995
-- All rights reserved.
--
-- This software is provided "as is" without warranty of any kind.  Green 
-- Mountain Computing Systems does not accept any responsibility for results
-- obtained by using this software and does not guarantee that the software
-- is correct.
--
-- spitest.vhd : This is a test bench for the Serial Peripheral Interface
--      (SPI) component of the HC11 VHDL model.
--
-- 5/25/95 : Created - Scott Thibault
--

-- This test bench instantiates and connects together two SPI components.
-- One of these is chosen to be the master and the other is the slave.
-- Two different transfers are made with different formats of communication.
-- The first transfer tests transfers with the clock phase set to '1' and the
-- second with the clock phase set to '0'.  These two formats described in
-- detail with timing diagrams in the M68HC11 Reference Manual.

-- Test bench entity with no inputs or outputs
entity test_spi is
end test_spi;

-- The test bench uses the vector functions, the HC11 types, the HC11 clock
-- model, and the HC11 SPI model.
library vector,hc11type,hc11clk,hc11spi;
use vector.functions.all;
use hc11type.types.all;
use hc11clk.all;
use hc11spi.all;

architecture behavoir of test_spi is
  -- The HC11 clock model
  component clock
    port (extal,E: out bit;
        ph1,ph2,as: out bit;
        ptaclk: out bit);
  end component;

  -- The HC11 SPI model
  component spi
  port (E : in bit;
        ph1, ph2, reset : in bit;
        ss: in bit;
        sckin: in bit;
        sckout: out bit;
        mi,si : in bit;
        mo,so : out bit;
        ss_dir : in bit;
        mfault : out bit;
        int_spi : out bit;
        spe,slave : out bit;
        reg_en : in bit;
        as, bus_rw : in bit;
        bus_addr : in word;
        bus_data : inout databus bus);
  end component;

  signal EXTAL,E,ph1,ph2,as : bit;      -- Clock signals
  signal reset : bit;                   -- The global reset line
  signal TxD,RxD : bit;                 -- Serial I/Os
  signal ss1,ss2 : bit;                 -- SPI ss outputs
  signal sclk : bit;                    -- SPI sclk lines
  signal gnd : bit :='0';               -- Ground
  signal ss_dir : bit;                  -- Direction of SS pin
  signal spi1_int,spi2_int : bit;       -- Interrupt request lines
  signal reg_en1,reg_en2: bit;          -- Enable lines for memory mapped 
                                        -- regsiters.
  signal en1,en2: boolean;              -- Local enable of read/writes
  signal rw : bit;                      -- System bus read/write line
  signal address : word;                -- System bus address bus
  signal data : databus bus;            -- System bus data bus
begin
  clk1 : clock
    port map (EXTAL,E,ph1,ph2,as,open);

  spi1 : spi
    port map (E,ph1,ph2,reset,ss1,gnd,sclk,RxD,gnd,TxD,open,ss_dir,open,
        spi1_int,open,open,reg_en1,as,rw,address,data);

  spi2 : spi
    port map (E,ph1,ph2,reset,ss2,sclk,open,gnd,TxD,open,RxD,ss_dir,open,
        spi2_int,open,open,reg_en2,as,rw,address,data);

  ss_dir<='0';   -- Set SS pin as input

  -- Generate a reset for one E cycle
  reset<='0','1' after 333ns;

  -- Enable read/writes to memory mapped registers starting at X"1000"  
  reg_en1<='1' when address(15 downto 8)=X"10" and en1 else '0';
  reg_en2<='1' when address(15 downto 8)=X"10" and en2 else '0';

  test : process
    -- Simulate a system bus write cycle
    procedure write_byte(w_addr : in word; w_data : in byte) is
    begin
      address<=w_addr;
      rw<='0';
      wait until E='1';
      data<=w_data;
      wait until as='1';
      data<=null;
      address<=X"0000";
    end write_byte;

    -- Simulate a system bus read cycle
    procedure read_byte(w_addr : in word; w_data : out byte) is
    begin
      address<=w_addr;
      rw<='1';
      wait until E='0' and E'event;
      w_data<=data;
      address<=X"0000";
    end read_byte;

    -- SPI memory mapped register addresses
    constant SPCR : word :=X"1028";
    constant SPSR : word :=X"1029";
    constant SPDR : word :=X"102A";
  begin
    ss1<='1';
    ss2<='1';
    en1<=false;
    en2<=false;
    -- Wait for reset to complete before beginning test
    wait until reset='1';

    -- Configure SPI 2 as a slave with 0 polarity and 0 phase, and load data 
    --   register with 0xCC
    en2<=true;
    write_byte(SPCR,byte'("01000000"));  -- Make spi2 slave pol=0 pha=0
    write_byte(SPDR,byte'("11001100"));  -- Set SPDR data
    en2<=false;

    -- Configure SPI 1 as a master with 0 polarity and 0 phase, and load data 
    --   register with 0xAA
    en1<=true;
    write_byte(SPCR,byte'("01010000"));  -- Make spi1 master pol=0 pha=0
    ss2<='0';
    write_byte(SPDR,byte'("01011010"));  -- This write will initiate transfer
    en1<=false;

    -- Wait for transfer to complete
    wait for 6us;

    -- Configure SPI 2 as a slave with 0 polarity and 1 phase, and load data 
    --   register with 0xCC
    en2<=true;
    write_byte(SPSR,byte'("00000000"));  -- Clear SPIF from last transfer
    write_byte(SPCR,byte'("01000100"));  -- Make sci2 slave pol=0 pha=1
    write_byte(SPDR,byte'("11001100"));  -- Set SPDR data
    en2<=false;

    -- Configure SPI 1 as a master with 0 polarity and 1 phase, and load data 
    --   register with 0xAA
    en1<=true;
    write_byte(SPSR,byte'("00000000"));  -- Clear SPIF from last transfer
    write_byte(SPCR,byte'("01010100"));  -- Make sci1 master pol=0 pha=1
    write_byte(SPDR,byte'("01011010"));  -- This write will initiate transfer

    -- Test complete
    wait;
  end process;
end behavoir;
type b to return to text