1. 程式人生 > >verilog簡單實現串列埠

verilog簡單實現串列埠

//uart 2017.10.7  傳送接收到的資料 
//波特率9600 一個停止位 無奇偶校驗
//DE2板子
/*
rx GPIO_K25 0 left   -----tx
tx GPIO_K26 1 right  -----rx
GND  右邊第6 或者倒數第6
*/

//復位不成功 ????? 復位按鍵有問題 靠右按即可復位 
//特別注意 如果一個條件中同時給一個暫存器賦不同的值 結果不確定 
//以下是錯誤程式碼例子   tx_num 
//同時賦值  這裡加一 下面賦值0
/*
		 tx_num<=tx_num+1'b1;
		 case(tx_num)
			 0:tx<=1'b0;
			 1:tx<=tx_data[0];
			 2:tx<=tx_data[1];
			 3:tx<=tx_data[2];
			 4:tx<=tx_data[3];
			 5:tx<=tx_data[4];
			 6:tx<=tx_data[5];
			 7:tx<=tx_data[6];
			 8:tx<=tx_data[7];
			 9:begin tx<=1'b1; tx_num<=4'b0; end
*/
//一些小的演算法問題 畫個時序圖 標出各個點暫存器的值 
//對照程式看是否正確 特別是需要判斷且改變狀態的點
//以下是程式碼
//----------------------程式碼------------------
module uart(
           clk,   //50Mhz
           rst_n, //reset
           rx,    //input    
           tx,    //ouptut   
           sw     //測試是否收到資料
);
input clk,rst_n;
input rx;
output reg tx;

//測試是否收到資料
output wire [7:0] sw;

//-----------------檢測是否有資料來--------
//邊沿檢測  
wire rx_start;
reg rx1;
[email protected]
(posedge clk or negedge rst_n) begin if(!rst_n) rx1<=1'b0; else rx1<=rx; end assign rx_start = ~rx & rx1; //-------------------波特率控制------------ wire bps_start; reg bps_start_rx,bps_start_tx; reg [3:0] rx_num,tx_num; // 2^4-1=15 [email protected](posedge clk or negedge rst_n) begin if(!rst_n) begin bps_start_rx<=1'b0; bps_start_tx<=1'b0; end else if(rx_start) bps_start_rx<=1'b1; //接收完資料後 開始傳送資料 else if(rx_num==10) begin bps_start_rx<=1'b0; bps_start_tx<=1'b1; end //傳送完資料後 無需產生波特率 else if(tx_num==10) bps_start_tx<=1'b0; end assign bps_start = bps_start_rx|bps_start_tx; //------------------產生波特率-------------- //9600 parameter bps_cnt=5208; //50Mhz / 9600 = 5208.3...... parameter bps_cnt_half=2604; reg [12:0] cnt;
[email protected]
(posedge clk or negedge rst_n) begin if(!rst_n) cnt<=13'b0; else if(cnt==bps_cnt) cnt<=13'b0; else if(bps_start) cnt<=cnt+1'b1; else cnt<=13'b0; end //-------------------------------------------- reg [7:0] rx_data,tx_data; //測試是否收到資料 assign sw=rx_data; //---------------------接收資料-------------- //receive
[email protected]
(posedge clk or negedge rst_n) begin if(!rst_n) begin rx_num<=4'b0; rx_data<=8'b0; end else if(cnt==bps_cnt_half) begin if(bps_start_rx) begin rx_num<=rx_num+1'b1; case(rx_num) 1:rx_data[0]<=rx; 2:rx_data[1]<=rx; 3:rx_data[2]<=rx; 4:rx_data[3]<=rx; 5:rx_data[4]<=rx; 6:rx_data[5]<=rx; 7:rx_data[6]<=rx; 8:rx_data[7]<=rx; 9:tx_data<=rx_data; endcase end end else if(rx_num==10) rx_num<=4'b0; end //---------------------傳送資料-------------- //transport [email protected](posedge clk or negedge rst_n) begin if(!rst_n) tx_num<=4'b0; else if(cnt==bps_cnt_half) begin if(bps_start_tx) begin tx_num<=tx_num+1'b1; case(tx_num) 0:tx<=1'b0; 1:tx<=tx_data[0]; 2:tx<=tx_data[1]; 3:tx<=tx_data[2]; 4:tx<=tx_data[3]; 5:tx<=tx_data[4]; 6:tx<=tx_data[5]; 7:tx<=tx_data[6]; 8:tx<=tx_data[7]; 9:tx<=1'b1; endcase end else tx<=1'b1; end else if(tx_num==10) tx_num<=4'b0; end endmodule