Forum Discussion

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

Help with statemachine/verilog

Hello to everyone, i am having a lot of trouble to work with state machines using verilog!

here is my code


module maquina_irig
    (
        clk_mi,
        rstn_mi,
        zero_mi,
        um_mi,
        p_mi,
        dez_mi,
        ts_mi,
        sinal_mi
    );
    
input clk_mi; // 20mhz from top
input rstn_mi; // reset from top
input zero_mi; // sinais irig com temporizacao
input um_mi;
input p_mi;
input dez_mi;
input ts_mi; // timestamp 
output sinal_mi; //sinal de saida
wire  ts_mi;
reg sinal_mi;
reg  current_state, next_state;
parameter idle = 0, send_p = 1, seconds =2;
             
always @ (posedge clk_mi or negedge rstn_mi)
        if (~rstn_mi)
         begin
                current_state <= idle;
         end
         else
         begin
                current_state <= next_state;
        end
        
always @ (posedge clk_mi)
    begin
        next_state = current_state;
        case (current_state)
            idle:                 next_state = send_p;
            send_p:                next_state = seconds;
            seconds:    next_state = idle;
            default:                next_state = idle;
        endcase
    end
always @ (posedge clk_mi)
    begin
        sinal_mi = 0;
        next_state = current_state;
        case (current_state)
            idle:                 ;
            send_p:                sinal_mi = p_mi;
            seconds:           ;
            default:             ;
        endcase
end
endmodule
I am having those errors


Error (10028): Can't resolve multiple constant drivers for net "next_state" at maquina_irig.v(61)
Error (10029): Constant driver at maquina_irig.v(41)
Error (10028): Can't resolve multiple constant drivers for net "next_state" at maquina_irig.v(61)
Error (10028): Can't resolve multiple constant drivers for net "next_state" at maquina_irig.v(61)
Any light in this darkness i am ? Thanks for the help..

Also if someone happens to know of any material about this subject i would be really thankful!

10 Replies

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

    The error is caused by simple violation of Verilog syntax. You can't drive the variable next_state in more than one place.

    But it's completely unclear, why you did it all. Apparently you have copied second always block without thinking. The assignment next_state = current_state; in the third always block is simply useless.

    In addition, assigning both next_state and current_state in an edge sensitive always block is far from a reasonable FSM design. It causes an unwanted delay of one clock cycle and possibly strange behaviour. I suggest to use FSM examples from a Verilog text book as astarting point.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Quartus II has a template menu option with some state machine implementations that you can look at. With a verilog or VHDL file open got to Edit --> Insert Template and choose the one you want to use.

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

    --- Quote Start ---

    Quartus II has a template menu option with some state machine implementations that you can look at. With a verilog or VHDL file open got to Edit --> Insert Template and choose the one you want to use.

    --- Quote End ---

    Thanks for the tip. I am using the Moore state machine now.

    My output is a 1bit reg.

    I want to send in one state two signals, "1" and "0" in the same state

    How can i do that? I can't just do

    Initial_State:

    begin

    out<= 1;

    out<= 0;

    end

    right?

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

    You apparently intend to send them sequentially. Using two states is the siimplest way..

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

    --- Quote Start ---

    You apparently intend to send them sequentially. Using two states is the siimplest way..

    --- Quote End ---

    Yes i've done that, but now my state machine has 20 states, where 10 of them is just a replicated state

    F.E

    
    SECOND:
                    begin
                        if(ts_mi==0)
                            sinal_mi <= zero_mi;
                        else if(ts_mi==1)
                            sinal_mi <= um_mi;
                    end
                    
                P_BEFORE_MINUTE:
                    begin
                    sinal_mi <= p_mi;
                    end
    

    I need to verify the bits on a byte reponsable for the seconds, then send a "p_mi" signal, and it goes like this untill years!

    seconds->p_mi->minuts->p_mi->hours-> ....... ->years

    All the p_before (minute/hour..etc) has the same code

    Same applies for the hour/minut etc..

    .. Is there some way to do a simplification?

    Thanks for the support
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I'm not sure if I understood what the statemachine is supposed to do but if this is just a realtime timer for keeping track of year:days:hours:minutes:seconds then I would just implement this as a bunch of modulo counters. When the 'second' counter hits 60 that enables the 'minute' counter to increment. Likewise when the 'minute' counter hits '60' you enable the 'hour' counter to increment.

    With separate counters you are just implement a bunch of simple but separate state machines. This approach is much easier since the state transitions become trivial because you are not trying to encode it all into one state machine.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Actually i have my counters that generate my timestamp and i am using my it to generate an IRIG-B signal

    this time machinal is to generate the irig-b signal. Is a little bit more complex than simple counters and my boss told me to do using state machines :D

    It's working now throught.. Thanks a lot for the support!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    but now my state machine has 20 states, where 10 of them is just a replicated state

    --- Quote End ---

    The other option is to use hiearchical state machines, in this case a simple sub state machine to perform a particular action, that is needed multiple times.