标签:
杂谈 |
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

加载中…