Search code examples
verilogsystem-verilogquartus

Swapping 2 parameters in always_ff @


I have an issue with my code.

I'm trying to swap between Xspeed and Yspeed at the same clock while the if statement is true.

I'm getting the errors:

cant resolve multiple constant drivers for net

and

constant drivers at module_name

Several if statements show the same errors.

int Xspeed, topLeftX_FixedPoint; // local parameters 
int Yspeed, topLeftY_FixedPoint;



//////////--------------------------------------------------------------------------------------------------------------=
//  calculation 0f Y Axis speed using gravity or colision

always_ff@(posedge clk or negedge resetN)
begin
    if(!resetN) begin 
        Yspeed  <= INITIAL_Y_SPEED;
        topLeftY_FixedPoint <= INITIAL_Y * FIXED_POINT_MULTIPLIER;
    end 
    else begin
    // colision Calcultaion 
            
        //hit bit map has one bit per edge:  Left-Top-Right-Bottom
      if ((collision && HitEdgeCode [2] == 1 && HitEdgeCode[1]==1)) begin // hit top border of brick  
                if (Yspeed < 0 && Xspeed > 0) begin // while moving up and moving right
                        Yspeed <= Xspeed ;
                        Xspeed <= Yspeed ;  // negative move left 
                end
            end

The full the code:

// (c) Technion IIT, Department of Electrical Engineering 2021 
//-- Alex Grinshpun Apr 2017
//-- Dudy Nov 13 2017
// SystemVerilog version Alex Grinshpun May 2018
// coding convention dudy December 2018
// updaed Eyal Lev Feb 2021


module  pokadoor_moveCollision  (   
 
                    input   logic   clk,
                    input   logic   resetN,
                    input   logic   startOfFrame,  // short pulse every start of frame 30Hz 
                    input   logic   Y_direction,  //change the direction in Y to up  
                    input   logic   toggleX,    //toggle the X direction 
                    input logic collision,  //collision if smiley hits an object
                    input   logic   [3:0] HitEdgeCode, //one bit per edge 

                    output   logic signed   [10:0]  topLeftX, // output the top left corner 
                    output   logic signed   [10:0]  topLeftY  // can be negative , if the object is partliy outside 
                    
);


// a module used to generate the  ball trajectory.  

parameter int INITIAL_X = 320;
parameter int INITIAL_Y = 240;
parameter int INITIAL_X_SPEED = 60;
parameter int INITIAL_Y_SPEED = 150;
parameter int MAX_Y_SPEED = 230;
const int  Y_ACCEL = -1;

const int   FIXED_POINT_MULTIPLIER  =   64;
// FIXED_POINT_MULTIPLIER is used to enable working with integers in high resolution so that 
// we do all calculations with topLeftX_FixedPoint to get a resolution of 1/64 pixel in calcuatuions,
// we devide at the end by FIXED_POINT_MULTIPLIER which must be 2^n, to return to the initial proportions
const int   x_FRAME_SIZE    =   639 * FIXED_POINT_MULTIPLIER; // note it must be 2^n 
const int   y_FRAME_SIZE    =   479 * FIXED_POINT_MULTIPLIER;
const int   bracketOffset = 30;
const int   OBJECT_WIDTH_X = 64;

int Xspeed, topLeftX_FixedPoint; // local parameters 
int temp;
int Yspeed, topLeftY_FixedPoint;



//////////--------------------------------------------------------------------------------------------------------------=
//  calculation 0f Y Axis speed using gravity or colision

