module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
// Use FSM from Fsm_serial
// New: Datapath to latch input bits.
parameter IDLE = 13'b0000000000001;
parameter START = 13'b0000000000010;
parameter B0 = 13'b0000000000100;
parameter B1 = 13'b0000000001000;
parameter B2 = 13'b0000000010000;
parameter B3 = 13'b0000000100000;
parameter B4 = 13'b0000001000000;
parameter B5 = 13'b0000010000000;
parameter B6 = 13'b0000100000000;
parameter B7 = 13'b0001000000000;
parameter STOP = 13'b0010000000000;
parameter END = 13'b0100000000000;
parameter ERROR = 13'b1000000000000;
reg [12:0] state, next;
//ff
always @(posedge clk) begin
if(reset)
state = START;
else
state = next;
end
// trans
always @(*) begin
next = START;
case(state)
START:begin
if(in == 0)
next = B7;
else
next = START;
end
B7:begin
next = B6;
end
B6:begin
next = B5;
end
B5:begin
next = B4;
end
B4:begin
next = B3;
end
B3:begin
next = B2;
end
B2:begin
next = B1;
end
B1:begin
next = B0;
end
B0:begin
next = STOP;
end
STOP:begin
if(in == 1)
next = END;
else
next = ERROR;
end
ERROR:
if(in == 1)
next = START;
else
next = ERROR;
END:
if(in == 0)
next = B7;
else
next = START;
default:begin
next = START;
end
endcase
end
//out
assign done = (state == END)? 1: 0;
always @(negedge clk) begin
case (state)
B7:
out_byte[7] = in;
B6:
out_byte[6] = in;
B5:
out_byte[5] = in;
B4:
out_byte[4] = in;
B3:
out_byte[3] = in;
B2:
out_byte[2] = in;
B1:
out_byte[1] = in;
B0:
out_byte[0] = in;
default:
out_byte = out_byte;
endcase
end
endmodule
题目故意在clk下降沿放了一次in的改变, 我是下降沿锁存, 所以错了
改成上升沿
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
);
// Use FSM from Fsm_serial
// New: Datapath to latch input bits.
parameter IDLE = 13'b0000000000001;
parameter START = 13'b0000000000010;
parameter B0 = 13'b0000000000100;
parameter B1 = 13'b0000000001000;
parameter B2 = 13'b0000000010000;
parameter B3 = 13'b0000000100000;
parameter B4 = 13'b0000001000000;
parameter B5 = 13'b0000010000000;
parameter B6 = 13'b0000100000000;
parameter B7 = 13'b0001000000000;
parameter STOP = 13'b0010000000000;
parameter END = 13'b0100000000000;
parameter ERROR = 13'b1000000000000;
reg [12:0] state, next;
//ff
always @(posedge clk) begin
if(reset)
state = START;
else
state = next;
end
// trans
always @(*) begin
next = START;
case(state)
START:begin
if(in == 0)
next = B7;
else
next = START;
end
B7:begin
next = B6;
end
B6:begin
next = B5;
end
B5:begin
next = B4;
end
B4:begin
next = B3;
end
B3:begin
next = B2;
end
B2:begin
next = B1;
end
B1:begin
next = B0;
end
B0:begin
next = STOP;
end
STOP:begin
if(in == 1)
next = END;
else
next = ERROR;
end
ERROR:
if(in == 1)
next = START;
else
next = ERROR;
END:
if(in == 0)
next = B7;
else
next = START;
default:begin
next = START;
end
endcase
end
//out
assign done = (state == END)? 1'b1: 1'b0;
always @(posedge clk) begin
case (state)
START:
out_byte = 8'b0;
B7:
out_byte[7] = in;
B6:
out_byte[6] = in;
B5:
out_byte[5] = in;
B4:
out_byte[4] = in;
B3:
out_byte[3] = in;
B2:
out_byte[2] = in;
B1:
out_byte[1] = in;
B0:
out_byte[0] = in;
default:
out_byte = out_byte;
endcase
end
endmodule
修改位顺序, 验证OK了, 但是感觉很奇怪
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
);
// Use FSM from Fsm_serial
// New: Datapath to latch input bits.
parameter IDLE = 13'b0000000000001;
parameter START = 13'b0000000000010;
parameter B0 = 13'b0000000000100;
parameter B1 = 13'b0000000001000;
parameter B2 = 13'b0000000010000;
parameter B3 = 13'b0000000100000;
parameter B4 = 13'b0000001000000;
parameter B5 = 13'b0000010000000;
parameter B6 = 13'b0000100000000;
parameter B7 = 13'b0001000000000;
parameter STOP = 13'b0010000000000;
parameter END = 13'b0100000000000;
parameter ERROR = 13'b1000000000000;
reg [12:0] state, next;
//ff
always @(posedge clk) begin
if(reset)
state = START;
else
state = next;
end
// trans
always @(*) begin
next = START;
case(state)
START:begin
if(in == 0)
next = B0;
else
next = START;
end
B0:begin
next = B1;
end
B1:begin
next = B2;
end
B2:begin
next = B3;
end
B3:begin
next = B4;
end
B4:begin
next = B5;
end
B5:begin
next = B6;
end
B6:begin
next = B7;
end
B7:begin
next = STOP;
end
STOP:begin
if(in == 1)
next = END;
else
next = ERROR;
end
ERROR:
if(in == 1)
next = START;
else
next = ERROR;
END:
if(in == 0)
next = B0;
else
next = START;
default:begin
next = START;
end
endcase
end
//out
assign done = (state == END)? 1'b1: 1'b0;
always @(posedge clk) begin
case (state)
START:
out_byte = 8'b0;
B7:
out_byte[7] = in;
B6:
out_byte[6] = in;
B5:
out_byte[5] = in;
B4:
out_byte[4] = in;
B3:
out_byte[3] = in;
B2:
out_byte[2] = in;
B1:
out_byte[1] = in;
B0:
out_byte[0] = in;
default:
out_byte = out_byte;
endcase
end
endmodule
更新:对bit计数减少状态
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
);
// Use FSM from Fsm_serial
// New: Datapath to latch input bits.
parameter START = 5'b00001;
parameter RECV = 5'b00010;
parameter STOP = 5'b00100;
parameter END = 5'b01000;
parameter ERROR = 5'b10000;
reg [4:0] state, next;
//ff
always @(posedge clk) begin
if(reset)
state = START;
else
state = next;
end
integer cnt;
// trans
always @(*) begin
next = START;
case(state)
START:begin
if(in == 0)
next = RECV;
else
next = START;
end
RECV: begin
if(cnt == 7)
next = STOP;
else
next = RECV;
end
STOP:begin
if(in == 1)
next = END;
else
next = ERROR;
end
ERROR:
if(in == 1)
next = START;
else
next = ERROR;
END:
if(in == 0)
next = RECV;
else
next = START;
default:begin
next = START;
end
endcase
end
always @(posedge clk) begin
if(reset)
cnt = 0;
else begin
if((state == START) || (state == END))
cnt = 0;
else
cnt = cnt+1;
end
end
//out
assign done = (state == END)? 1'b1: 1'b0;
always @(posedge clk) begin
case (state)
START:
out_byte = 8'b0;
RECV:
case(cnt)
0:
out_byte[0]=in;
1:
out_byte[1]=in;
2:
out_byte[2]=in;
3:
out_byte[3]=in;
4:
out_byte[4]=in;
5:
out_byte[5]=in;
6:
out_byte[6]=in;
7:
out_byte[7]=in;
endcase
default:
out_byte = out_byte;
endcase
end
endmodule
验证成功,但是有个warrning
修改:完美了
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
);
// Use FSM from Fsm_serial
// New: Datapath to latch input bits.
parameter START = 5'b00001;
parameter RECV = 5'b00010;
parameter STOP = 5'b00100;
parameter END = 5'b01000;
parameter ERROR = 5'b10000;
reg [4:0] state, next;
//ff
always @(posedge clk) begin
if(reset)
state = START;
else
state = next;
end
integer cnt;
// trans
always @(*) begin
next = START;
case(state)
START:begin
if(in == 0)
next = RECV;
else
next = START;
end
RECV: begin
if(cnt == 7)
next = STOP;
else
next = RECV;
end
STOP:begin
if(in == 1)
next = END;
else
next = ERROR;
end
ERROR:
if(in == 1)
next = START;
else
next = ERROR;
END:
if(in == 0)
next = RECV;
else
next = START;
default:begin
next = START;
end
endcase
end
always @(posedge clk) begin
if(reset)
cnt = 0;
else begin
if((state == START) || (state == END))
cnt = 0;
else
cnt = cnt+1;
end
end
//out
assign done = (state == END)? 1'b1: 1'b0;
always @(posedge clk) begin
case (state)
START:
out_byte = 8'b0;
RECV:
out_byte[cnt] = in;
default:
out_byte = out_byte;
endcase
end
endmodule