无法实现简单的 ALU
我有一个用 Verilog 描述的基本 8 位 ALU。我正在尝试实现该设计,但收到错误消息:
ERROR:NgdBuild:809 - output pad net 'quotient<1>'有非法负载: 模块 Mmux_opcode[2]_GND_1_o_wide_mux_8_OUT81 上的引脚 I3,类型为 LUT6
该设计执行以下运算:加法、减法、乘法、除法、AND、OR、XOR 和 XNOR。有趣的是,除非被除数除以 2(基本上是右移),否则 Xilinx XST 无法合成除法器。因此,为了解决这个问题,我使用了 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
显然我的代码很糟糕,我的评论可能是错误的,但我只是 Verilog 的初学者。但是,我确实计划大大改进此代码并添加更多操作供我练习,该模块本身确实成功地进行了正确的综合和模拟。我无法在任何 FPGA 上实现它。任何人都知道代码或 Xilinx ISE(像往常一样充满错误)或项目设置是否有问题
?代码,以反映答案提供的建议。
I have a basic 8-bit ALU described in Verilog. I am trying to implement the design, but I am getting error messages:
ERROR:NgdBuild:809 - output pad net 'quotient<1>' has an illegal load:
pin I3 on block Mmux_opcode[2]_GND_1_o_wide_mux_8_OUT81 with type LUT6
The design does the following operation, addition, subtraction, multiplication, division, AND, OR, XOR, and XNOR. The interesting thing about it is the fact that Xilinx XST cannot synthesis a divider unless the dividend is being divided by a factor of 2 (basically shifting right). So to take care of this I used a CORE IP component generated by Xilinx Core Generator. It takes in a single clock (no clock enable or synchronous clear, and outputs the correct quotient and remainder after about 20 or so clock cycles. The core itself can be found under math functions in the Core Generator program. Anyway, here's my code:
`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
Obviously my code terrible and my comments are probably erroneous, but I am just a beginner with Verilog. However, I do plan on improving this code greatly and adding more operations for me to practice. The module itself does successfully synthesis and simulate correctly, but I am unable to implement it on any FPGA. Anyone know if there is a problem with the code, or Xilinx ISE (which is full of bugs as usual), or maybe the project settings?
EDIT: I've made a few changes to the code, to reflect the advice provided by the answers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的 coregen 项目中是否选择了“使用 IO 焊盘创建网表包装器”选项?从错误来看,Divider8 内核有一个 OBUF 或类似的输出缓冲区来驱动商输出。 OBUF 只能驱动离开 FPGA 的信号。
另请注意,尽管这与 ngdbuild 错误无关:通常在顺序块中使用非阻塞分配(“始终@(thoughtge clk)”),例如“OUT <= A + B”。对此的简短解释是,它推迟更新 OUT 信号,直到处理完当前时间的所有其他事件,这避免了模拟器中的竞争条件。
Do you have the "Create netlist wrapper with IO pads" option selected in your coregen project? From the error it sounds like the Divider8 core has an OBUF or similar output buffer driving the quotient output. OBUF can only drive a signal that is leaving the FPGA.
Another note, although this is not related to the ngdbuild error: normally non-blocking assignments are used in sequential blocks ("always @(posedge clk)"), e.g. "OUT <= A + B". The short explanation of this is that it defers updating the OUT signal until all other events for the current time have been processed, which avoids race conditions in the simulator.
这不是答案,但我认为这些技巧可能会改进您的代码。
由于我没有您的
Divider8
模块,因此无法编译您的代码,除非我注释掉divider
实例。错误消息似乎与该实例有关。对于许多综合工具来说,
initial
块是不可综合的。由于我不使用xilinx,所以无法评论它的支持。也许您可以删除initial
块。最好使用非阻塞赋值 (
<=
) 来综合顺序逻辑。例如:您可以将常量重新编码为:
This is not an answer, but I think these tips might improve your code.
Since I do not have your
Divider8
module, I can't compile your code, unless I comment out thedivider
instance. It seems like the error message is related to that instance.For many synthesis tools
initial
blocks are not synthesizable. Since I do not use xilinx, I can not comment on its support. Perhaps you could just delete theinitial
block.It is better to use non-blocking assignments (
<=
) for synthesizing sequential logic. For example:You could re-code your constant as: