verilog奇偶分频一段式两段式三段式状态机.docx

上传人:b****3 文档编号:4915252 上传时间:2022-12-11 格式:DOCX 页数:16 大小:90.60KB
下载 相关 举报
verilog奇偶分频一段式两段式三段式状态机.docx_第1页
第1页 / 共16页
verilog奇偶分频一段式两段式三段式状态机.docx_第2页
第2页 / 共16页
verilog奇偶分频一段式两段式三段式状态机.docx_第3页
第3页 / 共16页
verilog奇偶分频一段式两段式三段式状态机.docx_第4页
第4页 / 共16页
verilog奇偶分频一段式两段式三段式状态机.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

verilog奇偶分频一段式两段式三段式状态机.docx

《verilog奇偶分频一段式两段式三段式状态机.docx》由会员分享,可在线阅读,更多相关《verilog奇偶分频一段式两段式三段式状态机.docx(16页珍藏版)》请在冰豆网上搜索。

verilog奇偶分频一段式两段式三段式状态机.docx

verilog奇偶分频一段式两段式三段式状态机

汇报总结

1、偶数分频

偶数倍分频相对简单,可以通过计数器对预分频的脉冲沿计数实现,如果要进行N倍(N为整数)偶数分频,可由预分频的时钟触发计数器计数,当计数器从0计数到N/2—1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数,以此循环下去。

分频的主体程序如下:

`definediv_en8

modulefreq_div_even(clk_in,

reset,

clk_out

);

inputclk_in;

inputreset;

outputclk_out;

regclk_out;

reg[2:

0]count;

initial

begin

count=0;

clk_out=0;

end

always@(posedgeclk_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

end

endmodule

下面定义N为8,对一个脉冲8分频,测试程序如下:

`timescale1ns/1ns

moduletestbench;

regreset;

regclk_in;

reg[2:

0]count;

wireclk_out;

freq_div_eventest(.clk_in(clk_in),

.reset(reset),

.clk_out(clk_out)

);

initial

begin

reset=0;

clk_in=0;

#5reset=1;

end

always#10clk_in=~clk_in;

endmodule

波形图如下:

2、奇数分频

对于对占空比没有特殊要求的奇数分频,需要对上升沿和下降沿脉冲进行计数,利用下降沿产生的波形移相半个输入脉冲的作用,最后用错位“异或”法实现。

一个n(n=3)分频的程序如下:

moduleclk_divN(

clk_in,

reset,

clk_out

);

inputclk_in;

inputreset;

outputclk_out;

integercnt1,cnt2;

regclk_divp;

regclk_divn;

parametern=3;

