我们可以发送任意八位数据din,din之间可以间隔任何时间,只要模块接受到新的din数据,就会以固定的频率
一个接一个的将数据发出。仿真波形如下:
![](https://www.cnblogs.com/images/cnblogs_com/changlong/QQ截图未命名1.jpg)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
设计代码:
1
module uart_tx(din,load,clk,rst,txd,ready,c_state);
2
input [7:0] din; //data to be transmitted
3
input load; //loads the transmit register
4
input clk; // 1x transmit clock
5
input rst; // resets the registers
6
output txd; // output data
7
output ready; // indicates ready to recieve char to transmit
8
output [3:0]c_state; //state output,just for debug
9![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
10
reg ready; //ready status bit
11
reg shift; //shift bit
12
reg txd; //transmit bit
13![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
14
reg [7:0] hold; //holding register for the data
15
reg [8:0] send; //send bits
16
17
//load data
18
always@(posedge clk or posedge rst)
19
begin
20
if(rst)
21
hold<=0;
22
else if(load)
23
hold<=din;
24
else
25
hold<=hold;
26
end
27
//ready to send bit
28
always@(posedge clk or posedge rst)
29
begin
30
if(rst)
31
ready<=0;
32
else if(load)
33
ready<=1;
34
else
35
ready<=0;
36
end
37![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
38
//shift and send bit
39
always@(posedge clk or posedge rst)
40
begin
41
if(rst)begin
42
send[8:0]<=9'b111111111;
43
txd<=1'b1;
44
end
45
else if(ready)begin
46![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
send[8:0]<=
{hold,1'b0};
47
txd<=send[0];
48
end
49
else if(shift)begin
50![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
send[8:0]<=
{1'b1,send[8:1]};
51
txd<=send[0];
52
end
53
else begin
54
send<=send;
55
txd<=send[0];
56
end
57
end
58![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
59
// state machine
60
parameter [3:0] //synopsys enum STATE_TYPE
61
UART_IDLE = 4'b0000,
62
UART_STARTBIT = 4'b0001,
63
UART_BIT7 = 4'b0010,
64
UART_BIT6 = 4'b0011,
65
UART_BIT5 = 4'b0100,
66
UART_BIT4 = 4'b0101,
67
UART_BIT3 = 4'b0110,
68
UART_BIT2 = 4'b0111,
69
UART_BIT1 = 4'b1000,
70
UART_BIT0 = 4'b1001,
71
UART_STOPBIT = 4'b1010;
72
73![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
74
reg [3:0] c_state;
75
reg [3:0] n_state;
76
77
//sequencial logic
78
always @ (posedge clk or posedge rst)
79
begin
80
if (rst)
81
c_state <= UART_IDLE;
82
else
83
c_state <= n_state;
84
end
85
//combinational logic
86
always @ (c_state or ready or shift)
87
begin
88
case (c_state) //synopsys full_case
89
UART_IDLE: begin
90
if (ready ) begin
91
n_state <= UART_STARTBIT;
92
shift = 0;
93
end
94
else begin
95
n_state <= UART_IDLE;
96
shift = 0;
97
end
98
end
99
UART_STARTBIT: begin
100
n_state <= UART_BIT7;
101
shift = 1;
102
end
103
UART_BIT7: begin
104
if(shift) begin
105
n_state <= UART_BIT6;
106
shift = 1;
107
end
108
else begin
109
n_state <= UART_BIT7;
110
shift = 0;
111
end
112
end
113
UART_BIT6: begin
114
if(shift) begin
115
n_state <= UART_BIT5;
116
shift = 1;
117
end
118
else begin
119
n_state <= UART_BIT6;
120
shift = 0;
121
end
122
end
123
UART_BIT5: begin
124
if(shift) begin
125
n_state <= UART_BIT4;
126
shift = 1;
127![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
128
end
129
else begin
130
n_state <= UART_BIT5;
131
shift = 0;
132
end
133
end
134
UART_BIT4: begin
135
if(shift) begin
136
n_state <= UART_BIT3;
137
shift = 1;
138![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
139
end
140
else begin
141
n_state <= UART_BIT4;
142
shift = 0;
143
end
144
end
145
UART_BIT3: begin
146
if(shift) begin
147
n_state <= UART_BIT2;
148
shift = 1;
149
end
150
else begin
151
n_state <= UART_BIT3;
152
shift = 0;
153
end
154
end
155
UART_BIT2: begin
156
if(shift) begin
157
n_state <= UART_BIT1;
158
shift = 1;
159![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
160
end
161
else begin
162
n_state <= UART_BIT2;
163
shift = 0;
164
end
165
end
166
UART_BIT1: begin
167
if(shift) begin
168
n_state <= UART_BIT0;
169
shift = 1;
170
end
171
else begin
172
n_state <= UART_BIT1;
173
shift = 0;
174
end
175
end
176
UART_BIT0: begin
177
if(shift) begin
178
n_state <= UART_STOPBIT;
179
shift = 1;
180
end
181
else begin
182
n_state <= UART_BIT0;
183
shift = 0;
184
end
185
end
186
UART_STOPBIT: begin
187
if(!ready) begin
188
n_state <= UART_IDLE;
189
shift = 0;
190
end
191
else if (ready) begin
192
n_state <= UART_STARTBIT;
193
shift = 0;
194
end
195
else begin
196
n_state <= UART_STOPBIT;
197
shift = 0;
198
end
199
end
200
default: begin
201
n_state <= UART_IDLE;
202
shift = 0;
203
end
204
endcase
205
end
206
endmodule
207![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
208![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
testbench代码:
1
module uart_tx_testbench;
2
reg [7:0] din;
3
reg load;
4
reg clk;
5
reg rst;
6
wire txd;
7
wire ready;
8
wire[3:0] c_state;
9
uart_tx uart_tx_inst(
10
.din(din),
11
.load(load),
12
.clk(clk),
13
.rst(rst),
14
.txd(txd),
15
.ready(ready),
16
.c_state(c_state)
17
);
18
parameter p=10;
19
initial
20
begin
21
clk=0;
22
rst=1;
23
load=0;
24
#1 rst=0;
25
#p load=1;
26
din=8'b10101010;
27
#p load=0;
28
#p ;#p ;#p ;#p ;#p ;#p ;#p ;#p ;
29
#p ;#p ;#p ;#p ;#p ;#p ;#p ;#p ;
30
#p load=1;
31
din=8'b11001100;
32
#p load=0;
33
#p ;#p ;#p ;#p ;#p ;#p ;#p ;#p ;
34
#p load=1;
35
din=8'b11110000;
36
#p load=0;
37
#1000 $finish;
38
end
39
initial
40
begin
41
$monitor("din=%b,txd=%b,time=%d",din,txd,$time);
42
end
43
always #5 clk=~clk;
44
endmodule