Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

About the DIV_xx_x parameter #1

Open
David7Pan opened this issue Nov 22, 2021 · 9 comments
Open

About the DIV_xx_x parameter #1

David7Pan opened this issue Nov 22, 2021 · 9 comments

Comments

@David7Pan
Copy link

Is there any way to reduce the minimum value of parameter DIV_xx_x from 2 to 1?
I try to figure it out, but there still some confused questions like :
Why the minimum value of parameter DIV_xx_x is 2?
What the INIT_VAL means in cd_baud_rate module?To adjust the phase ?

Blessing!

@dukelec
Copy link
Owner

dukelec commented Nov 22, 2021

The theoretical minimum multiplier for oversampling is 3. (The DIV is counted from 0, so the minimal DIV value is 2.)

The following explains why oversampling is not feasible for 2. The waveform above is the 2x rising edge sampling clock, and the waveform below is the UART rx data:

   s   s   s   s   s
   1   2   3   4   5
   ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐
 ──┘ └─┘ └─┘ └─┘ └─┘ └──

 ──────┐       ┌───────
       └───────┘
 idle    start    bit0    ...

If s2 is sampled to 0, then s3 is used as the middle to get the correct data.
But if s2 samples to 1, then s3 samples to 0, and the final sample value of s4 may be 0 or 1.
Unlike the internal communication of FPGA, the clock accuracy of the external communication varies from node to node, and with noise and jitter, 2x sampling is not guaranteed to be correct.
Moreover, when using 2x oversampling, the clock accuracy error will continue to accumulate if multiple bytes are received continuously.

To achieve 3x oversampling, the logic is more complex than higher oversampling, and requires careful tuning of the data synchronization between modules. sync_3x and INIT_VAL are both for adjusting the phase.

@David7Pan
Copy link
Author

Thank you for your reply.
I got a new question, actually hoping to know, that in the cd_tx_ser module, why Arbitration Mode do not need 'tx_pre_len', but other modes need?

@dukelec
Copy link
Owner

dukelec commented Jun 2, 2022

The total output data has three states: Strong 0, Strong 1 and Weak 1.

The tx_pre_len corresponds to strong 1 output, while strong 1 output is not allowed in arbitration phase, so there is no tx_pre_len in arbitration mode.

If there is no tx_pre_len when outputting data, there will be a delay in the beginning of the output data after it passes through the 485 interface chip:

 ttl output: ──────┐       ┌───────
                   └───────┘       
 485 output: ───────┐      ┌───────
                    └──────┘       

(Because the time required to enable the output of the 485 chip is much longer than the delay in data transfer. The specific time lengths can be found in the corresponding 485 chip manuals.)
(The above figure ignores the delay in data transfer, as it is relatively short.)

This delay can cause problems in high-speed communication, but the rate of arbitration stage is usually not more than 1Mbps, so it does not cause problems.

@David7Pan
Copy link
Author

When reach_max_idle ,BS mode will send a break character, why this character does not need tx_pre_len? Will the delay cause the receiver got a wrong break character (be less than 10 bits) ?

@dukelec
Copy link
Owner

dukelec commented Jun 9, 2022

Because there may be multiple nodes sending the break character at the same time. Similar to arbitration mode, strong 1 data is not allowed to be sent in case of possible data collisions, so tx_pre_len is not used.

The received data may be shorter than 10 bits, but this will not cause problems. This is because the purpose of sending the break character is to put the bus into a non-idle state.

@HunterLiu0517
Copy link

The total output data has three states: Strong 0, Strong 1 and Weak 1.

The tx_pre_len corresponds to strong 1 output, while strong 1 output is not allowed in arbitration phase, so there is no tx_pre_len in arbitration mode.

If there is no tx_pre_len when outputting data, there will be a delay in the beginning of the output data after it passes through the 485 interface chip:

 ttl output: ──────┐       ┌───────
                   └───────┘       
 485 output: ───────┐      ┌───────
                    └──────┘       

(Because the time required to enable the output of the 485 chip is much longer than the delay in data transfer. The specific time lengths can be found in the corresponding 485 chip manuals.) (The above figure ignores the delay in data transfer, as it is relatively short.)

This delay can cause problems in high-speed communication, but the rate of arbitration stage is usually not more than 1Mbps, so it does not cause problems.

Wyh " the rate of arbitration stage is usually not more than 1Mbps"? Is there something wrong when the arbitration rate > 1Mbps?

@dukelec
Copy link
Owner

dukelec commented Sep 7, 2024

@HunterLiu0517

  1. During the arbitration phase, since weak 1s and strong 0s are being sent, the transition of the line from 0 to 1 takes slightly longer than the transition from 1 to 0. If the baud rate is very high, the bit width difference between 0 and 1 may become too large.

  2. Due to the transmission delay caused by the transceiver and the line, if two nodes are transmitting data simultaneously and the baud rate is too high, by the time each node reaches three-quarters of a bit, it may fail to read the corresponding bit from the other node. Instead, it might read the previous bit from the other node or itself.

@HunterLiu0517
Copy link

HunterLiu0517 commented Sep 12, 2024

@dukelec Thanks for your reply.

One more question,in the file "tests", why did you add the logic codes(as follows) in module cdbus_wrapper_dft.v? And If I delete the code, the simulation test fails.
In addition, In practical applications, how do you implement RX=TX of RS485? As we all know, RS485 usually works in half duplex mode.

wire rx0 = tx_en0 === 1 ? tx0 : (bus_a === 1'bx ? 1'bx : (bus_a !== 0));
wire rx1 = tx_en1 === 1 ? tx1 : (bus_a === 1'bx ? 1'bx : (bus_a !== 0));
wire rx2 = tx_en2 === 1 ? tx2 : (bus_a === 1'bx ? 1'bx : (bus_a !== 0));
wire b0_is0 = tx_en0 === 1 && tx0 === 0;
wire b1_is0 = tx_en1 === 1 && tx1 === 0;
wire b2_is0 = tx_en2 === 1 && tx2 === 0;
wire b0_is1 = tx_en0 === 1 && tx0 === 1;
wire b1_is1 = tx_en1 === 1 && tx1 === 1;
wire b2_is1 = tx_en2 === 1 && tx2 === 1;
wire [2:0] is0_cnt = b0_is0 + b1_is0 + b2_is0;
wire [2:0] is1_cnt = b0_is1 + b1_is1 + b2_is1;

@dukelec
Copy link
Owner

dukelec commented Oct 17, 2024

@HunterLiu0517

This piece of code is used to simulate the 485 interface circuit and the state of the 485 bus. A single wire, bus_a, is used here to represent the current state of the 485 bus.

In typical 485 circuits, the /RE and DE pins are usually controlled together, so that when transmitting, the receiving function is disabled. However, we only need to fix the /RE pin to a low level and control only the DE pin. This way, 'RX=TX' can be achieved during the transmission phase. You can check the wiring method of the 485 transceiver on the right side of the Block Diagram in the Readme.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants