自己写的串口代码,高采样时钟
这几年一直在努力提高自己,从研究所出来后,由于工作的方向变了,自然就接触不了超大规模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