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 beginclk_cnt <= 16'd0;rx_cnt <= rx_cnt + 1'b1;endendelse begin clk_cnt <= 16'd0;rx_cnt <= 4'd0;end
end
always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n) beginparity_bit <= 1'b0;endelse if (rx_flag && (rx_cnt == 4'd8) && (clk_cnt == BPS_CNT_HALF)) beginif (PARITY == "ODD")parity_bit <= ^rxdata; else if (PARITY == "EVEN")parity_bit <= ~^rxdata; end
end
always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n) beginreceived_parity <= 1'b0;endelse if (rx_flag && (rx_cnt == 4'd9) && (clk_cnt == BPS_CNT_HALF) beginreceived_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)) begincase(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;endcaseend
end
always @(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) beginuart_data <= 8'd0; uart_done <= 1'b0;frame_error <= 1'b0;parity_error <= 1'b0;endelse if(((rx_cnt == 4'd9) && (PARITY == "NONE")) || ((rx_cnt == 4'd10) && (PARITY != "NONE"))) beginif(clk_cnt == BPS_CNT_HALF) beginuart_data <= rxdata; uart_done <= 1'b1; if(PARITY == "NONE")frame_error <= ~uart_rxd_sync[1]; elseframe_error <= ~uart_rxd_sync[1]; if(PARITY != "NONE")parity_error <= (received_parity != parity_bit);elseparity_error <= 1'b0;endendelse beginuart_done <= 1'b0; end
endendmodule
2.串口发送
在这里插入代码片