DPI ಇಂಟರ್ಫೇಸ್ ಮತ್ತು FPGA ಬೋರ್ಡ್ ಮೂಲಕ ರಾಸ್ಪ್ಬೆರಿ Pi3 ಗೆ ಎರಡನೇ HDMI ಮಾನಿಟರ್


ಈ ವೀಡಿಯೊ ತೋರಿಸುತ್ತದೆ: ರಾಸ್ಪ್ಬೆರಿ ಪೈ3 ಬೋರ್ಡ್, ಜಿಪಿಐಒ ಕನೆಕ್ಟರ್ ಮೂಲಕ ಅದರೊಂದಿಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವ ಎಫ್‌ಪಿಜಿಎ ಬೋರ್ಡ್ ಮಾರ್ಸ್ ರೋವರ್ 2 ಆರ್ಪಿ (ಸೈಕ್ಲೋನ್ IV), ಇದಕ್ಕೆ HDMI ಮಾನಿಟರ್ ಸಂಪರ್ಕಗೊಂಡಿದೆ. ಎರಡನೇ ಮಾನಿಟರ್ ರಾಸ್ಪ್ಬೆರಿ Pi3 ನ ಪ್ರಮಾಣಿತ HDMI ಕನೆಕ್ಟರ್ ಮೂಲಕ ಸಂಪರ್ಕ ಹೊಂದಿದೆ. ಡ್ಯುಯಲ್ ಮಾನಿಟರ್ ಸಿಸ್ಟಮ್‌ನಂತೆ ಎಲ್ಲವೂ ಒಟ್ಟಿಗೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ.

ಇದನ್ನು ಹೇಗೆ ಕಾರ್ಯಗತಗೊಳಿಸಲಾಗುತ್ತದೆ ಎಂದು ಮುಂದೆ ನಾನು ನಿಮಗೆ ಹೇಳುತ್ತೇನೆ.

ಜನಪ್ರಿಯ ರಾಸ್ಪ್ಬೆರಿ Pi3 ಬೋರ್ಡ್ GPIO ಕನೆಕ್ಟರ್ ಅನ್ನು ಹೊಂದಿದೆ, ಅದರ ಮೂಲಕ ನೀವು ವಿವಿಧ ವಿಸ್ತರಣೆ ಕಾರ್ಡ್ಗಳನ್ನು ಸಂಪರ್ಕಿಸಬಹುದು: ಸಂವೇದಕಗಳು, ಎಲ್ಇಡಿಗಳು, ಸ್ಟೆಪ್ಪರ್ ಮೋಟಾರ್ ಡ್ರೈವರ್ಗಳು ಮತ್ತು ಹೆಚ್ಚು. ಕನೆಕ್ಟರ್‌ನಲ್ಲಿನ ಪ್ರತಿ ಪಿನ್‌ನ ನಿಖರವಾದ ಕಾರ್ಯವು ಪೋರ್ಟ್ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಅವಲಂಬಿಸಿರುತ್ತದೆ. GPIO ALT2 ಸಂರಚನೆಯು ಕನೆಕ್ಟರ್ ಅನ್ನು DPI ಇಂಟರ್ಫೇಸ್ ಮೋಡ್, ಡಿಸ್ಪ್ಲೇ ಪ್ಯಾರಲಲ್ ಇಂಟರ್ಫೇಸ್ಗೆ ಬದಲಾಯಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. DPI ಮೂಲಕ VGA ಮಾನಿಟರ್‌ಗಳನ್ನು ಸಂಪರ್ಕಿಸಲು ವಿಸ್ತರಣೆ ಕಾರ್ಡ್‌ಗಳಿವೆ. ಆದಾಗ್ಯೂ, ಮೊದಲನೆಯದಾಗಿ, VGA ಮಾನಿಟರ್‌ಗಳು ಇನ್ನು ಮುಂದೆ HDMI ಯಂತೆ ಸಾಮಾನ್ಯವಲ್ಲ, ಮತ್ತು ಎರಡನೆಯದಾಗಿ, ಡಿಜಿಟಲ್ ಇಂಟರ್ಫೇಸ್ ಅನಲಾಗ್ ಒಂದಕ್ಕಿಂತ ಹೆಚ್ಚು ಉತ್ತಮವಾಗಿದೆ. ಇದಲ್ಲದೆ, ಅಂತಹ VGA ವಿಸ್ತರಣೆ ಬೋರ್ಡ್‌ಗಳಲ್ಲಿನ DAC ಅನ್ನು ಸಾಮಾನ್ಯವಾಗಿ R-2-R ಸರಪಳಿಗಳ ರೂಪದಲ್ಲಿ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಸಾಮಾನ್ಯವಾಗಿ ಪ್ರತಿ ಬಣ್ಣಕ್ಕೆ 6 ಬಿಟ್‌ಗಳಿಗಿಂತ ಹೆಚ್ಚಿಲ್ಲ.

