加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

使用状态机FSM设计仲裁器

(2012-12-05 23:15:21)
标签:

杂谈

Fundamentals of Digital Logic with Verilog Design

Stephen Brown and Zvonko Vranesic

FSM可用来设计一个仲裁器来控制系统中的多个设备对共享资源的访问。同一时刻只能有一个设备访问这些资源。假设系统中所有的信号在同一时钟的上升沿改变数值。每个设备提供一个输入给FSM,叫做请求request。FSM给每个设备一个信号,叫做准许grant。一个设备使能request信号,请求使用资源。当共享资源处于空闲状态,仲裁器接收所有的请求。然后根据优先级,选择一个请求的设备,使能他的准许信号。当一个设备使用完共享资源,deassert 请求信号。

We will assume that there are three devices in the system, called device 1, device 2, and device 3. It is easy to see how the FSM can be extended to handle more devices. The request signals are named r1, r2, and r3, and the grant signals are called g1, g2, and g3. The devices are assigned a priority level such that device 1 has the highest priority, device 2 has the next highest, and device 3 has the lowest priority. Thus if more than one request signal is asserted when the FSM assigns a grant, the grant is given to the requesting device that has the highest priority.
A state diagram for the desired FSM, designed as a Moore-type machine, is depicted in Figure 8.72. Initially, on reset the machine is in the state called Idle. No grant signals are asserted, and the shared resource is not in use. There are three other states, called gnt1, gnt2, and gnt3. Each of these states asserts the grant signal for one of the devices. The FSM remains in the Idle state as long as all of the request signals are 0. In the state diagram the condition r1r2r3 = 000 is indicated by the arc labeled 000. When one or more request signals become 1, the machine moves to one of the grant states, according to the priority scheme. If r1 is asserted, then device 1 will receive the grant because it has the highest priority. This is indicated by the arc labeled 1xx that leads to state gnt1, which sets g1 = 1. The meaning of 1xx is that the request signal r1 is 1, and the values of signals r2 and r3 are irrelevant because of the priority scheme. As before, we use the symbol x to indicate that the value of the corresponding variable can be either 0 or 1. The machine stays in state gnt1 as long as r1 is 1. When r1 = 0, the arc labeled 0xx causes a change on the next positive clock edge back to state Idle, and g1 is deasserted. If other requests are active at this time, then the FSM will change to a new grant state after the next clock edge. The arc that causes a change to state gnt2 is labeled 01x. This label adheres to the priority scheme because it represents the condition that r2 = 1, but r1 = 0. Similarly, the condition for entering state gnt3 is given as 001, which indicates that the only request signal asserted is r3.

我们假设系统中包含三个设备,设备1,设备2,设备3。我们来看一个FSM如何来建一个仲裁器处理这些设备的请求。 三个设备的请求信号分别为r1,r2,r3。应答信号分别分g1,g2,g3。设备1拥有最高的优先级,设备2其次,设备3的优先级最低。因此,如果同一时刻,有多个设备同时发出请求信号时,仲裁器将把应答信号送给最高优先级的设备。

如下图,采用摩尔状态机设计仲裁器。

http://s1/middle/71462a654d3b8c8653500&690

 

verilog code

module arbiter(
    clk,
    rst_n,
    r,
    g
    );
   
    input clk;
    input rst_n;
    input [7:0] r;
   
    output [7:0] g;

    //(* FSM_ENCODING="ONE-HOT" *)   
    reg [8:0] curr_state;
    reg [8:0] next_state;
   
    reg [7:0] g;
   
    parameter     IDLE = 9'b0_0000_0001,
                gnt0 = 9'b0_0000_0010,
                gnt1 = 9'b0_0000_0100,
                gnt2 = 9'b0_0000_1000,
                gnt3 = 9'b0_0001_0000,
                gnt4 = 9'b0_0010_0000,
                gnt5 = 9'b0_0100_0000,
                gnt6 = 9'b0_1000_0000,
                gnt7 = 9'b1_0000_0000;
               
               
           
    //state reg
    always @ (posedge clk)
    begin
        if(!rst_n)
            begin
                curr_state <= IDLE;
            end
        else
            begin
                curr_state <= next_state;
            end
    end
   
    //next state logic
   
    always @ (curr_state or r)
    begin
        case(curr_state)
        IDLE:
            begin
                casex(r)
                    8'bxxxx_xxx1: next_state = gnt0;
                    8'bxxxx_xx10: next_state = gnt1;
                    8'bxxxx_x100: next_state = gnt2;
                    8'bxxxx_1000: next_state = gnt3;
                    8'bxxx1_0000: next_state = gnt4;
                    8'bxx10_0000: next_state = gnt5;
                    8'bx100_0000: next_state = gnt6;
                    8'b1000_0000: next_state = gnt7;

                    default: next_state = IDLE;
                endcase
            end
        gnt0:
            begin
                if(r[0] == 1'b1)
                    next_state = gnt0;
                else
                    next_state = IDLE;       
            end
        gnt1:
            begin
                if(r[1] == 1'b1)
                    next_state = gnt1;
                else
                    next_state = IDLE;       
            end   
        gnt2:
            begin
                if(r[2] == 1'b1)
                    next_state = gnt2;
                else
                    next_state = IDLE;       
            end
        gnt3:
            begin
                if(r[3] == 1'b1)
                    next_state = gnt3;
                else
                    next_state = IDLE;       
            end
        gnt4:
            begin
                if(r[4] == 1'b1)
                    next_state = gnt4;
                else
                    next_state = IDLE;       
            end
        gnt5:
            begin
                if(r[5] == 1'b1)
                    next_state = gnt5;
                else
                    next_state = IDLE;       
            end
        gnt6:
            begin
                if(r[6] == 1'b1)
                    next_state = gnt6;
                else
                    next_state = IDLE;       
            end   
        gnt7:
            begin
                if(r[7] == 1'b1)
                    next_state = gnt7;
                else
                    next_state = IDLE;       
            end   
           
        default:
            next_state = IDLE;
           
        endcase           
       
    end
   
    //output logic
    always @ (curr_state)
    begin
        case (curr_state)
            IDLE: g = 8'b0000_0000;
            gnt0: g = 8'b0000_0001;       
            gnt1: g = 8'b0000_0010;
            gnt2: g = 8'b0000_0100;
            gnt3: g = 8'b0000_1000;
            gnt4: g = 8'b0001_0000;
            gnt5: g = 8'b0010_0000;
            gnt6: g = 8'b0100_0000;
            gnt7: g = 8'b1000_0000;
           
            default: g = 8'b0000_0000;
        endcase                   
    end
   
endmodule
   
   

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有