FPGA學習筆記-------計數器結構03

UART
計數器結構描述uart
/計數器結構
//------------------------------------------------------------------------------------------------------------------------------------------------
//明德揚定義計數器
//計數器規則1:計數器逐一考慮3要素:初值、加一條件、結束值
//計數器規則2:計數器初值必須爲零
//計數器規則3:使用某一計數器值,必須同時滿足加一條件
//計數器規則4:結束條件必須同時滿足加一條件
//計數器規則5:當取某個數時,assign的形式必須爲:(加一條件)&&(cnt==計數值-1);
//計數器規則6:結束後必須回到0;
//計數器規則7:若要限定範圍,則推薦使用">=“和”<"兩種符號;
//計數器規則8:設計步驟是,先寫計數器的always段,條件用名字代替,然後用assign寫出加1條件;最後用assign寫出結束條件;
//計數器規則9:加1條件必須與計數器嚴格對齊,其他信號一律向計數器對齊;
//計數器規則10:命名規則必須符合規範,比如:add_cnt表示加1條件;end_cnt表示結束條件;
//計數器規則11:減1計數器暫時不用。

//計數器八步法
// 第一步:功能明確
// 第二步:功能波形
// 第三步:計數結構 ------根據波形找出實現時序需要的計數器數量和結構
// 第四步:加1和結束條件
// 第五步:定義特殊點
// 第六步:完整性檢查
// 第七步:計數器代碼
// 第八步:功能代碼
————————————————

//發送
always @(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin
				cnt1 <= 0;
			end
		else if(add_cnt1)       //加一條件
			begin
				if(end_cnt1)    //結束條件
					cnt_1 <= 0;
				else
					cnt1 <= cnt1 + 1'b1;
			end
	end

assign add_cnt1 = flag == 1;
assign end_cnt1 = add_cnt1 && cnt_1ms == 5208 - 1;

always @(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin
				cnt2 <= 0;
			end
		else if(add_cnt2)       //加一條件
			begin
				if(end_cnt2)    //結束條件
					cnt_2 <= 0;
				else
					cnt2 <= cnt2 + 1'b1;
			end
	end

assign add_cnt2 = end_cnt1;
assign end_cnt2 = add_cnt2 && cnt2 == 10 - 1;

//功能代碼
always@(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin
				flag <= 1'b0;
			end
		else if(tx_start)
			begin
				flag <= 1'b1;
			end
		else if(end_cnt2)
			begin 
				flag <= 0'b0;
			end
	end

assign tx_start = tx_vld && !flag;

always @(posedge clk or negedge rst_n)
	begin
		if(rst_n = 1'b0)
			begin 
				tx_data_tmp <= 10'b0;
			end
		else if(tx_start)
			begin
				tx_data_tmp <= {1'b1,tx_data,1'b0};
			end
	end
	
always @(posedge clk or negedge rst_n)
	begin
		if(rst_n = 1'b0)
			begin
				uart_tx <= 0;
			end
		else if(add_cnt1 && cnt1 == 0)
			begin
				uart_tx <= tx_data_tmp[cnt2];
			end
	end
	
always @(*)
	begin
		if(flag || tx_vld)
			tx_rdy = 1'b0;
		else
			tx_rdy = 1'b1;
	end
	
//接收
always @(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin
				cnt1 <= 0;
			end
		else if(add_cnt1)       //加一條件
			begin
				if(end_cnt1)    //結束條件
					cnt_1 <= 0;
				else
					cnt1 <= cnt1 + 1'b1;
			end
	end

assign add_cnt1 = flag == 1;
assign end_cnt1 = add_cnt1 && cnt_1ms == 5208 - 1;

always @(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin
				cnt2 <= 0;
			end
		else if(add_cnt2)       //加一條件
			begin
				if(end_cnt2)    //結束條件
					cnt_2 <= 0;
				else
					cnt2 <= cnt2 + 1'b1;
			end
	end

assign add_cnt2 = end_cnt1;
assign end_cnt2 = add_cnt2 && cnt2 == 9 - 1;	

//功能代碼
always @(posedge clk or negedge rst_n)               //檢測時序
	begin
		if(rst_n == 1'b0)
			begin
				uart_rx_ff0 <= 1;
				uart_rx_ff1 <= 1;
				uart_rx_ff2 <= 1;
			end
		else
			begin
				uart_rx_ff0 <= uart_rx;
				uart_rx_ff1 <= uart_rx_ff0;
				uart_rx_ff2 <= uart_rx_ff1;
			end
	end

always @(posedge clk or negedge rst_n)               
	begin
		if(rst_n == 1'b0)
			begin
				rx_data <= 0;
			end
		else if(cnt2 >= 1 && cnt2 < 9 && add_cnt1 && cnt1 == 2604-1)
			begin
				rx_data[cnt2 - 1] <= uart_rx_ff2;
			end
	end

always @(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin
				rx_vld <= 0;
			end
		else if(cnt2 == 8 && add_cnt1 && cnt1 == 2604 - 1)
			begin
				rx_vld <= 1;
			end
		else
			begin
				rx_vld <= 0;
			end
	end
	
always @(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin
				flag <= 0;
			end
		else if(uart_rx_ff1 = 0 && uart_rx_ff2 = 1)       //檢測到下降沿
			begin	
				flag <= 1;
			end
		else if(end_cnt2)
			begin
				flag <= 0;
			end
	end
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章