自己写的串口代码,高采样时钟

这几年一直在努力提高自己,从研究所出来后,由于工作的方向变了,自然就接触不了超大规模fpga了。也做不了fft和数字滤波器以及多相滤波等算法。转而在逻辑设计上更加深入的研究了。从千兆以太网的设计和mac的编写,以及sdram的另一种读写方式的研究,就是所谓的切换bank提高读写效率。

  最近重新学习了51单片机,发现其实软件和硬件是想通的。软件的编码最后变成了rom里面的数字,硬件再从rom中读出数据到ram里去一条条执行。

  今天我想分享下我写的串口控制程序,相比较于网上大多数的写法,我的独辟新境,有另一种风格。

 

  1 `timescale 1ns / 1ps
  2 //////////////////////////////////////////////////////////////////////////////////
  3 // Company: 
  4 // Engineer: 
  5 // 
  6 // Create Date:    14:45:55 11/03/2012 
  7 // Design Name: 
  8 // Module Name:    uart_rx 
  9 // Project Name: 
 10 // Target Devices: 
 11 // Tool versions: 
 12 // Description: 
 13 //
 14 // Dependencies: 
 15 //
 16 // Revision: 
 17 // Revision 0.01 - File Created
 18 // Additional Comments: 
 19 //
 20 //////////////////////////////////////////////////////////////////////////////////
 21 module my_uart_rx(clk_50MHZ,rxd,baud_sample_num,rx_dout_r,valid_r);
 22         input clk_50MHZ;  // recieve data colock
 23         //input reset; // recieve data reset
 24         input rxd;   // wire for recieve data
 25         input [15:0] baud_sample_num;
 26         //output rx_ready_n; // recieve data ready signal
 27         output reg[7:0]rx_dout_r;  // recieve data out put
 28         output reg valid_r;
 29         reg[7:0]rx_dout;  // recieve data out put
 30         reg valid;
 31 
 32 reg [15:0]counter=16'd0,num=16'd0;
 33 reg rxd_r1,rxd_r2;
 34 reg [3:0] i;
 35 
 36 reg [1:0] mystate=2'b00;
 37 parameter idle=2'b00;
 38 parameter rx_data=2'b01;
 39 parameter stop=2'b11;
 40 
 41 reg counter_en;
 42 
 43 always @(posedge clk_50MHZ)
 44 if(valid) rx_dout_r<=rx_dout;
 45 else rx_dout_r<=rx_dout_r;
 46 
 47 always @(posedge clk_50MHZ)
 48  valid_r<=valid;
 49 
 50 always @(posedge clk_50MHZ)
 51 begin
 52     rxd_r1<=rxd;
 53     rxd_r2<=rxd_r1;
 54 end
 55 
 56 reg reset;
 57 reg [3:0] cnt;
 58 always @(posedge clk_50MHZ)
 59 begin
 60      if(cnt<4'd15)begin reset<=1'b1;cnt<=cnt+1'b1;end
 61       else reset<=1'b0;
 62 end
 63 
 64 always @(posedge clk_50MHZ)
 65 begin
 66     if(reset)mystate<=idle;
 67     else
 68         begin
 69          case(mystate)
 70             idle:
 71                 begin
 72                     if(counter==baud_sample_num-1&&num>baud_sample_num/2)
 73                             mystate<=rx_data;
 74                     else     mystate<=idle;
 75                 end
 76             rx_data:
 77                 begin
 78                     if(counter==baud_sample_num-1&&i==7)
 79                             mystate<=stop;
 80                     else     mystate<=rx_data;
 81                 end
 82          stop:            mystate<=idle;
 83           default:        mystate<=idle;
 84         endcase
 85     end
 86 end
 87 
 88 
 89 always @(posedge clk_50MHZ)
 90 begin
 91     case(mystate)
 92     idle:
 93         begin
 94             if(!rxd_r1&&rxd_r2)
 95                         begin
 96                             counter_en<=1'b1;
 97                             counter<=16'd0;
 98                             
 99                         end
100             else if(counter_en)
101                        begin
102                             if(counter<baud_sample_num-1)
103                                     counter<=counter+1'b1;
104                             else  
105                                 begin
106                                      counter_en<=1'b0; 
107                                      counter<=16'd0;
108                                     
109                                 end
110                         end
111             end
112      rx_data:
113         begin
114             if(counter<baud_sample_num-1)
115                     counter<=counter+1'b1;
116             else  
117                 begin
118                     counter<=16'd0;
119                 end
120           end
121         stop:begin counter<=16'd0;counter_en<=1'b0;end
122         default:begin counter<=16'd0;counter_en<=1'b0;end
123     endcase
124 end
125 
126 always @(posedge clk_50MHZ)
127 begin
128     case(mystate)
129     idle:
130         begin
131            i<=0;
132             if(!rxd_r1&&rxd_r2)
133                         begin
134                             num<=16'd0;
135                         end
136             else if(counter_en)
137                        begin
138                            if(counter==baud_sample_num-1)num<=16'd0;
139                             else if(!rxd_r2)num<=num+1'b1;
140                             else num<=num;
141                         end
142                             
143         end
144      rx_data:
145         begin
146               if(counter==baud_sample_num-1)
147                   begin
148                         if(num>baud_sample_num/2)begin rx_dout[i]<=1'b1;i<=i+1'b1;num<=0;end
149                         else begin rx_dout[i]<=1'b0;i<=i+1'b1;num<=0;end
150                         
151                         //rx_dout[i]<=rxd_r2;i<=i+1'b1;num<=0;
152                     end
153                 else if(rxd_r2)num<=num+1'b1;
154                 else num<=num;
155             end
156         stop:begin num<=0;i<=0;end
157     default:num<=0;
158 endcase
159 end
160 
161 always @(posedge clk_50MHZ)
162 if(mystate==stop)valid<=1'b1;
163 else valid<=1'b0;
164 
165 endmodule
  1 module my_uart_tx(
  2 
  3 input [11:0] last_rev_addr,
  4 
  5 input clk,
  6 
  7 input EPCS_EN,
  8 
  9 input [15:0] baud_sample_num,
 10 
 11 input [31:0]length,
 12         
 13 input correct,
 14 input correct_valid,
 15 
 16 input rev_valid,
 17 
 18 input [7:0] rev_data,
 19 input [7:0] check_sum,
 20 
 21 output reg txd,
 22 
 23 output reg [10:0] raddr,
 24 output reg rden,
 25 
 26 output reg check_valid,
 27 output reg send_reg_valid,
 28 output reg [7:0] send_reg,
 29 
 30 input tRL_valid,
 31 
 32 input [15:0]temperature1,
 33 
 34 input [15:0]temperature2,
 35 
 36 input [15:0]TO,
 37 
 38 input [15:0]RHO,
 39 
 40 input [7:0]TSL
 41                         
 42     );
 43 
 44 
 45 reg valid_a;
 46 
 47 
 48 
 49 parameter idle=2'b00;
 50 parameter send=2'b01;
 51 parameter send_t=2'b10;
 52 
 53 
 54 reg [1:0]mystate;
 55 reg [3:0] cnt;
 56 reg [15:0] counter;
 57 reg reset;
 58 
 59 reg [11:0]counter_a;
 60 reg[7:0] send_rega[15:0];
 61 
 62 reg [7:0] send_regc[32:0];
 63 
 64 //2048+4
 65 wire [31:0] tx_length=last_rev_addr+5/*synthesis syn_keep=1*/;
 66 
 67 always @(posedge clk)
 68 if(correct_valid)
 69  begin
 70     if(correct)begin
 71                     send_rega[0]<=8'h7E;
 72                          send_rega[1]<=8'h7E;
 73                          send_rega[2]<=8'h55;
 74                          send_rega[3]<=8'h3C;
 75                          send_rega[4]<=8'h00;
 76                          send_rega[5]<=8'h00;
 77                          send_rega[6]<=8'h00;
 78                          send_rega[7]<=8'h00;
 79                          
 80                          send_rega[8]<=tx_length[7:0];//8'h04;
 81                          send_rega[9]<=tx_length[15:8];//8'h08;
 82                          send_rega[10]<=tx_length[23:16];//8'h00;
 83                          send_rega[11]<=tx_length[31:24];//8'h00;
 84                          
 85                         send_rega[12]<= 8'h01;
 86                         send_rega[13]<=8'h00;
 87                         send_rega[14]<=8'h00;
 88                         send_rega[15]<=8'h00;
 89                     end
 90     else       begin
 91                     send_rega[0]<=8'h7E;
 92                          send_rega[1]<=8'h7E;
 93                          send_rega[2]<=8'h55;
 94                          send_rega[3]<=8'h3C;
 95                          send_rega[4]<=8'h00;
 96                          send_rega[5]<=8'h00;
 97                          send_rega[6]<=8'h00;
 98                          send_rega[7]<=8'h00;
 99                          
100                          send_rega[8]<=tx_length[7:0];//8'h04;
101                          send_rega[9]<=tx_length[15:8];//8'h08;
102                          send_rega[10]<=tx_length[23:16];//8'h00;
103                          send_rega[11]<=tx_length[31:24];//8'h00;
104                          
105                          send_rega[12]<= 8'h00;
106                          send_rega[13]<=8'h00;
107                          send_rega[14]<=8'h00;
108                          send_rega[15]<=8'h00;
109                     end
110 end
111 
112 
113 always @(posedge clk)
114 send_reg_valid<=valid_b;
115 
116 always @(posedge clk)
117 if(valid_b)
118 begin
119     if(counter_a>=12'd1&&counter_a<=12'd16)send_reg<=send_rega[counter_a-1];
120     else if(counter_a>=12'd17&&counter_a<=last_rev_addr+17)send_reg<=rev_data;
121     else send_reg<=check_sum;
122 end
123 
124 reg valid_b;
125 
126 reg EPCS_EN_d1,EPCS_EN_d2;
127 
128 always @(posedge clk)
129 begin
130 
131     EPCS_EN_d1<=EPCS_EN;
132     EPCS_EN_d2<=EPCS_EN_d1;
133     
134 end
135 
136 reg rev_valid_d1,rev_valid_d2;
137 always @(posedge clk)
138 begin
139     rev_valid_d1<=rev_valid;
140     rev_valid_d2<=rev_valid_d1;
141 end
142 
143 reg correct_valid_t;
144 always @(posedge clk)
145 begin
146    if(reset)correct_valid_t<=1'b0;
147     else if(EPCS_EN_d2&&rev_valid_d1&&!rev_valid_d2)correct_valid_t<=1'b1;
148     else if(!EPCS_EN_d2&&correct_valid)correct_valid_t<=1'b1;
149     else if(counter_a==1)correct_valid_t<=1'b0;
150 end
151 
152 reg mybusy;
153 always @(posedge clk)
154 begin
155 if(reset)mybusy<=1'b0;
156 else if(correct_valid_t&&!mybusy) mybusy<=1'b1;
157 else if(counter_a==0)//(mytime==20'd1000000)
158  mybusy<=1'b0;
159 
160 end
161 reg mywait_en;
162 reg [19:0] mytime;
163 always @(posedge clk)
164 begin
165     if(counter_a==last_rev_addr+18)begin mywait_en<=1'b1;mytime<=20'd0;end
166     else if(mywait_en)
167         begin
168             if(mytime<20'd1000000)mytime<=mytime+1'b1;
169             else begin mytime<=0;mywait_en<=1'b0;end
170         end
171     else begin mytime<=0;mywait_en<=1'b0;end
172 
173 end
174 
175 always @(posedge clk)
176 begin
177 //if(EPCS_EN_d2&&rev_valid_d1&&!rev_valid_d2&&!mybusy)
178 if(correct_valid_t&&!mybusy)
179     begin
180         counter_a<=12'd1;valid_a<=1'b0;valid_b<=1'b0;
181     end
182 //else if(!EPCS_EN_d2&&correct_valid&&!mybusy)begin counter_a<=12'd1;valid_a<=1'b0;valid_b<=1'b0;end
183 else if(valid_a)
184     begin
185         valid_a<=1'b0;
186         valid_b<=1'b1;
187         
188     end
189 else if(valid_b)
190     begin
191         valid_b<=1'b0;
192         if(counter_a<last_rev_addr+18)counter_a<=counter_a+1'b1;
193         else counter_a<=12'd0;
194     end        
195     
196 else if(mystate==idle)
197     begin
198         if(counter_a>=12'd1&&counter_a<=last_rev_addr+18)valid_a<=1'b1;
199         else valid_a<=1'b0;
200     end
201 
202 
203         
204 end
205 
206 
207 
208 always @(posedge clk)
209 if(rden)begin rden<=1'b0;raddr<=11'd0;end
210 else if(mystate==idle)
211     begin
212         if(counter_a>=12'd17&&counter_a<=last_rev_addr+17)begin rden<=1'b1;raddr<=counter_a-17;end
213         else rden<=1'b0;
214     end
215 else begin rden<=1'b0;raddr<=11'd0;end
216 
217 always @(posedge clk)
218 begin
219     if(counter_a>=12'd4&&counter_a<=last_rev_addr+17)
220         begin
221             check_valid<=1'b1;
222         end
223     else
224         check_valid<=1'b0;
225 end
226 //always @(posedge clk)
227 //begin
228 //if(valid)                    begin valid_a<=1'b1;send_rega<=rx_dout;end
229 //else if(mystate==idle)    begin valid_a<=1'b0;send_reg<=send_rega; end
230 //end
231 
232 
233 
234 
235 
236 
237 
238 
239 
240 
241 
242 
243 reg valid_c,valid_d;
244 
245 
246 
247 
248 
249 
250 
251 always @(posedge clk)
252 begin
253     if(cnt<4'd15)begin reset<=1'b1;cnt<=cnt+1'b1;end
254     else begin reset<=1'b0;end
255 end
256 
257 reg [3:0]i;
258 always @(posedge clk)
259 begin
260     if(reset)mystate<=idle;
261     else
262         begin
263             case(mystate)
264                 idle:
265                     begin
266                         if(valid_a)         begin mystate<=send;i<=0;end
267                         //else if(valid_c)begin mystate<=send_t;i<=0;end
268                         else mystate<=idle;
269                     end
270                 send:
271                     begin
272                         if(i<10)
273                             begin
274                                 if(counter<baud_sample_num-1)begin counter<=counter+1'b1;end
275                                 else begin counter<=0;i<=i+1;end
276                             end
277                         else
278                             begin
279                                 if(counter<baud_sample_num-1)begin counter<=counter+1'b1;end
280                                 else begin counter<=0;i<=0;mystate<=idle;end
281                             end
282                      end
283 //                send_t:
284 //                    begin
285 //                        if(i<10)
286 //                            begin
287 //                                if(counter<baud_sample_num-1)begin counter<=counter+1'b1;end
288 //                                else begin counter<=0;i<=i+1;end
289 //                            end
290 //                        else
291 //                            begin
292 //                                if(counter<baud_sample_num-1)begin counter<=counter+1'b1;end
293 //                                else begin counter<=0;i<=0;mystate<=idle;end
294 //                            end
295 //                     end
296                     
297                  default:mystate<=idle;
298                 endcase
299             end
300 end
301  always @(posedge clk)
302 begin
303     if(mystate==send)
304         begin
305             if(i==0)txd<=1'b0;
306             else if(i==9||i==10)txd<=1'b1;
307             else txd<=send_reg[i-1];
308         end
309 //    else if(mystate==send_t)
310 //        begin
311 //            if(i==0)txd<=1'b0;
312 //            else if(i==9||i==10)txd<=1'b1;
313 //            else txd<=send_regl[i-1];
314 //        end
315      else txd<=1'b1;
316 end
317 
318 endmodule

 






posted on 2014-09-12 13:19  不灭的流星  阅读(375)  评论(0编辑  收藏  举报

导航