1.时序
发送模块的功能在于:对输入的一个多位数据,按照波特率规定的时间拆分成一位一位的数据发送
①tx模块多了一个触发信号,也就是rx模块的rx_over作为tx模块的trig信号
②同样是tx的第一个下降沿来之后,开始发送;发送完成后拉高,结束传输
③传输的速率看波特率,根据波特率计算每个数据发送所需要的时间
2.分析
①同样使用两个计数器,分别计数一个bit的时间和bit的个数
②使用一个寄存器存下输入进来的发送数据
③标志flag_tx的有效区域
④tx的发送使用一个case语句完成,且在flag_tx下完成,初值为1
⑤大致模块:
3.verilog代码
module tx
(
input clk,
input rst_n,
input [7:0] tx_data,
input trig,
output reg tx
);
//参数
parameter _9600 = 5208;
parameter _8bit = 9;
//内部信
reg [7:0] reg_tx_data;
reg flag_tx;
reg [12:0] cnt_9600;
reg [3:0] cnt_8bit;
//将输入数据存入寄存器
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
reg_tx_data <= 0;
else if(trig && !flag_tx)
reg_tx_data <= tx_data;
end
//传输有效区域信号
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
flag_tx <= 0;
else if(trig && !flag_tx)
flag_tx <= 1;
else if(flag_tx && cnt_8bit == _8bit-1 && cnt_9600 == _9600-1)
flag_tx <=0;
end
//一位数据传输时间计数
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_9600 <= 0;
else if(flag_tx)begin
if(cnt_9600 == _9600-1)
cnt_9600 <= 0;
else
cnt_9600 <= cnt_9600 + 1;
end
end
//数据个数计数
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_8bit <= 0;
else if(flag_tx && cnt_9600 == _9600-1)begin
if(cnt_8bit == _8bit-1)
cnt_8bit <= 0;
else
cnt_8bit <= cnt_8bit + 1;
end
end
//tx
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
tx <= 0;
else if(flag_tx)
case(cnt_8bit)
0: tx <= 0;
1: tx <= reg_tx_data[0];
2: tx <= reg_tx_data[1];
3: tx <= reg_tx_data[2];
4: tx <= reg_tx_data[3];
5: tx <= reg_tx_data[4];
6: tx <= reg_tx_data[5];
7: tx <= reg_tx_data[6];
8: tx <= reg_tx_data[7];
default:tx <= 1;
endcase
else
tx <= 1;
end
endmodule
4.测试仿真
tx的仿真要比rx的仿真要简单很多,关键在于延迟的计算,如果延迟不对,那么波特率就不是9600,那么数据就会乱套;
`timescale 1 ns/1 ns
module tb_tx();
//输入信号
reg[7:0] tx_data ;
reg trig;
reg clk ;
reg rst_n;
//输出信号
wire tx;
//参数
parameter CYCLE = 20;
//待测试的模块例化
tx u2
(
.clk (clk ),
.rst_n (rst_n ),
.trig (trig ),
.tx_data (tx_data ),
.tx (tx )
);
//生成本地时钟50M
initial begin
clk = 0;
forever
#(CYCLE/2)
clk=~clk;
end
//产生复位信号
initial begin
rst_n = 1;
#2;
rst_n = 0;
#2
rst_n = 1;
end
initial begin
tx_data <= 8'd0;
trig <= 0;
#20;
tx_data <= 8'b01010101;
trig <= 1'b1;
#937440; //一共9个比特 ,因此是937440(5208*20*9)的时间
trig <= 1'b0;
#2;
tx_data <= 8'b10101010;
trig <= 1'b1;
#937440;
trig <= 1'b0;
end
endmodule
仿真结果:在modelsim中,先输入的是高位,因此01010101的仿真应该是10101010的tx数据