FSM
HDLbits中FSM部分答案&笔记。
sequence recognition (FSM-hdlc)
创建一个有限状态机来识别这三个序列:
0111110:需要丢弃一个位的信号(光盘)。
01111110:标记帧的开头/结尾(标志)。
01111111…: 错误 (7 或更多 1 秒) (错误)。
module top_module(
input clk,
input reset, // Synchronous reset
input in,
output disc,
output flag,
output err);
parameter IDLE=0,ONE=1,TWO=2,THREE=3,FOUR=4,FIVE=5,SIX=6,ERR=7,DISC=8,FLAG=9;
reg [3:0] state,next_state;
always @(posedge clk)begin
if(reset)
state<=IDLE;
else state<=next_state;
end
always @(*)begin //状态转移
case(state)
IDLE:begin
next_state=in?ONE:IDLE;
end
ONE:begin
next_state=in?TWO:IDLE;
end
TWO:begin
next_state=in?THREE:IDLE;
end
THREE:begin
next_state=in?FOUR:IDLE;
end
FOUR:begin
next_state=in?FIVE:IDLE;
end
FIVE:begin
next_state=in?SIX:DISC;
end
SIX:begin
next_state=in?ERR:FLAG;
end
DISC:begin
next_state=in?ONE:IDLE;
end
FLAG:begin
next_state=in?ONE:IDLE;
end
ERR:begin
next_state=in?ERR:IDLE;
end
endcase
end
//输出部分
always @(posedge clk) begin
if(reset)begin
disc <= 1'd0;
flag <= 1'd0;
err <= 1'd0;
end
else begin
case(next_state)
DISC:begin //处于DISC状态时输出disc=1;
disc <= 1'd1;
flag <= 1'd0;
err <= 1'd0;
end
FLAG:begin
disc <= 1'd0;
flag <= 1'd1;
err <= 1'd0;
end
ERR:begin
disc <= 1'd0;
flag <= 1'd0;
err <= 1'd1;
end
default:begin
disc <= 1'd0;
flag <= 1'd0;
err <= 1'd0;
end
endcase
end
end
endmodule
Q5a:Serial two’s complementer(Moore FSM)
求补码,用摩尔型状态机:
IDLE:初始状态
S1:直到输入有一个1(前面一直输入0时,取反加一为0且有最高进位,直到输入一个1,取反加一不进位。eg:100—>011–>100)
S2:在S1的基础上输入1时的状态
module top_module (
input clk,
input areset,
input x,
output z
);
parameter IDLE= 2'd0, S1 = 2'd1, S2 = 2'd2;
reg [1:0] state, next_state;
always @(*) begin
case( state)
IDLE: next_state = x ? S1 : IDLE;
S1: next_state = x ? S2 : S1;
S2: next_state = x ? S2 : S1;
endcase
end
always @(posedge clk or posedge areset) begin
if(areset)begin
state <= IDLE;
end
else begin
state <= next_state;
end
end
assign z = ( state == S1);
endmodule
##Q5b:Serial two’s complementer(Mealy FSM)
module top_module (
input clk,
input areset,
input x,
output z
);
parameter A = 2'd1, B= 2'd2;
reg [1:0] state, next_state;
always @(*) begin
case( state)
A: next_state = x ? B : A;
B: next_state = B ;
endcase
end
always @(posedge clk or posedge areset) begin
if(areset)begin
state <= A;
end
else begin
state <= next_state;
end
end
assign z =( ( state == A)&&x) || (state == B)&&~x);
endmodule
##Q3a:FSM
假设 FSM 以名为 A 的重置状态开始,如下所述。只要 s = 0,FSM 就一直处于状态 A,当 s = 1 时,它将移动到状态 B。
一旦处于状态B,FSM将在接下来的三个时钟周期中检查输入w的值。如果w = 1,恰好是其中两个时钟周期,则FSM必须在下一个时钟周期中将输出z设置为1。否则,z 必须为 0。
FSM 继续检查 w 以获取接下来的三个时钟周期,依此类推。下面的时序图说明了不同 w 值所需的 z 值。
使用尽可能少的状态。请注意,s 输入仅在状态 A 中使用,因此您只需要考虑 w 输入。
module top_module (
input clk,
input reset, // Synchronous reset
input s,
input w,
output z
);
parameter A=0,B=1;
reg [1:0] state,next_state;
reg [1:0] counter,num_w;
always @(posedge clk)begin
if(reset)
state<=A;
else
state<=next_state;
end
always @(*)begin
case(state)
A:next_state=s?B:A;
B: next_state=B;
default:next_state=A;
endcase
end
always @(posedge clk)begin
if(reset||counter==2'd2)begin
counter<=2'd0;
end
else begin
if(state==B)begin
counter<=counter+1'd1;
end
end
end
always @(posedge clk)begin
if(reset)begin
num_w<=2'd0;
end
else begin
if(counter==2'd0)begin
num_w<=w?1'd1:1'd0;
end
else
if(state==B)begin
num_w<=w?(num_w+1'd1):num_w;
end
end
end
assign z=(state==B)&&(num_w==2'd2)&&(counter==2'd0);
endmodule
##Q3b:FSM
module top_module (
input clk,
input reset, // Synchronous reset
input x,
output z
);
parameter S0=0,S1=1,S2=2,S3=3,S4=4;
reg [2:0] state,next_state;
always @(posedge clk)begin
if(reset)
state<=S0;
else
state<=next_state;
end
always @(*)begin
case(state)
S0:next_state=x?S1:S0;
S1:next_state=x?S4:S1;
S2:next_state=x?S1:S2;
S3:next_state=x?S2:S1;
S4:next_state=x?S4:S3;
endcase
end
assign z=(state==S3)||(state==S4);
endmodule
##Q3b:FSM Logic
assign Y0 = ((~y[2]&y[0])|(y==3'b100))&~x | (~y[2]&~y[0])&x;
assign z = (y == 3'b011) | (y == 3'b100);
Q2a,Q2b改天再更叭。FSM终于快结束了,有些题目有空还得刷一下。