Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

multiple registers inside if-else of an always block

Status
Not open for further replies.

sky_above

Member level 2
Joined
May 14, 2018
Messages
43
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
375
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 a moderator:

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.
 

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.
 

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.
 

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 a moderator:

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).
 

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 - - -

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.

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 ?

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?


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 a moderator:

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.
 


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

 

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 - - -


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 ;

 

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.
 

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 - - -



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
 

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.
 

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?
 

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.
 

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
Capture.PNG
and the following synthesis results, which also have an undefined start value for combonational feedback loop.
Capture.PNG

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).
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top