Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Tri-State Signals

Status
Not open for further replies.

trump110

Programmer
Aug 9, 2007
1
US
I'm come across a stumbling block in my code and I was wondering if I could get a little help. I realize now that my background of higher level programming languages is hindering me. This is my first time doing anything complex with VHDL and my project deadline is to close to go back and do things right.

I wrote my code in blocks/functions and I'm using signals to pass information between blocks. One such signal is a group of 8 std_logic that is basically a control register internal to the chip. I am tri-stating the signals when not used, but compiling gives and error that the signals are multi-driven or directly/indirectly feeding itself.

Below are a couple sections of the code to show you what I'm trying to do. I greatly simplified things to keep it small, but this should give you a feel for things.

Any help would be great.

Code:
INIT:
 process (CLK)
 variable state     : integer range 0 to 15 := 0;
 begin
  if (CLK'EVENT and CLK = '1')
  then
   if (REG_0_HOLD(0) = '0')
   then
    REG_0_HOLD(1 to 7) <= "0000000";
    state := 0;
   else
    case state is
     when 0 =>
      RESETn_HOLD <= '0';
      START <= '0';
      state := state + 1;
     when 1 =>
      RESETn_HOLD <= '0';
      START <= '0';
      state := state + 1;
     when 2 =>
      RESETn_HOLD <= '1';
      START <= '0';
      state := state + 1;
     when 3 =>
      RESETn_HOLD <= '1';
      START <= '0';
      state := state + 1;
     when 4 =>
      RESETn_HOLD <= '1';
      START <= '0';
      state := state + 1;
     when 5 =>
      RESETn_HOLD <= '1';
      START <= '0';
      state := state + 1;
     when 6 =>
      RESETn_HOLD <= '1';
      START <= '0';
      state := state + 1;
     when 7 =>
      RESETn_HOLD <= '1';
      START <= '0';
      state := state + 1;
     when 8 =>
      RESETn_HOLD <= '1';
      START <= '0';
      state := state + 1;
     when 9 =>
      RESETn_HOLD <= '1';
      START <= '0';
      state := state + 1;
     when 10 =>
      RESETn_HOLD <= '1';
      START <= '0';
      state := state + 1;
     when 11 =>
      RESETn_HOLD <= '1';
      START <= '0';
      state := state + 1;
     when 12 =>
      RESETn_HOLD <= '1';
      START <= '0';
      state := state + 1;
     when 13 =>
      RESETn_HOLD <= '1';
      START <= '0';
      state := state + 1;
     when 14 =>
      RESETn_HOLD <= '1';
      START <= '0';
      state := state + 1;
     when others =>
      RESETn_HOLD <= '1';
      START <= '1';
      REG_0_HOLD <= "ZZZZZZZZ";
    end case;
   end if;
  end if;
 end process;

Code:
CONTROL:
 process (CLK)
 variable state   : integer range 0 to 7      := 0;
 begin
  if (CLK = '1' and START = '1')
  then
   case state is
    when 0 =>
     if (REG_0_HOLD(2) = '1' and REG_0_HOLD(3) = '0' and BUSY = '0')
     then
      ADD_RD <= REG_0_HOLD(4 to 7);
      state := state + 1;
     elsif (REG_0_HOLD(2) = '0' and REG_0_HOLD(3) = '1' and BUSY = '0')
     then
      ADD_WR <= REG_0_HOLD(4 to 7);
      if (REG_0_HOLD(4) = '0')
      then
       DATA_WR <= REG_2_HOLD;
      else
       DATA_WR <= REG_3_HOLD;
      end if;
      state := state + 1;
     else
      DATA_WR <= "ZZZZZZZZ";
      ADD_WR <= "ZZZZ";
      ADD_RD <= "ZZZZ";
      state := 0;
     end if;
    when 1 =>
     if(READ = '0' and REG_0_HOLD(2) = '1')
     then
      if (REG_0_HOLD(4) = '0')
      then
       REG_2_HOLD <= DATA_RD;
      else
       REG_3_HOLD <= DATA_RD;
      end if;
      REG_0_HOLD(2) <= '0';
      state := 0;
     elsif (WRITE = '0' and REG_0_HOLD(3) = '1')
     then
      REG_0_HOLD(3) <= '0';
      state := 0;
     else
      state := state;
     end if;
    when others =>
     NULL;
   end case;
  else
   DATA_WR <= "ZZZZZZZZ";
   ADD_WR <= "ZZZZ";
   ADD_RD <= "ZZZZ";
  end if;
 end process;
 
Hi Trump110,

The signal REG_0_HOLD is multi driven, because you assign a value to REG_0_HOLD(2) and REG_0_HOLD(3) in both processes above.

Another problem with REG_0_HOLD is, that you haven't assigned a value to it at states 0-14. This will cause undefined values and probrably will produce bad use of latches.

The third problem I can spot is the use of CLK. The second process isn't using the clock edge, but the positive clock level. This means that all vhdl within the if (CLK = '1' and START = '1') statement will be executed many times, while CLK and START are '1'. The number of executions depends on the speed of the circuit.

Keep in mind that every signal must always be defined! The following aren't always defined:

whitch where
------------------------------------------------------------
REG_0_HOLD state 0-14
ADD_RD elsif (REG_0_HOLD(2) = '0' and ..........
ADD_WR if (REG_0_HOLD(2) = '1' and REG..........
DATA_WR if (REG_0_HOLD(2) = '1' and REG..........

There are more signals in your code which aren't always defined. It is possible that some signals will function without defining them erverywhere, but it's good design practice to do so. You also generate latches (which you don't want) when you don't always define.

I hope this will help you a bit further.

Greatz,
Bert
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top