X-Git-Url: http://git.joshuawise.com/fpgaboy.git/blobdiff_plain/1eefdc8e89a69963b1c1a084fe4ecec844997293..298e8085b4f8f70121204fa4aed3a188034f6879:/Uart.v diff --git a/Uart.v b/Uart.v index e521304..332620b 100644 --- a/Uart.v +++ b/Uart.v @@ -10,7 +10,8 @@ module UART( input rd, input [15:0] addr, inout [7:0] data, - output reg serial = 1); + output reg serial = 1, + input serialrx); wire data_decode = (addr == `DATA_ADDR); wire stat_decode = (addr == `STAT_ADDR); @@ -19,22 +20,27 @@ module UART( reg [7:0] tx_data = 0; reg [15:0] tx_clkdiv = 0; - reg [3:0] tx_state = 4'b1011; // 1011 is the not busy state. - wire tx_busy = tx_state != 4'b1011; + reg [3:0] tx_state = 4'b0000; + reg tx_busy = 0; wire tx_newdata = (wr) && (!tx_busy) && data_decode; - assign data = (rd && stat_latch) ? (tx_busy ? 8'b1 : 8'b0) : - (rd && data_latch) ? (8'b0) : + reg rx_hasdata = 0; + reg [15:0] rx_clkdiv = 0; + reg [3:0] rx_state = 4'b0000; + reg [7:0] rx_data; + + assign data = (stat_latch) ? {6'b0, rx_hasdata, tx_busy} : + (data_latch) ? rx_data : 8'bzzzzzzzz; always @(posedge clk) begin data_latch <= rd && data_decode; stat_latch <= rd && stat_decode; - /* deal with diqing */ if(tx_newdata) begin tx_data <= data; tx_state <= 4'b0000; + tx_busy <= 1; end else if (tx_clkdiv == 0) begin tx_state <= tx_state + 1; if (tx_busy) @@ -49,14 +55,44 @@ module UART( 4'b0111: serial <= tx_data[6]; 4'b1000: serial <= tx_data[7]; 4'b1001: serial <= 1; - 4'b1010: serial <= 1; + 4'b1010: tx_busy <= 0; default: $stop; + endcase + end + + if ((rx_state == 0) && (serialrx == 0) /*&& (rx_hasdata == 0)*/) /* Kick off. */ + rx_state <= 4'b0001; + else if ((rx_state != 4'b0000) && (rx_clkdiv == 0)) begin + if (rx_state != 4'b1010) + rx_state <= rx_state + 1; + else + rx_state <= 0; + case (rx_state) + 4'b0001: begin end /* Twiddle thumbs -- this is the end of the half bit. */ + 4'b0010: rx_data[0] <= serialrx; + 4'b0011: rx_data[1] <= serialrx; + 4'b0100: rx_data[2] <= serialrx; + 4'b0101: rx_data[3] <= serialrx; + 4'b0110: rx_data[4] <= serialrx; + 4'b0111: rx_data[5] <= serialrx; + 4'b1000: rx_data[6] <= serialrx; + 4'b1001: rx_data[7] <= serialrx; + 4'b1010: begin end /* Expect a 1 */ endcase end + + rx_hasdata <= (rx_hasdata && ~(rd && data_decode)) || ((rx_state == 4'b1010) && (tx_clkdiv == 0)); - if((tx_newdata && !tx_busy) || (tx_clkdiv == `CLK_DIV)) + if(tx_newdata || (tx_clkdiv == `CLK_DIV)) tx_clkdiv <= 0; else tx_clkdiv <= tx_clkdiv + 1; + + if ((rx_state == 0) && (serialrx == 0) /*&& (rx_hasdata == 0)*/) /* Wait half a period before advancing. */ + rx_clkdiv <= `CLK_DIV / 2 + `CLK_DIV / 4; + else if (rx_clkdiv == `CLK_DIV) + rx_clkdiv <= 0; + else + rx_clkdiv <= rx_clkdiv + 1; end endmodule