Bidirectional Bus problem with ModelSim.

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

Reply to
Telenochek
Loading thread data ...

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)

Reply to
Brad Smallridge

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.

Reply to
Duane Clark

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

Reply to
Vladislav Muravin

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.