সুচিপত্র:

বেসিস 3 এফপিজিএ ডিজিটাল অডিও সিনথেসাইজার: 5 টি ধাপ
বেসিস 3 এফপিজিএ ডিজিটাল অডিও সিনথেসাইজার: 5 টি ধাপ

ভিডিও: বেসিস 3 এফপিজিএ ডিজিটাল অডিও সিনথেসাইজার: 5 টি ধাপ

ভিডিও: বেসিস 3 এফপিজিএ ডিজিটাল অডিও সিনথেসাইজার: 5 টি ধাপ
ভিডিও: বেসিস সফটএক্সপোর নতুন রেকর্ড | Software | BASIS | News | Ekattor TV 2024, জুলাই
Anonim
Image
Image
Basys3 FPGA ডিজিটাল অডিও সিনথেসাইজার
Basys3 FPGA ডিজিটাল অডিও সিনথেসাইজার
Basys3 FPGA ডিজিটাল অডিও সিনথেসাইজার
Basys3 FPGA ডিজিটাল অডিও সিনথেসাইজার

এই ডিজিটাল সাইন ওয়েভ কীবোর্ড সিনথেসাইজার ব্যবহারকারীর ইনপুটগুলি একটি কীবোর্ডের মত স্থাপিত ক্ষণস্থায়ী সুইচগুলির মাধ্যমে গ্রহণ করবে এবং একটি স্পিকারের মাধ্যমে একটি অডিও তরঙ্গ বের করবে। ব্যবহারকারীর ইনপুটগুলির উপর ভিত্তি করে, ডিভাইসটি C4 থেকে C6 পর্যন্ত বিভিন্ন ফ্রিকোয়েন্সিগুলির সাইন ওয়েভ তৈরি করবে। ব্যবহারকারী C4 থেকে C6 পর্যন্ত নোট ইনপুট করতে পারেন (মোট 25 টি নোট), এবং একই সাথে চারটি কী - যদি চারটির বেশি কী চাপানো হয়, তাহলে চারটি সর্বনিম্ন সুর বাজানো হবে।

এই প্রকল্পটি আমাদের Cal Poly CPE 133 ডিজিটাল ডিজাইন ক্লাসের জন্য রায়ান মরিস এবং মাভিস Tsoi দ্বারা করা হয়েছিল:)

ধাপ 1: তত্ত্ব

একটি FPGA বোর্ড শুধুমাত্র ডিজিটাল সিগন্যাল আউটপুট করতে পারে। অন্য কথায়, এটি শুধুমাত্র একটি উচ্চ (3.3V) ভোল্টেজ বা কম (0V) ভোল্টেজ তৈরি করতে পারে। যাইহোক, অডিও সংকেতগুলি এনালগ এবং ভোল্টেজের অসীম বৃদ্ধি হতে পারে। এটির কাছাকাছি যেতে, আমরা একটি এনালগ তরঙ্গ অনুকরণ করার জন্য একটি PWM (পালস প্রস্থ মডুলেশন) সংকেত ব্যবহার করব। যদি আপনি জানেন না PWM কি, তাহলে এটি দেখুন:

ধাপ 2: উপকরণ এবং সরঞ্জাম

  • ভিভাডো সহ কম্পিউটার ইনস্টল
  • আমরা Vivado সংস্করণ 2017.2 ব্যবহার করব
  • Basys3 FPGA বোর্ড
  • 25 এসপিডিটি সীমা সুইচ (আমরা এগুলি ব্যবহার করেছি)
  • 30 জাম্পার তার (এক প্রান্ত পুরুষ, অন্য প্রান্ত কোন ব্যাপার না), 12 ইঞ্চি
  • তার কাটার যন্ত্র
  • তারের স্ট্রিপার
  • সোল্ডারিং জন্য অতিরিক্ত তারের
  • রজন-কোর সোল্ডার
  • তাতাল
  • Female”মহিলা অডিও জ্যাক
  • পরিবর্ধক/স্পিকার
  • সুইচগুলি মাউন্ট করার জন্য কিছু (আমরা প্রোটোবোর্ড + কাঠের বাক্স ব্যবহার করেছি)

