+`define IN_CLK 8400000
+`define OUT_CLK 9600
+`define CLK_DIV `IN_CLK / `OUT_CLK
+`define MMAP_ADDR 16'hFF50
+
+module UART(
+ input clk,
+ input wr,
+ input rd,
+ input [15:0] addr,
+ input [7:0] data,
+ output reg serial);
+
+ reg [7:0] data_stor = 0;
+ reg [15:0] clkdiv = 0;
+ reg have_data = 0;
+ reg data_end = 0;
+ reg [3:0] diqing = 4'b0000;
+
+ wire new = (wr) && (!have_data) && (addr == `MMAP_ADDR);
+
+ always @ (negedge clk)
+ begin
+`define FUQING 4'b1010
+ /* deal with diqing */
+ if(new) begin
+ data_stor <= ~data;
+ have_data <= 1;
+ diqing <= 4'b0000;
+ end else if (clkdiv == 0) begin
+ diqing <= diqing + 1;
+ if (have_data)
+ case (diqing)
+ 4'b0000: serial <= 1;
+ 4'b0001: serial <= data_stor[0];
+ 4'b0010: serial <= data_stor[1];
+ 4'b0011: serial <= data_stor[2];
+ 4'b0100: serial <= data_stor[3];
+ 4'b0101: serial <= data_stor[4];
+ 4'b0110: serial <= data_stor[5];
+ 4'b0111: serial <= data_stor[6];
+ 4'b1000: serial <= data_stor[7];
+ 4'b1001: serial <= 0;
+ 4'b1010: have_data <= 0;
+ default: $stop;
+ endcase
+ end
+
+ /* deal with clkdiv */
+ if((new && !have_data) || clkdiv == `CLK_DIV)
+ clkdiv <= 0;
+ else
+ clkdiv <= clkdiv + 1;
+ end
+endmodule