复用引脚,陷阱多多
本来一个简简单单的TFT,本以为是个小case,代码到仿真个把小时的事情 ,到搭起来的简陋调试板上一试,不亮,什么问题?当然代码不可能一次OK,所以回头找问题,最后总算能够在上下电的瞬间看到自己测试用的色彩了,但是只有那么短暂的瞬间。 其实大多问题出在简陋的板子上,又折腾了一番,情况稍微好了那么一些,测试色彩出来了,但是时序明显不稳定,不停的又杂色掺杂进来一闪一闪的。一直以为有可能是没用上 DE 信号配合 HSY/VSY使用,但是 datasheet 上明白地写着可以使用不带 DE 信号的 HSY 模式。 最后板子都快让咱用烙铁捣鼓烂了,实在很无奈。 静下心来发现有时代码下载进去后蜂鸣器跟着乱叫,那么一定是有地方短路了,这是第一反应,也绝对不是 VCC 和GND,这是可以肯定的。 很有可能是I/0口什么地方短路了,于是再一次细心地搜寻,结果发现了 CPLD 上接 LCD_CLK 的 l/0 口似乎和GND 短路了 ,并且这个I/0口原来是 BJ-EPM 板子上与一个在 SN74LS4245 上定义为 DQ的接口相连的,而这个接口以前不用,焊接好了也没有测试过,原来是它和GND 之间短路了 。 也难怪原来时序不稳定 ,解决了这个问题之后再试,发现问题似乎依旧,那又是为什么呢?忽然想起某天和同事讨论设计DSP的5V到3.3V外设扩展总线接口时使用 74ALVC164245APW(下文简称 4245)的问题。 这个4245很值得注意,DlR接高电平时代表着一个方向 ,接低电平时代表着另一个方向。 对于该CPLD,不用4245时会给DIR一个高阻态,那么它的DO会是什么状态?换了别的厂家的4245,也许不一定是一个固定的状态。 问题肯定就在这个与4245复用的LCD时钟信号上了 ,用不起咱还躲不起啊,哈哈,换!
被综合掉的寄存器
一个很蹊跷的仿真问题,问题是这样的,一个测试中写下面的一段代码:
// 色彩信号产生
reg[23:0] vga_rgb; //色彩显示寄存器
always @(posedge ck or negedge rst_n)
if(!rst_n) vga_rgb <= 24'd0;
else if (! valid) vga_rgb <= 24'd0;
else vga_rgb <= 24'hff_00_ff;
//r,g,b控制液晶屏颜色显示
assign lcd_r = vga_rgb[23:16];
assign lcd_g = vga_rgb[15:8];
assign lcd_b = vga_rgb[7:0];
很明显,这段代码里的vga_rgb寄存器的位15~8是不变的,始终为0。 而这样的代码在仿真时,vga_Igb的值却出现了一些意外, 如图2.57所示 。 在代码中 ,寄存器vga_rgb的位15~8虽然始终保持低电平,但是仿真结果却是高阻态。 为什么呢?回头看看综合报告,如图2.58所示: 说明 vga_rgb[15:8] 被综合掉了,即所谓 removed registers,所以这个 8 位寄存器不存在 了,仿真时也就只能以 8’hzz 代替了 。 若将代码改成:
// 色彩信号产生
reg[23:0] vga_rgb; //色彩显示寄存器
always @(posedge ck or negedge rst_n)
if(!rst_n) vga_rgb <= 24'd0;
else if (! valid) vga_rgb <= 24'd0;
else vga_rgb <= 24'hff_ff_ff;
//r,g,b控制液晶屏颜色显示
assign lcd_r = vga_rgb[23:16];
assign lcd_g = vga_rgb[15:8];
assign lcd_b = vga_rgb[7:0];
这样 vga_rgb 的所有 24 个寄存器都可能出现变化,也就不会被综合掉,那仿真后是否正常呢?如图2.59所示,得到预期的结果。 因此,在代码中如果是从始至终没有变化的信号值很可能让“智能”的综合工具优化了。
Cyclone器件全局时钟尽在掌握
Cyclone 系列的器件基本都有 2 个PLL,只有 EP1C3 是 1个 PLL。 Cyclone 系列器件的全局时钟网络分配情况大体如图 2. 60 所示 。 CLKO/CLKl 可以作为 PLLl 的输人,CLK2/CLK3 可以作为 PLL2(EP1C3 没有)的输人。 当然了,如果尝试用上面规定的时钟引脚以外的引脚作为 PLL 的输入,那么只会换来 Quartus ll 的报错信息。 而从图 2.60 中可以看到 PLL 最多可以有 3 个输出:C0,C1,E0。 C0 和 C1一般作为内部时钟使用,而 E0 只能作为外部输出使用的时钟,也就是说这个 E0 必须直接连接到器件外部的引脚上。 如果尝试在 FPGA 内部逻辑使用 E0 作为时钟;那么同样只能换来 Quartus II 的报错信息。 另外有一点必须提一下,先看图 2.61: 第2条方波是作为 PLL 输人的时钟 clk,而往下第 3 条、第4 条、第 5条波形分别是 C0、 C1、E0,最后面一个是所谓的 lock 信号(高电平表示 PLL 输出有效) 。 也就是当 PLL 复位完成或者使能(到底要复位还是使能是可以在配置 PLL 时选择的)若干个时钟周期后 PLL 的输出才会有效,那么在 lock 拉高以后的 PLL 才是我们想要的。 图 2.61 输入的时钟和输出的时钟之间似乎没有相位差,是很理想的一个状态。 但是实际上 PLL 出来的时钟和输入的时钟之 间总是存在相位差的。可以看看仿真后的波形,如图 2.62 所示 : 因此,在 PLL 时钟资源充裕的情况下,统一使用 PLL输出时钟作为内部逻辑的时钟,而不使用 PLL 的输入作为内部时钟,这样是为了防止内部的各个时钟之间出现不期望的相位差,同时也发现 PLL 的输人时钟驱动内部逻辑的 clock network latency 相对要比 PLL 输出的时钟驱动内部逻辑的clock network lacency 大得多。 如果非得用PLL的输人时钟同时作为内部逻辑的时钟,最好是根据它们的相位关系进行一下时钟的对齐,如图2.63和图2.64所示。 下面再看看Cyclone器件的内部全局时钟网络的分配,如图2.65所示,一共8个全局时钟网络,左右各4个。而PLLl的输出C0、C1、CLK0/1以及DPCLK0~3(复用的时钟引脚)或者内部的逻辑可以使用左边的4个全局时钟网络;PLL2的输出C0、C1、CLK2/3以及DPCLK4 ~7(复用的时钟引脚)或者内部的逻辑可以使用右边的4个全局时钟网络。PLL输出作为外部时钟的E0是不会(也没有必要)分配到全局时钟网络的。 就拿左侧来说,可以使用4个全局时钟网络的信号其实不少,它们之中到底谁使用有限的全局时钟网络呢?这都是可以由设计者来掌控的。当然了,在设计者不进行设置时,综合工具会根据开发软件的默认设置来分配。 如果选择Setting–>Fitter Setting–>More Setting里的Aut Global Clock, Quartus ii在实现时会根据内部逻辑的实际情况自动分配全局时钟,就是说谁占用全局时钟网络软件说了算(一般系统的时钟和复位信号会占用全局时钟网络)。当然,也可以人为关闭它,然后自己来分配,这时可以到Assignment Edit中Global Signals里进行分配,接着可以到编译报告里查看Fitter–>Rescource Section–>Global里的信息。 另外还有一个值得注意的地方,并不是任何一个时钟信号或者复位信号都可以随意地占用任意一个全局时钟网络。 表2. 2列出了全局时钟网络资源的详细分配情况,比如PLLl的输出 C0 只能使用GCLK1 或者CCLK2,C2 只能使用GCLK0 或者GCLK3。 拿一个实例来看看,有一个从CLK1引脚输入的时钟信号clk,这个时钟信号clk同时是PLL1的输入,用于产生两个PLL1输出C0和C1;系统本身有一个复位信号rst_n。此外,内部逻辑产生一个时钟clk_divown,在AutoGlobal Clock开启的情况下得到了如图2.66所示的全局时钟网络的分配结果。 PLL1的C0分配到GCLK2,C1分配到了GCLK3,PLL1的输入时钟即clk分配到了GCLK1,它们都分配到了规定的全局时钟网络内。另外,clk_div_own和rst_n随机分配。 这个器件的全局时钟网络对于我们的实例还是绰绰有余的,但是一个大的系统,时钟交错,高扇出的信号层出不穷,那么对于全局时钟信号的掌控就需要格外小心了。
M4K使用率
在使用Cyclone的M4K时发现了一个问题,设计中需要配置一个数据宽度为224位、深度为32的Signal-Port ROM。原则上这样一个ROM占用的存储空间应该为224位X32= 7 168位,这样最多两个M4K(4096位X2=8192位)也足够了,但是发现Mega Wizard里显示的资源利用是7个M4K。挺纳闷的,于是查看了datasheet。 datasheet 罗列了一个 M4K 可以配置的 ROM 或者 RAM 为 4 KbX1、 2 KbX2 、 1 KbX4、 512 bX 8、 512 b X 9 、256 bX16、 256 b X 18、 128 bX 32 、 128 bX 36。 注释里这么说: Altera Quartus II自动层叠或连接多个 M4K 块以满足更宽或者更深的 RAM/ROM 配置。 这下明白了,应该说一个 M4K 最多可以配置 36 位宽,如果再大了,那么就会占用其他的M4K 块,所以设计中的 224 位至少时需要 7 个 M4K 块 (7X 36=252 > 224 ,而 6X36=216 < 224) 。 至于到底是配置大位宽还是提高M4K利用率,还是看设计需要。鱼和熊掌不可兼得!
|