0

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 
1

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

The SO also put the reset logic in a separate always block which is a big no-no for RTL. It should be moved into one always block: always @(posedge clk, posedge rst) begin if (rst) begin /* reset code here */ end else begin /* sequential code here */ end end

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.