使用不从零开始的索引在 Verilog 中声明变量
Declaring Variable in Verilog with Indexing that doesn't start at zero
我在 Verilog 中使用这个连线声明:
wire [23:15] myvar;
我的代码有效,我以前见过这种编码风格,但我不确定实际发生了什么,我只能猜测正在声明一条 9 位宽的连线。是这样吗?我想在网上阅读更多内容,但我不知道这叫什么,所以很抱歉这个简单的问题。
您声明的是 9 位线是正确的。许多设计对于 LSB 和 MSB 值应该是什么,索引编号应该进入哪个方向有不同的想法。在您开始引用单个位或切片之前,索引值的用途并不重要。
Verilog 是一种硬件描述语言 (HDL)。无论你 write/declare,最终都会变成 硬件 的一种形式。
让我们看看下图:
在这里,声明 wire [23:15] myvar;
或 wire [8:0] myvar;
会声明相同的 束线,九位宽 。只是 索引部分 有所不同。不管你叫它a[0]
(当a
是wire [8:0] a
)还是a[15]
(当a
是wire [23:15] a
)。编码部分根据程序员的易用性而有所不同,而综合部分保持相同。
此外,请注意,在 前 情况下,myvar[15]
是最低有效位,而 后者 具有 myvar[0]
作为最低有效位。我们可以交换声明部分,这也将交换 MSB-LSB。
reg [7:0] reg1; // 8-bit vector with MSB=7 LSB=0
reg [0:7] reg2; // 8-bit vector with MSB=0 LSB=7
// ...
// ...
reg1 = 8'hF0; // reg1[7] = 1 and reg1[0] = 0 ultimately, reg1 = F0
reg2 = 8'hF0; // reg2[7] = 0 and reg2[0] = 1 ultimately, reg2 = F0
让我们举个例子:
wire [23:15] myvar;
reg [23:15] reg2;
reg [31:0] reg3;
initial begin
$monitor("myvar = %0h myvar2 = %0h reg3 = %0h",myvar,myvar2,reg3);
reg3 = 32'h5ABC_FEDC;
// This will correctly assign values to reg2, since it is [23:15]
for(int i=16;i<20;i++)
begin
reg2[i] = myvar[i];
$display("1: reg2[%0d] = %0h myvar[%0d] = %0h",i,reg2[i],i,myvar[i]);
end
// While, this will not assign correctly,
// since reg2 does not have [5:0] indexes,neither does myvar
for(int i=0;i<5;i++)
begin
reg2[i] = myvar[i];
$display("2: reg2[%0d] = %0h myvar[%0d] = %0h",i,reg2[i],i,myvar[i]);
end
end
另一种选择是您的 reg
是 [8:0]
而 wire
是 [23:0]
。这里 是 所有重要的,但 只是在编码部分 .请注意,在下面的 first 片段中,值被分配给 reg1[4:0]
,而在 second 片段中,它在 reg1[20:15]
.
reg [8:0] reg1;
wire [23:15] myvar;
// Correct, since LSB of myvar is at index position 15
for(int i=0;i<5;i++)
begin
reg1[i] = myvar[i+15];
$display("3 : reg1[%0d] = %0h myvar[%0d] = %0h",i,reg1[i],i,myvar[i+15]);
end
reg [31:0] reg1;
wire [23:15] myvar;
// reg1[19:15] is assigned here
for(int i=15;i<20;i++)
begin
reg1[i] = myvar[i];
$display("4 : reg1[%0d] = %0h myvar[%0d] = %0h",i,reg1[i],i,myvar[i]);
end
所以,最后,只有一些 切片 在从电线驱动时有所不同,对 实际硬件 没有影响。更多信息可以从 Verilog Syntax Details link.
获得
我在 Verilog 中使用这个连线声明:
wire [23:15] myvar;
我的代码有效,我以前见过这种编码风格,但我不确定实际发生了什么,我只能猜测正在声明一条 9 位宽的连线。是这样吗?我想在网上阅读更多内容,但我不知道这叫什么,所以很抱歉这个简单的问题。
您声明的是 9 位线是正确的。许多设计对于 LSB 和 MSB 值应该是什么,索引编号应该进入哪个方向有不同的想法。在您开始引用单个位或切片之前,索引值的用途并不重要。
Verilog 是一种硬件描述语言 (HDL)。无论你 write/declare,最终都会变成 硬件 的一种形式。
让我们看看下图:
在这里,声明 wire [23:15] myvar;
或 wire [8:0] myvar;
会声明相同的 束线,九位宽 。只是 索引部分 有所不同。不管你叫它a[0]
(当a
是wire [8:0] a
)还是a[15]
(当a
是wire [23:15] a
)。编码部分根据程序员的易用性而有所不同,而综合部分保持相同。
此外,请注意,在 前 情况下,myvar[15]
是最低有效位,而 后者 具有 myvar[0]
作为最低有效位。我们可以交换声明部分,这也将交换 MSB-LSB。
reg [7:0] reg1; // 8-bit vector with MSB=7 LSB=0
reg [0:7] reg2; // 8-bit vector with MSB=0 LSB=7
// ...
// ...
reg1 = 8'hF0; // reg1[7] = 1 and reg1[0] = 0 ultimately, reg1 = F0
reg2 = 8'hF0; // reg2[7] = 0 and reg2[0] = 1 ultimately, reg2 = F0
让我们举个例子:
wire [23:15] myvar;
reg [23:15] reg2;
reg [31:0] reg3;
initial begin
$monitor("myvar = %0h myvar2 = %0h reg3 = %0h",myvar,myvar2,reg3);
reg3 = 32'h5ABC_FEDC;
// This will correctly assign values to reg2, since it is [23:15]
for(int i=16;i<20;i++)
begin
reg2[i] = myvar[i];
$display("1: reg2[%0d] = %0h myvar[%0d] = %0h",i,reg2[i],i,myvar[i]);
end
// While, this will not assign correctly,
// since reg2 does not have [5:0] indexes,neither does myvar
for(int i=0;i<5;i++)
begin
reg2[i] = myvar[i];
$display("2: reg2[%0d] = %0h myvar[%0d] = %0h",i,reg2[i],i,myvar[i]);
end
end
另一种选择是您的 reg
是 [8:0]
而 wire
是 [23:0]
。这里 是 所有重要的,但 只是在编码部分 .请注意,在下面的 first 片段中,值被分配给 reg1[4:0]
,而在 second 片段中,它在 reg1[20:15]
.
reg [8:0] reg1;
wire [23:15] myvar;
// Correct, since LSB of myvar is at index position 15
for(int i=0;i<5;i++)
begin
reg1[i] = myvar[i+15];
$display("3 : reg1[%0d] = %0h myvar[%0d] = %0h",i,reg1[i],i,myvar[i+15]);
end
reg [31:0] reg1;
wire [23:15] myvar;
// reg1[19:15] is assigned here
for(int i=15;i<20;i++)
begin
reg1[i] = myvar[i];
$display("4 : reg1[%0d] = %0h myvar[%0d] = %0h",i,reg1[i],i,myvar[i]);
end
所以,最后,只有一些 切片 在从电线驱动时有所不同,对 实际硬件 没有影响。更多信息可以从 Verilog Syntax Details link.
获得