目錄
序言
原題複現
我的設計
上篇博文:
HDLBits 系列(30)Serial Receiver
寫了串行接收器如何接收8位串行資料,正确接收8位串行資料後給一個接收完畢标志信号,這篇博文來繼續進一步輸出正确接收的串行資料,在done有效時刻輸出并行的8bit資料。
特别容易實作,對上篇部落格的代碼進行略微添加即可。需要注意的是這種uart協定先發送的bit位為低bit位。
先給出原題,在給出設計:
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.
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
// Use FSM from Fsm_serial
localparam START = 0, B1 = 1, B2 = 2, B3 = 3, B4 = 4, B5 = 5, B6 = 6, B7 = 7, B8 = 8, STOP = 9, DONE0 = 10, DONE1 = 11;
reg [3:0] state, next_state;
always@(*) begin
case(state)
START: begin
if(in == 0) next_state = B1;
else next_state = START;
end
B1: begin
next_state = B2;
end
B2: begin
next_state = B3;
end
B3: begin
next_state = B4;
end
B4: begin
next_state = B5;
end
B5: begin
next_state = B6;
end
B6: begin
next_state = B7;
end
B7: begin
next_state = B8;
end
B8: begin
next_state = STOP;
end
STOP: begin
if(in == 0) next_state = DONE1;
else next_state = DONE0;
end
DONE0: begin
if(in == 1) next_state = START;
else next_state = B1;
end
DONE1: begin
if(in == 0) next_state = DONE1;
else next_state = START;
end
default: begin
next_state = START;
end
endcase
end
always@(posedge clk) begin
if(reset) state <= START;
else state <= next_state;
end
assign done = (state == DONE0) ? 1 : 0;
// New: Datapath to latch input bits.
reg [7:0] out_byte_mid;
always@(*) begin
case(state)
START: begin
;
end
B1: begin
out_byte_mid[0] = in;
end
B2: begin
out_byte_mid[1] = in;
end
B3: begin
out_byte_mid[2] = in;
end
B4: begin
out_byte_mid[3] = in;
end
B5: begin
out_byte_mid[4] = in;
end
B6: begin
out_byte_mid[5] = in;
end
B7: begin
out_byte_mid[6] = in;
end
B8: begin
out_byte_mid[7] = in;
end
STOP: begin
;
end
DONE0: begin
;
end
DONE1: begin
;
end
default: begin
;
end
endcase
end
assign out_byte = (done == 1)? out_byte_mid:'bz;
endmodule