element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • 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 & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • 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
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • 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
Community Hub
Community Hub
Member Blogs [jc2048] Staircase Generator
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Leaderboard
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Community Hub to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: jc2048
  • Date Created: 27 Nov 2021 4:14 PM Date Created
  • Views 6362 views
  • Likes 11 likes
  • Comments 23 comments
  • intel
  • MAX II
  • cpld
  • experimenting
  • analogue design
  • vhdl
  • transistors
  • jc2048
  • altera
Related
Recommended

[jc2048] Staircase Generator

jc2048
jc2048
27 Nov 2021

Introduction

Here's a curious waveform. How do you think I did that?

image

At first glance it looks like the output of a DAC driven from an incrementing counter, but it's not.
Instead, I have a digital part (a CPLD), producing a simple stream of pulses, and an analogue part
that works as a 'charge pump', adding a set amount of charge to a capacitor each time one of the
control pulses arrives. There's also a reset pulse to bring the level back down close to zero.

Here's the waveform again with the control pulses from the CPLD below it.

image

The output changes in response to the pulses, so it is 'discrete time' in nature [like sampling], and
the steps are a fixed size [so like the quantization of digitising], yet the core of it is analogue
with not a gate in sight. Another way of thinking about it, is that it's a kind of analogue adder.

This is the circuit diagram of the analogue part that I drew before construction. The build was
similar, except that I added a 15R resistor between the MOSFET and the 68n.

image

When the 'step' transistor is off, the 2.2n capacitor charges via the 1k resistors to each rail. When
the transistor turns on, it lifts that end of the capacitor to the rail and the other end lifts above
the rail, turning on the second transistor and allowing the 2.2n capacitor to discharge into the 68n.
When the 'reset' waveform goes high, the MOSFET simply discharges the 68n capacitor. Obviously,
whatever is connected to the 68n capacitor needs to be a fairly high impedance or the capacitor will
just discharge via the load - the 10M 'scope probe suffices for the experiment.

This is the build on a little prototyping board [the MAX II CPLD board is underneath - it's not very
obvious, but there are headers going down to it].

image


CPLD Logic Design

Here is the VHDL that produces the 'step' and 'reset' waveforms. It's fairly straightforward. I chose
a basic timing interval of 10us [it doesn't want to be too fast or the capacitors won't charge and
discharge fully], so I have a prescaler that produces an enable for one clock every 10us and work from
there with a simple state machine, with three states, and a counter to count off the steps to give the
two waveforms. (Sorry I haven't quite got the hang of using _numeric and I'm still overloading the
addition with ieee.std_logic_unsigned)

---------------------------------------------------------------
--- Filename: CPLD-staircase-generator.vhd                  ---
--- Target device: EPM240T100C5                             ---
---                                                         ---
--- control pulses for analogue staircase generator         ---
---                                                         ---
--- Jon Clift 7th November 2021                             ---
---                                                         ---
---------------------------------------------------------------
--- Rev    Date         Comments                            ---
--- 1.0    07-Nov-21                                        ---
---------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;  
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
  
entity CPLD_staircase_generator is  
  port (  
    clk_i:       in  std_logic;      --- input clock (50MHz osc).  
    step_x:      out std_logic;      --- 
    reset_x:     out std_logic       --- 
    );  
end CPLD_staircase_generator;  
  
architecture arch of CPLD_staircase_generator is

constant STEP_X_STATE : std_logic_vector(1 downto 0) := "10";
constant PAUSE_X_STATE : std_logic_vector(1 downto 0) := "01";
constant RESET_X_STATE : std_logic_vector(1 downto 0) := "00";
constant NUMBER_OF_STEPS : std_logic_vector  (3 downto 0):= "1001";  --- 9 steps
constant STEP_INTERVAL : std_logic_vector  (3 downto 0):= "1001";    --- 9 (x 10us) between step pulses  
signal ten_micro_en: std_logic;  
signal prescaler: std_logic_vector (8 downto 0) := "000000000";   
signal interval_count: std_logic_vector (3 downto 0) := "0000";
signal step_count: std_logic_vector (3 downto 0) := "0000";
signal state: std_logic_vector (1 downto 0) := RESET_X_STATE;

