零基础学FPGA(七)浅谈状态机
时间:02-25
来源:互联网
点击:
今天我们来写状态机。
关于状态机呢,想必大家应该都接触过,通俗的讲就是数电里我们学的状态转换图。状态机分为两中类型,一种叫Mealy型,一种叫Moore型。前者就是说时序逻辑的输出不仅取决于当前的状态,还取决于输入,而后者就是时序逻辑的输出仅仅取决于当前的状态。下面两个图分别表示两种不同的状态机。
下面我们就通过代码来写一下状态机,以下面的状态转换图为例
首先,是一种典型的状态机写法,这种写法我们称为一段时状态机,用于一些简单的设计是可以的,但如果是复杂的状态机,不建议大家用这种写法。
//***********************************************************
//可综合的状态机设计的典型方法
//实现典型的状态机设计
//**********************************************
module fsm (clk,rst_n,A,k1,k2,State);
input clk;
input rst_n;
input A;
output k1,k2;
output [1:0] State;
reg k1;
reg k2;
reg [1:0] State; //当前状态寄存器
parameter Idle = 2'b00,
Start = 2'b01,
Stop = 2'b10,
Clear = 2'b11; //编码 ,注意,只有在最后一句用分号,其他地方用逗号
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
State 状态机
//***********************************************************
//由输出指定的码表示状态的状态机
//小墨同学于2014年5月21日在金翰林宿舍作
//用于高速状态机的设计
//**********************************************
module fsm2(clk,rst_n,A,k1,k2,State);
input clk;
input rst_n;
input A;
output k1,k2;
output [4:0] State;
reg [4:0] State; //当前状态寄存器
assign k1 =State[0];
assign k2 =State[4];
parameter Idle = 5'b00000, //采用毒热编码(每个状态只有一个寄存器置位的状态机这样用的组合电路省一些,而且速度也快)
Start = 5'b00010,
Stop = 5'b00100,
StoptoClear = 5'b11000,
Clear = 5'b01010,
CleartoIdle = 5'b00111; //编码 ,注意,只有在最后一句用分号,其他地方用逗号
always @(posedge clk or negedge rst_n)
if(!rst_n)
State <= Idle;
else case (State) //状态判断与组合逻辑赋值
Idle :if(A)
State <= Start;
else
State <= Idle;
Start :if(!A) State <= Stop;
else State <= Start;
Stop :if(A)
State <=StoptoClear;
else State <= Stop;
StoptoClear :State <= Stop;
Clear :if(!A)
State <= Clear;
else State <= Clear;
CleartoIdle :State <= Idle;
default : State <= Idle;//告诉综合器 case语句已经指定了所有状态,这样综合器就会删除不需要的译码电路,使生成的电路简单
endcase
endmodule
//**************************************************
这样写就是把状态码的指定与状态机控制的输出联系起来,把状态的变化直接作用于输出,这样做可以提高输出信号的开关素的并节省电路器件。但这种方法也有缺点,就是快关的维持时间必须与状态维持的时间一致,这种设计方法常用在告诉状态机中。
下面这种写法应该是以后我们经常要用到的,即三段式状态机写法,比较适合于多输出的状态机设计。
//***********************************************************
//***************************************************
//多输出状态时的状态机
//用于多输出时的状态机设计,也即三段式状态机的常见写法,推荐!
//*********************************************
module fsm3 (clk,rst_n,A,k1,k2,state);
input clk,rst_n,A;
output k1,k2;
output [1:0] state;
reg k1,k2;
reg [1:0] state;
reg [1:0] xiaomo;
parameter Idle = 2'b00,
start = 2'b01,
stop = 2'b10,
clear = 2'b11;
always @ (posedge clk or negedge rst_n)
if(!rst_n) state <= Idle;
else state <= xiaomo; //每一个时钟产生一个可能的变化,即时序逻辑部分
always @ (state or A) //组合逻辑部分
begin
case (state)
Idle : if(A) xiaomo = start;
else iaomo = Idle;
start : if(!A)xiaomo = stop;
else iaomo = start;
stop : if(A)xiaomo = clear;
else iaomo = stop;
clear : if(!A) xiaomo =Idle;
else iaomo = clear;
default : xiaomo = 2'bxx;
endcase
end
always @ (state or A or rst_n) //产生输出k1的组合逻辑
if(!rst_n) k1=0;
else if(state ==clear && !A)
k1=1;
else k1=0;
always @(state or A or rst_n) //产生输出k2的组合逻辑
if(!rst_n) k2=0;
else if(state ==stop && A)
k2=1;
else k2=0;
endmodule
//**************************************************
关于状态机呢,想必大家应该都接触过,通俗的讲就是数电里我们学的状态转换图。状态机分为两中类型,一种叫Mealy型,一种叫Moore型。前者就是说时序逻辑的输出不仅取决于当前的状态,还取决于输入,而后者就是时序逻辑的输出仅仅取决于当前的状态。下面两个图分别表示两种不同的状态机。
下面我们就通过代码来写一下状态机,以下面的状态转换图为例
首先,是一种典型的状态机写法,这种写法我们称为一段时状态机,用于一些简单的设计是可以的,但如果是复杂的状态机,不建议大家用这种写法。
//***********************************************************
//可综合的状态机设计的典型方法
//实现典型的状态机设计
//**********************************************
module fsm (clk,rst_n,A,k1,k2,State);
input clk;
input rst_n;
input A;
output k1,k2;
output [1:0] State;
reg k1;
reg k2;
reg [1:0] State; //当前状态寄存器
parameter Idle = 2'b00,
Start = 2'b01,
Stop = 2'b10,
Clear = 2'b11; //编码 ,注意,只有在最后一句用分号,其他地方用逗号
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
State 状态机
//***********************************************************
//由输出指定的码表示状态的状态机
//小墨同学于2014年5月21日在金翰林宿舍作
//用于高速状态机的设计
//**********************************************
module fsm2(clk,rst_n,A,k1,k2,State);
input clk;
input rst_n;
input A;
output k1,k2;
output [4:0] State;
reg [4:0] State; //当前状态寄存器
assign k1 =State[0];
assign k2 =State[4];
parameter Idle = 5'b00000, //采用毒热编码(每个状态只有一个寄存器置位的状态机这样用的组合电路省一些,而且速度也快)
Start = 5'b00010,
Stop = 5'b00100,
StoptoClear = 5'b11000,
Clear = 5'b01010,
CleartoIdle = 5'b00111; //编码 ,注意,只有在最后一句用分号,其他地方用逗号
always @(posedge clk or negedge rst_n)
if(!rst_n)
State <= Idle;
else case (State) //状态判断与组合逻辑赋值
Idle :if(A)
State <= Start;
else
State <= Idle;
Start :if(!A) State <= Stop;
else State <= Start;
Stop :if(A)
State <=StoptoClear;
else State <= Stop;
StoptoClear :State <= Stop;
Clear :if(!A)
State <= Clear;
else State <= Clear;
CleartoIdle :State <= Idle;
default : State <= Idle;//告诉综合器 case语句已经指定了所有状态,这样综合器就会删除不需要的译码电路,使生成的电路简单
endcase
endmodule
//**************************************************
这样写就是把状态码的指定与状态机控制的输出联系起来,把状态的变化直接作用于输出,这样做可以提高输出信号的开关素的并节省电路器件。但这种方法也有缺点,就是快关的维持时间必须与状态维持的时间一致,这种设计方法常用在告诉状态机中。
下面这种写法应该是以后我们经常要用到的,即三段式状态机写法,比较适合于多输出的状态机设计。
//***********************************************************
//***************************************************
//多输出状态时的状态机
//用于多输出时的状态机设计,也即三段式状态机的常见写法,推荐!
//*********************************************
module fsm3 (clk,rst_n,A,k1,k2,state);
input clk,rst_n,A;
output k1,k2;
output [1:0] state;
reg k1,k2;
reg [1:0] state;
reg [1:0] xiaomo;
parameter Idle = 2'b00,
start = 2'b01,
stop = 2'b10,
clear = 2'b11;
always @ (posedge clk or negedge rst_n)
if(!rst_n) state <= Idle;
else state <= xiaomo; //每一个时钟产生一个可能的变化,即时序逻辑部分
always @ (state or A) //组合逻辑部分
begin
case (state)
Idle : if(A) xiaomo = start;
else iaomo = Idle;
start : if(!A)xiaomo = stop;
else iaomo = start;
stop : if(A)xiaomo = clear;
else iaomo = stop;
clear : if(!A) xiaomo =Idle;
else iaomo = clear;
default : xiaomo = 2'bxx;
endcase
end
always @ (state or A or rst_n) //产生输出k1的组合逻辑
if(!rst_n) k1=0;
else if(state ==clear && !A)
k1=1;
else k1=0;
always @(state or A or rst_n) //产生输出k2的组合逻辑
if(!rst_n) k2=0;
else if(state ==stop && A)
k2=1;
else k2=0;
endmodule
//**************************************************
电路 相关文章:
- 基于Virtex-5 FPGA设计Gbps无线通信基站(05-12)
- 基于FPGA的DVI/HDMI接口实现(05-13)
- 基于ARM的嵌入式系统中从串配置FPGA的实现(06-09)
- 基于PLB总线的H.264整数变换量化软核的设计(03-20)
- FPGA按键模式的研究与设计(03-24)
- 周立功:如何兼顾学习ARM与FPGA(05-23)