OpenCores
URL https://opencores.org/ocsvn/mod_sim_exp/mod_sim_exp/trunk

Subversion Repositories mod_sim_exp

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /mod_sim_exp
    from Rev 62 to Rev 61
    Reverse comparison

Rev 62 → Rev 61

/trunk/rtl/vhdl/ram/dpram_altera.vhd
0,0 → 1,84
-- Quartus II VHDL Template
--
-- Simple Dual-Port RAM with separate read and write addresses and data widths
-- that are controlled by the parameters RW and WW. RW and WW must specify a
-- read/write ratio that's supported by the memory blocks in your target
-- device. Otherwise, no RAM will be inferred.
 
library ieee;
use ieee.std_logic_1164.all;
library altera;
use altera.altera_standard_functions.all;
 
entity dpram_altera is
generic (
WORDS : natural := 2;
RW : natural := 1024;
WW : natural := 32);
 
port (
we : in std_logic;
clk : in std_logic;
waddr : in natural range 0 to (WORDS * maximum(RW, WW)) / WW - 1;
wdata : in std_logic_vector(WW - 1 downto 0);
raddr : in natural range 0 to (WORDS * maximum(RW, WW)) / RW - 1;
q : out std_logic_vector(RW - 1 downto 0));
 
end dpram_altera;
 
architecture rtl of dpram_altera is
 
constant B : natural := minimum(RW, WW);
constant R : natural := maximum(RW, WW)/B;
 
-- Use a multidimensional array to model mixed-width
type word_t is array(R - 1 downto 0) of std_logic_vector(B - 1 downto 0);
type ram_t is array (0 to WORDS - 1) of word_t;
 
signal ram : ram_t;
begin -- rtl
 
-- Must handle read < write and write > read separately
smaller_read: if RW < WW generate
signal wdata_local : word_t;
begin
 
-- Re-organize the write data to match the RAM word type
unpack: for i in 0 to R - 1 generate
wdata_local(i) <= wdata(B*(i+1) - 1 downto B*i);
end generate unpack;
 
process(clk, we)
begin
if(rising_edge(clk)) then
if(we = '1') then
ram(waddr) <= wdata_local;
end if;
q <= ram(raddr / R )(raddr mod R);
end if;
end process;
end generate smaller_read;
 
not_smaller_read: if RW >= WW generate
signal q_local : word_t;
begin
 
-- Re-organize the read data from the RAM to match the output
unpack: for i in 0 to R - 1 generate
q(B*(i+1) - 1 downto B*i) <= q_local(i);
end generate unpack;
process(clk, we)
begin
if(rising_edge(clk)) then
if(we = '1') then
ram(waddr / R)(waddr mod R) <= wdata;
end if;
q_local <= ram(raddr);
end if;
end process;
end generate not_smaller_read;
 
end rtl;
/trunk/rtl/vhdl/ram/dpram_xilinx.vhd
0,0 → 1,123
--------------------------------------------------------------------------------
-- Entity: ram_xilinx
-- Date:2013-02-19
-- Author: Dinghe
--
-- Description ${cursor}
--------------------------------------------------------------------------------
--
-- correctly implemented as Block RAM, no other resources needed.
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
 
entity dpram_xilinx is
 
generic (
WIDTHA : integer := 32;
SIZEA : integer := 48;
ADDRWIDTHA : integer := 6;
WIDTHB : integer := 1536;
SIZEB : integer := 1;
ADDRWIDTHB : integer := 1
);
 
port (
clkA : in std_logic;
clkB : in std_logic;
enB : in std_logic;
weA : in std_logic;
addrA : in std_logic_vector(ADDRWIDTHA-1 downto 0);
addrB : in std_logic_vector(ADDRWIDTHB-1 downto 0);
diA : in std_logic_vector(WIDTHA-1 downto 0);
doB : out std_logic_vector(WIDTHB-1 downto 0)
);
 
end dpram_xilinx;
 
architecture behavioral of dpram_xilinx is
 
function max(L, R: INTEGER) return INTEGER is
begin
if L > R then
return L;
else
return R;
end if;
end;
 
function min(L, R: INTEGER) return INTEGER is
begin
if L < R then
return L;
else
return R;
end if;
end;
 
function log2 (val: INTEGER) return natural is
variable res : natural;
begin
for i in 0 to 31 loop
if (val <= (2**i)) then
res := i;
exit;
end if;
end loop;
return res;
end function Log2;
 
constant minWIDTH : integer := min(WIDTHA,WIDTHB);
constant maxWIDTH : integer := max(WIDTHA,WIDTHB);
constant maxSIZE : integer := max(SIZEA,SIZEB);
constant RATIO : integer := maxWIDTH / minWIDTH;
 
-- An asymmetric RAM is modelled in a similar way as a symmetric RAM, with an
-- array of array object. Its aspect ratio corresponds to the port with the
-- lower data width (larger depth)
type ramType is array (0 to maxSIZE-1) of std_logic_vector(minWIDTH-1 downto 0);
 
-- You need to declare ram as a shared variable when :
-- - the RAM has two write ports,
-- - the RAM has only one write port whose data width is maxWIDTH
-- In all other cases, ram can be a signal.
signal ram : ramType := (others => (others => '0'));
attribute ram_style : string;
attribute ram_style of ram:signal is "block";
signal readB : std_logic_vector(WIDTHB-1 downto 0):= (others => '0');
signal addrB_i : std_logic_vector(ADDRWIDTHB-1 downto 0):= (others => '0');
 
