HDLBits/Sequential Logic/Finite State Machines/Fsm serialdata
See also: Serial receiver
Now that you have a finite state machine that can identify when bytes are correctly received in a serial bitstream, add a datapath that will output the correctly-received data byte. out_byte needs to be valid when done is 1, and is don't-care otherwise.
Note that the serial protocol sends the least significant bit first.
本題與上題基本一致,只需要多一個8 bit 寄存器來寄存得到的數據並在 done 信號為高電平時候輸出即可。這里需要使用移位寄存器來實現移位寄存,可以從波形圖看出這是右移寄存器,因為不確定接收到的數據是否正確,所以只需不斷移位寄存即可,當 done 信號為正時進行輸出即為正確接收到的數據。狀態機與上題一致,波形圖如下。
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
parameter idle = 0,start = 1,data = 2,stop =3,error = 4;
reg[2:0] state, next_state;
reg[3:0] cnt;
reg done_r;
reg[7:0] out;
//state
always@(posedge clk)begin
if(reset)
state <= idle;
else
state <= next_state;
end
//transition
always@(*)begin
case(state)
idle: next_state=in?idle:start;
start: next_state=data;
data: next_state=(cnt==8)?(in?stop:error):data;
stop: next_state=in?idle:start;
error: next_state=in?idle:error;
endcase
end
//out
always@(posedge clk)begin
if(reset)
out<=0;
else
case(next_state)
start: out<=0;
data: out<={in,out[7:1]}; //移位寄存器
endcase
end
//cnt
always@(posedge clk)begin
if(reset)
cnt<=0;
else
case(next_state)
start: cnt<=0;
data: cnt<=cnt+1;
default: cnt<=cnt;
endcase
end
//done_r
always@(posedge clk)
case(next_state)
stop: done_r <= 1;
default: done_r <= 0;
endcase
assign done = done_r;
assign out_byte = out;
endmodule
沒有留言:
張貼留言