Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Dec 27th, 2011  |  syntax: VeriLog  |  size: 4.54 KB  |  views: 99  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. `timescale 1ns / 1ps
  2. /**
  3.         @brief A single 8-bit, no parity, 1 stop bit serial port.
  4.        
  5.         This is the raw UART and does not have a FIFO etc. The parent module must read
  6.         data the cycle after it becomes available and process or store it.
  7.        
  8.         @param clk              20.48 MHz clock signal
  9.         @param clkdiv   Clock divisor for baud rate generator (115200 baud = 178)
  10.  
  11.         @param tx               Outbound serial data line
  12.         @param txin             8-bit wide bus containing data to be transmitted
  13.         @param txrdy    Bring high for 1 clk when data is ready to be transmitted
  14.         @param txactive Indicates if transmitter is busy
  15.        
  16.         @param rx               Inbound serial data line
  17.         @param rxout    8-bit wide bus containing data recieved
  18.         @param rxrdy    Goes high for one clk when valid data is present on rxout
  19.         @param rxactive Indicates if reciever is busy
  20.  */
  21. module UART(clk, clkdiv, tx, txin, txrdy, txactive, rx, rxout, rxrdy, rxactive);
  22.  
  23.         input wire clk;
  24.         input wire[15:0] clkdiv;
  25.         input wire rx;
  26.        
  27.         //1/4 of the clock divisor (for 90 degree phase offset)
  28.         wire[13:0] clkdiv_offset;
  29.         assign clkdiv_offset = clkdiv[15:2];
  30.        
  31.         ///////////////////////////////////////////////////////////////////////////////////////////////
  32.         //Receiver
  33.         reg[15:0] rxbrg;
  34.         output reg rxactive;
  35.         reg[4:0] rxbitcount;
  36.         reg[7:0] rxbuf;
  37.         output reg[7:0] rxout;
  38.         output reg rxrdy;
  39.         initial begin
  40.                 rxbrg <= 0;
  41.                 rxactive <= 0;
  42.                 rxbitcount <= 0;
  43.                 rxbuf <= 0;
  44.                 rxout <= 0;
  45.                 rxrdy <= 0;
  46.         end
  47.        
  48.         always @(posedge clk) begin
  49.                
  50.                 //Clear data from output after one clock
  51.                 if(rxrdy) begin
  52.                         rxrdy <= 0;
  53.                         rxout <= 0;
  54.                 end
  55.                
  56.                 //If not currently recieving, look for falling edge on RX (start bit)
  57.                 if(!rxactive) begin
  58.                         if(rx == 0) begin
  59.                                
  60.                                 //Falling edge, start receiving after 1.25 bit period
  61.                                 //We want to sample 90 degrees out of phase with the original signal to get nice stable values
  62.                                 rxactive <= 1;
  63.                                 rxbrg <= clkdiv_offset + clkdiv;
  64.                                 rxbitcount <= 0;
  65.                         end
  66.                 end
  67.                
  68.                 //Currently recieving
  69.                 else begin
  70.                         rxbrg <= rxbrg - 1;
  71.                        
  72.                         //Time to sample a new bit
  73.                         if(rxbrg == 0) begin
  74.                        
  75.                                 //If we are on bits 0 through 7 (not the stop bit) read the bit into the rxbuf and bump the bit count, then reset the baud generator
  76.                                 if(rxbitcount < 8) begin
  77.                                         rxbuf <= {rx, rxbuf[7:1]};
  78.                                         rxbitcount <= rxbitcount + 1;
  79.                                         rxbrg <= clkdiv;
  80.                                 end
  81.                                
  82.                                 //Stop bit
  83.                                 else begin
  84.                                        
  85.                                         //Should always be 1, print warning in sim if this isnt the case
  86.                                         if(rx != 1)
  87.                                                 $display("[UART] Warning - stop bit isn't zero");
  88.                                        
  89.                                         //We're done reading
  90.                                         rxbitcount <= 0;
  91.                                         rxactive <= 0;
  92.                                        
  93.                                         //Data is ready
  94.                                         rxout <= rxbuf;
  95.                                         rxrdy <= 1;
  96.                                         $display("[UART] Read byte 0x%02x - '%c'", rxbuf, rxbuf);
  97.                                 end
  98.                                
  99.                         end
  100.        
  101.                 end
  102.                
  103.         end
  104.        
  105.         ///////////////////////////////////////////////////////////////////////////////////////////////
  106.         //Transmitter
  107.         output reg tx;
  108.         input wire txrdy;
  109.         input wire [7:0] txin;
  110.        
  111.         reg[15:0] txbrg;
  112.         reg[7:0] txbuf;
  113.         output reg txactive;
  114.         reg [3:0] txbitcount;
  115.         initial begin
  116.                 tx <= 1;
  117.                 txbuf <= 0;
  118.                 txactive <= 0;
  119.                 txbrg <= 0;
  120.                 txbitcount <= 0;
  121.         end
  122.        
  123.         always @(posedge clk) begin
  124.                
  125.                 //Time to start sending a new byte?
  126.                 if(txrdy) begin
  127.                
  128.                         //Already transmitting? Drop the byte, nothing we can do here.
  129.                         //TODO: add a FIFO
  130.                         if(txactive) begin
  131.                                 $display("[UART] Warning - transmit buffer overflow, byte dropped");
  132.                         end
  133.                        
  134.                         //Nope, set up a transmission
  135.                         else begin
  136.                                 if(txin > 8'h20) begin
  137.                                         $display("[UART] sending byte 0x%02x - '%c'", txin, txin);
  138.                                 end
  139.                                 else begin
  140.                                         $display("[UART] sending byte 0x%02x", txin);
  141.                                 end
  142.                                 txbuf <= txin;
  143.                                 txactive <= 1;
  144.                                 txbitcount <= 0;
  145.                                
  146.                                 //Send the start bit immediately
  147.                                 tx <= 0;
  148.                                 txbrg <= clkdiv;
  149.                         end
  150.                        
  151.                 end
  152.                
  153.                 //Currently transmitting?
  154.                 if(txactive) begin
  155.                
  156.                         //Done with this bit?
  157.                         if(txbrg == 0) begin
  158.                                
  159.                                 //Are we still sending normal data bits?
  160.                                 //Send the next data bit (LSB first)
  161.                                 if(txbitcount < 8) begin
  162.                                         txbitcount <= txbitcount + 1;
  163.                                         tx <= txbuf[0];
  164.                                         txbuf <= {1'b0, txbuf[7:1]};
  165.                                         txbrg <= clkdiv;
  166.                                 end
  167.                                
  168.                                 //Time to send the stop bit?
  169.                                 //Send it
  170.                                 else if(txbitcount == 8) begin
  171.                                         txbitcount <= 9;
  172.                                         tx <= 1;
  173.                                         txbrg <= clkdiv;
  174.                                 end
  175.                                
  176.                                 //Done sending? Reset stuff
  177.                                 else if(txbitcount == 9) begin
  178.                                         txbitcount <= 0;
  179.                                         txactive <= 0;
  180.                                 end
  181.                                
  182.                         end
  183.                        
  184.                         //Nope, just keep count
  185.                         else begin
  186.                                 txbrg <= txbrg - 1;
  187.                         end
  188.                
  189.                 end
  190.                
  191.         end
  192.  
  193. endmodule
clone this paste RAW Paste Data