]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
replace block memory in circular buffer with ip from Lattice.
authorTobias Weber <toweber86@gmail.com>
Thu, 19 Jul 2018 13:28:27 +0000 (15:28 +0200)
committerTobias Weber <toweber86@gmail.com>
Thu, 19 Jul 2018 13:28:27 +0000 (15:28 +0200)
mupix/Mupix8/sources/Datapath/CircularMemory.vhd
mupix/Mupix8/sources/Datapath/MupixTRBReadout.vhd
mupix/Mupix8/tb/MupixTRBReadoutTest.vhd
mupix/Mupix8/trb3_periph.prj

index b929e249d345c34fb7ee939c47264fb8e5284c96..ea0d02d75da86dedbfba575b35d0d230858f5014 100644 (file)
@@ -10,215 +10,211 @@ use ieee.numeric_std.all;
 use work.StdTypes.all;
 
 entity CircularMemory is
-       generic(
-               g_datawidth    : integer := 32; -- width of data words
-               g_addresswidth : integer := 10; -- width of address pointers, number of words is 2**g_addresswidth
-               g_clockspeed   : integer := 1e8; -- FPGA clock speed in Hz
-               g_boundedbuf   : boolean := false -- stop writing when buffer is full (FIFO mode)
-       );
-       port(
-               clk          : in  std_logic;   -- clock input
-               rst          : in  std_logic;   -- reset 
-               wr_en        : in  std_logic;   -- write enable
-               data_in      : in  std_logic_vector(g_datawidth - 1 downto 0); -- input word
-               rd_en        : in  std_logic;   --read enable
-               offset_en    : in  std_logic;  -- set offset between write and read pointer
-               offset       : in  std_logic_vector(g_addresswidth - 1 downto 0); -- read - write pointer offset
-               data_out     : out std_logic_vector(g_datawidth - 1 downto 0); -- output word
-               empty        : out std_logic;   --empty flag
-               full         : out std_logic;   --full flag
-               almost_empty : out std_logic;   --one more word remaining in buffer
-               almost_full  : out std_logic;   --one more word to write before buffer overflow
-               fillcnt      : out std_logic_vector(g_addresswidth downto 0); -- number of words in circular buffer
-               inword_freq  : out std_logic_vector(31 downto 0); -- number of input words per second
-               outword_freq : out std_logic_vector(31 downto 0) -- number of output words per second
-       );
+  generic(
+    g_datawidth    : integer := 32;     -- width of data words
+    g_addresswidth : integer := 10;  -- width of address pointers, number of words is 2**g_addresswidth
+    g_clockspeed   : integer := 1e8;    -- FPGA clock speed in Hz
+    g_boundedbuf   : boolean := false  -- stop writing when buffer is full (FIFO mode)
+    );
+  port(
+    clk          : in  std_logic;       -- clock input
+    rst          : in  std_logic;       -- reset 
+    wr_en        : in  std_logic;       -- write enable
+    data_in      : in  std_logic_vector(g_datawidth - 1 downto 0);  -- input word
+    rd_en        : in  std_logic;       --read enable
+    offset_en    : in  std_logic;  -- set offset between write and read pointer
+    offset       : in  std_logic_vector(g_addresswidth - 1 downto 0);  -- read - write pointer offset
+    data_out     : out std_logic_vector(g_datawidth - 1 downto 0);  -- output word
+    empty        : out std_logic;       --empty flag
+    full         : out std_logic;       --full flag
+    almost_empty : out std_logic;       --one more word remaining in buffer
+    almost_full  : out std_logic;  --one more word to write before buffer overflow
+    fillcnt      : out std_logic_vector(g_addresswidth downto 0);  -- number of words in circular buffer
+    inword_freq  : out std_logic_vector(31 downto 0);  -- number of input words per second
+    outword_freq : out std_logic_vector(31 downto 0)  -- number of output words per second
+    );
 end entity CircularMemory;
 
 architecture RTL of CircularMemory is
