【问题标题】:Unable to Implement Simple ALU无法实现简单的 ALU
【发布时间】:2011-03-16 19:09:56
【问题描述】:

我有一个用 Verilog 描述的基本 8 位 ALU。我正在尝试实现该设计,但收到错误消息:

ERROR:NgdBuild:809 - output pad net 'quotient' 有非法负载: 块 Mmux_opcode[2]_GND_1_o_wide_mux_8_OUT81 上的引脚 I3,类型为 LUT6

该设计执行以下操作:加法、减法、乘法、除法、AND、OR、XOR 和 XNOR。有趣的是,Xilinx XST 无法合成除法器,除非被除以 2 倍(基本上是右移)。因此,为了解决这个问题,我使用了 Xilinx Core Generator 生成的 CORE IP 组件。它需要一个时钟(没有时钟启用或同步清除,并在大约 20 个时钟周期后输出正确的商和余数。核心本身可以在核心生成器程序的数学函数下找到。无论如何,这是我的代码:

`timescale 1ns / 1ps
module ALU8(A,B,opcode,clk,OUT);

// I/O
// We have two 16-bit inputs
input [7:0] A,B;
// The opcode determines our next operation
input [2:0] opcode;
// The processor clock
input clk;
// A 32-bit output
output [15:0] OUT;

// The inputs are wires
wire [7:0] A,B;
wire [2:0] opcode;

// The output is a register
reg [15:0] OUT;

// The quotient and remainder for tyhe divider
wire [7:0] quotient,remainder;
// Declare an internal dividing unit
Divider8 divider(.rfd(), .clk(clk), .dividend(A), .quotient(quotient), .divisor(B), .fractional(remainder));

// Define operation codes, there's only 9 so far
parameter   ADD = 3'b000;
parameter   SUB = 3'b001;
parameter   MUL = 3'b010;
parameter   DIV = 3'b011;
parameter   AND = 3'b100;
parameter   OR  = 3'b101;
parameter   XOR = 3'b110;
parameter   XNOR    = 3'b111;

// On the rising-edge of the clock
always @(posedge clk)
begin
    // The output is determined by the operation
    // Think of it as a MUX
    // A MUX8 will be added in later
    case(opcode)
        ADD: OUT <= A + B;
        SUB: OUT <= A - B;
        MUL: OUT <= A * B;
        DIV: OUT <= {quotient,remainder};
        AND: OUT <= A & B;
        OR:  OUT <= A | B;
        XOR: OUT <= A ^ B;
        XNOR: OUT <= A ~^ B;
        default: OUT <= 16'b0000000000000000;
    endcase
end
endmodule

显然我的代码很糟糕,我的 cmets 可能是错误的,但我只是 Verilog 的初学者。但是,我确实计划大大改进此代码并添加更多操作供我练习。该模块本身确实成功地合成和正确模拟,但我无法在任何 FPGA 上实现它。有谁知道是代码有问题,还是 Xilinx ISE(像往常一样充满了 bug),或者项目设置有问题?

编辑:我对代码进行了一些更改,以反映答案提供的建议。

【问题讨论】:

    标签: verilog fpga xilinx synthesis


    【解决方案1】:

    您的 coregen 项目中是否选择了“使用 IO 焊盘创建网表包装器”选项?从错误来看,Divider8 内核有一个 OBUF 或类似的输出缓冲器来驱动商输出。 OBUF 只能驱动离开 FPGA 的信号。

    另一个注意事项,尽管这与 ngdbuild 错误无关:通常在顺序块中使用非阻塞分配(“always @(posedge clk)”),例如“OUT

    【讨论】:

    • @Andy 不,我没有。您是说选中此选项可以解决问题吗?另外,感谢您的建议,我很乐意接受对我的代码和风格的任何建议或批评。
    • @seljuq70 不,我的意思是如果它被启用就关闭它,所以这不是问题。您是否有一份来自 coregen 的报告,其中显示了用于实现除法器的原语(LUT*、FF* 等...)?你能发布 ngdbuild 日志文件吗?
    • @Andy 不想问这个问题,但是我在哪里可以找到这样的文件,它会被称为什么?我看到一个 ngc 文件,仅此而已。
    • @seljuq70 ngdbuild 日志将具有 .bld 扩展名。它看起来不像 coregen 生成我想要的那种报告,但你可以执行“netgen -sim -ofmt verilog ngcfile.ngc ngcfile.extracted.v”来查看核心中使用了什么(如果提取. v 有 OBUF 实例,这是个问题)。另一件事要检查。您(或者您之前是否)自己合成了分频器?这可能会生成一个带有 I/O 缓冲区的 .ngc,即使 coregen 生成的 .ngc 没有它们。
    • @seljuq70 我在 ISE 中尝试了代码,没有任何问题。我的猜测是有一个过时的文件(来自自己实现分隔符)导致问题。您可以尝试创建一个新项目,复制 ALU8.v,然后在 coregen 中重新生成分隔符。或者作为一个更简单的实验,删除 Divider8.{bld,ngd,ngc}
    【解决方案2】:

    这不是答案,但我认为这些提示可能会改进您的代码。

    由于我没有你的Divider8 模块,我无法编译你的代码,除非我注释掉divider 实例。错误消息似乎与该实例有关。

    对于许多合成工具initial 块是不可合成的。由于我不使用 xilinx,我无法评论它的支持。也许你可以删除initial 块。

    最好使用非阻塞赋值(&lt;=)来合成时序逻辑。例如:

    case(opcode)
        ADD: OUT <= A + B;
        SUB: OUT <= A - B;
    

    您可以将常量重新编码为:

        default: OUT = {16{1'b0}};
    

    【讨论】:

    猜你喜欢
    • 2016-08-24
    • 2012-03-13
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 2012-02-23
    • 2012-02-15
    • 2014-07-02
    • 1970-01-01
    相关资源
    最近更新 更多