FPGARelated.com
Forums

VHDL oddity

Started by Alex September 19, 2006
I would greatly appreciate if someone could explain the behavior I'm
seeing for me.

In the inner most if-state, where I write to bDATA_OUT ---- if I run
the program as written, it does nothing (my DATA_OUT lines remain in
the state they were previously).  If I remove the "else,   bDATA_OUT <=
"11000000"" segment, it properly outputs 00001010.  I don't understand
why it would work w/o the else, but not w/.

This is a snippet of a larger VHDL, trimmed down for debugging.

Thank you.

Alex McHale

entity driver is
    Port ( CLOCK : in  STD_LOGIC;
           ACTIVE : in STD_LOGIC;
           CLOCK_IN : in  STD_LOGIC;
           LATCH_IN : in  STD_LOGIC;
           DATA_IN : in  STD_LOGIC_VECTOR (7 downto 0);
           ADDRESS_IN : in  STD_LOGIC_VECTOR (4 downto 0);
           DATA_CLOCK_OUT : out STD_LOGIC;
           CLOCK_OUT : out  STD_LOGIC;
           LATCH_OUT : out  STD_LOGIC;
           DATA_OUT : out  STD_LOGIC_VECTOR (7 downto 0) );
end driver;

architecture Behavioral of driver is
    signal mode : STD_LOGIC := '0';
    signal column_out : STD_LOGIC_VECTOR(9 downto 0) := "0000000000";
    signal bDATA_OUT : STD_LOGIC_VECTOR(7 downto 0);
begin
    process( CLOCK )
    begin
        if( rising_edge( CLOCK ) ) then
            if mode='0' then
                CLOCK_OUT <= '0';
                LATCH_OUT <= '0';

                mode <= '1';
            elsif mode='1' then -- DATA INCOMING
                if column_out(0)='0' then
                    bDATA_OUT <= "00001010";
                else
                    bDATA_OUT <= "11000000";
                end if;

                CLOCK_OUT <= '1';
                LATCH_OUT <= '1';
                column_out <= column_out + 1;

                mode <= '0';
            end if;
        end if;
    end process;

    DATA_OUT <= bDATA_OUT;
end Behavioral;

Alex,

column_out is a 10 bit bus, and you are trying to compare it with a
single bit.

I think you forgot the 'others' keyword to force the compare to match
the constant with the thing being compared?

If this variable is a 6 bit counter:
(signal mhertz_count	: std_logic_vector(5 downto 0) ;)

mhertz_count <= (others => '0') ;

is the proper way to see if it is 0.

Austin

Alex wrote:
> I would greatly appreciate if someone could explain the behavior I'm > seeing for me. > > In the inner most if-state, where I write to bDATA_OUT ---- if I run > the program as written, it does nothing (my DATA_OUT lines remain in > the state they were previously). If I remove the "else, bDATA_OUT <= > "11000000"" segment, it properly outputs 00001010. I don't understand > why it would work w/o the else, but not w/. > > This is a snippet of a larger VHDL, trimmed down for debugging. > > Thank you. > > Alex McHale > > entity driver is > Port ( CLOCK : in STD_LOGIC; > ACTIVE : in STD_LOGIC; > CLOCK_IN : in STD_LOGIC; > LATCH_IN : in STD_LOGIC; > DATA_IN : in STD_LOGIC_VECTOR (7 downto 0); > ADDRESS_IN : in STD_LOGIC_VECTOR (4 downto 0); > DATA_CLOCK_OUT : out STD_LOGIC; > CLOCK_OUT : out STD_LOGIC; > LATCH_OUT : out STD_LOGIC; > DATA_OUT : out STD_LOGIC_VECTOR (7 downto 0) ); > end driver; > > architecture Behavioral of driver is > signal mode : STD_LOGIC := '0'; > signal column_out : STD_LOGIC_VECTOR(9 downto 0) := "0000000000"; > signal bDATA_OUT : STD_LOGIC_VECTOR(7 downto 0); > begin > process( CLOCK ) > begin > if( rising_edge( CLOCK ) ) then > if mode='0' then > CLOCK_OUT <= '0'; > LATCH_OUT <= '0'; > > mode <= '1'; > elsif mode='1' then -- DATA INCOMING > if column_out(0)='0' then > bDATA_OUT <= "00001010"; > else > bDATA_OUT <= "11000000"; > end if; > > CLOCK_OUT <= '1'; > LATCH_OUT <= '1'; > column_out <= column_out + 1; > > mode <= '0'; > end if; > end if; > end process; > > DATA_OUT <= bDATA_OUT; > end Behavioral; >
Oops,