begin

   clocked_stuff: process (clk_i)
      begin
         if (clk_i'event and clk_i='1') then

            --- prescaler down to 10us period
          
            if (prescaler(8 downto 0) = "111110011") then   --- if reached 499
               prescaler(8 downto 0) <= "000000000";        --- reset back to zero
               ten_micro_en <= '1';                         --- and set enable for one cycle
            else                                            --- else count down
               prescaler <= prescaler + 1;
               ten_micro_en <= '0';                         --- keeping enable low rest of time
            end if;

            --- state machine to generate the waveforms
         
            if (ten_micro_en = '1') then
               case state is
                  when STEP_X_STATE =>
                     step_x <= '0';
                     reset_x <= '0';
                     interval_count <= STEP_INTERVAL;
                     state <= PAUSE_X_STATE;
                  when PAUSE_X_STATE =>
                     step_x <= '1';
                     reset_x <= '0';
                     if(interval_count = "0000") then
                        if(step_count = "0000") then
                           state <= RESET_X_STATE;
                        else
                           step_count <= step_count - 1;
                           state <= STEP_X_STATE;
                        end if;
                     else
                        interval_count <= interval_count - 1;
                     end if;
                  when RESET_X_STATE =>
                     step_x <= '1';
                     reset_x <= '1';
                     interval_count <= STEP_INTERVAL;
                     step_count <= NUMBER_OF_STEPS;
                     state <= PAUSE_X_STATE;
                  when others =>
                     state <= RESET_X_STATE;
                  end case;
            end if;
            
         end if;
      end process;
 
end arch;  

Inspiration

If you are interested in what my inspiration for this was, it came from this booklet published by the
British electronics company Ferranti in the mid-seventies (you can tell it's the 1970s by the groovy
fonts without capitals and the glorious orange colour: designers back in the 1960s and 1970s had a lot
of fun before the world got all corporate, safe, and bland again) to promote their E-line transistors
(ZTX... series parts, still in production, though now owned by Diodes Inc as Ferranti is long gone).

image


This was their version of the circuit

image


I turned it upside down and added the CPLD to generate the pulse stream, but other than that it's much
the same, with just a little tweaking of values.

One difference, though, is that their circuit self-resets when the capacitor voltage reaches a preset voltage.

I don't imagine there's anything you might use it for now that couldn't be done better in other ways,
but it was fun to experiment with, and switched-capacitor circuits are still relevant in some areas.

If you found this blog interesting, you might like to read some of the others I've written: jc2048-blog-index-new-version

References

[1] Application Report: E-Line Transistors. Ferranti. 1975.

  • Sign in to reply

Top Comments

  • genebren
    genebren over 4 years ago +2
    Very cool project/blog! I really like the simplicity/elegance of your approach to this project. Nice example of using a CPLD to generate a programmable pulse sequence. Well done!
  • DAB
    DAB over 4 years ago +2
    It has been a long while since I did any transistor work. Well done.
  • Jan Cumps
    Jan Cumps over 4 years ago +2
    The FPGA design works like a charm. Running it on Xilinx Zynq. Clock also 50 MHz.
  • michaelkellett
    michaelkellett over 4 years ago +2
    Hello, nice to see some HDL for simple parts ! Here's a style thing that might help when you do state machines: You can replace: constant STEP_X_STATE : std_logic_vector(1 downto 0) := "10"; constant…
  • Jan Cumps
    Jan Cumps over 4 years ago +1
    I can't work out how to format as code and all the white space disappeared when I cut and pasted it. You will get a dialog where you can paste your code into; and select the programming language…
  • Jan Cumps
    Jan Cumps over 4 years ago in reply to Jan Cumps +1
    Testing with your code: --------------------------------------------------------------- --- Filename: CPLD-staircase-generator.vhd --- --- Target device: EPM240T100C5 --- --- --- --- control pulses…
  • Jan Cumps
    Jan Cumps over 4 years ago +1
    A question about the 68n capacitor: did you choose it to be large enough to hold 10 charges of the 2.2n one, or is it chosen for a particular time constant?
  • shabaz
    shabaz over 4 years ago +1
    Hi Jon, That's very neat, I thought it was from a DAC, but this is more interesting. Perhaps use-cases are low-cost ways to measure unknown capacitance, by number of pulses to charge to a threshold…
  • dougw
    dougw over 4 years ago +1
    Ultra cool circuit. I would have guessed an R2R DAC using a CPLD counter. Your circuit has the ability to generate much higher voltages than the digital logic supply would suggest, although you might…
Parents
  • michaelkellett
    michaelkellett over 4 years ago

    Hello, nice to see some HDL for simple parts !

    Here's a style thing that might help when you do state machines:

    You can replace:

    constant STEP_X_STATE : std_logic_vector(1 downto 0) := "10";
    constant PAUSE_X_STATE : std_logic_vector(1 downto 0) := "01";
    constant RESET_X_STATE : std_logic_vector(1 downto 0) := "00";

    with something like:

    TYPE t_x_state is (STEP_X_STATE , PAUSE_X_STATE , RESET_X_STATE );
    signal x_state : t_x_state;    

    and then in the case statement:

                    case x_state is
                        when STEP_X_STATE =>
                         --do stuff

                       more cases

                        when others =>
                               
                           -- handle it all going wrong
                    end case;

    Where it really pays off is when you want to add a state and go from maybe 4 bits to 5 bits, you don't need to edit all those "00110! again.

    MK

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • michaelkellett
    michaelkellett over 4 years ago

    Hello, nice to see some HDL for simple parts !

    Here's a style thing that might help when you do state machines:

    You can replace:

    constant STEP_X_STATE : std_logic_vector(1 downto 0) := "10";
    constant PAUSE_X_STATE : std_logic_vector(1 downto 0) := "01";
    constant RESET_X_STATE : std_logic_vector(1 downto 0) := "00";

    with something like:

    TYPE t_x_state is (STEP_X_STATE , PAUSE_X_STATE , RESET_X_STATE );
    signal x_state : t_x_state;    

    and then in the case statement:

                    case x_state is
                        when STEP_X_STATE =>
                         --do stuff

                       more cases

                        when others =>
                               
                           -- handle it all going wrong
                    end case;

    Where it really pays off is when you want to add a state and go from maybe 4 bits to 5 bits, you don't need to edit all those "00110! again.

    MK

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
  • jc2048
    jc2048 over 4 years ago in reply to michaelkellett

    Thanks. Defining a type with an enumeration for the states is certainly a useful approach to designing state machines. Let's hope no-one is too influenced by my bad habits.

    • 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