以下是串口發送部分
module xiaoze_tx(
input clk,
input rst_n,
input send_en,
input [3:0] bps_set,
input [7:0] data_in,
output reg tx_done,
output reg data_out,
output reg tx_state,
//************************測試******************
output reg bps_clk,
output reg [3:0] shift
);
//************************************
reg bps_clk;
reg [3:0] shift;
reg [15:0] bps;
reg [15:0] bps_cnt;
reg [7:0] data_in_a;
reg [7:0] data_in_b;
//************************************
always@(posedge clk or negedge rst_n)
if(!rst_n) bps <= 16'd 5207; //默認值為9600
else begin
case(bps_set)
4'd 0 : bps <= 16'd 5207; //9600
4'd 1 : bps <= 16'd 2603; //19200
4'd 2 : bps <= 16'd 1301; //38400
4'd 3 : bps <= 16'd 867; //57600
4'd 4 : bps <= 16'd 433; //115200
default : bps <= 16'd 5207; //默認值為9600
endcase
end
//******************************************
always@(posedge clk or negedge rst_n)
if(!rst_n) bps_cnt <= 16'd 0;
else if(tx_state == 1'b 1) bps_cnt <= (bps_cnt == bps)? 16'd 0 : bps_cnt + 1'd 1;
else bps_cnt <= 16'd 0;
//*******************************************
always@(posedge clk or negedge rst_n)
if(!rst_n) bps_clk <= 1'b 0;
else if(bps_cnt == 16'd 1) bps_clk <= 1'b 1;
else bps_clk = 1'b 0;
//*******************************************
always@(posedge clk or negedge rst_n)
if(!rst_n) shift <= 4'd 0;
else if(tx_done == 1'b 1) shift <= 4'd 0;
else if(bps_clk == 1'b 1) shift <= shift + 1'd 1;
else shift <= shift;
//*******************************************
always@(posedge clk or negedge rst_n)
if(!rst_n) begin
data_in_a <= 8'b 0;
data_in_b <= 8'b 0;
end
else begin
data_in_a <= data_in;
data_in_b <= data_in_a;
end
//*********************************************
always@(posedge clk or negedge rst_n)
if(!rst_n) data_out <= 1'b 1; //rx默認為高電平
else begin
case(shift)
4'd 0 : data_out <= 1'b 1;//默認值
4'd 1 : data_out <= 1'b 0; //起始位
4'd 2 : data_out <= data_in_b[0];
4'd 3 : data_out <= data_in_b[1];
4'd 4 : data_out <= data_in_b[2];
4'd 5 : data_out <= data_in_b[3];
4'd 6 : data_out <= data_in_b[4];
4'd 7 : data_out <= data_in_b[5];
4'd 8 : data_out <= data_in_b[6];
4'd 9 : data_out <= data_in_b[7];
4'd 10 : data_out <= 1'b 1;//停止位
4'd 11 : data_out <= 1'b 1;//默認值
default : data_out <= 1'b 1;//默認值
endcase
end
//*********************************************
always@(posedge clk or negedge rst_n)
if(!rst_n) tx_done <= 1'b 0;
else if(shift == 4'd 11) tx_done <= 1'b 1;
else tx_done <= 1'b 0;
//**********************************************
always@(posedge clk or negedge rst_n)
if(!rst_n) tx_state <= 1'b 0;
else if(send_en == 1'b 1) tx_state <= 1'b 1;
else if(tx_done == 1'b 1) tx_state <= 1'b 0;
else tx_state <= tx_state;
endmodule
//以下是串口接收部分
module xiaoze_rx(
input clk,
input rst_n,
input data_in,
input [2:0] bps,
output reg rx_stop,
output reg rx_state,
output reg [7:0] data_out
);
//**********************數據定義區**************************
reg [8:0] bps_set;
reg data_a;
reg data_b;
reg data_c;
reg data_d;
wire nedge;
reg [8:0] cnt;
reg bps_clk;
reg [7:0] shift;
reg [2:0] data_read [7:0];
reg [2:0] data_start;
reg [2:0] data_stop;
reg start_n;
//*********************************************************
//波特率設置模塊
always@(posedge clk or negedge rst_n)
if(!rst_n) bps_set <= 9'd 324;
else begin
case(bps)
3'd 0 : bps_set<= 9'd 324; //9600
3'd 1 : bps_set<= 9'd 162; //19200
3'd 2 : bps_set<= 9'd 80; //38400
3'd 3 : bps_set<= 9'd 53; //57600
3'd 4 : bps_set<= 9'd 26; //115200
endcase
end
//************************************************************
//消除亞穩態
always@(posedge clk or negedge rst_n)
if(!rst_n) begin
data_a <= 1'b 0;
data_b <= 1'b 0;
end
else begin
data_a <= data_in;
data_b <= data_a;
end
//****************************************************************
//接收啟動模塊
always@(posedge clk or negedge rst_n)
if(!rst_n) begin
data_c <= 1'b 0;
data_d <= 1'b 0;
end
else begin
data_c <= data_b;
data_d <= data_c;
end
//******************************************************************
//分頻計數模塊
always@(posedge clk or negedge rst_n)
if(!rst_n) cnt <= 9'd 0;
else if(rx_state) cnt <= (cnt == bps_set)? 9'd 0 : cnt + 1'd 1;
else cnt <= 9'd 0;
//******************************************************************
//波特率時鐘模塊
always@(posedge clk or negedge rst_n)
if(!rst_n) bps_clk <= 1'b 0;
else if(cnt == bps_set) bps_clk <= 1'b 1;
else bps_clk <= 1'b 0;
//******************************************************************
//移位計數模塊
always@(posedge clk or negedge rst_n)
if(!rst_n) shift <= 8'd 0;
else if(rx_stop) shift <= 8'd 0;
else if(bps_clk) shift <= shift + 1'd 1;
else shift <= shift;
//*******************************************************************
//傳送完成標志位設置,如果起始位接收失敗也要清零
always@(posedge clk or negedge rst_n)
if(!rst_n) rx_stop <= 1'b 0;
else if(shift == 9'd 159 || (shift == 9'd 11 && data_read[0][2])) rx_stop <= 1'b 1;
else rx_stop <= 1'b 0;
//*********************************************************************
//數據讀取模塊
always@(posedge clk or negedge rst_n)
if(!rst_n) begin
data_start <= 3'd 0;
data_read[0] <= 3'd 0;
data_read[1] <= 3'd 0;
data_read[2] <= 3'd 0;
data_read[3] <= 3'd 0;
data_read[4] <= 3'd 0;
data_read[5] <= 3'd 0;
data_read[6] <= 3'd 0;
data_read[7] <= 3'd 0;
data_stop <= 3'd 0;
end
else if(bps_clk) begin // *else if (bps_clk)
case(shift)
0 : begin
data_start <= 3'd 0;
data_read[0] <= 3'd 0;
data_read[1] <= 3'd 0;
data_read[2] <= 3'd 0;
data_read[3] <= 3'd 0;
data_read[4] <= 3'd 0;
data_read[5] <= 3'd 0;
data_read[6] <= 3'd 0;
data_read[7] <= 3'd 0;
data_stop <= 3'd 0;
end
5,6,7,8,9,10 : data_start <= data_start + data_b;
21,22,23,24,25,26 : data_read [0] <= data_read [0] + data_b;
37,38,39,40,41,42 : data_read [1] <= data_read [1] + data_b;
53,54,55,56,57,58 : data_read [2] <= data_read [2] + data_b;
69,70,71,72,73,74 : data_read [3] <= data_read [3] + data_b;
85,86,87,88,89,90 : data_read [4] <= data_read [4] + data_b;
102,103,104,105,106,107 : data_read [5] <= data_read [5] + data_b;
117,118,119,120,121,122 : data_read [6] <= data_read [6] + data_b;
133,134,135,136,137,138 : data_read [7] <= data_read [7] + data_b;
149,150,151,152,153,154 : data_stop<= data_stop + data_b;
endcase
end
//************************************************************************
//數據校準模塊
always@(posedge clk or negedge rst_n)
if(!rst_n) data_out <= 8'd 0;
else if (shift == 8'd 159) begin
data_out[0] <=data_read[0][2];
data_out[1] <=data_read[1][2];
data_out[2] <=data_read[2][2];
data_out[3] <=data_read[3][2];
data_out[4] <=data_read[4][2];
data_out[5] <=data_read[5][2];
data_out[6] <=data_read[6][2];
data_out[7] <=data_read[7][2];
end
//*************************************************************************
//狀態位設置模塊
always@(posedge clk or negedge rst_n)
if(!rst_n) rx_state <= 1'b 0;
else if(nedge && shift < 8'd 5) rx_state <= 1'b 1;
else if(rx_stop) rx_state <= 1'b 0;
else rx_state <= rx_state;
//*************************************************************************
assign nedge = (data_d && (!data_c));
endmodule
|