(原创)uart接收模块的设计
在此接受模块中,我们用的是16倍采样频率,每次都是在发送数据的中间采样,这样能保证采集到数
据的正确性与完整性,而且设计了起始位采样同步计数器,采样数据同步计数器,更加保证采到的数据的
正确性。才传送过程中,我们允许每8位的数据间有任意时间间隔,采用低起始位和高截止位作为标志。
仿真波形如下:

模块代码如下:
1module uart_rx(clk_16,rst,rxd,dout,error_bit,overrun,ready,busy,c_state);
2 output [7:0] dout; //data output from input shift register
3 input clk_16; //system clock
4 input rst;
5 input rxd; //serial port input
6 output error_bit; //framing error
7 output overrun; //overrun error
8 output ready; //data is ready
9 output busy;
10 output [3:0] c_state; //just for debug
11
12
13 reg busy;
14 reg ready;
15
16 reg din,din1;
17 reg start; //indicates a start condition
18 reg synstart; //synchronize the clock bit divider
19 reg [2:0] start_cnt;
20 reg synbit;
21 reg [3:0] bit_cnt; //divide by sixteen bit counter
22 reg bitenable;
23
24 reg shift; //enable shifter
25 reg done; //indicate all bits shifted in
26
27 reg [3:0] n_state;
28 reg [3:0] c_state;
29 reg [7:0] hold; //data hold in register
30 reg [7:0] dout;
31
32 wire underrun;
33 wire overrun;
34 wire error_bit;
35
36always@(posedge clk_16 or posedge rst)
37begin
38 if(rst)begin
39 din<=1;
40 din1<=1;
41 end
42 else
43 din<=din1;
44 din1<=rxd;
45end
46
47//synchronize the start
48always@(din or din1 or busy)
49begin
50 if(din&&!din1&&!busy)
51 synstart<=1;
52 else
53 synstart<=0;
54end
55
56always @(posedge clk_16 or posedge rst)
57begin
58 if (rst)
59 start_cnt <= 4'b0; //initialize counter
60 else if(synstart) //synchronize
61 start_cnt <= 4'b0;
62 else if(!busy&&!din1)
63 start_cnt<=start_cnt+1; //count
64 else
65 start_cnt<=0;
66end
67
68always@(start_cnt or busy)
69begin
70 if(rst)
71 start<=0;
72 else if(!busy&&(start_cnt==4'b110))
73 start<=1;
74 else
75 start<=0;
76end
77always@(posedge clk_16 or posedge rst)
78begin
79 if(rst)
80 busy<=0;
81 else if(start)
82 busy<=1;
83 else if(done)
84 busy<=0;
85 else
86 busy<=busy;
87end
88//synchronize the sending bit,
89always@(start or busy)
90begin
91 if(start&&!busy)
92 synbit<=1;
93 else
94 synbit<=0;
95end
96
97always @(posedge clk_16 or posedge rst)
98begin
99 if (rst)
100 bit_cnt <= 4'b0; //initialize counter
101 else if (synbit) //synchronize
102 bit_cnt<= 4'b0;
103 else
104 bit_cnt=bit_cnt+1; //count
105end
106
107always@(bit_cnt or busy or rst)
108begin
109 if(rst)
110 bitenable<=0;
111 else if(busy&&(bit_cnt==4'b1111))
112 bitenable<=1;
113 else
114 bitenable<=0;
115end
116
117always@(posedge clk_16 or posedge rst)
118begin
119 if(rst)
120 hold<=8'b00000000;
121 else if(shift)
122 hold[7:0]<={din,hold[7:1]};
123 else
124 hold<=hold;
125end
126
127always@(posedge clk_16 or posedge rst)
128begin
129 if(rst)
130 ready<=0;
131 else if(done)begin
132 ready<=1;
133 dout<=hold;
134 end
135 else
136 ready<=0;
137end
138
139
140parameter [3:0] //synopsys enum STATE_TYPE
141 UART_IDLE = 4'b0000,
142 UART_STARTBIT = 4'b0001,
143 UART_BIT7 = 4'b0010,
144 UART_BIT6 = 4'b0011,
145 UART_BIT5 = 4'b0100,
146 UART_BIT4 = 4'b0101,
147 UART_BIT3 = 4'b0110,
148 UART_BIT2 = 4'b0111,
149 UART_BIT1 = 4'b1000,
150 UART_BIT0 = 4'b1001,
151 UART_STOPBIT = 4'b1010;
152 //sequential logic
153 always @ (posedge clk_16 or posedge rst)
154 begin
155 if (rst) c_state <= UART_IDLE;
156 else c_state <= n_state;
157 end
158 //conbinational logic
159 always @ (c_state or bitenable or start)
160 begin
161 case (c_state) //synopsys full_case
162 UART_IDLE: begin
163 if(start)
164 begin
165 n_state = UART_STARTBIT;
166 shift = 0;
167 done = 0;
168 end
169 else
170 begin
171 n_state = UART_IDLE;
172 shift = 0;
173 done = 0;
174 end
175 end
176 UART_STARTBIT: begin
177 if(bitenable)
178 begin
179 n_state = UART_BIT7;
180 shift = 1;
181 done = 0;
182 end
183 else
184 begin
185 n_state = UART_STARTBIT;
186 shift = 0;
187 done = 0;
188 end
189 end
190 UART_BIT7: begin
191 if(bitenable)
192 begin
193 n_state = UART_BIT6;
194 shift = 1;
195 done = 0;
196 end
197 else
198 begin
199 n_state = UART_BIT7;
200 shift = 0;
201 done = 0;
202 end
203 end
204 UART_BIT6: begin
205 if(bitenable)
206 begin
207 n_state = UART_BIT5;
208 shift = 1;
209 done = 0;
210 end
211 else
212 begin
213 n_state = UART_BIT6;
214 shift = 0;
215 done = 0;
216 end
217 end
218 UART_BIT5: begin
219 if(bitenable)
220 begin
221 n_state = UART_BIT4;
222 shift = 1;
223 done = 0;
224 end
225 else
226 begin
227 n_state = UART_BIT5;
228 shift = 0;
229 done = 0;
230 end
231 end
232 UART_BIT4: begin
233 if(bitenable)
234 begin
235 n_state = UART_BIT3;
236 shift = 1;
237 done = 0;
238 end
239 else
240 begin
241 n_state = UART_BIT4;
242 shift = 0;
243 done = 0;
244 end
245 end
246 UART_BIT3: begin
247 if(bitenable)
248 begin
249 n_state = UART_BIT2;
250 shift = 1;
251 done = 0;
252 end
253 else
254 begin
255 n_state = UART_BIT3;
256 shift = 0;
257 done = 0;
258 end
259 end
260 UART_BIT2: begin
261 if(bitenable)
262 begin
263 n_state = UART_BIT1;
264 shift = 1;
265 done = 0;
266
267 end
268 else
269 begin
270 n_state = UART_BIT2;
271 shift = 0;
272 done = 0;
273 end
274 end
275 UART_BIT1: begin
276 if(bitenable)
277 begin
278 n_state = UART_BIT0;
279 shift = 1;
280 done = 0;
281
282 end
283 else
284 begin
285 n_state = UART_BIT1;
286 shift = 0;
287 done = 0;
288
289 end
290 end
291 UART_BIT0: begin
292 if(bitenable)
293 begin
294 n_state = UART_STOPBIT;
295 shift = 0;
296 done = 1;
297 end
298 else
299 begin
300 n_state = UART_BIT0;
301 shift = 0;
302 done = 0;
303 end
304 end
305 UART_STOPBIT: begin
306 if(start)
307 begin
308 n_state = UART_STARTBIT;
309 shift = 0;
310 done = 0;
311 end
312 else
313 begin
314 n_state = UART_IDLE;
315 shift = 0;
316 done = 0;
317 end
318 end
319 default: begin
320 n_state = UART_IDLE;
321 shift = 0;
322 done = 0;
323 end
324 endcase
325 end
326endmodule
testbench代码如下:
1
`timescale 1ns/10ps2
module uart_rx_testbench;3
parameter p=160;4
reg clk_16;5
reg rst;6
reg rxd;7
wire [7:0]dout;8
wire error_bit;9
wire overrun;10
wire ready;11
wire busy;12
wire [3:0]c_state;13
uart_rx uart_rx_inst(14
.clk_16(clk_16), 15
.rst(rst), 16
.rxd(rxd), 17
.dout(dout),18
.error_bit(error_bit),19
.overrun(overrun),20
.ready(ready),21
.busy(busy),22
.c_state(c_state)23
);24
initial25
begin26
27
rst=0;28
clk_16=1;29
// clk_1=1;30
rxd=1;31
#1 rst=1;32
#1 rst=0;33
#p rxd=1;34
#p rxd=1;35
//1byte36
#p rxd=0;37
#p rxd=0;38
#p rxd=0;39
#p rxd=0;40
#p rxd=0;41
#p rxd=1;42
#p rxd=1;43
#p rxd=1;44
#p rxd=1;45
#p rxd=1;46
//1byte47
#p rxd=0;48
#p rxd=1;49
#p rxd=0;50
#p rxd=1;51
#p rxd=0;52
#p rxd=1;53
#p rxd=0;54
#p rxd=1;55
#p rxd=0;56
#p rxd=1;57
//1byte58
#p rxd=0;59
#p rxd=1;60
#p rxd=1;61
#p rxd=1;62
#p rxd=1;63
#p rxd=0;64
#p rxd=0;65
#p rxd=0;66
#p rxd=0;67
#p rxd=1;68
//1byte69
#p rxd=0;70
#p rxd=1;71
#p rxd=1;72
#p rxd=0;73
#p rxd=1;74
#p rxd=1;75
#p rxd=0;76
#p rxd=1;77
#p rxd=1;78
#p rxd=1;79
//1byte80
#p rxd=0;81
#p rxd=1;82
#p rxd=1;83
#p rxd=1;84
#p rxd=1;85
#p rxd=1;86
#p rxd=1;87
#p rxd=0;88
#p rxd=1;89
#p rxd=1;90
#20000 $finish; 91
end92
always #5 clk_16=~clk_16;93
//always #80 clk_1=~clk_1;94
endmodule95


浙公网安备 33010602011771号