赞
踩
当接收模块接收到数据后,需要重新发送形成回环验证模块正确性。思路和结束模块有一点点的小差异。接收模块最终输出的是一个并行的八位数据,所以只有在最后输出保证输出结果正确就可以,而发送模块必须按照波特率时钟发送每一位的数据。具体代码实现如下
- module uart_tx(
- //-----------input
- clk,rst_n,pi_data,pi_flag,
- //-----------output
- tx_data
- );
- input clk;
- input rst_n;
- input [7:0] pi_data;
- input pi_flag;
- output tx_data;
- parameter idle = 2'd0,
- start = 2'd1,
- work = 2'd2,
- stop = 2'd3;
- //------------------------------
- localparam baud_cnt_end = 5207 ;
- localparam baud_cnt_m = (baud_cnt_end + 1) / 2 - 1;
- //------------------------------
- //------------------------------
- reg pi_flag1;
- reg pi_flag2;
- reg tx_flag;
- reg [12:0] baud_cnt;
- reg [3:0] bit_cnt;
- reg tx_data;
- reg [1:0] current_state;
- reg [1:0] next_state;
- always@(posedge clk )
- begin
- pi_flag1 <= pi_flag;
- pi_flag2 <= pi_flag1;
- end
- //------------------------------
- //第一个进程,同步时序always块,形式固定
- always@(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- current_state <= idle;
- else
- current_state <= next_state;
- end
- //第二个always,组合逻辑模块,描述状态迁移条件判断
- always@(*)
- begin
- case(current_state)
- idle:
- begin
- tx_flag = 1'b0;
- begin
- if(pi_flag2)
- next_state = start;
- else
- next_state = idle;
- end
- end
- start:
- begin
- tx_flag = 1'b1;
- begin
- if(bit_cnt == 4'd1)
- next_state = work;
- else
- next_state = start;
- end
- end
- work:
- begin
- tx_flag = 1'b1;
- begin
- if(bit_cnt == 4'd9)
- next_state = stop;
- else
- next_state = work;
- end
- end
- stop:
- begin
- tx_flag = 1'b1;
- begin
- if(bit_cnt == 4'd10)
- next_state = idle;
- else
- next_state = stop;
- end
- end
- default:
- begin
- next_state = idle;
- end
- endcase
- end
- //第三个进程,描述输出,同步时序always块
- //reg [3:0] bit_cnt;
- always@(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- bit_cnt <= 4'd0;
- else
- if(!tx_flag)
- bit_cnt <= 4'd0;
- else
- if(baud_cnt == baud_cnt_end)
- bit_cnt <= bit_cnt + 1'b1;
- end
- //reg [12:0] baud_cnt;
- always@(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- baud_cnt <= 13'd0;
- else
- if(baud_cnt == baud_cnt_end)
- baud_cnt <= 13'd0;
- else
- if(tx_flag)
- baud_cnt <= baud_cnt + 1'b1;
- else
- baud_cnt <= 13'd0;
- end
- reg [7:0] pi_data_r;
- always@(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- pi_data_r <= 8'd0;
- else
- if(pi_flag)
- pi_data_r <= pi_data;
- else
- pi_data_r <= pi_data_r;
- end
- //define tx_data
- always@(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- tx_data <= 1'b1;
- else
- if(tx_flag)
- case(bit_cnt)
- 4'd0 : tx_data <= 1'b0 ;
- 4'd1 : tx_data <= pi_data_r[0] ;
- 4'd2 : tx_data <= pi_data_r[1] ;
- 4'd3 : tx_data <= pi_data_r[2] ;
- 4'd4 : tx_data <= pi_data_r[3] ;
- 4'd5 : tx_data <= pi_data_r[4] ;
- 4'd6 : tx_data <= pi_data_r[5] ;
- 4'd7 : tx_data <= pi_data_r[6] ;
- 4'd8 : tx_data <= pi_data_r[7] ;
- 4'd9 : tx_data <= 1'b1 ;
- default:;
- endcase
- else
- tx_data <= 1'b1;
- end
- endmodule
- module top_uart(
- input clk ,
- input rst_n ,
- input rx_data ,
- output tx_data
- );
- wire [7:0] data;
- wire flag;
- uart_tx A(
- .clk (clk ),
- .rst_n (rst_n ),
- .pi_data (data ),
- .pi_flag (flag ),
- .tx_data (tx_data)
- );
- uart_rx B(
- .clk (clk ),
- .rst_n (rst_n ),
- .rx_data (rx_data),
- .po_data (data ),
- .po_flag (flag )
- );
- endmodule
- module tb_fsm;
-
- // Inputs
- reg clk;
- reg rst_n;
- reg rx_data;
-
- // Outputs
- wire tx_data;
-
- // Instantiate the Unit Under Test (UUT)
- top_uart uut (
- .clk(clk),
- .rst_n(rst_n),
- .rx_data(rx_data),
- .tx_data(tx_data)
- );
- always #10 clk = ~clk;
- initial begin
- // Initialize Inputs
- clk = 0;
- rst_n = 0;
- rx_data = 1;
-
- // Wait 100 ns for global reset to finish
- #100;
- rst_n = 1;
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 0;//start
- #104140;
- rx_data = 0;//1
- #104140;
- rx_data = 1;//2
- #104140;
- rx_data = 0;//3
- #104140;
- rx_data = 1;//4
- #104140;
- rx_data = 0;//5
- #104140;
- rx_data = 1;//6
- #104140;
- rx_data = 0;//7
- #104140;
- rx_data = 1;//8
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 0;
- #104140;
- rx_data = 1;//1
- #104140;
- rx_data = 0;
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 0;//4
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 0;
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 0;//8
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 1;
- #104140;
- rx_data = 1;
-
- // Add stimulus here
-
- end
-
- endmodule
对于uart,发送和接收应该是人机交互的一个方式,通过发送的字符控制内部等等其他东西。对于模块不理解的可以回头看看仿真图,对图中的各个时序进行理解。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。