1

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.

sj755
  • 3,944
  • 14
  • 59
  • 79

2 Answers2

1

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 the divider 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 the initial block.

It is better to use non-blocking assignments (<=) for synthesizing sequential logic. For example:

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

You could re-code your constant as:

    default: OUT = {16{1'b0}};
toolic
  • 57,801
  • 17
  • 75
  • 117
  • Hopefully. BTW, I was considering actually asking for a question-answer site for HDL, CPLD, FPGA, ASIC. You wouldn't happen to know any would you? – sj755 Mar 16 '11 at 21:14
  • Stackexchange for programmable logic: http://area51.stackexchange.com/proposals/20632/programmable-logic-and-fpga-design?referrer=ZolqNc0edhvG1iedac--IA2 – Martin Thompson Mar 18 '11 at 14:47
1

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.

Andy
  • 4,789
  • 23
  • 20
  • @Andy No I don't. Are you saying checking this option will correct the issue? Also, thanks for the advice, I'm happy to accept any advice or criticism of my code and style. – sj755 Mar 17 '11 at 21:40
  • @seljuq70 No, I meant to turn it off if it was enabled, so that's not the issue. Do you have a report from coregen that shows what primitives were used to implement the divider (LUT*, FF*, etc...)? Can you post the ngdbuild log file? – Andy Mar 18 '11 at 15:22
  • @Andy Hate to ask this, but where would I find such a file, and what would it be called? I see a ngc file, but that's it. – sj755 Mar 18 '11 at 18:55
  • @seljuq70 The ngdbuild log would have the .bld extension. It doesn't look like coregen generates the kind of report I was thinking of, but you can do "netgen -sim -ofmt verilog ngcfile.ngc ngcfile.extracted.v" to see what is used in the core (if the extracted.v has OBUF instantiations, that's a problem). One other thing to check. Are you (or did you previously) synthesize the divider by itself? That might have generated a .ngc with I/O buffers, even if the coregen-generated .ngc does not have them. – Andy Mar 18 '11 at 19:52
  • @Andy The divider itself synthesizes and I was able to implement it by itself. There is a file called Divider8.bld in the main project directory. I'll post up its contents if you like, but it doesn't look like anything of use, because there are no errors. I'm beginning to suspect the code itself is the issue. – sj755 Mar 18 '11 at 20:08
  • 1
    @seljuq70 I tried the code in ISE and didn't have any issues. My guess is there's a stale file (from implementing the divider by itself) that's causing problems. You could try creating a new project, copy over ALU8.v, and regenerate the divider in coregen. Or as a simpler experiment, delete Divider8.{bld,ngd,ngc} – Andy Mar 18 '11 at 20:41
  • @Andy Really?!? For your project settings, what FPGA did you select? Just so we're on the exact same page. – sj755 Mar 18 '11 at 20:51
  • @seljuq70 I picked xc5vlx20t-2-ff323. I had some trouble getting XST to find the divider (unresolved module errors), but no errors from ngdbuild. – Andy Mar 18 '11 at 20:55
  • I've found the root of the problem, the ngc file for Divider8 was located in the IP Core directory within my project folder. After moving it, it suddenly worked. By the way, did you get an warning like this? Attribute "INIT" on "divider/blk00000003/sig0000009a" is on the wrong type of object. Please see the Constraints Guide for more information on this attribute. – sj755 Mar 18 '11 at 21:23
  • @seljuq70 No, I didn't get that warning. Not sure what would cause that... maybe if the core wasn't generated for the same device? – Andy Mar 18 '11 at 23:27
  • @Andy Maybe...Anyway, I appreciate the help. I guess it is possible to get Verilog answers on this site, although it doesn't take less than 30 minutes like if I were to ask a C/C++ related question. – sj755 Mar 19 '11 at 00:56