diff --git a/libraries/base/common/src/vhdl/common_ram_rw_rw.vhd b/libraries/base/common/src/vhdl/common_ram_rw_rw.vhd index 5c333e54056b31e78ac718e495a8ddde09ab4440..4a2740b82e22215a7acbc6da526b0df18f0b119a 100644 --- a/libraries/base/common/src/vhdl/common_ram_rw_rw.vhd +++ b/libraries/base/common/src/vhdl/common_ram_rw_rw.vhd @@ -1,34 +1,49 @@ -------------------------------------------------------------------------------- +-- ----------------------------------------------------------------------------- -- --- Copyright (C) 2014 +-- Copyright 2014-2023 -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands -- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at -- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. +-- http://www.apache.org/licenses/LICENSE-2.0 -- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. -- -------------------------------------------------------------------------------- +-- ----------------------------------------------------------------------------- +-- +-- Author: +-- - +-- Changed by: +-- D.F. Brouwer +-- Description: +-- This a true dual port ram that only uses one clock domain +-- Remarks: +-- The crw_crw RAM covers all other variants, which were utilized by other +-- common RAM variant files. However, because the crw_crw IP is no longer +-- supported as it was previously used for previous FPGA technology identifiers +-- (device types) by the Agilex 7 (agi027_xxxx), the rw_rw IP should be used. +-- As a result, this file has been modified. [1] +-- Reference: +-- [1] Based on the architecture of common_ram_crw_crw.vhd. -library IEEE, technology_lib; +library IEEE, technology_lib, tech_memory_lib; use IEEE.std_logic_1164.all; +use work.common_pkg.all; use work.common_mem_pkg.all; use technology_lib.technology_select_pkg.all; entity common_ram_rw_rw is generic ( - g_technology : natural := c_tech_select_default; - g_ram : t_c_mem := c_mem_ram; - g_init_file : string := "UNUSED"; + g_technology : natural := c_tech_select_default; + g_ram : t_c_mem := c_mem_ram; + g_init_file : string := "UNUSED"; g_true_dual_port : boolean := true ); port ( @@ -51,34 +66,127 @@ entity common_ram_rw_rw is end common_ram_rw_rw; architecture str of common_ram_rw_rw is + constant c_rd_latency : natural := sel_a_b(g_ram.latency < 2, g_ram.latency, 2); -- handle read latency 1 or 2 in RAM + constant c_pipeline : natural := sel_a_b(g_ram.latency > c_rd_latency, g_ram.latency - c_rd_latency, 0); -- handle rest of read latency > 2 in pipeline + + -- Intermediate signal for extra pipelining + signal ram_rd_dat_a : std_logic_vector(rd_dat_a'range); + signal ram_rd_dat_b : std_logic_vector(rd_dat_b'range); + + -- Map sl to single bit slv for rd_val pipelining + signal ram_rd_en_a : std_logic_vector(0 downto 0); + signal ram_rd_en_b : std_logic_vector(0 downto 0); + signal ram_rd_val_a : std_logic_vector(0 downto 0); + signal ram_rd_val_b : std_logic_vector(0 downto 0); begin - -- Use only one clock domain + assert g_ram.latency >= 1 + report "common_ram_rw_rw : only support read latency >= 1" + severity FAILURE; + + -- memory access + gen_true_dual_port : if g_true_dual_port = true generate + u_ram : entity tech_memory_lib.tech_memory_ram_rw_rw + generic map ( + g_technology => g_technology, + g_adr_w => g_ram.adr_w, + g_dat_w => g_ram.dat_w, + g_nof_words => g_ram.nof_dat, + g_rd_latency => c_rd_latency, + g_init_file => g_init_file + ) + port map ( + clock => clk, + enable => clken, + wren_a => wr_en_a, + wren_b => wr_en_b, + data_a => wr_dat_a, + data_b => wr_dat_b, + address_a => adr_a, + address_b => adr_b, + q_a => ram_rd_dat_a, + q_b => ram_rd_dat_b + ); + end generate; + + gen_simple_dual_port : if g_true_dual_port = false generate + u_ram : entity tech_memory_lib.tech_memory_ram_r_w + generic map ( + g_technology => g_technology, + g_adr_w => g_ram.adr_w, + g_dat_w => g_ram.dat_w, + g_nof_words => g_ram.nof_dat, + g_rd_latency => c_rd_latency, + g_init_file => g_init_file + ) + port map + ( + clock => clk, + enable => clken, + wren => wr_en_a, + wraddress => adr_a, + data => wr_dat_a, + rdaddress => adr_b, + q => ram_rd_dat_b + ); + end generate; + + -- read output + u_pipe_a : entity work.common_pipeline + generic map ( + g_pipeline => c_pipeline, + g_in_dat_w => g_ram.dat_w, + g_out_dat_w => g_ram.dat_w + ) + port map ( + clk => clk, + clken => clken, + in_dat => ram_rd_dat_a, + out_dat => rd_dat_a + ); + + u_pipe_b : entity work.common_pipeline + generic map ( + g_pipeline => c_pipeline, + g_in_dat_w => g_ram.dat_w, + g_out_dat_w => g_ram.dat_w + ) + port map ( + clk => clk, + clken => clken, + in_dat => ram_rd_dat_b, + out_dat => rd_dat_b + ); + + -- rd_val control + ram_rd_en_a(0) <= rd_en_a; + ram_rd_en_b(0) <= rd_en_b; + + rd_val_a <= ram_rd_val_a(0); + rd_val_b <= ram_rd_val_b(0); + + u_rd_val_a : entity work.common_pipeline + generic map ( + g_pipeline => g_ram.latency, + g_in_dat_w => 1, + g_out_dat_w => 1 + ) + port map ( + clk => clk, + clken => clken, + in_dat => ram_rd_en_a, + out_dat => ram_rd_val_a + ); - u_crw_crw : entity work.common_ram_crw_crw + u_rd_val_b : entity work.common_pipeline generic map ( - g_technology => g_technology, - g_ram => g_ram, - g_init_file => g_init_file, - g_true_dual_port => g_true_dual_port + g_pipeline => g_ram.latency, + g_in_dat_w => 1, + g_out_dat_w => 1 ) port map ( - rst_a => rst, - rst_b => rst, - clk_a => clk, - clk_b => clk, - clken_a => clken, - clken_b => clken, - wr_en_a => wr_en_a, - wr_en_b => wr_en_b, - wr_dat_a => wr_dat_a, - wr_dat_b => wr_dat_b, - adr_a => adr_a, - adr_b => adr_b, - rd_en_a => rd_en_a, - rd_en_b => rd_en_b, - rd_dat_a => rd_dat_a, - rd_dat_b => rd_dat_b, - rd_val_a => rd_val_a, - rd_val_b => rd_val_b + clk => clk, + clken => clken, + in_dat => ram_rd_en_b, + out_dat => ram_rd_val_b ); end str;