EmbDev.net

Forum: FPGA, VHDL & Verilog Memory Interface with a Muxed Address/Data Bus


Author: Max (Guest)
Posted on:

Rate this post
0 useful
not useful
Hallo,

I want to implement a memory interface in VHDL between an FPGA and a 
processor. The address/data bus is a 16-bit multiplexed bus with an ALE, 
write protect and BusWait. According to the NVIDIA Tegra 3 Technical 
Reference Manual (p. 2099-2111), the lower 16 bit of addresses are 
multiplexed with data bus.

I have experience using a tri-state buffers only with data buses. How do 
I also control the flow of the address using a tri-state buffer. Or is 
there any other way to implement this interface? It would be great if 
anybody could share a reference VHDL module for the above.

Thanks!

Author: Markus F. (mfro)
Posted on:

Rate this post
0 useful
not useful
Max wrote:
>
> I have experience using a tri-state buffers only with data buses. How do
> I also control the flow of the address using a tri-state buffer. Or is
> there any other way to implement this interface? It would be great if
> anybody could share a reference VHDL module for the above.
>

I don't know this particular processor so this might be a bit too 
general for you, but anyway: whenever ALE is asserted, do what this 
signal tells you: latch the address for later use.

In all other cases, you can treat the bus just like it was a data bus.

Author: Max (Guest)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Thank you.

Below is the code. I hope, I am going in the right direction.

Is it the right way to read/Wite the Muxed INOUT bus. I have latched the 
address on a rising edge and the Read/Write takes place in the falling 
edge. Is it the correct way? Also, I am not sure if I have used the 
Bus_Wait and Write Protect(WP) correctly.
As per the Refrence Manual:

Wait (or Ready): Level configurable input. When asserted, WAIT (RDY) 
indicates the read data is invalid (Wait) or Valid (Ready). WAIT (RDY) 
is driven by the devices when CEx_N and OE_N are low and High-Z when 
when CEx_N or OE_N are high.

Write Protect: Active low output. When low, WP_N enables the device lock 
down mechanism, or inhibits write cycles.

The timing diagrams are attached. (Following sync read in which data is 
read at the falling edge )


entity Mem_IF is

    Port ( 
         RO_Register_0 :  in STD_LOGIC_VECTOR(15 downto 0);
       RO_Register_1 :  in STD_LOGIC_VECTOR(15 downto 0);
       RO_Register_2 :  in STD_LOGIC_VECTOR(15 downto 0);
                
       BCLK : in  STD_LOGIC;
         n_Reset: in STD_LOGIC;
           n_OE : in STD_LOGIC;
       n_WE: in STD_LOGIC;
       ALE: in STD_LOGIC;
       Bus_Wait: out STD_LOGIC;
       n_WP: in STD_LOGIC;
       n_CS_0: in STD_LOGIC;
       
       WR_Register_0 :  out STD_LOGIC_VECTOR(15 downto 0);
       WR_Register_1 :  out STD_LOGIC_VECTOR(15 downto 0);
       WR_Register_2 :  out STD_LOGIC_VECTOR(15 downto 0);              
       
       Add_Data: inout STD_LOGIC_VECTOR(15 downto 0)
       
  );     
    
end Mem_IF;

architecture Behavioral of Mem_IF is 
    
  signal latched_addr : std_logic_vector (15 downto 0);
  signal data_out     : std_logic_vector (15 downto 0); 
  
  begin
  
  Add_Data <= data_out when (n_CS_0 = '0' and n_OE = '0' and n_WE = '1') else (others=>'Z');
   
   latch_addr : process (BCLK, n_Reset) is
   begin
      if(n_reset = '0') then 
      latched_addr <= (others=>'0');
    
      elsif (rising_edge(BCLK)) then
       if (n_CS_0 = '0' and ALE = '1') then
        
      latched_addr <= Add_Data;   
         end if;
    end if;   
   end process latch_addr;
       
   
   MEM_READ : process (BCLK, n_Reset) is
   begin
      if(n_reset = '0') then 
      Bus_Wait <= '0';
      data_out <= (others=>'0');
    
      elsif (falling_edge(BCLK)) then
       if (n_CS_0 = '0' and n_WE = '1' and n_OE = '0' and ALE = '0') then
        CASE (latched_addr) IS 
            
        WHEN H"00" =>   data_out <=  RO_Register_0;
        WHEN H"01" =>   data_out <= RO_Register_1;
        WHEN H"02" =>   data_out <=  RO_Register_2;
      
           WHEN OTHERS =>  data_out <=  (others=>'0');
  
    
        END CASE;
          
            Bus_Wait <= '1';
         end if;
    end if;   
   end process MEM_READ;
   
  
   MEM_WRITE : process (BCLK, n_Reset) is
   begin
      if(n_Reset = '0') then 
      Bus_Wait <= '0';
      data_out <= (others=>'0');
    
      elsif (falling_edge(BCLK)) then
       if (n_CS_0 = '0' and n_WE = '0' and n_OE = '1' and n_WP = '1' and ALE = '0') then
        
      Bus_Wait <= '0';
      
      CASE (latched_addr) IS 
            
        WHEN H"10" =>   WR_Register_0 <= Add_Data;     
                WHEN H"10" =>   WR_Register_1 <= Add_Data;             
                WHEN H"10" =>   WR_Register_2 <= Add_Data;     
        
        WHEN OTHERS =>  data_out <=  (others=>'0');
  
    
        END CASE;
         end if;
    end if;   
   end process MEM_WRITE;
 
 end  Behavioral;

Author: Markus F. (mfro)
Posted on:

Rate this post
0 useful
not useful
I would assume your manual should have a bus state diagram and I would 
also assume you'll probably need a state machine on the FPGA side that 
would resemble it.

Other than that, you'll most likely need a testbench to verify you have 
implemented the state machine correctly.

Without the detailed specs (no, I'm not going to read or even download 
it) it is difficult to be more specific.

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.