icache.py add test_icache and icache_sim derived from icache_tb.vhdl
authorCole Poirier <colepoirier@gmail.com>
Fri, 11 Sep 2020 00:46:49 +0000 (17:46 -0700)
committerCole Poirier <colepoirier@gmail.com>
Fri, 11 Sep 2020 00:46:49 +0000 (17:46 -0700)
src/soc/experiment/icache.py

index 4fad5a2b295334cee796f46017a9071afb66efcf..ae642ec0a34b229bb87096b14976b272695744a8 100644 (file)
@@ -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()