]> Joshua Wise's Git repositories - fpgaboy.git/blob - Uart.v
Fix some simulator-only bugs involving debugging/illegal states. Make rd and wr...
[fpgaboy.git] / Uart.v
1 `define IN_CLK 8388608
2 `define OUT_CLK 57600
3 `define CLK_DIV `IN_CLK / `OUT_CLK
4 `define MMAP_ADDR 16'hFF50
5
6 module UART(
7         input clk,
8         input wr,
9         input rd,
10         input [15:0] addr,
11         inout [7:0] data,
12         output reg serial = 1);
13
14         reg rdlatch = 0;
15         wire decode = (addr == `MMAP_ADDR);
16         
17         wire [7:0] odata;
18         assign data = rdlatch ? odata : 8'bzzzzzzzz;
19
20         reg [7:0] data_stor = 0;
21         reg [15:0] clkdiv = 0;
22         reg have_data = 0;
23         reg [3:0] diqing = 4'b0000;
24         
25         wire newdata = (wr) && (!have_data) && decode;
26         
27         assign odata = have_data ? 8'b1 : 8'b0;
28
29         always @ (posedge clk)
30         begin
31                 rdlatch <= rd && decode;
32                 /* deal with diqing */
33                 if(newdata) begin
34                         data_stor <= data;
35                         have_data <= 1;
36                         diqing <= 4'b0000;
37                 end else if (clkdiv == 0) begin
38                         diqing <= diqing + 1;
39                         if (have_data)
40                                 case (diqing)
41                                 4'b0000: serial <= 0;
42                                 4'b0001: serial <= data_stor[0];
43                                 4'b0010: serial <= data_stor[1];
44                                 4'b0011: serial <= data_stor[2];
45                                 4'b0100: serial <= data_stor[3];
46                                 4'b0101: serial <= data_stor[4];
47                                 4'b0110: serial <= data_stor[5];
48                                 4'b0111: serial <= data_stor[6];
49                                 4'b1000: serial <= data_stor[7];
50                                 4'b1001: serial <= 1;
51                                 4'b1010: have_data <= 0;
52                                 default: $stop;
53                         endcase
54                 end
55
56                 /* deal with clkdiv */
57                 if((newdata && !have_data) || clkdiv == `CLK_DIV)
58                         clkdiv <= 0;
59                 else
60                         clkdiv <= clkdiv + 1;
61         end
62 endmodule
This page took 0.027743 seconds and 4 git commands to generate.