首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

影响FPGA设计中时钟因素的探讨(2)

影响FPGA设计中时钟因素的探讨(2)

  在状态机中,一般也要将大的计数器移到状态机外,因为计数器这东西一般是经常是大于4输入的,如果再和其它条件一起做为状态的跳变判据的话,必然会增加LUT的级联,从而增大组合逻辑。以一个6输入的计数器为例,我们原希望当计数器计到111100后状态跳变,现在我们将计数器放到状态机外,当计数器计到111011后产生个enable信号去触发状态跳变,这样就将组合逻辑减少了。
     状态机一般包含三个模块,
(1)一个输出模块,
(2)一个决定下个状态是什么的模块
(3)一个保存当前状态的模块。
     组成三个模块所采用的逻辑也各不相同。输出模块通常既包含组合逻辑又包含时序逻辑;决定下一个状态是什么的模块通常由组合逻辑构成;保存现在状态的通常由时序逻辑构成。三个模块的关系如下图9所示。

图9 状态机的组成
  所有通常写状态机时也按照这三个模块将状态机分成三部分来写,如下面就是一种良好的状态机设计方法:
/*-----------------------------------------------------
This is FSM demo program
Design Name : arbiter
File Name : arbiter2.v
-----------------------------------------------------*/
module arbiter2 (
                    clock , // clock
                    reset , // Active high, syn reset
                    req_0 , // Request 0
                    req_1 , // Request 1
                    gnt_0 ,
                    gnt_1
                );
//-------------Input Ports-----------------------------
input    clock ;
input    reset ;
input    req_0 ;
input    req_1 ;
//-------------Output Ports----------------------------
output    gnt_0 ;
output    gnt_1 ;
//-------------Input ports Data Type-------------------
wire    clock ;
wire    reset ;
wire    req_0 ;
wire    req_1 ;
//-------------Output Ports Data Type------------------
reg        gnt_0 ;
reg        gnt_1 ;
//-------------Internal Constants--------------------------
parameter     SIZE = 3 ;
parameter     IDLE = 3'b001 ,
            GNT0 = 3'b010 ,
            GNT1 = 3'b100 ;
//-------------Internal Variables---------------------------
reg        [SIZE-1:0] state ;        // Seq part of the FSM
wire    [SIZE-1:0] next_state ;    // combo part of FSM

//----------Code startes Here------------------------
assign    next_state = fsm_function(req_0, req_1);
//------------fsm_function--------------//
function [SIZE-1:0] fsm_function;
input     req_0;    //parameter
input     req_1;    //parameter
begin
    case(state)
        IDLE :   
            if (req_0 == 1'b1)   
                fsm_function = GNT0;
            else if (req_1 == 1'b1)
                fsm_function = GNT1;
            else
                fsm_function = IDLE;
        GNT0 :
            if (req_0 == 1'b1)
                fsm_function = GNT0;
            else
                fsm_function = IDLE;
        GNT1 :
            if (req_1 == 1'b1)
                fsm_function = GNT1;
            else
                fsm_function =IDLE;
        default : fsm_function = IDLE;
        endcase
end
endfunction

always@(posedge clock)
begin
    if (reset == 1'b1)
        state <= IDLE;
    else
        state <= next_state;
end
//----------Output Logic-----------------------------
always @ (posedge clock)
begin
    if (reset == 1'b1)
        begin
        gnt_0 <= #1 1'b0;
        gnt_1 <= #1 1'b0;
        end
    else
        begin
        case(state)
            IDLE :
                begin
                gnt_0 <= #1 1'b0;
                gnt_1 <= #1 1'b0;
                end
            GNT0 :
                begin
                gnt_0 <= #1 1'b1;
                gnt_1 <= #1 1'b0;
                end
            GNT1 :
                begin
                gnt_0 <= #1 1'b0;
                gnt_1 <= #1 1'b1;
                end
            default :
                begin
                gnt_0 <= #1 1'b0;
                gnt_1 <= #1 1'b0;
                end
        endcase
        end
end // End Of Block OUTPUT_
endmodule
  状态机通常要写成3段式,从而避免出现过大的组合逻辑
  上面说的都是可以通过流水的方式切割组合逻辑的情况,但是有些情况下我们是很难去切割组合逻辑的,在这些情况下我们又该怎么做呢?
  状态机就是这么一个例子,我们不能通过往状态译码组合逻辑中加入流水。如果我们的设计中有一个几十个状态的状态机,它的状态译码逻辑将非常
继承事业,薪火相传
返回列表