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