Error (10170): expecting "<=", or "=", or "+=", or "-=", or "*=", or "/=", or "%=", or "&=", or "|=", or "^=", etc

Error (10170): expecting "<=", or "=", or "+=", or "-=", or "*=", or "/=", or "%=", or "&=", or "|=", or "^=", etc

module accumulator (
    input [7:0] A ,
    input reset,
    input clk,
    output reg carryout,
    output reg overflow,
    output reg [8:0] S,
    output reg HEX0,
    output reg HEX1,
    output reg HEX2,
    output reg HEX3
    );

    reg signA;
    reg signS;
    reg [7:0] magA;
    reg [7:0] magS;
    reg Alarger;

    initial begin
        S = 9'b000000000;
    end

    always_ff @ (posedge clk, posedge reset) begin
        if (reset) begin
            S = 9'b000000000;
        end
        else begin

            begin
            signA <= A[7];              //Is A negative or positive
            signS <= S[7];
            S <= A + S;
            end

            if (signA == 1) begin           //A is negative so magnitude is of 2s compliment
                magA <= (~A[7:0] + 1'b1);
            end
            else begin
                magA <= A;
            end

            if (signS == 1) begin           //sum is negative so magnitude is of 2s compliment
                magS <= (~S[7:0] + 1'b1);
            end
            else begin
                magS <= S;
            end

            if (magA > magS) begin
                Alarger <= 1'b1;        //Magnitude of A is larger than magnitude of sum
            end
            else begin
                Alarger <= 1'b0;
            end

            if ((signA == 1) & (Alarger == 1) & (S[7] == 0)) begin
                overflow <= 1'b1;
            end
            else begin
                overflow <= 1'b0;
            end
            if ((signS == 1) & (Alarger == 0) & (S[7] == 0)) begin
                overflow <= 1'b1;
            end
            else begin
                overflow <= 1'b0;
            end
            if ((signS == 1) & (signA == 1) & (S[7] == 0)) begin
                overflow <= 1'b1;
            end
            else begin
                overflow <= 1'b0;
            end
            if ((signS == 0) & (signA == 0) & (S[7] == 1)) begin
                overflow <= 1'b1;
            end
            else begin
                overflow <= 1'b0;
            end
            if (S[8] == 1) begin            //carryout occurred
                carryout <= 1'b1;
                overflow <= 1'b0;
                S <= 9'b000000000;      //sum no longer valid
            end
            else begin
                carryout <= 1'b0;
            end

            display_hex h1                  //display of A
            (
                .bin            (magA),
                .hexl           (HEX2),
                .hexh           (HEX3)
            );

            display_hex h2                  //display of sum
            (
                .bin            (S[7:0]),
                .hexl           (HEX0),
                .hexh           (HEX1)
            );
        end
    end

endmodule 

我正在尝试制作一个累加器,将 A(可以有符号或无符号的 8 位二进制值)重复加到总和上。计算总和后,总和和 A 应在 4 个十六进制显示 LED 上显示该值(2 个 LED 用于 A,2 个 LED 用于总和)。但是,我很难编译它。我已经搜索了错误代码,它似乎是语法错误的一般错误,并且可以有多种含义。

我无法重现确切的错误,但是将 display_hex 的实例移到 always_ff 之外解决了主要问题:

module accumulator
(
    /* ... */
);
    // ...

    always_ff @ (posedge clk, posedge reset) begin
        /* ... */
    end

    display_hex h1 (
        /* ... */
    );

    display_hex h2 (
        /* ... */
    );
endmodule

另一件事:代码从 initialalways 驱动变量 S。这会创建多个驱动程序,代码将无法编译。要解决此问题,请完全删除初始值,您不需要它,因为 S 将在断言 reset 时设置为 0。

您可以将所有逻辑移动到初始块中;它看起来像这样(但这很可能不会合成):

initial begin
    S = 0;

    forever begin
        wait @(posedge clock);

        // Do stuff here ..
    end
end

错误是这两行的结果:

display_hex h1                  //display of A
(
  .bin            (magA),
  .hexl           (HEX2),
  .hexh           (HEX3)
);

display_hex h2                  //display of sum
(
  .bin            (S[7:0]),
  .hexl           (HEX0),
  .hexh           (HEX1)
);

在这里,您似乎有一个名为 display_hex 的模块,它将 8 位值转换为七段显示所需的数字。您正在尝试使用模块,就好像它是一个函数,而模块非常不是函数。 Verilog 中的模块(或您正在使用的 SystemVerilog,但此时的区别确实是象征性的)可以被认为是一组接受一些输入并吐出一些输出的硬件;重要的是要注意它们是静态的。它们要么存在于设计中,要么不存在;就像在面包板上使用 IC 一样。顶部模块是面包板,您在该模块下声明的模块是您插入电路板的组件。输入和输出是您必须连接才能使一切正常工作的各种连接(引脚)。

就是说,always 块(如您正在使用的 always_ff)形成了一种描述模块内部逻辑和寄存器的方式。因此,您确实认为在其中分配 logic/reg 变量来描述硬件的行为方式。如果您查看您的逻辑,您会注意到模块声明依赖于 reset;即如果 reset 被断言,这些模块将不存在,这没有任何意义。电信号不会使电路中的整个 IC 消失!因此,您需要从累加器的逻辑描述中提取模块声明,如下所示:

module accumulator (
  ...
  );
  ...
  display_hex h1                  //display of A
    (
      .bin            (magA),
      .hexl           (HEX2),
      .hexh           (HEX3)
    );

  display_hex h2                  //display of sum
    (
      .bin            (S[7:0]),
      .hexl           (HEX0),
      .hexh           (HEX1)
    );
  ...
  always_ff @(posedge clk, posedge reset) begin
    // Your accumulator logic here
    ...
  end
endmodule

请注意 display_hex 模块的模块声明是独立的,因为我声明这些模块存在,不依赖于任何东西!

但是,除此之外,您的设计还有许多问题:

  1. 当您使用 SystemVerilog 构造 (always_ff) 时,您应该声明所有变量类型 logic,而不是 reg 或留空(即, input clk 应该是 input logic clkreg signA 应该是 logic signA)。 logic 类型让一切变得更简单,所以使用它 :)

  2. 在你的 always_ff 块中,你正确地 reset 除了赋值应该是 NBA(使用 S <= 9'b0;,而不是 S = 9'b0; if (reset))

  3. 您在 always_ff 中使用了 NBA,这是正确的,但是,您似乎需要在以下逻辑中立即使用这些值。这不会像您预期的那样工作,或者至少不会在同一时钟周期内起作用。要解决此问题,您需要决定什么应该是寄存器,什么应该只是中间逻辑产生的值,然后为中间值创建一个单独的 always_comb

  4. 我假设 HEX 变量用于七段显示,因此它们应该至少声明 [6:0] HEXn