声明和使用常量的静态数组

时间:2019-02-12 21:34:44

标签: arrays verilog memory-address

我刚进入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
    );

我不想编写if语句来检查输入数据的每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

但是我担心这将导致另一个失败。

我使用Xilinx的ISE,现在,我模拟了一个spartan 6 xc6slx9(我的板在下个月到货)。

我在这里做什么错了?

此外,由于显示始终是静态的,因此有没有办法只实例化一次而不在每次实例化新模块时都不创建电路?

2 个答案:

答案 0 :(得分:1)

您需要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,

答案 1 :(得分:0)

您在声明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