HBLbits_Verilog Basic_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).
For example:
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output [23:0] out_bytes,
output done); //
parameter Byte1=0, Byte2=1, Byte3=2, Done=3;
reg [2:0] state, state_next;
wire Byte12Byte2, Byte22Byte3, Byte32Done, Done2Byte1, Done2Byte2;
reg [7:0] data1, data2, data3;
always@(posedge clk) begin
if(reset)
state <= Byte1;
else begin
state <= state_next;
end
end
always@(*) begin
case (state)
Byte1:begin
if(Byte12Byte2)
state_next = Byte2;
else
state_next = state;
end
Byte2:begin
if(Byte22Byte3)
state_next = Byte3;
end
Byte3:begin
if(Byte32Done)
state_next = Done;
end
Done:begin
if(Done2Byte1)
state_next = Byte1;
else
state_next = 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 == Byte1)
data1 <= in;
else if(state == Byte2)
data2 <= in;
else if(state == Byte3)
data3 <= in;
else if(state == Done)
data1 <= in;
else begin
data1<=0;
data2<=0;
data3<=0;
end
end
end
assign done = state == Done;
assign out_bytes = (state == Done)?{data1, data2, data3}:24'hZZZZZZ;
endmodule
另一方法
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output [23:0] out_bytes,
output done); //
reg [1:0] state, next_state;
localparam D1 = 0, D2 = 1, D3 = 2, DONE = 3;
// State transition logic (combinational)
always@(*) begin
case(state)
D1: begin
if(in[3] == 1) next_state = D2;
else next_state = D1;
end
D2: begin
next_state = D3;
end
D3: begin
next_state = DONE;
end
DONE: begin
if(in[3] == 1) next_state = D2;
else next_state = D1;
end
default: begin
next_state = D1;
end
endcase
end
always@(posedge clk) begin
if(reset) state <= D1;
else state <= next_state;
end
// New: Datapath to store incoming bytes.
reg [7:0] in_r;
reg [1:0] state_r;
always@(posedge clk) begin
if(reset) begin
in_r <= 0;
state_r <= D1;
end
else begin
state_r <= state;
in_r <= in;
end
end
reg [23:0] out_bytes_mid;
always@(*) begin
case(state)
D1: begin
if(in[3] == 1) out_bytes_mid[23:16] = in;
end
D2: begin
if(state_r == DONE && in_r[3] == 1) begin
out_bytes_mid[15:8] = in;
out_bytes_mid[23:16] = in_r;
end
else out_bytes_mid[15:8] = in;
end
D3: begin
out_bytes_mid[7:0] = in;
end
DONE: begin
;
end
default: begin
;
end
endcase
end
assign out_bytes = (done == 1)? out_bytes_mid:'bx;
assign done = (state == DONE)?1:0;
endmodule
沒有留言:
張貼留言