0
\$\begingroup\$
    `timescale 1ns / 1ps                    

    module Control(H, C, S, X, rst, clk);                   
    output reg[1:0] H, C;                   
    output [2:0] S;                 
    input X, rst, clk;                  

    reg[2:0] state, state_n;                    
    reg[4:0] cnt_12, cnt_34;                    
    reg[2:0] cnt_23, cnt_40;                    

    parameter   S0 = 3'd0,              
                    S1 = 3'd1,  
                    S2 = 3'd2,  
                    S3 = 3'd3,  
                    S4 = 3'd4;  
    parameter   green = 2'd0,               
                    yellow = 2'd1,  
                    red = 2'd2; 

    always @(posedge clk)                   
        if(rst) begin               
            state = S0;         
            cnt_12 = 5'd20;         
            cnt_23 = 3'd5;          
            cnt_34 = 5'd25;         
            cnt_40 = 3'd5;          
        end else                
            state = state_n;            

    always @(negedge clk)                   
        case(state)             
            S0 : begin if(X)            
                        state_n = S1;
                    else    
                        state_n = S0;
                  end       
            S1 : begin          
                    if(cnt_12 > 1) begin    
                        state_n = S1;
                        cnt_12 = cnt_12 - 1'd1;
                    end     
                    else begin  
                        state_n = S2;
                        cnt_12 = 5'd20;
                    end 
                  end       
            S2 : begin          
                    if(cnt_23 > 1) begin    
                        state_n = S2;
                        cnt_23 = cnt_23 - 1'd1;
                    end else begin  
                        state_n = S3;
                        cnt_23 = 3'd5;
                    end 
                    end 
            S3 : begin          
                    if(cnt_34 > 1) begin    
                        state_n = S3;
                        cnt_34 = cnt_34 - 1'd1;
                    end else begin  
                        state_n = S4;
                        cnt_34 = 5'd25;
                    end 
                    end 
            S4 : begin          
                    if(cnt_40 > 1) begin    
                        state_n = S4;
                        cnt_40 = cnt_40 - 1'd1;
                    end else begin  
                        state_n = S0;
                        cnt_40 = 3'd5;
                    end 
                    end 
            default : state_n = S0;         
        endcase             

    always @(posedge clk) begin                 
        H = green;              
        C = red;                
        case(state)             
            S0 : ;          
            S1 : ;          
            S2 : H = yellow;            
            S3 : begin H = red; C = green; end          
            S4 : begin H = red; C = yellow; end         
            default : ;         
        endcase             
    end                 
    assign S = state;                   
    endmodule                   

The code can be simulated correctly and get the right figure enter image description here

But when I try to get a bit fire and write it into my basys2, I got this error: enter image description here

I don't understand cause when cnt_12 or other reg change when rst turn high at posedge clk, they can also be assigned at negedge clk, will posedge and negledge time contend ? how can I solve this problem or modify my code ?

\$\endgroup\$
1
\$\begingroup\$

You are assigning the cnt_## signals in more than one always block. This is not allowed and results in a multiple driver error.

The code in question

always @(posedge clk)                   
    if(rst) begin               
        state = S0;         
        cnt_12 = 5'd20;         
        cnt_23 = 3'd5;          
        cnt_34 = 5'd25;         
        cnt_40 = 3'd5;          
    end else                
        state = state_n;            

always @(negedge clk) 

Always put begin and end around things - even if strictly not necessary. It makes things far clearer and stops mistakes like this.

always @(posedge clk) begin                 
    if(rst) begin               
        state = S0;         
        cnt_12 = 5'd20;         
        cnt_23 = 3'd5;          
        cnt_34 = 5'd25;         
        cnt_40 = 3'd5;          
    end else begin              
        state = state_n;            
    end
end

always @(negedge clk) begin
...
        cnt_12 = 5'd20;
...
end

Notice how the variable exists in two always blocks? This is never allowed.

You are also not allowed to clock a register with both a negative edge and a positive edge. Dual-Edge flip-flops do not exist is most FPGAs.

\$\endgroup\$
  • \$\begingroup\$ To add, non-blocking assignments (<=) should be used when assigning flops; blocking assignments (=) are for combinational logic. The synthesis tool should give a warning. \$\endgroup\$ – Greg Jun 29 '15 at 16:23
  • \$\begingroup\$ @Greg not always, but in this case I totally agree with you! There are times when blocking makes the code more succinct, but here it is just another potential debugging headache. \$\endgroup\$ – Tom Carpenter Jun 29 '15 at 18:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.