top_down设计的认知

写在前面的话

本节呢,梦翼师兄重点和大家谈一下层次化设计方法,我们所谓的层次化设计,实际上就是对一个很大的系统设计进行拆分,直到拆分成很容易实现的最小模块为止。我们都知道,如果我们想要盖一栋大楼,那么首先一定是先设计好工程图纸,然后建筑工人才可以根据设计图纸施工。那么电子系统设计呢?其实也是这样的,在进行具体代码设计之前,我们首先应该认真分析整个的项目需求,在确定项目需求理解无误的情况下,按照电路功能不同,我们可以将整个系统划分成若干个比较大的子模块,然后根据各子模块的功能,进行进一步的细分,直至无法分解。好的层次划分可以有效降低系统开发难度,同时也有利于团队作战,团队中的每个人只需要负责完成自己的那部分模块,最后由顶层设计者进行组装拼接即可完成整体项目的设计。

层次化设计框图示例

如上图所示就是一个简易的层次化设计模型,系统顶层模块只是负责连线,将各功能单元正确的组合起来。而各功能单元又由各自对应的若干子模块组成,同一单元的子模块之间有着相应的级联关系。

层次化设计实例

大家还记得梦翼师兄给大家分享的流水灯实验吗?在这里,我们回顾一下,我们首先用状态机实现了流水灯的时序,然后由于LED灯切换时间过快,我们无法看到流水的现象,因此我们又采用了两种方式来限制LED切换,第一种:在状态机中嵌入延时计数器 第二种:创建一个时钟分频模块,然后用慢时钟驱动状态机。我们利用以上两种方式最终都实现了流水灯的结果,而且所有的代码修改都是在同一个文件下。那么今天梦翼师兄和大家一起来学一下层次化设计的实现方式。

系统顶层架构图

模块功能介绍

模块名

功能描述

Freq

时钟分频模块,用来分频产生慢时钟

LED_Driver

LED驱动,控制LED灯切换

Led_flow

系统顶层模块,负责子模块级联

 

 

 顶层模块端口介绍

端口名

端口说明

Clk_sys

系统50MHz时钟输入

Rst_n

系统复位

Pio_led

LED驱动端口

4.1.3.4 系统内部连线介绍

连线名

连线说明

Clk_slow

分频得到的慢时钟信号

4.1.3.5 代码解释

LED_Driver 模块代码

/****************************************************          

*   Engineer        :   梦翼师兄

*   QQ               :   761664056

*   The module function:流水灯驱动模块

*****************************************************/

01  module led_learn(

02                      clk,   //系统时钟输入

03                      rst_n, //系统复位

04                      pio_led//LED驱动输出

05                  );

06  //系统输入

07  input clk;   //系统时钟输入

08  input rst_n; //系统复位

09  //系统输出

10  output reg [3:0]pio_led;//LED驱动输出

11  //中间寄存器定义

12  reg [1:0]state;//状态寄存器定义

13      

14  //LED驱动逻辑

15  always@(posedge clk or negedge rst_n)

16      begin

17          if(!rst_n)

18              begin

19                  pio_led<=4'b1111;//LED全部熄灭

20                  state<=0;//寄存器赋初值

21              end 

22          else begin 

23              case(state)

24                  0:begin

25                      pio_led<=4'b0111;//第一个灯点亮

26                      state<=1;//状态跳转

27                  end 

28                  1:begin

29                      pio_led<=4'b1011;//第二个灯点亮

30                      state<=2;//状态跳转                 

31                  end 

32                  2:begin

33                      pio_led<=4'b1101;//第三个灯点亮

34                      state<=3;//状态跳转                 

35                  end 

36                  3:begin

37                      pio_led<=4'b1110;//第四个灯点亮

38                      state<=0;//状态跳转                 

39                  end 

40                  default:state<=0;

41                  endcase 

42          end

43      end 

44  endmodule 

本模块代码就是我们之前做过的做基本状态机驱动模块,每来一个驱动时钟上升沿,状态发生一次跳转,LED值随之发生改变。

Freq 模块代码

