1、verilog奇偶分频一段式两段式三段式状态机汇报总结1、偶数分频偶数倍分频相对简单,可以通过计数器对预分频的脉冲沿计数实现,如果要进行N倍(N为整数)偶数分频,可由预分频的时钟触发计数器计数,当计数器从0计数到N/21时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数,以此循环下去。分频的主体程序如下:define div_en 8 module freq_div_even(clk_in,reset,clk_out); input clk_in; input reset; output clk_out; reg clk_out; reg2:0 count; initia
2、l begin count=0; clk_out=0; end always(posedge clk_in) begin if(!reset) begin count=0; clk_out=0; end else if(count=(div_en/2-1) begin clk_out=clk_out; count=0; end else begin count=count+1; end endendmodule下面定义N为8,对一个脉冲8分频,测试程序如下:timescale 1ns/1nsmodule testbench; reg reset; reg clk_in; reg2:0 coun
3、t; wire clk_out;freq_div_even test(.clk_in(clk_in), .reset(reset), .clk_out(clk_out); initial begin reset=0; clk_in=0; #5 reset=1; end always #10 clk_in=clk_in; endmodule波形图如下:2、奇数分频对于对占空比没有特殊要求的奇数分频,需要对上升沿和下降沿脉冲进行计数,利用下降沿产生的波形移相半个输入脉冲的作用,最后用错位“异或”法实现。一个n(n=3)分频的程序如下:module clk_divN( clk_in,reset,cl
4、k_out); input clk_in; input reset; output clk_out; integer cnt1,cnt2; reg clk_divp; reg clk_divn; parameter n=3; always(posedge clk_in) begin if(!reset) begin clk_divp=0; cnt1=0; end else if(cnt1=(n-1) cnt1=0; else if(cnt1=0|cnt1=(n-1)/2) begin cnt1=cnt1+1; clk_divp=clk_divp; end else cnt1=cnt1+1; e
5、nd always(negedge clk_in) begin if(!reset) begin clk_divn=0; cnt2=0; end else if(cnt2=(n-1) cnt2=0; else if(cnt1=0|cnt1=(n-1)/2) begin cnt2=cnt2+1; clk_divn=clk_divn; end else cnt2=cnt2+1; end assign clk_out=clk_divp|clk_divn; endmodule测试程序如下:timescale 1ns/1nsmodule clk_div3_tb; reg clk_in; reg rese
6、t; wire clk_out; clk_divN uut (.clk_in(clk_in), .reset(reset), .clk_out(clk_out); initial begin clk_in = 0; reset = 0; #10 reset=1; end always #5 clk_in=clk_in; endmodule3分频、5分频和7分频仿真波形分别如下:3分频5分频7分频3、状态机 状态机分为两种、一种称为Mealy状态机,它的时序逻辑输出不但取决于状态还取决于输入;另外一种称为Moore状态机,它的输出只取决于当前的状态。实际的设计工作中大部分都是Mealy状态机。有
7、限状态机设计一般步骤:1、逻辑抽象,得出状态转换图;2、状态化简;3、状态分配;4、选定触发器的类型并求出状态方程、驱动方程和输出方程;5、按照方程得出逻辑图。FSM的描述方法有3中:1、在1个always 模块里面,该模块中既描述状态转移,又描述状态的输入和输出,这种写法一般被称为一段式FSM 描述方法;2、还有一种写法是将用2 个always 模块,其中一个always 模块采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律,这种写法被称为两段式FSM 描述方法;3、还有一种写法是在两段式描述方法基础上发展出来的,这种写法使用3 个always 模块,一个a
8、lways模块采用同步时序描述状态转移;第二个采用组合逻辑判断状态转移条件,描述状态转移规律;第三个always模块使用同步时序电路描述每个状态的输出,这种写法本书称为三段式。三种描述方式的优缺点比较如下表:表 6-1 3种FSM 描述方法比较表比较项目一段式描述方法两段式描述方法三段式描述方法推荐等级不推荐推荐最优推荐代码简洁程度(对于相对复杂的FSM )冗长最简洁简洁always 模块个数123是否利于时序约束不利于利于利于是否有组合逻辑输出可以无组合逻辑输出多数情况有组合逻辑输出无组合逻辑输出是否利于综合与布局布线不利于利于利于代码的可靠性与可维护度低高最好代码风格的规范性低,任意度较大
9、,格式化规范,格式化规范 我们主要学习三段式的FSM描述方法。例如:需要编写下图所示状态机:现状态输入次状态输出S0(00)0S0(00)00S0(00)1S1(01)00S1(01)0S0(00)01S1(01)1S2(10)01S2(10)0S0(00)10S2(10)1S3(11)10S3(11)0S0(00)11S3(11)1S3(11)11一段式的的程序,如下:/ state_1paragraph.vmodule state_1para( reset,clk,x,out); input reset,clk; input x; output out; reg 1:0 out; reg
10、2:0 Next_state; /NextState parameter 2:0 /one hot with zero idle S0 = 2b00, S1 = 2b01, S2 = 2b10, S3 = 2b11; always (posedge clk or negedge reset) if (!reset) begin Next_state = S0; out = 2b00; end else begin Next_state = 2bx; out = 2b00; case (Next_state) S0: begin if (x=0) begin out = 2b00; Next_s
11、tate = S0; end else begin out = 2b01; /输出要看下一状态 Next_state = S1; end end S1: begin if (x=0) begin out = 2b00; Next_state = S0; end else begin out = 2b10; Next_state = S2; end end S2: begin if (x=0) begin out = 2b00; Next_state = S0; end else begin out = 2b11; Next_state = S3; end end S3: begin if (x
12、=0) begin out = 2b00; Next_state = S0; end else begin out = 2b11; Next_state = S3; end end endcase end endmodule两段式的程序如下:module state_2para( reset,clk,x,out);input reset,clk;input x;output out;reg 1:0 out;reg 2:0 Next_state,Current_state;parameter 2:0 /one hot with zero idleS0 = 2b00,S1 = 2b01,S2 =
13、2b10,S3 = 2b11;/描述状态转移,非阻塞方式赋值always (posedge clk or negedge reset)if (!reset)Current_state = S0;elseCurrent_state = Next_state;/描述状态转移的条件,阻塞方式赋值always (Current_state or x)beginNext_state = 2bx;S3_out;case (Current_state)S0: beginS0_out;if (x=0) Next_state = S0;else Next_state = S1;endS1: beginS1_ou
14、t;if (x=0) Next_state = S0;else Next_state = S2;endS2: beginS2_out;if (x=0) Next_state = S0;else Next_state = S3;endS3: beginS3_out;if (x=0) Next_state = S0;else Next_state = S3;endendcaseend/定义输出任务 task S0_out; out = 2b00; endtask task S1_out; out = 2b01; endtask task S2_out; out = 2b10; endtask ta
15、sk S3_out; out = 2b11; endtaskendmodule三段式的程序如下:module state3 ( reset,clk,x,out);input reset,clk;input x,;output out;reg 1:0 out;reg 2:0 Next_state,Current_state;parameter 2:0S0 = 2b00,S1 = 2b01,S2 = 2b10,S3 = 2b11;always (posedge clk or negedge reset)if (!reset)Current_state = S0;elseCurrent_state
16、= Next_state;always (reset or Current_state or x) /与二段式区别beginNext_state = 2bx;case (Current_state) /注意S0: beginif (x=0) Next_state = S0;else Next_state = S1;endS1: beginif (x=0) Next_state = S0;else Next_state = S2;endS2: beginif (x=0) Next_state = S0;else Next_state = S3;endS3: beginif (x=0) Next_
17、state = S0;else Next_state = S3;endendcaseendalways (posedge clk or negedge reset)if (!reset)out = 0;elsebeginout = 0;case (Next_state)/需要注意,不是Current_stateS0: out = 2b00;S1: out = 2b01;S2: out = 2b10;S3: out = 2b11;endcaseendendmodule三种方法的测试程序如下:/ state_1paragraph_tb.vtimescale 1ns/1nsmodule state_
18、1parag_tb;reg reset;reg clk;reg x;wire1:0 out;state_1para tb( .reset(reset), .clk(clk), .x(x), .out(out) );initial begin clk=0; reset=0; x=0; #10 reset=1; #1000 reset=0; # 100 reset=1; endalways #20 clk=clk;always(posedge clk) begin #10 x=$random%2;/输入x随机在0和1之间变化 endendmodule一段式的仿真波形图二段式的仿真波形图三段式的仿真波形图
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1