OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子全套STM32/FPGA开发资料,上千讲STM32视频教程,RT1052教程免费下载啦...
查看: 877|回复: 17

新手求救 这里如何延时2us

[复制链接]

  离线 

226

主题

829

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1360
金钱
1360
注册时间
2011-10-9
在线时间
101 小时
发表于 2017-11-6 14:49:12 | 显示全部楼层 |阅读模式
1金钱
/LED块
always @(posedge CLK)
begin
        CNT_LED = CNT_LED + 1'b1;
        if(CNT_LED==28'h17d7840)begin        //2HZ输出
        LED = !LED;                                                        //LED取反       
        CNT_LED = 28'd0;                                        //清除计数

        end
       
end

always @(posedge FIRE)                //上升沿事件
begin

       
                        OK_OUT = 0;
                           for (a=9'd0;a<22;a=a+1)
                           begin
                          
                           ADDR_OUT[a]=1;
                            
                                     
                            for (i=9'd0;i<14;i=i+1)
                                        begin
                                       
                                       
                                                        DATA_OUT=!Input_Cache[Xrom[a*i+i+1]];
                                        //<<<<<<<<<<<<<<<<<<<这里要求延时2us
                                       
                                end
                          
                          
                       
                         end
                                OK_OUT = 1;
end

最佳答案

查看完整内容[请看2#楼]

放下了几个月 这2天临时有空 又拿出来折腾了下 居然很快就想通并调试成功了 记录下心得 FPGA是硬件模式并行系统 ,所以我的理解是 全部触发都最好基于时钟。 为了保持第一个信号逻辑 必须有RST 逻辑。 其次 ,之前百思不得解的延时问题。 在FPGa里面没有延时 只有时序。 所以目前理解正确的方式 应该是建立一个 2us的时钟分频 然后置标志 来处理分频时间点达到目的。 因为是并行 就算时钟每次触发进入程序,只要状态 ...
回复

使用道具 举报

  离线 

226

主题

829

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1360
金钱
1360
注册时间
2011-10-9
在线时间
101 小时
 楼主| 发表于 2017-11-6 14:49:13 | 显示全部楼层
放下了几个月  这2天临时有空 又拿出来折腾了下 居然很快就想通并调试成功了
记录下心得

FPGA是硬件模式并行系统 ,所以我的理解是 全部触发都最好基于时钟。 为了保持第一个信号逻辑 必须有RST 逻辑。

其次 ,之前百思不得解的延时问题。  在FPGa里面没有延时 只有时序。 所以目前理解正确的方式 应该是建立一个 2us的时钟分频 然后置标志 来处理分频时间点达到目的。

因为是并行 就算时钟每次触发进入程序,只要状态机的状态没变 其实什么都没变。 所以这里只需要改变状态机即可。
时钟分频输出标记

always @(posedge CLK  )
begin
   
       
if (fire == 1)  //RST=0 重启
        begin
        CNT_2us =0;       
        H2us=1;
        L2us=0;
        c=0;
        d=1;
        end
       
        if(fire == 0 )
        begin
       
                                 CNT_2us = CNT_2us + 1'b1;
                                 CNT_1us = CNT_1us + 1'b1;
                                 
                                 
                                 if (CNT_1us == 16'h40 & c == 1)  //窄周期
                                 begin
                                 H2us=1;
                                 L2us=0;
                                 CNT_2us=0;
                                 d=1;
                                 c=0;
                                 
                                 end
                                 
                                 
                                 if(CNT_2us==16'h65 & d == 1) //宽周期
                                 begin        //2HZ输出
                                 H2us=0;
                                 L2us=1;
                                 CNT_1us=0;
                                 c=1;
                                 d=0;
                                // L2us=!L2us;                               
                                 CNT_2us = 16'd0;                                        //清除计数
                         end
                                 
         end
end


然后通过标记改变状态
回复

使用道具 举报

  离线 

51

主题

6113

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
10130
金钱
10130
注册时间
2014-4-1
在线时间
961 小时
发表于 2017-11-6 16:45:15 | 显示全部楼层

用计数器实现。

回复

使用道具 举报

  离线 

226

主题

829

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1360
金钱
1360
注册时间
2011-10-9
在线时间
101 小时
 楼主| 发表于 2017-11-6 21:30:21 来自手机 | 显示全部楼层
高手能否举个例子,总想不好计数器的结构
回复

使用道具 举报

  离线 

516

主题

9万

帖子

31

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
134732
金钱
134732
注册时间
2010-12-1
在线时间
1316 小时
发表于 2017-11-7 00:42:55 | 显示全部楼层
帮顶
回复

使用道具 举报

  离线 

51

主题

6113

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
10130
金钱
10130
注册时间
2014-4-1
在线时间
961 小时
发表于 2017-11-7 09:12:55 | 显示全部楼层
本帖最后由 xuande 于 2017-11-7 09:32 编辑

楼主肯定是刚开始学。

第一段,2Hz方波,
整体还行,但缺少复位信号,会造成第一个脉冲不可信。复位逻辑必须有。

第二段几个问题:
1、用 FIRE 电平触发事件而不是时钟,这会造成异步时序,带来潜在问题,比如逻辑冒险,很难解决的。
改正:
always    @(posedge   clk)
begin
      if    (FIRE)
            ............      else
            ............
end

2、也缺少复位逻辑。这情况在前一段只会造成头一个脉冲不可信,但在这一段会产生致命问题。
3、for循环,我只见过用在 testbench 里。因为 testbench 是软件理解软件,但是否能综合(就是用真实电路实现)就要划问号了。
    我不敢说绝对不可综合,但从来没见过这么用,我自己也从来不用。


回复

使用道具 举报

  离线 

51

主题

6113

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
10130
金钱
10130
注册时间
2014-4-1
在线时间
961 小时
发表于 2017-11-7 09:24:03 | 显示全部楼层
2us 延时,大概这样:
always    @( posedge clk ,  negedge rst )
begin
       if    ( !rst )
            begin
            counter2uS = 0;
            .........           (复位逻辑)            end
       else
            begin
            counter2uS =  counter2uS + 1;
            if      (counter2uS == 2uS)
                    .............
            else
                    .............
            end
end





回复

使用道具 举报

  离线 

226

主题

829

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1360
金钱
1360
注册时间
2011-10-9
在线时间
101 小时
 楼主| 发表于 2017-11-7 11:44:30 | 显示全部楼层
本帖最后由 simms01 于 2017-11-7 11:50 编辑
回复错了 ,见楼下
回复

使用道具 举报

  离线 

226

主题

829

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1360
金钱
1360
注册时间
2011-10-9
在线时间
101 小时
 楼主| 发表于 2017-11-7 11:49:46 | 显示全部楼层
本帖最后由 simms01 于 2017-11-7 11:52 编辑
xuande 发表于 2017-11-7 09:12
楼主肯定是刚开始学。

第一段,2Hz方波,

确实  刚开始学的

其中1  复位信号  RST 这个信号 是硬件的引脚信号 还是可以虚拟一个信号给他?

2 如果不用 for  这种要循环20多次的情况  怎么去解决?就是收到一个fire高电平 里面的事情干20次。难道一遍一遍列出来?

3. 计数器延时 例如 LED闪烁是可以 但是怎么在另一个 always里面调用这个延时?本来想用while的 发现在PGA里面 用while就是个傻子   

从stm32转过来 好多不能理解的:(  开发板教程只是给出例子也没解说,望大神帮忙解答下
回复

使用道具 举报

  离线 

51

主题

6113

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
10130
金钱
10130
注册时间
2014-4-1
在线时间
961 小时
发表于 2017-11-7 11:52:33 | 显示全部楼层
simms01 发表于 2017-11-7 11:49
确实  刚开始学的

其中1  复位信号  RST 这个信号 是硬件的引脚信号 还是可以虚拟一个信号给他?


下午有时间再答你。

回复

使用道具 举报

  离线 

226

主题

829

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1360
金钱
1360
注册时间
2011-10-9
在线时间
101 小时
 楼主| 发表于 2017-11-7 12:37:20 | 显示全部楼层
本帖最后由 simms01 于 2017-11-7 12:44 编辑
xuande 发表于 2017-11-7 11:52
下午有时间再答你。

今天下载了某大神的例子  发现  直接是结构错了 不知道下面理解对不对   :( 就如 刚学C没懂main一样

always    @( posedge clk ,  negedge rst )   《《===这玩意就像 单片机的  main()
begin
   if (!rst)
  begin
    ...各种变量信号 赋初值
  end
  else
  begin
    ...这里是程序  类似单片机的大循环
   例如  if (spi_clk)   //<<==问题是 当这个spi_ck 比 CLK 要宽很多 那么 这里不是被执行很多次? 每次CLK上升沿+ spiclk高电平  就执行一次
    begin

   end

   

  end

end
回复

使用道具 举报

  离线 

51

主题

6113

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
10130
金钱
10130
注册时间
2014-4-1
在线时间
961 小时
发表于 2017-11-7 14:01:48 | 显示全部楼层
本帖最后由 xuande 于 2017-11-7 14:02 编辑
simms01 发表于 2017-11-7 11:49
确实  刚开始学的

其中1  复位信号  RST 这个信号 是硬件的引脚信号 还是可以虚拟一个信号给他?




1、是外部提供的硬件信号,和CPU复位端一样。

2、(自己替换begin 。。。。end)
begin
         if    ( !rst )
              {  a=0;   }
         else
              {
              if     (  a < 20 )
                    {
                    ...........(你要做的事)
                    a = a + 1;
                    }
              }
end


3、好像没法调用。
     最多就是用计数器的值做一下判断,比如等于1干什么,等于10干什么。
     但这和延时是两回事。




回复

使用道具 举报

  离线 

51

主题

6113

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
10130
金钱
10130
注册时间
2014-4-1
在线时间
961 小时
发表于 2017-11-7 14:15:02 | 显示全部楼层
本帖最后由 xuande 于 2017-11-7 14:22 编辑
simms01 发表于 2017-11-7 12:37
今天下载了某大神的例子  发现  直接是结构错了 不知道下面理解对不对   :( 就如 刚学C没懂main ...

红字的话很好,说明你已经深入考虑进去了。

解决的方法大概有:
1、设标志,如果在本次高电平期间已经做了一次动作,则设标志。
比如:
if     (!rst)
     {  flag = 0;    }
else
     {
     if     ((spi_clk)  && (flag == 0))
         {
          。。。。。。。。(你的事)
          flag = 1;
         }
     else if   (!spi_clk)
           {  flag = 0;  }
     }

2、记录下spi_clk 前天、昨天、今天的状态,自己检测上升沿。出现001、011,就是上升沿到了。




回复

使用道具 举报

  离线 

51

主题

6113

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
10130
金钱
10130
注册时间
2014-4-1
在线时间
961 小时
发表于 2017-11-7 14:26:30 | 显示全部楼层
本帖最后由 xuande 于 2017-11-7 14:27 编辑
simms01 发表于 2017-11-7 12:37
今天下载了某大神的例子  发现  直接是结构错了 不知道下面理解对不对   :( 就如 刚学C没懂main ...


设计硬件,关键就是“并行”,这一点和CPU有本质区别。
1、每个always就是一个CPU,独立运行自己的线程。
2、任何一个变量,只能在一个线程里改写,
     其他线程不能改写它,否则就错了,
     在其他线程可以读,比如根据它的值来做点事,为1干什么,2干什么,5干什么,之类。



回复

使用道具 举报

  离线 

226

主题

829

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1360
金钱
1360
注册时间
2011-10-9
在线时间
101 小时
 楼主| 发表于 2017-11-7 17:30:10 | 显示全部楼层
xuande 发表于 2017-11-7 14:26
设计硬件,关键就是“并行”,这一点和CPU有本质区别。
1、每个always就是一个CPU,独立运行自己的线 ...

谢大神解答,搞技术在于折腾 发现在折腾中会了很多 呵

不过发现pga 的写法 限制比单片机的多很多 关键是没有像C那样的全局变量 一个变量只能在一个always 里面写,其他的只能读了。

感觉c是很随意的,最多运行效率差一点点  但是fpga 一个意思2个写法 占用的资源差很远............有点像汇编,要非常严谨。

再深入折腾下 。  谢谢大神:)   
回复

使用道具 举报

  离线 

15

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
94
金钱
94
注册时间
2018-3-7
在线时间
11 小时
发表于 2018-3-8 15:44:43 | 显示全部楼层
你延时是要对哪个信号延迟?是不是想对上一句执行完后延时?这不是c语言哦
回复

使用道具 举报

  离线 

0

主题

9

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2018-6-3
在线时间
3 小时
发表于 2018-6-3 09:36:40 | 显示全部楼层
刚学一个学期,看到always的时候,吓得我连忙去翻课本,what 没学过always语句呀
意识中都是process的进程语句,看到后面,感觉always和process好像,
回复

使用道具 举报

  离线 

226

主题

829

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1360
金钱
1360
注册时间
2011-10-9
在线时间
101 小时
 楼主| 发表于 2018-6-5 09:28:09 | 显示全部楼层
PGA就是入门难点 理解了只有还是挺好处理事情的

例如这个帖子 可以
always    @( posedge clk ,  negedge rst ) 
begin
这里设置标志  例如  2us 到了 h2us=1   可以理解为分频也可以理解为定时器

end

然后应用

if ( FIRE==1 &&  H2us==1)

这样就可以实现精确的时序输出
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则




关闭

正点原子双11大促销上一条 /1 下一条

正点原子公众号

QQ|联系我们|手机版|官方淘宝店|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2018-11-16 11:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表
/* */