242 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
| library ieee;
 | |
| use ieee.std_logic_1164.all;
 | |
| use ieee.numeric_std.all;
 | |
| use std.textio.all;
 | |
| 
 | |
| entity sysbus_test is
 | |
| end sysbus_test;
 | |
| 
 | |
| architecture rtl of sysbus_test is
 | |
| 
 | |
|   component sysbus is
 | |
|     port(
 | |
|           clk: in std_logic;
 | |
|           rst: in std_logic;
 | |
| 
 | |
|         -- master port 0
 | |
|           m0_addr: in std_logic_vector(15 downto 0);
 | |
|           m0_wdata: in std_logic_vector(15 downto 0);
 | |
|           m0_rdata: out std_logic_vector(15 downto 0);
 | |
|           m0_re: in std_logic;
 | |
|           m0_we: in std_logic;
 | |
|           m0_busy: out std_logic;
 | |
| 
 | |
|         -- master port 1
 | |
|           m1_addr: in std_logic_vector(15 downto 0);
 | |
|           m1_wdata: in std_logic_vector(15 downto 0);
 | |
|           m1_rdata: out std_logic_vector(15 downto 0);
 | |
|           m1_re: in std_logic;
 | |
|           m1_we: in std_logic;
 | |
|           m1_busy: out std_logic;
 | |
| 
 | |
|         -- actual bus
 | |
|           bus_addr: out std_logic_vector(15 downto 0);
 | |
|           bus_wdata: out std_logic_vector(15 downto 0);
 | |
|           bus_rdata: in std_logic_vector(15 downto 0);
 | |
|           bus_re: out std_logic;
 | |
|           bus_we: out std_logic
 | |
|         );
 | |
|   end component;
 | |
| 
 | |
|   signal finished: std_logic := '0';
 | |
|   signal clk, rst: std_logic := '0';
 | |
| 
 | |
|   signal m0_addr, m0_wdata, m0_rdata: std_logic_vector(15 downto 0);
 | |
|   signal m0_re, m0_we, m0_busy: std_logic;
 | |
|   signal m1_addr, m1_wdata, m1_rdata: std_logic_vector(15 downto 0);
 | |
|   signal m1_re, m1_we, m1_busy: std_logic;
 | |
|   signal bus_addr, bus_wdata, bus_rdata: std_logic_vector(15 downto 0);
 | |
|   signal bus_re, bus_we : std_logic;
 | |
| 
 | |
|   signal bus_rdata_next: std_logic_vector(15 downto 0);
 | |
| 
 | |
| begin
 | |
|   dut: sysbus port map(clk => clk, rst => rst,
 | |
|                       m0_addr => m0_addr, m0_wdata => m0_wdata, m0_rdata => m0_rdata,
 | |
|                       m0_re => m0_re, m0_we => m0_we, m0_busy => m0_busy,
 | |
|                       m1_addr => m1_addr, m1_wdata => m1_wdata, m1_rdata => m1_rdata,
 | |
|                       m1_re => m1_re, m1_we => m1_we, m1_busy => m1_busy,
 | |
|                       bus_addr => bus_addr, bus_wdata => bus_wdata, bus_rdata => bus_rdata,
 | |
|                       bus_re => bus_re, bus_we => bus_we
 | |
|                   );
 | |
| 
 | |
|   -- clock
 | |
|   process
 | |
|   begin
 | |
|     if finished = '0' then
 | |
|       clk <= not clk;
 | |
|       wait for 5 ns;
 | |
|     else
 | |
|       clk <= '0';
 | |
|       wait;
 | |
|     end if;
 | |
|   end process;
 | |
| 
 | |
|   -- memory
 | |
|   process(bus_re, bus_addr)
 | |
|   begin
 | |
|     bus_rdata_next <= x"0000";
 | |
|     if bus_re = '1' then
 | |
|       case bus_addr is
 | |
|         when x"feed" =>
 | |
|           bus_rdata_next <= x"babe";
 | |
|         when x"dead" =>
 | |
|           bus_rdata_next <= x"beef";
 | |
|         when others =>
 | |
|       end case;
 | |
|     end if;
 | |
|   end process;
 | |
| 
 | |
|   process(clk, rst)
 | |
|   begin
 | |
|     if rst = '1' then
 | |
|       bus_rdata <= x"0000";
 | |
|     elsif rising_edge(clk) then
 | |
|       bus_rdata <= bus_rdata_next;
 | |
|     end if;
 | |
|   end process;
 | |
| 
 | |
|   process
 | |
|   begin
 | |
|     rst <= '1';
 | |
| 
 | |
|     m0_re <= '0';
 | |
|     m0_we <= '0';
 | |
|     m1_re <= '0';
 | |
|     m1_we <= '0';
 | |
| 
 | |
|     wait for 1 ns;
 | |
|     assert(m0_busy='0') report "Fail rst" severity error;
 | |
|     assert(m1_busy='0') report "Fail rst" severity error;
 | |
| 
 | |
|     rst <= '0';
 | |
| 
 | |
|     wait for 10 ns;
 | |
|     assert(m0_busy='0') report "Should still be idle" severity error;
 | |
|     assert(m1_busy='0') report "Should still be idle" severity error;
 | |
| 
 | |
|     -- m0 write
 | |
| 
 | |
|     m0_addr <= x"feed";
 | |
|     m0_wdata <= x"babe";
 | |
|     m0_we <= '1';
 | |
| 
 | |
