Skip to content
Snippets Groups Projects
Commit 91d4cc9a authored by Reinier van der Walle's avatar Reinier van der Walle
Browse files

cleanup

parent aaec1ead
No related branches found
No related tags found
1 merge request!327Resolve HPR-85
Pipeline #49206 passed
Showing
with 27 additions and 730 deletions
README.txt for $HDL_WORK/libraries/technology/ip_arria10/fifo
Contents:
1) FIFO components
2) Arria10 IP
3) Implementation options (LUTs or block RAM)
4) Synthesis trials
5) Issues
1) FIFO components:
ip_arria10_fifo_sc = Single clock FIFO
ip_arria10_fifo_dc = Dual clock FIFO
ip_arria10_fifo_dc_mixed_widths = Dual clock FIFO with different read and write data widths (ratio power of 2)
2) Arria10 IP
The IP was ported from Stratix IV by:
. copy original MegaWizard <fifo_name>.vhd file
. rename <fifo_name>.vhd into ip_arria10_<fifo_name>.vhd (also replace name inside the file)
. commit the fifo/ip_arria10_<fifo_name>.vhd to preserve the MegaWizard original
. open in to Quartus 14, set device family to Arria10 and finish automatically convert to Qsys
. then generate HDL (select VHDL for both sim and synth) and finish to save it as ip_arria10_<fifo_name>.qsys
this yields:
ip_arria10_fifo_sc.qsys
ip_arria10_fifo_dc.qsys
ip_arria10_fifo_dc_mixed_widths.qsys
The Arria10 FIFO IP still uses the altera_mf package (so not the altera_lnsim package as with the block RAM). The
FIFOs map to the altera_mf components to scfifo, dcfifo and dcfifo_mixed_widths.
The IP only needs to be generated with ./generate_ip.sh if it need to be modified, because the ip_arria10_fifo_*.vhd
directly instantiates the altera_mf component.
The instantiation is copied manually from the ip_arria10_fifo_*/fifo_140/sim/ip_arria10_fifo_*.vhd and
saved in the <fifo_name>.vhd file. So then the MegaWizard vhd file is overwritten, but that is fine because it is
no longer needed, it could easily be derived from the original in $UNB and it is still as a previous verion in SVN.
3) Implementation options (LUTs or block RAM)
The IP FIFO can be set to use LUTs (MLAB) or block RAM (M20K) via g_use_eab.
4) Synthesis trials
The quartus/fifo.qpf Quartus project was used to verify that the FIFO IP actually synthesise to the appropriate FPGA resources.
Use the Quartus GUI to manually select a top level component for synthesis e.g. by right clicking the entity vhd file
in the file tab of the Quartus project navigator window.
Then check the resource usage in the synthesis and fitter reports.
5) Issues
No issues.
\ No newline at end of file
README.txt for $HDL_WORK/libraries/technology/ip_arria10/ram
Contents:
1) RAM components
2) ROM components
3) Arria10 IP
4) Inferred IP
5) Memory initialisation file
6) Implementation options (LUTs or block RAM)
7) Synthesis trials
1) RAM components:
ip_arria10_ram_crwk_crw = Two read/write ports each port with own port clock and with power of two ratio between port widths
ip_arria10_ram_crw_crw = Two read/write ports each port with own port clock and with same address and data width on both ports
ip_arria10_ram_cr_cw = One read port with clock and one write port with clock and with same address and data width on both ports
ip_arria10_ram_r_w = Single clock, one read port and one write port and with same address and data width on both ports
2) ROM components:
ip_arria10_rom_r_w = Not available and not needed, because the ip_arria10_ram_r_w can be used for ROM IP by not connecting the
write port.
3) Arria10 IP
The IP only needs to be generated with
./generate_ip.sh
if it need to be modified, because the ip_arria10_ram_*.vhd directly instantiates the altera_syncram component.
The instantiation is copied manually from the ip_arria10_ram_*/ram_2port_140/sim/ip_arria10_ram_*.vhd.
It appears that the altera_syncram component can be synthesized even though it comes from the altera_lnsim package,
that is a simulation package. However it resembles how it worked for Straix IV with altera_mf.
4) Inferred IP
The inferred Altera code was obtained using template insert with Quartus 14.0a10.
The ram_crwk_crw can not be inferred.
For the other RAM the g_inferred generic is set to FALSE because the inferred instances do not yet support g_init_file.
It is possible to init the RAM using a function e.g.:
function init_ram
return memory_t is
variable tmp : memory_t := (others => (others => '0'));
begin
for addr_pos in 0 to 2**ADDR_WIDTH - 1 loop
-- Initialize each address with the address itself
tmp(addr_pos) := std_logic_vector(to_unsigned(addr_pos, DATA_WIDTH));
end loop;
return tmp;
end init_ram;
-- Declare the RAM signal and specify a default value. Quartus II
-- will create a memory initialization file (.mif) based on the
-- default value.
signal ram : memory_t := init_ram;
5) Memory initialisation file
To support the g_init_file requires first reading the file in a certain format. For us an integer format or SLV format
with one value per line (line number = address) would be fine. Using SLV format is necessary if the RAM data is wider
than 32 bit, because VHDL integer range is only 2**32. The tb_common_pkg has functiosn to read such a file. Quartus
creates a mif file from this when it infers the RAM. However our current UniBoard1 designs provide a mif file that fits
the RAM IP. Therefore it is easier initially to also use the RAM IP for Arria10. In future for RadioHDL a generic
RAM init file format is preferrable though.
6) Implementation options (LUTs or block RAM)
The IP and inferred RAM can be set to use LUTs (MLAB) or block RAM (M20K), however this is not supported yet.
. For IP RAM this would imply adding a generic to set the appropriate parameter in the altera_syncram
. For inferred RAM is would imply adding a generic to be used for the syntype attribute.
From http://www.alterawiki.com/wiki/Mapping_SRLs_to_registers,_MLABs,_or_Block_RAMs:
entity
g_ramstyle : STRING := "MLAB,no_rw_check"
architecture
attribute ramstyle : string;
signal ram : memory_t := init_ram;
attribute ramstyle of ram : signal is g_ramstyle;
7) Synthesis trials
The quartus/ram.qpf Quartus project was used to verify that the inferred RAM and the block RAM IP actually synthesise
to the appropriate FPGA resources.
Use the Quartus GUI to manually select a top level component for synthesis e.g. by right clicking the entity vhd file
in the file tab of the Quartus project navigator window.
Then check the resource usage in the synthesis and fitter reports.
......@@ -5,7 +5,7 @@ hdl_lib_uses_sim =
hdl_lib_technology = ip_ultrascale
synth_files =
ip_ultrascale_true_dual_port_ram_dual_clock.vhd
# ip_ultrascale_true_dual_port_ram_dual_clock.vhd
# ip_ultrascale_simple_dual_port_ram_dual_clock.vhd
# ip_ultrascale_simple_dual_port_ram_single_clock.vhd
......
-------------------------------------------------------------------------------
--
-- Copyright (C) 2014
-- Copyright 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.
--
-------------------------------------------------------------------------------
-- RadioHDL wrapper
-- Purpose: Instantiate RAM IP with generics
-- Description:
-- Copied component instantiation from Vivado XPM template
LIBRARY ieee;
USE ieee.std_logic_1164.all;
......
-------------------------------------------------------------------------------
--
-- Copyright (C) 2023
-- Copyright 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.
--
-------------------------------------------------------------------------------
-- RadioHDL wrapper
-- Purpose: Instantiate RAM IP with generics
-- Description:
-- Copied component instantiation from Vivado XPM template
LIBRARY ieee;
USE ieee.std_logic_1164.all;
......
-- (C) 2001-2014 Altera Corporation. All rights reserved.
-- Your use of Altera Corporation's design tools, logic functions and other
-- software and tools, and its AMPP partner logic functions, and any output
-- files any of the foregoing (including device programming or simulation
-- files), and any associated documentation or information are expressly subject
-- to the terms and conditions of the Altera Program License Subscription
-- Agreement, Altera MegaCore Function License Agreement, or other applicable
-- license agreement, including, without limitation, that your use is for the
-- sole purpose of programming logic devices manufactured by Altera and sold by
-- Altera or its authorized distributors. Please refer to the applicable
-- agreement for further details.
LIBRARY ieee, technology_lib;
USE ieee.std_logic_1164.all;
USE technology_lib.technology_pkg.all;
LIBRARY altera_lnsim;
USE altera_lnsim.altera_lnsim_components.all;
ENTITY ip_arria10_e2sg_ram_crwk_crw IS
GENERIC (
g_adr_a_w : NATURAL := 5;
g_dat_a_w : NATURAL := 32;
g_adr_b_w : NATURAL := 4;
g_dat_b_w : NATURAL := 64;
g_nof_words_a : NATURAL := 2**5;
g_nof_words_b : NATURAL := 2**4;
g_rd_latency : NATURAL := 1; -- choose 1 or 2
g_init_file : STRING := "UNUSED"
);
PORT
(
address_a : IN STD_LOGIC_VECTOR (g_adr_a_w-1 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (g_adr_b_w-1 DOWNTO 0);
clk_a : IN STD_LOGIC := '1';
clk_b : IN STD_LOGIC ;
data_a : IN STD_LOGIC_VECTOR (g_dat_a_w-1 DOWNTO 0);
data_b : IN STD_LOGIC_VECTOR (g_dat_b_w-1 DOWNTO 0);
wren_a : IN STD_LOGIC := '0';
wren_b : IN STD_LOGIC := '0';
q_a : OUT STD_LOGIC_VECTOR (g_dat_a_w-1 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR (g_dat_b_w-1 DOWNTO 0)
);
END ip_arria10_e2sg_ram_crwk_crw;
ARCHITECTURE SYN OF ip_arria10_e2sg_ram_crwk_crw IS
CONSTANT c_outdata_reg_a : STRING := tech_sel_a_b(g_rd_latency=1, "UNREGISTERED", "CLOCK0");
CONSTANT c_outdata_reg_b : STRING := tech_sel_a_b(g_rd_latency=1, "UNREGISTERED", "CLOCK1");
COMPONENT altera_syncram
GENERIC (
address_reg_b : string;
clock_enable_input_a : string;
clock_enable_input_b : string;
clock_enable_output_a : string;
clock_enable_output_b : string;
indata_reg_b : string;
init_file : string;
init_file_layout : string;
intended_device_family : string;
lpm_type : string;
numwords_a : integer;
numwords_b : integer;
operation_mode : string;
outdata_aclr_a : string;
outdata_aclr_b : string;
outdata_reg_a : string;
outdata_reg_b : string;
power_up_uninitialized : string;
read_during_write_mode_port_a : string;
read_during_write_mode_port_b : string;
widthad_a : integer;
widthad_b : integer;
width_a : integer;
width_b : integer;
width_byteena_a : integer;
width_byteena_b : integer
);
PORT (
address_a : in std_logic_vector(g_adr_a_w-1 downto 0);
address_b : in std_logic_vector(g_adr_b_w-1 downto 0);
clock0 : in std_logic;
clock1 : in std_logic;
data_a : in std_logic_vector(g_dat_a_w-1 downto 0);
data_b : in std_logic_vector(g_dat_b_w-1 downto 0);
wren_a : in std_logic;
wren_b : in std_logic;
q_a : out std_logic_vector(g_dat_a_w - 1 downto 0);
q_b : out std_logic_vector(g_dat_b_w - 1 downto 0)
);
END COMPONENT;
BEGIN
-- Copied from ip_arria10_e2sg_ram_crwk_crw/ram_2port_140/sim/ip_arria10_e2sg_ram_crwk_crw_ram_2port_140_iyfl3wi.vhd
u_altera_syncram : altera_syncram
GENERIC MAP (
address_reg_b => "CLOCK1",
clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS",
clock_enable_output_a => "BYPASS",
clock_enable_output_b => "BYPASS",
indata_reg_b => "CLOCK1",
init_file => g_init_file,
init_file_layout => "PORT_B",
intended_device_family => "Arria 10",
lpm_type => "altera_syncram",
numwords_a => g_nof_words_a,
numwords_b => g_nof_words_b,
operation_mode => "BIDIR_DUAL_PORT",
outdata_aclr_a => "NONE",
outdata_aclr_b => "NONE",
outdata_reg_a => c_outdata_reg_a,
outdata_reg_b => c_outdata_reg_b,
power_up_uninitialized => "FALSE",
read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ",
read_during_write_mode_port_b => "NEW_DATA_NO_NBE_READ",
widthad_a => g_adr_a_w,
widthad_b => g_adr_b_w,
width_a => g_dat_a_w,
width_b => g_dat_b_w,
width_byteena_a => 1,
width_byteena_b => 1
)
PORT MAP (
address_a => address_a,
address_b => address_b,
clock0 => clk_a,
clock1 => clk_b,
data_a => data_a,
data_b => data_b,
wren_a => wren_a,
wren_b => wren_b,
q_a => q_a,
q_b => q_b
);
END SYN;
-------------------------------------------------------------------------------
--
-- Copyright (C) 2014
-- 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.
--
-- 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.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------
-- RadioHDL wrapper
LIBRARY ieee, technology_lib;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE technology_lib.technology_pkg.all;
LIBRARY altera_lnsim;
USE altera_lnsim.altera_lnsim_components.all;
ENTITY ip_arria10_e2sg_ram_r_w IS
GENERIC (
g_inferred : BOOLEAN := FALSE;
g_adr_w : NATURAL := 5;
g_dat_w : NATURAL := 8;
g_nof_words : NATURAL := 2**5;
g_rd_latency : NATURAL := 1; -- choose 1 or 2
g_init_file : STRING := "UNUSED"
);
PORT (
clk : IN STD_LOGIC := '1';
data : IN STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0) := (OTHERS=>'0');
rdaddress : IN STD_LOGIC_VECTOR(g_adr_w-1 DOWNTO 0) := (OTHERS=>'0');
wraddress : IN STD_LOGIC_VECTOR(g_adr_w-1 DOWNTO 0) := (OTHERS=>'0');
wren : IN STD_LOGIC := '0';
q : OUT STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0)
);
END ip_arria10_e2sg_ram_r_w;
ARCHITECTURE SYN OF ip_arria10_e2sg_ram_r_w IS
CONSTANT c_outdata_reg_b : STRING := tech_sel_a_b(g_rd_latency=1, "UNREGISTERED", "CLOCK1");
COMPONENT altera_syncram
GENERIC (
address_aclr_b : string;
address_reg_b : string;
clock_enable_input_a : string;
clock_enable_input_b : string;
clock_enable_output_b : string;
init_file : string;
intended_device_family : string;
lpm_type : string;
numwords_a : integer;
numwords_b : integer;
operation_mode : string;
outdata_aclr_b : string;
outdata_reg_b : string;
power_up_uninitialized : string;
widthad_a : integer;
widthad_b : integer;
width_a : integer;
width_b : integer;
width_byteena_a : integer
);
PORT (
address_a : in std_logic_vector(g_adr_w-1 downto 0);
address_b : in std_logic_vector(g_adr_w-1 downto 0);
clock0 : in std_logic;
data_a : in std_logic_vector(g_dat_w-1 downto 0);
wren_a : in std_logic;
q_b : out std_logic_vector(g_dat_w-1 downto 0)
);
END COMPONENT;
SIGNAL rdaddr : natural range 0 to g_nof_words - 1;
SIGNAL wraddr : natural range 0 to g_nof_words - 1;
SIGNAL out_q : STD_LOGIC_VECTOR (g_dat_w-1 DOWNTO 0);
SIGNAL reg_q : STD_LOGIC_VECTOR (g_dat_w-1 DOWNTO 0);
BEGIN
ASSERT g_rd_latency=1 OR g_rd_latency=2 REPORT "ip_arria10_e2sg_ram_r_w : read latency must be 1 (default) or 2" SEVERITY FAILURE;
gen_ip : IF g_inferred=FALSE GENERATE
-- Copied from ip_arria10_e2sg_ram_r_w/ram_2port_140/sim/ip_arria10_e2sg_ram_r_w_ram_2port_140_hukd7xi.vhd
u_altera_syncram : altera_syncram
GENERIC MAP (
address_aclr_b => "NONE",
address_reg_b => "CLOCK0",
clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS",
clock_enable_output_b => "BYPASS",
init_file => g_init_file,
intended_device_family => "Arria 10",
lpm_type => "altera_syncram",
numwords_a => g_nof_words,
numwords_b => g_nof_words,
operation_mode => "DUAL_PORT",
outdata_aclr_b => "NONE",
outdata_reg_b => c_outdata_reg_b,
power_up_uninitialized => "FALSE",
widthad_a => g_adr_w,
widthad_b => g_adr_w,
width_a => g_dat_w,
width_b => g_dat_w,
width_byteena_a => 1
)
PORT MAP (
address_a => wraddress,
address_b => rdaddress,
clock0 => clk,
data_a => data,
wren_a => wren,
q_b => q
);
END GENERATE;
gen_inferred : IF g_inferred=TRUE GENERATE
rdaddr <= TO_INTEGER(UNSIGNED(rdaddress));
wraddr <= TO_INTEGER(UNSIGNED(wraddress));
u_mem : entity work.ip_arria10_e2sg_simple_dual_port_ram_single_clock
generic map (
DATA_WIDTH => g_dat_w,
ADDR_WIDTH => g_adr_w
)
port map (
clk => clk,
raddr => rdaddr,
waddr => wraddr,
data => data,
we => wren,
q => out_q
);
reg_q <= out_q WHEN rising_edge(clk);
q <= out_q WHEN g_rd_latency=1 ELSE reg_q;
END GENERATE;
END SYN;
-------------------------------------------------------------------------------
--
-- Copyright (C) 2014
-- 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.
--
-- 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.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- The inferred Altera code was obtained using template insert with Quartus 14.0a10.
-- Quartus II VHDL Template
-- Simple Dual-Port RAM with different read/write addresses and
-- different read/write clock
library ieee;
use ieee.std_logic_1164.all;
entity ip_arria10_e2sg_simple_dual_port_ram_dual_clock is
generic
(
DATA_WIDTH : natural := 8;
ADDR_WIDTH : natural := 6
);
port
(
rclk : in std_logic;
wclk : in std_logic;
raddr : in natural range 0 to 2**ADDR_WIDTH - 1;
waddr : in natural range 0 to 2**ADDR_WIDTH - 1;
data : in std_logic_vector((DATA_WIDTH-1) downto 0);
we : in std_logic := '1';
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end ip_arria10_e2sg_simple_dual_port_ram_dual_clock;
architecture rtl of ip_arria10_e2sg_simple_dual_port_ram_dual_clock is
-- Build a 2-D array type for the RAM
subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t;
-- Declare the RAM signal.
signal ram : memory_t;
begin
process(wclk)
begin
if(rising_edge(wclk)) then
if(we = '1') then
ram(waddr) <= data;
end if;
end if;
end process;
process(rclk)
begin
if(rising_edge(rclk)) then
q <= ram(raddr);
end if;
end process;
end rtl;
-------------------------------------------------------------------------------
--
-- Copyright (C) 2014
-- 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.
--
-- 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.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- The inferred Altera code was obtained using template insert with Quartus 14.0a10.
-- Quartus II VHDL Template
-- Simple Dual-Port RAM with different read/write addresses but
-- single read/write clock
library ieee;
use ieee.std_logic_1164.all;
entity ip_arria10_e2sg_simple_dual_port_ram_single_clock is
generic
(
DATA_WIDTH : natural := 8;
ADDR_WIDTH : natural := 6
);
port
(
clk : in std_logic;
raddr : in natural range 0 to 2**ADDR_WIDTH - 1;
waddr : in natural range 0 to 2**ADDR_WIDTH - 1;
data : in std_logic_vector((DATA_WIDTH-1) downto 0);
we : in std_logic := '1';
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end ip_arria10_e2sg_simple_dual_port_ram_single_clock;
architecture rtl of ip_arria10_e2sg_simple_dual_port_ram_single_clock is
-- Build a 2-D array type for the RAM
subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t;
-- Declare the RAM signal.
signal ram : memory_t;
begin
process(clk)
begin
if(rising_edge(clk)) then
if(we = '1') then
ram(waddr) <= data;
end if;
-- On a read during a write to the same address, the read will
-- return the OLD data at the address
q <= ram(raddr);
end if;
end process;
end rtl;
-------------------------------------------------------------------------------
--
-- Copyright (C) 2014
-- 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.
--
-- 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.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- The inferred Altera code was obtained using template insert with Quartus 14.0a10.
-- Quartus II VHDL Template
-- True Dual-Port RAM with dual clock
--
-- Read-during-write on port A or B returns newly written data
--
-- Read-during-write on port A and B returns unknown data.
library ieee;
use ieee.std_logic_1164.all;
entity ip_arria10_e2sg_true_dual_port_ram_dual_clock is
generic
(
DATA_WIDTH : natural := 8;
ADDR_WIDTH : natural := 6
);
port
(
clk_a : in std_logic;
clk_b : in std_logic;
addr_a : in natural range 0 to 2**ADDR_WIDTH - 1;
addr_b : in natural range 0 to 2**ADDR_WIDTH - 1;
data_a : in std_logic_vector((DATA_WIDTH-1) downto 0);
data_b : in std_logic_vector((DATA_WIDTH-1) downto 0);
we_a : in std_logic := '1';
we_b : in std_logic := '1';
q_a : out std_logic_vector((DATA_WIDTH -1) downto 0);
q_b : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end ip_arria10_e2sg_true_dual_port_ram_dual_clock;
architecture rtl of ip_arria10_e2sg_true_dual_port_ram_dual_clock is
-- Build a 2-D array type for the RAM
subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t;
-- Declare the RAM
shared variable ram : memory_t;
begin
-- Port A
process(clk_a)
begin
if(rising_edge(clk_a)) then
if(we_a = '1') then
ram(addr_a) := data_a;
end if;
q_a <= ram(addr_a);
end if;
end process;
-- Port B
process(clk_b)
begin
if(rising_edge(clk_b)) then
if(we_b = '1') then
ram(addr_b) := data_b;
end if;
q_b <= ram(addr_b);
end if;
end process;
end rtl;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment