Quad Port RAM

Joined
Jan 14, 2009
Messages
5
Reaction score
0
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.

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.
 
Joined
Jan 14, 2009
Messages
5
Reaction score
0
Solved

Sorry. I made a big mistake in test bench file :lol: ,

I had connected doB to PortB and PortD, oops, many days checking why didn't working but was a simple finger error.

Now is working
:lol: :lol: :lol: :lol: :lol:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,525
Members
44,997
Latest member
mileyka

Latest Threads

Top