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
Personal Blogs
  • Community Hub
  • More
Personal Blogs
Legacy Personal Blogs Verilog PWM
  • Blog
  • Documents
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: djfraz
  • Date Created: 5 Oct 2017 8:34 AM Date Created
  • Views 2121 views
  • Likes 3 likes
  • Comments 12 comments
  • fpga
  • verilog
Related
Recommended

Verilog PWM

djfraz
djfraz
5 Oct 2017

For an Assignment for university my class had to write a verilog program to produce a PWM output derived from the ASCII Value of our initials which can drive a servo.

We were provided a sample verilog source from fpgas for fun, which was clear as mud, but did produce the required output. All examples a could find online where for a simpler PWM output, ie with a period the same size as the largest value of the pulse. Which is more suited for constructing a analog output.

 

So I have gone through the source provided and found what i considered an acceptable explanation, from which I taught a several of my classmates who where struggling. I though I would put it up here for everyone to see, I hope it is of some use to someone. And apologies for poorly drawn graphs.

 

For producing a Servo signal we need pulses between 1ms and 2ms with a frequency of between 50Hz - 100Hz

 

image

As we want to module to accept a 8-bit number to determine the pulse width, in the case of my assignment an ASCII Character, we need to divide the variation by the number of steps you can have in a 8-bit value.

 

1ms/256 steps = 3.9us per step

 

Therefore we need to generate a clock with period 3.9us from which we will work from to produce the outputs.

For this we take the frequency of the input clock, in this case 50MHz, multiply it by the time variation and divide by the number of steps in that variation.

 

(50e^(6) x 1e^(-3))/256 ~= 195

 

This is the value we will use to generate a saw tooth wave which will allow us to generate the clock of period 3.9us

A counter will be incremented on each 50MHZ clock edge, when this counter reaches 195; we generate a pulse on clkTick and reset the counter. This looping is what will generate the 3.9us clock

 

image

 

To generate the period between the pulses we will use a second saw tooth counter which will use the 3.9us clock to increment it.

To calculate the size of this counter we need to use the desired period of the output

 

log2(output period/clock period) = log2(16ms/3.9us) = log2(4109) ~= 12-bits

 

16ms was used as it gives a value closest to a whole bit. This counter will be incremented every 3.9us clock pulse so we have approximately 16ms between pulses, and will be allowed to roll over to zero when it maximum value is reached.

 