|     wait for 10 ns;
 | |
|     assert(bus_addr=x"feed") report "Did not do write" severity error;
 | |
|     assert(bus_wdata=x"babe") report "Did not do write" severity error;
 | |
| 
 | |
|     m0_we <= '0';
 | |
| 
 | |
|     -- read
 | |
|     m0_re <= '1';
 | |
|     wait for 10 ns;
 | |
|     assert(m0_rdata=x"babe") report "Did not do read" severity error;
 | |
|     assert(m1_busy='1') report "Did not do block m1 for m0 read" severity error;
 | |
| 
 | |
|     m0_re <= '0';
 | |
| 
 | |
|     wait for 10 ns;
 | |
|     assert(m0_busy='0') report "m0 was not idle" severity error;
 | |
|     assert(m1_busy='0') report "m1 was not idle" severity error;
 | |
| 
 | |
|     -- m1 write
 | |
| 
 | |
|     m1_addr <= x"dead";
 | |
|     m1_wdata <= x"beef";
 | |
|     m1_we <= '1';
 | |
| 
 | |
|     wait for 10 ns;
 | |
|     assert(bus_addr=x"dead") report "Did not do write" severity error;
 | |
|     assert(bus_wdata=x"beef") report "Did not do write" severity error;
 | |
| 
 | |
|     m1_we <= '0';
 | |
| 
 | |
|     -- read
 | |
|     m1_re <= '1';
 | |
|     wait for 10 ns;
 | |
|     assert(m1_rdata=x"beef") report "Did not do read m1" severity error;
 | |
|     assert(m0_busy='1') report "Did not do block m0 for m1 read" severity error;
 | |
| 
 | |
|     m1_re <= '0';
 | |
| 
 | |
|     wait for 10 ns;
 | |
|     assert(m0_busy='0') report "m0 was not idle" severity error;
 | |
|     assert(m1_busy='0') report "m1 was not idle" severity error;
 | |
| 
 | |
| 
 | |
|     -- serious shit below
 | |
|     -- concurent writes
 | |
| 
 | |
|     m0_addr <= x"feed";
 | |
|     m0_wdata <= x"babe";
 | |
|     m0_we <= '1';
 | |
| 
 | |
|     m1_addr <= x"dead";
 | |
|     m1_wdata <= x"beef";
 | |
|     m1_we <= '1';
 | |
| 
 | |
|     wait for 9 ns;
 | |
|     assert(bus_addr=x"feed") report "Did not do write m0" severity error;
 | |
|     assert(bus_wdata=x"babe") report "Did not do write m0" severity error;
 | |
|     wait for 1 ns;
 | |
|     assert(m1_busy='1') report "Did not do delay m1" severity error;
 | |
| 
 | |
|     m0_we <= '0';
 | |
|     m1_we <= '0';
 | |
| 
 | |
|     wait for 9 ns;
 | |
|     assert(bus_addr=x"dead") report "Did not do write m1" severity error;
 | |
|     assert(bus_wdata=x"beef") report "Did not do write m1" severity error;
 | |
|     wait for 1 ns;
 | |
| 
 | |
|     wait for 10 ns;
 | |
|     assert(m0_busy='0') report "m0 was not idle" severity error;
 | |
|     assert(m1_busy='0') report "m1 was not idle" severity error;
 | |
| 
 | |
|     -- concurrent reads (!!)
 | |
| 
 | |
|     m0_re <= '1';
 | |
|     m1_re <= '1';
 | |
|     wait for 10 ns;
 | |
|     assert(m0_rdata=x"babe") report "Did not do read m0" severity error;
 | |
|     assert(m1_busy='1') report "Did not do block m1 for m0 read" severity error;
 | |
| 
 | |
|     m0_re <= '0';
 | |
| 
 | |
|     wait for 20 ns;
 | |
|     assert(m1_busy='0') report "m1 was not idle" severity error;
 | |
|     assert(m1_rdata=x"beef") report "Did not do read m1" severity error;
 | |
|     assert(m0_busy='1') report "Did not do block m0 for m1 read" severity error;
 | |
| 
 | |
|     m1_re <= '0';
 | |
| 
 | |
|     wait for 10 ns;
 | |
|     assert(m0_busy='0') report "m0 was not idle" severity error;
 | |
|     assert(m1_busy='0') report "m1 was not idle" severity error;
 | |
| 
 | |
|     -- concurrent read & write (OMG)
 | |
|     m1_re <= '1';
 | |
|     m0_we <= '1';
 | |
| 
 | |
|     wait for 10 ns;
 | |
|     assert(m1_rdata=x"beef") report "Did not do read m1" severity error;
 | |
|     assert(m0_busy='1') report "Did not do block m0 for m1 read" severity error;
 | |
| 
 | |
|     m1_re <= '0';
 | |
| 
 | |
|     wait for 10 ns;
 | |
|     assert(bus_addr=x"feed") report "Did not do write m0" severity error;
 | |
|     assert(bus_wdata=x"babe") report "Did not do write m0" severity error;
 | |
| 
 | |
|     m0_we <= '0';
 | |
| 
 | |
|     wait for 10 ns;
 | |
|     assert(m0_busy='0') report "m0 was not idle" severity error;
 | |
|     assert(m1_busy='0') report "m1 was not idle" severity error;
 | |
| 
 | |
|     assert false report "Test done." severity note;
 | |
|     finished <= '1';
 | |
|     wait;
 | |
|   end process;
 | |
| end rtl;
 |