EmbDev.net

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


von Max (Guest)


Rate this post
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!

von Markus F. (mfro)


Rate this post
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.

von Max (Guest)


Attached files:

Rate this post
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 )


1
entity Mem_IF is
2
3
    Port ( 
4
         RO_Register_0 :  in STD_LOGIC_VECTOR(15 downto 0);
5
       RO_Register_1 :  in STD_LOGIC_VECTOR(15 downto 0);
6
       RO_Register_2 :  in STD_LOGIC_VECTOR(15 downto 0);
7
                
8
       BCLK : in  STD_LOGIC;
9
         n_Reset: in STD_LOGIC;
10
           n_OE : in STD_LOGIC;
11
       n_WE: in STD_LOGIC;
12
       ALE: in STD_LOGIC;
13
       Bus_Wait: out STD_LOGIC;
14
       n_WP: in STD_LOGIC;
15
       n_CS_0: in STD_LOGIC;
16
       
17
       WR_Register_0 :  out STD_LOGIC_VECTOR(15 downto 0);
18
       WR_Register_1 :  out STD_LOGIC_VECTOR(15 downto 0);
19
       WR_Register_2 :  out STD_LOGIC_VECTOR(15 downto 0);              
20
       
21
       Add_Data: inout STD_LOGIC_VECTOR(15 downto 0)
22
       
23
  );     
24
    
25
end Mem_IF;
26
27
architecture Behavioral of Mem_IF is 
28
    
29
  signal latched_addr : std_logic_vector (15 downto 0);
30
  signal data_out     : std_logic_vector (15 downto 0); 
31
  
32
  begin
33
  
34
  Add_Data <= data_out when (n_CS_0 = '0' and n_OE = '0' and n_WE = '1') else (others=>'Z');
35
   
36
   latch_addr : process (BCLK, n_Reset) is
37
   begin
38
      if(n_reset = '0') then 
39
      latched_addr <= (others=>'0');
40
    
41
      elsif (rising_edge(BCLK)) then
42
       if (n_CS_0 = '0' and ALE = '1') then
43
        
44
      latched_addr <= Add_Data;   
45
         end if;
46
    end if;   
47
   end process latch_addr;
48
       
49
   
50
   MEM_READ : process (BCLK, n_Reset) is
51
   begin
52
      if(n_reset = '0') then 
53
      Bus_Wait <= '0';
54
      data_out <= (others=>'0');
55
    
56
      elsif (falling_edge(BCLK)) then
57
       if (n_CS_0 = '0' and n_WE = '1' and n_OE = '0' and ALE = '0') then
58
        CASE (latched_addr) IS 
59
            
60
        WHEN H"00" =>   data_out <=  RO_Register_0;
61
        WHEN H"01" =>   data_out <= RO_Register_1;
62
        WHEN H"02" =>   data_out <=  RO_Register_2;
63
      
64
           WHEN OTHERS =>  data_out <=  (others=>'0');
65
  
66
    
67
        END CASE;
68
          
69
            Bus_Wait <= '1';
70
         end if;
71
    end if;   
72
   end process MEM_READ;
73
   
74
  
75
   MEM_WRITE : process (BCLK, n_Reset) is
76
   begin
77
      if(n_Reset = '0') then 
78
      Bus_Wait <= '0';
79
      data_out <= (others=>'0');
80
    
81
      elsif (falling_edge(BCLK)) then
82
       if (n_CS_0 = '0' and n_WE = '0' and n_OE = '1' and n_WP = '1' and ALE = '0') then
83
        
84
      Bus_Wait <= '0';
85
      
86
      CASE (latched_addr) IS 
87
            
88
        WHEN H"10" =>   WR_Register_0 <= Add_Data;     
89
                WHEN H"10" =>   WR_Register_1 <= Add_Data;             
90
                WHEN H"10" =>   WR_Register_2 <= Add_Data;     
91
        
92
        WHEN OTHERS =>  data_out <=  (others=>'0');
93
  
94
    
95
        END CASE;
96
         end if;
97
    end if;   
98
   end process MEM_WRITE;
99
 
100
 end  Behavioral;

von Markus F. (mfro)


Rate this post
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.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.