File size: 1,452 Bytes
0ba037b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// 8N1 UART transmitter. Load with start when ready is high.
module uart_tx #(
  parameter int CW = 10                  // width of cpb
)(
  input  logic          clk,
  input  logic          reset,
  input  logic [CW-1:0] cpb,             // clocks per bit (>= 4)
  input  logic       start,
  input  logic [7:0] data,
  output logic       ready,
  output logic       tx
);
  logic [CW-1:0] FULL;
  assign FULL = cpb - 1'b1;

  // LSB first: start, data[7:0], stop, then one guard bit so ready rises only
  // after the stop bit has lasted a full bit time.
  logic [10:0] shreg;
  logic [3:0] left;                 // bit times still to send
  logic [CW-1:0] cnt;
  // The line is stored inverted: FPGA flip-flops power up low, so tx is idle
  // high from configuration, before the first reset edge (a low line would be a
  // start bit, i.e. a junk byte, to the host). No initial value is needed.
  logic tx_n;
  assign tx = !tx_n;

  assign ready = (left == 0);

  always_ff @(posedge clk) begin
    if (reset) begin
      tx_n <= 1'b0; left <= '0; cnt <= '0; shreg <= '1;
    end else if (left == 0) begin
      tx_n <= 1'b0;
      if (start) begin
        shreg <= {2'b11, data, 1'b0};
        left <= 4'd11;
        cnt <= '0;
      end
    end else if (cnt == 0) begin
      tx_n <= !shreg[0];
      shreg <= {1'b1, shreg[10:1]};
      left <= left - 1'b1;
      cnt <= FULL;
    end else begin
      cnt <= cnt - 1'b1;
    end
  end
endmodule