Uart.V 串口 fpga

http://home.eeworld.com.cn/my/space-uid-210489-blogid-66899.html

 

Verilog代码
  1. module uart #(     
  2.     parameter clk_freq = 50000000,     
  3.     parameter baud = 9600  
  4. ) (     
  5.     input sys_clk,     
  6.     input sys_rst,     
  7.      
  8.     output rx_irq,     
  9.     output tx_irq,     
  10.      
  11.     input uart_rx,     
  12.     output uart_tx     
  13. );     
  14.     
  15. wire [7:0] rx_data;     
  16. reg [7:0] tx_data;     
  17. reg tx_wr;     
  18.   
  19. always @(posedge sys_clk)       
  20. begin           
  21.     if (rx_irq)       
  22.     begin       
  23.     tx_data <= rx_data;        
  24.     tx_wr <= 1'b1;       
  25.     end        
  26.     else   
  27.     begin   
  28.     tx_wr <= 1'b0;      
  29.     end   
  30. end    
  31.   
  32. uart_transceiver transceiver(     
  33.     .sys_clk(sys_clk),     
  34.     .sys_rst(sys_rst),     
  35.      
  36.     .uart_rx(uart_rx),     
  37.     .uart_tx(uart_tx),     
  38.      
  39.     .divisor(clk_freq/baud/16),     
  40.      
  41.     .rx_data(rx_data),     
  42.     .rx_done(rx_irq),     
  43.      
  44.     .tx_data(tx_data),     
  45.     .tx_wr(tx_wr),     
  46.     .tx_done(tx_irq)     
  47. );      
  48.        
  49. endmodule   

 

  uart_transceiver.v

  /*

Verilog代码
  1.  * Milkymist VJ SoC   
  2.  * Copyright (C) 2007200820092010 Sebastien Bourdeauducq   
  3.  * Copyright (C) 2007 Das Labor   
  4.  *   
  5.  * This program is free software: you can redistribute it and/or modify   
  6.  * it under the terms of the GNU General Public License as published by   
  7.  * the Free Software Foundation, version 3 of the License.   
  8.  *   
  9.  * This program is distributed in the hope that it will be useful,   
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of   
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   
  12.  * GNU General Public License for more details.   
  13.  *   
  14.  * You should have received a copy of the GNU General Public License   
  15.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.   
  16.  */   
  17.   
  18. module uart_transceiver(   
  19.     input sys_rst,   
  20.     input sys_clk,   
  21.   
  22.     input uart_rx,   
  23.     output reg uart_tx,   
  24.   
  25.     input [15:0] divisor,   
  26.   
  27.     output reg [7:0] rx_data,   
  28.     output reg rx_done,   
  29.   
  30.     input [7:0] tx_data,   
  31.     input tx_wr,   
  32.     output reg tx_done   
  33. );   
  34.   
  35. //-----------------------------------------------------------------   
  36. // enable16 generator   
  37. //-----------------------------------------------------------------   
  38. reg [15:0] enable16_counter;   
  39.   
  40. wire enable16;   
  41. assign enable16 = (enable16_counter == 16'd0);   
  42.   
  43. always @(posedge sys_clk) begin   
  44.     if(sys_rst)   
  45.         enable16_counter <= divisor - 16'b1;   
  46.     else begin   
  47.         enable16_counter <= enable16_counter - 16'd1;   
  48.         if(enable16)   
  49.             enable16_counter <= divisor - 16'b1;   
  50.     end   
  51. end   
  52.   
  53. //-----------------------------------------------------------------   
  54. // Synchronize uart_rx   
  55. //-----------------------------------------------------------------   
  56. reg uart_rx1;   
  57. reg uart_rx2;   
  58.   
  59. always @(posedge sys_clk) begin   
  60.     uart_rx1 <= uart_rx;   
  61.     uart_rx2 <= uart_rx1;   
  62. end   
  63.   
  64. //-----------------------------------------------------------------   
  65. // UART RX Logic   
  66. //-----------------------------------------------------------------   
  67. reg rx_busy;   
  68. reg [3:0] rx_count16;   
  69. reg [3:0] rx_bitcount;   
  70. reg [7:0] rx_reg;   
  71.   
  72. always @(posedge sys_clk) begin   
  73.     if(sys_rst) begin   
  74.         rx_done <= 1'b0;   
  75.         rx_busy <= 1'b0;   
  76.         rx_count16  <= 4'd0;   
  77.         rx_bitcount <= 4'd0;   
  78.     end else begin   
  79.         rx_done <= 1'b0;   
  80.   
  81.         if(enable16) begin   
  82.             if(~rx_busy) begin // look for start bit   
  83.                 if(~uart_rx2) begin // start bit found   
  84.                     rx_busy <= 1'b1;   
  85.                     rx_count16 <= 4'd7;   
  86.                     rx_bitcount <= 4'd0;   
  87.                 end   
  88.             end else begin   
  89.                 rx_count16 <= rx_count16 + 4'd1;   
  90.   
  91.                 if(rx_count16 == 4'd0) begin // sample   
  92.                     rx_bitcount <= rx_bitcount + 4'd1;   
  93.   
  94.                     if(rx_bitcount == 4'd0) begin // verify startbit   
  95.                         if(uart_rx2)   
  96.                             rx_busy <= 1'b0;   
  97.                     end else if(rx_bitcount == 4'd9) begin   
  98.                         rx_busy <= 1'b0;   
  99.                         if(uart_rx2) begin // stop bit ok   
  100.                             rx_data <= rx_reg;   
  101.                             rx_done <= 1'b1;   
  102.                         end // ignore RX error   
  103.                     end else   
  104.                         rx_reg <= {uart_rx2, rx_reg[7:1]};   
  105.                 end   
  106.             end   
  107.         end   
  108.     end   
  109. end   
  110.   
  111. //-----------------------------------------------------------------   
  112. // UART TX Logic   
  113. //-----------------------------------------------------------------   
  114. reg tx_busy;   
  115. reg [3:0] tx_bitcount;   
  116. reg [3:0] tx_count16;   
  117. reg [7:0] tx_reg;   
  118.   
  119. always @(posedge sys_clk) begin   
  120.     if(sys_rst) begin   
  121.         tx_done <= 1'b0;   
  122.         tx_busy <= 1'b0;   
  123.         uart_tx <= 1'b1;   
  124.     end else begin   
  125.         tx_done <= 1'b0;   
  126.         if(tx_wr) begin   
  127.             tx_reg <= tx_data;   
  128.             tx_bitcount <= 4'd0;   
  129.             tx_count16 <= 4'd1;   
  130.             tx_busy <= 1'b1;   
  131.             uart_tx <= 1'b0;   
  132. `ifdef SIMULATION   
  133.             $display("UART: %c", tx_data);   
  134. `endif   
  135.         end else if(enable16 && tx_busy) begin   
  136.             tx_count16  <= tx_count16 + 4'd1;   
  137.   
  138.             if(tx_count16 == 4'd0) begin   
  139.                 tx_bitcount <= tx_bitcount + 4'd1;   
  140.                    
  141.                 if(tx_bitcount == 4'd8) begin   
  142.                     uart_tx <= 1'b1;   
  143.                 end else if(tx_bitcount == 4'd9) begin   
  144.                     uart_tx <= 1'b1;   
  145.                     tx_busy <= 1'b0;   
  146.                     tx_done <= 1'b1;   
  147.                 end else begin   
  148.                     uart_tx <= tx_reg[0];   
  149.                     tx_reg <= {1'b0, tx_reg[7:1]};   
  150.                 end   
  151.             end   
  152.         end   
  153.     end   
  154. end   
  155.   
  156. endmodule
posted on 2012-12-04 13:27  龙骑士_01  阅读(438)  评论(0编辑  收藏  举报