ALT2 ಮೋಡ್‌ನಲ್ಲಿ, GPIO ಕನೆಕ್ಟರ್ ಪಿನ್‌ಗಳು ಈ ಕೆಳಗಿನ ಅರ್ಥವನ್ನು ಹೊಂದಿವೆ:

DPI ಇಂಟರ್ಫೇಸ್ ಮತ್ತು FPGA ಬೋರ್ಡ್ ಮೂಲಕ ರಾಸ್ಪ್ಬೆರಿ Pi3 ಗೆ ಎರಡನೇ HDMI ಮಾನಿಟರ್

ಇಲ್ಲಿ ನಾನು ಕನೆಕ್ಟರ್‌ನ RGB ಪಿನ್‌ಗಳನ್ನು ಕ್ರಮವಾಗಿ ಕೆಂಪು, ಹಸಿರು ಮತ್ತು ನೀಲಿ ಬಣ್ಣಗಳನ್ನು ಬಣ್ಣಿಸಿದ್ದೇನೆ. ಇತರ ಪ್ರಮುಖ ಸಂಕೇತಗಳೆಂದರೆ V-SYNC ಮತ್ತು H-SYNC ಸಂಕೇತಗಳು, ಹಾಗೆಯೇ CLK. CLK ಗಡಿಯಾರದ ಆವರ್ತನವು ಪಿಕ್ಸೆಲ್ ಮೌಲ್ಯಗಳನ್ನು ಕನೆಕ್ಟರ್‌ಗೆ ಔಟ್‌ಪುಟ್ ಮಾಡುವ ಆವರ್ತನವಾಗಿದೆ; ಇದು ಆಯ್ದ ವೀಡಿಯೊ ಮೋಡ್ ಅನ್ನು ಅವಲಂಬಿಸಿರುತ್ತದೆ.

ಡಿಜಿಟಲ್ HDMI ಮಾನಿಟರ್ ಅನ್ನು ಸಂಪರ್ಕಿಸಲು, ನೀವು ಇಂಟರ್ಫೇಸ್ನ DPI ಸಂಕೇತಗಳನ್ನು ಸೆರೆಹಿಡಿಯಬೇಕು ಮತ್ತು ಅವುಗಳನ್ನು HDMI ಸಂಕೇತಗಳಿಗೆ ಪರಿವರ್ತಿಸಬೇಕು. ಇದನ್ನು ಮಾಡಬಹುದು, ಉದಾಹರಣೆಗೆ, ಕೆಲವು ರೀತಿಯ FPGA ಬೋರ್ಡ್ ಬಳಸಿ. ಇದು ಬದಲಾದಂತೆ, ಈ ಉದ್ದೇಶಗಳಿಗಾಗಿ ಮಾರ್ಸ್ ರೋವರ್ 2 ಆರ್ಪಿ ಬೋರ್ಡ್ ಸೂಕ್ತವಾಗಿದೆ. ಸತ್ಯದಲ್ಲಿ, ವಿಶೇಷ ಅಡಾಪ್ಟರ್ ಮೂಲಕ ಈ ಬೋರ್ಡ್ ಅನ್ನು ಸಂಪರ್ಕಿಸುವ ಮುಖ್ಯ ಆಯ್ಕೆಯು ಈ ರೀತಿ ಕಾಣುತ್ತದೆ:

DPI ಇಂಟರ್ಫೇಸ್ ಮತ್ತು FPGA ಬೋರ್ಡ್ ಮೂಲಕ ರಾಸ್ಪ್ಬೆರಿ Pi3 ಗೆ ಎರಡನೇ HDMI ಮಾನಿಟರ್

