module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
parameter S0=0,S1=1,S2=2,S3=3,S4=4,S5=5;
//S0等待start为1,start为1下个周期跳变至S1,S1接收8位数据,接收完后跳变至S4状态,
//S4状态判断奇校验,若正确跳转至S2,不正确跳转至S5;S5是奇校验不正确后等待停止位出现(in=1),然后跳转至S0
//S2判断stop信号是否是一个周期等到,1个周期则跳变至S3,多个周期则跳变回S0,S3状态对done信号进行判断输出 。
reg [2:0] state,next_state;
reg [4:0] counter;
always@(posedge clk) begin
if(reset)
state<=S0;
else
state<=next_state;
end
always@(posedge clk) begin
if(reset)
counter<=0;
else if(next_state==S1 || next_state==S2 || next_state==S4)
counter<=counter+1'b1;
else
counter<=0;
end
always@(*) begin
case(state)
S0: next_state = in?S0:S1;
S1: next_state = (counter==8)?S4:S1;
S4: next_state = ((~^out_byte)==in)?S2:S5;
S5: next_state = in?S0:S5; //奇校验不正确后等待停止位即in=1出现,然后调至S0
S2: next_state = in?((counter==10)?S3:S0):S2;
S3: next_state = in?S0:S1;
default: next_state = S0;
endcase
end
always@(posedge clk) begin
case(next_state)
S1: out_byte<={in,out_byte[7:1]};
S4: out_byte<={in,out_byte[7:1]}; //在时钟上升沿采取数据in,采取的是上个周期时in的值,所以S4状态采取最后一位in的值
S3: out_byte<=out_byte;
S2: out_byte<=out_byte;
default: out_byte<=0;
endcase
end
assign done = (state==S3);
endmodule
Fsm serialdp
于 2022-03-21 23:25:26 首次发布