You are comparing a single bit (one element) so I am wrong...

Austin


Austin Lesea wrote:
> Alex, > > column_out is a 10 bit bus, and you are trying to compare it with a > single bit. > > I think you forgot the 'others' keyword to force the compare to match > the constant with the thing being compared? > > If this variable is a 6 bit counter: > (signal mhertz_count : std_logic_vector(5 downto 0) ;) > > mhertz_count <= (others => '0') ; > > is the proper way to see if it is 0. > > Austin > > Alex wrote: >> I would greatly appreciate if someone could explain the behavior I'm >> seeing for me. >> >> In the inner most if-state, where I write to bDATA_OUT ---- if I run >> the program as written, it does nothing (my DATA_OUT lines remain in >> the state they were previously). If I remove the "else, bDATA_OUT <= >> "11000000"" segment, it properly outputs 00001010. I don't understand >> why it would work w/o the else, but not w/. >> >> This is a snippet of a larger VHDL, trimmed down for debugging. >> >> Thank you. >> >> Alex McHale >> >> entity driver is >> Port ( CLOCK : in STD_LOGIC; >> ACTIVE : in STD_LOGIC; >> CLOCK_IN : in STD_LOGIC; >> LATCH_IN : in STD_LOGIC; >> DATA_IN : in STD_LOGIC_VECTOR (7 downto 0); >> ADDRESS_IN : in STD_LOGIC_VECTOR (4 downto 0); >> DATA_CLOCK_OUT : out STD_LOGIC; >> CLOCK_OUT : out STD_LOGIC; >> LATCH_OUT : out STD_LOGIC; >> DATA_OUT : out STD_LOGIC_VECTOR (7 downto 0) ); >> end driver; >> >> architecture Behavioral of driver is >> signal mode : STD_LOGIC := '0'; >> signal column_out : STD_LOGIC_VECTOR(9 downto 0) := "0000000000"; >> signal bDATA_OUT : STD_LOGIC_VECTOR(7 downto 0); >> begin >> process( CLOCK ) >> begin >> if( rising_edge( CLOCK ) ) then >> if mode='0' then >> CLOCK_OUT <= '0'; >> LATCH_OUT <= '0'; >> >> mode <= '1'; >> elsif mode='1' then -- DATA INCOMING >> if column_out(0)='0' then >> bDATA_OUT <= "00001010"; >> else >> bDATA_OUT <= "11000000"; >> end if; >> >> CLOCK_OUT <= '1'; >> LATCH_OUT <= '1'; >> column_out <= column_out + 1; >> >> mode <= '0'; >> end if; >> end if; >> end process; >> >> DATA_OUT <= bDATA_OUT; >> end Behavioral; >>
Hi Alex,

I modeled this with ISE 7.1 and ModelSimXE III 6.0d and the
DATA_OUT alternates between 00001010 and 11000000 as I expected.

I am not sure what you expected to see.

Brad Smallridge
aivision



