From 21a79e6f3fa887cc4268695f2dbb387b7040a78c Mon Sep 17 00:00:00 2001 From: yunlongLi <1203701249@qq.com> Date: Tue, 5 Nov 2024 15:39:53 +0800 Subject: [PATCH] add uart.v --- protocol/READ.md | 11 +- protocol/uart.v | 260 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+), 2 deletions(-) create mode 100644 protocol/uart.v diff --git a/protocol/READ.md b/protocol/READ.md index 4875ad0..05d80a7 100644 --- a/protocol/READ.md +++ b/protocol/READ.md @@ -1,2 +1,9 @@ -# TODO test the git config -# second test \ No newline at end of file + +Peripheral interface is pushed here to do it. + +# 1 UART + +# 2 SPI + +# 3 I2C + diff --git a/protocol/uart.v b/protocol/uart.v new file mode 100644 index 0000000..0a49373 --- /dev/null +++ b/protocol/uart.v @@ -0,0 +1,260 @@ +//========================================================== +//--Author : colonel +//--Date : 11-05 +//--Module : uart_send +//--Function: uart is diviede into uart_send,uart_reciver +//========================================================== +module uart_send( +//==========================< 端口 >========================= + input clk, + input rst_n, + input tx_en, + input [8 -1:0] tx_din, + + output reg uart_txd +); +//==========================< 参数 >========================= +localparam BAUD_RATE = 9600; +localparam CLK_FREQ = 50000000; +localparam BAUD_PERIOD = CLK_FREQ / BAUD_RATE; + +//==========================< 信号 >========================= +reg tx_en_sync0; +reg tx_en_sync1; + +//========================================================= +//-- tx_en_sync0/1 +//========================================================= +always @(posedge clk or rst_n) begin + if (!rst_n) begin + tx_en_sync0 <= 1'b0; + tx_en_sync1 <= 1'b0; + end else begin + tx_en_sync0 <= tx_en; + tx_en_sync1 <= tx_en_sync0; + end +end + +wire start_flag = tx_en_sync0 && !tx_en_sync1; //pos pulse + +//==========================< 信号 >========================= +reg [16 -1:0] bps_cnt; +reg [4 -1:0] tx_cnt; + +//========================================================= +//-- bps_cnt, tx_cnt: +//========================================================= +always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + bps_cnt <= 'b0; + end else begin + if (bps_cnt < BAUD_PERIOD -1) begin + bps_cnt <= bps_cnt + 1'b1; + end else begin + bps_cnt <= 'b0; + end + end +end + +always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + tx_cnt <= 'b0; + end else begin + if (bps_cnt==BAUD_PERIOD-1) begin + tx_cnt <= tx_cnt + 1'b1; + end else if(start_flag)begin + tx_cnt <= 1'b0; + end else begin + tx_cnt <= tx_cnt; + end + end +end + + +//==========================< 信号 >========================= +reg tx_flag; +reg [8 -1:0] tx_data; //floped for uart_din + +//========================================================= +//-- tx_flag,tx_data +//========================================================= +always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + tx_data <= 'd0; + end else begin + if (start_flag) begin + tx_data <= tx_din; + end else if (tx_cnt==4'd9) begin + tx_data <= 0; + end else begin + tx_data <= tx_data; + end + end +end + +always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + tx_flag <= 1'b0; + end else begin + if (start_flag) begin + tx_flag <= 1'b1; + end else if(tx_cnt==4'd9 && (bps_cnt==BAUD_PERIOD/2)) begin + tx_flag <= 1'b0; + end else begin + tx_flag <= tx_flag; + end + end +end + +//========================================================= +//-- uart_txd +//========================================================= + +always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + uart_txd <= 1'b1; + end else begin + if (tx_flag) begin + case (tx_cnt) + 4'd0: uart_txd <= 1'b0; + 4'd1: uart_txd <= tx_data[0]; + 4'd2: uart_txd <= tx_data[1]; + 4'd3: uart_txd <= tx_data[2]; + 4'd4: uart_txd <= tx_data[3]; + 4'd5: uart_txd <= tx_data[4]; + 4'd6: uart_txd <= tx_data[5]; + 4'd7: uart_txd <= tx_data[6]; + 4'd8: uart_txd <= tx_data[7]; + 4'd9: uart_txd <= 1'b1; + default: uart_txd <= 1'b1; + endcase + end else begin + uart_txd <= 1'b1; + end + end +end + + +endmodule + + +//========================================================== +//--Author : colonel +//--Date : 11-05 +//--Module : uart_reci +//--Function: uart is diviede into uart_send,uart_reciver +//========================================================== +module uart_reciver ( +//==========================< 端口 >========================= + input clk, + input rst_n, + input uart_rxd, + + output [8 -1:0] uart_txd, + output rx_done +); +//==========================< 参数 >========================= +localparam BAUD_RATE = 9600; +localparam CLK_FREQ = 50000000; +localparam BAUD_PERIOD = CLK_FREQ / BAUD_RATE; + +//==========================< 信号 >========================= +reg uart_rxd_r1; +reg uart_rxd_r2; + +//========================================================= +//-- uart_rxd_r1/2 +//========================================================= +always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + uart_rxd_r1 <= 1'b0; + uart_rxd_r2 <= 1'b0; + end else begin + uart_rxd_r1 <= uart_rxd; + uart_rxd_r2 <= uart_rxd_r1; + end +end + +wire start_flag_neg = uart_rxd_r2 && !uart_rxd_r1; + +//==========================< 信号 >========================= +reg [16 -1:0] bps_cnt; +reg [4 -1:0] rx_cnt; + +//========================================================= +//-- bps_cnt, rx_cnt: +//========================================================= +always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + bps_cnt <= 'b0; + end else begin + if (bps_cnt < BAUD_PERIOD -1) begin + bps_cnt <= bps_cnt + 1'b1; + end else begin + bps_cnt <= 'b0; + end + end +end + +always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + rx_cnt <= 'b0; + end else begin + if (bps_cnt==BAUD_PERIOD-1) begin + rx_cnt <= rx_cnt + 1'b1; + end else if(start_flag_neg) begin + rx_cnt <= 1'b0; + end else begin + rx_cnt <= rx_cnt; + end + end +end + +//==========================< 信号 >========================= +reg rx_flag; + +//========================================================= +//-- rx_flag +//========================================================= +always @(posedge clk or rst_n) begin + if (!rst_n) begin + rx_flag <= 1'b0; + end else begin + if (start_flag_neg) begin + rx_flag <= 1'b1; + end else if (rx_cnt==4'd9 && (bps_cnt==BAUD_PERIOD/2)) begin + rx_flag <= 1'b0; + end else begin + rx_flag <= rx_flag; + end + end +end + +//==========================< 信号 >========================= +reg [8 -1:0] uart_txd_r; +//========================================================= +//-- uart_txd_r +//========================================================= +always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + uart_txd_r <= 8'b0; + end else begin + if (rx_flag && bps_cnt==BAUD_PERIOD/2) begin + case (rx_cnt) + 4'd1: uart_txd_r[0] <= uart_rxd_r1; + 4'd2: uart_txd_r[1] <= uart_rxd_r1; + 4'd3: uart_txd_r[2] <= uart_rxd_r1; + 4'd4: uart_txd_r[3] <= uart_rxd_r1; + 4'd5: uart_txd_r[4] <= uart_rxd_r1; + 4'd6: uart_txd_r[5] <= uart_rxd_r1; + 4'd7: uart_txd_r[6] <= uart_rxd_r1; + 4'd8: uart_txd_r[7] <= uart_rxd_r1; + default: ; + endcase + end else begin + uart_txd_r <= uart_txd_r; + end + end +end + +endmodule \ No newline at end of file