prismprojection Posted April 23, 2016 Report Share Posted April 23, 2016 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 -- \ \ / \ -- \___\/\___\ -- --Command: --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 ); PORT( 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) ); END COMPONENT; COMPONENT PWMGenerator generic ( C_PWM_WIDTH : integer := pwm_width; C_PWM_TYPE : integer := 1 -- 2 phase, 1 phase or Enable chopping ); PORT( Clk : in std_logic; Duty : in std_logic_vector(C_PWM_WIDTH-1 downto 0); Out1 : out std_logic; Out2 : out std_logic ); END COMPONENT; 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 begin --Put your code here GEN_PWMS: for j in 0 to pwm_count-1 generate Inst_pwm_inst: PWMGenerator GENERIC MAP( C_PWM_WIDTH => pwm_width, C_PWM_TYPE => 1 ) PORT MAP( 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) PORT MAP( wishbone_in => wishbone_in, wishbone_out => wishbone_out, clk_96Mhz => clk_96Mhz, register_in => register_in_array, register_out => register_out_array ); end BEHAVIORAL; Quote Link to comment Share on other sites More sharing options...
Jaxartes Posted April 23, 2016 Report Share Posted April 23, 2016 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. Quote Link to comment Share on other sites More sharing options...
erickone96 Posted November 22, 2016 Report Share Posted November 22, 2016 Hello, 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. thanks, Erick Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.