]>
Commit | Line | Data |
---|---|---|
7d9d69c7 | 1 | `define IN_CLK 8388608 |
f888201b | 2 | `define OUT_CLK 57600 |
a0267255 | 3 | `define CLK_DIV `IN_CLK / `OUT_CLK |
1eefdc8e JW |
4 | `define DATA_ADDR 16'hFF52 |
5 | `define STAT_ADDR 16'hFF53 | |
a0267255 JW |
6 | |
7 | module UART( | |
8 | input clk, | |
9 | input wr, | |
10 | input rd, | |
11 | input [15:0] addr, | |
a85b19a7 | 12 | inout [7:0] data, |
1e26cecc | 13 | output reg serial = 1); |
a8f4468d | 14 | |
1eefdc8e JW |
15 | wire data_decode = (addr == `DATA_ADDR); |
16 | wire stat_decode = (addr == `STAT_ADDR); | |
17 | reg data_latch = 0; | |
18 | reg stat_latch = 0; | |
a85b19a7 | 19 | |
1eefdc8e JW |
20 | reg [7:0] tx_data = 0; |
21 | reg [15:0] tx_clkdiv = 0; | |
22 | reg [3:0] tx_state = 4'b1011; // 1011 is the not busy state. | |
23 | wire tx_busy = tx_state != 4'b1011; | |
24 | wire tx_newdata = (wr) && (!tx_busy) && data_decode; | |
a85b19a7 | 25 | |
1eefdc8e JW |
26 | assign data = (rd && stat_latch) ? (tx_busy ? 8'b1 : 8'b0) : |
27 | (rd && data_latch) ? (8'b0) : | |
28 | 8'bzzzzzzzz; | |
a0267255 | 29 | |
1eefdc8e | 30 | always @(posedge clk) |
a0267255 | 31 | begin |
1eefdc8e JW |
32 | data_latch <= rd && data_decode; |
33 | stat_latch <= rd && stat_decode; | |
a0267255 | 34 | /* deal with diqing */ |
1eefdc8e JW |
35 | if(tx_newdata) begin |
36 | tx_data <= data; | |
37 | tx_state <= 4'b0000; | |
38 | end else if (tx_clkdiv == 0) begin | |
39 | tx_state <= tx_state + 1; | |
40 | if (tx_busy) | |
41 | case (tx_state) | |
7d9d69c7 | 42 | 4'b0000: serial <= 0; |
1eefdc8e JW |
43 | 4'b0001: serial <= tx_data[0]; |
44 | 4'b0010: serial <= tx_data[1]; | |
45 | 4'b0011: serial <= tx_data[2]; | |
46 | 4'b0100: serial <= tx_data[3]; | |
47 | 4'b0101: serial <= tx_data[4]; | |
48 | 4'b0110: serial <= tx_data[5]; | |
49 | 4'b0111: serial <= tx_data[6]; | |
50 | 4'b1000: serial <= tx_data[7]; | |
7d9d69c7 | 51 | 4'b1001: serial <= 1; |
1eefdc8e | 52 | 4'b1010: serial <= 1; |
a0267255 JW |
53 | default: $stop; |
54 | endcase | |
55 | end | |
56 | ||
1eefdc8e JW |
57 | if((tx_newdata && !tx_busy) || (tx_clkdiv == `CLK_DIV)) |
58 | tx_clkdiv <= 0; | |
a0267255 | 59 | else |
1eefdc8e | 60 | tx_clkdiv <= tx_clkdiv + 1; |
a0267255 JW |
61 | end |
62 | endmodule |