Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
7 years ago

Bit memorisation in if statement

Hi everyone,

First i'm sorry because i'm french, so my english may be bad.

My project consists to control many servo-motors via the DE0 Nano Board via UART.

In order to do that, i send serial data via a terminal like "100,120,80,200". There are 4 servos, 4 commands which are separated by commas, a character which is recognized like a separator to attribute the right value (pulse width) to the right servo via a counter incrementation.

For this separator, i've made a "block state" to not attribute the value of the "," character on my servo and wait the next value in my RX buffer.

My code will talks better than me :


sel_servo: process (reset_n, rx_buffer(d_width DOWNTO 1), clk, compteur)
begin
    if (reset_n = '0' OR compteur > 3) then
        compteur <= 0;
    elsif (clk'EVENT AND clk = '1') then
        if((rx_buffer(d_width DOWNTO 1) = "00101100") and block_state = '1') then
            compteur <= compteur + 1;
            block_state <= '0';
        else
            compteur <= compteur;
            block_state <= block_state;
            blockstate <= block_state;                                                 -- just watch the bit on LEDs
        end if;
    case compteur is
        when 0 =>
            if block_state = '0' and (rx_buffer(d_width DOWNTO 1) /= "00101100") then       -- "00101100" is the binary value for comma character
                block_state <= '1';
                posiS0 <= rx_buffer(d_width DOWNTO 1);
                pwmiS0 <= unsigned('0' & posiS0 ) + 64;
            end if;
        when 1 =>
            if block_state = '0' and (rx_buffer(d_width DOWNTO 1) /= "00101100") then            -- the "compteur" value represents the servo 
                block_state <= '1';
                posiS1 <= rx_buffer(d_width DOWNTO 1);
                pwmiS1 <= unsigned('0' & posiS1 ) + 64;            
            end if;
        when 2 =>
            if block_state = '0' and (rx_buffer(d_width DOWNTO 1) /= "00101100") then
                block_state <= '1';
                posiS2 <= rx_buffer(d_width DOWNTO 1);
                pwmiS2 <= unsigned('0' & posiS2 ) + 64;        
            end if;
        when 3 =>
            if block_state = '0' and (rx_buffer(d_width DOWNTO 1) /= "00101100") then
                block_state <= '1';
                posiS3 <= rx_buffer(d_width DOWNTO 1);
                pwmiS3 <= unsigned('0' & posiS3 ) + 64;
            end if;
        when 4 =>
            compteur <= 0;
        end case;
    end if;
end process;

This code compiles successfully.

My problem is that the "block_state" bit seems falls when i send a comma, but rises after immediatly. It didn't memorised his state, and i try a lot of different way but i didn't find any issues.

I hope i was clear in this description of my problem.

Thanks you !

6 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    No, I usually use GTKWave but it's not the easiest way to simulate... So I visualize all my signal with oscilloscope. Have you seen any problem in my code?

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Looking at other people's code is never very easy without the whole code and a testbench and some time. But then its usually much easier to debug it yourself. Altera provide modelsim for free. Have you tried using that?

    Notes on your code:

    
    if((rx_buffer(d_width DOWNTO 1) = "00101100") and block_state = '1') then
        compteur <= compteur + 1;
        block_state <= '0';
    else
    

    If d_width is NOT 8, then this statement will always be FALSE. Comparing two vectors of different lengths always returns false without any warnings. The same with the /= comparisons. If DWIDTH /= 8 then all of the /= compares will always be TRUE.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Of course I understand that it's not easy to debug it for you. I will try to simulate this tomorrow, I also tried modelsim, but it doesn't work because of some bugs, that's why I use GTKWave.

    D_width value is 8, and the value of "compteur" is incremented like expected (I've also checked that with some leds in the board).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Not in my code, in modelsim, I have tried it a few months ago when I've begun Fpga development, but it didn't work. It's a bug which seems come from my OS system, but don't worry about that. I will be back with the simulation and test bench tomorrow (in France, it's already 11 p.m !).

    Thanks you for your answers.