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.

[SOLVED] Verilog Loop operation with registers.

Status
Not open for further replies.

ismailov-e

Member level 1
Joined
Jan 26, 2015
Messages
34
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
295
Hi
Who can help me please.
I want to make some loop operation. for example: use loop in register indexes


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
reg [7:0] res;
reg [7:0] buff
for (i = 0; i < 8 ; i = i + 1)
res <= buff[i+1:i] + i;
 
 
module integers( clock, res
    );
input clock;
output res;
wire clock;
reg [7:0] res;
reg [7:0] buff = 0;
genvar i;
 
    for (i = 0; i < 8 ; i = i + 1)
    begin 
    always@ (negedge clock)
        begin
            res <= buff + i;
            end
    end




it outputs only one. but should counts.
 
Last edited by a moderator:

You're misunderstanding loops. They are for generating parallel logic not a sequence in time. Output res can be only driven by one source, the shown code should give a multiple drivers error.

- specify what you exactly want to achieve
- read a Verilog text book or tutorial
- write a code that complies with Verilog syntax rules
- come back with specific questions about your design, if any
 

Actually i wrote separate code. But it seems merged.
For example i have a 8-bit register "res [7:0]". Let say i want to find positive value in each bits in this register. Count positive bits.
 

Actually i wrote separate code. But it seems merged.
For example i have a 8-bit register "res [7:0]". Let say i want to find positive value in each bits in this register. Count positive bits.
This kind of question can easily be looked up by you. Why make us do it. I found a post on edaboard that discusses this.

Use the advanced search and look for a post called "Count the number of 1's" as the title of the post.
 

What kind of "loop" do you want? Basically two options:

1 - Do you want something that loops in time?
2 - Do you want to unroll logic, so that you get multiple pieces of logic that execute simultaneously side by side (loop in space)?

Option 1) is typically what people want. And then they try (and fail) to use the loop keyword in verilog for that. This is precisely NOT how it works.

When you use the loop construct in verilog you actually get option 2.

So, repeat after me: loop in verilog does NOT loop temporally. loop in verilog loops spatially.

If you want something that loops in time you should use a counter.

If I look at your code you are already ahead of a large number of the "Don't know what looping does" crowd, because you do some things right. Buuuut there's also a few problems with it.

It would help if you can clearly state what your requirements are:

Should it produce a result every clock cycle? Or is it allowed to produce a result every 8th cycle for example.
What does "Count positive bits." mean exactly? I suspect you want to find the number of bits that is set to value of 1, but not 100% sure.

So do you want something like this?

input ==> output
8'b00000000 => 0
8'b00010000 => 1
8'b10000000 => 1
8'b00100110 => 3
8'b11111111 => 8
...
etc
 
  • Like
Reactions: dpaul

    dpaul

    Points: 2
    Helpful Answer Positive Rating
ok guys. i have this code:


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module integers( clock, res
    );
input clock;
output res;
wire clock;
reg [7:0] res;
reg [7:0] buff = 0;
genvar i;
 
for (i = 0; i < 8 ; i = i + 1) begin: test
    always@ (negedge clock)
        begin
                    buff[i] <= 1;
                    res <= buff;
        end
    end
 
 
endmodule



For each clock сycle it should output:
res = 00000001
res = 00000011
res = 00000111
.
till
res = 11111111
but it outputs:
everytime
res =1111111
it seem it shows last count. complete loop then outputs. Not every clock сycle.
what i want is:
buff <= 1;
when i = 1
buff[1] = 1
and outputs = 00000001
fist bit to set one;
then
buff[2] = 1 e.t.c

- - - Updated - - -


Code Verilog - [expand]
1
2
3
module integers( clock, res
    );
input clock;

I succed it with this code: Just i wanted to try how loop operation can handle that.


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
output res;
wire clock;
reg [7:0] res;
reg [7:0] buff = 0;
reg [7:0] count = 0;
genvar i;
 
//for (i = 0; i < 8 ; i = i + 1) begin: test
    always@ (negedge clock)
        begin
            count <= count + 1;
                    buff[count] <= 1;
                    res <= buff;
        end
    //end

 
Last edited by a moderator:

As suspected. I repeat the repeat after me part...

So, repeat after me: loop in verilog does NOT loop temporally. loop in verilog loops spatially.

If you want something that loops in time you should use a counter.

It's a common enough mistake, so no shame there. But it does help to read replies.

What you made there is 8 always blocks that exist and execute in parallel. I'll post the equivalent to help understand what's going on.

Your code:

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module integers( clock, res);
input clock;
output res;
wire clock;
reg [7:0] res;
reg [7:0] buff = 0;
genvar i;
 
for (i = 0; i < 8 ; i = i + 1) begin: test
    always@ (negedge clock)
    begin
       buff[i] <= 1;
       res <= buff;
    end
end
 
endmodule



Equivalent code with the generate loop explicitely unrolled:

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
30
module integers( clock, res);
input clock;
output res;
wire clock;
reg [7:0] res;
reg [7:0] buff = 0;
 
    // equivalent for i=0
    always @(negedge clock)
    begin
        buff[0] <= 1;
        res     <= buff;
    end
 
    // equivalent for i=1
    always @(negedge clock)
    begin
        buff[1] <= 1;
        res     <= buff;
    end
 
    // equivalents for i=2..6 go here
 
    // equivalent for i=7
    always @(negedge clock)
    begin
        buff[7] <= 1;
        res     <= buff;
    end
endmodule



And as you can imagine that is equivalent to:

Code Verilog - [expand]
1
2
3
4
5
6
7
...
    // equivalent with all the above always blocks lumped together
    always @(negedge clock)
    begin
        buff <= 8'b11111111;
        res  <= buff;
    end



And that is why you get that all ones (8'b11111111) result after one clock cycle.

And to repeat the repeated repetition:
If you want something that loops in time you should use a counter.

Hope that clear things up. :)

PS: Two more minor things. First, it generally gives better results to use spaces instead of tabs when posting code. Four (4) spaces for an indent is a reasonable value IMO. And the other minor thing is that it's considered better style to use this kind of module port declaration:


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
module integers(
    input            clock, // you could comment this, although clock is probably understood well enough
    output reg [7:0] res    // putting a short description of the "res" signal here will increase code readability
    );
    reg [7:0] buff = 0;
 
    always @(negedge clock)
    begin
        buff <= 8'b11111111;
        res  <= buff;
    end
endmodule



That's a bit shorter, and possibly more readable and maintainable.
 

in this code (count reg) can use as index for one bit and works well; but when i want to use multiple indexes it shows bug"count is not a constant" I mean when i wan't to use group of bits instead of code "buff[count] <= 1;" try "buff[count+1:count] <= 3;"


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module integers( clock, res
    );
input clock;
output res;
wire clock;
reg [7:0] res;
reg [7:0] buff = 0;
reg [7:0] count = 0;
genvar i;
 
//for (i = 0; i < 8 ; i = i + 1) begin: test
    always@ (negedge clock)
        begin
            count <= count + 1;
                    buff[count] <= 1;
                    res <= buff;
        end
    //end

 
Last edited by a moderator:

I have no idea what you mean. Can you rephrase the question?

That, and try to actually incorporate suggestions to improve your code readability:
- Your indents are haphazard and all over the place. use 4 spaces per indent. Why? Short version: least amount of trouble, and always works
- Do not put in commented bits of old code, unless these are specific to the problem being discussed. In this case your two commented lines have nothing to do with the rest of it.
- Better to post a complete module. Now we have to guess what comes after it. sometimes relevant, sometime not.
- And for bonus points you could use verilog-2001 ANSI style module port declarations, as shown to you in previous posts.

Anyways, main thing is I don't understand this... please rephrase:
in this code (count reg) can use as index for one bit and works well; but when i want to use multiple indexes it shows bug"count is not a constant"
 

I think the OP is trying to assign a slice.


Code Verilog - [expand]
1
2
// assign by pairs of indicies [1:0], [3:2], etc
buff[2*count +:2] <= 3;

 

    V

    Points: 2
    Helpful Answer Positive Rating
ads-ee Thanks a lot.
You have caught exact what i mean.
One question: is there any sources(books) where i can find such rools.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top