1

我正在尝试将整数值传递给模块,但该IF语句不适用于该参数。它引发以下错误。我是Verilog的新手,所以我不知道如何进行这项工作。

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 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 模块

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

4 回答 4

4

if(reset)我的理解是,如果您使用异步重置,verilog 中的第一条语句 always 必须是该术语。

所以翻牌结构应该总是这样:

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

因此,对于您的情况,您应该if(clockHandler==0)在语句内移动块else,因为它与重置执行无关。更好的做法是将它移到一个单独的组合 always 块中,因为在 always 块中混合阻塞和非阻塞语句通常不是一个好主意,除非你真的知道你在做什么。我认为在你的情况下这很好。

于 2013-06-03T03:48:22.073 回答
0

这是编译错误还是综合错误?我使用相同的代码来查看它是否可以正常编译,并且我会得到错误。另外,建议在同步块中使用“<=”而不是“=”

于 2013-06-05T07:01:12.410 回答
0

您对两个不同的事情使用相同的翻牌结构。在代码中线性地这会导致状态的滑动。如果状态依赖于该时钟或该重置,我总是将所有内容放在一个构造中,否则您需要额外的步骤来确保多个信号不会试图改变您的状态。

当涉及到翻牌结构时,您也不需要开始/结束,Verilog 知道如何为您处理。我相信 Verilog 可以接受它,但我通常不会那样做。在块中使用单个语句时,您也不必使用它。

所以你的第一个模块看起来像这样(如果我在某个地方错过了一个块,请告诉我):

clock_divider.v 模块(已编辑)

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

如果 clk_o 不打算在其他操作发生的同时进行处理,那么您可以使用通用的“else”语句将其他所有内容分开。只需确保将第二个构造嵌套为 if 语句来检查您的状态。

并且还记得添加 always @ (posedge clk or negedge rst_n) 到你的 main.v 模块,正如 Tim 提到的。

于 2013-06-05T22:06:51.573 回答
0

添加到蒂姆的答案 - 原始代码(无论如何在第 17 行左右)是有效的 Verilog。

它的意思是“只要有上升沿clk或下降沿rst_n,检查clockHandler并做某事”(顺便说一句,去掉开始/结束;它们是多余的和冗长的)。当您想在实际硬件中实现此功能时,问题就出现了,因此错误消息可能来自合成器,它需要的不仅仅是有效的 Verilog。合成器怀疑它必须构建某种同步元素,但它不能(或者不会,准确地说)处理在clockHandler边缘进行检查的情况。遵循合成模板的规则,你就不会遇到这个问题。 clkrst_n

于 2013-06-03T11:42:40.797 回答