Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21603 Discussions

Problems with Verilog % Modulo and if-Statements

Altera_Forum
Honored Contributor II
6,841 Views

Hi all, 

 

I got a problem with a normally relatively straightforward piece of Verilog code representing some modulo arithmetics and an if-statement. 

 

 

In the code below, the modulo of the registers a and b is calculated ( c=a mod b). The next if statement then checks if c, the result of the mod operation is equal to zero. 

 

Depending on how the values for a and b are put into the registers, the code works fine or produces rubbish: 

 

 

If the FIRST Option is used to obtain values for a and b, the condition of the if-statement doesn't become true and the following code isn't executed. 

 

However, if the SECOND Option is used to hardwire the values, the if-statement works fine. 

 

 

 

I already checked the output register c of the modulo operation which appears to be 4'b0000 in both cases. 

 

I'm stuck here and could really use some help on what's wrong with the modulo operation and/or the if-statement. 

 

I'm using Quartus II 10.0 Build 262 Web Edition on Ubuntu 10.04 LTS. The testing is done on the actual hardware, a Cyclone II FPGA on a TS7300 Board by embeddedarm. 

 

If you need any more information, I'll be more than happy to supply. 

 

Any help is appreciated, 

 

Regards, 

 

Jonas Lindmann 

 

 

reg ip; reg iq; reg iStage; reg a; reg b; reg c; always @(posedge wb_clk_i) begin // FIRST OPTION: Calculate a and b ip = 3'b001; // 1 iq = 3'b011; // 3 iStage = 3'b010; // 2 a = iq + 1'b1; // 4 = 3 + 1 b = 1'b1<<(iStage); // 4 // --------------------------------- // SECOND OPTION "Hardwire" a and b // a = 4'b0100; // 4 // b = 4'b0100; // 4 // --------------------------------- c = a % b; // 0 = 4 mod 4 if (c == 4'b0000) begin // Do something // This code here is never executed when using 1st option. end else begin // Do something else end end
0 Kudos
9 Replies
Altera_Forum
Honored Contributor II
4,852 Views

As written, the code generates no logic, because everything is constant and can be evaluated at compile time. And both set of constants refer to the first if case, at least with my Quartus version. Thus I assume that the code in your test has been different. Without knowing the real thing, I don't want to guess what happened. 

 

As a more general comment, you're writing Verilog like sequential C code. Did you understand, how the generated logic will look like? The complete chain of blocking assignments has to be calculated in a single clock cycle by hardwired logic. That's possible for simple constructs, but not the usual way to write logic programs. 

 

Most text books suggest to use nonblocking statements in sequential code (edge sensitive always blocks).
0 Kudos
Altera_Forum
Honored Contributor II
4,852 Views

Hi FvM, 

Hi all, 

 

thanks a lot for you quick reply. I think I didn't explain my actual problem in a proper manner... 

 

To clarify: 

This code was broken down to only show the core of the problem. In "real life", the registers ip, iq, and iStage will be fed from an external module. Thus, the values will of course change. 

 

As already mentioned, the core problem is the modulo operation and the if-statement taking the result of the mod operation which appears when the registers take these very values hardwired in the code.  

 

The comparison ==4'b0000 does somehow now work properly and always the code in the else statement is executed. 

 

To clarify another point:  

The two "OPTIONS" in the code should be exchanged. This is to clarify that if you use the result of the mod operation in the if statement, it doesn't work properly. However, if you hardwire the values, the if-statement works fine. So just (un)comment of the options and see the difference when it comes to the if-statement. 

 

If you need any more information, I'll be more than happy to supply. 

 

Thanks again, 

 

Jonas
0 Kudos
Altera_Forum
Honored Contributor II
4,852 Views

Jonas, 

 

Maybe it's because you stripped the code down to a small snippet. For me it seems you mix-up a program and a model. If there is an edge triggered block @(posedge wb_clk_i) and blocking assignments inside the block than in most cases there is this mix-up. I recommend to use non-blocking assigmnents and to keep in mind that all assignments execute in parallel. The if statement never takes the result from the aforementioned modulo operation at the same clock edge.  

 

Harald
0 Kudos
Altera_Forum
Honored Contributor II
4,852 Views

It looks like you calculate, in the same procedural block, the values for 'a' and 'b'. use these values to calculate 'c', use 'c' to decide what to do. 

 

All is done using 'blocking' statement. 

 

this is dangerous.  

You should recode using: 

1) non_blocking statement in describing circuits; 

2) One procedural block for each signal. 

3) separate sequential logic from combinational logic. 

 

More practically. Use a combinational block that calculates c as a function of a and b. 

use a sequential block that, when the clock edge arrives, decide what to do as a function of c value. 

 

From what I know the use of blocking statements will probably cause difference between functional and gate level simulations.
0 Kudos
Altera_Forum
Honored Contributor II
4,852 Views

 

--- Quote Start ---  

If you need any more information, I'll be more than happy to supply. 

--- Quote End ---  

 

If you want to get an answer, post a compilable example that reproduces the problem (generating real logic, not something that's considered a fake by the compiler). 

 

One more point about the blocking statements. At least the statements generating the output from the sequential block should be non-blocking. Intermediate results assigned by blocking statements will effectively generate combinational logic in front of the final registered value. It's O.K., when you know, what you're doing and the timing is acceptable for your design.
0 Kudos
Altera_Forum
Honored Contributor II
4,852 Views

Hi all, 

 

thanks for you help and your comments on my code. I think the code again needs some review and definitely needs to be done from a point of view which is more "hardware". 

 

However, I do not fully understand what you mean by using combinational logic for doing the calculations.  

 

So here's as far as I understood you: 

 

1) The Calculations of a, b, and c should NOT be done in an "always" block 

2) The if-statement is then executed in an "always" block triggered by the clock 

 

What does that mean for me? 

How can I create the calculation outside of the always statement? 

Do I maybe even have to implement a module for each of the calculations? 

 

How do I correctly trigger all this stuff?  

 

By the way: What's the deal with the always blocks? Can I rely on the code being executed like e.g. in a C environment or does timing matter here? 

In other words: is it guaranteed that the code is properly executed sequentially? 

 

Thanks a lot! 

 

Jonas Lindmann
0 Kudos
Altera_Forum
Honored Contributor II
4,852 Views

It is not tru that combinational block should not use always block. 

 

In your case: 

 

--- Quote Start ---  

 

always @(iq,iStage) 

begin 

c <= (iq + 1'b1) % (1'b1<<(iStage)); 

end 

 

--- Quote End ---  

 

 

is a combinational block. 

It can also be written without the always statement as: 

 

--- Quote Start ---  

 

assign c = (iq + 1'b1) % (1'b1<<(iStage)); 

 

--- Quote End ---  

 

 

By the way, are you sure that shifting a 1 bit signal (1'b1) provides a signal with more than one bit? 

 

Maybe that, if iStage is a two bit signal the maximum shift is three positions, the command should be: 

 

--- Quote Start ---  

 

assign c = (iq + 1'b1) % (4'b0001<<(iStage)); 

 

--- Quote End ---  

 

 

Not sure about this however...
0 Kudos
Altera_Forum
Honored Contributor II
4,852 Views

 

--- Quote Start ---  

 

By the way: What's the deal with the always blocks? Can I rely on the code being executed like e.g. in a C environment or does timing matter here? 

In other words: is it guaranteed that the code is properly executed sequentially? 

 

--- Quote End ---  

 

 

 

In a procedural block the commands are executed sequentially. 

Timing has no influence on this. 

 

If you use blocking assignments '=', (for example to assign a value to variable Y) and you use Y again to assigna a value to Z. Z is calculated using the new value of Y. 

 

If you use non blocking assignments '<=', (for example to assign a value to variable Y) and you use Y again to assigna a value to Z. Z is calculated using the value of Y before entering in the always statement. In this case Y is updated only when exiting from the always statement. 

 

Hope it helps. 

Better to read a Verilog book regarding these aspects.
0 Kudos
Altera_Forum
Honored Contributor II
4,852 Views

Hi all, 

 

thanks a lot for all your very helpful remarks. I will keep them in mind when redesigning the code. 

 

Thanks again, 

 

Jonas
0 Kudos
Reply