Hardware Design: SIE
Sign in or create your account | Project List | Help
Hardware Design: SIE Git Source Tree
Root/
| 1 | //----------------------------------------------------- |
| 2 | // Design Name : uart |
| 3 | // File Name : uart.v |
| 4 | //----------------------------------------------------- |
| 5 | module uart #( |
| 6 | parameter freq_hz = 100000000, |
| 7 | parameter baud = 115200 |
| 8 | ) ( |
| 9 | input reset, |
| 10 | input clk, |
| 11 | // UART lines |
| 12 | input uart_rxd, |
| 13 | output reg uart_txd, |
| 14 | // |
| 15 | output reg [7:0] rx_data, |
| 16 | output reg rx_avail, |
| 17 | output reg rx_error, |
| 18 | input rx_ack, |
| 19 | input [7:0] tx_data, |
| 20 | input tx_wr, |
| 21 | output reg tx_busy |
| 22 | ); |
| 23 | |
| 24 | parameter divisor = freq_hz/baud/16; |
| 25 | |
| 26 | //----------------------------------------------------------------- |
| 27 | // enable16 generator |
| 28 | //----------------------------------------------------------------- |
| 29 | reg [15:0] enable16_counter; |
| 30 | |
| 31 | wire enable16; |
| 32 | assign enable16 = (enable16_counter == 0); |
| 33 | |
| 34 | always @(posedge clk) |
| 35 | begin |
| 36 | if (reset) begin |
| 37 | enable16_counter <= divisor-1; |
| 38 | end else begin |
| 39 | enable16_counter <= enable16_counter - 1; |
| 40 | if (enable16_counter == 0) begin |
| 41 | enable16_counter <= divisor-1; |
| 42 | end |
| 43 | end |
| 44 | end |
| 45 | |
| 46 | //----------------------------------------------------------------- |
| 47 | // syncronize uart_rxd |
| 48 | //----------------------------------------------------------------- |
| 49 | reg uart_rxd1; |
| 50 | reg uart_rxd2; |
| 51 | |
| 52 | always @(posedge clk) |
| 53 | begin |
| 54 | uart_rxd1 <= uart_rxd; |
| 55 | uart_rxd2 <= uart_rxd1; |
| 56 | end |
| 57 | |
| 58 | //----------------------------------------------------------------- |
| 59 | // UART RX Logic |
| 60 | //----------------------------------------------------------------- |
| 61 | reg rx_busy; |
| 62 | reg [3:0] rx_count16; |
| 63 | reg [3:0] rx_bitcount; |
| 64 | reg [7:0] rxd_reg; |
| 65 | |
| 66 | always @ (posedge clk) |
| 67 | begin |
| 68 | if (reset) begin |
| 69 | rx_busy <= 0; |
| 70 | rx_count16 <= 0; |
| 71 | rx_bitcount <= 0; |
| 72 | rx_avail <= 0; |
| 73 | rx_error <= 0; |
| 74 | end else begin |
| 75 | if (rx_ack) begin |
| 76 | rx_avail <= 0; |
| 77 | rx_error <= 0; |
| 78 | end |
| 79 | |
| 80 | if (enable16) begin |
| 81 | if (!rx_busy) begin // look for start bit |
| 82 | if (!uart_rxd2) begin // start bit found |
| 83 | rx_busy <= 1; |
| 84 | rx_count16 <= 7; |
| 85 | rx_bitcount <= 0; |
| 86 | end |
| 87 | end else begin |
| 88 | rx_count16 <= rx_count16 + 1; |
| 89 | |
| 90 | if (rx_count16 == 0) begin // sample |
| 91 | rx_bitcount <= rx_bitcount + 1; |
| 92 | |
| 93 | if (rx_bitcount == 0) begin // verify startbit |
| 94 | if (uart_rxd2) begin |
| 95 | rx_busy <= 0; |
| 96 | end |
| 97 | end else if (rx_bitcount == 9) begin // look for stop bit |
| 98 | rx_busy <= 0; |
| 99 | if (uart_rxd2) begin // stop bit ok |
| 100 | rx_data <= rxd_reg; |
| 101 | rx_avail <= 1; |
| 102 | rx_error <= 0; |
| 103 | end else begin // bas stop bit |
| 104 | rx_error <= 1; |
| 105 | end |
| 106 | end else begin |
| 107 | rxd_reg <= { uart_rxd2, rxd_reg[7:1] }; |
| 108 | end |
| 109 | end |
| 110 | end |
| 111 | end |
| 112 | end |
| 113 | end |
| 114 | |
| 115 | //----------------------------------------------------------------- |
| 116 | // UART TX Logic |
| 117 | //----------------------------------------------------------------- |
| 118 | reg [3:0] tx_bitcount; |
| 119 | reg [3:0] tx_count16; |
| 120 | reg [7:0] txd_reg; |
| 121 | |
| 122 | always @ (posedge clk) |
| 123 | begin |
| 124 | if (reset) begin |
| 125 | tx_busy <= 0; |
| 126 | uart_txd <= 1; |
| 127 | end else begin |
| 128 | if (tx_wr && !tx_busy) begin |
| 129 | txd_reg <= tx_data; |
| 130 | tx_bitcount <= 0; |
| 131 | tx_count16 <= 1; |
| 132 | tx_busy <= 1; |
| 133 | uart_txd <= 0; |
| 134 | end else if (enable16 && tx_busy) begin |
| 135 | tx_count16 <= tx_count16 + 1; |
| 136 | |
| 137 | if (tx_count16 == 0) begin |
| 138 | tx_bitcount <= tx_bitcount + 1; |
| 139 | |
| 140 | if (tx_bitcount == 8) begin |
| 141 | uart_txd <= 'b1; |
| 142 | end else if (tx_bitcount == 9) begin |
| 143 | uart_txd <= 'b1; |
| 144 | tx_busy <= 0; |
| 145 | end else begin |
| 146 | uart_txd <= txd_reg[0]; |
| 147 | txd_reg <= { 1'b0, txd_reg[7:1] }; |
| 148 | end |
| 149 | end |
| 150 | end |
| 151 | end |
| 152 | end |
| 153 | |
| 154 | |
| 155 | endmodule |
| 156 |
Branches:
master