always@(posedgeclk_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;

end

always@(negedgeclk_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

assignclk_out=clk_divp|clk_divn;

endmodule

测试程序如下:

`timescale1ns/1ns

moduleclk_div3_tb;

regclk_in;

regreset;

wireclk_out;

clk_divNuut(.clk_in(clk_in),

.reset(reset),

.clk_out(clk_out)

);

initial

begin

clk_in=0;

reset=0;

#10reset=1;

end

always#5clk_in=~clk_in;

endmodule

3分频、5分频和7分频仿真波形分别如下:

3分频

5分频

7分频

 

3、状态机

状态机分为两种、一种称为Mealy状态机,它的时序逻辑输出不但取决于状态还取决于输入;另外一种称为Moore状态机,它的输出只取决于当前的状态。

实际的设计工作中大部分都是Mealy状态机。

有限状态机设计一般步骤:

1、逻辑抽象,得出状态转换图;2、状态化简;3、状态分配;4、选定触发器的类型并求出状态方程、驱动方程和输出方程;5、按照方程得出逻辑图。

FSM的描述方法有3中:

1、在1个always模块里面,该模块中既描述状态转移,又描述状态的输入和输出,这种写法一般被称为一段式FSM描述方法;

2、还有一种写法是将用2个always模块,其中一个always模块采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律,这种写法被称为两段式FSM描述方法;

3、还有一种写法是在两段式描述方法基础上发展出来的,这种写法使用3个always模块,一个always模块采用同步时序描述状态转移;第二个采用组合逻辑判断状态转移条件,描述状态转移规律;第三个always模块使用同步时序电路描述每个状态的输出,这种写法本书称为三段式。

三种描述方式的优缺点比较如下表:

表6-13种FSM描述方法比较表

比较项目

一段式描述方法

两段式描述方法

三段式描述方法

推荐等级

不推荐

推荐

最优推荐

代码简洁程度(对于相对复杂的FSM)

冗长

最简洁

简洁

always模块个数

1

2

3

是否利于时序约束

不利于

利于

利于

是否有组合逻辑输出

可以无组合逻辑输出

多数情况有组合逻辑输出

无组合逻辑输出

是否利于综合与布局布线

不利于

利于

利于

代码的可靠性与可维护度

最好

代码风格的规范性

低,任意度较大,格式化

规范,格式化

规范

我们主要学习三段式的FSM描述方法。

例如:

需要编写下图所示状态机:

现状态

输入

次状态

输出

S0(00)

0

S0(00)

00

S0(00)

1

S1(01)

00

S1(01)

0

S0(00)

01

S1(01)

1

S2(10)

01

S2(10)

0

S0(00)

10

S2(10)

1

S3(11)

10

S3(11)

0

S0(00)

11

S3(11)

1

S3(11)

11

 

一段式的的程序,如下:

//state_1paragraph.v

modulestate_1para(reset,clk,x,out);

inputreset,clk;

inputx;

outputout;

reg[1:

0]out;

reg[2:

0]Next_state;//NextState

parameter[2:

0]//onehotwithzeroidle

S0=2'b00,

S1=2'b01,

S2=2'b10,

S3=2'b11;

always@(posedgeclkornegedgereset)

if(!

reset)

begin

Next_state<=S0;

out<=2'b00;

end

else

begin

Next_state<=2'bx;

out<=2'b00;

case(Next_state)

S0:

begin

if(x==0)

begin

out<=2'b00;

Next_state<=S0;

end

else

begin

out<=2'b01;//输出要看下一状态

Next_state<=S1;

end

end

S1:

begin

if(x==0)

begin

out<=2'b00;

Next_state<=S0;

end

else

begin

out<=2'b10;

Next_state<=S2;

end

end

S2:

begin

if(x==0)

begin

out<=2'b00;

Next_state<=S0;

end

else

begin

out<=2'b11;

Next_state<=S3;

end

end

S3:

begin

if(x==0)

begin

out<=2'b00;

Next_state<=S0;

end

else

begin

out<=2'b11;

Next_state<=S3;

end

end

endcase

end

endmodule

两段式的程序如下:

modulestate_2para(reset,clk,x,out);

inputreset,clk;

inputx;

outputout;

reg[1:

0]out;

reg[2:

0]Next_state,Current_state;

parameter[2:

0]//onehotwithzeroidle

S0=2’b00,

S1=2’b01,

S2=2’b10,

S3=2’b11;

//描述状态转移,非阻塞方式赋值

always@(posedgeclkornegedgereset)

if(!

reset)

Current_state<=S0;

else

Current_state<=Next_state;

//描述状态转移的条件,阻塞方式赋值

always@(Current_stateorx)

begin

Next_state=2’bx;

S3_out;

case(Current_state)

S0:

begin

S0_out;

if(x==0)Next_state=S0;

elseNext_state=S1;

end

S1:

begin

S1_out;

if(x==0)Next_state=S0;

elseNext_state=S2;

end

S2:

begin

S2_out;

if(x==0)Next_state=S0;

elseNext_state=S3;

end

S3:

begin

S3_out;

if(x==0)Next_state=S0;

elseNext_state=S3;

end

endcase

end

//定义输出任务

taskS0_out;

out=2'b00;

endtask

taskS1_out;

out=2'b01;

endtask

taskS2_out;

out=2'b10;

endtask

taskS3_out;

out=2'b11;

endtask

endmodule

三段式的程序如下:

modulestate3(reset,clk,x,out);

inputreset,clk;

inputx,;

outputout;

reg[1:

0]out;

reg[2:

0]Next_state,Current_state;

parameter[2:

0]

S0=2’b00,

S1=2’b01,

S2=2'b10,

S3=2’b11;

always@(posedgeclkornegedgereset)

if(!

reset)

Current_state<=S0;

else

Current_state<=Next_state;

always@(resetorCurrent_stateorx)//与二段式区别

begin

Next_state=2’bx;

case(Current_state)//注意

S0:

begin

if(x==0)Next_state=S0;

elseNext_state=S1;

end

S1:

begin

if(x==0)Next_state=S0;

elseNext_state=S2;

end

S2:

begin

if(x==0)Next_state=S0;

elseNext_state=S3;

end

S3:

begin

if(x==0)Next_state=S0;

elseNext_state=S3;

end

endcase

end

always@(posedgeclkornegedgereset)

if(!

reset)

out<=0;

else

begin

out<=0;

case(Next_state)//需要注意,不是Current_state

S0:

out<=2’b00;

S1:

out<=2’b01;

S2:

out<=2’b10;

S3:

out<=2’b11;

endcase

end

endmodule

三种方法的测试程序如下:

//state_1paragraph_tb.v

`timescale1ns/1ns

modulestate_1parag_tb;

regreset;

regclk;

regx;

wire[1:

0]out;

state_1paratb(.reset(reset),

.clk(clk),

.x(x),

.out(out)

);

initial

begin

clk=0;

reset=0;

x=0;

#10reset=1;

#1000reset=0;

#100reset=1;

end

always#20clk=~clk;

always@(posedgeclk)

begin

#10x={$random}%2;//输入x随机在0和1之间变化

end

endmodule

一段式的仿真波形图

二段式的仿真波形图

三段式的仿真波形图

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1