"Alex" <alexmchale@gmail.com> wrote in message 
news:1158680022.780556.64880@e3g2000cwe.googlegroups.com...
>I would greatly appreciate if someone could explain the behavior I'm > seeing for me. > > In the inner most if-state, where I write to bDATA_OUT ---- if I run > the program as written, it does nothing (my DATA_OUT lines remain in > the state they were previously). If I remove the "else, bDATA_OUT <= > "11000000"" segment, it properly outputs 00001010. I don't understand > why it would work w/o the else, but not w/. > > This is a snippet of a larger VHDL, trimmed down for debugging. > > Thank you. > > Alex McHale > > entity driver is > Port ( CLOCK : in STD_LOGIC; > ACTIVE : in STD_LOGIC; > CLOCK_IN : in STD_LOGIC; > LATCH_IN : in STD_LOGIC; > DATA_IN : in STD_LOGIC_VECTOR (7 downto 0); > ADDRESS_IN : in STD_LOGIC_VECTOR (4 downto 0); > DATA_CLOCK_OUT : out STD_LOGIC; > CLOCK_OUT : out STD_LOGIC; > LATCH_OUT : out STD_LOGIC; > DATA_OUT : out STD_LOGIC_VECTOR (7 downto 0) ); > end driver; > > architecture Behavioral of driver is > signal mode : STD_LOGIC := '0'; > signal column_out : STD_LOGIC_VECTOR(9 downto 0) := "0000000000"; > signal bDATA_OUT : STD_LOGIC_VECTOR(7 downto 0); > begin > process( CLOCK ) > begin > if( rising_edge( CLOCK ) ) then > if mode='0' then > CLOCK_OUT <= '0'; > LATCH_OUT <= '0'; > > mode <= '1'; > elsif mode='1' then -- DATA INCOMING > if column_out(0)='0' then > bDATA_OUT <= "00001010"; > else > bDATA_OUT <= "11000000"; > end if; > > CLOCK_OUT <= '1'; > LATCH_OUT <= '1'; > column_out <= column_out + 1; > > mode <= '0'; > end if; > end if; > end process; > > DATA_OUT <= bDATA_OUT; > end Behavioral; >
Yes, I hadn't yet modeled it.  It works fine in the simulator for me as
well.  The problem appears when I run it on our hardware.  So now I'm
left even more stumped.


Brad Smallridge wrote:
> Hi Alex, > > I modeled this with ISE 7.1 and ModelSimXE III 6.0d and the > DATA_OUT alternates between 00001010 and 11000000 as I expected. > > I am not sure what you expected to see. > > Brad Smallridge > aivision > > > > "Alex" <alexmchale@gmail.com> wrote in message > news:1158680022.780556.64880@e3g2000cwe.googlegroups.com... > >I would greatly appreciate if someone could explain the behavior I'm > > seeing for me. > > > > In the inner most if-state, where I write to bDATA_OUT ---- if I run > > the program as written, it does nothing (my DATA_OUT lines remain in > > the state they were previously). If I remove the "else, bDATA_OUT <= > > "11000000"" segment, it properly outputs 00001010. I don't understand > > why it would work w/o the else, but not w/. > > > > This is a snippet of a larger VHDL, trimmed down for debugging. > > > > Thank you. > > > > Alex McHale > > > > entity driver is > > Port ( CLOCK : in STD_LOGIC; > > ACTIVE : in STD_LOGIC; > > CLOCK_IN : in STD_LOGIC; > > LATCH_IN : in STD_LOGIC; > > DATA_IN : in STD_LOGIC_VECTOR (7 downto 0); > > ADDRESS_IN : in STD_LOGIC_VECTOR (4 downto 0); > > DATA_CLOCK_OUT : out STD_LOGIC; > > CLOCK_OUT : out STD_LOGIC; > > LATCH_OUT : out STD_LOGIC; > > DATA_OUT : out STD_LOGIC_VECTOR (7 downto 0) ); > > end driver; > > > > architecture Behavioral of driver is > > signal mode : STD_LOGIC := '0'; > > signal column_out : STD_LOGIC_VECTOR(9 downto 0) := "0000000000"; > > signal bDATA_OUT : STD_LOGIC_VECTOR(7 downto 0); > > begin > > process( CLOCK ) > > begin > > if( rising_edge( CLOCK ) ) then > > if mode='0' then > > CLOCK_OUT <= '0'; > > LATCH_OUT <= '0'; > > > > mode <= '1'; > > elsif mode='1' then -- DATA INCOMING > > if column_out(0)='0' then > > bDATA_OUT <= "00001010"; > > else > > bDATA_OUT <= "11000000"; > > end if; > > > > CLOCK_OUT <= '1'; > > LATCH_OUT <= '1'; > > column_out <= column_out + 1; > > > > mode <= '0'; > > end if; > > end if; > > end process; > > > > DATA_OUT <= bDATA_OUT; > > end Behavioral; > >
> Yes, I hadn't yet modeled it. It works fine in the simulator for me as > well. The problem appears when I run it on our hardware. So now I'm > left even more stumped.
You are scoping it? Or it's a video display? It could be a rise time issue if the clock is too fast. That would explain how you see the "0001010" when you leave the else statement out. Brad Smallridge aivision
>> > if column_out(0)='0' then >> > bDATA_OUT <= "00001010"; >> > else >> > bDATA_OUT <= "11000000"; >> > end if;
Alex,

