時序檢測模塊
理解4段狀態機的思路
//四段狀態機
//第一段
//一個always模塊採用同步時序的方式描述狀態轉移
always @(posedge clk or negedge rst_n)
begin
if(!rst_n == 1'b0)
begin
state_c <= HEAD;
end
else
begin
state_c <= state_n;
end
end
//第二段
//一個always採用組合邏輯的方式判斷狀態轉移條件
always @(*)
begin
case(state_c)
HEAD:
begin
if(hea2typ_start)
begin
state_n = TYPE;
end
else
begin
state_n = state_c;
end
end
TYPE:
begin
if(typ2len_start)
begin
state_n = LEN;
end
else if(typ2dat_start)
begin
state_n = DATA;
end
else
begin
state_n = state_c;
end
end
LEN:
begin
if(len2dat_start)
begin
state_n = DATA;
end
else
begin
state_n = state_c;
end
end
DATA:
begin
if(dat2fcs_start)
begin
state_n = FCS;
end
else
begin
state_n = state_c;
end
end
FCS:
begin
if(fcs2hea_start)
begin
state_n = HEAD;
end
else
begin
state_n = state_c;
end
end
endcase
end
//第三段
//用assign定義轉移條件。注意一定要加上現態
assign hea2typ_start = state_c == HEAD && din_ff0 == 8'h55 && din == 8'hd5;
assign typ2len_start = state_c == TYPE && din != 0;
assign len2dat_start = state_c == LEN && end_cnt;
assign typ2dat_start = state_c == TYPE && din = 0;
assign dat2fcs_start = state_c == DATA && end_cnt;
assign fcs2hea_start = state_c == FCS && end_cnt;
//第四段
//採用同步時序電路設計每一個狀態的輸出
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
cnt <= 1'b0;
end
else if(add_cnt)
begin
if(end_cnt)
begin
cnt <= 1'b0;
end
else
begin
cnt <= cnt + 1'b1;
end
end
end
assign add_cnt = state_c != HEAD;
assign end_cnt = add_cnt && cnt = x - 1;
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
din_ff0 <= 0;
end
else
begin
din_ff0 <= din;
end
end
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
length <= 0;
end
else if(state_c == LEN)
begin
length <= {length[7:0],din}; //length爲最大計數65535的16位計數器
end
end
always @(*)
begin
if(state_c == LEN)
x = 2;
else if(state_c == DATA)
x = length;
else if(state_c == TYPE)
x = 1;
else
x = 4;
end
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
dout <= 1'b0;
end
else
begin
dout <= din;
end
end
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
dout_sop <= 1'b0;
end
else if(state_c == TYPE)
begin
dout_sop <= 1'b1;
end
else
begin
dout_sop <= 1'b0;
end
end
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
dout_eop <= 1'b0;
end
else if(state_c == FCS && end_cnt)
begin
dout_eop <= 1'b1;
end
else
begin
dout_eop <= 1'b0;
end
end
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
dout_vld <= 1'b0;
end
else if(state_c != HEAD)
begin
dout_vld <= 1'b1;
end
else
begin
dout_vld <= 1'b0;
end
end