ধাপ 3: ওয়্যারিং এবং হার্ডওয়্যার সেটআপ

ওয়্যারিং এবং হার্ডওয়্যার সেটআপ
ওয়্যারিং এবং হার্ডওয়্যার সেটআপ
ওয়্যারিং এবং হার্ডওয়্যার সেটআপ
ওয়্যারিং এবং হার্ডওয়্যার সেটআপ
ওয়্যারিং এবং হার্ডওয়্যার সেটআপ
ওয়্যারিং এবং হার্ডওয়্যার সেটআপ

সিস্টেম আর্কিটেকচার

চিত্র 1 দেখুন: 25 উপলব্ধ ইনপুট → Basys3 বোর্ড → পরিবর্ধক এবং স্পিকার।

আউটপুট

চিত্র 2 দেখুন: Basys3 বোর্ড → 1/2 মহিলা অডিও জ্যাক → স্পিকার (পরিবর্ধক সহ)

ইনপুট

Basys3 বোর্ডে pmod সংযোগগুলি অবশ্যই একটি কম ইনপুট দেখতে মাটির সাথে সংযুক্ত থাকতে হবে এবং ওপেন সার্কিট হিসাবে ছেড়ে দিলে সঠিকভাবে কাজ করবে না। এই কারণে, আমাদের সমস্ত নোট কীগুলির জন্য আমাদের SPDT সুইচ ব্যবহার করতে হবে। একটি এসপিডিটি সুইচ মূলত ব্যবহারকারীকে চাপ দিলে সার্কিটের মধ্যে স্যুইচ করার অনুমতি দেয়, তাই আমরা সেগুলিকে আমাদের "বোতাম" হিসাবে ব্যবহার করব নিম্ন (0V) বা উচ্চ (3.3V) সংকেতগুলি Basys3 বোর্ডে।

প্রতিটি সুইচে 3.3V এর সাথে NO (সাধারনভাবে খোলা) টার্মিনাল থাকবে, NC (সাধারনত বন্ধ) টার্মিনাল GND এর সাথে সংযুক্ত থাকবে, এবং FPGA ইনপুটের সাথে সংযুক্ত COM (সাধারণ) টার্মিনাল থাকবে। চিত্র 3 দেখুন।

যেহেতু আমাদের 25 টি সীমা সুইচ আছে, তারা সবাই একটি সাধারণ 3.3V লাইন এবং একটি সাধারণ GND লাইন ভাগ করবে। তারপরে, প্রতিটি সীমা সুইচ থেকে সংকেত লাইন 8 টি গ্রুপে একত্রিত হবে এবং বাসিস 3 বোর্ডে পিএমড সংযোগের সাথে সংযুক্ত হবে জিপেবল জাম্পার তারগুলি ব্যবহার করে আমরা যে স্মৃতিময় জগাখিচুড়ি করব তা কমানোর জন্য। চিত্র 4 বা প্রথম আটটি কীগুলির উদাহরণ দেখুন।

ধাপ 4: ভিএইচডিএল সেটআপ (ভিভাদো)

ভিএইচডিএল সেটআপ (ভিভাদো)
ভিএইচডিএল সেটআপ (ভিভাদো)
ভিএইচডিএল সেটআপ (ভিভাদো)
ভিএইচডিএল সেটআপ (ভিভাদো)

সাইন ওয়েভ জেনারেটর এবং পিডব্লিউএম জেনারেটরকে প্রথমে পরীক্ষা করা হয়েছিল যাতে আমাদের ধারণা কাজ করে, তারপর ইনপুট সীমাবদ্ধতা এবং প্রশস্ততা সংযোজনকারী/শিফটার একীভূত হয়। ফাংশনের বিবরণ এবং প্রতিটি প্রসেস ব্লকের I/O চিত্রের মতো দেখানো হয়েছে। কোডটি নীচে দেখানো হয়েছে, তবে এটি VHD এবং txt ফাইল হিসাবে সংযুক্ত। যদি অসঙ্গতি থাকে, তাহলে ভিএইচডি ফাইলের সাথে যান।

