(原创)uart发送数据模块设计
我们可以发送任意八位数据din,din之间可以间隔任何时间,只要模块接受到新的din数据,就会以固定的频率
一个接一个的将数据发出。仿真波形如下:

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 register4
input clk; // 1x transmit clock5
input rst; // resets the registers6
output txd; // output data7
output ready; // indicates ready to recieve char to transmit8
output [3:0]c_state; //state output,just for debug9

10
reg ready; //ready status bit11
reg shift; //shift bit12
reg txd; //transmit bit13

14
reg [7:0] hold; //holding register for the data15
reg [8:0] send; //send bits16
17
//load data18
always@(posedge clk or posedge rst)19
begin20
if(rst)21
hold<=0;22
else if(load)23
hold<=din;24
else 25
hold<=hold;26
end 27
//ready to send bit28
always@(posedge clk or posedge rst)29
begin30
if(rst)31
ready<=0;32
else if(load)33
ready<=1;34
else 35
ready<=0;36
end37

38
//shift and send bit39
always@(posedge clk or posedge rst)40
begin41
if(rst)begin42
send[8:0]<=9'b111111111;43
txd<=1'b1;44
end45
else if(ready)begin46

send[8:0]<=
{hold,1'b0};47
txd<=send[0];48
end49
else if(shift)begin50

send[8:0]<=
{1'b1,send[8:1]};51
txd<=send[0];52
end53
else begin54
send<=send;55
txd<=send[0];56
end57
end58

59
// state machine 60
parameter [3:0] //synopsys enum STATE_TYPE61
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

74
reg [3:0] c_state;75
reg [3:0] n_state;76
77
//sequencial logic78
always @ (posedge clk or posedge rst)79
begin80
if (rst) 81
c_state <= UART_IDLE; 82
else 83
c_state <= n_state; 84
end85
//combinational logic86
always @ (c_state or ready or shift)87
begin 88
case (c_state) //synopsys full_case89
UART_IDLE: begin90
if (ready ) begin91
n_state <= UART_STARTBIT;92
shift = 0;93
end94
else begin95
n_state <= UART_IDLE;96
shift = 0;97
end98
end 99
UART_STARTBIT: begin100
n_state <= UART_BIT7; 101
shift = 1; 102
end103
UART_BIT7: begin104
if(shift) begin105
n_state <= UART_BIT6; 106
shift = 1; 107
end108
else begin109
n_state <= UART_BIT7; 110
shift = 0;111
end112
end113
UART_BIT6: begin114
if(shift) begin115
n_state <= UART_BIT5; 116
shift = 1; 117
end118
else begin119
n_state <= UART_BIT6; 120
shift = 0;121
end122
end123
UART_BIT5: begin124
if(shift) begin125
n_state <= UART_BIT4; 126
shift = 1; 127

128
end129
else begin130
n_state <= UART_BIT5; 131
shift = 0;132
end133
end134
UART_BIT4: begin135
if(shift) begin136
n_state <= UART_BIT3; 137
shift = 1; 138

139
end140
else begin141
n_state <= UART_BIT4; 142
shift = 0;143
end144
end145
UART_BIT3: begin146
if(shift) begin147
n_state <= UART_BIT2; 148
shift = 1; 149
end150
else begin151
n_state <= UART_BIT3; 152
shift = 0;153
end154
end155
UART_BIT2: begin156
if(shift) begin157
n_state <= UART_BIT1; 158
shift = 1; 159

160
end161
else begin162
n_state <= UART_BIT2; 163
shift = 0;164
end165
end166
UART_BIT1: begin167
if(shift) begin168
n_state <= UART_BIT0; 169
shift = 1; 170
end171
else begin172
n_state <= UART_BIT1; 173
shift = 0;174
end175
end176
UART_BIT0: begin177
if(shift) begin178
n_state <= UART_STOPBIT; 179
shift = 1; 180
end181
else begin182
n_state <= UART_BIT0; 183
shift = 0;184
end185
end186
UART_STOPBIT: begin187
if(!ready) begin188
n_state <= UART_IDLE; 189
shift = 0; 190
end191
else if (ready) begin192
n_state <= UART_STARTBIT;193
shift = 0; 194
end195
else begin196
n_state <= UART_STOPBIT;197
shift = 0; 198
end199
end200
default: begin201
n_state <= UART_IDLE;202
shift = 0; 203
end 204
endcase205
end 206
endmodule207

208

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
initial20
begin21
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
end39
initial40
begin41
$monitor("din=%b,txd=%b,time=%d",din,txd,$time);42
end43
always #5 clk=~clk;44
endmodule

浙公网安备 33010602011771号