Verilog数据类型
我正在学习verilog作为我大学课程的一部分,但是我的模块讲师离开了,所以我希望在这里得到一些帮助 我们给出了一个参数化n位灰度到二进制代码转换器的示例,如下所示:Verilog数据类型,verilog,fpga,hdl,Verilog,Fpga,Hdl,我正在学习verilog作为我大学课程的一部分,但是我的模块讲师离开了,所以我希望在这里得到一些帮助 我们给出了一个参数化n位灰度到二进制代码转换器的示例,如下所示: module bin_n_gray #(parameter n=4) (input [n-1 : 0] gray, output [n-1 : 0] bin); integer i; always @ (*) for(i = 0; i < n; i = i+1) bi
module bin_n_gray #(parameter n=4) (input [n-1 : 0] gray, output [n-1 : 0] bin);
integer i;
always @ (*)
for(i = 0; i < n; i = i+1)
bin[i] = ^(gray >> i);
endmodule
模块bin_n_gray#(参数n=4)(输入[n-1:0]灰色,输出[n-1:0]bin);
整数i;
始终@(*)
对于(i=0;i>i);
端模
我的问题:
由于bin[i]
变量位于@always
块中赋值语句的左侧,该变量不应该声明为output reg[n-1:0]bin
我认为进程块赋值语句左侧的变量,即始终
/初始
应声明为reg
数据类型
由于bin[i]变量位于“@always”块内赋值语句的左侧,该变量不应该声明为“output reg[n-1:0]bin”吗
是的,至少根据Xilinx XST,它应该需要您所说的reg
。问题中给出的代码在使用该工具进行合成时出错(并且缺少不相关的分号)
首先,让我们从理解Verilog中的过程块开始(假设我们使用Verilog开发硬件,例如FPGA设计)。程序块是始终块(有两种类型,组合块和顺序块),以及我们在此不介绍的其他几种类型的块。首先要知道的是,在程序块中,唯一允许的赋值是那些在左侧有reg
的赋值
这并不一定意味着将创建一个物理寄存器/触发器。在这种情况下,一个将不会。原因是块声明为始终@(*)
。该声明意味着该过程是组合的(即非顺序的,没有任何内部状态或时钟信号)。因此,不会创建物理触发器
或者,您可以将程序块声明为始终@(posedge some_clock_signal)
。这意味着创建了顺序逻辑,可以使用物理触发器(或其他存储方式,如FPGA查找表中的分布式内存)。需要注意的是,您仍然在那里声明为reg
,但现在您实际上正在创建寄存器
在一种情况下,您可以使用wire
(或output
),这是通过连续赋值(例如assigna=b&c
)实现的,它不属于程序块。在本例中,我使用generate
执行与原始代码中的循环相同的操作:
module bin_n_gray #(parameter n=4) (input [n-1 : 0] gray, output [n-1 : 0] bin);
genvar i;
generate
for (i=0; i < n; i=i+1)
begin: graydecoder // arbitrary label needed by generate syntax
assign bin[i] = ^(gray >> i);
end
endgenerate
endmodule
模块bin_n_gray#(参数n=4)(输入[n-1:0]灰色,输出[n-1:0]bin);
genvar i;
生成
对于(i=0;i>i);
结束
最终生成
端模
由于bin[i]变量位于“@always”块内赋值语句的左侧,该变量不应该声明为“output reg[n-1:0]bin”吗
是的,至少根据Xilinx XST,它应该需要您所说的reg
。问题中给出的代码在使用该工具进行合成时出错(并且缺少不相关的分号)
首先,让我们从理解Verilog中的过程块开始(假设我们使用Verilog开发硬件,例如FPGA设计)。程序块是始终块(有两种类型,组合块和顺序块),以及我们在此不介绍的其他几种类型的块。首先要知道的是,在程序块中,唯一允许的赋值是那些在左侧有reg
的赋值
这并不一定意味着将创建一个物理寄存器/触发器。在这种情况下,一个将不会。原因是块声明为始终@(*)
。该声明意味着该过程是组合的(即非顺序的,没有任何内部状态或时钟信号)。因此,不会创建物理触发器
或者,您可以将程序块声明为始终@(posedge some_clock_signal)
。这意味着创建了顺序逻辑,可以使用物理触发器(或其他存储方式,如FPGA查找表中的分布式内存)。需要注意的是,您仍然在那里声明为reg
,但现在您实际上正在创建寄存器
在一种情况下,您可以使用wire
(或output
),这是通过连续赋值(例如assigna=b&c
)实现的,它不属于程序块。在本例中,我使用generate
执行与原始代码中的循环相同的操作:
module bin_n_gray #(parameter n=4) (input [n-1 : 0] gray, output [n-1 : 0] bin);
genvar i;
generate
for (i=0; i < n; i=i+1)
begin: graydecoder // arbitrary label needed by generate syntax
assign bin[i] = ^(gray >> i);
end
endgenerate
endmodule
模块bin_n_gray#(参数n=4)(输入[n-1:0]灰色,输出[n-1:0]bin);
genvar i;
生成
对于(i=0;i>i);
结束
最终生成
端模
我糊涂了!你能不能简单地解释一下,因为我只是在学这些东西@我很乐意,但不幸的是我现在不能。“如果我在半小时到一小时左右的时间内更新我的答案会有问题吗?你的答案的第一部分似乎是肯定的,应该声明为reg,但第二部分似乎你的说辞很好,”AndyWest说,“一旦我有机会,我会澄清这个措辞。@AndyWest你是对的(我没有注意到)。至少根据我的FPGA工具(Xilinx ISE/XST),它需要是一个reg
。我现在就在答案编辑中写一个解释