HDLBits PS/2
Fsm ps2
网址:https://hdlbits.01xz.net/wiki/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.
本题可分为byte1,byte2,byte3,d四个状态,接收数据时判断条件为in[3],只有d和byte1需要判断,done信号在d状态为1.
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output done); //
parameter d=0,byte1=1,byte2=2,byte3=3;
reg [1:0] state,next_state;
always @(posedge clk) begin
if(reset) state<=byte1;
else state<=next_state;
end
always @(*) begin
case(state)
d: next_state=in[3]?byte2:byte1;
byte1: next_state=in[3]?byte2:byte1;
byte2: next_state=byte3;
byte3: next_state=d;
endcase
end
assign done=(state==d);
endmodule
Fsm ps2data
See also: PS/2 packet parser.
Now that you have a state machine that will identify three-byte messages in a PS/2 byte stream, add a datapath that will also output the 24-bit (3 byte) message whenever a packet is received (out_bytes[23:16]
is the first byte, out_bytes[15:8]
is the second byte, etc.).
out_bytes
needs to be valid whenever the done
signal is asserted. You may output anything at other times (i.e., don’t-care).
在前一题的基础上多了一个数据路径(我觉得跟上一道题没啥区别,就多了一个out_bytes按时序移位赋值)。
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output [23:0] out_bytes,
output done); //
reg [23:0] t;
parameter d=0,byte1=1,byte2=2,byte3=3;
reg [1:0] state,next_state;
always @(posedge clk) begin
if(reset) state<=byte1;
else state<=next_state;
end
always @(*) begin
case(state)
d: next_state=in[3]?byte2:byte1;
byte1: next_state=in[3]?byte2:byte1;
byte2: next_state=byte3;
byte3: next_state=d;
endcase
end
always @(posedge clk) begin
if(reset) t<=24'b0;
else t<={t[15:0],in};
end
assign done=(state==d);
assign out_bytes=t;
endmodule