GPIO ಪೋರ್ಟ್‌ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಹೆಚ್ಚಿಸಲು ಮತ್ತು ರಾಸ್ಪ್ಬೆರಿಗೆ ಹೆಚ್ಚಿನ ಬಾಹ್ಯ ಸಾಧನಗಳನ್ನು ಸಂಪರ್ಕಿಸಲು ಈ ಬೋರ್ಡ್ ಅನ್ನು ಬಳಸಲಾಗುತ್ತದೆ. ಅದೇ ಸಮಯದಲ್ಲಿ, ಈ ಸಂಪರ್ಕದೊಂದಿಗೆ 4 GPIO ಸಂಕೇತಗಳನ್ನು JTAG ಸಂಕೇತಗಳಿಗೆ ಬಳಸಲಾಗುತ್ತದೆ, ಇದರಿಂದಾಗಿ ರಾಸ್ಪ್ಬೆರಿಯಿಂದ ಪ್ರೋಗ್ರಾಂ FPGA ಫರ್ಮ್ವೇರ್ ಅನ್ನು FPGA ಗೆ ಲೋಡ್ ಮಾಡಬಹುದು. ಈ ಕಾರಣದಿಂದಾಗಿ, ಈ ಪ್ರಮಾಣಿತ ಸಂಪರ್ಕವು ನನಗೆ ಸರಿಹೊಂದುವುದಿಲ್ಲ; 4 DPI ಸಂಕೇತಗಳು ಹೊರಬರುತ್ತವೆ. ಅದೃಷ್ಟವಶಾತ್, ಬೋರ್ಡ್‌ನಲ್ಲಿರುವ ಹೆಚ್ಚುವರಿ ಬಾಚಣಿಗೆಗಳು ರಾಸ್ಪ್ಬೆರಿ-ಹೊಂದಾಣಿಕೆಯ ಪಿನ್ಔಟ್ ಅನ್ನು ಹೊಂದಿವೆ. ಹಾಗಾಗಿ ನಾನು ಬೋರ್ಡ್ ಅನ್ನು 90 ಡಿಗ್ರಿ ತಿರುಗಿಸಬಹುದು ಮತ್ತು ಅದನ್ನು ನನ್ನ ರಾಸ್ಪ್ಬೆರಿಗೆ ಸಂಪರ್ಕಿಸಬಹುದು:

DPI ಇಂಟರ್ಫೇಸ್ ಮತ್ತು FPGA ಬೋರ್ಡ್ ಮೂಲಕ ರಾಸ್ಪ್ಬೆರಿ Pi3 ಗೆ ಎರಡನೇ HDMI ಮಾನಿಟರ್

ಸಹಜವಾಗಿ, ನೀವು ಬಾಹ್ಯ JTAG ಪ್ರೋಗ್ರಾಮರ್ ಅನ್ನು ಬಳಸಬೇಕಾಗುತ್ತದೆ, ಆದರೆ ಇದು ಸಮಸ್ಯೆಯಲ್ಲ.

ಇನ್ನೂ ಒಂದು ಸಣ್ಣ ಸಮಸ್ಯೆ ಇದೆ. ಪ್ರತಿ FPGA ಪಿನ್ ಅನ್ನು ಗಡಿಯಾರದ ಇನ್ಪುಟ್ ಆಗಿ ಬಳಸಲಾಗುವುದಿಲ್ಲ. ಈ ಉದ್ದೇಶಗಳಿಗಾಗಿ ಬಳಸಬಹುದಾದ ಕೆಲವು ಮೀಸಲಾದ ಪಿನ್‌ಗಳು ಮಾತ್ರ ಇವೆ. ಆದ್ದರಿಂದ GPIO_0 CLK ಸಿಗ್ನಲ್ FPGA ಇನ್‌ಪುಟ್ ಅನ್ನು ತಲುಪುವುದಿಲ್ಲ, ಇದನ್ನು FPGA ಗಡಿಯಾರ ಇನ್‌ಪುಟ್ ಆಗಿ ಬಳಸಬಹುದು. ಹಾಗಾಗಿ ನಾನು ಇನ್ನೂ ಒಂದು ತಂತಿಯನ್ನು ಸ್ಕಾರ್ಫ್ ಮೇಲೆ ಹಾಕಬೇಕಾಗಿತ್ತು. ನಾನು GPIO_0 ಮತ್ತು ಬೋರ್ಡ್‌ನ KEY[1] ಸಂಕೇತವನ್ನು ಸಂಪರ್ಕಿಸುತ್ತೇನೆ:

DPI ಇಂಟರ್ಫೇಸ್ ಮತ್ತು FPGA ಬೋರ್ಡ್ ಮೂಲಕ ರಾಸ್ಪ್ಬೆರಿ Pi3 ಗೆ ಎರಡನೇ HDMI ಮಾನಿಟರ್

ಈಗ ನಾನು FPGA ಯೋಜನೆಯ ಬಗ್ಗೆ ಸ್ವಲ್ಪ ಹೇಳುತ್ತೇನೆ. ಎಚ್‌ಡಿಎಂಐ ಸಿಗ್ನಲ್‌ಗಳನ್ನು ಉತ್ಪಾದಿಸುವಲ್ಲಿ ಮುಖ್ಯ ತೊಂದರೆ ಎಂದರೆ ಅತಿ ಹೆಚ್ಚು ಆವರ್ತನಗಳು. ನೀವು HDMI ಕನೆಕ್ಟರ್ ಪಿನ್‌ಔಟ್ ಅನ್ನು ನೋಡಿದರೆ, RGB ಸಿಗ್ನಲ್‌ಗಳು ಈಗ ಸೀರಿಯಲ್ ಡಿಫರೆನ್ಷಿಯಲ್ ಸಿಗ್ನಲ್‌ಗಳಾಗಿವೆ ಎಂದು ನೀವು ನೋಡಬಹುದು:

