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.

Wires in verilog code does not update immediately

Status
Not open for further replies.

Ameera Q

Newbie level 3
Joined
May 12, 2015
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
57
Salam everyone,
I'm new to the forum, I'll try to explain my problem step by step:

In my verilog code I have one top module and one sub module that is generated many times using generate for loop, the output of one sub-module is an input to the next,
These I/Os is declared as array of wires in the top module and I'm passing for example wire as input and wire[i+1] as output. each wire is a vector of let us say N bits.

Inside the sub-module the input is converted to 2D array and used to produce a 2D array reg that is converted to a vector and assigned to the output.


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//this is not my actual code but it is exactly what I'm doing
module sub (CLK,E,W_IN,W_OUT);
input CLK,E;
input wire [N-1 : 0] W_IN;
output wire[N-1 : 0] W_OUT;
 
wire [W-1 : 0] IN  [0 : N/W]; //2D array for input
reg [W-1 : 0] OUT [0 : N/W]; //2D array for output
 
//generate loop to convert from vector to 2D and vice versa
genvar i;
generate    
            for (i= 0; i< N/W; i= i+1) begin :loop
                assign W_OUT [(i+1)*W-1 -: W] = OUT[i]; 
                assign IN[i] = W_IN[(i+1)*W-1 -: W]; 
 
            end 
endgenerate
always @(posedge CLK or posedge E)  begin
// rest of code manipulates OUT



my problem is that the value of OUT is updated but the value of W_OUT is not updated until the next CLK :sad:
W_OUT is a wire it should be updated immediately as far as I know. So why it isn't updated immediately ?? Is there something wrong with the assignment ??

Thanks in advance.
 
Last edited by a moderator:

I don't know why this assignment doesn't happen when OUT changes.
Code:
assign W_OUT [(i+1)*W-1 -: W] = OUT[i];
Perhaps you should post an example that can be compiled, which exhibits the problem.

Note you could write an equivalent assignment that is easier to read like so:
Code:
assign W_OUT [i*W [COLOR="#FF0000"]+[/color]: W] = OUT[i];

Also this isn't be synthesizable:
Code:
always @(posedge CLK or posedge E)  begin
 

I don't know why this assignment doesn't happen when OUT changes.
Code:
assign W_OUT [(i+1)*W-1 -: W] = OUT[i];
Perhaps you should post an example that can be compiled, which exhibits the problem.

