一个关于Diamond中的Reveal如何选用参考时钟的问题

最近在调试DDR3的时候遇到一个奇怪的问题,经过一段时间的排查定位,最后发现是Reveal引起的,下面来简单地总结一下。

1、问题描述:

在使用Lattice DDR Controller相关IP的时候,一般建议把Clarity或者IPexpress生成的评估工程下面的lpf文件中的约束拷贝过来,稍加修改,添加至自己的工程的lpf文件中。

在相关约束中有这样两句:

FREQUENCY NET "sclk*" 150.000000 MHz PAR_ADJ 30.000000 ;
BLOCK PATH FROM CLKNET "*/clkos*" TO CLKNET "sclk*" ;

都是关于sclk的约束。但是在MAP的时候却报错说找不到sclk*,所以把以上两条约束给Disable掉了。也就是说这两条约束不会对PAR和TRACE产生任何影响。警告如下:

WARNING - map: 
     D:/My_Project/EVDK_Proj/ECP5_ISP/implementation/ECP5_ISP.lpf(10):
     Semantic error in "BLOCK PATH FROM CLKNET "*/clkos*" TO CLKNET "sclk*" ;":
     sclk* matches no nets in the design.  This preference has been disabled.
WARNING - map:
     D:/My_Project/EVDK_Proj/ECP5_ISP/implementation/ECP5_ISP.lpf(347): Semantic
     error in "FREQUENCY NET "sclk*" 150.000000 MHz PAR_ADJ 30.000000 ;": sclk*
     matches no nets in the design.  This preference has been disabled.

百思不得其解,突然想起来工程中好像有Reveal(选用了sclk作为采样时钟),于是乎尝试把Reveal禁止掉,并删除Reveal相关的约束,发现居然好了……

2、问题分析

于是乎,在Strategy中设置Check Unconstrained Connections & Paths,居然也没有找到sclk……消失了……

检查刚才删除的Reveal相关的约束:

rvl_alias "reveal_ist_583" "ddr3_test_top_inst/sclk";

发现Reveal给sclk起了个别名,也就是说sclk消失的原因是其被重命名为reveal_ist_583了……

检查另一个工程,则为:

rvl_alias "sclk" "u_ddr_ulogic/sclk";

因此,另一个工程并不会出现这样的情况。但是问题是这句约束是Reveal自动产生的,什么时候会出现第一种情况(有问题的),什么时候又会是正常的呢?

检查Reveal Troubleshooting Guide.pdf文档,发现如下一段话:

image.png

也就是说,当Reveal选用的采样时钟是内部信号(且不存在于顶层),同时该时钟信号有相关的时序约束时,就可能会发生这样的情况。

3、解决问题

找到了问题了,如何解决呢?

最简单的方法显然是换一个采样时钟,但是对于很多情况下来说,这是不太现实的。

有人可能觉得只需要把

rvl_alias "reveal_ist_583" "ddr3_test_top_inst/sclk";

修改成

rvl_alias "sclk" "ddr3_test_top_inst/sclk";

就可以了,就像另一个工程中的那样。但是实践证明,这样是不行的,因为这句约束是在综合的时候由Reveal自动产生的,强制的修改并没有意义(即使是在综合结束后再去修改,然后再进行MAP,依旧是然并卵)。

在Reveal Troubleshooting Guide.pdf文档中,推荐的解决方法是:

修改

FREQUENCY NET "sclk*" 150.000000 MHz PAR_ADJ 30.000000 ;
BLOCK PATH FROM CLKNET "*/clkos*" TO CLKNET "sclk*" ;

为:

FREQUENCY NET "reveal_ist_583" 150.000000 MHz PAR_ADJ 30.000000 ; // With Reveal
BLOCK PATH FROM CLKNET "*/clkos*" TO CLKNET "reveal_ist_583" ;   // With Reveal

4、Reveal采样时钟选择注意事项

4.1、采样时钟的频率不能太低,至少要大于JTAG的时钟频率;

4.2、采样时钟的频率也不能太高,一般要低于200MHz;

4.3、尽量使用顶层的时钟信号(避免出现本文讨论的问题);

4.4、尽量不要使用门控的时钟信号,保持采样时钟的持续稳定;

4.5、如需不需要持续采样,可以使用Sample Enable,或者合理地设置触发条件(多次触发)。

5、主要参考文档

Reveal39TroubleshootingGuide.pdf

RevealUG_39.pdf

6、推荐阅读

http://www.cnblogs.com/xiaozhuge/p/5636384.html

Diamond在线调试工具Reveal使用教程.pdf

注:原文最早发表于本人的ChinaAET博客(http://blog.chinaaet.com/justlxy/

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的扫雷游戏的Java代码,仅供参考: ```java import java.util.*; public class Minesweeper { private int rows; private int cols; private int numMines; private int[][] board; private boolean[][] revealed; private boolean gameOver; private int remainingTiles; public Minesweeper(int rows, int cols, int numMines) { this.rows = rows; this.cols = cols; this.numMines = numMines; this.board = new int[rows][cols]; this.revealed = new boolean[rows][cols]; this.gameOver = false; this.remainingTiles = rows * cols - numMines; // initialize board with mines and numbers Random rand = new Random(); for (int i = 0; i < numMines; i++) { int row = rand.nextInt(rows); int col = rand.nextInt(cols); if (board[row][col] != -1) { board[row][col] = -1; for (int r = row - 1; r <= row + 1; r++) { for (int c = col - 1; c <= col + 1; c++) { if (r >= 0 && r < rows && c >= 0 && c < cols && board[r][c] != -1) { board[r][c]++; } } } } else { i--; } } } public void reveal(int row, int col) { if (revealed[row][col] || gameOver) { return; } revealed[row][col] = true; remainingTiles--; if (board[row][col] == -1) { gameOver = true; return; } else if (board[row][col] == 0) { for (int r = row - 1; r <= row + 1; r++) { for (int c = col - 1; c <= col + 1; c++) { if (r >= 0 && r < rows && c >= 0 && c < cols) { reveal(r, c); } } } } } public void printBoard() { for (int r = 0; r < rows; r++) { for (int c = 0; c < cols; c++) { if (revealed[r][c]) { if (board[r][c] == -1) { System.out.print("* "); } else { System.out.print(board[r][c] + " "); } } else { System.out.print("- "); } } System.out.println(); } } public boolean isGameOver() { return gameOver; } public boolean isGameWon() { return remainingTiles == 0; } } ``` 使用示例: ```java Minesweeper game = new Minesweeper(10, 10, 15); Scanner scanner = new Scanner(System.in); while (!game.isGameOver() && !game.isGameWon()) { game.printBoard(); System.out.print("Enter row and column to reveal: "); int row = scanner.nextInt(); int col = scanner.nextInt(); game.reveal(row, col); } if (game.isGameWon()) { System.out.println("Congratulations, you won!"); } else { System.out.println("Game over!"); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值