Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

RAM data write and read

Status
Not open for further replies.

Kosyas41

Member level 3
Member level 3
Joined
Apr 12, 2016
Messages
62
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Visit site
Activity points
502
Hello,
I little bit confused with dual port RAM,my target is write and read data.I want to write data.like on the certain positions will be 128 and on the rest positions will be just 0.
I reading this article https://www.altera.co.jp/ja_JP/pdfs/literature/hb/qts/qts_qii51007.pdf
and I think I need true dual port Ram.
Code:
     library ieee;
    use ieee.std_logic_1164.all;
    entity true_dual_port_ram_single_clock is
     generic (
      DATA_WIDTH : natural := 8;
      ADDR_WIDTH : natural := 6
     );
     port (
      clk : 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 true_dual_port_ram_single_clock;
    architecture rtl of true_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.
     shared variable ram : memory_t;
begin
     process(clk)
     begin
     if(rising_edge(clk)) then -- Port A
      if(we_a = '1') then
       ram(addr_a) <= data_a;
       -- Read-during-write on the same port returns NEW data
       q_a <= data_a;
      else
       -- Read-during-write on the mixed port returns OLD data
       q_a <= ram(addr_a);
      end if;
     end if;
     end process;
     process(clk)
     begin
     if(rising_edge(clk)) then -- Port B
      if(we_b = '1') then
       ram(addr_b) := data_b;
       -- Read-during-write on the same port returns NEW data
       q_b <= data_b;
      else
       -- Read-during-write on the mixed port returns OLD data
       q_b <= ram(addr_b);
      end if;
     end if;
     end process;
end rtl;
but the question.how can I write data to this Ram?
 

Could you pls write an example how to do it?
Im trying to do it like this.Is it right?
Code:
library ieee;
    use ieee.std_logic_1164.all;
    entity true_dual_port_ram_single_clock is
     generic (
      DATA_WIDTH : natural := 8;
      ADDR_WIDTH : natural := 6
     );
     port (
      clk : 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 true_dual_port_ram_single_clock;
    architecture rtl of true_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.
     shared variable ram : memory_t;
begin
     process(clk)
     begin
     if(rising_edge(clk)) then -- Port A
      if(we_a = '1') then
		case addr_a is
		when 0 =>
		data_a <= 128;
		when 16 =>
		data_a <= 128;
                when others =>
                data_a <=0;
                end case;
       ram(addr_a) <= data_a;
       -- Read-during-write on the same port returns NEW data
       q_a <= data_a;
      else
       -- Read-during-write on the mixed port returns OLD data
       q_a <= ram(addr_a);
      end if;
     end if;
     end process;
     process(clk)
     begin
     if(rising_edge(clk)) then -- Port B
      if(we_b = '1') then
       ram(addr_b) := data_b;
       -- Read-during-write on the same port returns NEW data
       q_b <= data_b;
      else
       -- Read-during-write on the mixed port returns OLD data
       q_b <= ram(addr_b);
      end if;
     end if;
     end process;
end rtl;
but the question.how can I
 
Last edited:

thanks for reply,so as I understand true_dual_port_ram_single_clock this is not my case.I should use ram_dual.vhd from link which you send?
 


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
process(clk)
   begin
    if(rising_edge(clk)) then -- Port A
        if(we_a = '1') then
            case addr_a is
                when 0 => data_a <= 128;
                when 16 => data_a <= 128;
                when others => data_a <=0;
            end case;
            ram(addr_a) <= data_a;
            -- Read-during-write on the same port returns NEW data
            q_a <= data_a;
        else
            -- Read-during-write on the mixed port returns OLD data
            q_a <= ram(addr_a);
      end if;


The above code won't work for writing to a RAM (at least what you expect to write), the process is clocked and therefore the write enable is used as an enable to generate the address, which will delay the data generated by a clock cycle. This means the write occurs (the we_a) before the updated of the data. The signals: we_a, data_a, and addr_a should all valid at the same time to write the data_a @addr_a.
 

THe following might help you. The READ and WRITE codes are different, but you can easily combine them.

Code:
entity rx_buffer is
    generic (WIDTH : integer := 2);
    
    port ( clock        : in std_logic;
           n_reset      : in std_logic;
           rxbuff_en    : in std_logic;
           rxbuff_wr_en : in std_logic;
           rxbuff_addr  : in std_logic_vector(WIDTH-1 downto 0);
           rxbuff_in    : in std_logic_vector(7 downto 0);
           rxbuff_out   : out std_logic_vector(7 downto 0)
          );
end rx_buffer;


architecture rx_buffer_arc of rx_buffer is
    
    type mem_arr is array (natural range<>) of std_logic_vector(7 downto 0);
    signal DATA_ARR_q, DATA_ARR_in : mem_arr(0 to WIDTH+1);   
   
    begin
        
        process (rxbuff_en, rxbuff_wr_en, rxbuff_addr, DATA_ARR_q, rxbuff_in)            
            begin
                
                DATA_ARR_in <= DATA_ARR_q;
               
                rxbuff_out <= (others => '0');                                          
                                         
                if (rxbuff_en = '1') then
                    
                    if (rxbuff_wr_en = '1') then                        
                        if (rxbuff_addr = "00") then
                            DATA_ARR_in(0) <= rxbuff_in;
                        elsif (rxbuff_addr = "01") then
                            DATA_ARR_in(1) <= rxbuff_in;
                        elsif (rxbuff_addr = "10") then
                            DATA_ARR_in(2) <= rxbuff_in;
                        else
                            DATA_ARR_in(3) <= rxbuff_in;
                        end if;                        
                    else                                                            
                        if (rxbuff_addr = "00") then
                            rxbuff_out <= DATA_ARR_q(0);
                        elsif (rxbuff_addr = "01") then
                            rxbuff_out <= DATA_ARR_q(1); 
                        elsif (rxbuff_addr = "10") then
                            rxbuff_out <= DATA_ARR_q(2);  
                        else 
                            rxbuff_out <= DATA_ARR_q(3);
                        end if;                                                    
                    end if;                   
                                
                end if;            
        end process;                   
        
        process (clock, n_reset)
           begin
               
               if (n_reset = '0') then
                   DATA_ARR_q <= (others => (others => '0'));                    
               else
                  if (clock='1' and clock'event) then
                      DATA_ARR_q <= DATA_ARR_in;                      
                  end if;
              end if; 
        end process;                                           
end rx_buffer_arc;

Code:
entity tx_buffer is
    generic (WIDTH : integer := 2);
    
    port ( clock        : in std_logic;
           n_reset      : in std_logic;
           txbuff_en    : in std_logic;
           txbuff_wr_en : in std_logic;
           txbuff_addr  : in std_logic_vector(WIDTH-1 downto 0);
           txbuff_in    : in std_logic_vector(7 downto 0);
           txbuff_out   : out std_logic_vector(7 downto 0)
          );
end tx_buffer;


architecture tx_buffer_arc of tx_buffer is
    
    type mem_arr is array (natural range<>) of std_logic_vector(7 downto 0);
    signal DATA_ARR_q, DATA_ARR_in : mem_arr(0 to WIDTH+1);      
    
    begin
        
        process (txbuff_en, txbuff_wr_en, txbuff_addr, DATA_ARR_q, txbuff_in)            
            begin
                -- next-state assignments
                DATA_ARR_in <= DATA_ARR_q;
                
                txbuff_out <= (others => '0');     
                                                                 
                                         
                if (txbuff_en = '1') then
                    
                    if (txbuff_wr_en = '1') then
                        
                        if (txbuff_addr = "00") then
                            DATA_ARR_in(0) <= txbuff_in;
                        elsif (txbuff_addr = "01") then
                            DATA_ARR_in(1) <= txbuff_in;
                        elsif (txbuff_addr = "10") then
                            DATA_ARR_in(2) <= txbuff_in;
                        else
                            DATA_ARR_in(3) <= txbuff_in;
                        end if;                        
                    else  
                                                                              
                        if (txbuff_addr = "00") then
                            txbuff_out <= DATA_ARR_q(0);
                        elsif (txbuff_addr = "01") then
                            txbuff_out <= DATA_ARR_q(1); 
                        elsif (txbuff_addr = "10") then
                            txbuff_out <= DATA_ARR_q(2);  
                        else 
                            txbuff_out <= DATA_ARR_q(3);
                        end if;                                                    
                    end if;                                     
                                   
                end if;
            
        end process;           
        
        
        process (clock, n_reset)
           begin
               
               if (n_reset = '0') then
                   DATA_ARR_q <= (others => (others => '0'));                    
               else
                  if (clock='1' and clock'event) then
                      DATA_ARR_q <= DATA_ARR_in;                      
                  end if;
              end if; 
        end process;                      
                                
end tx_buffer_arc;
 
THe following might help you. The READ and WRITE codes are different, but you can easily combine them.

Code:
entity rx_buffer is
    generic (WIDTH : integer := 2);
    
    port ( clock        : in std_logic;
           n_reset      : in std_logic;
           rxbuff_en    : in std_logic;
           rxbuff_wr_en : in std_logic;
           rxbuff_addr  : in std_logic_vector(WIDTH-1 downto 0);
           rxbuff_in    : in std_logic_vector(7 downto 0);
           rxbuff_out   : out std_logic_vector(7 downto 0)
          );
end rx_buffer;


architecture rx_buffer_arc of rx_buffer is
    
    type mem_arr is array (natural range<>) of std_logic_vector(7 downto 0);
    signal DATA_ARR_q, DATA_ARR_in : mem_arr(0 to WIDTH+1);   
   
    begin
        
        process (rxbuff_en, rxbuff_wr_en, rxbuff_addr, DATA_ARR_q, rxbuff_in)            
            begin
                
                DATA_ARR_in <= DATA_ARR_q;
               
                rxbuff_out <= (others => '0');                                          
                                         
                if (rxbuff_en = '1') then
                    
                    if (rxbuff_wr_en = '1') then                        
                        if (rxbuff_addr = "00") then
                            DATA_ARR_in(0) <= rxbuff_in;
                        elsif (rxbuff_addr = "01") then
                            DATA_ARR_in(1) <= rxbuff_in;
                        elsif (rxbuff_addr = "10") then
                            DATA_ARR_in(2) <= rxbuff_in;
                        else
                            DATA_ARR_in(3) <= rxbuff_in;
                        end if;                        
                    else                                                            
                        if (rxbuff_addr = "00") then
                            rxbuff_out <= DATA_ARR_q(0);
                        elsif (rxbuff_addr = "01") then
                            rxbuff_out <= DATA_ARR_q(1); 
                        elsif (rxbuff_addr = "10") then
                            rxbuff_out <= DATA_ARR_q(2);  
                        else 
                            rxbuff_out <= DATA_ARR_q(3);
                        end if;                                                    
                    end if;                   
                                
                end if;            
        end process;                   
        
        process (clock, n_reset)
           begin
               
               if (n_reset = '0') then
                   DATA_ARR_q <= (others => (others => '0'));                    
               else
                  if (clock='1' and clock'event) then
                      DATA_ARR_q <= DATA_ARR_in;                      
                  end if;
              end if; 
        end process;                                           
end rx_buffer_arc;

Code:
entity tx_buffer is
    generic (WIDTH : integer := 2);
    
    port ( clock        : in std_logic;
           n_reset      : in std_logic;
           txbuff_en    : in std_logic;
           txbuff_wr_en : in std_logic;
           txbuff_addr  : in std_logic_vector(WIDTH-1 downto 0);
           txbuff_in    : in std_logic_vector(7 downto 0);
           txbuff_out   : out std_logic_vector(7 downto 0)
          );
end tx_buffer;


architecture tx_buffer_arc of tx_buffer is
    
    type mem_arr is array (natural range<>) of std_logic_vector(7 downto 0);
    signal DATA_ARR_q, DATA_ARR_in : mem_arr(0 to WIDTH+1);      
    
    begin
        
        process (txbuff_en, txbuff_wr_en, txbuff_addr, DATA_ARR_q, txbuff_in)            
            begin
                -- next-state assignments
                DATA_ARR_in <= DATA_ARR_q;
                
                txbuff_out <= (others => '0');     
                                                                 
                                         
                if (txbuff_en = '1') then
                    
                    if (txbuff_wr_en = '1') then
                        
                        if (txbuff_addr = "00") then
                            DATA_ARR_in(0) <= txbuff_in;
                        elsif (txbuff_addr = "01") then
                            DATA_ARR_in(1) <= txbuff_in;
                        elsif (txbuff_addr = "10") then
                            DATA_ARR_in(2) <= txbuff_in;
                        else
                            DATA_ARR_in(3) <= txbuff_in;
                        end if;                        
                    else  
                                                                              
                        if (txbuff_addr = "00") then
                            txbuff_out <= DATA_ARR_q(0);
                        elsif (txbuff_addr = "01") then
                            txbuff_out <= DATA_ARR_q(1); 
                        elsif (txbuff_addr = "10") then
                            txbuff_out <= DATA_ARR_q(2);  
                        else 
                            txbuff_out <= DATA_ARR_q(3);
                        end if;                                                    
                    end if;                                     
                                   
                end if;
            
        end process;           
        
        
        process (clock, n_reset)
           begin
               
               if (n_reset = '0') then
                   DATA_ARR_q <= (others => (others => '0'));                    
               else
                  if (clock='1' and clock'event) then
                      DATA_ARR_q <= DATA_ARR_in;                      
                  end if;
              end if; 
        end process;                      
                                
end tx_buffer_arc;

Now I have code like
Code:
library ieee;
    use ieee.std_logic_1164.all;
entity tx_buffer is
    generic (WIDTH : integer := 2);
    
    port ( clock        : in std_logic;
           n_reset      : in std_logic;
           txbuff_en    : in std_logic;
           txbuff_wr_en : in std_logic;
           txbuff_addr  : in std_logic_vector(WIDTH-1 downto 0);
           txbuff_in    : in std_logic_vector(7 downto 0);
           txbuff_out   : out std_logic_vector(7 downto 0);
			  rxbuff_en    : in std_logic;
           rxbuff_wr_en : in std_logic;
           rxbuff_addr  : in std_logic_vector(WIDTH-1 downto 0);
           rxbuff_in    : in std_logic_vector(7 downto 0);
           rxbuff_out   : out std_logic_vector(7 downto 0)
			  
          );
end tx_buffer;


architecture tx_buffer_arc of tx_buffer is
    
    type mem_arr is array (natural range<>) of std_logic_vector(7 downto 0);
    signal DATA_ARR_q, DATA_ARR_in : mem_arr(0 to WIDTH+1);      
    
    begin
        
        process (txbuff_en, txbuff_wr_en, rxbuff_en,rxbuff_wr_en, rxbuff_addr, txbuff_addr, DATA_ARR_q, txbuff_in,rxbuff_in)            
            begin
                -- next-state assignments
                DATA_ARR_in <= DATA_ARR_q;
                
                txbuff_out <= (others => '0');     
                                                                 
                                         
                if (txbuff_en = '1') then
                    
                    if (txbuff_wr_en = '1') then
                        
                        if (txbuff_addr = "00") then
                            DATA_ARR_in(0) <= txbuff_in;
                        elsif (txbuff_addr = "01") then
                            DATA_ARR_in(1) <= txbuff_in;
                        elsif (txbuff_addr = "10") then
                            DATA_ARR_in(2) <= txbuff_in;
                        else
                            DATA_ARR_in(3) <= txbuff_in;
                        end if;                        
                    else  
                                                                              
                        if (txbuff_addr = "00") then
                            txbuff_out <= DATA_ARR_q(0);
                        elsif (txbuff_addr = "01") then
                            txbuff_out <= DATA_ARR_q(1); 
                        elsif (txbuff_addr = "10") then
                            txbuff_out <= DATA_ARR_q(2);  
                        else 
                            txbuff_out <= DATA_ARR_q(3);
                        end if;                                                    
                    end if;                                     
                                   
                end if;
            rxbuff_out <= (others => '0');                                          
                                         
                if (rxbuff_en = '1') then
                    
                    if (rxbuff_wr_en = '1') then                        
                        if (rxbuff_addr = "00") then
                            DATA_ARR_in(0) <= rxbuff_in;
                        elsif (rxbuff_addr = "01") then
                            DATA_ARR_in(1) <= rxbuff_in;
                        elsif (rxbuff_addr = "10") then
                            DATA_ARR_in(2) <= rxbuff_in;
                        else
                            DATA_ARR_in(3) <= rxbuff_in;
                        end if;                        
                    else                                                            
                        if (rxbuff_addr = "00") then
                            rxbuff_out <= DATA_ARR_q(0);
                        elsif (rxbuff_addr = "01") then
                            rxbuff_out <= DATA_ARR_q(1); 
                        elsif (rxbuff_addr = "10") then
                            rxbuff_out <= DATA_ARR_q(2);  
                        else 
                            rxbuff_out <= DATA_ARR_q(3);
                        end if;                                                    
                    end if;                   
                                
                end if; 
        end process;           
        
        
        process (clock, n_reset)
           begin
               
               if (n_reset = '0') then
                   DATA_ARR_q <= (others => (others => '0'));                    
               else
                  if (clock='1' and clock'event) then
                      DATA_ARR_q <= DATA_ARR_in;                      
                  end if;
              end if; 
        end process;   
		  
                                
end tx_buffer_arc;
You mean combine like this?

- - - Updated - - -

Code:
library ieee;
    use ieee.std_logic_1164.all;
    entity true_dual_port_ram_single_clock is
     generic (
      DATA_WIDTH : integer := 8;
      ADDR_WIDTH : integer := 6;
		WIDTH : integer :=2
     );
     port (
      clk : in std_logic;
		n_reset      : 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);
		txbuff_en    : in std_logic;
           txbuff_wr_en : in std_logic;
           txbuff_addr  : in std_logic_vector(WIDTH-1 downto 0);
           txbuff_in    : in std_logic_vector(7 downto 0);
           txbuff_out   : out std_logic_vector(7 downto 0);
			  rxbuff_en    : in std_logic;
           rxbuff_wr_en : in std_logic;
           rxbuff_addr  : in std_logic_vector(WIDTH-1 downto 0);
           rxbuff_in    : in std_logic_vector(7 downto 0);
           rxbuff_out   : out std_logic_vector(7 downto 0)
     );
    end true_dual_port_ram_single_clock;
    architecture rtl of true_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.
	  type mem_arr is array (natural range<>) of std_logic_vector(7 downto 0);
    signal DATA_ARR_q, DATA_ARR_in : mem_arr(0 to WIDTH+1);     
     shared variable ram : memory_t;
begin
     process(clk)
     begin
     if(rising_edge(clk)) then -- Port A
      if(we_a = '1') then
       ram(addr_a) := data_a;
       -- Read-during-write on the same port returns NEW data
       q_a <= data_a;
      else
       -- Read-during-write on the mixed port returns OLD data
       q_a <= ram(addr_a);
      end if;
     end if;
     end process;
     process(clk,txbuff_en, txbuff_wr_en, rxbuff_en,rxbuff_wr_en, rxbuff_addr, txbuff_addr, DATA_ARR_q, txbuff_in,rxbuff_in)
     begin
	                  DATA_ARR_in <= DATA_ARR_q;
                
                txbuff_out <= (others => '0');     
                                                                 
                                         
                if (txbuff_en = '1') then
                    
                    if (txbuff_wr_en = '1') then
                        
                        if (txbuff_addr = "00") then
                            DATA_ARR_in(0) <= txbuff_in;
                        elsif (txbuff_addr = "01") then
                            DATA_ARR_in(1) <= txbuff_in;
                        elsif (txbuff_addr = "10") then
                            DATA_ARR_in(2) <= txbuff_in;
                        else
                            DATA_ARR_in(3) <= txbuff_in;
                        end if;                        
                    else  
                                                                              
                        if (txbuff_addr = "00") then
                            txbuff_out <= DATA_ARR_q(0);
                        elsif (txbuff_addr = "01") then
                            txbuff_out <= DATA_ARR_q(1); 
                        elsif (txbuff_addr = "10") then
                            txbuff_out <= DATA_ARR_q(2);  
                        else 
                            txbuff_out <= DATA_ARR_q(3);
                        end if;                                                    
                    end if;                                     
                                   
                end if;
            rxbuff_out <= (others => '0');                                          
                                         
                if (rxbuff_en = '1') then
                    
                    if (rxbuff_wr_en = '1') then                        
                        if (rxbuff_addr = "00") then
                            DATA_ARR_in(0) <= rxbuff_in;
                        elsif (rxbuff_addr = "01") then
                            DATA_ARR_in(1) <= rxbuff_in;
                        elsif (rxbuff_addr = "10") then
                            DATA_ARR_in(2) <= rxbuff_in;
                        else
                            DATA_ARR_in(3) <= rxbuff_in;
                        end if;                        
                    else                                                            
                        if (rxbuff_addr = "00") then
                            rxbuff_out <= DATA_ARR_q(0);
                        elsif (rxbuff_addr = "01") then
                            rxbuff_out <= DATA_ARR_q(1); 
                        elsif (rxbuff_addr = "10") then
                            rxbuff_out <= DATA_ARR_q(2);  
                        else 
                            rxbuff_out <= DATA_ARR_q(3);
                        end if;                                                    
                    end if;                   
                                
                end if; 
        end process;           
        
        
        process (clk, n_reset)
           begin
               
               if (n_reset = '0') then
                   DATA_ARR_q <= (others => (others => '0'));                    
               else
                  if (clk='1' and clk'event) then
                      DATA_ARR_q <= DATA_ARR_in;                      
                  end if;
              end if;
     if(rising_edge(clk)) then -- Port B
	  
      if(we_b = '1') then
       ram(addr_b) := data_b;
       -- Read-during-write on the same port returns NEW data
       q_b <= data_b;
      else
       -- Read-during-write on the mixed port returns OLD data
       q_b <= ram(addr_b);
      end if;
     end if;
     end process;
end rtl;
 

The READ and WRITE codes are different, but you can easily combine them.
Sorry about the above comment in #8.

Both codes in #8 represent the same functionality. You can use any one.

If the signal *buff_wr_en = '1' then memory WRITE is facilitated else READ occurs.
The memory address is defined by the *buff_addr signal.
Note that the memory depth is defined by: generic (WIDTH : integer := 2);
The memory width is defined by:
type mem_arr is array (natural range<>) of std_logic_vector(7 downto 0);

You can easily change the above to suite your needs.

What more can I say, it is very simple and self-explanatory in my opinion.
 

Note that it is not a true dual port RAM model.
The code I provided, with that, you either do a READ or a WRITE one at a time.

ok/but how I can write a right code?Could you pls help me?
Due to your above comment in #7, I gave you an example.
Now that you know, you can develop your own code.
 
Last edited:

I have a code for dual port RAM.and I want to write there some data.So Its mean that I can use your code and it will write data in dp RAM?
Code:
library ieee;
    use ieee.std_logic_1164.all;
    entity true_dual_port_ram_single_clock is
     generic (
      DATA_WIDTH : integer := 8;
      ADDR_WIDTH : integer := 6;
		WIDTH : integer :=2
     );
     port (
      clk : in std_logic;
		n_reset      : 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);
		txbuff_en    : in std_logic;
           txbuff_wr_en : in std_logic;
           txbuff_addr  : in std_logic_vector(WIDTH-1 downto 0);
           txbuff_in    : in std_logic_vector(7 downto 0);
           txbuff_out   : out std_logic_vector(7 downto 0)
     );
    end true_dual_port_ram_single_clock;
    architecture rtl of true_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.
	  type mem_arr is array (natural range<>) of std_logic_vector(7 downto 0);
    signal DATA_ARR_q, DATA_ARR_in : mem_arr(0 to WIDTH+1);     
     shared variable ram : memory_t;
begin
     process(clk)
     begin
     if(rising_edge(clk)) then -- Port A
      if(we_a = '1') then
       ram(addr_a) := data_a;
       -- Read-during-write on the same port returns NEW data
       q_a <= data_a;
      else
       -- Read-during-write on the mixed port returns OLD data
       q_a <= ram(addr_a);
      end if;
     end if;
     end process;
     process(clk,txbuff_en, txbuff_wr_en, txbuff_addr, DATA_ARR_q, txbuff_in)
     begin
	                  DATA_ARR_in <= DATA_ARR_q;
                
                txbuff_out <= (others => '0');     
                                                                 
                                         
                if (txbuff_en = '1') then
                    
                    if (txbuff_wr_en = '1') then
                        
                        if (txbuff_addr = "00") then
                            DATA_ARR_in(0) <= txbuff_in;
                        elsif (txbuff_addr = "01") then
                            DATA_ARR_in(1) <= txbuff_in;
                        elsif (txbuff_addr = "10") then
                            DATA_ARR_in(2) <= txbuff_in;
                        else
                            DATA_ARR_in(3) <= txbuff_in;
                        end if;                        
                    else  
                                                                              
                        if (txbuff_addr = "00") then
                            txbuff_out <= DATA_ARR_q(0);
                        elsif (txbuff_addr = "01") then
                            txbuff_out <= DATA_ARR_q(1); 
                        elsif (txbuff_addr = "10") then
                            txbuff_out <= DATA_ARR_q(2);  
                        else 
                            txbuff_out <= DATA_ARR_q(3);
                        end if;                                                    
                    end if;                                     
                                   
                end if;
        
        end process;           
        
        
        process (clk, n_reset)
           begin
               
               if (n_reset = '0') then
                   DATA_ARR_q <= (others => (others => '0'));                    
               else
                  if (clk='1' and clk'event) then
                      DATA_ARR_q <= DATA_ARR_in;                      
                  end if;
              end if;
     if(rising_edge(clk)) then -- Port B
	  
      if(we_b = '1') then
       ram(addr_b) := data_b;
       -- Read-during-write on the same port returns NEW data
       q_b <= data_b;
      else
       -- Read-during-write on the mixed port returns OLD data
       q_b <= ram(addr_b);
      end if;
     end if;
     end process;
end rtl;
for example like this?
 

.So Its mean that I can use your code and it will write data in dp RAM?

You have to understand both the codes and then use your knowledge and common sense.

for example like this?
Sorry, I can't work as a compiler for you.

You can't just copy and paste! The ports are different and also the functionality. You have just copy pasted my process block into your code. How can it work?

Plz review your VHDL basics first. Then self-understand what you want to achieve. All things can come later.
 
Last edited:

You have to understand both the codes and then use your knowledge and common sense.
FYI, the OP want's you to write an entire example for them. It's not about common sense or knowledge, it's a fundamental problem of not having a engineer's thought process.

I see it sort of as the difference between those that find the following to be easy and hard.
easy:
1+1 = 2
hard:
You have one dog, one wolverine, a three legged crocodile, and one cat. How many domesticated animals do you own?

Both are just simple 1+1 addition problems, but the word problem requires the ability to break a problem down and extract information to solve. But I remember in grade school and high school, so many students would groan when the math teacher would give out word problems. To me they were the opportunity to set the top of the curve (actually get a 100% on and screw the curve up completely ;-))
 

FYI, the OP want's you to write an entire example for them.
I never do that.

It's not about common sense or knowledge,.....
I wanted to say technical common sense.

To the OP: Please go through my codes and first understand how a simple write and read takes place. Do write a test-bench for it and study the signal transitions via the waveforms after simulation. After that you can go for the modelling a true dual port RAM. I say that because I have an impression that you lack some basic understanding.
 

I never do that.
:-D

I wanted to say technical common sense.
Does such a thing even exist!? I must have read too many questions on edaboard, based on what I've seen around here, such a thing is not at all common. In fact it seems to be an endangered species on the brink of extinction. Or maybe it's the engineering equivalent of the dodo bird. ;-)

To the OP: Please go through my codes and first understand how a simple write and read takes place. Do write a test-bench for it and study the signal transitions via the waveforms after simulation. After that you can go for the modelling a true dual port RAM. I say that because I have an impression that you lack some basic understanding.
Very nicely put, but next you'll be asked to write the testbench or give them an example testbench. :roll:
 

You have one dog, one wolverine, a three legged crocodile, and one cat. How many domesticated animals do you own?
Interesting. I'm going to say the wolverine eats the cat. The dog can outrun the crocodile, even if the dog is small due to the four-leg advantage. But without knowing how large the dog is, it is impossible to know if the wolverine would also eat it.
 

Now I have this code
Code:
library ieee;
    use ieee.std_logic_1164.all;
    entity true_dual_port_ram_single_clock is
     generic (
      DATA_WIDTH : natural := 8;
      ADDR_WIDTH : natural := 6
     );
     port (
      clk : 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 true_dual_port_ram_single_clock;
    architecture rtl of true_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.
     shared variable ram : memory_t;
	  begin
     process(clk)
     begin
     if(rising_edge(clk)) then -- Port A
      if(we_a = '1') then
		case addr_a is
                when 0 => 
					 q_a <= "10000000";
                when 16 => 
					 q_a <= "10000000";
                when others => 
					 q_a <="00000000";
            end case;

		ram(addr_a) := data_a;

       -- Read-during-write on the same port returns NEW data
       q_a <= data_a;
      else
       -- Read-during-write on the mixed port returns OLD data
		 		case addr_a is
                when 0 => 
					 q_a <= "10000000";
                when 16 => 
					 q_a <= "10000000";
                when others => 
					 q_a <="00000000";
            end case;
       q_a <= ram(addr_a);
      end if;
     end if;
     end process;
     process(clk)
     begin
     if(rising_edge(clk)) then -- Port B
      if(we_b = '1') then
				case addr_b is
                when 0 => 
					 q_b <= "10000000";
                when 16 => 
					 q_b <= "10000000";
                when others => 
					 q_b <="00000000";
            end case;
       ram(addr_b) := data_b;
       -- Read-during-write on the same port returns NEW data
       q_b <= data_b;
      else
       -- Read-during-write on the mixed port returns OLD data
		       if(we_b = '1') then
				case addr_b is
                when 0 => 
					 q_b <= "10000000";
                when 16 => 
					 q_b <= "10000000";
                when others => 
					 q_b <="00000000";
            end case;
       q_b <= ram(addr_b);
      end if;
     end if;
	  end if;
     end process;
end rtl;
 
Last edited:

Yes, go ahead, I have just *glanced* through your code.
Recheck the signals on your sensitivity list (one problem area- we_a or we_b is missing).

Code:
       ram(addr_b) := data_b;
       -- Read-during-write on the same port returns NEW data
       q_b <= data_b;
Also be sure what you are doing in the above part. You are executing the above when we_b = '1'.

If there are errors compiler will complain!
Use a test-bench to simulate your model.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top