Couple of things strike me as cause for concern, being rusty on my VHDL
I don't recall the semantics of incomplete specifications, ans would
hesitate to say any of these comments will help, but still...

1. if mode='0' clause does not define signals bDATA_OUT and
column_out[].
2. not sure why you have elsif mode='1' instead of just "else" --
synthesis is one thing but simulation considers 'X' 'U' 'Z' etc
(9-value logic) and it's prudent to have "else" specified.
3. synthesis and simulation may not implement logic identically.

HTH,

-rajeev-

Alex wrote:
> I would greatly appreciate if someone could explain the behavior I'm > seeing for me. > > In the inner most if-state, where I write to bDATA_OUT ---- if I run > the program as written, it does nothing (my DATA_OUT lines remain in > the state they were previously). If I remove the "else, bDATA_OUT <= > "11000000"" segment, it properly outputs 00001010. I don't understand > why it would work w/o the else, but not w/. > > This is a snippet of a larger VHDL, trimmed down for debugging. > > Thank you. > > Alex McHale > > entity driver is > Port ( CLOCK : in STD_LOGIC; > ACTIVE : in STD_LOGIC; > CLOCK_IN : in STD_LOGIC; > LATCH_IN : in STD_LOGIC; > DATA_IN : in STD_LOGIC_VECTOR (7 downto 0); > ADDRESS_IN : in STD_LOGIC_VECTOR (4 downto 0); > DATA_CLOCK_OUT : out STD_LOGIC; > CLOCK_OUT : out STD_LOGIC; > LATCH_OUT : out STD_LOGIC; > DATA_OUT : out STD_LOGIC_VECTOR (7 downto 0) ); > end driver; > > architecture Behavioral of driver is > signal mode : STD_LOGIC := '0'; > signal column_out : STD_LOGIC_VECTOR(9 downto 0) := "0000000000"; > signal bDATA_OUT : STD_LOGIC_VECTOR(7 downto 0); > begin > process( CLOCK ) > begin > if( rising_edge( CLOCK ) ) then > if mode='0' then > CLOCK_OUT <= '0'; > LATCH_OUT <= '0'; > > mode <= '1'; > elsif mode='1' then -- DATA INCOMING > if column_out(0)='0' then > bDATA_OUT <= "00001010"; > else > bDATA_OUT <= "11000000"; > end if; > > CLOCK_OUT <= '1'; > LATCH_OUT <= '1'; > column_out <= column_out + 1; > > mode <= '0'; > end if; > end if; > end process; > > DATA_OUT <= bDATA_OUT; > end Behavioral;
Brad Smallridge wrote:
>>Yes, I hadn't yet modeled it. It works fine in the simulator for me as >>well. The problem appears when I run it on our hardware. So now I'm >>left even more stumped. > > > You are scoping it? Or it's a video display? > > It could be a rise time issue if the clock is too fast. > That would explain how you see the "0001010" when you > leave the else statement out. > > Brad Smallridge > aivision > > > >>>> if column_out(0)='0' then >>>> bDATA_OUT <= "00001010"; >>>> else >>>> bDATA_OUT <= "11000000"; >>>> end if; > > >
What clock rate is this running at? Is it meeting timing? Having the "if" might slow the circuit down. Of course now that I think about it maybe not: tbit <= column_out(0); bDATA_OUT <= tbit & tbit & '0' & '0' & not tbit & '0' & not tbit & '0'; Can be used to replace the if, but the synthesizer is probably doing this already. -Dave -- David Ashley http://www.xdr.com/dash Embedded linux, device drivers, system architecture
Alex,
Its better to see your RTL shematic, anyway try this if it makes
difference.  Doubt if it is what you need :)

