芯查查logo
  • 数据服务
    1. 新产品
    2. 物料选型
    3. 查替代
    4. 丝印反查
    5. 查品牌
    6. PCN/PDN
    7. 查方案
    8. 查代理
    9. 数据合作
  • SaaS/方案
      SaaS产品
    1. 供应链波动监控
    2. 半导体产业链地图
    3. BOM管理
    4. 解决方案
    5. 汽车电子
    6. 政府机构
    7. 数据API
  • 商城
  • 行业资讯
    1. 资讯
    2. 直播
  • 论坛社区
    1. 论坛
    2. 学习
    3. 测评中心
    4. 活动中心
    5. 积分商城
  • 查一下
  • 开通会员
现代的仪表Gary
萤火工场CEM5861G-M11毫米波雷达面板测评3

post一下FPGA的串口驱动代码

总体的设计框图如下

以下是TX模块  

module  uart_tx#(
   parameter            P_UART_DATA_WIDTH = 8 , // 5 - 9 bits
   parameter            P_UART_STOP_WIDTH = 1 , // 1 bit or 2 bits
   parameter            P_UART_PARITY_MOD = 0   // No check:0  // Odd check:1 // Even check:2
) (
   input                i_clk ,
   input                i_rst ,
/*-----------------*USER INTERFACE*-----------------*/
   input  [ P_UART_DATA_WIDTH - 1 :   0 ] i_user_tx_data  ,
   input                                  i_user_tx_valid ,
   output                                 o_user_tx_ready ,
   
/*-----------------*DRIVE INTERFACE*-----------------*/
   output               o_uart_tx 
   
);
/*-----------------*function*-----------------*/
   
   
/*-----------------*parameter*----------------*/
   
   
/*-----------------*port*---------------------*/
   
   
/*-----------------*mechine*------------------*/
   
   
/*-----------------*reg*----------------------*/
//INPUT----USER
   reg    [P_UART_DATA_WIDTH - 1 : 0] r_i_user_tx_data ;

//OUTPUT----USER
   reg                  r_o_user_tx_ready ;

//OUTPUT----DERIVE
   reg                  r_o_uart_tx ;

//COUNTER
   reg    [  15 :   0 ] r_cnt ;

//OTHER
   reg                  r_parity ;


/*-----------------*wire*---------------------*/
//Handshake Indication Signal
   wire                 w_uart_active ;
   
/*-----------------*component*----------------*/
   
   
/*-----------------*assign*-------------------*/
//OUTPUT----USER
   assign o_user_tx_ready = r_o_user_tx_ready ;

//OUTPUT----DRIVE
   assign o_uart_tx = r_o_uart_tx ;

//Handshake Indication Signal
   assign w_uart_active = i_user_tx_valid & r_o_user_tx_ready ;
   
/*-----------------*always*-------------------*/
//COUNTER
always @(posedge i_clk , posedge i_rst) begin
   if(i_rst)begin
       r_cnt <= 0;
   end
   else if(r_cnt == (1 + P_UART_DATA_WIDTH + P_UART_STOP_WIDTH) - 1 && P_UART_PARITY_MOD == 0)begin
       r_cnt <= 0;
   end
   else if(r_cnt == (1 + P_UART_DATA_WIDTH + 1 + P_UART_STOP_WIDTH) - 1 && P_UART_PARITY_MOD >= 1)begin
       r_cnt <= 0;
   end
   else if(!r_o_user_tx_ready)begin
       r_cnt <= r_cnt + 1;
   end
   else begin
       r_cnt <= r_cnt;
   end
end

//OUTPUT----USER
always @(posedge i_clk , posedge i_rst) begin
   if(i_rst)begin
       r_o_user_tx_ready <= 1;
   end
   else if(w_uart_active)begin
       r_o_user_tx_ready <= 0;
   end
   else if(r_cnt >= (1 + P_UART_DATA_WIDTH + P_UART_STOP_WIDTH) - 2 && P_UART_PARITY_MOD == 0)begin
       r_o_user_tx_ready <= 1;
   end
   else if(r_cnt >= (1 + P_UART_DATA_WIDTH + 1 + P_UART_STOP_WIDTH) - 2 && P_UART_PARITY_MOD >= 1)begin
       r_o_user_tx_ready <= 1;
   end
   else begin
       r_o_user_tx_ready <= r_o_user_tx_ready;
   end
end

//INPUT----USER
always @(posedge i_clk , posedge i_rst) begin
   if(i_rst)begin
       r_i_user_tx_data <= 0;
   end
   else if(w_uart_active)begin
       r_i_user_tx_data <= i_user_tx_data;
   end
   else if(!r_o_user_tx_ready)begin
       r_i_user_tx_data <= r_i_user_tx_data >> 1;
   end
   else begin
       r_i_user_tx_data <= r_i_user_tx_data;
   end
end

//OUTPUT----DRIVE
always @(posedge i_clk , posedge i_rst) begin
   if(i_rst)begin
       r_o_uart_tx <= 1;
   end
   else if(w_uart_active)begin
       r_o_uart_tx <= 0;
   end
   else if(r_cnt == (1 + P_UART_DATA_WIDTH) - 1 && P_UART_PARITY_MOD == 0)begin
       r_o_uart_tx <= 1;                                              //STOP
   end
   else if(r_cnt == (1 + P_UART_DATA_WIDTH) - 1 && P_UART_PARITY_MOD == 1)begin
       r_o_uart_tx <= ~ r_parity;
   end
   else if(r_cnt == (1 + P_UART_DATA_WIDTH) - 1 && P_UART_PARITY_MOD == 2)begin
       r_o_uart_tx <= r_parity;
   end
   else if (r_cnt >= (1 + P_UART_DATA_WIDTH + 1) - 1 && P_UART_PARITY_MOD >= 1) begin
       r_o_uart_tx <= 1;                                              //STOP
   end
       else if(!r_o_user_tx_ready)begin
       r_o_uart_tx <= r_i_user_tx_data[0];
   end
   else begin
       r_o_uart_tx <= 1;
   end
end

//Implement parity function
always @(posedge i_clk , posedge i_rst) begin
   if(i_rst)begin
       r_parity <= 0;
   end
   else if(r_cnt <= P_UART_DATA_WIDTH)begin
       r_parity <= r_parity ^ r_i_user_tx_data[0];
   end
   else begin
       r_parity <= r_parity;
   end
end
   
endmodule

以下是RX模块   
module  uart_rx#(
   parameter            P_UART_DATA_WIDTH = 8 , // 5 - 9 bits
   parameter            P_UART_STOP_WIDTH = 1 , // 1 bit or 2 bits
   parameter            P_UART_PARITY_MOD = 0   // No check:0  // Odd check:1 // Even check:2
) (
   input                i_clk ,
   input                i_rst ,
/*-----------------*USER INTERFACE*-----------------*/
   output [ P_UART_DATA_WIDTH - 1 :   0 ] o_user_rx_data  ,
   output                                 o_user_rx_valid ,
   
/*-----------------*DRIVE INTERFACE*-----------------*/
   input                i_uart_rx 
   
);
/*-----------------*function*-----------------*/
   
   
/*-----------------*parameter*----------------*/
   
   
/*-----------------*port*---------------------*/
   
   
/*-----------------*mechine*------------------*/
   
   
/*-----------------*reg*----------------------*/
//INPUT----USER
   reg    [ P_UART_DATA_WIDTH - 1 :   0 ] r_o_user_rx_data  ;
   reg                                    r_o_user_rx_valid ;

//OUTPUT----DERIVE

//COUNTER
   reg    [  15 :   0 ] r_cnt ;

//OTHER
   reg                  r_parity ;


/*-----------------*wire*---------------------*/

   
/*-----------------*component*----------------*/
   
   
/*-----------------*assign*-------------------*/
//OUTPUT----USER
   assign o_user_rx_data  = r_o_user_rx_data  ;
   assign o_user_rx_valid = r_o_user_rx_valid ;
   
/*-----------------*always*-------------------*/
//COUNTER
always @(posedge i_clk , posedge i_rst) begin
   if(i_rst)begin
       r_cnt <= 0;
   end
   else if(r_cnt == (1 + P_UART_DATA_WIDTH + P_UART_STOP_WIDTH) - 1 && P_UART_PARITY_MOD == 0)begin
       r_cnt <= 0;
   end
   else if(r_cnt == (1 + P_UART_DATA_WIDTH + 1 + P_UART_STOP_WIDTH) - 1 && P_UART_PARITY_MOD >= 1)begin
       r_cnt <= 0;
   end
   else if(r_cnt > 0 || !i_uart_rx)begin
       r_cnt <= r_cnt + 1;
   end
   else begin
       r_cnt <= r_cnt;
   end
end

//OUTPUT----USER
always @(posedge i_clk , posedge i_rst) begin
   if(i_rst)begin
       r_o_user_rx_data <= 0;
   end
   else if(r_cnt >= 1 && r_cnt <= P_UART_DATA_WIDTH)begin
       r_o_user_rx_data <= {i_uart_rx,r_o_user_rx_data[P_UART_DATA_WIDTH - 1 : 1]};
   end
   else begin
       r_o_user_rx_data <= r_o_user_rx_data;
   end
end
always @(posedge i_clk , posedge i_rst) begin
   if(i_rst)begin
       r_o_user_rx_valid <= 0;
   end
   else if(r_cnt == P_UART_DATA_WIDTH + P_UART_STOP_WIDTH - 1 && P_UART_PARITY_MOD == 0)begin
       r_o_user_rx_valid <= 1;
   end
   else if(r_cnt == P_UART_DATA_WIDTH + P_UART_STOP_WIDTH && P_UART_PARITY_MOD == 1 && !r_parity == i_uart_rx)begin
       r_o_user_rx_valid <= 1;
   end
   else if(r_cnt == P_UART_DATA_WIDTH + P_UART_STOP_WIDTH && P_UART_PARITY_MOD == 2 && r_parity == i_uart_rx)begin
       r_o_user_rx_valid <= 1;
   end
   else begin
       r_o_user_rx_valid <= 0;
   end
end

//Implement parity function
always @(posedge i_clk , posedge i_rst) begin
   if(i_rst)begin
       r_parity <= 0;
   end
   else if(r_cnt >= 1 && r_cnt <= P_UART_DATA_WIDTH)begin
       r_parity <= r_parity ^ i_uart_rx;
   end
   else begin
       r_parity <= 0;
   end
end
   
endmodule

 

module_uart_drive#(
   parameter            P_SYSTEM_CLK      = 100_000_000 , // system clock
   parameter            P_UART_BAUDRATE   = 115200        , // 9600、19200 、38400 、57600 、115200、230400、460800、921600
   parameter            P_UART_DATA_WIDTH = 8           , // 5 - 9 bits
   parameter            P_UART_STOP_WIDTH = 1           , // 1 bit or 2 bits
   parameter            P_UART_PARITY_MOD = 0             // No check:0  // Odd check:1 // Even check:2

) (
   input                i_clk ,
   input                i_rst ,
/*-----------------*USER INTERFACE*-----------------*/
   output                               o_user_clk      ,
   output                               o_user_rst      ,

   input  [ P_UART_DATA_WIDTH - 1 : 0 ] i_user_tx_data  ,
   input                                i_user_tx_valid ,
   output                               o_user_tx_ready ,

   output [ P_UART_DATA_WIDTH - 1 : 0 ] o_user_rx_data  ,
   output                               o_user_rx_valid ,
   
/*-----------------*DRIVE INTERFACE*-----------------*/
   output               o_uart_tx ,
   input                i_uart_rx 
   
);
/*-----------------*function*-----------------*/
   
   
/*-----------------*parameter*----------------*/
   
   
/*-----------------*port*---------------------*/
   
   
/*-----------------*mechine*------------------*/
   
   
/*-----------------*reg*----------------------*/
//Metronome ---- The first beat eliminates metastability and the second beat aligns the data with the clock of this module.
   reg    [ P_UART_DATA_WIDTH - 1 : 0 ] r_user_rx_data_1d  ;
   reg                                  r_user_rx_valid_1d ;
   reg    [ P_UART_DATA_WIDTH - 1 : 0 ] r_user_rx_data_2d  ;
   reg                                  r_user_rx_valid_2d ;

/*-----------------*wire*---------------------*/
//INPUT
   wire                 w_rst ;

//OTHER
   wire   [ P_UART_DATA_WIDTH - 1 : 0 ] w_user_rx_data  ;
   wire                                 w_user_rx_valid ;
               
   wire                                 w_uart_tx_clk ;
   wire                                 w_uart_tx_rst ;
   wire                                 w_uart_rx_clk ;
   wire                                 w_uart_rx_rst ;

/*-----------------*component*----------------*/
   baudrate_gen #(
       .P_SYSTEM_CLK    (P_SYSTEM_CLK    ),
       .P_UART_BAUDRATE (P_UART_BAUDRATE )
   )u_baudrate_gen(
       .i_clk           (i_clk           ),
       .i_rst           (w_rst           ),
       .i_uart_rx       (i_uart_rx       ),
       .i_user_rx_valid (w_user_rx_valid ),
       .o_uart_tx_clk   (w_uart_tx_clk   ),
       .o_uart_tx_rst   (w_uart_tx_rst   ),
       .o_uart_rx_clk   (w_uart_rx_clk   ),
       .o_uart_rx_rst   (w_uart_rx_rst   )
   );
   
   uart_tx #(
       .P_UART_DATA_WIDTH (P_UART_DATA_WIDTH ), // 5 - 9 bits
       .P_UART_STOP_WIDTH (P_UART_STOP_WIDTH ), // 1 bit or 2 bits
       .P_UART_PARITY_MOD (P_UART_PARITY_MOD )  // No check:0  // Odd check:1 // Even check:2
   )u_uart_tx(
       .i_clk           (w_uart_tx_clk ),
       .i_rst           (w_uart_tx_rst ),
       .i_user_tx_data  (i_user_tx_data  ),
       .i_user_tx_valid (i_user_tx_valid ),
       .o_user_tx_ready (o_user_tx_ready ),
       .o_uart_tx       (o_uart_tx       )
   );

   uart_rx #(
       .P_UART_DATA_WIDTH (P_UART_DATA_WIDTH ), // 5 - 9 bits
       .P_UART_STOP_WIDTH (P_UART_STOP_WIDTH ), // 1 bit or 2 bits
       .P_UART_PARITY_MOD (P_UART_PARITY_MOD )  // No check:0  // Odd check:1 // Even check:2
   )u_uart_rx(
       .i_clk           (w_uart_rx_clk ),
       .i_rst           (w_uart_rx_rst ),
       .o_user_rx_data  (w_user_rx_data  ),
       .o_user_rx_valid (w_user_rx_valid ),
       .i_uart_rx       (i_uart_rx       )
   );
   
   
/*-----------------*assign*-------------------*/
//INPUT ---- USER
   assign w_rst = ~i_rst ;
//OUTPUT ---- USER
   assign o_user_clk      = w_uart_tx_clk      ;
   assign o_user_rst      = w_uart_rx_rst      ;
   assign o_user_rx_data  = r_user_rx_data_2d  ;
   assign o_user_rx_valid = r_user_rx_valid_2d ;
   
/*-----------------*always*-------------------*/
//Metronome ---- The first beat eliminates metastability and the second beat aligns the data with the clock of this module.
   always @(posedge i_clk , posedge w_rst) 
   begin
       if(w_rst)
       begin
           r_user_rx_data_1d  <= 0 ;
           r_user_rx_valid_1d <= 0 ;
           r_user_rx_data_2d  <= 0 ;
           r_user_rx_valid_2d <= 0 ;
       end else begin
           r_user_rx_data_1d  <= w_user_rx_data     ;
           r_user_rx_valid_1d <= w_user_rx_valid    ;
           r_user_rx_data_2d  <= r_user_rx_data_1d  ;
           r_user_rx_valid_2d <= r_user_rx_valid_1d ;
       end
   end
   
endmodule

具体测评控制等之后再补充

萤火工场
版块: 开发板测评
前4天 23:51
  • 举报
😁😂😃😄😅😆😉😊😋😌😍😏😒😓😔😖😘😚😜😝😞😠😡😢😣😤😥😨😩😪😫😭😰😱😲😳😵😷😸😹😺😻😼😽😾😿🙀🙅🙆🙇🙈🙉🙊🙋🙌🙍🙎🙏✂✅✈✉✊✋✌✏✒✔✖✨✳✴❄❇❌❎❓❔❕❗❤➕➖➗➡➰🚀🚃🚄🚅🚇🚉🚌🚏🚑🚒🚓🚕🚗🚙🚚🚢🚤🚥🚧🚨🚩🚪🚫🚬🚭🚲🚶🚹🚺🚻🚼🚽🚾🛀Ⓜ🅰🅱🅾🅿🆎🆑🆒🆓🆔🆕
@好友

全部评论

加载中
游客登录通知
已选择 0 人
自定义圈子
移动
发布帖子
发布动态
发布问答
最新帖子
【星允派 NEBULA PI】09:USB虚拟CDC与串口1【星允派 NEBULA PI】15:高级定时器输出PWM【星允派 NEBULA PI】14:使用DMA方式读取ADC【有奖话题35期】明明硬件比软件难,但为什么待遇还不如软件?【星允派 NEBULA PI】12:添加时间任务调度器
热门版块
查看更多
问型号
问技术
问行情
电子DIY
汽车电子工程师论坛
工业电子专区
新手入门指南
单片机/MCU论坛
PCB设计
开源项目

26

收藏

分享

微信扫码
分享给好友

评论