verilog基础tips
1、阻塞赋值和非阻塞赋值
阻塞:在本语句中“右式计算”和“左式更新”完全完成之后,才开始执行下一条语句
非阻塞:当前语句的执行不会阻塞下一语句的执【非阻塞相对于阻塞赋值多出一个触发器,时序逻辑中要用非阻塞赋值<=】
阻塞赋值:在复位信号无效后第一个时钟周期a=0,b=0,c=0
always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0)begin a=0; b=1; c=2; end else begin b=a; c=b; end end
非阻塞赋值:在复位信号无效后第一个时钟周期a=0;b=1;c=2;
always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0)begin a<=0; b<=1; c<=2; end else begin b<=a; c<=b; end end
2、if else 语句
具有优先级的if else 语句过多会造成时钟频率的下降
3、时钟分频
参考:小数分频
参考:任意小数分频
在一般情况下,应用到时钟分频尽量用IP核,因为这样的时钟偏斜比较小。(时钟偏斜:同一时钟到达不同寄存器的延时不同)
尽量不用自己分频出来的信号直接作为时钟,可以加入标志信号,在利用源时钟的情况下加入标志信号实现原本的功能
module cnt( input clk, input rst_n, output [ 3 : 0] cnt ); always@(posedge clk or negedge rst_n)begin //进行四分频 if(rst_n == 1'b0) div_cnt <= 'h0; else div_cnt <= div_cnt + 1'b1; end always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) clk_4 <= 'h0; else if(div_cnt == 2'd1) clk_4 <= 'h1; else if(div_cnt == 2'd3) clk_4 <= 'h0; end /*------\/-------- by $Tyz 2021-02-20 --------\/--------{{{ * 需要避免的写法,不用自己分频的信号直接作为时钟使用 always@(posedge clk_4 or negedge rst_n)begin if(rst_n == 1'b0) cnt <= 'h0; else cnt <= cnt + 1'b1; end --------/\-------- by $Tyz 2021-02-20 --------/\------}}}*/ always@(posedge clk or negedge rst_n)begin //建议使用的方式,利用flag信号 if(rst_n == 1'b0) clk_flag <= 'h0; else if(div_cnt == 2'd1) clk_flag <= 'h1; else clk_flag <= 'h0; end always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) cnt <= 'h0; else if(clk_flag) cnt <= cnt + 1'b1; end endmodule
3.1 偶数分频
经常用到的就是偶数分频
`timescale 1ns / 1ns /********** 任意偶数分频器************/ module divider_even #(parameter DIV = 4)( input sys_clk, input sys_rst_n, input [7:0] M_N, // 取代DIV了 output reg div_clk // 任意偶数数分频输出时钟 ); reg [7:0] cnt; always@(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) cnt <= 0; else if(cnt == M_N-1) cnt <= 0; else cnt <= cnt + 1; end always@(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) div_clk <= 1'b0; else if((cnt == 0) || (cnt == (M_N/2))) div_clk <= ~div_clk; else div_clk <= div_clk; end endmodule
3.2 奇数分频:
3.2.1 奇数分频可以直接采用计数器进行得到,如5分频就可以进行模5计数,在等于5的时候拉高,否则拉低信号,则可得到占空比为1/5的分频信号
3.2.2 奇数分频要要求占空比为50%。
首先进行模5计数
而后利用clk的上升沿连续拉低pos_clk三个时钟,而后连续拉高两个时钟周期。
之后再利用clk的下降沿连续拉低neg_clk三个时钟,而后拉高两个时钟周期。
最后对pos_clk 和neg_clk 进行或运算得到输出的分频时钟
tips:上面的拉高拉低可以互换,最后的结果都是相同的(但此时最后的输出为pos_clk和neg_clk与运算)
//奇数分频 N分频 // . . . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ + // clk | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | // + +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ // - ------- ------- ------- ------- ------- --------------------------------------------------------------------------------------- // bus X 0 X 1 X 2 X 3 X 4 X // - ------- ------- ------- ------- ------- --------------------------------------------------------------------------------------- // +---------------+ // pos_clk | | // ------------------------+ +--------------------------------------------------------------------------------------- // --+ +---------------+ // neg_clk | | | // +-------------------------+ +--------------------------------------------------------------------------------------- // --+ +-------------------+ // clk_out | | | // +---------------------+ +------------------------------------------------------------------------------------------- module even_divider( clk, rst_n, clk_out ); input clk; input rst_n; output clk_out; reg pos_clk; reg neg_clk; reg [ 7 : 0] div_cnt; parameter DIV_NUM = 5; //其中N为奇数 always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) div_cnt <= 'h0; else if(div_cnt == DIV_NUM-1) div_cnt <= 'h0; else div_cnt <= div_cnt + 1'b1; end //pos_clk always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) pos_clk <= 'h0; else if((div_cnt >= (DIV_NUM-1)/2) && (div_cnt <= DIV_NUM-1)) pos_clk <= 'h0; else pos_clk <= 'h1; end //neg_clk always@(negedge clk or negedge rst_n)begin if(rst_n == 1'b0) neg_clk <= 'h0; else if((div_cnt >= (DIV_NUM-1)/2) && (div_cnt <= DIV_NUM-1)) neg_clk <= 'h0; else neg_clk <= 'h1; end assign clk_out = pos_clk | neg_clk; endmodule
3.2.3 小数分频
tips:一般情况下,自己设计的小数分频对时序要求很高的电路并不使用,可以使用软件自带的IP进行小数分频的设计
4、状态机
状态机可分为mealy型和moore型:
按照写法状态机可分为一段式,二段式,三段式:
二段式状态机可以避免三段式状态机中由于组合逻辑而产生的的竞争冒险现象,同时减少代码复杂度。
而时钟采到毛刺的概率较低,可以有效消除毛刺影响
发
原文地址:https://www.cnblogs.com/tianyuzh/p/14412412.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- C++中静态成员函数访问非静态成员的实例
- Spring Boot+Mybatis的整合过程
- java使用webuploader实现跨域上传详解
- C++ 随机数与随机种子数的实例
- Nodejs之http的表单提交
- Java编程实现汉字按字母顺序排序的方法示例
- Nodejs之TCP服务端与客户端聊天程序详解
- js实现从左向右滑动式轮播图效果
- thinkPHP微信分享接口JSSDK用法实例
- FTP服务器详解之监控ftp服务器、上传文件到ftp服务器、ftp文件监控的方法
- JSP页面间的传值方法总结
- C语言中字符串实现正序与逆序实例详解
- Laravel使用PHPQRCODE实现生成带有LOGO的二维码图片功能示例
- Spring Boot 编写Servlet、Filter、Listener、Interceptor的方法
- Linux下Oracle如何导入导出dmp文件详解