(原创)system verilog——uart发送模块的设计
仿真结果如下:
p_start是验证从载入要发送的数据到发送低有效的起始位这段时间的时序是否正确,,p_shift是验证从准备好开始发送到发送过程中
的数据的九次移位是否正确,p_state是跟踪发送过程中状态机的状态。
具体代码如下:
1
`timescale 1ns/10ps2
module uart_tx(din,load,clk,rst,txd,ready,c_state);3
parameter fifo_sva=1'b1;4
input [7:0] din; 5
input load; 6
input clk; 7
input rst; 8
output txd; 9
output ready; 10
output [3:0]c_state; //state output,just for debug11

12
logic ready; //ready status bit13
logic shift; //shift bit14
logic txd; //transmit bit15

16
logic [7:0] hold; //holding the data17
logic [8:0] send; //send bits18
19
//load data20
always_ff@(posedge clk or posedge rst)21
begin22
if(rst)23
hold<=0;24
else if(load)25
hold<=din;26
else 27
hold<=hold;28
end 29
//ready to send bit30
always_ff@(posedge clk or posedge rst)31
begin32
if(rst)33
ready<=0;34
else if(load)35
ready<=1;36
else 37
ready<=0;38
end39

40
//shift and send bit41
always_ff@(posedge clk or posedge rst)42
begin43
if(rst)begin44
send[8:0]<=9'b111111111;45
txd<=1'b1;46
end47
else if(ready)begin48

send[8:0]<=
{hold,1'b0};49
txd<=send[0];50
end51
else if(shift)begin52

send[8:0]<=
{1'b1,send[8:1]};53
txd<=send[0];54
end55
else begin56
send<=send;57
txd<=send[0];58
end59
end60

61
// state machine 62
parameter [3:0] //synopsys enum STATE_TYPE63
UART_IDLE = 4'b0000,64
UART_STARTBIT = 4'b0001,65
UART_BIT7 = 4'b0010,66
UART_BIT6 = 4'b0011,67
UART_BIT5 = 4'b0100,68
UART_BIT4 = 4'b0101,69
UART_BIT3 = 4'b0110,70
UART_BIT2 = 4'b0111,71
UART_BIT1 = 4'b1000,72
UART_BIT0 = 4'b1001,73
UART_STOPBIT = 4'b1010;74
75

76
logic [3:0] c_state;77
logic [3:0] n_state;78
79
//sequencial logic80
always_ff @ (posedge clk or posedge rst)81
begin82
if (rst) 83
c_state <= UART_IDLE; 84
else 85
c_state <= n_state; 86
end87
//combinational logic88
always_ff @ (c_state or ready or shift)89
begin 90
case (c_state) //synopsys full_case91
UART_IDLE: begin92
if (ready ) begin93
n_state <= UART_STARTBIT;94
shift = 0;95
end96
else begin97
n_state <= UART_IDLE;98
shift = 0;99
end100
end 101
UART_STARTBIT: begin102
n_state <= UART_BIT7; 103
shift = 1; 104
end105
UART_BIT7: begin106
if(shift) begin107
n_state <= UART_BIT6; 108
shift = 1; 109
end110
else begin111
n_state <= UART_BIT7; 112
shift = 0;113
end114
end115
UART_BIT6: begin116
if(shift) begin117
n_state <= UART_BIT5; 118
shift = 1; 119
end120
else begin121
n_state <= UART_BIT6; 122
shift = 0;123
end124
end125
UART_BIT5: begin126
if(shift) begin127
n_state <= UART_BIT4; 128
shift = 1; 129

130
end131
else begin132
n_state <= UART_BIT5; 133
shift = 0;134
end135
end136
UART_BIT4: begin137
if(shift) begin138
n_state <= UART_BIT3; 139
shift = 1; 140

141
end142
else begin143
n_state <= UART_BIT4; 144
shift = 0;145
end146
end147
UART_BIT3: begin148
if(shift) begin149
n_state <= UART_BIT2; 150
shift = 1; 151
end152
else begin153
n_state <= UART_BIT3; 154
shift = 0;155
end156
end157
UART_BIT2: begin158
if(shift) begin159
n_state <= UART_BIT1; 160
shift = 1; 161

162
end163
else begin164
n_state <= UART_BIT2; 165
shift = 0;166
end167
end168
UART_BIT1: begin169
if(shift) begin170
n_state <= UART_BIT0; 171
shift = 1; 172
end173
else begin174
n_state <= UART_BIT1; 175
shift = 0;176
end177
end178
UART_BIT0: begin179
if(shift) begin180
n_state <= UART_STOPBIT; 181
shift = 1; 182
end183
else begin184
n_state <= UART_BIT0; 185
shift = 0;186
end187
end188
UART_STOPBIT: begin189
if(!ready) begin190
n_state <= UART_IDLE; 191
shift = 0; 192
end193
else if (ready) begin194
n_state <= UART_STARTBIT;195
shift = 0; 196
end197
else begin198
n_state <= UART_STOPBIT;199
shift = 0; 200
end201
end202
default: begin203
n_state <= UART_IDLE;204
shift = 0; 205
end 206
endcase207
end 208

209

210
//sva sequence description211
sequence s_state;212
(c_state==UART_STARTBIT) ##1(c_state==UART_BIT7) 213
##1(c_state==UART_BIT6) ##1(c_state==UART_BIT5) 214
##1(c_state==UART_BIT4) ##1(c_state==UART_BIT3) 215
##1(c_state==UART_BIT2) ##1(c_state==UART_BIT1) 216
##1(c_state==UART_BIT0) ##1(c_state==UART_STOPBIT);217
endsequence218
//sva property description219
property p_start; 220
@(posedge clk)221
load|=>ready ##2!txd; 222
endproperty223
property p_state; 224
@(posedge clk)225
((!rst)&&ready)|=>s_state;226
endproperty227
property p_shift; 228
@(posedge clk)229
((!rst)&&ready)|=>(shift[*9]); 230
endproperty231

232
//sva check233
always_ff@(posedge clk)234
if(fifo_sva)235
begin236
a_start:assert property(p_start) 237
else $display("start error at %d !",$time);238
a_state:assert property(p_state)239
else $display("state machine error at %d !",$time);240
a_shift:assert property(p_shift)241
else $display("shift error at %d !",$time); 242
c_start:cover property(p_start);243
c_c_state:cover property(p_state);244
c_shift:cover property(p_shift);245
end246
endmodule247

testbench如下:
1
`timescale 1ns/10ps2
module uart_tx_testbench; 3
logic [7:0] din;4
logic load;5
logic clk;6
logic rst;7
wire txd;8
wire ready;9
wire[3:0] c_state;10
uart_tx #(1)11
uart_tx_inst(12
.din(din),13
.load(load),14
.clk(clk),15
.rst(rst),16
.txd(txd),17
.ready(ready),18
.c_state(c_state)19
);20
parameter p=10;21
initial22
begin23
clk=1;24
rst=1;25
load=0;26
#1 rst=0;27
#p load=1;28
din=8'b10101010;29
#p load=0;30
#p ;#p ;#p ;#p ;#p ;#p ;#p ;#p ;31
#p ;#p ;#p ;#p ;#p ;#p ;#p ;#p ;32
#p load=1;33
din=8'b11001100;34
#p load=0;35
#p ;#p ;#p ;#p ;#p ;#p ;#p ;#p ;36
#p load=1;37
din=8'b11110000;38
#p load=0;39
#1000 $finish;40
end41
initial42
begin43
$monitor("din=%b,txd=%b,time=%d",din,txd,$time);44
end45
always #5 clk=~clk;46
endmodule47

以上代码都已通过调试,调试环境为modelsim6.3f

浙公网安备 33010602011771号