বিটিডব্লিউ: আমাদের সম্ভবত আমাদের লাইনগুলি ছোট করা উচিত ছিল কিন্তু ইন্সট্রাকটেবলগুলিতে কোড এম্বেড করাও মোকাবেলা করার জন্য বেশ বিরক্তিকর হয়ে উঠেছিল, তাই ব্যবধানটি সবচেয়ে বড় নয় এবং কোনও সিনট্যাক্স হাইলাইট করা নেই। আপনার যদি ভিভাডো থাকে এবং কোডটি অনুসরণ করতে চান, আমরা আপনাকে ফাইলটি ডাউনলোড করার জন্য সুপারিশ করছি।

প্রথমে, সাইন ওয়েভ জেনারেটর মডিউলটি দেখুন।

লাইব্রেরি IEEE; IEEE. STD_LOGIC_1164. ALL ব্যবহার করুন; IEEE. NUMERIC_STD. ALL ব্যবহার করুন; সত্তা Wave_Generator হল পোর্ট (ট্রিগার: STD_LOGIC এ; - কী প্রেস করুন Freq_Cnt: STD_LOGIC_VECTOR এ (15 ডাউন 0); ফ্রেক ওয়েভজেন CLK থেকে: STD_LOGIC এ; - তরঙ্গ প্রান্ত Wave_Generator স্বাক্ষরিত প্রশস্ততা; আর্কিটেকচার ওয়েভ_জেনারেটরের আচরণগত সংকেত i: পূর্ণসংখ্যা পরিসর 0 থেকে 64: = 0; -প্রশস্ততা মেমরি ব্যাঙ্কের সূচক মেমরি_ টাইপ পূর্ণসংখ্যার পরিসরের অ্যারে (0 থেকে 63) -64 থেকে 63; - প্রশস্ততা মান রাখার জন্য মেমরি ব্যাংক (রম) তৈরি করুন- এই র্যাম বা রম কি শুধু ভাবছে … সংকেত প্রশস্ততা: memory_type: = (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); - সাইন ওয়েভ শুরুর প্রক্রিয়া (ওয়েভজেনসিএলকে, ট্রিগার) ভেরিয়েবল কাউন্টারের জন্য প্রশস্ততা মেমরি ব্যাংক: স্বাক্ষরবিহীন (15 ডাউনটো 0): = to_unsigned (0, 16); - ক্লক ডিভাইডার কাউন্টার, নামকরণ করা হয়েছে count1 থেকে শুরু হলে যদি (কাউন্টার = স্বাক্ষরবিহীন (Freq_Cnt)) তাহলে - Freq_Cnt = 100Mhz / (নোট freq * সাইন ওয়েভের 64 বিভাগ) - কাউন্টার রিসেট করুন এবং আউটপুট কাউন্টারে প্রশস্ততা ডেটা বরাদ্দ করুন: = to_unsigned (0, 16); WaveOut <= STD_LOGIC_VECTOR (to_signed (amplitude (i), 10)); - পরবর্তী পড়ার জন্য i <= i + 1 বৃদ্ধি; - যদি একটি সাইন ওয়েভ সম্পন্ন হয় তবে পুনরায় সেট করুন (i = 63) তারপর i <= 0; যদি শেষ; যদি শেষ; - (কাউন্টার = স্বাক্ষরবিহীন (Freq_Cnt)) অন্য- কী চাপানো হয় না- আউটপুট, প্রশস্ততা সূচক এবং কাউন্টার ওয়েভআউট <= "0000000000"; আমি <= 0; পাল্টা: = to_unsigned (0, 16); -আউটপুট প্রশস্ততা = -64 যখন কোন নোট খেলা শেষ হয় যদি; - (ট্রিগার = '1') শেষ হলে; - (রাইজিং_ এজ (CLK)) শেষ প্রক্রিয়া; শেষ আচরণ;

আমরা অভ্যন্তরীণ ঘড়ি এবং একটি রম ব্যবহার করে Basys3 এ একটি ডিজিটাল সাইন ওয়েভ তৈরি করব। এই রম values টি মান সংরক্ষণ করবে যা একটি সাইন ওয়েভে amp টি প্রশস্ততার প্রতিনিধিত্ব করে। চিত্র 1 দেখুন। আমরা যে 64 টি মান ব্যবহার করি তা বেশ ভালো রেজোলিউশনের সঙ্গে একটি সাইন ওয়েভ অনুকরণ করে।

অভ্যন্তরীণ ঘড়ি ব্যবহার করে, আমরা একটি মান গণনা করি যা ঘড়ির গতিকে আমাদের তরঙ্গের ফ্রিকোয়েন্সি দ্বারা বিভক্ত করে এবং 64: Clk div = 100MHz / (Freq * 64) প্রতিবার আমাদের কাউন্টার সেই মান পৌঁছায়, আমরা একটি নম্বর থেকে কল করি রম এবং আমাদের তরঙ্গ জেনারেটর মডিউল থেকে এটি পাঠান। আমাদের তরঙ্গের ফ্রিকোয়েন্সি নির্ভর করবে কত দ্রুত আমরা এই পরিবর্ধনগুলিকে বলি।

আমাদের 25 টি উপ-মডিউল থাকবে, প্রতিটি একটি ফ্রিকোয়েন্সি/নোটের সাথে যুক্ত।

এখানে সাইন ওয়েভ জেনারেটর মডিউলগুলিকে কল করা কোডের অবশিষ্টাংশ রয়েছে:

লাইব্রেরি IEEE; IEEE. STD_LOGIC_1164. ALL ব্যবহার করুন; IEEE. NUMERIC_STD. ALL ব্যবহার করুন; সত্তা Two_Octave_Synth হল পোর্ট (CLK: STD_LOGIC এ; O4: STD_LOGIC_VECTOR (11 ডাউনটো 0); O5: STD_LOGIC_VECTOR (12 ডাউনটো 0); আউটপুট: STD_LOGIC); শেষ Two_Octave_Synth; Two_Octave_Synth- এর আর্কিটেকচার বিহেভিয়ারাল উপাদান Wave_Generator হল পোর্ট (ট্রিগার: STD_LOGIC এ; Freq_Cnt: STD_LOGIC_VECTOR (15 downto 0); wavegenCLK: STD_LOGIC এ; WaveOut: আউট STD_LOGIC_VECTOR) শেষ উপাদান; --------------------------- তরঙ্গ জেনারেটর থেকে আউটপুট সংকেত ------------------ ----- সংকেত WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, Wave5, Wave5, Wave5, Wave5 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: স্বাক্ষরবিহীন (0 ডাউনটো 4); সিগন্যাল cntC4, cntCs4, cntD4, cntDs4, cntE4, cntF4, cntFs4, cntG4, cntGs4, cntA4, cntAs4, cntB4, cntC5, cntCs5, cntD5, cntDs5, cnt5, cnt5, cnt5, cnt5, cnt5: স্বাক্ষরবিহীন (0 থেকে 4 পর্যন্ত); সংকেত ত্রুটি: STD_LOGIC; ----------------------------------- সাইন ওয়েভ যুক্ত করার জন্য ----------- --------------- সংকেত Wave0, Wave1, Wave2, Wave3: স্বাক্ষরিত -ওয়েভ জেনারেটর মডিউল আউটপুট সিগন্যাল ওয়েভসাম থেকে সিগন্যাল: STD_LOGIC_VECTOR (9 ডাউনটো 0); -সংক্ষিপ্ত সাইন ওয়েভের জন্য সিগন্যাল (2 এর প্রশংসা -512 থেকে 511) সংকেত ইতিবাচক ওয়েভসাম: STD_LOGIC_VECTOR (9 ডাউনটো 0); -PWM জেনারেটরে ব্যবহারের জন্য 0 থেকে 1023 স্বাক্ষরিত ----------------------------------- PWM তৈরির জন্য ---------------- --signal off_length: স্বাক্ষরবিহীন (dow টি ডাউনটো): = to_unsigned (127, 7) -স্বাক্ষরবিহীন (WAVE); সিগন্যাল PWM: স্বাক্ষরবিহীন (0 থেকে 0): = to_unsigned (0, 10); Note_C4 শুরু করুন: Wave_Generator পোর্ট ম্যাপ (Trigger => O4 (0), Freq_Cnt => X "1755", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveC4); --5973, 261.63 Hz Note_Cs4: Wave_Generator পোর্ট ম্যাপ (ট্রিগার => O4 (1), Freq_Cnt => X "1606", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveCs4);-5638, 277.18 Hz Note_D4: Wave_Generator পোর্ট ম্যাপ (Trigger => O4 (2), Freq_Cnt => X "14C9", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveD4); --5321, 293.66 Hz Note_Ds4: Wave_Generator পোর্ট ম্যাপ (ট্রিগার => O4 (3), Freq_Cnt => X "139F", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveDs4);-5023, 311.13 Hz Note_E4: Wave_Generator পোর্ট ম্যাপ (Trigger => O4 (4), Freq_Cnt => X "1285", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveE4); --4741, 329.63 Hz Note_F4: Wave_Generator পোর্ট ম্যাপ (ট্রিগার => O4 (5), Freq_Cnt => X "117B", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveF4); --4475, 349.23 Hz Note_Fs4: Wave_Generator পোর্ট ম্যাপ (ট্রিগার => O4 (6), Freq_Cnt => X "1080", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveFs4);-4224, 369.99 Hz Note_G4: Wave_Generator পোর্ট ম্যাপ (Trigger => O4 (7), Freq_Cnt => X "0F92", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveG4); --3986, 392.00 Hz Note_Gs4: Wave_Generator পোর্ট ম্যাপ (ট্রিগার => O4 (8), Freq_Cnt => X "0EB3", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveGs4);-3763, 415.30 Hz Note_A4: Wave_Generator পোর্ট ম্যাপ (Trigger => O4 (9), Freq_Cnt => X "0DE0", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveA4); --3552, 440.00 Hz Note_As4: Wave_Generator পোর্ট ম্যাপ (ট্রিগার => O4 (10), Freq_Cnt => X "0D18", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveAs4);-3352, 466.16 Hz Note_B4: Wave_Generator পোর্ট ম্যাপ (Trigger => O4 (11), Freq_Cnt => X "0C5C", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveB4); --3164, 493.88 Hz -------------------------------------------- -------------------------------------------------- --------------------------- Note_C5: Wave_Generator পোর্ট ম্যাপ (ট্রিগার => O5 (0), Freq_Cnt => X "0BAB", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveC5); -2987, 523.25 Hz Note_Cs5: Wave_Generator port map (Trigger => O5 (1), Freq_Cnt => X "0B03", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveCs5);-2819, 554.37 Hz Note_D5: Wave_Generator পোর্ট ম্যাপ (Trigger => O5 (2), Freq_Cnt => X "0A65", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveD5); --2661, 587.33 Hz Note_Ds5: Wave_Generator পোর্ট ম্যাপ (ট্রিগার => O5 (3), Freq_Cnt => X "09D0", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveDs5);-2512, 622.25 Hz Note_E5: Wave_Generator পোর্ট ম্যাপ (Trigger => O5 (4), Freq_Cnt => X "0943", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveE5); --2371, 659.25 Hz Note_F5: Wave_Generator পোর্ট ম্যাপ (ট্রিগার => O5 (5), Freq_Cnt => X "08Be", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveF5); --2238, 698.46 Hz Note_Fs5: Wave_Generator পোর্ট ম্যাপ (ট্রিগার => O5 (6), Freq_Cnt => X "0840", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveFs5);-2112, 739.99 Hz Note_G5: Wave_Generator পোর্ট ম্যাপ (Trigger => O5 (7), Freq_Cnt => X "07CA", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveG5); --1994, 783.99 Hz Note_Gs5: Wave_Generator পোর্ট ম্যাপ (ট্রিগার => O5 (8), Freq_Cnt => X "075A", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveGs5);-1882, 830.61 Hz Note_A5: Wave_Generator পোর্ট ম্যাপ (Trigger => O5 (9), Freq_Cnt => X "06F0", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveA5); --1776, 880.00 Hz Note_As5: Wave_Generator পোর্ট ম্যাপ (ট্রিগার => O5 (10), Freq_Cnt => X "068C", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveAs5);-1676, 932.33 Hz Note_B5: Wave_Generator পোর্ট ম্যাপ (Trigger => O5 (11), Freq_Cnt => X "062E", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveB5); --1582, 987.77 Hz Note_C6: Wave_Generator পোর্ট ম্যাপ (ট্রিগার => O5 (12), Freq_Cnt => X "05D6", wavegenCLK => CLK, স্বাক্ষরিত (WaveOut) => WaveC6); --1494, 1046.5 Hz ------------ নোট নির্বাচনের যুক্তি ------------ 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; নির্বাচন: প্রক্রিয়া WaveB5, WaveC6) শুরু হয় যদি (cntC6 = "00000") তাহলে --------------- যদি কোন সংকেত তৈরি না হয় Wave0 <= "0000000000"; ওয়েভ 1 <= "0000000000"; ওয়েভ 2 <= "0000000000"; ওয়েভ 3 <= "0000000000"; অন্যথায় যদি (O4 (0) = '1') তাহলে ------------------- দ্রষ্টব্য C4 Wave0 Wave0 Wave1 ত্রুটি Wave0 Wave1 Wave2 ত্রুটি Wave0 Wave1 Wave1 Wave2 Wave3 ত্রুটি Wave0 Wave1 Wave2 Wave3 ত্রুটি Wave0 Wave1 Wave2 Wave3 ত্রুটি Wave0 Wave1 Wave1 Wave3 ত্রুটি Wave0 Wave1 Wave0 Wave3 ত্রুটি Wave0 Wave1 Wave2 Wave3 ত্রুটি Wave0 Wave1 Wave2 Wave3 Wave0 Wave0 Wave0 ত্রুটি Wave0 Wave0 Wave0 Wave0 Wave0 Wave2 Wave3 ত্রুটি Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave0 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave3 error Wave0 Wave0 Wave0 Wave0 Wave1 Wave0 = ওয়েভসি 6; ওয়েভ 1 <= "0000000000"; ওয়েভ 2 <= "0000000000"; Wave3 Wave1 <= WaveC6; ওয়েভ 2 <= "0000000000"; Wave3 Wave2 <= WaveC6; Wave3 Wave3 ত্রুটি Wave1 <= "0000000000"; ওয়েভ 2 <= "0000000000"; ওয়েভ 3 ওয়েভ 2 <= "0000000000"; Wave3 Wave3 ত্রুটি <= '1'; শেষ কেস; যদি শেষ; যদি শেষ; শেষ প্রক্রিয়া; ------------- সাইন ওয়েভ অ্যাডার -------------------- ওয়েভসাম <= STD_LOGIC_VECTOR (Wave0 + Wave1 + Wave2 + Wave3); --------- সাইন ওয়েভকে পিডব্লিউএমের জন্য ইতিবাচক করুন --------------------- পজিটিভ ওয়েভসাম <= ওয়েভসাম নয়); ------------- PWM জেনারেটর --------------------- প্রক্রিয়া (CLK)-পরিবর্তনশীল গণনা: স্বাক্ষরবিহীন (1 ডাউন 0 পর্যন্ত): = to_unsigned (0, 2); যদি শুরু হয় -if (count = to_unsigned (4, 2)) তারপর-count: = to_unsigned (0, 2); --if (PWM = to_ if (PWM <ping_length) তারপর আউটপুট <= '1'; অন্যথায় আউটপুট <= '0'; শেষ হলে; PWM <= PWM + 1; ping_length <= স্বাক্ষরবিহীন (ইতিবাচক ওয়েভসাম);-শেষ if; end if; end process; end Behavioral;

4 নোট নির্বাচক এই প্রকল্পের সবচেয়ে জটিল অংশ হল মাত্র চারটি ফ্রিকোয়েন্সি নির্বাচন করা। আমরা এটি একটি সম্পূর্ণ লোটা IF স্টেটমেন্ট দিয়ে করেছি, এবং আমরা ভেরিয়েবলের পরিবর্তে সিগন্যাল ব্যবহার করেছি যাতে প্রক্রিয়াটি সিমুলেটেড এবং ডিবাগ করা যায়। আমরা ভেরিয়েবল এবং ফোর লুপ ব্যবহার করে অন্যান্য পদ্ধতি চেষ্টা করেছি, কিন্তু রান-টাইম ত্রুটির মধ্যে দৌড়ে গিয়েছিলাম। সুতরাং, শেষ পর্যন্ত, আমরা সিদ্ধান্ত নিয়েছি যে যদি এটি কাজ করে তবে আমরা এটি একা রেখে দেব।ভাঙা অ্যামিরাইট নয় কি ঠিক করবেন?

চারটি আউটপুট তরঙ্গকে Wave0, Wave1, Wave2, Wave3 লেবেল করা হয়েছে - এগুলিই চূড়ান্ত আউটপুট গঠনের জন্য একত্রিত হবে।

কোডটি দেখলে, আপনি C4, Cs4, D4, Ds4, ইত্যাদি লেবেলযুক্ত সংকেতগুলির একটি গুচ্ছ দেখতে পাবেন। যোগ করার জন্য 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 ঝুলিয়ে রাখব এবং এটি দিয়ে কিছু করব না।

সমস্ত 25 নোটের ক্ষেত্রে কভার করার জন্য IF স্টেটমেন্টগুলি পুনরাবৃত্তি করা হয়।

প্রশস্ততা অ্যাডার

সর্বনিম্ন 4 টি তরঙ্গ নির্বাচিত হওয়ার পর আমাদের সেগুলো একসাথে যুক্ত করতে হবে। আমরা শুধুমাত্র চারটি নোট একসাথে যুক্ত করার কারণ হল যে আমরা আমাদের আউটপুটের জন্য যে PWM ধারণাটি ব্যবহার করছি তা শুধুমাত্র একটি নির্দিষ্ট রেজোলিউশন থাকতে পারে যতক্ষণ না PWM খুব ধীর গতিতে চলছে এবং স্পিকার PWM বর্গ তরঙ্গ বাছাই শুরু করবে। উদাহরণস্বরূপ, যদি আমরা 8192 (13 বিট) এর রেজোলিউশন ব্যবহার করতাম, সেই 8192 পয়েন্টের প্রত্যেকটি জাহাজের ঘড়ির ক্রমবর্ধমান প্রান্তের সাথে মিলিত হতে হবে। সুতরাং, 100MHz / 8192 = 12.2kHz, যা মানুষের শ্রবণের পরিসরের মধ্যে ভাল।

প্রশস্ততার প্রকৃত সংযোজন অতি সহজ, আপনাকে শুধু নিশ্চিত করতে হবে যে এটি সত্যিই দ্রুত চলতে পারে।

PWM আউটপুট

PWM এর দায়িত্ব চক্র সেই মুহূর্তে আমাদের আউটপুট তরঙ্গের প্রশস্ততা প্রতিনিধিত্ব করবে। উদাহরণস্বরূপ, যদি আমাদের 0 থেকে 128 এর একটি প্রশস্ততা পরিসীমা থাকে, 0 হবে 0%শুল্ক চক্র, 64 হবে 50%, 128 হবে 100%ইত্যাদি, এই PWM অত্যন্ত দ্রুত চলবে (আমাদের 97.6 kHz), এত দ্রুত যে স্পিকার পৃথক বর্গ তরঙ্গ চিনবে না এবং পরিবর্তে গড় ভোল্টেজের দিকে তাকাবে, আমাদের "এনালগ" সংকেত তৈরি করবে।

সীমাবদ্ধতা ফাইল

আপনি হয়তো আপনার হার্ডওয়্যারকে ভিন্নভাবে সংযুক্ত করেছেন, তাই নিশ্চিত করুন যে সীমাবদ্ধতা ফাইলটি মেলে।

ধাপ 5: কোড ডাউনলোড

নীচে কোড, উভয়.txt বিন্যাসে এবং.vhd ভিভাদোর জন্য। ওয়েভ_ জেনারেটর হল ওয়েভ জেনারেটর সাব-মডিউল, এবং টু_অকটেভ_সিন্থ হল অন্য সবকিছুর সাথে শীর্ষ মডিউল।

প্রস্তাবিত: