verilog-串口接收与发送模块
1.串口接收
module uart_recv_parity(
input sys_clk,
input sys_rst_n,
input uart_rxd,
output reg uart_done,
output reg frame_error,
output reg parity_error,
output reg [7:0] uart_data
);
parameter CLK_FREQ = 50000000;
parameter UART_BPS = 9600;
parameter PARITY = "ODD";
localparam BPS_CNT = CLK_FREQ/UART_BPS;
localparam BPS_CNT_HALF = BPS_CNT/2;
reg [1:0] uart_rxd_sync;
reg [15:0] clk_cnt;
reg [3:0] rx_cnt;
reg rx_flag;
reg [7:0] rxdata;
reg parity_bit;
reg received_parity;
wire start_flag = (uart_rxd_sync == 2'b10);
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
uart_rxd_sync <= 2'b11;
else
uart_rxd_sync <= {uart_rxd_sync[0], uart_rxd
};
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
rx_flag <= 1'b0;
else if(start_flag)
rx_flag <= 1'b1;
else if((rx_cnt == 4'd9 && PARITY == "NONE") ||
(rx_cnt == 4'd10 && PARITY != "NONE"))
if(clk_cnt == BPS_CNT_HALF)
rx_flag <= 1'b0;
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
clk_cnt <= 16'd0;
rx_cnt <= 4'd0;
end
else if(rx_flag) begin
if(clk_cnt < BPS_CNT - 1)
clk_cnt <= clk_cnt + 1'b1;
else begin
clk_cnt <= 16'd0;
rx_cnt <= rx_cnt + 1'b1;
end
end
else begin
clk_cnt <= 16'd0;
rx_cnt <= 4'd0;
end
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
parity_bit <= 1'b0;
end
else if (rx_flag &&
(rx_cnt == 4'd8) &&
(clk_cnt == BPS_CNT_HALF)) begin
if (PARITY == "ODD")
parity_bit <= ^rxdata;
else if (PARITY == "EVEN")
parity_bit <= ~^rxdata;
end
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
received_parity <= 1'b0;
end
else if (rx_flag &&
(rx_cnt == 4'd9) &&
(clk_cnt == BPS_CNT_HALF) begin
received_parity <= uart_rxd_sync[1];
end
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
rxdata <= 8'd0;
else if(rx_flag &&
(clk_cnt == BPS_CNT_HALF)) begin
case(rx_cnt)
4'd1: rxdata[0] <= uart_rxd_sync[1];
4'd2: rxdata[1] <= uart_rxd_sync[1];
4'd3: rxdata[2] <= uart_rxd_sync[1];
4'd4: rxdata[3] <= uart_rxd_sync[1];
4'd5: rxdata[4] <= uart_rxd_sync[1];
4'd6: rxdata[5] <= uart_rxd_sync[1];
4'd7: rxdata[6] <= uart_rxd_sync[1];
4'd8: rxdata[7] <= uart_rxd_sync[1];
default: rxdata <= rxdata;
endcase
end
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n) begin
uart_data <= 8'd0;
uart_done <= 1'b0;
frame_error <= 1'b0;
parity_error <= 1'b0;
end
else if(((rx_cnt == 4'd9) &&
(PARITY == "NONE")) ||
((rx_cnt == 4'd10) &&
(PARITY != "NONE"))) begin
if(clk_cnt == BPS_CNT_HALF) begin
uart_data <= rxdata;
uart_done <= 1'b1;
if(PARITY == "NONE")
frame_error <= ~uart_rxd_sync[1];
else
frame_error <= ~uart_rxd_sync[1];
if(PARITY != "NONE")
parity_error <= (received_parity != parity_bit);
else
parity_error <= 1'b0;
end
end
else begin
uart_done <= 1'b0;
end
end
endmodule
2.串口发送
在这里插入代码片