-       
-       component BlockMemory
-               generic(
-                       DataWidth    : integer := 10;
-                       AddressWidth : integer := 10
-               );
-               port(
-                       clk    : in  std_logic;
-                       reset  : in  std_logic;
-                       WrEn   : in  std_logic;
-                       WrAddr : in  std_logic_vector(AddressWidth - 1 downto 0);
-                       Din    : in  std_logic_vector(DataWidth - 1 downto 0);
-                       ReAddr : in  std_logic_vector(AddressWidth - 1 downto 0);
-                       Dout   : out std_logic_vector(DataWidth - 1 downto 0)
-               );
-       end component BlockMemory;
-       
-       --counters for write/read frequency
-       signal ticks_counter                   : unsigned(f_log2(g_clockspeed) - 1 downto 0) := (others => '0');
-       signal inword_counter, outword_counter : unsigned(31 downto 0)                       := (others => '0');
-
-       --read and write pointers
-       constant c_high_address          : integer                               := 2**g_addresswidth;
-       signal readpointer               : integer range 0 to c_high_address - 1 := 0;
-       signal writepointer              : integer range 0 to c_high_address - 1 := 0;
-       signal words_in_buffer           : integer range 0 to c_high_address     := 0;
-       signal read_write_pointer_offset : integer range -(c_high_address - 1) to c_high_address - 1 := 0;
-
-       --wires to block memory
-       signal WrEn_mem   : std_logic;
-       signal WrAddr_mem : std_logic_vector(g_addresswidth - 1 downto 0);
-       signal Din_mem    : std_logic_vector(g_datawidth - 1 downto 0);
-       signal ReAddr_mem : std_logic_vector(g_addresswidth - 1 downto 0);
-       signal Dout_mem   : std_logic_vector(g_datawidth - 1 downto 0);
-
-       signal empty_i          : std_logic;
-       signal full_i           : std_logic;
-       signal rd_en_i          : std_logic;
-       signal wr_en_i          : std_logic;
-       signal increment_wd_cnt : std_logic := '0';
-       signal decrement_wd_cnt : std_logic := '0';
-       
+
+  component RAM_DP_4096_32 is
+    port (
+      WrAddress : in  std_logic_vector(11 downto 0);
+      RdAddress : in  std_logic_vector(11 downto 0);
+      Data      : in  std_logic_vector(31 downto 0);
+      WE        : in  std_logic;
+      RdClock   : in  std_logic;
+      RdClockEn : in  std_logic;
+      Reset     : in  std_logic;
+      WrClock   : in  std_logic;
+      WrClockEn : in  std_logic;
+      Q         : out std_logic_vector(31 downto 0));
+  end component RAM_DP_4096_32;
+
+  --counters for write/read frequency
+  signal ticks_counter                   : unsigned(f_log2(g_clockspeed) - 1 downto 0) := (others => '0');
+  signal inword_counter, outword_counter : unsigned(31 downto 0)                       := (others => '0');
+
+  --read and write pointers
+  constant c_high_address          : integer                                                   := 2**g_addresswidth;
+  signal readpointer               : integer range 0 to c_high_address - 1                     := 0;
+  signal writepointer              : integer range 0 to c_high_address - 1                     := 0;
+  signal words_in_buffer           : integer range 0 to c_high_address                         := 0;
+  signal read_write_pointer_offset : integer range -(c_high_address - 1) to c_high_address - 1 := 0;
+
+  --wires to block memory
+  signal WrEn_mem   : std_logic;
+  signal WrAddr_mem : std_logic_vector(g_addresswidth - 1 downto 0);
+  signal Din_mem    : std_logic_vector(g_datawidth - 1 downto 0);
+  signal ReAddr_mem : std_logic_vector(g_addresswidth - 1 downto 0);
+  signal Dout_mem   : std_logic_vector(g_datawidth - 1 downto 0);
+
+  signal empty_i          : std_logic;
+  signal full_i           : std_logic;
+  signal rd_en_i          : std_logic;
+  signal wr_en_i          : std_logic;
+  signal increment_wd_cnt : std_logic := '0';
+  signal decrement_wd_cnt : std_logic := '0';
+
 begin
-       
-       memory : entity work.BlockMemory
-               generic map(
-                       DataWidth    => g_datawidth,
-                       AddressWidth => g_addresswidth
-               )
-               port map(
-                       clk    => clk,
-                       reset  => rst,
-                       WrEn   => WrEn_mem,
-                       WrAddr => WrAddr_mem,
-                       Din    => Din_mem,
-                       ReAddr => ReAddr_mem,
-                       Dout   => Dout_mem
-               );
-               
-       write_proc : process(clk) is
-       begin
-               if rising_edge(clk) then
-                       if rst = '1' then
-                               writepointer     <= 0;
-                               increment_wd_cnt <= '0';
-                       else
-                               if wr_en_i = '1' then
-                                       increment_wd_cnt <= '1';
-                                       if writepointer = c_high_address - 1 then
-                                               writepointer <= 0;
-                                       else
-                                               writepointer <= writepointer + 1;
-                                       end if;
-                               else
-                                       writepointer     <= writepointer;
-                                       increment_wd_cnt <= '0';
-                               end if;
-                       end if;
-               end if;
-       end process write_proc;
-       
-       WrAddr_mem <= std_logic_vector(to_unsigned(writepointer, g_addresswidth));
-       Din_mem    <= data_in;
-       WrEn_mem   <= wr_en_i;
-
-       read_write_offset_proc : process(offset, writepointer) is
-       begin
-               read_write_pointer_offset <= writepointer - to_integer(unsigned(offset)) after 2 ns;
-       end process read_write_offset_proc;
-
-       read_proc : process(clk) is
-       begin
-               if rising_edge(clk) then
-                       if rst = '1' then
-                               readpointer      <= 0;
-                               decrement_wd_cnt <= '0';
-                       else
-                               if offset_en = '1' then
-                                       if read_write_pointer_offset >= 0 then
-                                               readpointer <= read_write_pointer_offset;
-                                       else
-                                               readpointer <= c_high_address + read_write_pointer_offset;
-                                       end if;
-                               elsif rd_en_i = '1' then
-                                       decrement_wd_cnt <= '1';
-                                       if readpointer = c_high_address - 1 then
-                                               readpointer <= 0;
-                                       else
-                                               readpointer <= readpointer + 1;
-                                       end if;
-                               else
-                                       decrement_wd_cnt <= '0';
-                                       readpointer      <= readpointer;
-                               end if;
-                       end if;
-               end if;
-       end process read_proc;
-       
-       ReAddr_mem <= std_logic_vector(to_unsigned(readpointer, g_addresswidth));
-       
-       word_counter_proc : process(clk) is
-       begin
-               if rising_edge(clk) then
-                       if rst = '1' then
-                               words_in_buffer <= 0;
-                       elsif offset_en = '1' then
-                               words_in_buffer <= to_integer(unsigned(offset));
-                       else
-                               words_in_buffer <= words_in_buffer;
-                               if increment_wd_cnt = '1' and decrement_wd_cnt = '0' then
-                                       if words_in_buffer < c_high_address then
-                                               words_in_buffer <= words_in_buffer + 1;
-                                       else
-                                               words_in_buffer <= words_in_buffer;
-                                       end if;
-                               elsif increment_wd_cnt = '0' and decrement_wd_cnt = '1' then
-                                       if words_in_buffer > 0 then
-                                               words_in_buffer <= words_in_buffer - 1;
-                                       else
-                                               words_in_buffer <= 0;
-                                       end if;
-                               end if;
-                       end if;
-               end if;
-       end process word_counter_proc;
-       
-       throughput_proc : process (clk) is
-       begin
-               if rising_edge(clk) then
-                       if rst = '1' then
-                               ticks_counter <= (others => '0');
-                               inword_counter <= (others => '0');
-                               outword_counter <= (others => '0');
-                       else
-                               if wr_en = '1' then
-                                       inword_counter <= inword_counter + 1;
-                               end if;
-                               if rd_en = '1' then
-                                       outword_counter <= outword_counter + 1;
-                               end if;
-                               if ticks_counter = g_clockspeed - 1 then
-                                       ticks_counter <= (others => '0');
-                                       inword_counter <= (others => '0');
-                                       outword_counter <= (others => '0');
-                                       inword_freq <= std_logic_vector(inword_counter);
-                                       outword_freq <= std_logic_vector(outword_counter);
-                               else
-                                       ticks_counter <= ticks_counter + 1;
-                               end if;
-                       end if;
-               end if;
-       end process throughput_proc;
-       
-       empty_i <= '1' when words_in_buffer = 0 else '0';
-       full_i  <= '1' when words_in_buffer = c_high_address else '0';
-       rd_en_i <= not empty_i and rd_en;
-       wr_en_i <= (wr_en and not full_i) when g_boundedbuf = true else wr_en; 
-       
-       empty        <= empty_i;
-       almost_empty <= '1' when (words_in_buffer < 3) else '0';
-       full         <= full_i;
-       almost_full  <= '1' when words_in_buffer >= c_high_address - 1 else '0';
-       fillcnt      <= std_logic_vector(to_unsigned(words_in_buffer, g_addresswidth + 1));
-       data_out     <= Dout_mem;
-       
+
+  RAM_DP_4096_32_1: entity work.RAM_DP_4096_32
+    port map (
+      WrAddress => WrAddr_mem,
+      RdAddress => ReAddr_mem,
+      Data      => Din_mem,
+      WE        => WrEn_mem,
+      RdClock   => clk,
+      RdClockEn => '1',
+      Reset     => rst,
+      WrClock   => clk,
+      WrClockEn => '1',
+      Q         => Dout_mem);
+
+  write_proc : process(clk) is
+  begin
+    if rising_edge(clk) then
+      if rst = '1' then
+        writepointer     <= 0;
+        increment_wd_cnt <= '0';
+      else
+        if wr_en_i = '1' then
+          increment_wd_cnt <= '1';
+          if writepointer = c_high_address - 1 then
+            writepointer <= 0;
+          else
+            writepointer <= writepointer + 1;
+          end if;
+        else
+          writepointer     <= writepointer;
+          increment_wd_cnt <= '0';
+        end if;
+      end if;
+    end if;
+  end process write_proc;
+
+  WrAddr_mem <= std_logic_vector(to_unsigned(writepointer, g_addresswidth));
+  Din_mem    <= data_in;
+  WrEn_mem   <= wr_en_i;
+
+  read_write_offset_proc : process(offset, writepointer) is
+  begin
+    read_write_pointer_offset <= writepointer - to_integer(unsigned(offset)) after 2 ns;
+  end process read_write_offset_proc;
+
+  read_proc : process(clk) is
+  begin
+    if rising_edge(clk) then
+      if rst = '1' then
+        readpointer      <= 0;
+        decrement_wd_cnt <= '0';
+      else
+        if offset_en = '1' then
+          if read_write_pointer_offset >= 0 then
+            readpointer <= read_write_pointer_offset;
+          else
+            readpointer <= c_high_address + read_write_pointer_offset;
+          end if;
+        elsif rd_en_i = '1' then
+          decrement_wd_cnt <= '1';
+          if readpointer = c_high_address - 1 then
+            readpointer <= 0;
+          else
+            readpointer <= readpointer + 1;
+          end if;
+        else
+          decrement_wd_cnt <= '0';
+          readpointer      <= readpointer;
+        end if;
+      end if;
+    end if;
+  end process read_proc;
+
+  ReAddr_mem <= std_logic_vector(to_unsigned(readpointer, g_addresswidth));
+
+  word_counter_proc : process(clk) is
+  begin
+    if rising_edge(clk) then
+      if rst = '1' then
+        words_in_buffer <= 0;
+      elsif offset_en = '1' then
+        words_in_buffer <= to_integer(unsigned(offset));
+      else
+        words_in_buffer <= words_in_buffer;
+        if increment_wd_cnt = '1' and decrement_wd_cnt = '0' then
+          if words_in_buffer < c_high_address then
+            words_in_buffer <= words_in_buffer + 1;
+          else
+            words_in_buffer <= words_in_buffer;
+          end if;
+        elsif increment_wd_cnt = '0' and decrement_wd_cnt = '1' then
+          if words_in_buffer > 0 then
+            words_in_buffer <= words_in_buffer - 1;
+          else
+            words_in_buffer <= 0;
+          end if;
+        end if;
+      end if;
+    end if;
+  end process word_counter_proc;
+
+  throughput_proc : process (clk) is
+  begin
+    if rising_edge(clk) then
+      if rst = '1' then
+        ticks_counter   <= (others => '0');
+        inword_counter  <= (others => '0');
+        outword_counter <= (others => '0');
+      else
+        if wr_en = '1' then
+          inword_counter <= inword_counter + 1;
+        end if;
+        if rd_en = '1' then
+          outword_counter <= outword_counter + 1;
+        end if;
+        if ticks_counter = g_clockspeed - 1 then
+          ticks_counter   <= (others => '0');
+          inword_counter  <= (others => '0');
+          outword_counter <= (others => '0');
+          inword_freq     <= std_logic_vector(inword_counter);
+          outword_freq    <= std_logic_vector(outword_counter);
+        else
+          ticks_counter <= ticks_counter + 1;
+        end if;
+      end if;
+    end if;
+  end process throughput_proc;
+
+  empty_i <= '1'                    when words_in_buffer = 0              else '0';
+  full_i  <= '1'                    when words_in_buffer = c_high_address else '0';
+  rd_en_i <= not empty_i and rd_en;
+  wr_en_i <= (wr_en and not full_i) when g_boundedbuf = true              else wr_en;
+
+  empty        <= empty_i;
+  almost_empty <= '1' when (words_in_buffer < 3)                 else '0';
+  full         <= full_i;
+  almost_full  <= '1' when words_in_buffer >= c_high_address - 1 else '0';
+  fillcnt      <= std_logic_vector(to_unsigned(words_in_buffer, g_addresswidth + 1));
+  data_out     <= Dout_mem;
+
 end architecture RTL;
