UART发送器

UART介绍
通过串行数据通道进行信息交换和远程交互的系统使用串行器/解串器(SerDes)接口进行数据串并格式的转换。它作为主机/设备和串行数据通路之间的接口如图。主机以并行字格式储存信息,以串行单比特格式发送和接受数据。调试解调器也称异步收发器(UART),该设备能够接受和发送串行数据,而且接受和发送单元不同步。
在这里插入图片描述
UART以ASCII码格式交换文本信息。其中每个字母符号采用7位编码和1位错误检验的奇偶校验码。在发送方,UART对位数据打包在最低位上增加起始位,在最高位增加停止位,如图。
在这里插入图片描述
从起始位开始的前9个数据位按顺序发送,每个位持续一个UART的时钟周期,停止位的有效时间可能超过一个时钟周期。

UART接收器的实现代码如链接
UART接收器

UART发送器介绍
UART发送器的接口信号如图
在这里插入图片描述
其中,输入信号由主机提供,输出信号只有一个串行数据流Serial_out。该发送器包括了控制器、用于计数已发送比特数的状态寄存器(Bit_count)、数据寄存器(XMT_datareg)、数据移位寄存器(XMT_shftreg),第二个在包含在数据通路中,后两个寄存器位于Datapath_unit中。
各位信号解释如下:
Load_XMT_datareg:idle状态下决定Load_XMT_DR的值(判断是否需要将Data_Bus的内容送到XMT_datareg)
Byte_ready:决定Load_XMT_shftreg信号的值(确定是否将XMT_datareg的内容载入XMT_shftreg)
T_byte:确定字节数据的传输开始,包括停止位,起始位,校验位。
BC_It_BCmax:用于指示数据通路中比特计数器的状态
控制状态机输出信号:
Load_XMT_DR:声明将Data_Bus中的内容载入XMT_datareg
Load_XMT_shftreg:声明将XMT_data_reg的内容载入XMT_shftreg
start:将XMT_shftreg[0]清0表示数据的传输开始
shift:将XMT_shftreg向LSB方向移一位,并用停止位(1)回填
clear:将bit_count清零

工作模式
描述UART发送器的工作状态用状态机描述,由idle,waiting,sending三个状态。
一:当复位信号rst有效时,状态机进入idle状态,bit_count清零,将XMT_shftreg的所有位初始化为1,在idle状态下,外部主机在时钟有效沿判定Load_XMT_datareg有效后,输出信号Load_XMT_DR将Data_Bus的内容载入XMT_datareg,状态机保持idle状态知道start有效而且让XMT_shftreg[0]清零。
二:当Byte_ready有效(同时rst和Load_XMT_datareg无效),Load_XMT_shftreg为有效值,状态机进入waiting状态,Load_XMT_shftreg有效表表明XMT_datareg送到内部寄存器执行相应操作,分三个步骤:(1)状态idle转到waiting,(2)XMT_datareg的内容载入XMT_shftrerg最左边比特——XMT_shftreg是一个(word_size+1)位的移位寄存器,它的LSB位表示传输的起始和终止(3)XMT_shftreg的LSB重载入1(停止位)。状态机保持waiting状态直到外部主机声明T_byte有效
三:T_byte有效后下一个时钟有效沿,状态机进入sending状态,XMT_shftreg的LSB置0产生传送开始信号。同时shift置为1保持sending状态,在传送过程中,shift始终有效,XMT_shftreg的内容向LSB移位并且驱动外部串行通道,数据移位时候XMT_shftreg用1回填,bit_count加一操作,在sending状态下bit_count小于9(BC_It_BCmax有效)时shift有效,当bit_count等于9,(BC_It_BCmax无效,clear有效),表示该字所有位已经串行输出,然后在下一个有效状态返回idle状态。
其中UART发送器的ASM图如下
在这里插入图片描述
UART发送器的控制信号和数据流如下
在这里插入图片描述
实现代码与测试代码

module UART_XMTR #(parameter word_size = 8)(
	output			Serial_out,
	input [word_size-1:0] Data_Bus,
	input	Load_XMT_datareg,
			Byte_ready,
			T_byte,
			Clock,
			rst_b
);

Control_Unit M0(Load_XMT_DR,Load_XMT_shftreg,start,shift,clear,Load_XMT_datareg,
				Byte_ready,T_byte,BC_It_BCmax,Clock,rst_b);
Datapath_Unit M1(Serial_out,BC_It_BCmax,Data_Bus,Load_XMT_DR,Load_XMT_shftreg,start,shift,clear,Clock,rst_b);

endmodule

module Control_Unit #(
	parameter 	one_hot_count = 3,
				state_count = one_hot_count,
				size_bit_count = 3,
				idle = 3'b001,
				waiting = 3'b010,
				sending = 3'b100,
				all_ones = 9'b1_1111_1111
)(
	output reg		Load_XMT_DR,
	output reg		Load_XMT_shftreg,
	output reg      start,
	output reg		shift,
	output reg		clear,
	input			Load_XMT_datareg,
	input			Byte_ready,
	input			T_byte,
	input			BC_It_BCmax,
	input			Clock,
	input			rst_b
);
	reg [state_count-1:0] state,next_state;
	always@(state,Load_XMT_datareg,Byte_ready,T_byte,BC_It_BCmax)begin:output_and_next_state
		Load_XMT_DR = 0;
		Load_XMT_shftreg = 0;
		start = 0;
		shift = 0;
		clear = 0;
		next_state = idle;
		case(state)
			idle:		if(Load_XMT_datareg == 1'b1)begin
							Load_XMT_DR = 1;
							next_state = idle;
						end
						else if(Byte_ready == 1'b1)begin
							Load_XMT_shftreg = 1;
							next_state = waiting;
						end
			waiting:	if(T_byte == 1'b1)begin
							start = 1;
							next_state = sending;
						end else next_state = waiting;
			sending:	if(BC_It_BCmax)begin
						shift = 1;
						next_state = sending;
						end
						else begin
							clear = 1;
							next_state = idle;
						end
			default:	next_state = idle;
		endcase
	end
	
	always@(posedge Clock, negedge rst_b)begin:state_transitions
		if(rst_b == 1'b0) state <= idle; else state <= next_state;
	end
endmodule

module Datapath_Unit #(
	parameter		word_size = 8,
					size_bit_count = 3,
					all_ones = {(word_size+1){1'b1}}
)(
	output			Serial_out,BC_It_BCmax,
	input [word_size-1:0] Data_Bus,
	input Load_XMT_DR,Load_XMT_shftreg,start,shift,clear,Clock,rst_b
);

	reg [word_size-1:0] XMT_datareg;
	reg [word_size:0] XMT_shftreg;
	reg [size_bit_count:0] bit_count;
	
	assign Serial_out = XMT_shftreg[0];
	assign BC_It_BCmax = (bit_count < word_size + 1);
	always@(posedge Clock, negedge rst_b)
		if(rst_b == 1'b0)begin
			XMT_shftreg <= all_ones;
			bit_count <= 0;
		end
		else begin
			if(Load_XMT_DR == 1'b1)XMT_datareg <= Data_Bus;
			if(Load_XMT_shftreg == 1'b1) XMT_shftreg <= {XMT_datareg,1'b1};
			if(start == 1'b1) XMT_shftreg[0] <= 0;
			if(clear == 1'b1) bit_count <= 0;
			if(shift == 1'b1)begin
				XMT_shftreg <= {1'b1,XMT_shftreg[word_size:1]};
				bit_count <= bit_count + 1;
			end
		end
endmodule

测试代码

module Test_uart8();
  parameter word_size = 8;
  reg [word_size-1:0] Data_Bus;
  reg Byte_ready, Load_XMT_datareg, T_byte, rst_b;
  wire Serial_out;
  wire Clock;

  reg [5:0] k;
  reg [word_size+1:0] Serial_test;

  UART_XMTR M0 
  (Serial_out, Data_Bus,Load_XMT_datareg, Byte_ready, T_byte, Clock, rst_b);

  Clock_Unit M2 (Clock);

  initial #2000 $finish;
  initial begin #5 rst_b =0;#5 rst_b =1 ; end
  initial begin #40 Byte_ready = 1; #10 Byte_ready = 0; end
  initial begin #10 Load_XMT_datareg = 0; #10 Load_XMT_datareg = 1; #10 Load_XMT_datareg = 0; end
  initial begin #90 Load_XMT_datareg=1; #10 Load_XMT_datareg = 0;end
  initial begin #120 Load_XMT_datareg = 1; #10 Load_XMT_datareg = 0; end

always @ (posedge Clock or negedge rst_b) 
  if (rst_b == 0) Serial_test <= 0; 
  else Serial_test <= {Serial_out, Serial_test[word_size+1 : 1]};

  wire [word_size-1:0] sent_word = Serial_test[word_size:1];

  initial begin 
    #80 T_byte = 1;
    forever begin 
      #10 T_byte = ~T_byte;#120 T_byte = ~T_byte;
    end
   end
  
  initial begin
    #5 Data_Bus <= 8'b1010_0111;  // ha6
    #80 Data_Bus <= 8'b0001_1010; // h1a
    #40 Data_Bus <= 8'hb4;
  end
endmodule

module Clock_Unit(output reg Clock);
parameter delay = 0;
parameter Pulse_Width = 5;
initial begin #delay Clock = 0; forever #Pulse_Width Clock = ~Clock;end
endmodule

仿真结果
在这里插入图片描述
用modelsim仿真与书中一样!
谢谢!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值