1

I am trying to pass an integer value to a module, but the IF statement does not work with the parameter. It throws the following error. I am new to Verilog so I have no idea how to make this work.

Error (10200): Verilog HDL Conditional Statement error at clock_divider.v(17): 
cannot match operand(s) in the condition to the corresponding edges in the enclosing
event control of the always construct

clock_divider.v module

module clock_divider (clockHandler, clk, rst_n, clk_o);

parameter DIV_CONST = 10000000 ;  // 1 second
parameter DIV_CONST_faster = 10000000 / 5;
input clockHandler;
input clk;
input rst_n;

output reg clk_o;

reg [31:0] div;
reg en;
integer div_helper = 0;

always @ (posedge clk or negedge rst_n)
begin
    if(clockHandler == 0)
    begin div_helper = DIV_CONST;
    end

    else
    begin div_helper = DIV_CONST_faster;
    end

    if (!rst_n)
    begin div <= 0;
          en <= 0;
    end

    else
    begin
        if (div == div_helper)
        begin div <= 0;
              en <= 1;
        end

        else
        begin div <= div + 1;
              en <= 0;
        end
    end
end

always @ (posedge clk or negedge rst_n)
begin
if (!rst_n)
begin
    clk_o <= 1'b0;
end
else if (en)
    clk_o <= ~clk_o;
end

endmodule

main.v module

reg clockHandler = 1;

// 7-seg display mux
always @ (*)
begin
    case (SW[2:0])
        3'b000: hexdata <= 16'h0188;
        3'b001: hexdata <= register_A ;
        3'b010: hexdata <= program_counter ;
        3'b011: hexdata <= instruction_register ;
        3'b100: hexdata <= memory_data_register_out ;
        3'b111: hexdata <= out;   
        default: hexdata <= 16'h0188;
    endcase

    if(SW[8] == 1)
    begin
      clockHandler = 1;
    end
    else
    begin
      clockHandler = 0;
    end
end

HexDigit d0(HEX0,hexdata[3:0]);
HexDigit d1(HEX1,hexdata[7:4]);
HexDigit d2(HEX2,hexdata[11:8]);
HexDigit d3(HEX3,hexdata[15:12]);


clock_divider clk1Hzfrom50MHz (
                clockHandler,
                CLOCK_50,
                KEY[3],
                clk_1Hz
                );

4 Answers 4

4

It's my understanding that the first statement in a verilog always block must be the if(reset) term if you're using an asynchronous reset.

So the flop construct should always look like this:

always @ (posedge clk or negedge rst_n) begin
   if(~rst_n) begin
       ...reset statements...
   end else begin
       ...all other statements...
   end
end

So for your case you should move the if(clockHandler==0) block inside the else statement, because it is not relevant to the reset execution. Even better would be to move it into a separate combinational always block, since mixing blocking and nonblocking statements inside an always block is generally not a good idea unless you really know what you're doing. I think it is fine in your case though.

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

Comments

0

To add to Tim's answer - the original code (around line 17, anyway) is valid Verilog.

What it's saying is "whenever there's a rising edge on clk or a falling edge on rst_n, check clockHandler and do something" (by the way, get rid of the begin/ends; they're redundant and verbose). The problem comes when you want to implement this in real hardware, so the error message is presumably from a synthesiser, which needs more than valid Verilog. The synth suspects that it has to build a synchronous element of some sort, but it can't (or won't, to be precise) handle the case where clockHandler is examined on an edge of both clk and rst_n. Follow the rules for synthesis templates, and you won't get this problem.

1 Comment

A common error is expanding an if statement, potentially just to include a $display and forgetting to add a begin ... end. everything looks good at first glance code indented correctly but now only the first line is included as part of the condition. I always recommend adding begin .. end statements, but in way that does not add too many extra lines, and indented correctly.
0

is this a compilation error or synthesis error? i used the same code to see if it compiles fine, and i din get errors.. Also, it is recommended to use "<=" inside synchronous blocks rather than "="

Comments

0

You're using the same flop construct for two different things. Linearly in code this causes a slipping of states. I always place everything within one construct if the states rely on that clock or that reset, otherwise you require extra steps to make sure more than one signal isn't trying to change your state.

You also don't need the begin/end when it comes to the flop construct, Verilog knows how to handle that for you. I believe Verilog is okay with it though, but I generally don't do that. You also don't have to use it when using a single statement within a block.

So your first module would look like this (if I missed a block somewhere just let me know):

clock_divider.v module (edited)

module clock_divider (clockHandler, clk, rst_n, clk_o);

parameter DIV_CONST = 10000000 ;  // 1 second
parameter DIV_CONST_faster = 10000000 / 5;
input clockHandler;
input clk;
input rst_n;

output reg clk_o;

reg [31:0] div;
reg en;
integer div_helper = 0;

always @ (posedge clk or negedge rst_n)
begin
    if(!rst_n)
    begin
        div <= 0;
        en <= 0;
        clk_o <= 1'b0;
    end
    else if(en)
    begin
        clk_o <= ~ clk_o;

        if(clockHandler == 0)
        begin 
            div_helper = DIV_CONST;
        end
        else
        begin 
            div_helper = DIV_CONST_faster;
        end
        else
        begin
            if (div == div_helper)
            begin 
                div <= 0;
                en <= 1;
            end
        end
        else
        begin 
            div <= div + 1;
            en <= 0;
        end
    end
end
end module

If that clk_o isn't meant to be handled at the same time those other operations take place, then you can separate everything else with a general 'else' statement. Just be sure to nest that second construct as an if-statement to check your state.

And also remember to add always @ (posedge clk or negedge rst_n) to your main.v module as Tim mentioned.

Comments

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.