فهرست مطالب:

سنتز کننده صوتی دیجیتال Basys3 FPGA: 5 مرحله
سنتز کننده صوتی دیجیتال Basys3 FPGA: 5 مرحله

تصویری: سنتز کننده صوتی دیجیتال Basys3 FPGA: 5 مرحله

تصویری: سنتز کننده صوتی دیجیتال Basys3 FPGA: 5 مرحله
تصویری: ویس فیلتر چیست - Voice Filter 2024, جولای
Anonim
Image
Image
سنتز کننده صوتی دیجیتال Basys3 FPGA
سنتز کننده صوتی دیجیتال Basys3 FPGA
سنتز کننده صوتی دیجیتال Basys3 FPGA
سنتز کننده صوتی دیجیتال Basys3 FPGA

این سینت سایزر دیجیتالی موج سینوسی ورودی های کاربر را از طریق یک سری کلیدهای لحظه ای که مانند صفحه کلید تنظیم شده اند ، گرفته و موج صوتی را از طریق بلندگو خروجی می دهد. بر اساس ورودی های کاربر ، دستگاه امواج سینوسی با فرکانس های مختلف از C4 تا C6 ایجاد می کند. کاربر می تواند یادداشت ها را از C4 تا C6 (مجموع 25 نت) و همزمان تا چهار کلید را وارد کند - اگر بیش از چهار کلید را فشار دهید ، چهار کمترین صدا پخش می شود.

این پروژه توسط رایان موریس و Mavis Tsoi برای کلاس طراحی دیجیتال Cal Poly CPE 133 ما انجام شده است:)

مرحله 1: نظریه

یک برد FPGA فقط می تواند سیگنال های دیجیتال را خروجی دهد. به عبارت دیگر ، تنها می تواند ولتاژ بالا (3.3V) یا ولتاژ پایین (0V) تولید کند. با این حال ، سیگنال های صوتی آنالوگ هستند و می توانند بی نهایت افزایش ولتاژ داشته باشند. برای حل این مشکل ، ما از یک سیگنال PWM (تعدیل عرض پالس) برای شبیه سازی یک موج آنالوگ استفاده می کنیم. اگر نمی دانید PWM چیست ، این را بررسی کنید:

مرحله 2: مواد و ابزارها

  • کامپیوتر با Vivado نصب شده است
  • ما از نسخه Vivado 2017.2 استفاده خواهیم کرد
  • تخته FPGA Basys3
  • 25 سوئیچ محدود SPDT (ما از اینها استفاده کردیم)
  • 30 سیم جامپر (یک سر نر ، سر دیگر مهم نیست) ، 12 اینچ
  • سیم بر، دم باریک
  • استریپرهای سیم
  • سیم یدکی برای لحیم کاری
  • لحیم کاری هسته ای رزینی
  • آهن لحیم کاری
  • جک صوتی زن”
  • تقویت کننده/بلندگو
  • چیزی برای نصب سوئیچ ها (ما از صفحه اصلی + جعبه چوبی استفاده کردیم)

مرحله 3: سیم کشی و راه اندازی سخت افزار

سیم کشی و راه اندازی سخت افزار
سیم کشی و راه اندازی سخت افزار
سیم کشی و راه اندازی سخت افزار
سیم کشی و راه اندازی سخت افزار
سیم کشی و راه اندازی سخت افزار
سیم کشی و راه اندازی سخت افزار

معماری سیستم

شکل 1: 25 ورودی موجود Board Basys3 Board pl تقویت کننده و بلندگو را ببینید.

خروجی

به شکل 2 مراجعه کنید: Basys3 Board → 1/2 Jack Audio Jack → Speaker (با تقویت کننده)

ورودی

اتصالات pmod روی برد Basys3 برای مشاهده ورودی کم باید به زمین متصل شوند و اگر به صورت یک مدار باز باقی بماند به درستی کار نمی کند. به همین دلیل ، ما باید از کلیدهای SPDT برای همه کلیدهای یادداشت خود استفاده کنیم. یک سوئیچ SPDT اساساً به کاربر اجازه می دهد تا هنگام فشار دادن بین مدارها جابجا شود ، بنابراین ما از آنها به عنوان "دکمه" خود برای ورود سیگنال های کم (0V) یا زیاد (3.3V) به برد Basys3 استفاده می کنیم.

