Synchronous HDLC framing involves decoding a continuous bit stream of data to look for bit patterns that indicate the beginning and end of frames (packets). Seeing exactly 6 consecutive 1s (i.e., 01111110) is a "flag" that indicate frame boundaries. To avoid the data stream from accidentally containing "flags", the sender inserts a zero after every 5 consecutive 1s which the receiver must detect and discard. We also need to signal an error if there are 7 or more consecutive 1s.
Create a finite state machine to recognize these three sequences:
- 0111110: Signal a bit needs to be discarded (disc).
- 01111110: Flag the beginning/end of a frame (flag).
- 01111111...: Error (7 or more 1s) (err).
When the FSM is reset, it should be in a state that behaves as though the previous input were 0.
Here are some example sequences that illustrate the desired operation.
Discard 0111110:
Flag 01111110:
Reset behaviour and error 01111111...:
module top_module(
input clk,
input reset, // Synchronous reset
input in,
output disc,
output flag,
output err);
parameter IDLE = 3'h0;
parameter BITS_CNT = 3'h1;
parameter DISC = 3'h2;
parameter FLAG = 3'h3;
parameter ERROR = 3'h4;
reg [2:0] cur_state, nxt_state;
reg [15:0] bits_cnt;
always @(*)
begin
case(cur_state)
IDLE:
begin
nxt_state = in?BITS_CNT:IDLE;
end
BITS_CNT:
begin
case(bits_cnt)
'h0:
nxt_state = in?BITS_CNT:IDLE;
'h1:
nxt_state = in?BITS_CNT:IDLE;
'h2:
nxt_state = in?BITS_CNT:IDLE;
'h3:
nxt_state = in?BITS_CNT:IDLE;
'h4:
nxt_state = in?BITS_CNT:DISC;
'h5:
nxt_state = in?ERROR:FLAG;
default:
nxt_state = ERROR;
endcase
end
DISC:
begin
nxt_state = in?BITS_CNT:IDLE;
end
FLAG:
begin
nxt_state = in?BITS_CNT:IDLE;
end
ERROR:
begin
nxt_state = in?ERROR:IDLE;
end
default:
begin
nxt_state = IDLE;
end
endcase
end
always @(posedge clk)
begin
if(reset)
cur_state <= IDLE;
else
cur_state <= nxt_state;
end
always @(posedge clk)
begin
if(reset)
bits_cnt <= 16'h0;
else if(cur_state == BITS_CNT)
bits_cnt <= bits_cnt + 1'h1;
else
bits_cnt <= 16'h0;
end
assign disc = cur_state == DISC;
assign flag = cur_state == FLAG;
assign err = cur_state == ERROR;
endmodule