I'm having a heck of a time trying to figure out how to connect the core generated Block RAM of a Xilinx Spartan 6 FPGA up to a bidirectional data bus. All the examples I can find say to just use the in and out data ports individually, but in my case I am forced to use it as a bidirectional data bus.
I am using VHDL.
The generated component has the following definition:
COMPONENT ram
PORT (
clka : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
Which is instantiated as follows:
ram1 : ram
PORT MAP (
clka => clk,
wea => r_w,
addra => addr,
dina => din,
douta => dout
);
Can someone show me a process block that will connect dina
and douta
to an inout
port called data
?
I tried the following, with 0% success:
process(clk)
begin
if rising_edge(clk) then
if r_w = "1" then
-- Write
din <= data;
dout <= temp;
else
-- Read
din <= (others => 'Z');
data <= dout;
end if;
end if;
end process;
Thank you for your assistance!
First of all, it's important to understand that internally to a modern FPGA (such as the Xilinx Spartan-6 you are talking about), there is not really any true bidirectional routing. Real bidirectional/tristate signals can only be used on I/O pins. Internal bidirectional/tristate signals can be emulated, but this is generally only done for interfacing with legacy HDL, not for anything new.
Now, regardless of whether there was true tristate or not, in order to hook up unidirectional dina
and douta
to the a "bidirectional" data
, you need some signal to control when the memory is driving or not. Since we have short names already, let's just call it oe
for "output enable". This signal will need to be controlled by your design in a way that make sense.
Given that, you can turn your two unidirectional signals in different directions plus your output enable direction selector into a logically bidirectional data bus with the following concurrent code (not in a process):
dina <= data;
data <= douta when oe = '1' else (others => 'Z');