test_ldst_pi.py: add dcache regression and random test from test_dcache.py
[soc.git] / src / soc / experiment / cache_ram.py
index 848582a6611c00cc32b254ffec53f757cae81282..50ee1367cc84301bcf9cecf0f6cae51d13273227 100644 (file)
@@ -1,80 +1,60 @@
-# entity cache_ram is
-#     generic(
-#      ROW_BITS : integer := 16;
-#      WIDTH    : integer := 64;
-#      TRACE    : boolean := false;
-#      ADD_BUF  : boolean := false
-#      );
-# 
-#     port(
-#      clk     : in  std_logic;
-#      rd_en   : in  std_logic;
-#      rd_addr : in  std_logic_vector(ROW_BITS - 1 downto 0);
-#      rd_data : out std_logic_vector(WIDTH - 1 downto 0);
-#      wr_sel  : in  std_logic_vector(WIDTH/8 - 1 downto 0);
-#      wr_addr : in  std_logic_vector(ROW_BITS - 1 downto 0);
-#      wr_data : in  std_logic_vector(WIDTH - 1 downto 0)
-#      );
-# 
-# end cache_ram;
-# 
-# architecture rtl of cache_ram is
-#     constant SIZE : integer := 2**ROW_BITS;
-# 
-#     type ram_type is array (0 to SIZE - 1) of std_logic_vector(WIDTH - 1 downto 0);
-#     signal ram : ram_type;
-#     attribute ram_style : string;
-#     attribute ram_style of ram : signal is "block";
-# 
-#     signal rd_data0 : std_logic_vector(WIDTH - 1 downto 0);
-# 
-# begin
-#     process(clk)
-#      variable lbit : integer range 0 to WIDTH - 1;
-#      variable mbit : integer range 0 to WIDTH - 1;
-#      variable widx : integer range 0 to SIZE - 1;
-#      constant sel0 : std_logic_vector(WIDTH/8 - 1 downto 0)
-#             := (others => '0');
-#     begin
-#      if rising_edge(clk) then
-#             with m.If( TRACE then
-#                 with m.If( wr_sel /= sel0 then
-#                     report "write a:" & to_hstring(wr_addr) &
-#                         " sel:" & to_hstring(wr_sel) &
-#                         " dat:" & to_hstring(wr_data);
-#                 end with m.If(;
-#             end with m.If(;
-#             for i in 0 to WIDTH/8-1 loop
-#                 lbit := i * 8;
-#                 mbit := lbit + 7;
-#                 widx := to_integer(unsigned(wr_addr));
-#                 with m.If( wr_sel(i) = '1' then
-#                     ram(widx)(mbit downto lbit) <= wr_data(mbit downto lbit);
-#                 end with m.If(;
-#             end loop;
-#          with m.If( rd_en = '1' then
-#              rd_data0 <= ram(to_integer(unsigned(rd_addr)));
-#              if TRACE then
-#                  report "read a:" & to_hstring(rd_addr) &
-#                      " dat:" & to_hstring(ram(to_integer(unsigned(rd_addr))));
-#              end with m.If(;
-#          end with m.If(;
-#      end with m.If(;
-#     end process;
-# 
-#     buf: with m.If( ADD_BUF generate
-#     begin
-#      process(clk)
-#      begin
-#          with m.If( rising_edge(clk) then
-#              rd_data <= rd_data0;
-#          end with m.If(;
-#      end process;
-#     end generate;
-# 
-#     nobuf: with m.If( not ADD_BUF generate
-#     begin
-#      rd_data <= rd_data0;
-#     end generate;
-# 
-# end;
+# TODO: replace with Memory at some point
+from nmigen import Elaboratable, Signal, Array, Module
+from nmutil.util import Display
+
+class CacheRam(Elaboratable):
+
+    def __init__(self, ROW_BITS=16, WIDTH = 64, TRACE=True, ADD_BUF=False,
+                       ram_num=0):
+        self.ram_num = ram_num # for debug reporting
+        self.ROW_BITS = ROW_BITS
+        self.WIDTH = WIDTH
+        self.TRACE = TRACE
+        self.ADD_BUF = ADD_BUF
+        self.rd_en     = Signal()
+        self.rd_addr   = Signal(ROW_BITS)
+        self.rd_data_o = Signal(WIDTH)
+        self.wr_sel    = Signal(WIDTH//8)
+        self.wr_addr   = Signal(ROW_BITS)
+        self.wr_data   = Signal(WIDTH)
+    def elaborate(self, platform):
+        m = Module()
+        comb, sync = m.d.comb, m.d.sync
+
+        ROW_BITS = self.ROW_BITS
+        WIDTH = self.WIDTH
+        TRACE = self.TRACE
+        ADD_BUF = self.ADD_BUF
+        SIZE = 2**ROW_BITS
+     
+        ram = Array(Signal(WIDTH) for i in range(SIZE))
+        #attribute ram_style of ram : signal is "block";
+     
+        rd_data0 = Signal(WIDTH)
+     
+        with m.If(TRACE):
+            with m.If(self.wr_sel.bool()):
+                sync += Display( "write ramno %d a: %%x "
+                                 "sel: %%x dat: %%x" % self.ram_num,
+                                self.wr_addr,
+                                self.wr_sel, self.wr_data)
+        for i in range(WIDTH//8):
+            lbit = i * 8;
+            mbit = lbit + 8;
+            with m.If(self.wr_sel[i]):
+                sync += ram[self.wr_addr][lbit:mbit].eq(self.wr_data[lbit:mbit])
+        with m.If(self.rd_en):
+            sync += rd_data0.eq(ram[self.rd_addr])
+            if TRACE:
+                sync += Display("read ramno %d a: %%x dat: %%x" % self.ram_num,
+                                self.rd_addr, ram[self.rd_addr])
+                pass
+
+
+        if ADD_BUF:
+            sync += self.rd_data_o.eq(rd_data0)
+        else:
+            comb += self.rd_data_o.eq(rd_data0)
+
+        return m