element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Summer of FPGA
  • Challenges & Projects
  • Design Challenges
  • Summer of FPGA
  • More
  • Cancel
Summer of FPGA
Blog Audio Synth # 6 - Sound generation with CmodS7
  • Blog
  • Forum
  • Documents
  • Files
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: a33333
  • Date Created: 24 Jan 2022 2:53 AM Date Created
  • Views 1910 views
  • Likes 7 likes
  • Comments 0 comments
Related
Recommended

Audio Synth # 6 - Sound generation with CmodS7

a33333
a33333
24 Jan 2022

Table of Contents

  1. Audio Synth #1 - The project
  2. Audio Synth #2 - Board introduction and IDE setup
  3. Audio Synth #3 - Arduino to CmodS7 COMM Test
  4. Audio Synth #4 - Use PWM to control LED
  5. Audio Synth #5 - Testing the I2S PCM5102 DAC Decoder Board
  6. Audio Synth #6 - Sound generation with CmodS7
  7. Audio Synth #7 - Design challenge ends, project continues

===========================================================

I2S protocol

I will be using a PCM5102 I2S DAC board for sound generation. “I2S is a serial bus standard used to communicate PCM audio data between integrated circuits in an electronic device. The I2S bus separates clock and serial data signals, resulting in simpler receivers than those required for asynchronous communications systems that need to recover the clock from the data stream” (https://en.wikipedia.org/wiki/I%C2%B2S).

The following timing diagram and explanation are taken from wikipedia. 

image

 “The bit clock pulses once for each discrete bit of data on the data lines. The bit clock frequency is the product of the sample rate, the number of bits per channel and the number of channels. So, for example, CD Audio with a sample frequency of 44.1 kHz, with 16 bits of precision and two channels (stereo) has a bit clock frequency of: 44.1 kHz × 16 × 2 = 1.4112 MHz

The word select clock lets the device know whether channel 0 or channel 1 is currently being sent, because I2S allows two channels to be sent on the same data line. It is a 50% duty-cycle signal that has the same frequency as the sample frequency. For stereo material, the I2S specification states that left audio is transmitted on the low cycle of the word select clock and the right channel is transmitted on the high cycle. It is typically synchronized to the falling edge of the serial clock, as the data is latched on the rising edge. The word select clock changes one bit clock period before the MSB is transmitted. This enables, for example, the receiver to store the previous word and clear the input for the next.

Data is signed, encoded as two’s complement with the MSB first. This allows the number of bits per frame to be arbitrary, with no negotiation required between transmitter and receiver.”

Sound Generation Project

This is a Verilog project that uses the PCM5102 DAC board to generate a continuous sound with a 400Hz pitch (A4 is at 440Hz btw). To keep things simple, I will use a square wave with 50% duty cycle. For a sampling frequency of 48Khz, generating 400Hz translates into 120 samples per period of square wave, which means 60 samples will be on a high level, and 60 samples on low. Working with 16 bits ( 65,536 quantization levels) in two’s complement, the highest possible amplitude is 0x7FFF (corresponding to 32,767), while the lowest is 0x8001 (corresponding to  -32,767). So, generating a continuous pitch of 400Hz at the highest volume (amplitude), using a 50% duty square wave at 48000Hz, boils down to feeding the DAC with 60 samples of 0x7FFF followed by 60 samples of 0x8001 and repeating this sequence forever.     

Design options

The first option would be to use an existing I2S Verilog core. Xilinx offers a I2S Transmitter and a I2S Receiver https://www.xilinx.com/products/intellectual-property/audio-i2s.html, however Spartan 7 family is not supported. The second option, which I am going to take, is to write the Verilog code and generate “from scratch” all the signals to be fed into the DAC PCM5102 board.  

Next figure shows the I2S timing diagram which I found in the PCM5100 datasheet. https://www.ti.com/lit/ds/symlink/pcm5101.pdf?ts=1642966567280&ref_url=https%253A%252F%252Fwww.google.com%252F

image

The frequency of LRCK is the sampling frequency I chose, i.e. 48KHz. I will use 16 bits with BCK=64x48KHz = 3.072MHz. I selected this value for BCK from table 5 from the datasheet. PCM 5102 also needs a system clock (SCK) signal. From table 3  in the datasheet I selected a SCK=512x48KHz= 24.576MHz. So, if I can generate a SCK clock at 24.576MHz, I can derive BCK using a freq. divider by 8. Once BCK is available, I can use its negative edges to output the data according to the timing diagrams. The whole process will be clear once you look at the Verilog code.    

SCK Clock Generation

I spent some time reading  Xilinx UG472 that describes clocking resources (architecture, CMTs, buffers, etc…)  https://www.xilinx.com/support/documentation/user_guides/ug472_7Series_Clocking.pdf   The FPGA on Cmod S7 has 3 Clock Management Tiles, each with a phase-locked loop and mixed-mode clock manager.

I continued reading about how to use Clocking Wizard in Xilinx PG065 https://www.xilinx.com/support/documentation/ip_documentation/clk_wiz/v6_0/pg065-clk-wiz.pdf

After a while I felt confident (or maybe just brave…) enough to give it a try, with the intention of going back to UG472 to clarify finer points if needed. Here are a couple of screenshots of the Clocking Wizard. You can see the 12MHz clock on CmodS7 as clk_in1 and also clk_out1 at 24.576MHz.

image

image

Clocking Wizard generates a Verilog wrapper (module sckClock.v).  Here is an extract: 

//----------------------------------------------------------------------------
//  Output     Output      Phase    Duty Cycle   Pk-to-Pk     Phase
//   Clock     Freq (MHz)  (degrees)    (%)     Jitter (ps)  Error (ps)
//----------------------------------------------------------------------------
// clk_out1__24.57600______0.000______50.0______598.000____693.818
//
//----------------------------------------------------------------------------
// Input Clock   Freq (MHz)    Input Jitter (UI)
//----------------------------------------------------------------------------
// __primary__________12.000____________0.010

`timescale 1ps/1ps

(* CORE_GENERATION_INFO = "sckClock,clk_wiz_v6_0_9_0_0,{component_name=sckClock,use_phase_alignment=true,use_min_o_jitter=false,use_max_i_jitter=false,use_dyn_phase_shift=false,use_inclk_switchover=false,use_dyn_reconfig=false,enable_axi=0,feedback_source=FDBK_AUTO,PRIMITIVE=MMCM,num_out_clk=1,clkin1_period=83.333,clkin2_period=10.0,use_power_down=false,use_reset=true,use_locked=true,use_inclk_stopped=false,feedback_type=SINGLE,CLOCK_MGR_TYPE=NA,manual_override=false}" *)

module sckClock 
 (
  // Clock out ports
  output        clk_out1,
  // Status and control signals
  input         reset,
  output        locked,
 // Clock in ports
  input         clk_in1
 );

  sckClock_clk_wiz inst
  (
  // Clock out ports  
  .clk_out1(clk_out1),
  // Status and control signals               
  .reset(reset), 
  .locked(locked),
 // Clock in ports
  .clk_in1(clk_in1)
  );

endmodule

Now that I have a Verilog module that takes CmodS7’s 12MHz clock as input and outputs a SCK clock at 24.756MHz, I will look at how I can write the whole sound test app. The first module I wrote is oscI2S.v. This takes a 24.756MHz clock as input and outputs the needed BCK and LRCK clocks. (division by 8 and 64). https://github.com/a3333333/Summer-of-FPGA/blob/main/soundTest/cmods7/oscillatorI2S.v

The second module I wrote was a squareWaveGenerator. The hw32 and lw32 registers contain the whole sequence (32 bit) for the high and low levels. (to make things more visible in the simulator I used the value 0x75F5 instead of 0x7FFF for the high level.) To keep things simple, I only send data on the left channel, the right channel stays at 0. https://github.com/a3333333/Summer-of-FPGA/blob/main/soundTest/cmods7/squareWaveGenerator.v

To test the code, I wrote a testbech. https://github.com/a3333333/Summer-of-FPGA/blob/main/soundTest/cmods7/testbench.v Here is the result of the simulation: on the left channel one can see a series of 8 samples (4 samples of high level followed by 4 samples low level). For the simulation I tried various numbers of samples: 8, 16, 20, 30, etc… The code behaved well for all tests, so for the final version of the code I used 120 samples (60 high level + 60 low level) so that the generated pitch will be 400Hz. 

image

Here is a close up where one can see the high level (75F5) and the low level (8001) on the left channel.

image

here are a couple of schematics for the implemented design.

image

image

Finally, here is a movie where you can hear the 400Hz pitch of the 50% duty square wave:

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

Github repository: 

https://github.com/a3333333/Summer-of-FPGA/tree/main/soundTest

Concepts: Xilinx Clocking Resources, Clock Management Tile, Clocking Wizard, I2S protocol, 

  • Sign in to reply
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube