/**
******************************************************************************
* @file tx_rs232_v4.v
* @author 西殿源
* @version V4
* @date 07/20/2012
* @brief RS232串口发送模块
* @info 1. 状态机分段
2. 端口命名风格调整
3. 配置变量整合为寄存器组,没找到可以整合的部分
******************************************************************************
*/
module tx_rs232_v4(
output reg tx_ro, //串行发送口
output reg ***_ro, //发送成功标志
input rst_n, //下降沿异步复位
input entx, //单脉冲使能发送
input clk, //输入时钟
input[7:0] din //预发送数据并行输入
);
parameter START = 4'd0;
parameter DAT0 = 4'd1;
parameter DAT1 = 4'd2;
parameter DAT2 = 4'd3;
parameter DAT3 = 4'd4;
parameter DAT4 = 4'd5;
parameter DAT5 = 4'd6;
parameter DAT6 = 4'd7;
parameter DAT7 = 4'd8;
parameter VRFY = 4'd9;
parameter STOP = 4'd10;
parameter FLAG = 4'd11;
parameter IDLE = 4'd12;
parameter YES = 1'b1;
parameter NO = 1'b0;
parameter BAUD = 9600;
parameter XTAL = 1000000;
parameter BAUD_9600 = 8'd103;
reg baud_adj;
reg [7:0] din_r; //输入数据寄存器
reg entx_r; //使能锁存
reg [3:0] stat_cur; //当前状态
reg [3:0] stat_nxt; //下一状态
reg tx_tmp;
reg [7:0] fp_cnt;
reg ***_r;
wire clk_w;
reg verify_reg=0;
//对输入的1M时钟进行104分频,
always @(posedge clk,negedge rst_n) begin //
if(!rst_n) fp_cnt <= 8'b0;
else if(fp_cnt == BAUD_9600) fp_cnt <= 8'b0;
else fp_cnt <= fp_cnt + 8'b1;
end//always
//当满足1.有数据发送请求脉冲;2.分频值满。
//两个条件同时满足时,方可使能时钟
assign clk_w = ( (entx_r == YES) && (fp_cnt == BAUD_9600));
//1.初始化状态,端口;2.检测数据发送请求;3.状态切换,同步输出
always @(posedge clk,negedge rst_n) begin
if(!rst_n) begin
stat_cur <= IDLE;
tx_ro <= 1'b1;
entx_r <= NO;
***_ro <= NO;
end
else if(entx) begin
entx_r <= YES;
din_r <= din;
stat_cur <= START;
end
else if(clk_w) begin
tx_ro <= tx_tmp;
entx_r <= ~***_r;
***_ro <= ***_r;
stat_cur <= stat_nxt;
end
else begin
***_ro <= NO;
end
end//always
always @(stat_cur) begin //组合逻辑部分
case(stat_cur)
START: begin
tx_tmp = 1'b0;
***_r = NO;
stat_nxt = DAT0;
end
DAT0: begin
tx_tmp = din_r[0];
***_r = NO;
stat_nxt = DAT1;
end
DAT1: begin
tx_tmp = din_r[1];
***_r = NO;
stat_nxt = DAT2;
end
DAT2: begin
tx_tmp = din_r[2];
***_r = NO;
stat_nxt = DAT3;
end
DAT3: begin
tx_tmp = din_r[3];
***_r = NO;
stat_nxt = DAT4;
end
DAT4: begin
tx_tmp = din_r[4];
***_r = NO;
stat_nxt = DAT5;
end
DAT5: begin
tx_tmp = din_r[5];
***_r = NO;
stat_nxt = DAT6;
end
DAT6: begin
tx_tmp = din_r[6];
***_r = NO;
stat_nxt = DAT7;
end
DAT7: begin
tx_tmp = din_r[7];
***_r = NO;
stat_nxt = STOP;
end
VRFY: begin
tx_tmp = verify_reg;
***_r = NO;
stat_nxt = STOP;
end
STOP: begin
tx_tmp = 1'b1;
***_r = YES;
stat_nxt = IDLE;
end
IDLE: begin
stat_nxt = IDLE;
end
default: begin
stat_nxt = IDLE;
end
endcase
end//always
endmodule
文章评论(0条评论)
登录后参与讨论