DPI ಇಂಟರ್ಫೇಸ್ ಮತ್ತು FPGA ಬೋರ್ಡ್ ಮೂಲಕ ರಾಸ್ಪ್ಬೆರಿ Pi3 ಗೆ ಎರಡನೇ HDMI ಮಾನಿಟರ್

ಡಿಫರೆನ್ಷಿಯಲ್ ಸಿಗ್ನಲ್ ಬಳಕೆಯು ಟ್ರಾನ್ಸ್ಮಿಷನ್ ಲೈನ್ನಲ್ಲಿ ಸಾಮಾನ್ಯ ಮೋಡ್ ಹಸ್ತಕ್ಷೇಪವನ್ನು ಎದುರಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಪ್ರತಿ ಬಣ್ಣದ ಸಂಕೇತದ ಮೂಲ ಎಂಟು-ಬಿಟ್ ಕೋಡ್ ಅನ್ನು 10-ಬಿಟ್ TMDS (ಪರಿವರ್ತನೆ-ಕಡಿಮೆಗೊಳಿಸಿದ ಡಿಫರೆನ್ಷಿಯಲ್ ಸಿಗ್ನಲಿಂಗ್) ಆಗಿ ಪರಿವರ್ತಿಸಲಾಗುತ್ತದೆ. ಸಿಗ್ನಲ್‌ನಿಂದ ಡಿಸಿ ಘಟಕವನ್ನು ತೆಗೆದುಹಾಕಲು ಮತ್ತು ಡಿಫರೆನ್ಷಿಯಲ್ ಲೈನ್‌ನಲ್ಲಿ ಸಿಗ್ನಲ್ ಸ್ವಿಚಿಂಗ್ ಅನ್ನು ಕಡಿಮೆ ಮಾಡಲು ಇದು ವಿಶೇಷ ಕೋಡಿಂಗ್ ವಿಧಾನವಾಗಿದೆ. ಒಂದು ಬೈಟ್ ಬಣ್ಣಕ್ಕಾಗಿ 10 ಬಿಟ್‌ಗಳನ್ನು ಈಗ ಸೀರಿಯಲ್ ಲೈನ್‌ನಲ್ಲಿ ರವಾನೆ ಮಾಡಬೇಕಾಗಿರುವುದರಿಂದ, ಸೀರಿಯಲೈಸರ್ ಗಡಿಯಾರದ ವೇಗವು ಪಿಕ್ಸೆಲ್ ಗಡಿಯಾರದ ವೇಗಕ್ಕಿಂತ 10 ಪಟ್ಟು ಹೆಚ್ಚಿರಬೇಕು ಎಂದು ಅದು ತಿರುಗುತ್ತದೆ. ನಾವು ಉದಾಹರಣೆಗೆ ವೀಡಿಯೊ ಮೋಡ್ 1280x720 60Hz ಅನ್ನು ತೆಗೆದುಕೊಂಡರೆ, ಈ ಮೋಡ್‌ನ ಪಿಕ್ಸೆಲ್ ಆವರ್ತನವು 74,25 MHz ಆಗಿದೆ. ಧಾರಾವಾಹಿ 742,5 MHz ಆಗಿರಬೇಕು.

ನಿಯಮಿತ ಎಫ್‌ಪಿಜಿಎಗಳು, ದುರದೃಷ್ಟವಶಾತ್, ಇದಕ್ಕೆ ಸಮರ್ಥವಾಗಿಲ್ಲ. ಆದಾಗ್ಯೂ, ಅದೃಷ್ಟವಶಾತ್ ನಮಗೆ, FPGA ಅಂತರ್ನಿರ್ಮಿತ DDIO ಪಿನ್‌ಗಳನ್ನು ಹೊಂದಿದೆ. ಇವುಗಳು ಈಗಾಗಲೇ 2 ರಿಂದ 1 ಧಾರಾವಾಹಿಗಳಂತಹ ತೀರ್ಮಾನಗಳಾಗಿವೆ. ಅಂದರೆ, ಅವರು ಗಡಿಯಾರದ ಆವರ್ತನದ ಏರುತ್ತಿರುವ ಮತ್ತು ಬೀಳುವ ಅಂಚುಗಳ ಮೇಲೆ ಅನುಕ್ರಮವಾಗಿ ಎರಡು ಬಿಟ್ಗಳನ್ನು ಔಟ್ಪುಟ್ ಮಾಡಬಹುದು. ಇದರರ್ಥ FPGA ಯೋಜನೆಯಲ್ಲಿ ನೀವು 740 MHz ಅಲ್ಲ, 370 MHz ಅನ್ನು ಬಳಸಬಹುದು, ಆದರೆ ನೀವು FPGA ನಲ್ಲಿ DDIO ಔಟ್‌ಪುಟ್ ಅಂಶಗಳನ್ನು ಬಳಸಬೇಕಾಗುತ್ತದೆ. ಈಗ 370 MHz ಈಗಾಗಲೇ ಸಂಪೂರ್ಣವಾಗಿ ಸಾಧಿಸಬಹುದಾದ ಆವರ್ತನವಾಗಿದೆ. ದುರದೃಷ್ಟವಶಾತ್, 1280x720 ಮೋಡ್ ಮಿತಿಯಾಗಿದೆ. Mars Rover2rpi ಬೋರ್ಡ್‌ನಲ್ಲಿ ಸ್ಥಾಪಿಸಲಾದ ನಮ್ಮ ಸೈಕ್ಲೋನ್ IV FPGA ನಲ್ಲಿ ಹೆಚ್ಚಿನ ರೆಸಲ್ಯೂಶನ್ ಸಾಧಿಸಲಾಗುವುದಿಲ್ಲ.

ಆದ್ದರಿಂದ, ವಿನ್ಯಾಸದಲ್ಲಿ, ಇನ್ಪುಟ್ ಪಿಕ್ಸೆಲ್ ಆವರ್ತನ CLK PLL ಗೆ ಹೋಗುತ್ತದೆ, ಅಲ್ಲಿ ಅದು 5 ರಿಂದ ಗುಣಿಸಲ್ಪಡುತ್ತದೆ. ಈ ಆವರ್ತನದಲ್ಲಿ, R, G, B ಬೈಟ್ಗಳನ್ನು ಬಿಟ್ ಜೋಡಿಗಳಾಗಿ ಪರಿವರ್ತಿಸಲಾಗುತ್ತದೆ. TMDS ಎನ್‌ಕೋಡರ್ ಮಾಡುವುದು ಇದನ್ನೇ. ವೆರಿಲಾಗ್ HDL ನಲ್ಲಿನ ಮೂಲ ಕೋಡ್ ಈ ರೀತಿ ಕಾಣುತ್ತದೆ:

module hdmi(
	input wire pixclk,		// 74MHz
	input wire clk_TMDS2,	// 370MHz
	input wire hsync,
	input wire vsync,
	input wire active,
	input wire [7:0]red,
	input wire [7:0]green,
	input wire [7:0]blue,
	output wire TMDS_bh,
	output wire TMDS_bl,
	output wire TMDS_gh,
	output wire TMDS_gl,
	output wire TMDS_rh,
	output wire TMDS_rl
);

wire [9:0] TMDS_red, TMDS_green, TMDS_blue;
TMDS_encoder encode_R(.clk(pixclk), .VD(red  ), .CD({vsync,hsync}), .VDE(active), .TMDS(TMDS_red));
TMDS_encoder encode_G(.clk(pixclk), .VD(green), .CD({vsync,hsync}), .VDE(active), .TMDS(TMDS_green));
TMDS_encoder encode_B(.clk(pixclk), .VD(blue ), .CD({vsync,hsync}), .VDE(active), .TMDS(TMDS_blue));

reg [2:0] TMDS_mod5=0;  // modulus 5 counter
reg [4:0] TMDS_shift_bh=0, TMDS_shift_bl=0;
reg [4:0] TMDS_shift_gh=0, TMDS_shift_gl=0;
reg [4:0] TMDS_shift_rh=0, TMDS_shift_rl=0;

wire [4:0] TMDS_blue_l  = {TMDS_blue[9],TMDS_blue[7],TMDS_blue[5],TMDS_blue[3],TMDS_blue[1]};
wire [4:0] TMDS_blue_h  = {TMDS_blue[8],TMDS_blue[6],TMDS_blue[4],TMDS_blue[2],TMDS_blue[0]};
wire [4:0] TMDS_green_l = {TMDS_green[9],TMDS_green[7],TMDS_green[5],TMDS_green[3],TMDS_green[1]};
wire [4:0] TMDS_green_h = {TMDS_green[8],TMDS_green[6],TMDS_green[4],TMDS_green[2],TMDS_green[0]};
wire [4:0] TMDS_red_l   = {TMDS_red[9],TMDS_red[7],TMDS_red[5],TMDS_red[3],TMDS_red[1]};
wire [4:0] TMDS_red_h   = {TMDS_red[8],TMDS_red[6],TMDS_red[4],TMDS_red[2],TMDS_red[0]};