To generate the output pulse into we first need to take the input 8-bit and add a 4-bit binary 1 onto the front, this is done using condensation operator (can't remember actual name)

using;

     {4'b0001, Input}

this produces a 12-bit output with a minimum value of 256 and max of  511, which when multiplied by 3.9us give us 1ms and 2ms respectively. To do this in the code, we set the output high when this number is less than the current value of the 12-bit counter.

image

So by giving the input a value between 0 and 255 we can produce servo pulses between 1ms and 2ms with and variation of 3.9us.

 

I have included below my verilog source for my assignment, which includes some extra case statements for changing between upper and lower case, and for counting the output pulse to change the value after two. I will also add the original source from fpga for fun, and you will see what i mean by mud, no disrespect to the author.

 

I hope someone find this useful, or just interesting, please let me know your thought in the comments

Attachments:
Assignment2.txt.zip
RCServo (1).txt.zip
  • Sign in to reply

Top Comments

  • djfraz
    djfraz over 7 years ago in reply to michaelkellett +1
    What the line clkTick <=(clkCount == clkDiv -2) is using is the logical nature of the == operator (clkCount == cldDiv - 2) is equal to one when the condition is met and zero when it is not met. so it is…
  • michaelkellett
    michaelkellett over 7 years ago in reply to djfraz +1
    I know that it works in Verilog but the point is that it confuses the two kinds of 1 and 0. There is the 1 and 0 that are states that a hardware signal might assume and there are true and false which are…
  • djfraz
    djfraz over 7 years ago in reply to michaelkellett +1
    The original was horrible to read, was the main reason that i spent time teaching my classmates how to use it and to write this post.
Parents
  • michaelkellett
    michaelkellett over 7 years ago

    The original code is truly awful !

     

    You don't mention any kind of reset - it is almost always a good thing to have a way of starting off in a known condition - hardware powers up as it likes - in FPGAs or ASICs you often need to set them up - so if this were my code there would be  away of making sure that the counters start at zero and the outputs start at off.

     

    Here's a style comment - and why everyone should learn VHDL:

     

    ClkTick <= (ClkCount == ClkDiv - 2);

     

    This may be legal in Verilog but it shouldn't be !

    ClkTick is declared as reg so I assume you mean it to be some kind of hardware signal.

    But you are assigning the result of a logical comparison to it - why not describe what you really want:

     

    if (ClkCount == (ClkDiv - 2))

         ClkTick <= 0;

    else

         ClkTick <= 1;

     

    This is a simple example and it is clear to me what you mean, and probably clear to the compiler or Synthesizer.

    When you get on to more complicated stuff it will bite you !

     

    (The great thing about VHDL is that it never assumes anything - it is very strictly typed.)

     

    (You'll notice that I don't assume precedence of - over ==

    Since I work in C, VHDL, Verilog (a little) and a  few other things too, I find the cost of brackets to be worth paying. image)

     

    Hope this is helpful and thanks for your post.

     

     

    MK

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • djfraz
    djfraz over 7 years ago in reply to michaelkellett

    What the line

    clkTick <=(clkCount == clkDiv -2)

     

    is using is the logical nature of the == operator (clkCount == cldDiv - 2) is equal to one when the condition is met and zero when it is not met. so it is doing the same as your if statement, but more concisely. I think that in Verilog or most other language it would be down to preference as to which you use, and when you consider that it is synced to the clock.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • djfraz
    djfraz over 7 years ago in reply to djfraz

    the mext thing we need to try and do is interface the FPGA with a MBed mcu to take command on driving the servo.if you have any suggestions on the beat way of doing that i would be much appreciative

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • michaelkellett
    michaelkellett over 7 years ago in reply to djfraz

    There are many ways you can do this:

     

    1) dedicate one or more 1 bit signals from the micro to the FPGA to tell it what to do, this gets messy if there are many different commands or you need to transfer parameters.

     

    2) give your FPGA an SPI or UART interface to the micro - (or some other interface if you like but I think one of these will be fine).

     

    I like using UART interfaces when I can and sending human readable data. Then I can debug the FPGA using no more than a cheap USB to logic level UART lead connected to a PC(FTDI make them and Farnell sell them).

    If you need more speed then SPI can go faster (easily 10x faster and often better than that).

     

    Assuming you go the UART route, which at 115200 baud should be easily fast enough (but you'll need to check that) then I would use a protocol like this:

     

    C PPPP CRLF

     

    So the controller sends a single character command, followed by a space followed by a hex parameter followed by an optional space and a carriage return/line feed terminator. Code the FPGA to ignore extra spaces.

     

    It's reasonably easy to code this kind of interface but the great thing is that you can debug it with simple tools. Once you get to SPI the need for  a logic analyzer gets a lot greater.

     

    MK

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • djfraz
    djfraz over 7 years ago in reply to michaelkellett

    Thanks. Speed won't be an issue. as im doing this in a group for a semester project and my team have little to no experience with any of the concepts which we will be using. visual C# GUI, MBed and FPGA's which all have to communicate. The mbed is more of a signal passthrough, takes sensor reading and passes it to fpga, and takes input from the c# gui on a pc to pass onto the fpga. so i need to try and find a happy medium between what works best and what is easier for them to implement. all of this to control a lego sorter.

     

     

    I am thinking of writing a blog about the project, to keep myself sane as i try to do it. Ill mostly be doing the verilog for the fpga. but suspect that i will have a hand in most aspect of the project.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • michaelkellett
    michaelkellett over 7 years ago in reply to djfraz

    Unless it's a key part of the project - then don't use the mbed at all. If you use a UART interface on the FPGA you can talk directly to the PC via a standard COM port implemented by a USB <-> RS232 (or logic level) lead, C# can talk directly and easily to COM ports (as can almost every other programming language).

     

    (You will need to keep the Mbed board if you need fast deterministic decision making to assist the FPGA or other interfaces that would be very hard to implement on the FPGA.)

     

    MK

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • djfraz
    djfraz over 7 years ago in reply to michaelkellett

    I wish i could remove the mbed, but it is part of the specification given to us. the only part of the system that would be annoying, or at least at first glance, to implement on the fpga will be the adafruit color sensor, but even then i don't think that it would be too difficult. I might mention it to my lecturer, see what he says.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • djfraz
    djfraz over 7 years ago in reply to michaelkellett

    I wish i could remove the mbed, but it is part of the specification given to us. the only part of the system that would be annoying, or at least at first glance, to implement on the fpga will be the adafruit color sensor, but even then i don't think that it would be too difficult. I might mention it to my lecturer, see what he says.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
  • michaelkellett
    michaelkellett over 7 years ago in reply to djfraz

    I wouldn't worry about it too much - it can certainly improve the system flexibility. Might be best to save up your brownie points with your supervisor until you hit a really bad snag.

     

    It is  a common architecture, certainly the majority of FPGAs that I've deployed have been in systems with a PC - Micro - FPGA type of hierarchy so it's good preparation for real world stuff. Sometimes, just to add to the fun, we have a fast direct link (via Ethernet) between FPGA and PC as well.

     

    MK

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
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