always_ff@(posedge clk or negedge resetN)
begin
    if(!resetN) begin 
        Yspeed  <= INITIAL_Y_SPEED;
        topLeftY_FixedPoint <= INITIAL_Y * FIXED_POINT_MULTIPLIER;
    end 
    else begin
    // colision Calcultaion 
            
        //hit bit map has one bit per edge:  Left-Top-Right-Bottom
      if ((collision && HitEdgeCode [2] == 1 && HitEdgeCode[1]==1)) begin // hit top border of brick  
                if (Yspeed < 0 && Xspeed > 0) begin // while moving up and moving right
                        Yspeed <= Xspeed ;
                        Xspeed <= Yspeed ;  // negative move left 
                end
            end
        if ((collision && HitEdgeCode [2] == 1 && HitEdgeCode[3]==1)) begin // hit top border of brick  
                if (Yspeed < 0 && Xspeed < 0) begin // while moving up and moving left
                        Yspeed <= -Xspeed ;
                        Xspeed <= -Yspeed ;  // negative move left 
                end
            end
        if ((collision && HitEdgeCode [2] == 1 && HitEdgeCode[3]==0 && HitEdgeCode[1]==0)) begin  // hit top border of brick  
                    if (Yspeed < 0) begin// while moving up
                         Yspeed <= -Yspeed ; 
                    end
        end

        
            ////
            
        if ((collision && HitEdgeCode [0] == 1 && HitEdgeCode[1]==1)) begin// || (collision && HitEdgeCode [1] == 1 ))   hit bottom border of brick  
                if (Yspeed > 0  && Xspeed > 0) begin//  while moving down and moving right
                        Yspeed <= -Xspeed ;
                        Xspeed <= -Yspeed ;
                end
        end
        if ((collision && HitEdgeCode [0] == 1 && HitEdgeCode[3]==1)) begin// || (collision && HitEdgeCode [1] == 1 ))   hit bottom border of brick  
                if (Yspeed > 0  && Xspeed < 0) begin//  while moving down and moving left
                        Yspeed <= Xspeed ;
                        Xspeed <= Yspeed ;
                end
        end
      if ((collision && HitEdgeCode [0] == 1 && HitEdgeCode[3]==0 && HitEdgeCode[1]==0 )) begin// || (collision && HitEdgeCode [1] == 1 ))   hit bottom border of brick  
                if (Yspeed > 0 ) begin//  while moving down
                        Yspeed <= -Yspeed ; 
                end
        end
        // perform  position and speed integral only 30 times per second 
        
        if (startOfFrame == 1'b1) begin 
        
                topLeftY_FixedPoint  <= topLeftY_FixedPoint + Yspeed; // position interpolation 
                
                if (Yspeed < MAX_Y_SPEED ) //  limit the spped while going down 
                        Yspeed <= Yspeed  - Y_ACCEL ; // deAccelerate : slow the speed down every clock tick 
        
                                
                if (Y_direction) begin // button was pushed to go upwards 
                        if (Yspeed > 0 ) // while moving down
                                Yspeed <= -Yspeed  ;  // change speed to go up 
                end ; 


        end
    end
end 

//////////--------------------------------------------------------------------------------------------------------------=
//  calculation of X Axis speed using and position calculate regarding X_direction key or colision

always_ff@(posedge clk or negedge resetN)
begin
    if(!resetN)
    begin
        Xspeed  <= INITIAL_X_SPEED;
        topLeftX_FixedPoint <= INITIAL_X * FIXED_POINT_MULTIPLIER;
    end
    else begin
    
                
    //  an edge input is tested here as it is a very short instance   
    //if (toggleX)  
    
                //Xspeed <= -Xspeed; 
                
    // collisions with the sides            
                if (collision && HitEdgeCode [3] == 1 && HitEdgeCode[0] ==0 && HitEdgeCode[2]==0)  begin
                    if (Xspeed < 0 ) // while moving left
                            Xspeed <= -Xspeed ; // positive move right 
                end
            
                if (collision && HitEdgeCode [1] == 1 && HitEdgeCode[0] ==0 && HitEdgeCode[2]==0 ) begin  // hit right border of brick  
                    if (Xspeed > 0 ) //  while moving right
                            Xspeed <= -Xspeed  ;  // negative move left    
                end
           
            
        if (startOfFrame == 1'b1 )//&& Yspeed != 0) 
    
                        topLeftX_FixedPoint  <= topLeftX_FixedPoint + Xspeed;
            
                    
    end
end

//get a better (64 times) resolution using integer   
assign  topLeftX = topLeftX_FixedPoint / FIXED_POINT_MULTIPLIER ;   // note it must be 2^n 
assign  topLeftY = topLeftY_FixedPoint / FIXED_POINT_MULTIPLIER ;    


endmodule

The error:

Error (10028): Can't resolve multiple constant drivers for net "Xspeed[31]" at pokadoor_moveCollision.sv(139) Error (10029): Constant driver at pokadoor_moveCollision.sv(62) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[30]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[29]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[28]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[27]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[26]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[25]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[24]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[23]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[22]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[21]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[20]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[19]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[18]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[17]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[16]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[15]" at pokadoor_moveCollision.sv(139) Error (10028): Can't resolve multiple constant drivers for net "Xspeed[14]" at pokadoor_moveCollision.sv(139) Error (12152): Can't elaborate user hierarchy "Pokadoor_Block_bdf:inst14|pokadoor_moveCollision:inst" Error: Quartus Prime Analysis & Elaboration was unsuccessful. 20 errors, 15 warnings Error: Peak virtual memory: 4797 megabytes Error: Processing ended: Thu Apr 14 14:26:35 2022 Error: Elapsed time: 00:00:07 Error: Total CPU time (on all processors): 00:00:16


Solution

  • Those error messages are not very specific. You can get more helpful messages from other simulators, such as the ones on edaplayground (Cadence and Synopsys).

    The problem is that you must not assign to the same signal from different always_ff blocks. For example, your code assigns to Xspeed from both always_ff blocks.

    Refer to IEEE Std 1800-2017, section 9.2.2.4 Sequential logic always_ff procedure:

    Variables on the left-hand side of assignments within an always_ff procedure, including variables from the contents of a called function, shall not be written to by any other process.

    You must restructure your code such that all assignments to Xspeed are done in the same always_ff block.