diff --git a/simple_ram_behavioural.vhdl b/simple_ram_behavioural.vhdl index 2ccee79..afc3d51 100644 --- a/simple_ram_behavioural.vhdl +++ b/simple_ram_behavioural.vhdl @@ -8,70 +8,70 @@ use work.wishbone_types.all; use work.simple_ram_behavioural_helpers.all; entity mw_soc_memory is - generic ( - RAM_INIT_FILE : string; - MEMORY_SIZE : integer - ); + generic ( + RAM_INIT_FILE : string; + MEMORY_SIZE : integer + ); - port ( - clk : in std_ulogic; - rst : in std_ulogic; + port ( + clk : in std_ulogic; + rst : in std_ulogic; - wishbone_in : in wishbone_master_out; - wishbone_out : out wishbone_slave_out - ); + wishbone_in : in wishbone_master_out; + wishbone_out : out wishbone_slave_out + ); end mw_soc_memory; architecture behave of mw_soc_memory is - type wishbone_state_t is (IDLE, ACK); + type wishbone_state_t is (IDLE, ACK); - signal state : wishbone_state_t := IDLE; - signal ret_ack : std_ulogic := '0'; - signal identifier : integer := behavioural_initialize(filename => RAM_INIT_FILE, size => MEMORY_SIZE); - signal reload : integer := 0; + signal state : wishbone_state_t := IDLE; + signal ret_ack : std_ulogic := '0'; + signal identifier : integer := behavioural_initialize(filename => RAM_INIT_FILE, size => MEMORY_SIZE); + signal reload : integer := 0; begin - wishbone_process: process(clk) - variable ret_dat: std_ulogic_vector(63 downto 0) := (others => '0'); - begin - wishbone_out.ack <= ret_ack and wishbone_in.cyc and wishbone_in.stb; - wishbone_out.dat <= ret_dat; + wishbone_process: process(clk) + variable ret_dat: std_ulogic_vector(63 downto 0) := (others => '0'); + begin + wishbone_out.ack <= ret_ack and wishbone_in.cyc and wishbone_in.stb; + wishbone_out.dat <= ret_dat; - if rising_edge(clk) then - if rst = '1' then - state <= IDLE; - ret_ack <= '0'; - else - ret_dat := x"FFFFFFFFFFFFFFFF"; + if rising_edge(clk) then + if rst = '1' then + state <= IDLE; + ret_ack <= '0'; + else + ret_dat := x"FFFFFFFFFFFFFFFF"; - -- Active - if wishbone_in.cyc = '1' then - case state is - when IDLE => - if wishbone_in.stb = '1' then - -- write - if wishbone_in.we = '1' then - assert not(is_x(wishbone_in.dat)) and not(is_x(wishbone_in.adr)) severity failure; - report "RAM writing " & to_hstring(wishbone_in.dat) & " to " & to_hstring(wishbone_in.adr); - behavioural_write(wishbone_in.dat, wishbone_in.adr, to_integer(unsigned(wishbone_in.sel)), identifier); - reload <= reload + 1; - ret_ack <= '1'; - state <= ACK; - else - behavioural_read(ret_dat, wishbone_in.adr, to_integer(unsigned(wishbone_in.sel)), identifier, reload); - report "RAM reading from " & to_hstring(wishbone_in.adr) & " returns " & to_hstring(ret_dat); - ret_ack <= '1'; - state <= ACK; - end if; - end if; - when ACK => - ret_ack <= '0'; - state <= IDLE; - end case; - else - ret_ack <= '0'; - state <= IDLE; - end if; - end if; - end if; - end process; + -- Active + if wishbone_in.cyc = '1' then + case state is + when IDLE => + if wishbone_in.stb = '1' then + -- write + if wishbone_in.we = '1' then + assert not(is_x(wishbone_in.dat)) and not(is_x(wishbone_in.adr)) severity failure; + report "RAM writing " & to_hstring(wishbone_in.dat) & " to " & to_hstring(wishbone_in.adr); + behavioural_write(wishbone_in.dat, wishbone_in.adr, to_integer(unsigned(wishbone_in.sel)), identifier); + reload <= reload + 1; + ret_ack <= '1'; + state <= ACK; + else + behavioural_read(ret_dat, wishbone_in.adr, to_integer(unsigned(wishbone_in.sel)), identifier, reload); + report "RAM reading from " & to_hstring(wishbone_in.adr) & " returns " & to_hstring(ret_dat); + ret_ack <= '1'; + state <= ACK; + end if; + end if; + when ACK => + ret_ack <= '0'; + state <= IDLE; + end case; + else + ret_ack <= '0'; + state <= IDLE; + end if; + end if; + end if; + end process; end behave; diff --git a/simple_ram_behavioural_helpers.vhdl b/simple_ram_behavioural_helpers.vhdl index 8540fa0..507594f 100644 --- a/simple_ram_behavioural_helpers.vhdl +++ b/simple_ram_behavioural_helpers.vhdl @@ -2,29 +2,29 @@ library ieee; use ieee.std_logic_1164.all; package simple_ram_behavioural_helpers is - function behavioural_initialize (filename: String; size: integer) return integer; - attribute foreign of behavioural_initialize : function is "VHPIDIRECT behavioural_initialize"; + function behavioural_initialize (filename: String; size: integer) return integer; + attribute foreign of behavioural_initialize : function is "VHPIDIRECT behavioural_initialize"; - procedure behavioural_read (val: out std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer; reload: integer); - attribute foreign of behavioural_read : procedure is "VHPIDIRECT behavioural_read"; + procedure behavioural_read (val: out std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer; reload: integer); + attribute foreign of behavioural_read : procedure is "VHPIDIRECT behavioural_read"; - procedure behavioural_write (val: std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer); - attribute foreign of behavioural_write : procedure is "VHPIDIRECT behavioural_write"; + procedure behavioural_write (val: std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer); + attribute foreign of behavioural_write : procedure is "VHPIDIRECT behavioural_write"; end simple_ram_behavioural_helpers; package body simple_ram_behavioural_helpers is - function behavioural_initialize (filename: String; size: integer) return integer is - begin - assert false report "VHPI" severity failure; - end behavioural_initialize; + function behavioural_initialize (filename: String; size: integer) return integer is + begin + assert false report "VHPI" severity failure; + end behavioural_initialize; - procedure behavioural_read (val: out std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer; reload: integer) is - begin - assert false report "VHPI" severity failure; - end behavioural_read; + procedure behavioural_read (val: out std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer; reload: integer) is + begin + assert false report "VHPI" severity failure; + end behavioural_read; - procedure behavioural_write (val: std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer) is - begin - assert false report "VHPI" severity failure; - end behavioural_write; + procedure behavioural_write (val: std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer) is + begin + assert false report "VHPI" severity failure; + end behavioural_write; end simple_ram_behavioural_helpers; diff --git a/simple_ram_behavioural_tb.vhdl b/simple_ram_behavioural_tb.vhdl index 9523cd1..1527801 100644 --- a/simple_ram_behavioural_tb.vhdl +++ b/simple_ram_behavioural_tb.vhdl @@ -9,225 +9,233 @@ entity simple_ram_behavioural_tb is end simple_ram_behavioural_tb; architecture behave of simple_ram_behavioural_tb is - signal clk : std_ulogic; - signal rst : std_ulogic := '1'; + signal clk : std_ulogic; + signal rst : std_ulogic := '1'; - constant clk_period : time := 10 ns; + constant clk_period : time := 10 ns; - signal w_in : wishbone_slave_out; - signal w_out : wishbone_master_out; + signal w_in : wishbone_slave_out; + signal w_out : wishbone_master_out; begin - simple_ram_0: entity work.mw_soc_memory - generic map ( RAM_INIT_FILE => "simple_ram_behavioural_tb.bin", MEMORY_SIZE => 16 ) - port map (clk => clk, rst => rst, wishbone_out => w_in, wishbone_in => w_out); - - clock: process - begin - clk <= '1'; - wait for clk_period / 2; - clk <= '0'; - wait for clk_period / 2; - end process clock; - - stim: process - begin - w_out.adr <= (others => '0'); - w_out.dat <= (others => '0'); - w_out.cyc <= '0'; - w_out.stb <= '0'; - w_out.sel <= (others => '0'); - w_out.we <= '0'; - - wait for clk_period; - rst <= '0'; - - wait for clk_period; - - w_out.cyc <= '1'; - - -- test various read lengths and alignments - w_out.stb <= '1'; - w_out.sel <= "00000001"; - w_out.adr <= x"0000000000000000"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat(7 downto 0) = x"00" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "00000001"; - w_out.adr <= x"0000000000000001"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat(7 downto 0) = x"01" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "00000001"; - w_out.adr <= x"0000000000000007"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat(7 downto 0) = x"07" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "00000011"; - w_out.adr <= x"0000000000000000"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat(15 downto 0) = x"0100" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "00000011"; - w_out.adr <= x"0000000000000001"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat(15 downto 0) = x"0201" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "00000011"; - w_out.adr <= x"0000000000000007"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat(15 downto 0) = x"0807" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "00001111"; - w_out.adr <= x"0000000000000000"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat(31 downto 0) = x"03020100" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "00001111"; - w_out.adr <= x"0000000000000001"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat(31 downto 0) = x"04030201" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "00001111"; - w_out.adr <= x"0000000000000007"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat(31 downto 0) = x"0A090807" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "11111111"; - w_out.adr <= x"0000000000000000"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat(63 downto 0) = x"0706050403020100" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "11111111"; - w_out.adr <= x"0000000000000001"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat(63 downto 0) = x"0807060504030201" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "11111111"; - w_out.adr <= x"0000000000000007"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat(63 downto 0) = x"0E0D0C0B0A090807" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - -- test various write lengths and alignments - w_out.stb <= '1'; - w_out.sel <= "00000001"; - w_out.adr <= x"0000000000000000"; - w_out.we <= '1'; - w_out.dat(7 downto 0) <= x"0F"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "00000001"; - w_out.adr <= x"0000000000000000"; - w_out.we <= '0'; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat(7 downto 0) = x"0F" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "11111111"; - w_out.adr <= x"0000000000000007"; - w_out.we <= '1'; - w_out.dat <= x"BADC0FFEBADC0FFE"; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - w_out.stb <= '1'; - w_out.sel <= "11111111"; - w_out.adr <= x"0000000000000007"; - w_out.we <= '0'; - assert w_in.ack = '0'; - wait for clk_period; - assert w_in.ack = '1'; - assert w_in.dat = x"BADC0FFEBADC0FFE" report to_hstring(w_in.dat); - w_out.stb <= '0'; - wait for clk_period; - assert w_in.ack = '0'; - - assert false report "end of test" severity failure; - wait; - end process; + simple_ram_0: entity work.mw_soc_memory + generic map ( + RAM_INIT_FILE => "simple_ram_behavioural_tb.bin", + MEMORY_SIZE => 16 + ) + port map ( + clk => clk, + rst => rst, + wishbone_out => w_in, + wishbone_in => w_out + ); + + clock: process + begin + clk <= '1'; + wait for clk_period / 2; + clk <= '0'; + wait for clk_period / 2; + end process clock; + + stim: process + begin + w_out.adr <= (others => '0'); + w_out.dat <= (others => '0'); + w_out.cyc <= '0'; + w_out.stb <= '0'; + w_out.sel <= (others => '0'); + w_out.we <= '0'; + + wait for clk_period; + rst <= '0'; + + wait for clk_period; + + w_out.cyc <= '1'; + + -- test various read lengths and alignments + w_out.stb <= '1'; + w_out.sel <= "00000001"; + w_out.adr <= x"0000000000000000"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat(7 downto 0) = x"00" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "00000001"; + w_out.adr <= x"0000000000000001"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat(7 downto 0) = x"01" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "00000001"; + w_out.adr <= x"0000000000000007"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat(7 downto 0) = x"07" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "00000011"; + w_out.adr <= x"0000000000000000"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat(15 downto 0) = x"0100" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "00000011"; + w_out.adr <= x"0000000000000001"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat(15 downto 0) = x"0201" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "00000011"; + w_out.adr <= x"0000000000000007"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat(15 downto 0) = x"0807" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "00001111"; + w_out.adr <= x"0000000000000000"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat(31 downto 0) = x"03020100" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "00001111"; + w_out.adr <= x"0000000000000001"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat(31 downto 0) = x"04030201" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "00001111"; + w_out.adr <= x"0000000000000007"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat(31 downto 0) = x"0A090807" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "11111111"; + w_out.adr <= x"0000000000000000"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat(63 downto 0) = x"0706050403020100" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "11111111"; + w_out.adr <= x"0000000000000001"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat(63 downto 0) = x"0807060504030201" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "11111111"; + w_out.adr <= x"0000000000000007"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat(63 downto 0) = x"0E0D0C0B0A090807" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + -- test various write lengths and alignments + w_out.stb <= '1'; + w_out.sel <= "00000001"; + w_out.adr <= x"0000000000000000"; + w_out.we <= '1'; + w_out.dat(7 downto 0) <= x"0F"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "00000001"; + w_out.adr <= x"0000000000000000"; + w_out.we <= '0'; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat(7 downto 0) = x"0F" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "11111111"; + w_out.adr <= x"0000000000000007"; + w_out.we <= '1'; + w_out.dat <= x"BADC0FFEBADC0FFE"; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + w_out.stb <= '1'; + w_out.sel <= "11111111"; + w_out.adr <= x"0000000000000007"; + w_out.we <= '0'; + assert w_in.ack = '0'; + wait for clk_period; + assert w_in.ack = '1'; + assert w_in.dat = x"BADC0FFEBADC0FFE" report to_hstring(w_in.dat); + w_out.stb <= '0'; + wait for clk_period; + assert w_in.ack = '0'; + + assert false report "end of test" severity failure; + wait; + end process; end behave;