FPGARelated.com
Forums

Bidirectional Bus problem with ModelSim.

Started by Telenochek August 1, 2005
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 <= "ZZZZZZZZ";
	    IF(clk'EVENT and clk='1') THEN
            a <= bidir;
	    END IF;
        ELSE
	    bidir <= "11110000"; -- simply output a constant on the bus
      -- of course, in practice I would like to
                                 -- output something else.
        END IF;
    END PROCESS;
END Behavioral;
------------------------------

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 <= (others => '0');
 elsif(clk'event and clk='1') then
   if(sram_state_2 = sram_state_read ) then
     sram_read_data( 8 downto 0) <= sramdqa;
     sram_read_data(17 downto 9) <= sramdqb;
     sram_data_valid <= '1';
   else
     sram_data_valid <= '0';
   end if;
 end if;
 end process;

 sram_outgoing_data_pipeline:process (clk,reset)
 begin
 if(reset='1') then
   sram_write_data_1 <= (others => '0');
   sram_write_data_2 <= (others => '0');
 elsif(clk'event and clk='1') then
   sram_write_data_1 <= sram_write_data_0;
   sram_write_data_2 <= sram_write_data_1;
 end if;
 end process;

 sramdqa <= sram_write_data_2( 8 downto 0) when (sram_w_3 = '0') else 
(others=>'Z');
 sramdqb <= sram_write_data_2(17 downto 9) when (sram_w_3 = '0') else 
(others=>'Z');




Telenochek wrote:
> 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.
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

"Telenochek" <interpasha@hotmail.com> wrote in message 
news:1122919805.341703.215660@g14g2000cwa.googlegroups.com...
> 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 <= "ZZZZZZZZ"; > IF(clk'EVENT and clk='1') THEN > a <= bidir; > END IF; > ELSE > bidir <= "11110000"; -- simply output a constant on the bus > -- of course, in practice I would like to > -- output something else. > END IF; > END PROCESS; > END Behavioral; > ------------------------------ >