+ Post New Thread
Results 1 to 9 of 9
  1. #1
    Newbie level 6
    Points: 58, Level: 1

    Join Date
    May 2018
    Posts
    13
    Helped
    0 / 0
    Points
    58
    Level
    1

    multiple registers inside if-else of an always block

    There are 10 reg vectors defined in a rtl including two reg outputs of the rtl. The name of the reg vectors are reg1, reg2, reg3, reg4, reg5 ....There is a if-else statement in the rtl inside a combinational always block. When the first expression of the if-else statement evaluates true only the first reg named reg1 of the 10 reg vectors need to be assigned a new expression and other reg are not needed to be assigned new expressions. When the second expression of the if-else statement evaluates true only the second reg named reg2 of the 10 reg vectors need to be assigned a new expression and other reg are not needed to be assigned new expressions. So will the assignment for reg2, reg3, reg4... be as below for the first expression of the if-else statement or they need not be mentioned in the first expression of the if-else statement ?
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    if (expression1)
    reg1 = a+b;
    reg2 = reg2;
    reg3= reg3;
    reg4=reg4;
    reg5=reg5;
    ...............
    ...............
     
    else if ( expression2 )
    reg1 = reg1;
    reg2 = c-d;
    reg3= reg3;
    reg4=reg4;
    reg5=reg5;
    ...............
    ...............
    ...............
    ...............
    Last edited by ads-ee; 17th May 2018 at 15:42. Reason: added syntax tags

  2. #2
    Super Moderator
    Points: 243,288, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    42,258
    Helped
    12863 / 12863
    Points
    243,288
    Level
    100

    Re: multiple registers inside if-else of an always block

    Having either reg2 = reg2 or omitting an assignment to reg2 in a combinational always block is both creating latches, which is probably unwanted.


    To generate pure combinational logic, a default assignment for each variable should precede the conditional code.



    •   Alt16th May 2018, 15:34

      advertising

        
       

  3. #3
    Full Member level 5
    Points: 1,537, Level: 8

    Join Date
    Oct 2015
    Posts
    242
    Helped
    36 / 36
    Points
    1,537
    Level
    8

    Re: multiple registers inside if-else of an always block

    If you want to have the FlipFlop for those "registers", you Must use the non-blocking assignment.
    You are using Blocking assignment which can be inferred to combinational logic or latch.
    To improve one's brain, the doors are needed over the keys.



    •   Alt17th May 2018, 05:32

      advertising

        
       

  4. #4
    Super Moderator
    Points: 243,288, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    42,258
    Helped
    12863 / 12863
    Points
    243,288
    Level
    100

    Re: multiple registers inside if-else of an always block

    If you want to have the FlipFlop for those "registers", you Must use the non-blocking assignment.
    You are using Blocking assignment which can be inferred to combinational logic or latch.
    Not exactly correct. The essential point for latch synthesis is the said "combinational always block", no matter if you use blocking or non-blocking assignments. Blocking assignments in an edge sensitive always block can have several unwanted side effects, but will still infer registers.


    Nevertheless it's right to use non-blocking to model registered logic and blocking for combinational.

    - - - Updated - - -

    Referring to the original question, you need to define the intended functionality first.

    If a memory function is required (conditionally keeping the value of a variable), the logic should use a "registered" always block with edge event control.



    •   Alt17th May 2018, 09:28

      advertising

        
       

  5. #5
    Newbie level 6
    Points: 58, Level: 1

    Join Date
    May 2018
    Posts
    13
    Helped
    0 / 0
    Points
    58
    Level
    1

    Re: multiple registers inside if-else of an always block

    Quote Originally Posted by FvM View Post
    Having either reg2 = reg2 or omitting an assignment to reg2 in a combinational always block is both creating latches, which is probably unwanted.


    To generate pure combinational logic, a default assignment for each variable should precede the conditional code.
    Can we initialize registers just after a combinational block? For example can we do the following without violation Verilog syntax, sematics?
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    always (a.,b,c,d,e,....)
     
    reg1 = 10'b0;
    reg2 = 10'b1111011111;
    ....................
    ....................
     
    if (expression1)
    reg1 = a+b;
    reg2 = reg2;
    reg3= reg3;
    reg4=reg4;
    reg5=reg5;
    ...............
    ...............
     
    else if ( expression2 )
    reg1 = reg1;
    reg2 = c-d;
    reg3= reg3;
    reg4=reg4;
    reg5=reg5;
    ...............

    - - - Updated - - -

    The below code was tried for a binary search algorithm to search position of input m in the memory stor. In the if-else statement if (m < mem[(s+t)/2]) t is assigned but s is not assigned and when (m > mem[(s+t)/2]) assigned, then s is assigned but t is not. So what should be better to do for s and to here in this code?

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    
    module mname(m,ou);
     
    parameter n=6;
    parameter d=8;
    input [n-1 : 0] m;
    ouput [n-1 : 0] ou;
    reg [n-1 : 0] ou;
    reg [d-1,0]stor[n-1, 0];
    integer i;
    reg [n-1, 0] s = 0,t= 2(n)-1; /* 2(n) means 2 to the power n */
     
    always @(m)
     
    for (i=0, i<=(2(n-1))/2 , i=i+1) /* 2(n-1) means 2 to the power n-1 */
     
    if (m < mem[(s+t)/2])
     
    t= (s+n)/2 -1;
     
    else if ( m > mem[(s+t)/2])
     
    s= (s+n)/2 +1;
     
    else
    ou = (s+n)/2 ;
    i=(2(n-1))/2;
     
    endmodule
    Last edited by ads-ee; 17th May 2018 at 15:43. Reason: added syntax tags



  6. #6
    Super Moderator
    Points: 243,288, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    42,258
    Helped
    12863 / 12863
    Points
    243,288
    Level
    100

    Re: multiple registers inside if-else of an always block

    The default variable assignment is the correct way to avoid unwanted latches in combinational codes.

    As for the search code, I'm not sure what you want to achieve. Is it an exercise using Verilog as a programming language or intended for hardware synthesis? In the latter case, do you really want a fully parallel implementation performing the search in one clock cycle? Otherwise the search should be performed sequentially in clocked always block controlled by a state machine.

    I have difficulties to read the code due to semantic errors (missing variable declarations and respective initializations).



  7. #7
    Newbie level 6
    Points: 58, Level: 1

    Join Date
    May 2018
    Posts
    13
    Helped
    0 / 0
    Points
    58
    Level
    1

    Re: multiple registers inside if-else of an always block

    Quote Originally Posted by FvM View Post
    The default variable assignment is the correct way to avoid unwanted latches in combinational codes.
    Do you want to mean that initializing the reg variables as below just after the always block is a correct way according to Verilog? Can we initialize registers also while we are declaring reg variable like reg reg 5 = 18; reg reg6 = 12?
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    always (a.,b,c,d,e,....)
     
    reg1 = 10'b0;
    reg2 = 10'b1111011111;
    ....................
    ....................
     
    if (expression1)
    reg1 = a+b;
    reg2 = reg2;
    reg3= reg3;
    reg4=reg4;
    reg5=reg5;
    ...............
    ...............
     
    else if ( expression2 )
    reg1 = reg1;
    reg2 = c-d;
    reg3= reg3;
    reg4=reg4;
    reg5=reg5;
    ...............

    - - - Updated - - -

    Quote Originally Posted by FvM View Post
    As for the search code, I'm not sure what you want to achieve. Is it an exercise using Verilog as a programming language or intended for hardware synthesis?.
    Want to design a block which has a input m and the input will give a number whose location in the memory named stor will be the output of the block and the name of the output is ou. The memory named stor which is inside the block contains a sorted number. The given rtl was the rtl for the block.

    This is for Verilog intended for hardware synthesis.

    Quote Originally Posted by FvM View Post
    In the latter case, do you really want a fully parallel implementation performing the search in one clock cycle?
    The above code was for a fully parallel implementation or a combinational implementation. But was there any issues in the above code to be a synthesizable code for the above described block? Do we need to initialize reg variables named s and t anywhere in the above code ?

    Quote Originally Posted by FvM View Post
    Otherwise the search should be performed sequentially in clocked always block controlled by a state machine.
    Can you please describe how you will do that?


    Quote Originally Posted by FvM View Post
    I have difficulties to read the code due to semantic errors (missing variable declarations and respective initializations).
    The code or rtl of the above block is pasted again after minor changes?
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
    module mname(m,ou);
     
    parameter n=8;
    parameter d=10;
    input [n-1 : 0] m;
    output [n-1 : 0] ou;
    reg [n-1 : 0] ou;
    reg [d-1,0]stor[n-1, 0];
    integer i;
    reg [n-1, 0] s = 0;
    reg [n-1,0] t= 2n-1;
    always @(m)
     
    for (i=0, i<=2n-1 -1 , i=i+1) /* 2n means 2 to the power n. No superscript available to describe that. */
     
    if (m < mem[(s+t)/2])
     
    t= (s+n)/2 -1;
     
    else if ( m > mem[(s+t)/2])
     
    s= (s+n)/2 +1;
     
    else
    ou = (s+n)/2 ;
    i=2n-1 -1; /* 2n means 2 to the power n. No superscript available to describe that.  */
     
     
    endmodule
    Last edited by ads-ee; 17th May 2018 at 15:44. Reason: added syntax tags



  8. #8
    Super Moderator
    Points: 243,288, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    42,258
    Helped
    12863 / 12863
    Points
    243,288
    Level
    100

    Re: multiple registers inside if-else of an always block

    You'll also omit the useless identity assignments
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    always@(*)
    begin
      reg1 = init1;
      reg2 = init2;
      if (expression1)
        reg1 = a+b;
      else if ( expression2 )
        reg2 = c-d;
    end

    O.K. for hardware synthesis. If n is a small number, the parallel implementation is feasible, gives at least an interesting comparison to a serial solution.

    There are several issues with the design though. I don't apply to fix the syntax errors, you can try to compile the code and remove it one by one.


    It's however required to assure consistent initial conditions for all variables used in the iteration loop.

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    for (i=0, i<=2n-1 -1 , i=i+1)
    begin
      s=0; t=0; // necessary initial condition
      ou = OU_DEF; // to avoid latch generation 
      if (m < mem[(s+t)/2])
        t= (s+n)/2 -1;
      else if ( m > mem[(s+t)/2])
        s= (s+n)/2 +1;
      else
        ou = (s+n)/2 ;
    end

    Otherwise design a clocked always that performs one iteration step per clock cycle.



    •   Alt17th May 2018, 14:00

      advertising

        
       

  9. #9
    Super Moderator
    Points: 28,821, Level: 41
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,599
    Helped
    1595 / 1595
    Points
    28,821
    Level
    41

    Re: multiple registers inside if-else of an always block

    Code Verilog - [expand]
    1
    2
    
    for (i=0, i<=2n-1 -1 , i=i+1) /* 2n means 2 to the power n. No superscript available to describe that. */
    if (m < mem[(s+t)/2])
    This portion of code requires that mem is NOT a memory. Once the loop is unrolled all mem(xxxx) accesses are done in parallel, so it cannot be a memory.

    You do understand Verilog does not execute like a C program especially when written for synthesis, and if you attempt to do so (like you are trying to do) you'll end up with a huge slow combonational circuit.

    FYI, I also think you don't understand the reg keyword in Verilog does not mean a register is implied. It is a variable type not a register (hence the reason for creating the logic type in SystemVerilog, which takes the place of both reg and wire types and removes the confusion).

    - - - Updated - - -

    Besides I don't think your algorithm can be done in a single cycle as the algorithm you are using appears to require that s is stored between loop iterations, which implies a latch is necessary.

    Keep in mind that anything on the LHS of an assignment cannot show up on the RHS if you are writing combonational logic as that will require a latch.

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    
    // latch required in always @(*) blocks
    wire IN_sig;
    reg RHS_sig, LHS_sig
    // This is a latch as LHS_sig appears on the right hand side of the assignment.
    // i.e. if RHS_sig is low latch is transparent, if RHS_sig is high LHS_sig is latched.
    always @(*)
      LHS_sig = LHS_sig & RHS_sig || IN_sig & ~RHS_sig;
    end



--[[ ]]--