关于verilog的inout口的仿真问题
我这两天用verilog编的ARM7与CPLD总线连接的程序,编完后用Jlink查看过ARM收发的数据,总线是好使的,就是说源模块代码没问题。现在问题就出在编写testbench仿真总线inout口,能看到测试模块给源模块的总线输入数据,但是看不到总线输出数据。在网上找了下资料,发现有建议用"assign DATA = (~nWE)?treg_DATA:16'hzzzz;assign DATA_OUT=(~nOE)?DATA:16'hzzzz;"这种方式,通过treg_DATA输入数据,DATA_OUT观察输出数据,但是试验了发现不行,总线输出仍然是高阻态。后来在weizhiheng的这个帖子http://www.eetop.cn/bbs/thread-245831-1-1.html里找到另外一种方法,像这样reg [3:0] dirdata$inout$reg = 4'b0000;wire [3:0] dirdata = dirdata$inout$reg; ,通过dirdata 观察输出,但是发现也不行。所以只能上网求助大家了。我先粘贴源模块代码:
module lpcbus(clk,ADDR,DATA,nOE,nWE,nCS,led);
input clk,nOE,nWE,nCS;
output led;
input [7:0]ADDR;
inout [15:0]DATA;
reg [15:0]DATAOUT;
wire link_bus;
assign link_bus=!nOE;
assign DATA=(link_bus)?DATAOUT:16'hzzzz;
reg [25:0]cnt;
always@(posedge clk) begin
cnt<=cnt+1;
end
assign led=cnt[25];
reg [15:0]ram,ram2;
always@(nWE or nCS or ADDR) begin
if((nCS==0)&&(nWE==0)) begin
case(ADDR)
16'h55: begin ram<=DATA; end
16'h77: begin ram2<=DATA; end
default:begin end
endcase
end
end
always@(nOE or nCS or ADDR) begin
if((nCS==0)&&(nOE==0)) begin
case(ADDR)
16'h66: begin DATAOUT<=ram; end
16'h88: begin DATAOUT<=ram2; end
default: begin end
endcase
end
else begin
DATAOUT<=16'hzzzz;
end
end
endmodule
功能及其简单,就是往0X55写数时,能从0x66里读出来,是用来测试总线用的,试验结果验证好用。
下面是测试代码testbench和仿真波形图:
`timescale 1 ns/ 1 ns
module lpcbus_vlg_tst;
reg [7:0] ADDR;
reg [15:0] treg_DATA;
reg clk;
reg nCS;
reg nOE;
reg nWE;
wire [15:0] DATA;
wire [15:0] DATA_OUT;
wire led;
assign DATA = (~nWE)?treg_DATA:16'hzzzz;
assign DATA_OUT=(~nOE)?DATA:16'hzzzz;
initial begin
clk=0; nWE=1; nOE=1; nCS=1;
end
always #10 clk=~clk;
always begin
#50 ADDR=8'h55;treg_DATA=16'h1234; nWE=0; nCS=0;
#50 nWE=1; nCS=1; treg_DATA=16'hzzzz;
#50 ADDR=8'h66; nOE=0; nCS=0;
#50 nOE=1; nCS=1;
#100 ;
end
lpcbus i1 (
.ADDR(ADDR),
.DATA(DATA),
.clk(clk),
.led(led),
.nCS(nCS),
.nOE(nOE),
.nWE(nWE)
);
endmodule
仿真波形如图所示:可以看到,第一种方式时总线输出为高阻态ZZZZ,见红线那部分。

然后我按照weizhiheng的方式改了下测试代码:
`timescale 1 ns/ 1 ns
module lpcbus_vlg_tst;
reg [7:0] ADDR;
reg clk;
reg nCS;
reg nOE;
reg nWE;
reg [15:0] DATA$inout$reg = 16'h0000;
wire [15:0] DATA = DATA$inout$reg;
wire led;
initial begin
clk=0; nWE=1; nOE=1; nCS=1;
end
always #10 clk=~clk;
always begin
#50 ADDR=8'h55;DATA$inout$reg=16'h1234; nWE=0; nCS=0;
#50 nWE=1; nCS=1; DATA$inout$reg=16'hzzzz;
#50 ADDR=8'h66; nOE=0; nCS=0;
#50 nOE=1; nCS=1;
#50 ;
end
lpcbus i1 (
.ADDR(ADDR),
.DATA(DATA),
.clk(clk),
.led(led),
.nCS(nCS),
.nOE(nOE),
.nWE(nWE)
);
endmodule
仿真波形如下: 可以看到,DATA上面还是高阻态。

