Объявление и использование статического массива констант - PullRequest
0 голосов
/ 13 февраля 2019

Я только что вошел в verilog и хочу написать простой модуль, который получает 4-битное значение (называемое данными) и выводит 8-битное значение для 7-сегментного дисплея (называемого seven_seg).

module LCD_Encoder (
    input clk,
    input rst,
    input [3:0] data,       // digit to write 0-F
    output [6:0] seven_seg, // 7 segment out, LSB -> A, B, C, D, E, F, G <- MSB
    output dp               // decimal point
    );

Я не хотел писать, чтобы операторы проверяли все 16 различных значений входных данных, а затем решали, что отображать, поэтому я пришел к такому массиву:

// define 7 segment display, 16(different characters) * 7 bits(7 segment)
localparam [6:0] display [15:0] = {
    // GFE_DCBA
    7'b011_1111, // 0
    7'b000_0110, // 1
    7'b101_1011, // 2
    7'b100_1111, // 3
    7'b110_0110, // 4
    7'b110_1101, // 5
    7'b111_1101, // 6
    7'b000_0111, // 7
    7'b111_1111, // 8
    7'b110_1111, // 9
    7'b111_0111, // A
    7'b111_1100, // B
    7'b011_1001, // C
    7'b101_1110, // D
    7'b111_1001, // E
    7'b111_0001  // F
};

Десятичное числоточка на 7-сегментном дисплее обрабатывается отдельно.Однако я получаю эту ошибку:

Для инициализации необходимо использовать постоянное значение или константное выражение

Позже я хочу использовать массив следующим образом:

always @(posedge clk or posedge rst) begin
    if (rst == 1'b1) begin
        seven_seg <= 7'b0;
    end
    else begin
        // use 4-bit (0-F) data as address for the array
        seven_seg <= display[data]; // does this work??
    end
end

однако я боюсь, что это закончится еще одним провалом.

Я использую ISE из Xilinx и на данный момент, и я имитирую спартанца 6 xc6slx9 (моя доска прибывает в следующем месяце).

Что я здесь не так делаю?

Кроме того, поскольку отображение всегда будет статичным, есть ли способ иметь его только один раз и не создавать схему каждый раз, когда вы создаете новый модуль?

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Вы ошиблись в синтаксисе для объявления localparam.Чтобы решить эту проблему, вам нужно только добавить ' перед { в ваше начальное значение, например:

localparam [6:0] display [15:0] = '{
// GFE_DCBA
7'b011_1111, // 0
7'b000_0110, // 1
7'b101_1011, // 2
7'b100_1111, // 3
7'b110_0110, // 4
7'b110_1101, // 5
7'b111_1101, // 6
7'b000_0111, // 7
7'b111_1111, // 8
7'b110_1111, // 9
7'b111_0111, // A
7'b111_1100, // B
7'b011_1001, // C
7'b101_1110, // D
7'b111_1001, // E
7'b111_0001  // F
};

Или вы можете использовать оператор initial, с помощью которого ваш кодследующим образом:

// define 7 segment display, 16(different characters) * 8 bits(7 segment)
reg [6:0] display [15:0];
initial begin
    display[0] = 7'b011_1111; // 0
    display[1] = 7'b000_0110; // 1
    // Continue your display values in here
end
0 голосов
/ 13 февраля 2019

Вам нужна поддержка SystemVerilog, чтобы иметь массив localparam.Это требует Vivado, а не ISE.Чтобы смоделировать это в Verilog, вам нужно упаковать массив в один вектор и взять фрагмент из вектора

localparam [0:(7*16)-1] display  = {
    // GFE_DCBA
    7'b011_1111, // 0
    7'b000_0110, // 1
    7'b101_1011, // 2
    7'b100_1111, // 3
    7'b110_0110, // 4
    7'b110_1101, // 5
    7'b111_1101, // 6
    7'b000_0111, // 7
    7'b111_1111, // 8
    7'b110_1111, // 9
    7'b111_0111, // A
    7'b111_1100, // B
    7'b011_1001, // C
    7'b101_1110, // D
    7'b111_1001, // E
    7'b111_0001  // F
};
seven_seg <= display[data*7+:7];

Кроме того, ваши выходные порты должны быть объявлены как reg

output reg [6:0] seven_seg,
...