17. Serial receiver
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output done
);
parameter start=0,s1=1,s2=2,s3=3,s4=4,s5=5,s6=6,s7=7,s8=8,stop=9,idle=10,Wait=11;
reg [3:0] state,next;
always@(*) begin
case(state)
start: next= in? start:s1;
s1: next=s2;
s2: next=s3;
s3: next=s4;
s4: next=s5;
s5: next=s6;
s6: next=s7;
s7: next=s8;
s8: next=stop;
stop: next=in? idle:Wait;
idle: next=in?start:s1;
Wait:next=in? start:Wait;
endcase
end
always@(posedge clk) begin
if(reset)
state<=start;
else
state<=next;
end
assign done=(state==idle);
endmodule
18. Serial receiver and datapath
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
// Use FSM from Fsm_serial
parameter start=0,s1=1,s2=2,s3=3,s4=4,s5=5,s6=6,s7=7,s8=8,stop=9,idle=10,Wait=11;
reg [3:0]state,next;
reg [7:0]temp;
always@(*)begin
case(state)
start:next=in?start:s1;
s1:next=s2;
s2:next=s3;
s3:next=s4;
s4:next=s5;
s5:next=s6;
s6:next=s7;
s7:next=s8;
s8:next=stop;
stop:next=in?idle:Wait;
idle:next=in?start:s1;
Wait:next=in?start:Wait;
endcase
end
always@(posedge clk)begin
if(reset) state<=start;
else state<=next;
end
assign done=(state==idle);
// New: Datapath to latch input bits.
always@(posedge clk)begin
case(state)
s1:temp[0]<=in;
s2:temp[1]<=in;
s3:temp[2]<=in;
s4:temp[3]<=in;
s5:temp[4]<=in;
s6:temp[5]<=in;
s7:temp[6]<=in;
s8:temp[7]<=in;
endcase
end
assign out_byte=done?temp:8'b0;
endmodule
19.Serial receiver with parity checking 奇偶校验
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
parameter idle=0,start=1,s0=2,s1=3,s2=4,s3=5,s4=6,s5=7,s6=8,s7=9,s8=10,stop=11,WAIT=12;
wire[3:0] state,next;
wire odd_bit;
reg odd;
wire res;
always @(*)
begin
case(state)
idle: next=in? idle:start;
start:next=s0;
s0:next=s1;
s1:next=s2;
s2:next=s3;
s3:next=s4;
s4:next=s5;
s5:next=s6;
s6:next=s7;
s7:next=s8;
s8:next=in?stop:WAIT;
stop: next=in? idle:start;
WAIT: next=in? idle:WAIT;
endcase
end
always @(posedge clk)
begin
if(reset)
state<=idle;
else
state<=next;
end
assign done=(odd==0&&state==stop);
always@(posedge clk)
begin
case(state)
start:out_byte[0]<=in;
s0:out_byte[1]<=in;
s1:out_byte[2]<=in;
s2:out_byte[3]<=in;
s3:out_byte[4]<=in;
s4:out_byte[5]<=in;
s5:out_byte[6]<=in;
s6:out_byte[7]<=in;
s7: odd_bit<=in;
default: out_byte<=out_byte;
endcase
end
always@(*) //本字节结束,parity才会复位
begin
if(state==idle||state==stop)
res<=1;
else
res<=0;
end
parity u0(clk,res,in,odd);
endmodule
20. Sequence recognition
module top_module(
input clk,
input reset, // Synchronous reset
input in,
output disc,
output flag,
output err);
parameter none=0,s1=1,s2=2,s3=3,s4=4,s5=5,s6=6,discard=7,done=8,error=9,Wait=10;
reg [3:0]state,next;
always@(*)begin
case(state)
none:next=in?s1:none;
s1:next=in?s2:none;
s2:next=in?s3:none;
s3:next=in?s4:none;
s4:next=in?s5:none;
s5:next=in?s6:discard;
s6:next=in?error:done;
discard:next=in?s1:none;
done:next=in?s1:none;
error:next=in?error:none;
endcase
end
always@(posedge clk)begin
if(reset)
state<=none;
else
state<=next;
end
assign flag=(state==done);
assign disc=(state==discard);
assign err=(state==error);
endmodule
21. Design a Mealy
FSM
module top_module (
input clk,
input aresetn, // Asynchronous active-low reset
input x,
output z );
parameter s0=0,s1=1,s2=2;
wire[1:0]state,next;
always@(posedge clk or negedge aresetn)begin
if(!aresetn)
state<=s0;
else
state<=next;
end
always@(*)begin
case(state)
s0:next=x?s1:s0;
s1:next=x?s1:s2;
s2:next=x?s1:s0; //x=1返回s1,可以重叠着继续
default:next=s0;
endcase
end
//输出z,只有完成一个序列的时候z才输出1
always@(*)
begin
case(state)
s0:z=0;
s1:z=0;
s2:z=x;
endcase
end
endmodule
module top_module (
input clk,
input aresetn,
input x,
output reg z
);
// Give state names and assignments. I'm lazy, so I like to use decimal numbers.
// It doesn't really matter what assignment is used, as long as they're unique.
parameter S=0, S1=1, S10=2;
reg[1:0] state, next; // Make sure state and next are big enough to hold the state encodings.
// Edge-triggered always block (DFFs) for state flip-flops. Asynchronous reset.
always@(posedge clk, negedge aresetn)
if (!aresetn)
state <= S;
else
state <= next;
// Combinational always block for state transition logic. Given the current state and inputs,
// what should be next state be?
// Combinational always block: Use blocking assignments.
always@(*) begin
case (state)
S: next = x ? S1 : S;
S1: next = x ? S1 : S10;
S10: next = x ? S1 : S;
default: next = 'x;
endcase
end
// Combinational output logic. I used a combinational always block.
// In a Mealy state machine, the output depends on the current state *and*
// the inputs.
always@(*) begin
case (state)
S: z = 0;
S1: z = 0;
S10: z = x; // This is a Mealy state machine: The output can depend (combinational) on the input.
default: z = 1'bx;
endcase
end
endmodule
22.Q5a:Serial two’s complementer (Moore FSM)
module top_module (
input clk,
input areset,
input x,
output z
);
parameter A=0,B=1,C=2;
wire [1:0]state,next;
always@(posedge clk or posedge areset)
begin
if(areset)
state<=A;
else
state<=next;
end
always @(*)
begin
case(state)
A:next=x?B:A;
C:next=x?C:B;
B:next=x?C:B;
endcase
end
assign z=(state==B);
endmodule
23. Serial two’s complementer (Mealy FSM)
module top_module (
input clk,
input areset,
input x,
output z
);
parameter A=0,B=1;
reg state,next;
always@(posedge clk or posedge areset)begin
if(areset) state<=A;
else state<=next;
end
always@(*)begin
case(state)
A:next=x?B:A;
B:next=x;
endcase
end
assign z=(state==B && ~x)||(state==A && x);
//always@(*)
// begin
// case(state)
// A:z=x;
// B:z=~x;
// endcase
// end
endmodule
24. FSM
module top_module (
input clk,
input reset, // Synchronous reset
input s,
input w,
output z
);
parameter A=1'b0,B=1'b1;
reg state,next;
reg w0,w1;
reg[1:0] counter;
always@(posedge clk)
begin
if(reset)
state<=A;
else
state<=next;
end
always@(*)
begin
case(state)
A:next=s?B:A;
B:next=B;
endcase
end
always@(posedge clk)
begin
if(reset)begin
w0<=1'b0;
w1<=1'b0;
end
else if(state==B)
begin
w0<=w;
w1<=w0;
end
else
begin
w0<=1'b0;
w1<=1'b0;
end
end
always@(posedge clk)
begin
if(reset)
z<=1'b0;
else if((state==B)&&(counter==2'd0))
begin
if(w&w0&~w1|w&~w0&w1|~w&w0&w1)
z<=1'b1;
else
z<=1'b0;
end
else
z<=1'b0;
end
always@(posedge clk)
begin
if(reset)
counter<=2'd0;
else if(counter==2'd2)
counter<=2'd0;
else if(next==B)
counter<=counter+1'b1;
end
endmodule
25. Q3b:FSM
module top_module (
input clk,
input reset, // Synchronous reset
input x,
output z
);
parameter A=3'b000,B=3'b001,C=3'b010,D=3'b011,E=3'b100;
reg [2:0] state,next;
always@(posedge clk)
begin
if(reset)
state<=A;
else
state<=next;
end
always@(*)
begin
case(state)
A:next=x?B:A;
B:next=x?E:B;
C:next=x?B:C;
D:next=x?C:B;
E:next=x?E:D;
endcase
end
assign z=((state==D)||(state==E));
endmodule
26. FSM logic
module top_module (
input clk,
input [2:0] y,
input x,
output Y0,
output z
);
parameter A=3'b000,B=3'b001,C=3'b010,D=3'b011,E=3'b100;
reg [2:0] next;
always@(*)begin
case(y)
A:next=x?B:A;
B:next=x?E:B;
C:next=x?B:C;
D:next=x?C:B;
E:next=x?E:D;
endcase
end
assign Y0=((next==B)||(next==D));
assign z=((y==D)||(y==E));
endmodule
27.Q6b:FSM next-state logic
module top_module (
input [3:1] y,
input w,
output Y2);
parameter A=3'b000,B=3'b001,C=3'b010,D=3'b011,E=3'b100,F=3'b101;
reg [2:0]next;
always@(*)begin
case(y)
A:next=w?A:B;
B:next=w?D:C;
C:next=w?D:E;
D:next=w?A:F;
E:next=w?D:E;
F:next=w?D:C;
endcase
end
assign Y2=((next==D)||(next==C));
//此处为什么不能用当前状态来表示呢?没有显示出输入w的变化要求啊?
endmodule
28.Q6c:FSM one-hot next-state logic
module top_module (
input [6:1] y,
input w,
output Y2,
output Y4);
parameter A=6'b000001,B=6'b000010,C=6'b000100,D=6'b001000,E=6'b010000,F=6'b100000;
reg [5:0]next;
always@(*)begin
case(y)
A:next=w?A:B;
B:next=w?D:C;
C:next=w?D:E;
D:next=w?A:F;
E:next=w?D:E;
F:next=w?D:C;
endcase
end
assign Y2=~w&y[1];
assign Y4=w&(y[2]|y[3]|y[5]|y[6]);
endmodule
29.Q6:FSM
module top_module (
input clk,
input reset, // synchronous reset
input w,
output z);
parameter A=3'b000,B=3'b001,C=3'b010,D=3'b011,E=3'b100,F=3'b101;
reg [2:0]state,next;
always@(posedge clk)
begin
if(reset)
state<=A;
else
state<=next;
end
always@(*)
begin
case(state)
A:next=w?A:B;
B:next=w?D:C;
C:next=w?D:E;
D:next=w?A:F;
E:next=w?D:E;
F:next=w?D:C;
endcase
end
assign z=((state==E)||(state==F));
endmodule
30.Q2a:FSM
module top_module (
input clk,
input reset, // Synchronous active-high reset
input w,
output z
);
parameter A=3'b000,B=3'b001,C=3'b010,D=3'b011,E=3'b100,F=3'b101;
reg [2:0] state,next;
always@(posedge clk)
begin
if(reset)
state<=A;
else
state<=next;
end
always@(*)
begin
case(state)
A:next=w?B:A;
B:next=w?C:D;
C:next=w?E:D;
D:next=w?F:A;
E:next=w?E:D;
F:next=w?C:D;
endcase
end
assign z=((state==E)||(state==F));
endmodule
31.Q2b:one-hot FSM equation
module top_module (
input [5:0] y,
input w,
output Y1,
output Y3
);
assign Y1=w&y[0];
assign Y3=~w&(y[1]|y[2]|y[4]|y[5]);
endmodule
32. Q2a:FSM
module top_module (
input clk,
input resetn, // active-low synchronous reset
input [3:1] r, // request
output [3:1] g // grant
);
parameter A=2'd0,B=2'd1,C=2'd2,D=2'd3;
reg[2:0]state,next;
always@(posedge clk)
begin
if(!resetn)
state<=A;
else
state<=next;
end
always@(*)
begin
case(state)
A:begin
if(r[1])
next=B;
else if(~r[1]&r[2])
next=C;
else if(~r[1]&~r[2]&r[3])
next=D;
else if(~r[1]&~r[2]&~r[3])
next=A;
end
B:next=r[1]?B:A;
C:next=r[2]?C:A;
D:next=r[3]?D:A;
endcase
end
assign g[1]=(state==B);
assign g[2]=(state==C);
assign g[3]=(state==D);
endmodule
33.Q2b:Another FSM
module top_module (
input clk,
input resetn, // active-low synchronous reset
input x,
input y,
output f,
output g
);
parameter IDEL=4'd0,START=4'd1,A=4'd2,B=4'd3,C=4'd4,D=4'd5,E=4'd6,FONE=4'd7,FZERO=4'd8;
reg[3:0]state,next;
always@(posedge clk)
begin
if(!resetn)
state<=IDEL;
else
state<=next;
end
always@(*)
begin
case(state)
IDEL:next=START;
START:next=A;
A:next=x?B:A;
B:next=x?B:C;
C:next=x?D:A;
D:next=y?FONE:E;
E:next=y?FONE:FZERO;
FONE:next=FONE;
FZERO:next=FZERO;
endcase
end
assign f=(state==START);
assign g=((state==D)||(state==E)||(state==FONE));
endmodule