Вопрос

У меня есть базовый 8-битный ALU, описанный в Verilog.Я пытаюсь реализовать дизайн, но получаю сообщения об ошибках:

ОШИБКА: NgdBuild: 809 - коэффициент чистой выходной площадки<1>' имеет незаконную нагрузку:вывод I3 в блоке Mmux_opcode[2]_GND_1_o_wide_mux_8_OUT81 с типом LUT6

Дизайн выполняет следующие операции: сложение, вычитание, умножение, деление И, ИЛИ, XOR и XNOR.Интересной вещью в этом является тот факт, что Xilinx XST не может синтезировать делитель, если только дивиденд не делится в 2 раза (в основном смещаясь вправо).Поэтому, чтобы позаботиться об этом, я использовал ОСНОВНОЙ IP-компонент, сгенерированный Xilinx Core Generator.Он принимает один такт (без включения часов или синхронной очистки) и выводит правильное частное и остаток примерно через 20 тактов.Само ядро можно найти в разделе математические функции в программе Core Generator.В любом случае, вот мой код:

`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.Тем не менее, я планирую значительно улучшить этот код и добавить больше операций для практики.Сам модуль успешно выполняет синтез и корректное моделирование, но я не могу реализовать его ни на одной ПЛИС.Кто-нибудь знает, есть ли проблема с кодом, или с Xilinx ISE (который, как обычно, полон ошибок), или, может быть, с настройками проекта?

Редактировать:Я внес несколько изменений в код, чтобы отразить рекомендации, содержащиеся в ответах.

Это было полезно?

Решение

Выбрана ли у вас в вашем проекте coregen опция "Создать оболочку netlist с помощью IO pads"?Судя по ошибке, похоже, что ядро Divider8 имеет OBUF или аналогичный выходной буфер, управляющий коэффициентным выводом.OBUF может передавать только сигнал, выходящий из ПЛИС.

Еще одно замечание, хотя это не связано с ошибкой ngdbuild:обычно неблокирующие назначения используются в последовательных блоках ("always @(posedge clk)"), например"ВОН <= A + B".Краткое объяснение этого заключается в том, что обновление сигнала OUT откладывается до тех пор, пока не будут обработаны все остальные события за текущее время, что позволяет избежать условий гонки в симуляторе.

Другие советы

Это не ответ, но я думаю, что эти советы могут улучшить ваш код.

Поскольку у меня нет вашего Divider8 модуль, я не могу скомпилировать ваш код, пока не закомментирую divider пример.Похоже, что сообщение об ошибке связано с этим экземпляром.

Для многих инструментов синтеза initial блоки не поддаются синтезированию.Поскольку я не использую xilinx, я не могу комментировать его поддержку.Возможно, вы могли бы просто удалить initial блок.

Лучше использовать неблокирующие назначения (<=) для синтеза последовательной логики.Например:

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

Вы могли бы перекодировать свою константу следующим образом:

    default: OUT = {16{1'b0}};
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top