begin
 
-- port A: only write
process (clkA)
begin
if rising_edge(clkA) then
if weA = '1' then
ram(conv_integer(addrA)) <= diA;
end if;
end if;
end process;
 
-- port B: only read
process (clkB)
begin
if rising_edge(clkB) then
if enB = '1' then
addrB_i <= addrB;
end if;
doB <= readB;
end if;
end process;
ramoutput : for i in 0 to RATIO-1 generate
readB((i+1)*minWIDTH-1 downto i*minWIDTH)
<= ram(conv_integer(addrB_i & conv_std_logic_vector(i,log2(RATIO))));
end generate;
end behavioral;
/trunk/rtl/vhdl/ram/tdpram_xilinx.vhd
0,0 → 1,151
--------------------------------------------------------------------------------
-- Entity: ram_xilinx
-- Date:2013-02-19
-- Author: Dinghe
--
-- Description ${cursor}
--------------------------------------------------------------------------------
--
-- WIDTHA = 32
-- SIZEA = 32 --> 2 registers needed
-- ADDRWIDTHA = 5
-- WIDTHB = 512 --> 2 registers needed
-- SIZEB = 2
-- ADDRWIDTHB = 1
-- Found 32x32:2x512-bit dual-port RAM <Mram_ram> for signal <ram>.
-- Found 32-bit register for signal <doA>.
-- Found 512-bit register for signal <readB>.
-- Found 512-bit register for signal <doB>.
-- Found 32-bit register for signal <readA>.
-- Summary:
-- inferred 1 RAM(s).
-- inferred 1088 D-type flip-flop(s).
-- inferred 17 Multiplexer(s).
--
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
 
entity tdpram_xilinx is
 
generic (
WIDTHA : integer := 32;
SIZEA : integer := 32;
ADDRWIDTHA : integer := 5;
WIDTHB : integer := 512;
SIZEB : integer := 2;
ADDRWIDTHB : integer := 1
);
 
port (
clkA : in std_logic;
clkB : in std_logic;
enA : in std_logic;
enB : in std_logic;
weA : in std_logic;
weB : in std_logic;
addrA : in std_logic_vector(ADDRWIDTHA-1 downto 0);
addrB : in std_logic_vector(ADDRWIDTHB-1 downto 0);
diA : in std_logic_vector(WIDTHA-1 downto 0);
diB : in std_logic_vector(WIDTHB-1 downto 0);
doA : out std_logic_vector(WIDTHA-1 downto 0);
doB : out std_logic_vector(WIDTHB-1 downto 0)
);
 
end tdpram_xilinx;
 
architecture behavioral of tdpram_xilinx is
 
function max(L, R: INTEGER) return INTEGER is
begin
if L > R then
return L;
else
return R;
end if;
end;
 
function min(L, R: INTEGER) return INTEGER is
begin
if L < R then
return L;
else
return R;
end if;
end;
 
function log2 (val: INTEGER) return natural is
variable res : natural;
begin
for i in 0 to 31 loop
if (val <= (2**i)) then
res := i;
exit;
end if;
end loop;
return res;
end function Log2;
 
constant minWIDTH : integer := min(WIDTHA,WIDTHB);
constant maxWIDTH : integer := max(WIDTHA,WIDTHB);
constant maxSIZE : integer := max(SIZEA,SIZEB);
constant RATIO : integer := maxWIDTH / minWIDTH;
 
-- An asymmetric RAM is modelled in a similar way as a symmetric RAM, with an
-- array of array object. Its aspect ratio corresponds to the port with the
-- lower data width (larger depth)
type ramType is array (0 to maxSIZE-1) of std_logic_vector(minWIDTH-1 downto 0);
 
-- You need to declare ram as a shared variable when :
-- - the RAM has two write ports,
-- - the RAM has only one write port whose data width is maxWIDTH
-- In all other cases, ram can be a signal.
shared variable ram : ramType := (others => (others => '0'));
signal readA : std_logic_vector(WIDTHA-1 downto 0):= (others => '0');
signal readB : std_logic_vector(WIDTHB-1 downto 0):= (others => '0');
signal regA : std_logic_vector(WIDTHA-1 downto 0):= (others => '0');
signal regB : std_logic_vector(WIDTHB-1 downto 0):= (others => '0');
 
begin
 
process (clkA)
begin
if rising_edge(clkA) then
if enA = '1' then
if weA = '1' then
ram(conv_integer(addrA)) := diA;
readA <= diA;
else
readA <= ram(conv_integer(addrA));
end if;
end if;
regA <= readA;
end if;
end process;
 
process (clkB)
begin
if rising_edge(clkB) then
if enB = '1' then
for i in 0 to RATIO-1 loop
if weB = '1' then
ram(conv_integer(addrB & conv_std_logic_vector(i,log2(RATIO))))
:= diB((i+1)*minWIDTH-1 downto i*minWIDTH);
end if;
-- The read statement below is placed after the write statement on purpose
-- to ensure write-first synchronization through the variable mechanism
readB((i+1)*minWIDTH-1 downto i*minWIDTH)
<= ram(conv_integer(addrB & conv_std_logic_vector(i,log2(RATIO))));
end loop;
end if;
regB <= readB;
end if;
end process;
 
doA <= regA;
doB <= regB;
end behavioral;

powered by: WebSVN 2.1.0

© copyright 1999-2023 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.