drade13
drade13

Reputation: 31

Verilog if-else statements

I'm trying to write a module for a BCD counting stop watch. when I check the syntax I get errors saying:

ERROR:HDLCompilers:26 - "../counter.v" line 24 expecting 'end', found 'else'
ERROR:HDLCompilers:26 - "../counter.v" line 25 unexpected token: '='
ERROR:HDLCompilers:26 - "../counter.v" line 25 unexpected token: '+'
ERROR:HDLCompilers:26 - "../counter.v" line 25 expecting 'endmodule', found '1'

in the middle of my code. I'm not quite sure where the error is coming from and have tried to implement more begin/end but that did not fox the problem. Here is my code currently:

module BCDCount(en, clk, rst, direction, cTenths, cSec, cTS, cMin);
    input en, clk, rst, direction;
    output [3:0] cTenths, cSec, cTS, cMin;
    reg [3:0] cTenths, cSec, cTS, cMin;

always @(posedge clk)
if(en)
begin

    if(direction == 0)

        if(cMin== 4'b 1001)
                cMin <= 4'b 0000;
            if(cTS == 4'b 0101)
                cTS <= 4'b 0000;
                cMin = cMin +1;

                if(cSec == 4'b 1001)
                    cSec <= 4'b 0000;
                    cTS = cTS +1;
                    if(cTenths == 4'b 1001)
                        cTenths <= 4'b 0000;
                        cSec = cSec+1;
                    else 
                        cTenths = cTenths +1;
                else
                    cSec = cSec+1;
            else
                cTS = cTS + 1;

    if(direction == 1)

        if(cMin== 4'b 0000)
            cMin <= 4'b 1001;
            if(cTS == 4'b 0000)
                cTS <= 4'b 1001;
                cMin = cMin -1;
                if(cSec == 4'b  0000)
                    cSec <= 4'b 1001;
                    cTS = cTS -1;
                        if(cTenths == 4'b 0000)
                            cTenths <= 4'b 1001;
                            cSec = cSec-1;
                        else
                            cTenths = cTenths -1;
                else
                    cSec = cSec-1;
            else
                cTS = cTS - 1;

end
    always @(posedge rst)
        begin
            cMin <= 0;
            cTS <= 0;
            cSec <= 0;
            cTenths <= 0;
        end
endmodule 

Upvotes: 0

Views: 5327

Answers (1)

wilcroft
wilcroft

Reputation: 1635

Based on your indenting structure, it looks like you expect that for this code

  ...
        if(cTS == 4'b 0101)
            cTS <= 4'b 0000;
            cMin = cMin +1;
                if(cTenths == 4'b 1001)
  ...

Cmin = cMin + 1 will be executed in the case that cTS == 4'b0101. However, in Verilog, if statements only apply to the statement immediately preceding them (just like in C). To make them apply to multiple statements, we need to wrap those statements in begin-end blocks (just like {} in C).

So, you're getting errors that your code has an else statement, but it can't find the matching if!

You'll want to use the following:

  ...
        if(cTS == 4'b 0101)
        begin
            cTS <= 4'b 0000;
            cMin = cMin +1;
                if(cTenths == 4'b 1001)
            ...
        end
        else
  ...

Edit: Also of note - you're mixing blocking (=) and non-blocking (<=) assignments in your always block. For clocked always blocks, you should (basically) always use non-blocking assignments. Move any sequential assignment to their own always@(*) block.

You're also going to get errors that signals have multiple drivers, since you assign some signals values in multiple always blocks.

Upvotes: 2

Related Questions