基于Altera Quartus II的模块化设计应用

个人档案

基于Altera Quartus II的模块化设计应用


 


       和ISE不一样,Quartus II代码的模块化视图并不是你把子模块例化到顶层模块以后就能马上在工程代码窗口看到一个清晰的层次图。而是必须在你编译后才能够看到层次化的视图。


 


       我在这里列举一个串口通信(实验10)的实例:


       编写完该HDL的代码,还没有编译,此时在Project Navigator窗口中只有顶层模块my_uart_top。




       顶层模块如下(详细的注释代码请参考相关实验):



module my_uart_top(


                            clk,rst_n,


                            rs232_rx,rs232_tx


                            );


input clk;


input rst_n;


input rs232_rx;


output rs232_tx; 


wire bps_start1,bps_start2;


wire clk_bps1,clk_bps2;


wire[7:0] rx_data;


wire rx_int;  



speed_select        speed_rx(    


                                                 .clk(clk),                                                                                                                       .rst_n(rst_n),


                                                 .bps_start(bps_start1),


                                                 .clk_bps(clk_bps1)


                                          );


 


my_uart_rx                 my_uart_rx(       


                                                 .clk(clk),                                                                                                                       .rst_n(rst_n),


                                                 .rs232_rx(rs232_rx),


                                                 .rx_data(rx_data),


                                                 .rx_int(rx_int),


                                                 .clk_bps(clk_bps1),


                                                 .bps_start(bps_start1)


                                          );


 


///                                        


speed_select        speed_tx(    


                                                 .clk(clk),


                                                 .rst_n(rst_n),


                                                 .bps_start(bps_start2),


                                                 .clk_bps(clk_bps2)


                                          );


 


my_uart_tx                 my_uart_tx(       


                                                 .clk(clk),


                                                 .rst_n(rst_n),


                                                 .rx_data(rx_data),


                                                 .rx_int(rx_int),


                                                 .rs232_tx(rs232_tx),


                                                 .clk_bps(clk_bps2),


                                                 .bps_start(bps_start2)


                                          );


Endmodule


 


       我们一般不在顶层模块做任何逻辑设计,哪怕只是一个逻辑与操作。比较好的设计会明确的区分每一个模块单元。在上面这个设计中,是要实现一个串口自收发通信的功能。具体说就是不断的检测串口接收信号rs232_rx是否有数据,如果接收到起始位就把数据保存,然后再转手把接收到的数据通过串口发送信号rs232_tx发回给对方。即使是这样一个还不算太复杂的功能,如果都堆到一个模块里,代码不仅又臭又长,编写代码者如果不理好思路很容易自己就写晕了,以后维护起来或者要移植就更难了。


所以,模块化的设计势在必行。上面的代码把这个设计分成了四个模块:


1、My_uart_tx:串口数据接收模块;


2、Speed_tx:串口数据接收时钟校准模块;


3、My_uart_rx:串口数据发送模块;


4、Speed_rx:串口数据发送时钟校准模块。


       如此划分,层次清晰而且思路明确,写起代码来更是游刃有余。先来说模块例化的一些细节吧。就拿speed_select模块例化来看。第一行的speed_select            speed_rx,其中speed_select是要例化的模块名,是固定的;而speed_rx则是你任意给这个模块取的名字,它是用于区分例化多个相同的模块。就如speed_tx和speed_rx两个模块,因为它们的逻辑设计都是一样的,所以写一个模块,然后在例化的时候给个不同的名称就可以了。这有点类似软件设计中的子程序调用,但又有不同,由于硬件设计的并行性,这里的逻辑复制实际上在最后的硬件上是实现了两个一模一样的speed_select设计原型,可以说它们是完全独立的。即便是对于硬件资源的消耗没有减少,采用模块化设计以后也能从很大程度上减少设计者的重复劳动。


       信号的例化是这样的.clk(clk),点号后的clk代表例化模块内部的信号(是固定的,必须和内部的信号名一致),而括号内的clk则是例化模块的外部连接,可以例化模块内的信号名不同。


       在编译后,可以从Project Navigator窗口中看到例化的子模块:




 


另外,从Quartus II提供的RTL视图里,我们能够更深刻的感受到模块化带来的层次感:



点击看大图
转自:http://bbs.ednchina.com/BLOG_ARTICLE_184341.HTM

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FPGA控制RS232串口通信实现verilog设计Quartus9.1工程源码 module ex5_rs232( clk_in,ext_rst_n, rs232_rx,rs232_tx ); input clk_in; // 25MHz主时钟 input ext_rst_n; //外部输入复位信号,低有效 input rs232_rx; // RS232接收数据信号 output rs232_tx; // RS232发送数据信号 //---------------------------------------------------- wire rst_n; //低电平复位信号 wire bps_start1,bps_start2; //接收到数据后,波特率时钟启动信号置位 wire clk_bps1,clk_bps2; // clk_bps_r高电平为接收数据位的中间采样点,同时也作为发送数据的数据改变点 wire[7:0] rx_data; //接收数据寄存器,保存直至下一个数据来到 wire rx_int; //接收数据中断信号,接收到数据期间始终为高电平 reg clk; always@(posedge clk_in) clk = ~clk; //--------------------------------------------------- //复位产生模块 sys_ctrl uut_sc( .clk(clk), .ext_rst_n(ext_rst_n), .rst_n(rst_n) ); //--------------------------------------------------- //下面的四个模块中,speed_rx和speed_tx是两个完全独立的硬件模块,可称之为逻辑复制 //(不是资源共享,和软件中的同一个子程序调用不能混为一谈) //////////////////////////////////////////// speed_select speed_rx( .clk(clk), //波特率选择模块 .rst_n(rst_n), .bps_start(bps_start1), .clk_bps(clk_bps1) ); uart_rx my_uart_rx( .clk(clk), //接收数据模块 .rst_n(rst_n), .rs232_rx(rs232_rx), .rx_data(rx_data), .rx_int(rx_int), .clk_bps(clk_bps1), .bps_start(bps_start1) ); /////////////////////////////////////////// speed_select speed_tx( .clk(clk), //波特率选择模块 .rst_n(rst_n), .bps_start(bps_start2), .clk_bps(clk_bps2) ); uart_tx my_uart_tx( .clk(clk), //发送数据模块 .rst_n(rst_n), .rx_data(rx_data), .rx_int(rx_int), .rs232_tx(rs232_tx), .clk_bps(clk_bps2), .bps_start(bps_start2) ); endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值