串行数据接收
数据的发送按照特定的规则发送,因此接收也要按照发送的规则进行接收,从而完成数据的接收。
奇偶检验是每个字节后额为加一位 进行奇偶校验,使用奇校验位,接收的9位数据1的个数为奇数,如111000110有5个1,满足奇校验位的传输方式。
数据接收器满足这些条件:接收开始标志位、数据位、奇偶检验位、停止位,数 据是串行输入并行输出。
数据接收满足下列的时序条件(实现奇校验)
奇校验实现模块:
//主模块的子模块
module parity (
input clk,
input reset,
input in,
output reg odd);
always @(posedge clk)
if (reset) odd <= 0;
else if (in) odd <= ~odd;
endmodule
状态机实现带奇校验的接收器
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
reg[7:0] out_reg;
reg[2:0] state,next_state;
parameter idle = 1'b0,r_flag = 1'b1,rx_data = 2'd2,end_data=2'd3,wait_s=3'd4;
reg[3:0]cnt;
always@(posedge clk) begin
if(reset)begin
state <= idle;
cnt <= 3'b0;
end
else if(next_state==rx_data)begin
state <= next_state;
cnt <= cnt + 1'b1;
end
else begin
state <= next_state;
cnt <= 4'b0;
end
end
always@(*)begin
case(state)
idle:begin
next_state = in ? idle : r_flag;
end
r_flag:begin
next_state = rx_data;
end
rx_data:begin
next_state = (cnt==4'd9) ? (in ? (odd_c? end_data:idle): wait_s) : rx_data;
end
wait_s:begin
next_state = in ? idle : wait_s;
end
end_data:begin
next_state = in ? idle : r_flag;
end
endcase
end
always@(posedge clk)begin
if(next_state==rx_data)begin
if(cnt<4'd8)begin
out_reg[cnt] <= in;
end
else begin
out_reg <= out_reg;
end
end
end
assign done = (state==end_data) ? 1'b1:1'b0;
assign out_byte = (state==end_data) ? out_reg : out_byte;
assign reset_c = (next_state== rx_data) ? 1'b0 :1'b1;
assign in_w = (next_state== rx_data) ? in :1'b0;
wire odd_c;
wire reset_c;
wire in_w;
parity parity11(
.clk(clk),
.reset(reset_c),
.in(in_w),
.odd(odd_c)
);
endmodule
其中最关键的是状态rx_data 需要判断数据位,同时,根据奇偶校验位和停止位的判断数据是否有效。即 当完成数据位和奇校验位(开始位后9位)完成后,下一位为停止位,当有效时(即为1),同时奇偶校验模块的返回值为奇数(即为1)时,接收到的数据才有效。当停止位为无效(即为0)时,只有检测到停止有效位(即1)才开始下一个字节的接收检测。
练习
HDLbits—有限状态机奇偶校验