Bidirectional Bus problem with ModelSim.

Aug 01, 2005 3 Replies

Hello everyone! I am having a problem in ModelSim XE 5.8c with a very simple bidirectional bus. ModelSim outputs a bunch of XXXX's where its supposed to output data. I am using test bench waveforms with Xilinx ISE 6.303i.



Basically there are only 3 signals: the bidir. bus, wr_enable and clk. The idea behind this simple code is: if WR_EN is HIGH -> store bus data into a flip-flop on next clock edge.



else WR_EN is LOW -> output a constant value on the bus (in practice, I want to output something more useful, of course.)



Unfortunately, ModelSim outputs X's (don't cares) for every bit where the data in flip-flop conflicts with the constant. Let's say that 11110000 was stored in the flip-flop when WR_EN was high. And suppose that the constant to put on the bus is 00110000, when WR_EN goes low. When WR_EN actually does go low, ModelSim will output XX110000 instead of 00110000.



I think the problem might be with the way I designed the bus with VHDL. But I can't figure out where the problem is, and the code is VERY simple. Any help on this and maybe references to reading materials on bidirectional/tristate bus implementation in VHDL would be highly appreciated! Thanks, Pavel



Here is the code:



------------------------------ library IEEE; use IEEE.STD_LOGIC_1164.ALL;



------------------------------ ENTITY bidir_bus IS PORT( bidir : INOUT STD_LOGIC_VECTOR (7 DOWNTO 0); WR_en, clk : IN STD_LOGIC); END bidir_bus;



------------------------------ ARCHITECTURE Behavioral OF bidir_bus IS SIGNAL a : STD_LOGIC_VECTOR (7 DOWNTO 0); -- DFF that stores -- value from input. BEGIN PROCESS (WR_en, clk) BEGIN IF( WR_en = '1') THEN bidir


Not sure about your code. There might be an issue with the nesting of the if statements and whether the sensitivity list will allow both "ifs" to happen at the same time. You might want to rethink that.

Here is my code that I know works:

sram_read_data_pins_process:process(clk,reset) begin if(reset='1') then sram_read_data '0'); elsif(clk'event and clk='1') then if(sram_state_2 = sram_state_read ) then sram_read_data( 8 downto 0)

You are going to have several problems with the code. The fundamental problem is that the data is registered, but the wr_en is not. So what will happen is you set wr_en and the data, but the FPGA does not tristate the bus until one clock later. So you write junk on the first clock, and then valid data one clock later. Watch "a" during a wrote to see this happen.

The second problem is that when you pull wr_en low, you are apparently forgetting to tristate bus from the testbench you are using. So the testbench is driving the bus at the same time as the FPGA, resulting in X's on the bits that do not match.

Pavel,

I can see at least one fundamental problem, which is registered output. No need for references. Simply keep in mind that usually, bidirectional bus with tri-state is implemented without FFs, because when you sample 1'bz, the result is always 'X', BY LAW.

Try the following :

// sample dout assign dout = en ? dout1 : 1'bz; assign din = dout;

Hope this helps.

Vladislav

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required