我把整个工程都已经粘贴出来了,麻烦大家帮看看是什么问题,多谢了
自己顶起~
好心人帮看下吧
在你的nwe,ncs由H到L时,请确保DATA的数据不是高阻。
最好使用同步电路进行设计。
tb里面实例化的时候用tri类型的net进行连接
在module lpcbus 中,可以看到,你的双向口DATA在link_bus为1时作为输出,为0时作为输入。
在testbench中,将DATA定义为tri类型,
assign DATA = lpcbus_vlg_tst.i1.link_bus ? lpcbus_vlg_tst.i1.DATAOUT : treg_DATA;
不知道对不对,你试一下。
5# xcykii
按照你的方法试了不行
6# rosie_1128
按照你的方法试时,点开始仿真后报错,不能继续下去
Unresolved reference to 'DATAOUT' in lpcbus_vlg_tst.i1.DATAOUT
Unresolved reference to 'link_bus' in lpcbus_vlg_tst.i1.link_bus
你的第一种testbench仿真结果中,DATAOUT的值在波形图中看是什么?
我是指这段代码中的:
always@(nOE or nCS or ADDR) begin
if((nCS==0)&&(nOE==0)) begin
case(ADDR)
16'h66: begin DATAOUT<=ram; end
16'h88: begin DATAOUT<=ram2; end
default: begin end
endcase
end
else begin
DATAOUT<=16'hzzzz;
end
end
9# rosie_1128
你点击第一个图里看最后一个波形可以看到的,X状态(红色那部分波形)
问题解决了,我在modelsim里加入源文件模块一起编译后居然就好使了。见下面的波形图:往0x55和0x77分别写0x1234和0x4321,然后通过0x77和0x88读出来,大家看波形图上可以读出来了!
但是很疑惑,以前看modelsim教程里似乎不需编译源文件的啊。怎么回事呢。现在就算解决了也很疑惑
刚试了一下,编译顺序还有要求。得先编译顶层模块文件lpcbus.v和maxii_atoms.v和网表文件epm1270.vo,然后再编译源文件epm1270.v才行。如果先编译了epm1270.v就不好使的,见鬼了。
求高人出山啊!
学习了。
使用你的源代码和按照我所说的方法编制的testbench仿真没有错误。下面是结果。
使用modelsim6.1f。
完毕。
[img][/img]

使用modelsim的过程:
(1)建立工程,加入文件
(2)选择编译里面的compile all
(3)在work下面点击testbench进行仿真。
-------------------------------------------------------------------
希望大家能够喜欢!
本人的另一篇文章写modelsim的详细使用教程
http://www.eetop.cn/bbs/thread-136109-1-1.html
被下载了1800多次,非常感谢大家的支持!
在看外国不少很好的书的时候,发现人家的书写的很全面,一点就是一点,直到讲透为止
——可能正因为此,外国的书都老厚了!或者这样更适合自学:)国内的很多书我认为可能
需要老师的指点方可学的更好:)
所以,我在写东西的时候,倾向于尽可能细致的写,写一点的知识就要将其来龙去脉写全。
我在做项目的过程中,深刻的感觉到:问题的产生往往是对项目应用的技术缺乏深刻的了解。
你对技术了解透了,问题自然就没了。
所以别人问我fft怎么做时,我会给他讲蝶形算法,给他说如何抽取。呵呵,别人有时候会烦,
包括我老婆。但是,如果仅仅给一个C的实现,到网上一搜一堆,然而如果你要将其优化,例如
用查表的方法将其加速,你不了解基本原理,连倒位序部分和计算部分都分不开,怎么去做呢?
综上,对于一个知识点,要想用得好,就要学得透,要能够做到从根上去抓。
don't know
have no idea
ding...真好
不错,顶一下!
我用的是6.5d,版本有所不同。现在发现加入源文件编译这个方法对无inout端口的也没影响,所以以后按这个方法来吧。谢谢你了
谢谢了
学习了!
跟LZ情况一样,用weiziheng的方法,可写不可读,郁闷了
