声明和使用静态常量数组
Declaring and using a static array of constants
我刚接触 verilog,我想编写一个简单的模块,它在(称为数据)中获取一个 4 位值,并为 7 段显示输出一个 8 位值(称为 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段显示器的小数点是单独处理的。
但是我得到这个错误:
Constant value or constant expression must be used for initialization
稍后我想像这样使用数组:
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(我的板子下个月到货)。
我做错了什么?
此外,由于显示始终是静态的,有没有办法只显示一次,而不是在每次实例化新模块时都创建电路?
您需要 SystemVerilog 支持才能拥有本地参数数组。这需要 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,
你声明局部参数的语法有误。要解决这个问题,你只需要在你的初始值中的 {
之前添加一个 '
就像这样:
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
我刚接触 verilog,我想编写一个简单的模块,它在(称为数据)中获取一个 4 位值,并为 7 段显示输出一个 8 位值(称为 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段显示器的小数点是单独处理的。 但是我得到这个错误:
Constant value or constant expression must be used for initialization
稍后我想像这样使用数组:
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(我的板子下个月到货)。
我做错了什么?
此外,由于显示始终是静态的,有没有办法只显示一次,而不是在每次实例化新模块时都创建电路?
您需要 SystemVerilog 支持才能拥有本地参数数组。这需要 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,
你声明局部参数的语法有误。要解决这个问题,你只需要在你的初始值中的 {
之前添加一个 '
就像这样:
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