题目
In many (older) serial communications protocols, each data byte is sent along with a start bit and a stop bit, to help the receiver delimit bytes from the stream of bits. One common scheme is to use one start bit (0), 8 data bits, and 1 stop bit (1). The line is also at logic 1 when nothing is being transmitted (idle).
Design a finite state machine that will identify when bytes have been correctly received when given a stream of bits. It needs to identify the start bit, wait for all 8 data bits, then verify that the stop bit was correct. If the stop bit does not appear when expected, the FSM must wait until it finds a stop bit before attempting to receive the next byte.
题目解读:实现一个8bit数据的读取,当in=0时,表示开始位,这意味着下一个状态是读取数据;读取8bit数据,即计数8次,此外,无论读取成功与否都要将计数器置0,以便下次计数;8个数据读取完毕,当in=1时,表示停止位,即下一个状态done=1,当in=0时,状态未知直至in=1进入下一个状态时,done=1;
这里我定义4个状态,即开始START、读取数据DATA、停止STOP、未知IDLE。在START状态需要不断检测in的值,保证随时可以进入DATA状态;在DATA状态,需要计数9次,8个数据加1个停止位的检测,若in=1,则next_state=STOP,否则next_state=IDLE(未知态);在STOP状态(不是停止位),若in=0,则表明这里是开始位,next_state=DATA(直接进入数据读取),否则next_state=START;在IDLE状态,若in=1,则next_state=START,否则保持原态。
代码
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output done
);
parameter IDLE=2'b01;
parameter START=2'b00;
parameter DATA=2'b10;
parameter STOP=2'b11;
reg [1:0]state;
reg [1:0]next_state;
integer counter;//用于计数
always @(*)begin
case(state)
IDLE:begin
if(in==1)
next_state=START;
else
next_state=IDLE;
end
START:begin
if(in==0)
next_state=DATA;
else
next_state=START;
end
DATA:begin
if(counter==9)begin
if(in==1)
next_state=STOP;
else
next_state=IDLE;
end else
next_state=DATA;
end
STOP:begin
if(in==0)
next_state=DATA;
else
next_state=START;
end
endcase
end
always @(posedge clk)begin
if(reset)begin
state=START;
counter=0;
end else begin
state=next_state;
if(state==DATA)begin
counter=counter+1;
end
if(state!=DATA)begin//不管是否成功,置0,以便下次使用
counter=0;
end
end
end
assign done=state[0]&state[1];
endmodule
总结
1.开始总是遇到常数有多个驱动的问题,原因是我把counter=counter+1放在了多个地方,一般只放在时许逻辑部分
2.在使用counter进行计数时,忘记重置counter,导致我运行多次都没有成功