هر سوئیچ دارای ترمینال NO (معمولاً باز شده) به 3.3 ولت ، پایانه NC (معمولاً بسته) متصل به GND و پایانه COM (معمولی) متصل به ورودی FPGA خواهد بود. شکل 3 را ببینید.

از آنجا که ما 25 سوئیچ محدود داریم ، همه آنها یک خط 3.3V مشترک و یک خط GND مشترک دارند. سپس ، خط سیگنال از هر سوئیچ محدود در گروه های 8 تایی جمع شده و با استفاده از سیم های بلوز زیپ دار به اتصالات pmod روی برد Basys3 متصل می شود تا آشفتگی عظیمی را که ایجاد می کنیم به حداقل برساند. شکل 4 یا نمونه ای از هشت کلید اول را ببینید.

مرحله 4: راه اندازی VHDL (Vivado)

راه اندازی VHDL (Vivado)
راه اندازی VHDL (Vivado)
راه اندازی VHDL (Vivado)
راه اندازی VHDL (Vivado)

ژنراتور موج سینوسی و مولد PWM ابتدا مورد آزمایش قرار گرفتند تا مطمئن شوند که مفهوم ما کار می کند ، سپس محدود کننده ورودی و جمع کننده/تغییر دهنده دامنه یکپارچه شدند. جزئیات عملکرد و ورودی/خروجی هر بلوک فرآیند همانطور که در شکل نشان داده شده است. کد زیر نشان داده شده است ، اما به عنوان فایل VHD و txt نیز ضمیمه شده است. در صورت وجود مغایرت ، با فایل های VHD بروید.

BTW: احتمالاً باید خطوط خود را کوتاه می کردیم ، اما قرار دادن کد در Instructables نیز بسیار آزاردهنده بود ، بنابراین فاصله زیاد نیست و برجستگی نحو وجود ندارد. اگر Vivado دارید و می خواهید کد را دنبال کنید ، توصیه می کنیم فقط فایل را بارگیری کنید.

ابتدا اجازه دهید ماژول ژنراتور موج سینوسی را بررسی کنیم.

کتابخانه IEEE ؛ از IEEE. STD_LOGIC_1164. ALL استفاده کنید ؛ از IEEE. NUMERIC_STD. ALL استفاده کنید ؛ موجودیت Wave_Generator Port است (راه اندازی: در STD_LOGIC ؛ - کلید فشار Freq_Cnt: در STD_LOGIC_VECTOR (15 پایین 0) ؛ - مقدار شمارنده = 100 مگاهرتز / (توجه فرکانس*64 بخشهای موج سینوسی) (دور به نزدیکترین شماره) - تغییر نام داد از Freq wavegenCLK: در STD_LOGIC ؛ - Basys3 100 مگاهرتز CLK WaveOut: خارج STD_LOGIC_VECTOR (9 پایین 0)) ؛ - دامنه امضا شده انتهای موج Wave_Generator ؛ معماری Behavioral of Wave_Generator سیگنال i: محدوده صحیح 0 تا 64: = 0 است؛ -شاخص دامنه حافظه نوع حافظه نوع_آرایه (0 تا 63) با دامنه صحیح -64 تا 63 است. - ایجاد بانک حافظه (ROM) برای نگهداری مقادیر دامنه- آیا این RAM یا ROM فقط تعجب می کند … دامنه سیگنال: نوع_ حافظه: = (0، 7، 13، 19، 25، 30، 35، 40، 45، 49، 52 ، 55، 58، 60، 62، 63، 63، 63، 62، 60، 58، 55، 52، 49، 45، 40، 35، 30، 25، 19، 13، 7، 0، -7، -13 ، -19، -25، -30، -35، -40، -45، -49، -52، -55، -58، -60، -62، -63، -63، -63، -62، - 60 ، -58 ، -55 ، -52 ، -49 ، -45 ، -40 ، -35 ، -30 ، -25 ، -19 ، -13 ، -7) ؛ - بانک حافظه دامنه برای شروع فرایند موج سینوسی (wavegenCLK ، Trigger) شمارنده متغیر: بدون علامت (15 پایین به 0): = تا بدون_علامت (0 ، 16) ؛ - شمارنده تقسیم ساعت ، که از count1 تغییر نام داده است اگر (اگر (شمارنده = بدون علامت (Freq_Cnt)) سپس - Freq_Cnt = 100Mhz / (توجه داشته باشید به فرکانس * 64 بخش های موج سینوسی) - شمارنده را بازنشانی کرده و داده های دامنه را به شمارنده خروجی اختصاص دهید: = به_علامت (0 ، 16) ؛ WaveOut <= STD_LOGIC_VECTOR (به_امضا (دامنه (i) ، 10)) ؛ - افزایش i برای خواندن بعدی i <= i + 1 ؛ - اگر یک موج سینوسی در صورت کامل شدن (i = 63) ، i <= 0 بازنشانی شود ؛ پایان اگر؛ پایان اگر؛ - (شمارنده = بدون علامت (Freq_Cnt)) دیگری- کلید فشرده نشده است- خروجی را تنظیم مجدد ، شاخص دامنه و شمارنده WaveOut <= "0000000000" ؛ من <= 0؛ counter: = to_unsigned (0، 16)؛ -خروجی دامنه = -64 هنگامی که هیچ نت اجرا نمی شود اگر؛ - (راه اندازی = '1') پایان اگر؛ - (افزایش_لبه (CLK)) فرایند پایان ؛ پایان دادن به رفتار ؛

ما با استفاده از ساعت داخلی و ROM یک موج سینوسی دیجیتال در Basys3 ایجاد می کنیم. این ROM 64 مقدار ذخیره می کند که نشان دهنده 64 دامنه در یک موج سینوسی است. شکل 1 را ببینید. 64 مقداری که استفاده می کنیم از موج سینوسی با وضوح بسیار خوب تقلید می کند.

با استفاده از ساعت داخلی ، ما مقداری را محاسبه می کنیم که نشان دهنده سرعت ساعت بر فرکانس موج موردنظر ما است و 64: Clk div = 100MHz / (Freq * 64) هر زمان که شمارنده ما به آن مقدار می رسد ، با یک شماره از ROM و آن را از ماژول مولد موج ما ارسال کنید. فرکانس موج ما بستگی به این دارد که چقدر سریع این دامنه ها را می نامیم.

ما 25 زیر ماژول خواهیم داشت که هر کدام با یک فرکانس/یادداشت مرتبط هستند.

در اینجا باقی مانده کدی که ماژول های Sine Wave Generator را فراخوانی می کند:

کتابخانه IEEE ؛ از IEEE. STD_LOGIC_1164. ALL استفاده کنید ؛ از IEEE. NUMERIC_STD. ALL استفاده کنید ؛ موجودیت Two_Octave_Synth is Port (CLK: در STD_LOGIC ؛ O4: در STD_LOGIC_VECTOR (11 پایین 0) ؛ O5: در STD_LOGIC_VECTOR (12 پایین 0) ؛ خروجی: خروجی STD_LOGIC) ؛ پایان Two_Octave_Synth؛ architecture Behavioral of Two_Octave_Synth جزء است Wave_Generator is Port (ماشه: در STD_LOGIC ؛ Freq_Cnt: در STD_LOGIC_VECTOR (15 پایین به 0) ؛ wavegenCLK: در STD_LOGIC ؛ WaveOut: خارج STD_LOGIC_ (9) جزء پایان ؛ --------------------------- سیگنالهای خروجی از مولد موج ------------------ ----- سیگنال WaveC4، WaveCs4، WaveD4، WaveDs4، WaveE4، WaveF4، WaveFs4، WaveG4، WaveGs4، WaveA4، WaveAs4، WaveB4، WaveC5، WaveCs5، WaveD5، WaveDs5، WaveE5، WaveF5، WaveFs5، WaveG5، WaveGs5، WaveA5، WaveAs5 ، WaveB5 ، WaveC6: امضا شده (9 پایین 0) ؛ -------------------------------- برای منطق انتخاب یادداشت -------------- ------ سیگنال C4، Cs4، D4، Ds4، E4، F4، Fs4، G4، Gs4، A4، As4، B4، C5، Cs5، D5، Ds5، E5، F5، Fs5، G5، Gs5، A5 ، As5 ، B5 ، C6: بدون علامت (4 پایین 0) ؛ سیگنال cntC4، cntCs4، cntD4، cntDs4، cntE4، cntF4، cntFs4، cntG4، cntGs4، cntA4، cntAs4، cntB4، cntC5، cntCs5، cntD5، cntDs5، cntE5، cntF5، cntFs5، cntG5، cntGs5، cntA5، cntAs5، cntB5، cntC6: بدون امضا (4 پایین 0)؛ خطای سیگنال: STD_LOGIC؛ ------------------------------------ برای افزودن امواج سینوسی ----------- --------------- سیگنال Wave0 ، Wave1 ، Wave2 ، Wave3: امضا شده (9 پایین به 0) ؛ -علائم از سیگنال خروجی ماژول Wave Generator WaveSum: STD_LOGIC_VECTOR (9 پایین 0)؛ -علامت برای خلاصه امواج سینوسی (تعریف 2 از -512 تا 511) سیگنال مثبت WaveSum: STD_LOGIC_VECTOR (9 پایین 0 -بدون ثبت نام 0 تا 1023 ، برای استفاده در ژنراتور PWM ----------------------------------- برای تولید PWM ------------------------------- سیگنال ping_length: بدون علامت (9 پایین به 0): = بدون امضا (positiveWaveSum) ؛ --signal off_length: بدون علامت (6 پایین به 0): = به بدون_امضا (127 ، 7) -بدون امضا (WAVE) ؛ سیگنال PWM: بدون علامت (9 پایین به 0): = به_علامت نشده (0 ، 10) ؛ شروع Note_C4: نقشه پورت Wave_Generator (Trigger => O4 (0)، Freq_Cnt => X "1755"، wavegenCLK => CLK، امضا شده (WaveOut) => WaveC4)؛ --5973 ، 261.63 هرتز Note_Cs4: نقشه پورت Wave_Generator (Trigger => O4 (1) ، Freq_Cnt => X "1606" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveCs4) ؛-5638 ، 277.18 هرتز Note_D4: نقشه پورت Wave_Generator (Trigger => O4 (2) ، Freq_Cnt => X "14C9" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveD4) ؛ --5321 ، 293.66 هرتز Note_Ds4: نقشه پورت Wave_Generator (Trigger => O4 (3) ، Freq_Cnt => X "139F"، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveDs4) ؛-5023 ، 311.13 هرتز Note_E4: نقشه پورت Wave_Generator (Trigger => O4 (4) ، Freq_Cnt => X "1285" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveE4) ؛ --4741 ، 329.63 هرتز Note_F4: نقشه پورت Wave_Generator (Trigger => O4 (5)، Freq_Cnt => X "117B"، wavegenCLK => CLK، امضا شده (WaveOut) => WaveF4)؛ --4475 ، 349.23 هرتز Note_Fs4: نقشه پورت Wave_Generator (Trigger => O4 (6) ، Freq_Cnt => X "1080" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveFs4) ؛-4224 ، 369.99 هرتز Note_G4: نقشه پورت Wave_Generator (Trigger => O4 (7) ، Freq_Cnt => X "0F92" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveG4) ؛ --3986 ، 392.00 هرتز Note_Gs4: نقشه پورت Wave_Generator (Trigger => O4 (8) ، Freq_Cnt => X "0EB3" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveGs4) ؛-3763 ، 415.30 هرتز Note_A4: نقشه پورت Wave_Generator (Trigger => O4 (9) ، Freq_Cnt => X "0DE0" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveA4) ؛ --3552 ، 440.00 هرتز توجه_آس 4: نقشه پورت Wave_Generator (Trigger => O4 (10) ، Freq_Cnt => X "0D18" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveAs4) ؛-3352 ، 466.16 هرتز Note_B4: نقشه پورت Wave_Generator (Trigger => O4 (11) ، Freq_Cnt => X "0C5C" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveB4) ؛ --3164 ، 493.88 هرتز ------------------------------------------------ ------------------------------------------------------ --------------------------- Note_C5: نقشه پورت Wave_Generator (Trigger => O5 (0)، Freq_Cnt => X "0BAB"، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveC5) ؛ --2987 ، 523.25 هرتز Note_Cs5: نقشه پورت Wave_Generator (Trigger => O5 (1) ، Freq_Cnt => X "0B03"، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveCs5) ؛-2819 ، 554.37 هرتز Note_D5: نقشه پورت Wave_Generator (Trigger => O5 (2) ، Freq_Cnt => X "0A65" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveD5) ؛ --2661 ، 587.33 هرتز Note_Ds5: نقشه پورت Wave_Generator (Trigger => O5 (3)، Freq_Cnt => X "09D0"، wavegenCLK => CLK، امضا شده (WaveOut) => WaveDs5)؛-2512، 622.25 هرتز Note_E5: نقشه پورت Wave_Generator (Trigger => O5 (4) ، Freq_Cnt => X "0943" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveE5) ؛ --2371 ، 659.25 هرتز Note_F5: نقشه پورت Wave_Generator (Trigger => O5 (5)، Freq_Cnt => X "08Be"، wavegenCLK => CLK، امضا شده (WaveOut) => WaveF5)؛ --2238 ، 698.46 هرتز Note_Fs5: نقشه پورت Wave_Generator (Trigger => O5 (6)، Freq_Cnt => X "0840"، wavegenCLK => CLK، امضا شده (WaveOut) => WaveFs5)؛-2112، 739.99 هرتز Note_G5: نقشه پورت Wave_Generator (Trigger => O5 (7)، Freq_Cnt => X "07CA"، wavegenCLK => CLK، امضا شده (WaveOut) => WaveG5)؛ --1994 ، 783.99 هرتز Note_Gs5: نقشه پورت Wave_Generator (Trigger => O5 (8) ، Freq_Cnt => X "075A" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveGs5) ؛-1882 ، 830.61 هرتز Note_A5: نقشه پورت Wave_Generator (Trigger => O5 (9) ، Freq_Cnt => X "06F0" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveA5) ؛ --1776 ، 880.00 هرتز توجه_آس 5: نقشه پورت Wave_Generator (Trigger => O5 (10)، Freq_Cnt => X "068C"، wavegenCLK => CLK، امضا شده (WaveOut) => WaveAs5)؛-1676، 932.33 هرتز توجه_B5: نقشه پورت Wave_Generator (Trigger => O5 (11) ، Freq_Cnt => X "062E" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveB5) ؛ --1582 ، 987.77 هرتز توجه_C6: نقشه پورت Wave_Generator (Trigger => O5 (12) ، Freq_Cnt => X "05D6" ، wavegenCLK => CLK ، امضا شده (WaveOut) => WaveC6) ؛ --1494 ، 1046.5 هرتز ------------ منطق انتخاب نکته ------------ C4 <= "0000" & O4 (0)؛ Cs4 <= "0000" & O4 (1)؛ D4 <= "0000" & O4 (2)؛ Ds4 <= "0000" & O4 (3)؛ E4 <= "0000" & O4 (4)؛ F4 <= "0000" & O4 (5)؛ Fs4 <= "0000" & O4 (6)؛ G4 <= "0000" & O4 (7)؛ Gs4 <= "0000" & O4 (8)؛ A4 <= "0000" & O4 (9)؛ As4 <= "0000" & O4 (10)؛ B4 <= "0000" & O4 (11)؛ C5 <= "0000" & O5 (0)؛ Cs5 <= "0000" & O5 (1)؛ D5 <= "0000" & O5 (2)؛ Ds5 <= "0000" & O5 (3)؛ E5 <= "0000" & O5 (4)؛ F5 <= "0000" & O5 (5)؛ Fs5 <= "0000" & O5 (6)؛ G5 <= "0000" & O5 (7)؛ Gs5 <= "0000" & O5 (8)؛ A5 <= "0000" & O5 (9)؛ As5 <= "0000" & O5 (10)؛ B5 <= "0000" & O5 (11)؛ C6 <= "0000" & O5 (12)؛ cntC4 <= C4؛ cntCs4 <= C4 + Cs4؛ cntD4 <= C4 + Cs4 + D4 ؛ cntDs4 <= C4 + Cs4 + D4 + Ds4 ؛ cntE4 <= C4 + Cs4 + D4 + Ds4 + E4 ؛ cntF4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 ؛ cntFs4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 ؛ cntG4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 ؛ cntGs4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 ؛ cntA4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 ؛ cntAs4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 ؛ cntB4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 ؛ cntC5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 ؛ cntCs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 ؛ cntD5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 ؛ cntDs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 ؛ cntE5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 ؛ cntF5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 ؛ cntFs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 ؛ cntG5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 ؛ cntGs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5 ؛ cntA5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5 + A5 ؛ cntAs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5 + A5 + As5 ؛ cntB5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5 + A5 + As5 + B5 ؛ cntC6 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5 + A5 + As5 + B5 + C6 ؛ انتخاب: فرایند (WaveC4، WaveCs4، WaveD4، WaveDs4، WaveE4، WaveF4، WaveFs4، WaveG4، WaveGs4، WaveA4، WaveAs4، WaveB4، WaveC5، WaveCs5، WaveD5، WaveDs5، WaveE5، WaveF5، WaveFs5، WaveG5، WaveGs5، WaveA5، WaveAs5، WaveB5 ، WaveC6) شروع می شود اگر (cntC6 = "00000") سپس --------------- اگر سیگنالی تولید نمی شود Wave0 <= "0000000000" ؛ Wave1 <= "0000000000"؛ Wave2 <= "0000000000"؛ Wave3 <= "0000000000"؛ else if (O4 (0) = '1') سپس ------------------- توجه داشته باشید C4 Wave0 Wave0 Wave1 error Wave0 Wave1 Wave2 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 پخش کرد خطا Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 Wave0 Wave1 خطا Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 خطا Wave0 Wave1 Wave2 Wave3 Wave0 < = WaveC6 ؛ Wave1 <= "0000000000"؛ Wave2 <= "0000000000"؛ Wave3 Wave1 <= WaveC6؛ Wave2 <= "0000000000"؛ Wave3 Wave2 <= WaveC6؛ Wave3 Wave3 error Wave1 <= "0000000000"؛ Wave2 <= "0000000000"؛ Wave3 Wave2 <= "0000000000"؛ Wave3 Wave3 خطا <= '1'؛ مورد نهایی ؛ پایان اگر؛ پایان اگر؛ پایان فرایند ؛ ------------- جمع کننده موج سینوسی -------------------- WaveSum <= STD_LOGIC_VECTOR (Wave0 + Wave1 + Wave2 + Wave3) ؛ --------- موج سینوسی را برای pwm مثبت کنید --------------------- positiveWaveSum <= WaveSum (9) & WaveSum (8 پایین 0))؛ ------------- ژنراتور PWM --------------------- فرآیند (CLK)-تعداد متغیرها: بدون امضا (1 پایین تا 0): = to_unsigned (0، 2)؛ if را شروع کنید (افزایش_لبه (CLK)) سپس --count: = count + 1؛ --if (شمارش = به_علامت نشده (4 ، 2)) سپس-شمارش: = به_نامنه (0 ، 2) ؛ اگر اگر ؛ پایان اگر ؛ پایان فرایند ؛ پایان رفتار

4 نکته انتخابکننده ترین قسمت این پروژه انتخاب تنها چهار فرکانس است. ما این کار را با کل دستورات lotta IF انجام دادیم و از سیگنالها به جای متغیرها استفاده کردیم تا فرآیند شبیه سازی و اشکال زدایی شود. ما روش های دیگر را با استفاده از متغیرها و حلقه های FOR امتحان کردیم ، اما با خطاهای زمان اجرا مواجه شدیم. بنابراین ، در نهایت ، ما تصمیم گرفتیم که اگر کار کرد ، آن را به حال خود رها کنیم.آنچه امیریت شکسته نیست را برطرف نکنید؟

چهار موج خروجی دارای برچسب Wave0 ، Wave1 ، Wave2 ، Wave3 هستند - اینها مواردی هستند که برای تشکیل خروجی نهایی به هم اضافه می شوند.

با نگاه کردن به کد ، تعدادی سیگنال با برچسب C4 ، Cs4 ، D4 ، Ds4 و غیره خواهید دید. اینها سیگنال های 5 بیتی هستند که ماشه مربوطه را از O4 (اکتاو 4) یا O5 (اکتاو 5) می گیرند و آنها را ایجاد می کنند. 5 بیت برای افزودن

در مرحله بعد متغیرهای cntC4 ، cntCs4 و غیره نشان می دهند که چند نت کمتر از نت مورد نظر پخش شده است ، از جمله نت مورد نظر. به عنوان مثال ، اگر C4 ، E4 ، G4 ، A#4 و D5 پخش شوند (وتر C9) cntC4 1 ، cntE4 2 ، cntG4 3 و غیره خواهد بود.

سپس ، هر زمان که یک نت پخش می شود ، شمارش نت مورد نظر بررسی می شود تا مشخص شود که سیگنال نت را به کجا وصل می کند. به عنوان مثال ، اگر نت D5 پخش شود (که به معنی O5 (2) بالا است) و cntD5 3 باشد ، در حال حاضر 3 نت در حال پخش است ، با 2 نت کمتر از D5 ، بنابراین ما waveD5 را به Wave2 وصل می کنیم (موج سوم شمارش سیگنال از Wave0). متناوبا ، اگر cntD5 5 باشد ، در حال حاضر 5 نت در حال پخش است ، با 4 نت کمتر از D5 ، بنابراین ما فقط waveD5 را آویزان می گذاریم و کاری با آن نمی کنیم.

سپس عبارات IF برای پوشش دادن موارد مربوط به هر 25 یادداشت تکرار می شود.

Amplitude Adder

پس از انتخاب کمترین 4 موج ، باید آنها را با هم جمع کنیم. دلیل اینکه ما فقط چهار نت را با هم جمع می کنیم این است که ایده PWM که ما برای خروجی خود استفاده می کنیم فقط می تواند وضوح خاصی داشته باشد تا زمانی که PWM خیلی کند کار کند و بلندگو شروع به برداشتن موج مربعی PWM کند. به عنوان مثال ، اگر بخواهیم از رزولوشن 8192 (13 بیت) استفاده کنیم ، هر یک از این 8192 نقطه باید با لبه بالارونده ساعت روی صفحه مطابقت داشته باشد. بنابراین ، 100 مگاهرتز / 8192 = 12.2 کیلوهرتز ، که در محدوده شنوایی انسان قرار دارد.

افزودن واقعی دامنه ها بسیار ساده است ، فقط باید مطمئن شوید که می تواند بسیار سریع اجرا شود.

خروجی PWM

چرخه وظیفه PWM نشان دهنده دامنه موج خروجی ما در آن لحظه است. به عنوان مثال ، اگر دامنه دامنه ای از 0 تا 128 داشته باشیم ، 0 یک چرخه کار 0٪ ، 64٪ 50 ، 128٪ 100٪ و غیره خواهد بود. این PWM بسیار سریع اجرا می شود (ما 97.6 کیلوهرتز است) ، آنقدر سریع که بلندگو امواج مربعی را تشخیص نمی دهد و در عوض به ولتاژ متوسط نگاه می کند و سیگنال "آنالوگ" ما را ایجاد می کند.

فایل محدودیت ها

ممکن است سخت افزار خود را متفاوت متصل کرده باشید ، بنابراین فقط مطمئن شوید که فایل محدودیت ها مطابقت دارد.

مرحله 5: بارگیری کد

در زیر کد ، هم در قالب.txt و هم در.vhd برای Vivado آمده است. Wave_Generator زیر ماژول مولد موج است و Two_Octave_Synth ماژول برتر با سایر موارد است.

توصیه شده: