|
//产生串口发送时钟
module clk_gen_tr
(
input clk,
input rst_n,
output clk_t
);
`define BD_SEL CNT_115200
parameter CLK_HZ=50_000_000
parameter CNT_115200 = (CLK_HZ/115200)/2-1,
CNT_9600= (CLK_HZ/9600)/2-1,
CNT_57600= (CLK_HZ/57600)/2-1;
reg [8:0]div_cnt;
always @(posedge clk or negedge rst_n)
if(~rst_n)
div_cnt<=9’d0;
else if(div_cnt== `BD_SEL)
div_cnt<=9’d0;
else
div_cnt<= div_cnt+1’b1
always @(posedge clk or negedge rst_n)
if(~rst_n)
clk_t<=1’b0;
else if(div_cnt==`BD_SEL)
clk_t<=~ clk_t
endmodule
module rs_232_tr
(
input clk_t,
input rst_n,
output tx,
//fifo接口
output rd_en,
ouput rd_clk,
input [7:0]din,
input empty
)
reg tx_en;//当该使能信号为高电平的时候表示可以发送数据
reg [3:0] tx_st;//发送状态机
reg [7:0] tx_data;//用于保存发送的数据
parameter IDLE_T = 4’d0,//等待允许发送数据
START_T = 4’d1,//用于发送起始位
BIT0_T = 4‘d2//用于发送数据为第1位
BIT1_T = 4‘d3//用于发送数据为第2位
BIT2_T = 4‘d4//用于发送数据为第3位
BIT3_T = 4‘d5//用于发送数据为第4位
BIT4_T = 4‘d6//用于发送数据为第5位
BIT5_T = 4‘d7//用于发送数据为第6位
BIT6_T = 4‘d8//用于发送数据为第7位
BIT7_T = 4‘d9//用于发送数据为第8位
OV_T = 4’d10//用于发送校验位
END_T = 4‘d11;//用于发送停止位
always @(posedge clk_t or negedge rst_n)
if(~rst_n)
tx_st<= IDLE_T;
else case(tx_st)
IDLE_T:if(tx_en)
tx_st<= START_T;
START_T: tx_st<= BIT0_T;
BIT0_T: tx_st<= BIT1_T;
BIT1_T: tx_st<= BIT2_T;
BIT2_T: tx_st<= BIT3_T;
BIT3_T: tx_st<= BIT4_T;
BIT4_T: tx_st<= BIT5_T;
BIT5_T: tx_st<= BIT6_T;
BIT6_T: tx_st<= BIT7_T;
BIT7_T: tx_st<= OV_T;
OV_T: tx_st<= END_T;
END_T: tx_st<= IDLE_T;
default: tx_st<= IDLE_T;
endcase
//数据传输
always @(posedge clk_t or negedge rst_n)
if(~rst_n)
tx <= 1’b1;
else case(tx_st)
IDLE_T: tx <= 1’b1;
START_T: tx <= 1’b0;
BIT0_T: tx <= tx_data[0];
BIT1_T: tx <= tx_data[1];
BIT2_T: tx <= tx_data[2];
BIT3_T: tx <= tx_data[3];
BIT4_T: tx <= tx_data[4];
BIT5_T: tx <= tx_data[5];
BIT6_T: tx <= tx_data[6];
BIT7_T: tx <= tx_data[7];
OV_T: tx <= tx_data[0]^ tx_data[1]^ tx_data[2] ^tx_data[3] ^tx_data[4] ^tx_data[5] ^tx_data[6] ^tx_data[7];
END_T: tx <=1’b1;
default: tx <=1’b1;
endcase
//发送数据获取以及发送控制
always @(posedge clk_t or negedge rst_n)
if(~rst_n)
rd_en<=1’b0;
else if(tx_st== IDLE_T)&&(~empty)
rd_en<=1’b1;
else
rd_en<=1’b0;
always @(*) tx_en= rd_en;
always @(posedge clk_t or negedge rst_n)
if(~rst_n)
tx_data<=8’d0;
else if(if(tx_st== START_T)
tx_data<=din;
assign rd_clk=clk_t;
endmodule
|
|