阻塞:在本语句中“右式计算”和“左式更新”完全完成之后,才开始执行下一条语句
非阻塞:当前语句的执行不会阻塞下一语句的执【非阻塞相对于阻塞赋值多出一个触发器,时序逻辑中要用非阻塞赋值<=】
阻塞赋值:在复位信号无效后第一个时钟周期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
具有优先级的if else 语句过多会造成时钟频率的下降
参考:小数分频
参考:任意小数分频
在一般情况下,应用到时钟分频尽量用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
经常用到的就是偶数分频
`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.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进行小数分频的设计
状态机可分为mealy型和moore型:
按照写法状态机可分为一段式,二段式,三段式:
二段式状态机可以避免三段式状态机中由于组合逻辑而产生的的竞争冒险现象,同时减少代码复杂度。
而时钟采到毛刺的概率较低,可以有效消除毛刺影响
5、RAM
RAM分为单口RAM和双口RAM,双口RAM又分为真双口和伪双口。
原文:https://www.cnblogs.com/tianyuzh/p/14412412.html