OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6520|回复: 0

接手其它人FPGA项目时的小技巧——反推代码(下)

[复制链接]

31

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
142
金钱
142
注册时间
2018-7-19
在线时间
8 小时
发表于 2018-8-29 10:33:09 | 显示全部楼层 |阅读模式
之前介绍了如何通过逆向反推,高效去阅读他人的代码,快速地完成学习或者完成项目这种方法。现在给大家讲一下,在这个基础上,怎么能学习到更好的设计方法,掌握其精髓,从而提高设计水平。我们仍然以实现相同功能“帧率采样计算”的另外一组代码为例。
  
1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
  
9
  
10
  
11
  
12
  
13
  
14
  
15
  
16
  
17
  
18
  
19
  
20
  
21
  
22
  
23
  
24
  
25
  
26
  
27
  
28
  
29
  
30
  
31
  
32
  
33
  
34
  
35
  
36
  
37
  
38
  
39
  
40
  
41
  
42
  
43
  
44
  
45
  
46
  
47
  
reg [  :0]    cnt0    ;
  
wire         add_cnt0;
  
wire         end_cnt0
  
always @(posedge clk or negedge  rst_n)begin
  
    if(!rst_n)begin
  
        cnt0 <= 0;
  
    end
  
    else if(add_cnt0)begin
  
        if(end_cnt0)
  
            cnt0 <= 0;
  
        else
  
            cnt0 <= cnt0 + 1;
  
    end
  
end
  
  
assign add_cnt0 = 1;      
  
assign end_cnt0 = add_cnt0  && cnt0==26'd25_000000-1 ;
  
  
reg [  :0]    cnt1    ;
  
wire         add_cnt1;
  
wire         end_cnt1;
  
always @(posedge clk or negedge  rst_n)begin
  
    if(!rst_n)begin
  
        cnt1 <= 0;
  
    end
  
     else if(end_cnt0)begin
  
        cnt1 <= 0;
  
    end
  
    else if(add_cnt1)begin
  
        if(end_cnt1)
  
            cnt1 <= 0;
  
        else
  
            cnt1 <= cnt1 + 1;
  
    end
  
end
  
  
assign add_cnt1 =  CMOS_VSYNC_over;      
  
assign end_cnt1 = add_cnt1  && cnt1==100-1 ;
  
  
always  @(posedge clk or negedge rst_n)begin
  
    if(rst_n==1'b0)begin
  
        CMOS_FPS_DATA <= 0;
  
    end
  
    else if(end_cnt0) begin
  
        CMOS_FPS_DATA <= cnt1;
  
    end
  
end
      同样,通过反推法我们可以得知作者的思路如下:
1.  设定1秒内cnt0,不断+1; 数26'd25_25-000000表示1秒时间到;
2.  接下来对CMOS表示帧,设定值不超过100帧;
3.  设定清零cnt0,用cnt0数1秒的时间;
4.  CMOS_FPS_DATA <= cnt1,信号给出条件end_cnt0,至此功能得到实现。
  OK,我们现在可以简单比较一下。实现相同功能,第一个例子以2秒内'd50_000000条件下计数后除以2,第二个例子用1秒内cnt0作为时间,cnt1计数来实现。第二个例子完全没有使用data等,非常轻松地完成功能要求。
如果再深入去分析,可能会发现第二个例子有个更加奇妙之处。那就是实现了模板化设计,比如上述代码第1行到第17行处,就是一个模板,只需要键入Cnt0;对于这个模块来说,设计者仅仅输入了第16行的“1”和第17行的“26'd25_000000-1”,同时进行几个条件设置,即完成设计。这样的代码,给人的感觉就像武术大师李小龙,简单粗暴但是非常直接有效地击倒对手。
在前言中我们提到,正确的学习方法非常重要。通过思考,掌握其原理,无疑是提高自己水平最好的路径之一。在本案例实现相同功能的不同代码中,不应该是去生搬硬套,看代码后学会实现这个功能,也不仅仅应该学到运用反推法去看懂别人的代码。应该明白的是实现相同功能,有很多种方法,多去比较和思考不同设计的方法、思路、技巧,学习和借鉴其精髓,并运用到实际设计中。随着不断的积累,设计水平会得到不断的提升。
正确的学习方法还有一点是能够举一反三。上文的实例只是引用了一小部分模块,对于整个的项目同样可以运用反推法来实现。反推法看懂代码的核心,是通过功能反推过程,是一个逆向的思维过程,那么我们首先要知道的是功能点。有些同学要说了,那我不知道要实现功能是什么怎么办?功能点是一个设计目标,与什么设计方法、思路、工具完全没有关系。只需要通过看相关的数据手册、问相关的项目负责人,这个项目(模块)需要实现的是什么功能即可。对于一个整体的项目来说,其实方法是一样的。比如,一个摄像头显示的程序,分别有4个模块。我们不需要从头开始向下顺序看下去,事实上也很难看懂。我们知道最后的VGA显示是一定的(最终实现功能),那么需要什么样的VGA时序才能显示出图像呢?根据VGA的时序图、数据手册等资料,导入到模块4VGA时序模块。接着在模块4中继续反推,这个信号接口是从哪里来的?这个信号是从哪里输入的?在过程中再不断参考数据手册等资料,这样每个模块乃至每个信号都能依次推出来。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 00:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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