Thanks for your reply. I cant put my code it's very large and complicated.
I put a break-point inside the generate for loop and noticed that for different genvar value the statements inside the generate loop are executed in different times, (i.e when i = 0 the time is 135ns and when i =1 the time is 165ns, this is confusing me, I thought generate loop will be unrolled and all statement will be executed in the same time. :-?



Also this isn't be synthesizable:
Code:
always @(posedge CLK or posedge E)  begin

Why ?? this implements Asynchronous enable, how would I do it in another way ?
Thanks again.:smile:
 

Thanks for your reply. I cant put my code it's very large and complicated.
I put a break-point inside the generate for loop and noticed that for different genvar value the statements inside the generate loop are executed in different times, (i.e when i = 0 the time is 135ns and when i =1 the time is 165ns, this is confusing me, I thought generate loop will be unrolled and all statement will be executed in the same time. :-?
Like I said previously, write a testcase that exhibits the same behavior, which will allow someone to try the code out and see what is happening. My only guess (due to not having any useful code to go on) would be that your OUT inputs are being generated in a staggered fashion. (You also haven't proven it does what you say as there isn't any waveforms supplied to show the problem occurring.

Ameera Q said:
Why ?? this implements Asynchronous enable, how would I do it in another way ?
As the name of the second signal is E I assumed perhaps wrongly that it's not being used as a RESET or SET input to a FF, which you can make asynchronous, anything else won't synthesize. I assumed you were using E as either a clock or an enable (which appears to be the case). So unless it's an async reset/set then it won't work as coded. Hence the reason to always supply complete example code, either the actual code you are using or a sanitized testcase (that compiles and runs).

Don't forget to supply a testbench too!
 

Sorry for the late response, but when I was writing an example code, I noticed I was reading out the value at the same time of calculating the new desired value, so I solved the problem by postponing the read until the next CLK. Now when synthesizing the code I get the following warning about almost all my variables :
FF/Latch < > (without init value) has a constant value of 0 in block < >. This FF/Latch will be trimmed during the optimization process.
I'm reading these values from a 2D array (as a memory), So I think this is the problem.

I attached the example code here for your reference. The example is to do Bitwise ANDing for 2 large numbers by dividing the numbers into w-bit words and each sub module generated will be responsible for one bit of each word.
For example if we have 32bit numbers and divided into 8-bit words then we will need to generate 8 sub-modules, each sub-module is responsible for one bit of each 32/8 words.
(P.S This is an arbitrary example I come up with..)
the code runs correctly win simulated and produces the same warnings I get in my actual code.
Perhaps you could help me with them.
Thanks in advance.
 

Attachments

  • Sub.txt
    1.6 KB · Views: 57
  • tb.txt
    431 bytes · Views: 57
  • top.txt
    2.1 KB · Views: 71

You are using blocking assignments in a edge sensitive always block (i.e. to describe FFs), this is not recommended. Blocking assignments do not necessarily describe registers if the code uses the LHS output values on the RHS. In your case using blocking assignments shouldn't affect the results, but is a bad habit to get into as you will eventually write code that does not synthesized the same as it simulates. I advise you to read up on blocking vs. non-blocking assignments.

$display isn't a synthesizable, tasks are normally not something you would use in synthesizable code, functions yes, but only a much smaller subset of tasks can be synthesized (ones that behave just like a function), this one can be (disregarding the $display) as it contains no timing control statements (and could have been written as a function).


The code looks like someone who has experience writing software trying to apply how you break down problems in software to Verilog. You don't seem to be approaching Verilog from a hardware perspective, where you think of a digital circuit and describe that circuit using Verilog. In Verilog using for loops is just a means to replicate logic in a simple way without writing 100's of lines of unreadable code. Case in point is the use of a task to AND each bit makes no sense, the only time I can see working on individual bits makes sense is if the incoming data is serial. To do so with data that arrives as parallel data results in removing any benefit of using a higher level of abstraction to describe the circuit. You might as well write the code using instantiated AND gates. I'm wondering if the same issues apply to your actual design.
 

You are using blocking assignments in a edge sensitive always block (i.e. to describe FFs), this is not recommended. Blocking assignments do not necessarily describe registers if the code uses the LHS output values on the RHS. In your case using blocking assignments shouldn't affect the results, but is a bad habit to get into as you will eventually write code that does not synthesized the same as it simulates. I advise you to read up on blocking vs. non-blocking assignments.
Thanks for the advice. I changed my actual code and used non-blocking assignments to clear the registers in the else statement.
I can't use non-blocking in the (if) part because I need it to execute sequentially.
I have this for loop in my actual code in the if part to initialize SR_temp, is this OK ? i don't know another way to initialize it except that... and I think I can't use non-blocking assignment in it!

Code:
				for (ii = 0; ii <= W/2-2; ii = ii +1 )
				begin
					{C,SR_temp[i*W +: W]} = SR_temp[i*W +: W] + A[i*W] * (B[2*ii +: 2]<<(2*ii)) + C;
				end

another thing, is the use of non-blocking assignment will affect the CLK? i.e make it faster ?!

$display isn't a synthesizable,
Yes, I'm just using it in tracing the code.

tasks are normally not something you would use in synthesizable code, functions yes, but only a much smaller subset of tasks can be synthesized (ones that behave just like a function), this one can be (disregarding the $display) as it contains no timing control statements (and could have been written as a function).
I'm using tasks because the paper I'm working on describes the operations done as a task, so I thought they have used tasks in implementation, Should I change it to a function?

The code looks like someone who has experience writing software trying to apply how you break down problems in software to Verilog. You don't seem to be approaching Verilog from a hardware perspective, where you think of a digital circuit and describe that circuit using Verilog.
Yes, indeed. I have a problem with that. :-(

In Verilog using for loops is just a means to replicate logic in a simple way without writing 100's of lines of unreadable code.
hmmmmmm do you mean when I used for loop to clear registers ??. Is this the correct way??

Case in point is the use of a task to AND each bit makes no sense, the only time I can see working on individual bits makes sense is if the incoming data is serial. To do so with data that arrives as parallel data results in removing any benefit of using a higher level of abstraction to describe the circuit. You might as well write the code using instantiated AND gates. I'm wondering if the same issues apply to your actual design.
Yes you are right, but AND is just an example, I put it in a task to show you that I'm using tasks in my actual code.
In my actual code, each CLK, I read a word of the numbers stored in a memory and manipulating the whole word in the task.

The reason of dividing the numbers into words is to make a scalable design that could be applied to any size numbers. Actually the whole numbers should be stored in a memory and read out word by word. My design should have inputs of W-bit size to store the read numbers, but I didn't know how to link the design with a memory except the way I'm doing (by using 2D array). Perhaps you could advice me with that, and if you have some code examples or tutorials I'll appreciate it.

regarding the warning
FF/Latch < > (without init value) has a constant value of 0 in block < >. This FF/Latch will be trimmed during the optimization process.
What do you think is the reason -based on the code I attached previously- ?

Thanks for your help, really I appreciate it.
 

hi,
regarding the warning
FF/Latch < > (without init value) has a constant value of 0 in block < >. This FF/Latch will be trimmed during the optimization process.
What do you think is the reason -based on the code I attached previously-
this warning will come when your tool try to optimize the design.if you had any problem with the expected output go to behaviour model and solve it.
try to google the error code, it will give you more information
regards
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top