在下面的模块中,理想情况下cnt,width& start应该是inout port,而不是输出端口。
但我尝试将这些端口作为输出端口,但我仍然可以运行它而没有任何错误。那么inout和输出端口可以在Verilog中互换使用吗?
如果不是,那么确切的标准是什么,必须使用inout端口(在这种情况下不能使用输出端口)?
module (clk, rst, cnt, start, width, signal);
input clk, rst, signal;
output reg [11:0] cnt, width;
output reg start;
always @(posedge clk or negedge rst)
begin
if(~rst)
begin
cnt <= 0;
start = 0;
width <= 'h271;
end
else
begin
if(signal)
begin
width <= (start) ? width : 'h271;
start = 1;
end
cnt <= (start) ? (cnt + 1) : cnt;
end
end
endmodule
注意 - 我知道,对于inout端口,我需要修改代码,因为inout端口不能是reg类型。但我在这里只询问只是端口类型。
答案 0 :(得分:3)
output
和inout
端口存在差异:
您无法同时读取和写入inout
端口,因此保留'Z
进行阅读。
inout
端口永远不会属于reg
类型。它必须是wire
类型。
应该有一个信号决定给定的端口是input
还是output
。
在此模块中,您必须具有w_r
信号,其功能如下:
// w_r = 1 => output port
// w_r = 0 => input port
input w_r;
inout cnt;
reg write_cnt;
reg read_cnt;
// wire read_cnt;
assign cnt = w_r ? write_cnt : 1'bz; // driving logic for cnt
// inside some always block
read_cnt <= cnt;
write_cnt <= some_data;
由于inout
信号是有线的,因此它必须由连续赋值语句驱动。
参考这一部分:
那么inout和输出端口可以在Verilog中互换使用吗?
答案是不鼓励 可互换地使用。因为对于输出端口,您可以单独使用reg
类型。
从综合的角度来看,inout
端口可以具有三态驱动程序或Mux ,如下所示:(注意,对于综合工具,这个结果可能会有所不同,我不确定大约):
有关详细信息,请参阅Bidirectional port assignment和Bidirectional I/O Pins论坛问题。
答案 1 :(得分:3)
模拟器不关心端口方向。仿真工具总是使模块层次结构变得平坦,重要的是它们可以将两个端口信号连接在一起。它们不检查数据流是否实际沿指定方向流动。遗憾的是,标准所要求的内容以及工具中实现的内容并不总是匹配。
有时,用户会使用&#34;工作的代码&#34;在一个工具中,但在另一个工具中没有更强的错误检查。用户发现更容易让他们的工具供应商删除错误检查,而不是必须返回并修复他们的代码。一些大多数模拟器已经删除了任何检查以强制执行端口方向。
关于不声明在端口中使用的变量数据类型的规则大部分保持不变,但许多工具允许常量连接到inout端口。
答案 2 :(得分:2)
端口方向基本上是Verilog中的建议,并且在SystemVerilog中没有改变。这是一个历史问题,与Verilog XL(第一个Verilog模拟器)端口崩溃的方式有关;基本上,一切都是进不过的。当'95 LRM被写入时,这个现有的行为基本上被记录下来。在1364-2005中,这在12.3.8中显示为
声明为输入(输出)但用作输出(输入)或inout的端口可能会被强制转换为inout。如果不 强迫进入,必须发出警告。
在实践中,一切都以inout
结束,您可能会或可能不会收到警告。所以,你可以在模拟器中做很多事情,但是linter或者合成器应该为你拾取任何逻辑连接错误(如果它没有,它就没用了)。以下各节中还有其他特定的非方向规则 - input
和inout
端口必须为net
类型,依此类推。