signal test std_logic;
...
    test <=  column_out(0);

    process( CLOCK )
    begin
        if( rising_edge( CLOCK ) ) then

            mode <= not(mode);
            CLOCK_OUT <= mode;
            LATCH_OUT <= mode;

            if mode='1' then -- DATA INCOMING
                bDATA_OUT <= 'test' &'test'&"00"& not(test) & '0' &
not(test) & '0';
                column_out <= column_out + 1;
            end if;

        end if;
    end process;
...

Alex wrote:
> Yes, I hadn't yet modeled it. It works fine in the simulator for me as > well. The problem appears when I run it on our hardware. So now I'm > left even more stumped. > > > Brad Smallridge wrote: > > Hi Alex, > > > > I modeled this with ISE 7.1 and ModelSimXE III 6.0d and the > > DATA_OUT alternates between 00001010 and 11000000 as I expected. > > > > I am not sure what you expected to see. > > > > Brad Smallridge > > aivision > > > > > > > > "Alex" <alexmchale@gmail.com> wrote in message > > news:1158680022.780556.64880@e3g2000cwe.googlegroups.com... > > >I would greatly appreciate if someone could explain the behavior I'm > > > seeing for me. > > > > > > In the inner most if-state, where I write to bDATA_OUT ---- if I run > > > the program as written, it does nothing (my DATA_OUT lines remain in > > > the state they were previously). If I remove the "else, bDATA_OUT <= > > > "11000000"" segment, it properly outputs 00001010. I don't understand > > > why it would work w/o the else, but not w/. > > > > > > This is a snippet of a larger VHDL, trimmed down for debugging. > > > > > > Thank you. > > > > > > Alex McHale > > > > > > entity driver is > > > Port ( CLOCK : in STD_LOGIC; > > > ACTIVE : in STD_LOGIC; > > > CLOCK_IN : in STD_LOGIC; > > > LATCH_IN : in STD_LOGIC; > > > DATA_IN : in STD_LOGIC_VECTOR (7 downto 0); > > > ADDRESS_IN : in STD_LOGIC_VECTOR (4 downto 0); > > > DATA_CLOCK_OUT : out STD_LOGIC; > > > CLOCK_OUT : out STD_LOGIC; > > > LATCH_OUT : out STD_LOGIC; > > > DATA_OUT : out STD_LOGIC_VECTOR (7 downto 0) ); > > > end driver; > > > > > > architecture Behavioral of driver is > > > signal mode : STD_LOGIC := '0'; > > > signal column_out : STD_LOGIC_VECTOR(9 downto 0) := "0000000000"; > > > signal bDATA_OUT : STD_LOGIC_VECTOR(7 downto 0); > > > begin > > > process( CLOCK ) > > > begin > > > if( rising_edge( CLOCK ) ) then > > > if mode='0' then > > > CLOCK_OUT <= '0'; > > > LATCH_OUT <= '0'; > > > > > > mode <= '1'; > > > elsif mode='1' then -- DATA INCOMING > > > if column_out(0)='0' then > > > bDATA_OUT <= "00001010"; > > > else > > > bDATA_OUT <= "11000000"; > > > end if; > > > > > > CLOCK_OUT <= '1'; > > > LATCH_OUT <= '1'; > > > column_out <= column_out + 1; > > > > > > mode <= '0'; > > > end if; > > > end if; > > > end process; > > > > > > DATA_OUT <= bDATA_OUT; > > > end Behavioral; > > >
Alex,

If I'm reading this correctly, it seems that column_out has no
'initial' state in HW.  As far as I know, setting default values in
signal declarations (i.e. what you've done) works fine in a simulator,
but this information gets lost in synthesis, and thus HW (though there
are ways around it via UCFs, etc.).

You are therefore trying to read a signal that hasn't been set to any
state, and increment it by 1.  Think of it as:

 column_out <= "XXXX"+1;

"column_out" must be set to some initial value i.e. include a reset
signal in your entity/architecture.

Ex.

entity ...
port (
    ...
    reset : in std_logic;
    ...
};

architecture
...
begin

    process (clk, reset)
    begin
        if reset = '1' then
             column_out <= (others => '0');
        elsif rising_edge(clk) then
             ...

Hope this helps, and I hope I didn't miss anything in previous posts.