HBLbits_Verilog Basic_Fsm ps2
The PS/2 mouse protocol sends messages that are three bytes long. However, within a continuous byte stream, it's not obvious where messages start and end. The only indication is that the first byte of each three byte message always has bit[3]=1 (but bit[3] of the other two bytes may be 1 or 0 depending on data).
We want a finite state machine that will search for message boundaries when given an input byte stream. The algorithm we'll use is to discard bytes until we see one with bit[3]=1. We then assume that this is byte 1 of a message, and signal the receipt of a message once all 3 bytes have been received (done).
The FSM should signal done in the cycle immediately after the third byte of each message was successfully received.
Some timing diagrams to explain the desired behaviour
Under error-free conditions, every three bytes form a message:
在成功接收到每個消息的第三個位元組之後,FSM應該立即在週期中發出完成信號。
根據時序圖以及題目描述,我們可以大概畫出狀態轉移圖:
當輸入資料的in[7:0]的bit[3]=1時,開始接收資料;一次接收3位元組的資料,存入輸出out_bytes[23:0],並使能接收完成done=1。
狀態轉換圖
說明:現態state_c=Done時,若接收資料的bit[3]=1,則接收下一次的3位元組數;若bit[3]=0則重新接收資料。
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output done); //
parameter Byte1=0, Byte2=1, Byte3=2, Done=3;
reg [2:0] state_c, state_n;
wire Byte12Byte2, Byte22Byte3, Byte32Done, Done2Byte1, Done2Byte2;
reg [7:0] data1, data2, data3;
always@(posedge clk) begin
if(reset)
state_c <= Byte1;
else begin
state_c <= state_n;
end
end
always@(*) begin
case (state_c)
Byte1:begin
if(Byte12Byte2)
state_n = Byte2;
else
state_n = state_c;
end
Byte2:begin
if(Byte22Byte3)
state_n = Byte3;
end
Byte3:begin
if(Byte32Done)
state_n = Done;
end
Done:begin
if(Done2Byte1)
state_n = Byte1;
else
state_n = Byte2;
end
endcase
end
assign Byte12Byte2 = in[3]==1;
assign Byte22Byte3 = 1;
assign Byte32Done = 1;
assign Done2Byte1 = in[3]==0;
always@(posedge clk) begin
if(reset) begin
data1<=0;
data2<=0;
data3<=0;
end
else begin
if(state_c == Byte1)
data1 <= in;
else if(state_c == Byte2)
data2 <= in;
else if(state_c == Byte3)
data3 <= in;
else if(state_c == Done)
data1 <= in;
else begin
data1<=0;
data2<=0;
data3<=0;
end
end
end
assign done = state_c == Done;
//assign out_bytes = (state_c == Done)?{data1, data2, data3}:24'hZZZZZZ;
endmodule
實際上就是要求找出FRAME HEADER幀頭,在資料流程中找出三位元組中的第一個位元組,bit[3]=1為第一個位元組,與之後的兩個位元組組成一個資料幀,因此編寫狀態機時可以程式設計四個狀態:
IDLE
, BYTE1 ,BYTE2 ,BYTE3
但之前一直困惑我的是第一個位元組 bit[3]=1,但第二個與第三個位元組的bit[3]也能是1,那麼bit[3]=1是不是就不能作為第一個位元組的判斷依據呢?但後來聯繫實際的硬體電路想想,一個資料流程總有一個起始位元,即第一個位元組,不可能直接從第二個位元組開始,對應著軟體設計就是有一個reset的設計,因此在復位之後再對bit[3]進行檢測,若bit[3]=1則代表檢測到了第一個位元組,否則沒有檢測到第一個位元組
沒有留言:
張貼留言