错误(10170):期待“< =”,或“=”,或“+ =”,或“ - =”,或“* =”,或“/ =”,或“%=”或“& ; =“,或”| =“,或”^ =“等

时间:2015-10-05 12:25:21

标签: syntax-error verilog hdl intel-fpga accumulator

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位二进制值,可以是有符号或无符号)重复加到总和中。计算总和后,sum和A应显示4个十六进制显示LED上的值(A为2个LED,总和为2个LED)。但是,我很难将其编译。我已经搜索了错误代码,它似乎是语法错误的一般错误,可以有多种含义。

2 个答案:

答案 0 :(得分:1)

错误是这两行的结果:

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_ff)形成一种描述模块内逻辑和寄存器的方式。因此,您确实认为在其中分配logic / reg变量来描述硬件的行为方式。如果你看一下你的逻辑,你会注意到模块声明依赖于reset;即如果reset被断言,这些模块将不存在,这没有任何意义。电信号不会使电路中的整个IC消失!因此,您需要从您的acculumator的逻辑描述中提取模块声明,如下所示:

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或留空(即{{1} }应为input clkinput logic clk应为reg signA)。 logic signA类型只会让一切变得更简单,所以请使用它:)

  2. logic区块中,您正确always_ff,但分配应该是NBA(使用reset,而不是S <= 9'b0; S = 9'b0; }})

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

  4. 我假设always_comb变量适用于七个段显示,因此它们应该至少声明为HEX

答案 1 :(得分:0)

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

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

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

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

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

另一件事:代码驱动initial的变量S以及always。这会创建多个驱动程序,代码将无法编译。要解决此问题,请完全删除初始内容,因为S被置位时reset将设置为0,所以您不需要它。

OR

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

initial begin
    S = 0;

    forever begin
        wait @(posedge clock);

        // Do stuff here ..
    end
end