- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
So I wanted to take an input and decrement it in a combinational block.. here is the code I am talking about..always @ (posedge clock or posedge reset)
begin
if (reset)
begin
t0_reg <= 0;
t1_reg <= 20'd1;
n <= i;
end
else
begin
t0_reg <= t0_next;
t1_reg <= t1_next;
n <= n_next;
end
end
always @ (*)
begin
t0_next = t0_reg;
t1_next = t1_reg;
n_next = i;
if(n == 0) t0_next = 0;
else
begin
t1_next = t0_reg + t1_reg;
t0_next = t1_reg;
n_next = n - 1;
end
end
here i is a 4 bit input.. This circuit is for a fibonacci series.. When I made this I did not think this would work, because I thought at the end of the always @ * block the n_next signal would have been decremented by 1, but at the start of the same block it would again be assigned the value of i.. but what really happens is i keeps decrementing till it reaches 0.. and after it reaches 0 it gets the original value of i again and keeps going forever like this.. isnt this block read from top to bottom.. why does it appear that it stays in the else block till it decrements n_next to 0? Thanks
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your always @ (*) block will only update its outputs when the following signals change: t0_reg, t1_reg, i, or n.
So what is happening is that n_next is getting decremented when the block updates, but then that block does not update again until one of the signals listed above changes. So the event will be that the "always @ (posedge clock or posedge reset)" block will be updated on the next clock. But in that block n is being assigned the value of n_next (which was decremented). So now that "n" has changed the always @ (*) block will update sequentially. So first, n_next gets assigned the value of "i" but that doesn't matter because the if statement is false so n_next gets the value of n-1. This continues with n=n_next then n_next=n-1 until n==0 is true then n_next gets to keep the value of i. Hope this helps.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The behavior you mentioned is what I would expect... I think I never write combinational code in always statements like that. To me this would be much easier to understand ....
assign t1_next = (n == 0)? 0 : (t0_reg + t1_reg); assign t0_next = (n == 0)? t0_reg : t1_reg; assign n_next = (n == 0)? n : n - 1; If you are not familar with the terinary operator this is what it means: assign signal = (conditional)? true statement : false statement; So above when n equals 0 the statement before the colon is used, otherwise the statement after the colon is used (2:1 mux). If you use something with more statements then I recommend using case statements instead to implement the mux since a casescade of terinary operators uses priority (unless that's what you want).- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the helpful responses.
--- Quote Start --- So first, n_next gets assigned the value of "i" but that doesn't matter because the if statement is false so n_next gets the value of n-1. --- Quote End --- However I did not understand this.. How does it not matter as the value is assigned before the if statement.. need some clarification here please. --- Quote Start --- The behavior you mentioned is what I would expect... I think I never write combinational code in always statements like that. To me this would be much easier to understand ... --- Quote End --- Im familiar with this but with these statements I get confused with nested if's.. Thanks- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- However I did not understand this.. How does it not matter as the value is assigned before the if statement.. need some clarification here please. --- Quote End --- The value i does get assigned to n_next, but immediately after that once the if statement resvolves n_next gets the value of n-1. So, effectively you never see the assignment of the value of i to n_next. By the time the clocked process triggers, n_next is equal to n-1, not i. The only time n_next will retain the value of i (instead of being re-assigned to n-1) when the process resolves is when the if statement is true (i.e. n==0). So, if the clocked process we call Process1 and the always@(*) we call Process2 then follow through the logic of what happens... On reset Process1 n=i; --A change on 'n' triggers Process2 Process2 n_next=i; -- n_next gets set to i at first Process2 n_next=n-1; --since 'n' is not equal to zero -- reset state ends On clk Process1 n=n_next; --A change on 'n' triggers Process2 Process2 n_next=i; Process2 n_next=n-1; --since 'n' is not equal to zero On clk Process1 n=n_next; --A change on 'n' triggers Process2 Process2 n_next=i; Process2 n_next=n-1; --since 'n' is not equal to zero . . . --this continues until n_next==0 On clk Process1 n=n_next; --A change on 'n' triggers Process2 Process2 n_next=i; --since 'n' is now equal to zero then the whole thing starts over...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- The value i does get assigned to n_next, but immediately after that once the if statement resvolves n_next gets the value of n-1. So, effectively you never see the assignment of the value of i to n_next. By the time the clocked process triggers, n_next is equal to n-1, not i. The only time n_next will retain the value of i (instead of being re-assigned to n-1) when the process resolves is when the if statement is true (i.e. n==0). So, if the clocked process we call Process1 and the always@(*) we call Process2 then follow through the logic of what happens... On reset Process1 n=i; --A change on 'n' triggers Process2 Process2 n_next=i; -- n_next gets set to i at first Process2 n_next=n-1; --since 'n' is not equal to zero -- reset state ends On clk Process1 n=n_next; --A change on 'n' triggers Process2 Process2 n_next=i; Process2 n_next=n-1; --since 'n' is not equal to zero On clk Process1 n=n_next; --A change on 'n' triggers Process2 Process2 n_next=i; Process2 n_next=n-1; --since 'n' is not equal to zero . . . --this continues until n_next==0 On clk Process1 n=n_next; --A change on 'n' triggers Process2 Process2 n_next=i; --since 'n' is now equal to zero then the whole thing starts over... --- Quote End --- That was beautiful.. Many thanks for this detailed explanation.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page