index 8c992e1edb087e3d2a48195e5ee647c0ccba3aa3..d2421738ce4978cf73500d5601898cabfc47875f 100644 (file)
@@ -9,9 +9,11 @@ use ieee.numeric_std.all;
 
 entity MupixTRBReadout is
   generic(g_mupix_links           : natural := 4;   -- number of input data channels from mupix
-          g_cyc_mem_address_width : integer := 13;  -- memory depth of circular buffer
+          -- memory depth of circularbuffer (should match value of RAM in Circ Buffer)
+          g_cyc_mem_address_width : integer := 12;  
           g_datawidthfifo         : integer := 40;  -- width of data words from fifos
-          g_datawidthtrb          : integer := 32   -- trb data width
+          -- trb data width (should be 32 and match RAM in Circ Buffer)
+          g_datawidthtrb          : integer := 32   
           );
   port(
     clk                  : in  std_logic;  -- clock input
index 702833404f1fb224d2dcbf533067f9150a07408a..2da3c20aac569b232f06f9284996c3ca79c5907a 100644 (file)
@@ -57,7 +57,7 @@ architecture sim of MupixTRBReadoutTest is
 
   constant c_clk_period            : time    := 10 ns;
   constant c_mupix_links           : integer := 4;
-  constant c_cyc_mem_address_width : integer := 6;
+  constant c_cyc_mem_address_width : integer := 12;
   constant c_datawidthfifo         : integer := 40;
   constant c_datawidthtrb          : integer := 32;
 
index 1b9529c51f443f22b542fc60631130bf70322d70..75402e27cb1f76c8a65a73e2cc25a3b2f510fbde 100644 (file)
@@ -149,6 +149,7 @@ add_file -vhdl -lib "work" "cores/mupix_serdes_sim.vhd"
 add_file -vhdl -lib "work" "cores/serdes_fifo.vhd"
 add_file -vhdl -lib "work" "cores/mupix_sim_pll.vhd"
 add_file -vhdl -lib "work" "cores/fifo_sim.vhd"
+add_file -vhdl -lib "work" "cores/RAM_DP_4096_32.vhd"
 
 #MuPix Files
 add_file -vhdl -lib "work" "trb3_periph.vhd"