原创 串口发送模块 V4

2012-7-24 15:11 938 7 7 分类: FPGA/CPLD

/**
  ******************************************************************************
  * @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
     
     
  

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
7
关闭 站长推荐上一条 /3 下一条