132 fsm_onehot
Given the following state machine with 1 input and 2 outputs:
Suppose this state machine uses one-hot encoding, where state[0] through state[9] correspond to the states S0 though S9, respectively. The outputs are zero unless otherwise specified.
Implement the state transition logic and output logic portions of the state machine (but not the state flip-flops). You are given the current state in state[9:0] and must produce next_state[9:0] and the two outputs. Derive the logic equations by inspection assuming a one-hot encoding. (The testbench will test with non-one hot inputs to make sure you're not trying to do something more complicated).
Hint...
Logic equations for one-hot state transition logic can be derived by looking at in-edges of the state transition diagram.
module top_module(
input in,
input [9:0] state,
output [9:0] next_state,
output out1,
output out2);
parameter s0 = 10'b0000000001;
parameter s1 = 10'b0000000010;
parameter s2 = 10'b0000000100;
parameter s3 = 10'b0000001000;
parameter s4 = 10'b0000010000;
parameter s5 = 10'b0000100000;
parameter s6 = 10'b0001000000;
parameter s7 = 10'b0010000000;
parameter s8 = 10'b0100000000;
parameter s9 = 10'b1000000000;
// State transition logic
always@* begin
next_state[0] = (state[0]|state[1]|state[2]|state[3]|state[4]|state[7]|state[8]|state[9])&(~in);
next_state[1] = (state[0]|state[8]|state[9])∈
next_state[2] = state[1]∈
next_state[3] = state[2]∈
next_state[4] = state[3]∈
next_state[5] = state[4]∈
next_state[6] = state[5]∈
next_state[7] = state[6]&in|state[7]∈
next_state[8] = state[5]&~in;
next_state[9] = state[6]&~in;
end
// Output logic
assign out1 = state[8]|state[9];
assign out2 = state[7]|state[9];
endmodule
133 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
Hint...
- Although in[7:0] is a byte, the FSM only has one input: in[3].
- You need ~4 states. Three states likely wouldn't work because one of them needs to assert done, and done is asserted for only one cycle for each received message.
Hint...
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output done); //
parameter BYTE1=2'd0;
parameter BYTE2=2'd1;
parameter BYTE3=2'd2;
parameter DONE =2'd3;
reg [1:0] state,state_next;
// State transition logic (combinational)
always@(*)begin
state_next=state;
case(state)
BYTE1:state_next=in[3]?BYTE2:BYTE1;
BYTE2:state_next=BYTE3;
BYTE3:state_next=DONE;
DONE:state_next=in[3]?BYTE2:BYTE1;
endcase
end
// State flip-flops (sequential)
always@(posedge clk)begin
if(reset)begin
state<=BYTE1;
end
else begin
state<=state_next;
end
end
// Output logic
assign done = (state==DONE);
endmodule
134 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:
Hint...
Use the FSM from PS/2 packet parser and add a datapath to capture the incoming bytes.
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output [23:0] out_bytes,
output done); //
// FSM from fsm_ps2
parameter BYTE1=2'd0;
parameter BYTE2=2'd1;
parameter BYTE3=2'd2;
parameter DONE =2'd3;
reg [1:0] state,state_next;
// State transition logic (combinational)
always@(*)begin
state_next=state;
case(state)
BYTE1:state_next=in[3]?BYTE2:BYTE1;
BYTE2:state_next=BYTE3;
BYTE3:state_next=DONE;
DONE:state_next=in[3]?BYTE2:BYTE1;
endcase
end
// State flip-flops (sequential)
always@(posedge clk)begin
if(reset)begin
state<=BYTE1;
end
else begin
state<=state_next;
end
end
// Output logic
assign done = (state==DONE);
// New: Datapath to store incoming bytes.
reg [23:0]out_bytes_reg,out_bytes_next;
always@* begin
out_bytes_next = out_bytes_reg;
case(state)
BYTE1:out_bytes_next[23:16]=in;
BYTE2:out_bytes_next[15: 8]=in;
BYTE3:out_bytes_next[ 7: 0]=in;
DONE :out_bytes_next[23:16]=in;
endcase
end
always@(posedge clk)begin
if(reset)begin
out_bytes_reg<=24'd0;
end
else begin
out_bytes_reg<=out_bytes_next;
end
end
assign out_bytes = out_bytes_reg;
endmodule