You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quartus中Verilog HDL语法错误10170排查求助

平方根计算Verilog模块Quartus编译语法错误排查

问题概述

复制的平方根计算Verilog模块在Quartus中编译时触发Error(10170)语法错误,错误指向输入端口定义的wire logic处,移除wire关键字后问题仍未解决。

错误信息

  • Error (10170): Verilog HDL syntax error at sqrtvg.sv(5) near text "logic"; expecting an identifier ("logic" is a reserved keyword ), or "[", or "signed", or "unsigned"
  • Error (10170): Verilog HDL syntax error at sqrtvg.sv(6) near text "logic"; expecting an identifier ("logic" is a reserved keyword ), or "[", or "signed", or "unsigned"
  • Error (10170): Verilog HDL syntax error at sqrtvg.sv(9) near text "logic"; expecting an identifier ("logic" is a reserved keyword ), or "[", or "signed", or "unsigned"
  • Error (10112): Ignored design unit "sqrtvg" at sqrtvg.sv(1) due to previous errors

原代码

module sqrt #(
    parameter WIDTH=8,  // width of radicand
    parameter FBITS=0   // fractional bits (for fixed point)
    ) (
    input wire logic clk,
    input wire logic start,             // start signal
    output     logic busy,              // calculation in progress
    output     logic valid,             // root and rem are valid
    input wire logic [WIDTH-1:0] rad,   // radicand
    output     logic [WIDTH-1:0] root,  // root
    output     logic [WIDTH-1:0] rem    // remainder
    );

    logic [WIDTH-1:0] x, x_next;    // radicand copy
    logic [WIDTH-1:0] q, q_next;    // intermediate root (quotient)
    logic [WIDTH+1:0] ac, ac_next;  // accumulator (2 bits wider)
    logic [WIDTH+1:0] test_res;     // sign test result (2 bits wider)

    localparam ITER = (WIDTH+FBITS) >> 1;  // iterations are half radicand+fbits width
    logic [$clog2(ITER)-1:0] i;            // iteration counter

    always_comb begin
        test_res = ac - {q, 2'b01};
        if (test_res[WIDTH+1] == 0) begin  // test_res ≥0? (check MSB)
            {ac_next, x_next} = {test_res[WIDTH-1:0], x, 2'b0};
            q_next = {q[WIDTH-2:0], 1'b1};
        end else begin
            {ac_next, x_next} = {ac[WIDTH-1:0], x, 2'b0};
            q_next = q << 1;
        end
    end

    always_ff @(posedge clk) begin
        if (start) begin
            busy <= 1;
            valid <= 0;
            i <= 0;
            q <= 0;
            {ac, x} <= {{WIDTH{1'b0}}, rad, 2'b0};
        end else if (busy) begin
            if (i == ITER-1) begin  // we're done
                busy <= 0;
                valid <= 1;
                root <= q_next;
                rem <= ac_next[WIDTH+1:2];  // undo final shift
            end else begin  // next iteration
                i <= i + 1;
                x <= x_next;
                ac <= ac_next;
                q <= q_next;
            end
        end
    end
endmodule

问题根源与解决方法

核心原因

代码使用了SystemVerilog语法(logic关键字、always_comb、always_ff、$clog2),但Quartus默认可能以Verilog-2001或更早标准编译,而logic在传统Verilog中是保留关键字但不能用于端口声明,导致语法报错。

解决方案

方案1:切换Quartus编译标准为SystemVerilog

  1. 打开Quartus工程,点击Assignments → Settings
  2. 在左侧导航栏选择Language Settings → Verilog HDL Input
  3. 将Verilog HDL version设置为SystemVerilog
  4. 重新编译工程

此时可保留SystemVerilog语法,只需移除端口声明中冗余的wire(logic会自动根据端口方向推断类型:输入为wire,输出为reg),修正后的端口声明如下:

input  logic clk,
input  logic start,             // start signal
output logic busy,              // calculation in progress
output logic valid,             // root and rem are valid
input  logic [WIDTH-1:0] rad,   // radicand
output logic [WIDTH-1:0] root,  // root
output logic [WIDTH-1:0] rem    // remainder

方案2:修改代码兼容Verilog-2001标准

如果需要兼容传统Verilog环境,将SystemVerilog特有的语法替换为Verilog兼容写法:

  • 端口声明中,input wire logic改为input wire,output logic改为output reg
  • 内部logic替换为reg(always块内的信号用reg)
  • always_comb改为always @*,always_ff @(posedge clk)改为always @(posedge clk)
  • $clog2替换为手动计算的位宽(可根据参数范围设定固定位宽,或开启Quartus扩展支持使用$clog2)

修正后的Verilog兼容代码示例:

module sqrt #(
    parameter WIDTH=8,  // width of radicand
    parameter FBITS=0   // fractional bits (for fixed point)
    ) (
    input wire clk,
    input wire start,             // start signal
    output reg busy,              // calculation in progress
    output reg valid,             // root and rem are valid
    input wire [WIDTH-1:0] rad,   // radicand
    output reg [WIDTH-1:0] root,  // root
    output reg [WIDTH-1:0] rem    // remainder
    );

    reg [WIDTH-1:0] x, x_next;    // radicand copy
    reg [WIDTH-1:0] q, q_next;    // intermediate root (quotient)
    reg [WIDTH+1:0] ac, ac_next;  // accumulator (2 bits wider)
    reg [WIDTH+1:0] test_res;     // sign test result (2 bits wider)

    localparam ITER = (WIDTH+FBITS) >> 1;  // iterations are half radicand+fbits width
    // 手动计算位宽,适配WIDTH=8的场景,可根据参数范围调整
    reg [3:0] i;            // iteration counter

    always @* begin
        test_res = ac - {q, 2'b01};
        if (test_res[WIDTH+1] == 0) begin  // test_res ≥0? (check MSB)
            {ac_next, x_next} = {test_res[WIDTH-1:0], x, 2'b0};
            q_next = {q[WIDTH-2:0], 1'b1};
        end else begin
            {ac_next, x_next} = {ac[WIDTH-1:0], x, 2'b0};
            q_next = q << 1;
        end
    end

    always @(posedge clk) begin
        if (start) begin
            busy <= 1;
            valid <= 0;
            i <= 0;
            q <= 0;
            {ac, x} <= {{WIDTH{1'b0}}, rad, 2'b0};
        end else if (busy) begin
            if (i == ITER-1) begin  // we're done
                busy <= 0;
                valid <= 1;
                root <= q_next;
                rem <= ac_next[WIDTH+1:2];  // undo final shift
            end else begin  // next iteration
                i <= i + 1;
                x <= x_next;
                ac <= ac_next;
                q <= q_next;
            end
        end
    end
endmodule

内容的提问来源于stack exchange,提问作者Antel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 21:44:51