华中科技大学IC课程设计报告 断检测发送FIFO 状态标志位“EMPTY”, 如果为低电平(有数据待发送) , 状态机立刻转入起始态, 发送起始位。
2、自动转入移位态, 发送数据位, 直到8 位数据发送完毕后, 转入奇偶校验态, 发送校验位。最后在停止态, 发送停止位。当一帧数据发送完毕后, UART回到空闲态, 并等待下一个数据帧的开始。 4.2 模块设计过程
我在发送模块中使用的变量有data_in,clk,reset,idle(输入变量),data_out,data_tran,data_tran1(输出变量)。Clk为分频后的时钟频率;reset将UART重置,一般是将数据发送完毕后重置;idle线路繁忙判断标志位,为1表示繁忙,为0表示空闲。Data_out数据输出,将并行数据一个个转化成串行数据;data_tran为工作标志位,串行数据输出完毕为0,工作时为1;data_tran1表示并串转化标志位,转化时为0,转化完为1。
下面是我所做模块的完整代码: `timescale 1 ps/1 ps
module send(datain,clk,reset,idle,data_out,data_tran,data_tran1); input [7:0]datain; //数据输入端,待发送的8位数据
input clk,reset,idle; //reset重置UART,idle=1禁止输入,为0允许输入 output data_out; //串行数据输出 output data_tran; output data_tran1;
reg data_tran; //工作标志位,串行数据输出完毕为0,工作时为1
reg data_tran1; //并串转化标志位,转化时为0,转化完为1 reg data_out;
reg [7:0]data_save; //存储从datain送来的并行数据
reg [7:0]data_btoc; //开始并串转化时把数据从data_tran送到data_tran1,在data_tran1中转换成串行
reg parity; //奇偶校验位,接收端检错
reg [3:0]clk_div; //每个系统时钟上升沿计数,挤满给clk1附一个值 reg clk1_en; //clk1的使能信号
wire clk1; /*周期为16个系统周期,上升沿时cnt累加, 下降沿系统根据cnt的值做并串转换*/
reg [3:0]cnt; //clk1上升沿累加
reg sign1,sign2; //记录输入端wire变化 always@(posedge clk or posedge reset) begin
if(reset) begin
sign1<=1'b1; sign2<=1'b1;
6
华中科技大学IC课程设计报告 end else begin
sign1<=idle; sign2<=sign1; end end
always@(posedge clk or posedge reset) begin
if(reset) begin
data_tran<=1'b0; clk1_en<=1'b0; end
/*idle从1(禁止datain输入数据)变为0(允许datain输入数据), 在从1到0的下降沿并行数据从datain输入并存储在 内部寄存器data_save内,此时有sign1=0且sign2=1*/ else if(!sign1&&sign2) begin
data_tran<=1'b1; clk1_en<=1'b1; end
else if(cnt==4'b0010) //即将开始转化 data_tran<=1'b1;
else if(cnt==4'b1101) //转化和输出都完成 begin
data_tran<=1'b0; clk1_en<=1'b0; end end
always@(negedge idle or posedge reset) begin
if(reset)
data_save=8'b0; else
data_save=datain; ////下降沿存入输入数据 end
always@(posedge clk or posedge reset) begin
if(reset)
clk_div=4'b0; else if(clk1_en)
clk_div=clk_div+1; end
7
华中科技大学IC课程设计报告 assign clk1=clk_div[3]; ////周期为16个时钟周期 always@(negedge clk1 or posedge reset) if(reset) begin
data_out<=1'b1; data_tran1<=1'b1; parity<=1'b1; data_btoc<=8'b0; end
else ////clk1下降沿做并串转换和输出(clk1的上升沿 cnt累加)
begin
if(cnt==4'b0001) begin
data_btoc<=data_save;
data_tran1<=1'b0; //为0表示开始转换 end
else if(cnt==4'b0010) begin
data_out<=1'b0; //用0表示串行的开头 end
else if((cnt>=4'b0011)&&(cnt<=4'b1010)) begin //做并串转换
data_btoc[7:1]<=data_btoc[6:0]; //移位 data_btoc[0]<=1'b0; //低位填0
data_out<=data_btoc[7]; //最高位输出
parity<=parity^data_btoc[7]; //计算奇偶效验位 end
else if(cnt==4'b1011)
data_out<=parity; //输出奇偶校验位 else if(cnt==4'b1100) begin
data_out<=1'b1; //最后输出1作为串行的最后一位 data_tran1<=1'b1; end end
always@(posedge clk1 or posedge reset or negedge clk1_en) if(reset)
cnt=4'b0000; else if(!clk1_en) cnt=4'b0000; else
cnt=cnt+1; endmodule
8
华中科技大学IC课程设计报告 上面是发送端运行时的基本过程。 4.3 生成基本电路
4.4 仿真结果 如图6所示。
9
华中科技大学IC课程设计报告 图6 发送模块仿真波形
4.5 结果分析
从上述波形可以看出,输入数据为01010101。首先初始化输入数据,reset置1,idle置1,clk一直翻转,奇偶校验位初始置1,。在数据开始传递时,idle由0变到1,reset置为0,由于数据一直在传送,故data_tran一直为1,直到所有数据传送完毕,起始位为0,所以data_out先输出0,然后是8位数,分别为0,1,0,1,0,1,0,1;然后奇偶校验位,奇偶校验位初始为1,与传输的数据分别进行异或操作,首先1和0异或为1,再和8位数据的初始位0进行异或操作得到1,一直继续下去,直到8位数据的最后一位,奇偶校验位的值分别为1,1,0,0,1,1,0,0,1;结束位为1,当所有数据传输完毕后,data_tran变为0,标志数据传送完了。然后reset也置为高电平,idle也变为1,即禁止传输数据。当有新的数据要进行传输时,所有数据重置,即重复上述过程。
5 整体电路仿真分析
5.1
整体仿真结果
10