Modification RCL_PWM_x48


Recommended Posts

I need a 20-bit PWM with the counter clocked at 210MHz or greater. I looked at the RCL_PWM_x48 symbol code and tried to modify it to accept a clock separate from the soft core. Can someone take a look at the following and let me know if I'm on the right track? Thanks!

-- Copyright (c) 1995-2013 Xilinx, Inc.  All rights reserved.
--   ____  ____ 
--  /   /\/   / 
-- /___/  \  /    Vendor: Xilinx 
-- \   \   \/     Version : 14.7
--  \   \         Application : 
--  /   /         Filename : xil_12112_30
-- /___/   /\     Timestamp : 09/23/2014 15:24:59
-- \   \  /  \ 
--  \___\/\___\ 
--Design Name: 

library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
library UNISIM;
use UNISIM.Vcomponents.ALL;

--library work;
--use work.Wishbone_to_Registers_n_package.all;

library DesignLab;
use DesignLab.ALL;
use DesignLab.Wishbone_to_Registers_n_package.all;

entity PWM_20b_x5 is
	generic ( 
				pwm_count : integer := 5;
				pwm_width : integer := 20;
				register_count : integer := 5	--Each PWM has 1 register
   port ( wishbone_in  : in    std_logic_vector (100 downto 0); 
          wishbone_out : out   std_logic_vector (100 downto 0);
			 --Put your external connections here
			 PWM : out std_logic_vector(pwm_count-1 downto 0)
--			 DIR : out std_logic_vector(pwm_count-1 downto 0);
			 PWM_clk : in std_logic
end PWM_20b_x5;

architecture BEHAVIORAL of PWM_20b_x5 is

	COMPONENT Wishbone_to_Registers_n
	generic ( register_count : integer := register_count );
		wishbone_in : IN std_logic_vector(100 downto 0);         
		wishbone_out : OUT std_logic_vector(100 downto 0);
		PWM_clk : in std_logic;
		register_in : in register_type(0 to register_count-1);
		register_out : out register_type(0 to register_count-1)
	generic (
		C_PWM_WIDTH : integer := pwm_width;
		C_PWM_TYPE : integer := 1           -- 2 phase, 1 phase or Enable chopping
		Clk : in std_logic;
		Duty : in std_logic_vector(C_PWM_WIDTH-1 downto 0);
		Out1 : out std_logic;
		Out2 : out std_logic 
  signal register_in_array : register_type(0 to register_count-1);
  signal register_out_array : register_type(0 to register_count-1);
  signal DIR : std_logic_vector(pwm_count-1 downto 0);
  signal PWM_clk : std_logic;  
	--Put your unique register names here

	--Put your code here
	for j in 0 to pwm_count-1 generate
		Inst_pwm_inst: PWMGenerator 
			C_PWM_WIDTH => pwm_width,
			C_PWM_TYPE => 1
			CLK => PWM_clk,
			Duty => register_out_array(j)(pwm_width-1 downto 0),
			Out1 => PWM(j),
			Out2 => DIR(j)
		--register_in_array(j) <= register_out_array(j); 	--So we can read back what was written to the register.
	end generate GEN_PWMS;

	--Do not touch
	Inst_Wishbone_to_Registers_n: Wishbone_to_Registers_n 
	generic map (register_count => register_count) 
		wishbone_in => wishbone_in,
		wishbone_out => wishbone_out,
		clk_96Mhz => clk_96Mhz,
		register_in => register_in_array,
		register_out => register_out_array



Link to comment
Share on other sites

Some thoughts, more from what you're trying to do than from looking at your code:

  • 210MHz is a rather high clock rate to get on these FPGAs.  I think it can be done, but might require some trickery (especially pipelining) for it to make timing.
  • PWM is a rather simple thing: You have a counter, and you compare the counter value with your setting, and the result of the comparison is your output.
  • When you have more than one clock, the interaction between logic that uses the one clock, and logic which uses the other clock, can be tricky
    • I really haven't experimented with this much, usually I use the same clock for everything.
    • I think you're on the right track with this code -- where there's a piece which handles the Wishbone bus interaction (Wishbone_to_Registers_n, on the 96MHz clock) and another part which handles the PWM (on the >=210 MHz clock) and a simple one-way connection between them (register_out_array).
    • But you may have to put one or two clock cycles' worth of register delays between the components, to give XST a chance to synch them up.  In between, it tries to make logic respond within the worst-case period between the 210MHz clock and the 96MHz one.  I think for 210MHz that's something like 300ps!
    • Choosing your clock rate wisely might improve that: I believe for 216MHz it would be 1160ps, for 192MHz, 5200ps.
    • All this assumes your two clocks are derived from the same off-chip source (the 32MHz clock on the Papilio board).  If you have a second clock signal coming from off-chip then the situation gets more complicated.
  • I don't see anywhere "clk_96mhz" is being supplied to your code.  You use it (passing it to Wishbone_to_Registers_n) but the only clock you're getting is "PWM_clk".  You need to get both from somewhere...
  • If you want to see code which handles multiple clocks, in DesignLab, you might look for the video code.  It uses multiple clocks for the video output, and presumably still uses the 96MHz system clock for its Wishbone bus interface.  It's probably a rather complicated example, but at least it's an example.
Link to comment
Share on other sites

  • 6 months later...


I'm using the PWM generator block successfully, but the PWM signals have a frequency of about 375KHz (way too fast for my application). Is it possible to reuse that code for setting up a different PWM generator that uses a exteral clock that may allow me to generate PWMs at 1/100 frequency ? I'm not very familiar with VHDL.



Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.