always @(posedge clk_TMDS2)
begin
	TMDS_shift_bh <= TMDS_mod5[2] ? TMDS_blue_h  : TMDS_shift_bh  [4:1];
	TMDS_shift_bl <= TMDS_mod5[2] ? TMDS_blue_l  : TMDS_shift_bl  [4:1];
	TMDS_shift_gh <= TMDS_mod5[2] ? TMDS_green_h : TMDS_shift_gh  [4:1];
	TMDS_shift_gl <= TMDS_mod5[2] ? TMDS_green_l : TMDS_shift_gl  [4:1];
	TMDS_shift_rh <= TMDS_mod5[2] ? TMDS_red_h   : TMDS_shift_rh  [4:1];
	TMDS_shift_rl <= TMDS_mod5[2] ? TMDS_red_l   : TMDS_shift_rl  [4:1];
	TMDS_mod5 <= (TMDS_mod5[2]) ? 3'd0 : TMDS_mod5+3'd1;
end

assign TMDS_bh = TMDS_shift_bh[0];
assign TMDS_bl = TMDS_shift_bl[0];
assign TMDS_gh = TMDS_shift_gh[0];
assign TMDS_gl = TMDS_shift_gl[0];
assign TMDS_rh = TMDS_shift_rh[0];
assign TMDS_rl = TMDS_shift_rl[0];

endmodule

module TMDS_encoder(
	input clk,
	input [7:0] VD,	// video data (red, green or blue)
	input [1:0] CD,	// control data
	input VDE,  	// video data enable, to choose between CD (when VDE=0) and VD (when VDE=1)
	output reg [9:0] TMDS = 0
);

wire [3:0] Nb1s = VD[0] + VD[1] + VD[2] + VD[3] + VD[4] + VD[5] + VD[6] + VD[7];
wire XNOR = (Nb1s>4'd4) || (Nb1s==4'd4 && VD[0]==1'b0);
wire [8:0] q_m = {~XNOR, q_m[6:0] ^ VD[7:1] ^ {7{XNOR}}, VD[0]};

reg [3:0] balance_acc = 0;
wire [3:0] balance = q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7] - 4'd4;
wire balance_sign_eq = (balance[3] == balance_acc[3]);
wire invert_q_m = (balance==0 || balance_acc==0) ? ~q_m[8] : balance_sign_eq;
wire [3:0] balance_acc_inc = balance - ({q_m[8] ^ ~balance_sign_eq} & ~(balance==0 || balance_acc==0));
wire [3:0] balance_acc_new = invert_q_m ? balance_acc-balance_acc_inc : balance_acc+balance_acc_inc;
wire [9:0] TMDS_data = {invert_q_m, q_m[8], q_m[7:0] ^ {8{invert_q_m}}};
wire [9:0] TMDS_code = CD[1] ? (CD[0] ? 10'b1010101011 : 10'b0101010100) : (CD[0] ? 10'b0010101011 : 10'b1101010100);

always @(posedge clk) TMDS <= VDE ? TMDS_data : TMDS_code;
always @(posedge clk) balance_acc <= VDE ? balance_acc_new : 4'h0;

endmodule

ನಂತರ ಔಟ್ಪುಟ್ ಜೋಡಿಗಳನ್ನು DDIO ಔಟ್ಪುಟ್ಗೆ ನೀಡಲಾಗುತ್ತದೆ, ಇದು ಅನುಕ್ರಮವಾಗಿ ಏರುತ್ತಿರುವ ಮತ್ತು ಬೀಳುವ ಅಂಚುಗಳ ಮೇಲೆ ಒಂದು-ಬಿಟ್ ಸಿಗ್ನಲ್ ಅನ್ನು ಉತ್ಪಾದಿಸುತ್ತದೆ.

DDIO ಅನ್ನು ಈ ಕೆಳಗಿನ ವೆರಿಲಾಗ್ ಕೋಡ್‌ನೊಂದಿಗೆ ವಿವರಿಸಬಹುದು:

module ddio(
	input wire d0,
	input wire d1,
	input wire clk,
	output wire out
	);

reg r_d0;
reg r_d1;
always @(posedge clk)
begin
	r_d0 <= d0;
	r_d1 <= d1;
end
assign out = clk ? r_d0 : r_d1;
endmodule

