-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserial_tx.v
109 lines (100 loc) · 2.83 KB
/
serial_tx.v
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
module serial_tx #(
parameter CLK_PER_BIT = 50
)(
input clk,
input rst,
output tx,
input block,
output busy,
input [7:0] data,
input new_data
);
// clog2 is 'ceiling of log base 2' which gives you the number of bits needed to store a value
parameter CTR_SIZE = $clog2(CLK_PER_BIT);
localparam STATE_SIZE = 2;
localparam IDLE = 2'd0,
START_BIT = 2'd1,
DATA = 2'd2,
STOP_BIT = 2'd3;
reg [CTR_SIZE-1:0] ctr_d, ctr_q;
reg [2:0] bit_ctr_d, bit_ctr_q;
reg [7:0] data_d, data_q;
reg [STATE_SIZE-1:0] state_d, state_q = IDLE;
reg tx_d, tx_q;
reg busy_d, busy_q;
reg block_d, block_q;
assign tx = tx_q;
assign busy = busy_q;
always @(*) begin
block_d = block;
ctr_d = ctr_q;
bit_ctr_d = bit_ctr_q;
data_d = data_q;
state_d = state_q;
busy_d = busy_q;
case (state_q)
IDLE: begin
if (block_q) begin
busy_d = 1'b1;
tx_d = 1'b1;
end else begin
busy_d = 1'b0;
tx_d = 1'b1;
bit_ctr_d = 3'b0;
ctr_d = 1'b0;
if (new_data) begin
data_d = data;
state_d = START_BIT;
busy_d = 1'b1;
end
end
end
START_BIT: begin
busy_d = 1'b1;
ctr_d = ctr_q + 1'b1;
tx_d = 1'b0;
if (ctr_q == CLK_PER_BIT - 1) begin
ctr_d = 1'b0;
state_d = DATA;
end
end
DATA: begin
busy_d = 1'b1;
tx_d = data_q[bit_ctr_q];
ctr_d = ctr_q + 1'b1;
if (ctr_q == CLK_PER_BIT - 1) begin
ctr_d = 1'b0;
bit_ctr_d = bit_ctr_q + 1'b1;
if (bit_ctr_q == 7) begin
state_d = STOP_BIT;
end
end
end
STOP_BIT: begin
busy_d = 1'b1;
tx_d = 1'b1;
ctr_d = ctr_q + 1'b1;
if (ctr_q == CLK_PER_BIT - 1) begin
state_d = IDLE;
end
end
default: begin
state_d = IDLE;
end
endcase
end
always @(posedge clk) begin
if (rst) begin
state_q <= IDLE;
tx_q <= 1'b1;
end else begin
state_q <= state_d;
tx_q <= tx_d;
end
block_q <= block_d;
data_q <= data_d;
bit_ctr_q <= bit_ctr_d;
ctr_q <= ctr_d;
busy_q <= busy_d;
end
endmodule