1、这个题其实思路还是挺清楚的,就是在八个数据位后面又加了一个奇偶校验位。校验停止位之前的1的个数(奇偶校验位本身也包含在内),由于停止位本身就会有一个1所以要跟odd的取反进行想与(我写的逻辑是只要到了停止位就会输出,所以要在这之前判断能不能到停止状态位,到了之后在判断奇偶校验位)
2、这个题困扰了很久主要是有个地方写错了,复制的时候没注意看 停止位那里如果正常停止下一步是可以直接到下一个的开始状态的。
3、这个题可以看出奇偶校验位本身也是包含在奇偶校验里面了(4b是偶数个1,加上奇偶校验位才是奇数个 ),停止位又有一个1所以是6个1了所以done输出那里要跟odd取反再相与。
下图是没有取反与的
完整代码如下:
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
parameter START=0,B=1,C=2,D=3,E=4,F=5,G=6,H=7,I=8,stop=9,wate=10,dile=11;//十一种状态
parameter Jiao=12;
reg[3:0]state,next_state;
reg odd;
always@(*)begin
case(state)
START:next_state=B;//开始位下一个就是数据1
B:next_state=C;//数据1->数据2
C:next_state=D;//数据2
D:next_state=E;//数据3
E:next_state=F;//数据4
F:next_state=G;//数据5
G:next_state=H;//数据6
H:next_state=I;//数据7
I:next_state=Jiao;//数据8
Jiao:next_state=in?stop:wate;//
stop:next_state=(in)?dile:START;//停止位1正常停止0就是不正常代表丢数据
wate:next_state=(in)?dile:wate;//如果被拉低就是进入了开始状态
dile:next_state=(in)?dile:START;
default next_state=wate;
endcase
end
always@(posedge clk)begin
if(reset)
state<=dile;
else begin
state<=next_state;
end
end
assign done=((state==stop)&&!odd)?1:0;//如果是stop位in肯定会发一个1的,如果odd本来是奇数个的话就会变成偶数个
always@(*)begin
if(state==START) //总是会延后一个状态,当前虽然是显示start其实已经发了数据1了。就像跑步时的起跑指令一样一喊开始立马就出去了
out_byte[0]=in;
else if(state==B)
out_byte[1]=in;
else if(state==C)
out_byte[2]=in;
else if(state==D)
out_byte[3]=in;
else if(state==E)
out_byte[4]=in;
else if(state==F)
out_byte[5]=in;
else if(state==G)
out_byte[6]=in;
else if(state==H) begin
out_byte[7]=in;
end
end
// Modify FSM and datapath from Fsm_serialdata
parity parity_u(.clk(clk),.reset(reset|| next_state == dile || next_state == START),.in(in),.odd(odd));
// New: Add parity checking.
endmodule