ಆದರೆ ಇದು ಹೆಚ್ಚಾಗಿ ಆ ರೀತಿಯಲ್ಲಿ ಕೆಲಸ ಮಾಡುವುದಿಲ್ಲ. DDIO ಔಟ್‌ಪುಟ್ ಅಂಶಗಳನ್ನು ವಾಸ್ತವವಾಗಿ ಸಕ್ರಿಯಗೊಳಿಸಲು ನೀವು Alter ನ ಮೆಗಾಫಂಕ್ಷನ್ ALTDDIO_OUT ಅನ್ನು ಬಳಸಬೇಕಾಗುತ್ತದೆ. ನನ್ನ ಯೋಜನೆಯು ALTDDIO_OUT ಲೈಬ್ರರಿ ಘಟಕವನ್ನು ಬಳಸುತ್ತದೆ.

ಇದೆಲ್ಲವೂ ಸ್ವಲ್ಪ ಟ್ರಿಕಿಯಂತೆ ಕಾಣಿಸಬಹುದು, ಆದರೆ ಇದು ಕೆಲಸ ಮಾಡುತ್ತದೆ.

ವೆರಿಲಾಗ್ HDL ನಲ್ಲಿ ಬರೆದ ಎಲ್ಲಾ ಮೂಲ ಕೋಡ್ ಅನ್ನು ನೀವು ವೀಕ್ಷಿಸಬಹುದು ಇಲ್ಲಿ ಗಿಥಬ್‌ನಲ್ಲಿ.

FPGA ಗಾಗಿ ಕಂಪೈಲ್ ಮಾಡಿದ ಫರ್ಮ್‌ವೇರ್ ಅನ್ನು ಮಾರ್ಸ್ ರೋವರ್ 2 ಆರ್ಪಿ ಬೋರ್ಡ್‌ನಲ್ಲಿ ಸ್ಥಾಪಿಸಲಾದ ಇಪಿಸಿಎಸ್ ಚಿಪ್‌ಗೆ ಫ್ಲ್ಯಾಶ್ ಮಾಡಲಾಗಿದೆ. ಹೀಗಾಗಿ, FPGA ಬೋರ್ಡ್‌ಗೆ ವಿದ್ಯುತ್ ಅನ್ನು ಅನ್ವಯಿಸಿದಾಗ, FPGA ಅನ್ನು ಫ್ಲ್ಯಾಶ್ ಮೆಮೊರಿಯಿಂದ ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತದೆ.

ಈಗ ನಾವು ರಾಸ್ಪ್ಬೆರಿ ಸಂರಚನೆಯ ಬಗ್ಗೆ ಸ್ವಲ್ಪ ಮಾತನಾಡಬೇಕಾಗಿದೆ.

ನಾನು ಡೆಬಿಯನ್ ಬಸ್ಟರ್, ಆವೃತ್ತಿ:ಆಗಸ್ಟ್ 32, ಆಧಾರಿತ Raspberry PI OS (2020 ಬಿಟ್) ನಲ್ಲಿ ಪ್ರಯೋಗಗಳನ್ನು ಮಾಡುತ್ತಿದ್ದೇನೆ
ಬಿಡುಗಡೆ ದಿನಾಂಕ: 2020-08-20, ಕರ್ನಲ್ ಆವೃತ್ತಿ: 5.4.

ನೀವು ಎರಡು ಕೆಲಸಗಳನ್ನು ಮಾಡಬೇಕಾಗಿದೆ:

  • config.txt ಫೈಲ್ ಅನ್ನು ಸಂಪಾದಿಸಿ;
  • ಎರಡು ಮಾನಿಟರ್‌ಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಲು X ಸರ್ವರ್ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ರಚಿಸಿ.

/boot/config.txt ಫೈಲ್ ಅನ್ನು ಸಂಪಾದಿಸುವಾಗ ನಿಮಗೆ ಅಗತ್ಯವಿದೆ:

  1. i2c, i2s, spi ಬಳಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ;
  2. ಓವರ್‌ಲೇ dtoverlay=dpi24 ಬಳಸಿಕೊಂಡು DPI ಮೋಡ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ;
  3. ವೀಡಿಯೊ ಮೋಡ್ ಅನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಿ 1280×720 60Hz, DPI ನಲ್ಲಿ ಪ್ರತಿ ಪಿಕ್ಸೆಲ್‌ಗೆ 24 ಬಿಟ್‌ಗಳು;
  4. ಅಗತ್ಯವಿರುವ ಫ್ರೇಮ್‌ಬಫರ್‌ಗಳ ಸಂಖ್ಯೆ 2 ಅನ್ನು ಸೂಚಿಸಿ (max_framebuffers=2, ನಂತರ ಮಾತ್ರ ಎರಡನೇ ಸಾಧನ /dev/fb1 ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತದೆ)

config.txt ಫೈಲ್‌ನ ಪೂರ್ಣ ಪಠ್ಯವು ಈ ರೀತಿ ಕಾಣುತ್ತದೆ.

# For more options and information see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details

# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1

# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
disable_overscan=1

# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16

# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720

# uncomment if hdmi display is not detected and composite is being output
hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1

# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2

# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4

# uncomment for composite PAL
#sdtv_mode=2

#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

dtparam=i2c_arm=off
dtparam=spi=off
dtparam=i2s=off

dtoverlay=dpi24
overscan_left=0
overscan_right=0
overscan_top=0
overscan_bottom=0
framebuffer_width=1280
framebuffer_height=720
display_default_lcd=0
enable_dpi_lcd=1
dpi_group=2
dpi_mode=87
#dpi_group=1
#dpi_mode=4
dpi_output_format=0x6f027
dpi_timings=1280 1 110 40 220 720 1 5 5 20 0 0 0 60 0 74000000 3

# Uncomment this to enable infrared communication.
#dtoverlay=gpio-ir,gpio_pin=17
#dtoverlay=gpio-ir-tx,gpio_pin=18

# Additional overlays and parameters are documented /boot/overlays/README

# Enable audio (loads snd_bcm2835)
dtparam=audio=on

[pi4]
# Enable DRM VC4 V3D driver on top of the dispmanx display stack
#dtoverlay=vc4-fkms-v3d
max_framebuffers=2

[all]
#dtoverlay=vc4-fkms-v3d
max_framebuffers=2

ಇದರ ನಂತರ, ಎರಡು ಫ್ರೇಮ್‌ಬಫರ್‌ಗಳಲ್ಲಿ ಎರಡು ಮಾನಿಟರ್‌ಗಳನ್ನು ಬಳಸಲು X ಸರ್ವರ್‌ಗಾಗಿ ನೀವು ಕಾನ್ಫಿಗರೇಶನ್ ಫೈಲ್ ಅನ್ನು ರಚಿಸಬೇಕಾಗಿದೆ /dev/fb0 ಮತ್ತು /dev/fb1:

ನನ್ನ ಕಾನ್ಫಿಗರೇಶನ್ ಫೈಲ್ /usr/share/x11/xorg.conf.d/60-dualscreen.conf ಈ ರೀತಿ ಇದೆ

Section "Device"
        Identifier      "LCD"
        Driver          "fbturbo"
        Option          "fbdev" "/dev/fb0"
        Option          "ShadowFB" "off"
        Option          "SwapbuffersWait" "true"
EndSection

Section "Device"
        Identifier      "HDMI"
        Driver          "fbturbo"
        Option          "fbdev" "/dev/fb1"
        Option          "ShadowFB" "off"
        Option          "SwapbuffersWait" "true"
EndSection

Section "Monitor"
        Identifier      "LCD-monitor"
        Option          "Primary" "true"
EndSection

Section "Monitor"
        Identifier      "HDMI-monitor"
        Option          "RightOf" "LCD-monitor"
EndSection

Section "Screen"
        Identifier      "screen0"
        Device          "LCD"
        Monitor         "LCD-monitor"
EndSection

Section "Screen"
        Identifier      "screen1"
        Device          "HDMI" 
	Monitor         "HDMI-monitor"
EndSection

Section "ServerLayout"
        Identifier      "default"
        Option          "Xinerama" "on"
        Option          "Clone" "off"
        Screen 0        "screen0"
        Screen 1        "screen1" RightOf "screen0"
EndSection

ಸರಿ, ಇದು ಈಗಾಗಲೇ ಸ್ಥಾಪಿಸದಿದ್ದರೆ, ನೀವು Xinerama ಅನ್ನು ಸ್ಥಾಪಿಸಬೇಕಾಗಿದೆ. ನಂತರ ಮೇಲಿನ ಡೆಮೊ ವೀಡಿಯೊದಲ್ಲಿ ತೋರಿಸಿರುವಂತೆ ಡೆಸ್ಕ್‌ಟಾಪ್ ಜಾಗವನ್ನು ಎರಡು ಮಾನಿಟರ್‌ಗಳಿಗೆ ಸಂಪೂರ್ಣವಾಗಿ ವಿಸ್ತರಿಸಲಾಗುತ್ತದೆ.

ಬಹುಶಃ ಅಷ್ಟೆ. ಈಗ, Raspberry Pi3 ಮಾಲೀಕರು ಎರಡು ಮಾನಿಟರ್‌ಗಳನ್ನು ಬಳಸಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ.

Mars Rover2rpi ಬೋರ್ಡ್‌ನ ವಿವರಣೆ ಮತ್ತು ಸರ್ಕ್ಯೂಟ್ ರೇಖಾಚಿತ್ರವನ್ನು ಕಾಣಬಹುದು ಇಲ್ಲಿ ನೋಡಿ.

ಮೂಲ: www.habr.com