/****************************************************          

*   Engineer        :   梦翼师兄

*   QQ               :   761664056

*   The module function:时钟分频模块

*****************************************************/

01  module freq(clk,rst_n,clk_slow);

02  input clk;//系统50MHz时钟输入

03  input rst_n;//系统复位

04

05  output reg clk_slow;//慢时钟定义

06

07  reg [40:0]counter;//计数器定义

08

09  //时钟分频电路

10  always@(posedge clk or negedge rst_n)

11      begin

12          if(!rst_n)

13              begin

14                  counter<=0;//计数器赋初值

15                  clk_slow<=0;//慢时钟赋初值

16              end 

17          else 

18              begin

19                  if(counter<12)

20                      counter<=counter+1;

21                  else 

22                      begin

23                          counter<=0;

24                          clk_slow<=~clk_slow;

25                      end 

26              end 

27      end 

28  endmodule

该模块的作用就是利用计数器实现分频:统计一定的快时钟个数,然后驱动慢时钟寄存器值发生翻转,输出慢时钟。

Led_flow模块代码

/****************************************************          

*   Engineer        :   梦翼师兄

*   QQ               :   761664056

*   The module function:流水灯顶层模块

*****************************************************/

01  module Led_flow(clk,rst_n,pio_led);

02  input clk;//系统50MHz时钟输入

03  input rst_n;//系统复位

04

05  output  [3:0]pio_led;//LED驱动输出

06

07  wire clk_slow;//慢时钟定义

08          

09  freq freq(

10      .clk(clk),    //系统时钟输入

11      .rst_n(rst_n),//系统复位

12      .clk_slow(clk_slow)//慢时钟输出

13    );

14

15  led_learn led_learn(

16      .clk(clk_slow),  //驱动时钟输入

17      .rst_n(rst_n),   //系统复位

18      .pio_led(pio_led)//LED驱动输出

19   );

20      

21  endmodule 

该模块为系统顶层模块,负责将分频模块和LED驱动模块进行组装级联。梦翼师兄强烈建议在顶层模块只做模块级联,绝对不要编写任何逻辑。

仿真代码

/****************************************************          

*   Engineer        :   梦翼师兄

*   QQ               :   761664056

*   The module function:流水灯测试模块

*****************************************************/

01  `timescale 1ns/1ps //时间单位和精度定义

02  module tb;

03

04  //系统输入

05  reg clk;   //系统时钟输入

06  reg rst_n; //系统复位

07  //系统输出

08  wire [3:0]pio_led;//LED驱动输出

09  

10  initial

11      begin

12          clk=0;

13          rst_n=0;

14          #1000.1 rst_n=1;

15      end 

16      

17      always #10 clk=~clk;//50MHz时钟

18      

19  Led_flow Led_flow(

20          .clk(clk),       //系统时钟输入

21          .rst_n(rst_n),   //系统复位

22          .pio_led(pio_led)//LED驱动输出

23        );

24  endmodule

查看仿真波形如下

 

如何查看波形呢?既然逻辑是分模块的,那么我们查看波形是否正确也应该是分模块来看的,首先我们查看 freq模块,freq模块的功能就是快时钟产生慢时钟,通过波形我们可以看到clk_slow慢时钟确实产生了,说明该模块功能正确。

接下来,我们的目标是将慢时钟作为LED驱动模块的时钟源,也就是说LED驱动模块的时钟端口“clk”频率应该和clk_slow一致,查看波形可知,条件符合,说明顶层级联关系正确。

最后查看流水灯切换,应该发生在每一个驱动时钟上升沿,由波形图可知,逻辑全部正确,设计结束。

对于层次化设计,我们可以查看RTL级视图(软件操作请查看梦翼师兄视频)

 

可以看到,电路生成的RTL级视图和我们所设计的架构图一致,说明系统顶层连接正确。因此通常情况下,如果是进行层次化设计,设计结束以后我们应该首先查看RTL级视图是否正确,只有确保顶层连接正确的情况下我们才进行电路仿真,查看代码时序逻辑是否正确。

 

转载于:https://www.cnblogs.com/mengyi1989/p/11502817.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值