📄 rxcver.v
字号:
rx_frame_err <= 1'b0;
cs_state <= idle;
counter <= 16'b0000_0000_0000_0000;
end
else case (cs_state)
idle: begin
if ((sin_d0 == 1'b0) && (sin_d0_delay == 1'b1)) begin
cs_state <= idle1;
end
counter <= divisor - 1'b1;
end
idle1: begin
if (counter == divisor_2) begin
if (sin_d0 == 1'b1)
cs_state <= idle;
else begin
rsr <= 0;
databit_recved_num <= 4'h0;
rx_parity_err <= ~ parity_even;
rx_frame_err <= 1'b0;
end
end
if (counter == 16'b0000_0000_0000_0001) begin
cs_state <= shift;
counter <= divisor;
end
else
counter <= counter - 1'b1;
end
shift: begin
if (counter == divisor_2) begin
rsr <= {sin_d0, rsr[7:1]};
rx_parity_err <= rx_parity_err ^ sin_d0;
databit_recved_num <= databit_recved_num + 1;
end
if (counter == 16'b0000_0000_0000_0001) begin
if ((databits==2'b00 && databit_recved_num == 4'h5) ||
(databits==2'b01 && databit_recved_num == 4'h6) ||
(databits==2'b10 && databit_recved_num == 4'h7) ||
(databits==2'b11 && databit_recved_num == 4'h8))
if (parity_en == 1'b0)
cs_state <= stop;
else
cs_state <= parity;
counter <= divisor;
end
else
counter <= counter - 1'b1;
end
parity: begin
if (counter == divisor_2) begin
if (parity_stick == 1'b0)
rx_parity_err <= rx_parity_err ^ sin_d0;
else
if (parity_even == 1'b0)
rx_parity_err <= ~sin_d0;
else
rx_parity_err <= sin_d0;
end
if (counter == 16'b0000_0000_0000_0001) begin
cs_state <= stop;
counter <= divisor;
end
else
counter <= counter - 1'b1;
end
stop: begin
if (counter == divisor_2) begin
// The Receiver checks the 1st Stopbit only regardless of the number
// of Stop bits selected.
// Stop bit needs to be '1', otherwise it's a Framing error
rx_frame_err <= ~sin_d0;
cs_state <= idle;
end
counter <= counter - 1'b1;
end
default:
cs_state <= idle;
endcase
end
////////////////////////////////////////////////////////////////////////////////
// Receiver Buffer Register
////////////////////////////////////////////////////////////////////////////////
generate
if (FIFO == 1) begin
always @(posedge clk or posedge reset) begin
if (reset) begin
fifo_din <= 0;
fifo_wr <= 0; end
else if ((rx_idle == 1'b1) && (rx_idle_d1 == 1'b0)) begin
if (break_int_int)
begin
fifo_din <= {8'b0, 3'b100};
fifo_wr <= 1'b1;
end
else begin
case (databits)
2'b00: fifo_din <= { 3'b000, rsr[7:3], 1'b0, parity_err_int, frame_err_int};
2'b01: fifo_din <= { 2'b00 , rsr[7:2], 1'b0, parity_err_int, frame_err_int};
2'b10: fifo_din <= { 1'b0 , rsr[7:1], 1'b0, parity_err_int, frame_err_int};
default: fifo_din <= {rsr, 1'b0, parity_err_int, frame_err_int};
endcase
fifo_wr <= 1'b1; end
end
else
fifo_wr <= 1'b0;
end
always @(posedge clk or posedge reset)
if (reset)
fifo_wr_q <= 0;
else
fifo_wr_q <= fifo_wr;
assign fifo_wr_pulse = fifo_wr & ~fifo_wr_q;
rxcver_fifo RX_FIFO(
.Data (fifo_din),
.Clock (clk),
.WrEn (fifo_wr_pulse),
.RdEn (rbr_rd),
.Reset (reset),
.Q (rbr_fifo),
.Q_error (rbr_fifo_error),
.Empty (fifo_empty),
.Full (fifo_full),
.AlmostEmpty (fifo_almost_empty),
.AlmostFull (fifo_almost_full));
end
else begin
always @(posedge clk or posedge reset) begin
if (reset)
rbr <= 0;
else if ((rx_idle == 1'b1) && (rx_idle_d1 == 1'b0))
case (databits)
2'b00: rbr <= { 3'b000, rsr[7:3]};
2'b01: rbr <= { 2'b00 , rsr[7:2]};
2'b10: rbr <= { 1'b0 , rsr[7:1]};
default: rbr <= rsr;
endcase
end
end
endgenerate
////////////////////////////////////////////////////////////////////////////////
// Delayed Signals for edge detections
////////////////////////////////////////////////////////////////////////////////
always @(posedge clk or posedge reset) begin
if (reset) begin
sin_d0 <= 1'b0;
sin_d0_delay <= 1'b0;
end
else begin
// sin_d0 : Signal for rising edge detection of signal sin
// must be registered before using with sin_d1,
// since sin is ASYNCHRONOUS!!! to the system clock
sin_d0 <= sin;
sin_d0_delay <= sin_d0;
end
end
always @(posedge clk or posedge reset) begin
if (reset) begin
sin_d1 <= 1'b0;
rx_frame_err_d1 <= 1'b1;
end
else begin
//sin_d1 : Signal for falling edge detection of signal SIN
sin_d1 <= sin_d0;
// rx_frame_err_d1 :
// a delayed version of rx_frame_err for detacting the rising edge
// used to resynchronize the next frame after framing error
rx_frame_err_d1 <= rx_frame_err;
end
end
always @(posedge clk or posedge reset) begin
if (reset) begin
rx_idle_d1 <= 1'b1;
end
else begin
// rx_idle_d1 : Signal for rising edge detection of signal rx_idle
rx_idle_d1 <= rx_idle;
end
end
////////////////////////////////////////////////////////////////////////////////
// Generate Error Flags
////////////////////////////////////////////////////////////////////////////////
// Receiver Error Flags in lsr
// overrun_err(OE), parity_err(PE), frame_err(FE), break_int(BI)
// will be set to reflect the sin line status only after the whole frame
// (Start bit + Data bits + Parity bit + Stop bit) is received. A rising
// edge of rx_idle indicates the whole frame is received.
generate
if (FIFO == 1) begin
always @(posedge clk or posedge reset) begin
if (reset) begin
parity_err_int <= 1'b0;
frame_err_int <= 1'b0;
break_int_int <= 1'b0;
end
else begin
// Set parity_err flag if rx_parity_err is 1 when Parity enable
parity_err_int <= (rx_parity_err) & parity_en;
// Set frame_err flag if rx_frame_err is 1(Stop bit is sampled low)
frame_err_int <= rx_frame_err;
// Set break_int flag if hunt_one is still low
break_int_int <= (~ hunt_one);
end
end
always @(posedge clk or posedge reset)
if (reset)
overrun_err_int <= 1'b0;
else if (fifo_full && fifo_wr)
overrun_err_int <= 1'b1;
else if (lsr_rd)
overrun_err_int <= 1'b0;
assign overrun_err = overrun_err_int;
assign parity_err = rbr_fifo_error[1];
assign frame_err = rbr_fifo_error[0];
assign break_int = rbr_fifo_error[2];
// Receiver ready for read when data is available in rbr
assign rx_rdy = rbr_datardy;
end
else begin
always @(posedge clk or posedge reset) begin
if (reset) begin
overrun_err_int <= 1'b0;
parity_err_int <= 1'b0;
frame_err_int <= 1'b0;
break_int_int <= 1'b0;
end
else if (rx_idle && !rx_idle_d1) begin // update at rxidle rising
// Set overrun_err flag if RBR data is still not read by CPU
overrun_err_int <= rbr_datardy;
// Set parity_err flag if rx_parity_err is 1 when Parity enable
parity_err_int <= (parity_err_int | rx_parity_err) & parity_en;
// Set frame_err flag if rx_frame_err is 1(Stop bit is sampled low)
frame_err_int <= frame_err_int | rx_frame_err;
// Set break_int flag if hunt_one is still low
break_int_int <= break_int_int | (~ hunt_one);
end
else if (lsr_rd) begin // clear when LSR is read
parity_err_int <= 1'b0;
frame_err_int <= 1'b0;
overrun_err_int <= 1'b0;
break_int_int <= 1'b0;
end
end
assign overrun_err = overrun_err_int;
assign parity_err = parity_err_int;
assign frame_err = frame_err_int;
assign break_int = break_int_int;
// Receiver ready for read when data is available in rbr
assign rx_rdy = rbr_datardy;
end
//`endif
endgenerate
endmodule
`endif // RXCVER_FILE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -