原创 有限状态机

2009-11-7 13:51 2382 4 4 分类: FPGA/CPLD

要设计一个存储器控制模块,用状态机实现。


一般写法:


module fsm(clk,rst,ready,rw,oe,we);
output oe,we;
input clk,ready,rw,rst;
parameter idle="2"'b00,decision=2'b01,read=2'b10,write=2'b11;
reg oe,we;
//单进程描述
//对于同步电路来说,“毛刺”只发生在时钟跳变沿之后的一小段时间,因此在下一个跳变沿到来时“毛刺”已经消失。
//但是如果需要将输出作为其他模块的输入信号时(如使能,片选,复位等信号),就必须保证FSM的输出没有“毛刺”。
//这里将输出逻辑同步到时钟信号下,相当于把输出信号加载到一个DFF,这个寄存器由时钟来同步,保证输出没有毛刺产生。
//由于附加了与时钟同步的寄存器,所以这时的输出信号比不加寄存器时晚了一个周期。
reg[1:0] state;
always @(posedge clk or negedge rst)
begin
  if(!rst)
  state<=idle;
  else
  begin
    case(state)
    idle:begin oe<=0;we<=0;
       if(ready) state<=decision;
       else state<=idle; end
    decision:begin oe<=0;we<=0;
         if(rw==1) state<=read;
         else state<=write; end
    read:begin oe<=1;we<=0;
       if(ready) state<=idle;
       else state<=read; end
    write:begin oe<=0;we<=1;
       if(ready) state<=idle;
       else state<=write; end
   endcase
  end
end


//双进程描述,将输出逻辑和次态逻辑合并
//reg[1:0] pst,nst;
//
//always @(posedge clk)
//begin
//    if(!rst)
//    pst<=idle;
//    else
//    pst<=nst;
//end
//
//always @(pst or rw or ready)
//begin
//  case(pst)
//  idle:begin oe<=0;we<=0;
//       if(ready) nst<=decision;
//       else nst<=idle; end
//  decision:begin oe<=0;we<=0;
//         if(rw==1) nst<=read;
//         else nst<=write; end
//  read:begin oe<=1;we<=0;
//       if(ready) nst<=idle;
//       else nst<=read; end
//  write:begin oe<=0;we<=1;
//       if(ready) nst<=idle;
//       else nst<=write; end
//  endcase
//end
endmodule


改进之后


//改进的FSM去掉了输出逻辑而直接把状态作为输出信号,这样输出信号就直接来自于寄存器
//从而避免了“毛刺”的产生
//同时由于少了一级输出电路,因此可以减小输出信号的延时
module fsmpro(clk,rst,ready,rw,we,oe);
output oe,we;
input clk,ready,rw,rst;


//建立包括各个状态和输出信号的表格,并对表格添加状态位,得到各个不同状态的状态编码
//这里状态码从高位到低位依次是{oe,we,s},最后的输出即为oe=state[2];we=state[1];
parameter idle="3"'b000,decision=3'b001,read=3'b100,write=3'b010;
reg[2:0] state;


always @(posedge clk)
begin
  if(!rst)
  state<=idle;
  else
  begin
    case(state)
    idle:begin
       if(ready) state<=decision;
       else state<=idle; end
    decision:begin
         if(rw==1) state<=read;
         else state<=write; end
    read:begin
       if(ready) state<=idle;
       else state<=read; end
    write:begin
       if(ready) state<=idle;
       else state<=write; end
    default:state<=state;
   endcase
  end
end


assign we="state"[1];
assign oe="state"[2];
endmodule

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
4
关闭 站长推荐上一条 /3 下一条