From 1462c244189e07b294771ba71da76ce94aa48f9d Mon Sep 17 00:00:00 2001 From: Cole Poirier Date: Thu, 10 Sep 2020 17:46:49 -0700 Subject: [PATCH] icache.py add test_icache and icache_sim derived from icache_tb.vhdl --- src/soc/experiment/icache.py | 227 +++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) diff --git a/src/soc/experiment/icache.py b/src/soc/experiment/icache.py index 4fad5a2b..ae642ec0 100644 --- a/src/soc/experiment/icache.py +++ b/src/soc/experiment/icache.py @@ -1377,3 +1377,230 @@ class ICache(Elaboratable): # end process; # end generate; + +# icache_tb.vhdl +# +# library ieee; +# use ieee.std_logic_1164.all; +# +# library work; +# use work.common.all; +# use work.wishbone_types.all; +# +# entity icache_tb is +# end icache_tb; +# +# architecture behave of icache_tb is +# signal clk : std_ulogic; +# signal rst : std_ulogic; +# +# signal i_out : Fetch1ToIcacheType; +# signal i_in : IcacheToDecode1Type; +# +# signal m_out : MmuToIcacheType; +# +# signal wb_bram_in : wishbone_master_out; +# signal wb_bram_out : wishbone_slave_out; +# +# constant clk_period : time := 10 ns; +# begin +# icache0: entity work.icache +# generic map( +# LINE_SIZE => 64, +# NUM_LINES => 4 +# ) +# port map( +# clk => clk, +# rst => rst, +# i_in => i_out, +# i_out => i_in, +# m_in => m_out, +# stall_in => '0', +# flush_in => '0', +# inval_in => '0', +# wishbone_out => wb_bram_in, +# wishbone_in => wb_bram_out +# ); +# +# -- BRAM Memory slave +# bram0: entity work.wishbone_bram_wrapper +# generic map( +# MEMORY_SIZE => 1024, +# RAM_INIT_FILE => "icache_test.bin" +# ) +# port map( +# clk => clk, +# rst => rst, +# wishbone_in => wb_bram_in, +# wishbone_out => wb_bram_out +# ); +# +# clk_process: process +# begin +# clk <= '0'; +# wait for clk_period/2; +# clk <= '1'; +# wait for clk_period/2; +# end process; +# +# rst_process: process +# begin +# rst <= '1'; +# wait for 2*clk_period; +# rst <= '0'; +# wait; +# end process; +# +# stim: process +# begin +# i_out.req <= '0'; +# i_out.nia <= (others => '0'); +# i_out.stop_mark <= '0'; +# +# m_out.tlbld <= '0'; +# m_out.tlbie <= '0'; +# m_out.addr <= (others => '0'); +# m_out.pte <= (others => '0'); +# +# wait until rising_edge(clk); +# wait until rising_edge(clk); +# wait until rising_edge(clk); +# wait until rising_edge(clk); +# +# i_out.req <= '1'; +# i_out.nia <= x"0000000000000004"; +# +# wait for 30*clk_period; +# wait until rising_edge(clk); +# +# assert i_in.valid = '1' severity failure; +# assert i_in.insn = x"00000001" +# report "insn @" & to_hstring(i_out.nia) & +# "=" & to_hstring(i_in.insn) & +# " expected 00000001" +# severity failure; +# +# i_out.req <= '0'; +# +# wait until rising_edge(clk); +# +# -- hit +# i_out.req <= '1'; +# i_out.nia <= x"0000000000000008"; +# wait until rising_edge(clk); +# wait until rising_edge(clk); +# assert i_in.valid = '1' severity failure; +# assert i_in.insn = x"00000002" +# report "insn @" & to_hstring(i_out.nia) & +# "=" & to_hstring(i_in.insn) & +# " expected 00000002" +# severity failure; +# wait until rising_edge(clk); +# +# -- another miss +# i_out.req <= '1'; +# i_out.nia <= x"0000000000000040"; +# +# wait for 30*clk_period; +# wait until rising_edge(clk); +# +# assert i_in.valid = '1' severity failure; +# assert i_in.insn = x"00000010" +# report "insn @" & to_hstring(i_out.nia) & +# "=" & to_hstring(i_in.insn) & +# " expected 00000010" +# severity failure; +# +# -- test something that aliases +# i_out.req <= '1'; +# i_out.nia <= x"0000000000000100"; +# wait until rising_edge(clk); +# wait until rising_edge(clk); +# assert i_in.valid = '0' severity failure; +# wait until rising_edge(clk); +# +# wait for 30*clk_period; +# wait until rising_edge(clk); +# +# assert i_in.valid = '1' severity failure; +# assert i_in.insn = x"00000040" +# report "insn @" & to_hstring(i_out.nia) & +# "=" & to_hstring(i_in.insn) & +# " expected 00000040" +# severity failure; +# +# i_out.req <= '0'; +# +# std.env.finish; +# end process; +# end; +def icache_sim(dut): + i_out, i_in, m_out, m_in = dut.i_out, dut.i_in, dut.m_out, dut.m_in + + yield i_out.req.eq(0) + yield i_out.nia.eq(~1) + yield i_out.stop_mark.eq(0) + yield m_out.tlbld.eq(0) + yield m_out.tlbie.eq(0) + yield m_out.addr.eq(~1) + yield m_out.pte.eq(~1) + yield + yield + yield + yield + yield i_out.req.eq(1) + yield i_out.nia.eq(Const(0x0000000000000004, 64)) + for i in range(30): + yield + yield + assert i_in.valid + assert i_in.insn == Const(0x00000001, 32) \ + f"insn @{i_out.nia}={i_in.insn} expected 00000001" + yield i_out.req.eq(0) + yield + + # hit + yield i_out.req.eq(1) + yield i_out.nia.eq(Const(0x0000000000000008, 64)) + yield + yield + assert i_in.valid + assert i_in.insn == Const(0x00000002, 32) \ + f"insn @{i_out.nia}={i_in.insn} expected 00000002" + yield + + # another miss + yield i_out.req(1) + yield i_out.nia.eq(Const(0x0000000000000040, 64)) + for i in range(30): + yield + yield + assert i_in.valid + assert i_in.insn == Const(0x00000010, 32) \ + f"insn @{i_out.nia}={i_in.insn} expected 00000010" + + # test something that aliases + yield i_out.req.eq(1) + yield i_out.nia.eq(Const(0x0000000000000100, 64)) + yield + yield + assert i_in.valid + for i in range(30): + yield + yield + assert i_in.valid + assert i_in.insn == Const(0x00000040, 32) \ + f"insn @{i_out.nia}={i_in.insn} expected 00000040" + yield i_out.req.eq(0) + + +def test_icache(): + dut = ICache() + vl = rtlil.convert(dut, ports=[]) + with open("test_icache.il", "w") as f: + f.write(vl) + + #run_simulation(dut, icache_sim(), vcd_name='test_icache.vcd') + +if __name__ == '__main__': + test_icache() -- 2.30.2