Do class-based, equivalent to review it again verilog.
Achieved
1. The receiving end of the fixed pattern: 8N1 BAUD: 921600.
2. The transmitting end 8N1, any baud rate (not take the extreme values).
3. The digital display baud rate (hexadecimal).
used
1. overnight visit.
2.ego1 platform + usb2uart.
Overall block diagram
Tx the input signal through a frequency acquisition layer count value at 100Mhz, to the baud rate generating layer obtained receiving layer baud rate.
Receiving layer receives the serial data to the FIFO layer , layer FIFO serial transmission layer based on feedback data sent FIFO.
Transmitting a fixed layer data sent to the PC 921600 baud. In order to achieve the baud rate swap.
Frequency trap layer algorithm
1.uart agreement
Here we consider only the most commonly used 8N1, i.e., 8 data bits, no parity, 1 stop bit.
The rising edge of the clock line, tx and maintained until the falling edge of the line a rising edge that is a start bit. Then 8 data bits (LSB first). 10 and then to the high level stop bit.
It is worth mentioning that, tx line will not return to the original level after a certain level, for example, on a data bit is low, or low current position will not change back to high and then low after the end of the data bits.
What is the impact? If tx send 0xff, then there is only a low-level pulse! That is the start bit pulse width.
2. Algorithms
Hit two beats, clock synchronization and filter out spikes. Considering the data signal input mostly ascii.
We find a most special from the inside, U, this character is binary 10101010, plus the beginning of the end of the bit line level to the tx:
0101010101, there are four or five level pulse width, which is the ideal situation. Such pulse width is measured out of the baud rate.
However, if a general character, transmitting a plurality of low-level pulse bytes may obtain, from the smallest to find the most likely there is the baud rate (the minimum possible level pulse width is the minimum baud rate multiple).
所以我们的算法就是多次测频率,从里面找一个最小的,即认为是波特率。注意这里的频率,波特率都是相对于ego1的100Mhz时钟,并不需要化为实际波特率。
程序
1 `timescale 1ns / 1ps 2 3 4 module cap_freqence( 5 input clk, 6 input rst_n, 7 input freq_in, 8 input cap_en, 9 output freq_cap//27bit 0-134,217,727 对输入信号波特率测得的频率 10 ); 11 reg[26:0] freq_cap = 14'd10416; //rst ?????? 12 reg[26:0] tmp_cap,sequence_cap[2:0]; //cap 5 times and Use the smallest one as baud 13 reg [2:0] cap_cnt; 14 // reg cap_finish; 15 reg s0_RS_232_RX,s1_RS_232_RX; //同步寄存器,消除亚稳态 16 reg tmp0_RS_232_RX,tmp1_RS_232_RX; //数据寄存器,移位寄存器 17 reg cap_state; //0:idle 1:work 18 wire neg_RX;//下降沿 19 always@(posedge clk or negedge rst_n)//同步寄存器,消除亚稳态 20 if(!rst_n) 21 begin 22 s0_RS_232_RX <= 1'b0; 23 s1_RS_232_RX <= 1'b0; 24 end 25 else 26 begin 27 s0_RS_232_RX <= freq_in; //次态 28 s1_RS_232_RX <= s0_RS_232_RX;//现态 29 end 30 always@(posedge clk or negedge rst_n)//数据寄存器 31 if(!rst_n) 32 begin 33 tmp0_RS_232_RX <= 1'b0; 34 tmp1_RS_232_RX <= 1'b0; 35 end 36 else 37 begin 38 tmp0_RS_232_RX <= s1_RS_232_RX; 39 tmp1_RS_232_RX <= tmp0_RS_232_RX; 40 end 41 //共打两拍再检测输入脚 42 assign neg_RX = (!tmp0_RS_232_RX) & tmp1_RS_232_RX;//下降沿检测 43 44 always@(posedge clk or negedge rst_n)//cap工作状态 45 if(!rst_n)begin 46 cap_state <= 0; 47 end 48 else if(neg_RX) //下降沿开始测频 49 cap_state <= 1; 50 else if (tmp0_RS_232_RX) //高电平退出测频 51 cap_state <= 0; 52 53 always@(posedge clk or negedge rst_n)//以100Mhz时钟测输入引脚低电平脉宽 54 if(!rst_n) 55 begin 56 tmp_cap <= 27'd0; 57 58 end 59 else if(cap_state) //串口工作状态(接受)时计数 60 begin 61 if(tmp0_RS_232_RX) //计完一次频率 62 begin 63 sequence_cap[cap_cnt] <= tmp_cap; 64 tmp_cap <= 27'd0; 65 cap_cnt <= cap_cnt + 1;//0 1 2 3,4测完4次后为4 66 end 67 else 68 tmp_cap <= tmp_cap + 1'b1; 69 end 70 71 integer i; 72 reg[26:0] min_cap; 73 74 always@(cap_cnt) //测完一个序列便从测频序列里找出最小脉宽即为bps 75 begin 76 if (cap_cnt == 2'd5) 77 begin 78 min_cap=sequence_cap[0];//1st one as minimal cap 79 for (i=1;i<5;i=i+1) 80 if (sequence_cap[i] < min_cap) 81 if (sequence_cap[i] > 10) 82 min_cap = sequence_cap[i]; 83 if (cap_en) //手动控制更新baud 84 freq_cap = min_cap; 85 end 86 end 87 88 endmodule
这个程序有瑕疵,用了初始化。不懂
freq_cap
这个变量放在rst里面复位后,之后都不能被下面
freq_cap = min_cap;
这句更新,暂时这么写吧!