+ Post New Thread
Results 1 to 16 of 16
  1. #1
    Member level 2
    Points: 193, Level: 2

    Join Date
    May 2018
    Posts
    43
    Helped
    0 / 0
    Points
    193
    Level
    2

    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: 249,762, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,486
    Helped
    13214 / 13214
    Points
    249,762
    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.



    •   AltAdvertisment

        
       

  3. #3
    Full Member level 5
    Points: 1,575, Level: 9

    Join Date
    Oct 2015
    Posts
    247
    Helped
    36 / 36
    Points
    1,575
    Level
    9

    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.



  4. #4
    Super Moderator
    Points: 249,762, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,486
    Helped
    13214 / 13214
    Points
    249,762
    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.



  5. #5
    Member level 2
    Points: 193, Level: 2

    Join Date
    May 2018
    Posts
    43
    Helped
    0 / 0
    Points
    193
    Level
    2

    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: 249,762, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,486
    Helped
    13214 / 13214
    Points
    249,762
    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
    Member level 2
    Points: 193, Level: 2

    Join Date
    May 2018
    Posts
    43
    Helped
    0 / 0
    Points
    193
    Level
    2

    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



    •   AltAdvertisment

        
       

  8. #8
    Super Moderator
    Points: 249,762, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,486
    Helped
    13214 / 13214
    Points
    249,762
    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.



  9. #9
    Super Moderator
    Points: 29,664, Level: 42
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,843
    Helped
    1628 / 1628
    Points
    29,664
    Level
    42

    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



  10. #10
    Member level 2
    Points: 193, Level: 2

    Join Date
    May 2018
    Posts
    43
    Helped
    0 / 0
    Points
    193
    Level
    2

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

    Quote Originally Posted by FvM View Post
    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
    Can the initialization be done at declaration like


    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    reg  reg1 = init1;
    reg  reg2 = init2;
    always@(*)
    begin
      if (expression1)
        reg1 = a+b;
      else if ( expression2 )
        reg2 = c-d;
    end

    Is it allowed in Verilog for a synthsizable RTL to initialize the reg variables at declaration ?

    - - - Updated - - -

    Quote Originally Posted by FvM View Post
    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.
    Can a RTL for a FSM have internal reg vectors which are neither outputs of the FSM nor the reg variables for the present state and next state of the FSM? For example if we can declare a reg vector for a if-else iteration in Verilog like below in the next state logic of FSM for s and t ?

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    if (m < mem[(s+t)/2])
     
    t= (s+t)/2 -1;
     
    else if ( m > mem[(s+t)/2])
     
    s= (s+t)/2 +1;
     
    else
    ou = (s+t)/2 ;



  11. #11
    Super Moderator
    Points: 249,762, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,486
    Helped
    13214 / 13214
    Points
    249,762
    Level
    100

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

    Code:
    reg  reg1 = init1;
    Why not read the verilog language reference or simply trying if your compiler accepts it?


    The "variable declaration assignment" is the equivalent of a declaration plus initial statement.

    Code:
    reg  reg1;
    initial reg1 = init1;
    It's only executed once and thus not suitable for preventing latch generation in combinational always block.



  12. #12
    Member level 2
    Points: 193, Level: 2

    Join Date
    May 2018
    Posts
    43
    Helped
    0 / 0
    Points
    193
    Level
    2

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

    Quote Originally Posted by sky_above View Post

    Can a RTL for a FSM have internal reg vectors which are neither outputs of the FSM nor the reg variables for the present state and next state of the FSM? For example if we can declare a reg vector for a if-else iteration in Verilog like below in the next state logic of FSM for s and t ?

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    if (m < mem[(s+t)/2])
     
    t= (s+t)/2 -1;
     
    else if ( m > mem[(s+t)/2])
     
    s= (s+t)/2 +1;
     
    else
    ou = (s+t)/2 ;
    Can you please also answer the above?

    - - - Updated - - -



    Quote Originally Posted by FvM View Post
    Code:
    reg  reg1 = init1;
    Why not read the verilog language reference or simply trying if your compiler accepts it?


    The "variable declaration assignment" is the equivalent of a declaration plus initial statement.

    Code:
    reg  reg1;
    initial reg1 = init1;
    It's only executed once and thus not suitable for preventing latch generation in combinational always block.
    How will the latch generation can be prevented then for a combinational always block like below where we want s and t to get incremented or decremented by 1 in each iteration of the for loop? So here we cannot do s=0; t=0; ou = OU_DEF; just after the for loop declaration to avoid generation of latch.

    Code:
    for (i=0, i<=2n-1 -1 , i=i+1)
    begin
     
      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



  13. #13
    Super Moderator
    Points: 249,762, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,486
    Helped
    13214 / 13214
    Points
    249,762
    Level
    100

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

    Can a RTL for a FSM have internal reg vectors which are neither outputs of the FSM nor the reg variables for the present state and next state of the FSM? For example if we can declare a reg vector for a if-else iteration in Verilog like below in the next state logic of FSM for s and t?
    The variables have to be declared somewhere, which has been omitted in my code example snippet. It's not the point where the variables are declared. If the variable value is kept between iterations, combinational code synthesis may become difficult or even impossible, as mentioned by ads-ee.



  14. #14
    Member level 2
    Points: 193, Level: 2

    Join Date
    May 2018
    Posts
    43
    Helped
    0 / 0
    Points
    193
    Level
    2

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

    Quote Originally Posted by FvM View Post
    The variables have to be declared somewhere, which has been omitted in my code example snippet. It's not the point where the variables are declared. If the variable value is kept between iterations, combinational code synthesis may become difficult or even impossible, as mentioned by ads-ee.
    So if it is imlpemented as a FSM which is sequential the following question was asked? Can you please reply for that? You probably replied for the combinational always block by your above answer and not for FSM query. The ;ast post have two question one for combinational and another for sequential.

    Can a RTL for a FSM have internal reg vectors which are neither outputs of the FSM nor the reg variables for the present state and next state of the FSM? For example if we can declare a reg vector for a if-else iteration in Verilog like below in the next state logic of FSM for s and t?



  15. #15
    Super Moderator
    Points: 249,762, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,486
    Helped
    13214 / 13214
    Points
    249,762
    Level
    100

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

    I don't understand what you mean with internal reg. If you use regs in a clock sensitive always block, they are inferring storage elements (DFF, in some cases block RAM), no matter how they are declared. You can declare variables locally in a named always block, but that affects only the variable visibility, not the way it's synthesized.



    •   AltAdvertisment

        
       

  16. #16
    Super Moderator
    Points: 29,664, Level: 42
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,843
    Helped
    1628 / 1628
    Points
    29,664
    Level
    42

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

    Don't use for loops. If you can't code something without a for loop then the code is unsynthesizable. Only code that can be written without a for loop is synthesizable. A for loop is a convenience feature of Verilog to avoid writing repetitive code, it is not used as a way to perform temporal operations.

    - - - Updated - - -

    well it appears synthesis tools have gotten better at interpreting bad code...
    Tried the following code in Xilinx Vivado synthesis:
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    module test (
      input [3:0] in,
      output [3:0] ou
    );
     
    reg [3:0] s = 0;
    integer n;
     
    always @(*) begin
      for (n=0;n<3;n=n+1) begin : gen_s
        s = s + 1;
      end
    end
    assign ou = s + in;
     
    endmodule
    which results in the rather useless undefined feedback add loop
    Click image for larger version. 

Name:	Capture.PNG 
Views:	2 
Size:	12.6 KB 
ID:	146787
    and the following synthesis results, which also have an undefined start value for combonational feedback loop.
    Click image for larger version. 

Name:	Capture.PNG 
Views:	1 
Size:	43.2 KB 
ID:	146788

    This basically illustrates the uselessness of trying to code a feedback loop using a for loop, the initial value of 0 for the variable s does nothing as the result is a combainational loop. I didn't bother checking the synthesis report, but I'm sure it mentions there is a combonational loop in the code (which is a bad thing).



--[[ ]]--