这段描述使用的是VerilogHDL,其中有个被注释掉的信号dumy,暂时先不解释。这个描述是可综合的,我们使用Altera的MaxPlusII来仿真一下:
嗯,看起来不错,hwr_有效的时候hd正确传送到了sd,实现了hd输入,sd输出;hrd有效的时候sd正确传送到了hd,实现了sd输入,hd输出,这样hd、sd两个双向8位总线都正确实现了。
且慢,有没有不太好的地方?上面描述中hwr_直接作为了sd输出的使能控制信号sd_out_oe,由于swr_直接来自hwr_,因此swr_上沿到来后sd输出被立即关闭,许多外设器件要求有一定的数据写保持时间,而现在sd的写保持时间却为0。怎样克服这个缺点呢?把前面关于dumy信号的代码去掉注释符号”//”,把assign sd_out_oe =!hwr_;这句注释掉,再编译仿真一下看看:
哈哈,这下sd的输出保持时间够长了吧?dumy是用户定义的一个CPLD/FPGA外部引脚,按照上面的描述,在实际电路中将其固定接高,由于需要dumy信号和hwr取反然后通过与逻辑再形成sd_out_oe,带有门延迟,因此与最初的描述方法相比,sd输出关闭被延迟了。使用dumy信号这种方法需要额外占用CPLD/FPGA的一个引脚,也可以采取其他方式实现这个延迟功能。而Hd不需要这样特殊处理,为什么?呵呵,读者自己想想看?
还有一个看起来不太好的地方:HOST的hrd_有效而外设尚未将数据准备好的时候,hd总线上有一段时间的不定态,不过这不影响HOST的读功能,一般情况下不需要特殊处理,如果不希望出现这个现象,可以通过sd上拉、时钟同步处理等手段将其消除。
方才上面说过,这个例子只是用来说明双向信号的实现方法,例子本身可能没有什么实际用处,嘿嘿,如果把
assign hd = hd_out_oe ? hd_out : 8'hzz;
assign sd = sd_out_oe ? sd_out : 8'hzz;
改写为:
assign hd = hd_out_oe ? {hd_out[3:0],hd_out[7:4]} : 8'hzz;
assign sd = sd_out_oe ? {sd_out[3:0],sd_out[7:4]} :8'hzz; |