I'm using the Spartan 3E starter kit and I just trying to make a Quad Port RAM with the reading and writing ports independent. The code is the next:
First infer a Dual Port RAM with the reading and writing port indepent.
The RAM on Spartan 3E is a dual port, then I'm using Port A for writing and Port B for reading.
I use 4 Block RAM to emulate a Quad Port RAM with the write and read port independent. The way I'm trying to make it is by mux the 4 input ports and make a copy of the data in each blockRAM
But it doesn't work, I have some troubles with portB and portD but not with PortA and PortC.
I need help to solve it.
First infer a Dual Port RAM with the reading and writing port indepent.
Code:
--infer_dram.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;
entity infer_dram is
generic(WD: integer :=8; WA: integer :=8);
port ( r_add,w_add: in std_logic_vector(WA-1 downto 0);
en,we,rd,clk,clkx4: in std_logic;
di:in std_logic_vector(WD-1 downto 0);
do: out std_logic_vector(WD-1 downto 0)
);
end infer_dram;
architecture Behave of infer_dram is
type ram_type is array (0 to 2**WA-1) of std_logic_vector(WD-1 downto 0);
signal RAM : ram_type;
begin
--Write Process
process(en,clkx4,we,w_add,di)
begin
--if en='1' then
if rising_edge(clkx4) then
if we='1' then
RAM(conv_integer(unsigned(w_add)))<=di;
end if;
end if;
--end if;
end process;
--Read Process
process(clk,rd,r_add)
begin
if rising_edge(clk) then
--if rd='1' then
do<=RAM(conv_integer(unsigned(r_add)));
--end if;
end if;
-- end if;
end process;
end Behave;
The RAM on Spartan 3E is a dual port, then I'm using Port A for writing and Port B for reading.
Code:
--qpram.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH. ALL;
use IEEE.STD_LOGIC_UNSIGNED. ALL;
entity qpram is
generic(WD: integer :=8; WA: integer :=8);
port( clk,clkx4,en_a,en_b,en_c,en_d,we_a,we_b,we_c,we_d,rd_a,rd_b,rd_c,rd_d,encount,rst: in std_logic;
wadd_a,wadd_b,wadd_c,wadd_d,radd_a,radd_b,radd_c,radd_d: in std_logic_vector(WA-1 downto 0);
diA,diB,diC,diD: in std_logic_vector(WD-1 downto 0);
doA,doB,doC,doD: out std_logic_vector(WD-1 downto 0)
);
end qpram;
architecture Behave of qpram is
component infer_dram is
generic(WD: integer :=8; WA: integer :=8);
port ( r_add,w_add: in std_logic_vector(WA-1 downto 0);
en,we,rd,clk,clkx4: in std_logic;
di:in std_logic_vector(WD-1 downto 0);
do: out std_logic_vector(WD-1 downto 0)
);
end component;
component inPorts is
generic(WD: integer :=8; WA: integer :=8);
port( wadd_a,wadd_b,wadd_c,wadd_d: in std_logic_vector(WA-1 downto 0);
diA,diB,diC,diD: in std_logic_vector(WD-1 downto 0);
clkx4,en_a,en_b,en_c,en_d,we_a,we_b,we_c,we_d: in std_logic;
encount,rst: in std_logic;
en,we: out std_logic;
wadd: out std_logic_vector(WA-1 downto 0);
do: out std_logic_vector(WD-1 downto 0)
);
end component;
signal wadd: std_logic_vector(WA-1 downto 0);
signal en,we: std_logic;
signal di: std_logic_vector(WD-1 downto 0);
begin
InP: inPorts
generic map(WD,WA)
port map( wadd_a=>wadd_a,wadd_b=>wadd_b,wadd_c=>wadd_c,wadd_d=>wadd_d,
diA=>diA,diB=>diB,diC=>diC,diD=>diD,
clkx4=>clkx4,en_a=>en_a,en_b=>en_b,en_c=>en_c,en_d=>en_d,we_a=>we_a,we_b=>we_b,we_c=>we_c,we_d=>we_d,
encount=>encount,rst=>rst,
en=>en,we=>we,
wadd=>wadd,
do=>di
);
RAM_0: infer_dram
generic map(WD,WA)
port map( r_add=>radd_a,w_add=>wadd,
en=>en,we=>we,rd=>rd_a,clk=>clk,clkx4=>clkx4,
di=>di,
do=>doA
);
RAM_1: infer_dram
generic map(WD,WA)
port map( r_add=>radd_b,w_add=>wadd,
en=>en,we=>we,rd=>rd_b,clk=>clk,clkx4=>clkx4,
di=>di,
do=>doB
);
RAM_2: infer_dram
generic map(WD,WA)
port map( r_add=>radd_c,w_add=>wadd,
en=>en,we=>we,rd=>rd_c,clk=>clk,clkx4=>clkx4,
di=>di,
do=>doC
);
RAM_3: infer_dram
generic map(WD,WA)
port map( r_add=>radd_d,w_add=>wadd,
en=>en,we=>we,rd=>rd_d,clk=>clk,clkx4=>clkx4,
di=>di,
do=>doD
);
end Behave;
I use 4 Block RAM to emulate a Quad Port RAM with the write and read port independent. The way I'm trying to make it is by mux the 4 input ports and make a copy of the data in each blockRAM
Code:
--inPorts.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH. ALL;
use IEEE.STD_LOGIC_UNSIGNED. ALL;
entity inPorts is
generic(WD: integer :=8; WA: integer :=8);
port( wadd_a,wadd_b,wadd_c,wadd_d: in std_logic_vector(WA-1 downto 0);
diA,diB,diC,diD: in std_logic_vector(WD-1 downto 0);
clkx4,en_a,en_b,en_c,en_d,we_a,we_b,we_c,we_d: in std_logic;
encount,rst: in std_logic;
en,we: out std_logic;
wadd: out std_logic_vector(WA-1 downto 0);
do: out std_logic_vector(WD-1 downto 0)
);
end entity;
architecture Behave of inPorts is
signal count:std_logic_vector(1 downto 0);
begin
c:process(clkx4,rst,encount)
begin
if rst='1' then count<="00";
elsif encount='1' then
if rising_edge(clkx4) then
count<=count+"1";
end if;
end if;
end process;
mux_0: process(en_a,en_b,en_c,en_d, we_a,we_b,we_c,we_d,wadd_a,wadd_b,wadd_c,wadd_d,diA,diB,diC,diD,count)
begin
case count is
when "00" =>do<=diA; wadd<=wadd_a; we<=we_a;en<=en_a;
when "01" =>do<=diB; wadd<=wadd_b; we<=we_b;en<=en_b;
when "10" =>do<=diC; wadd<=wadd_c; we<=we_c;en<=en_c;
when "11" =>do<=diD; wadd<=wadd_d; we<=we_d;en<=en_d;
when others => do<=diA; wadd<=wadd_a; we<=we_a;en<=en_a;
end case;
end process;
end Behave;
But it doesn't work, I have some troubles with portB and portD but not with PortA and PortC.
I need help to solve it.