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

更新时间:2024-01-23 14:14:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

汇报总结

1、偶数分频

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

`define div_en 8

module freq_div_even(clk_in,

reset, clk_out );

input clk_in; input reset; output clk_out;

reg clk_out; reg[2:0] count;

initial 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 end

endmodule

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

`timescale 1ns/1ns

module testbench;

reg reset; reg clk_in; reg[2:0] count;

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, clk_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; end 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/1ns

module clk_div3_tb; reg clk_in; reg reset; 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; 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模块使用同步时序电路描述每个状态的输出,这种写法本书称为三段式。

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

比较项目 推荐等级 代码简洁程度(对于相对复杂的FSM ) always 模块个数 1 2 利于 多数情况有组合逻辑输出 是否利于综合与布局布线 代码的可靠性与可维护度 代码风格的规范性

表 6-1 3种FSM 描述方法比较表 一段式描述方法 两段式描述方法 不推荐 冗长 推荐 最简洁 三段式描述方法 最优推荐 简洁 3 利于 无组合逻辑输出 利于 最好 规范 是否利于时序约束 不利于 是否有组合逻辑输出 可以无组合逻辑输出 不利于 低 低,任意度较大,格式化 利于 高 规范,格式化 我们主要学习三段式的FSM描述方法。

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

10S0/000S1/011010S3/111S2/10 现状态 S0(00) 输入 0 次状态 S0(00) 输出 00

S0(00) 1 S1(01) 0 S1(01) 1 S2(10) 0 S2(10) 1 S3(11) 0 S3(11) 1

一段式的的程序,如下:

// state_1paragraph.v

module state_1para( reset,clk,x,out); input reset,clk; input x; output out;

reg [1:0] out;

reg [2:0] Next_state; //NextState

parameter [2:0] //one hot with zero idle S0 = 2'b00, S1 = 2'b01, S2 = 2'b10, S3 = 2'b11;

always @ (posedge clk or negedge reset) 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)

S1(01) 00 S0(00) 01 S2(10) 01 S0(00) 10 S3(11) 10 S0(00) 11 S3(11) 11 //输出要看下一状态 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

两段式的程序如下:

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 idle S0 = 2’b00, S1 = 2’b01, S2 = 2’b10, S3 = 2’b11;

//描述状态转移,非阻塞方式赋值 always @ (posedge clk or negedge reset) if (!reset)

Current_state <= S0; else

Current_state <= Next_state;

//描述状态转移的条件,阻塞方式赋值 always @ (Current_state or x) begin

Next_state = 2’bx; S3_out;

case (Current_state) S0:

begin

S0_out;

if (x==0) Next_state = S0; else Next_state = S1; end S1:

begin

S1_out;

if (x==0) Next_state = S0; else Next_state = S2; end S2: begin

S2_out;

if (x==0) Next_state = S0; else Next_state = S3;

end S3:

begin

S3_out;

if (x==0) Next_state = S0; else Next_state = S3;

end endcase end

//定义输出任务 task S0_out; out = 2'b00; endtask

task S1_out; out = 2'b01; endtask

task S2_out; out = 2'b10; endtask

task S3_out; out = 2'b11; endtask endmodule

三段式的程序如下:

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:0] S0 = 2’b00, S1 = 2’b01, S2 = 2'b10, S3 = 2’b11;

always @ (posedge clk or negedge reset)

if (!reset)

Current_state <= S0; else

Current_state <= Next_state;

always @ (reset or Current_state or x) //与二段式区别

begin

Next_state = 2’bx;

case (Current_state) //注意 S0:

begin

if (x==0) Next_state = S0; else Next_state = S1; end S1: begin

if (x==0) Next_state = S0; else Next_state = S2; end S2: begin

if (x==0) Next_state = S0; else Next_state = S3; end S3: begin

if (x==0) Next_state = S0; else Next_state = S3; end

endcase end

always @ (posedge clk or negedge reset) 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 `timescale 1ns/1ns

module state_1parag_tb;

reg reset; reg clk; reg x;

wire[1: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; end

always #20 clk=~clk;

always@(posedge clk) begin

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

endmodule

一段式的仿真波形图

二段式的仿真波形图

三段式的仿真波形图

本文来源:https://www.bwwdw.com/article/zv6o.html

Top