FPGARelated.com
Forums

Please Help me

Started by Joshi & Joshi December 10, 2009
Hello to all

i have master Clock 40 Mhz and from master Clock want Generate 1.2 K
hz Suare wave pulses at output

(1) what is problm with my Code
(2) how Counter works and how to take decide the Counter values like
these designs
(3) without Counter can we use Shift ??

my code is as below
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity Clk_divider is
  port(
    resetn           : in  std_logic; -- Reset
    MHZ_clock      : in  std_logic;
    Out_clock        : out std_logic

   );
  end Clk_divider;

architecture Clk_divider_arch of Clk_divider is

signal  clk_count  : std_logic_vector(16 downto 0) :=
"00000000000000000"; -- 16 Bit Counter

begin

Clock : process(resetn, MHZ_clock) -- 0.025uSec
begin
  if(resetn = '0') then
    Out_clock <= '0';

  elsif(MHZ_clock'event and MHZ_clock = '1') then
    	if(clk_count <= "01000001000101000") then ---    want Generate
Delay (40M Hz /1.2K Hz = 3320)
      		clk_count <= clk_count + '1';
       		out_clock <= '1';

     	elsif(( clk_count > "01000001000101000") AND (clk_count <
"10000010001010000"))then
                      -- 0 to 3333 ON and 3333 to  6666 OFF

            	out_clock <= '0';
                     clk_count <= clk_count + '1';
                       if(clk_count = "10000010001010000") then
	clk_count <= "00000000000000000" ;

                        end if;
          end if ;

  end if ;
        end process Clock ;
end Clk_divider_arch ;

Waiting fr  replies ..

with Advance Thanks
Joshi
On Dec 10, 8:20=A0am, "Joshi & Joshi" <joship...@gmail.com> wrote:
> Hello to all > > i have master Clock 40 Mhz and from master Clock want Generate 1.2 K > hz Suare wave pulses at output > > (1) what is problm with my Code > (2) how Counter works and how to take decide the Counter values like > these designs > (3) without Counter can we use Shift ?? > > my code is as below > library ieee; > use ieee.std_logic_1164.all; > use ieee.std_logic_arith.all; > use ieee.std_logic_unsigned.all; > > entity Clk_divider is > =A0 port( > =A0 =A0 resetn =A0 =A0 =A0 =A0 =A0 : in =A0std_logic; -- Reset > =A0 =A0 MHZ_clock =A0 =A0 =A0: in =A0std_logic; > =A0 =A0 Out_clock =A0 =A0 =A0 =A0: out std_logic > > =A0 =A0); > =A0 end Clk_divider; > > architecture Clk_divider_arch of Clk_divider is > > signal =A0clk_count =A0: std_logic_vector(16 downto 0) :=3D > "00000000000000000"; -- 16 Bit Counter > > begin > > Clock : process(resetn, MHZ_clock) -- 0.025uSec > begin > =A0 if(resetn =3D '0') then > =A0 =A0 Out_clock <=3D '0'; > > =A0 elsif(MHZ_clock'event and MHZ_clock =3D '1') then > =A0 =A0 =A0 =A0 if(clk_count <=3D "01000001000101000") then --- =A0 =A0wa=
nt Generate
> Delay (40M Hz /1.2K Hz =3D 3320) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 clk_count <=3D clk_count + '1'; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 out_clock <=3D '1'; > > =A0 =A0 =A0 =A0 elsif(( clk_count > "01000001000101000") AND (clk_count < > "10000010001010000"))then > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 -- 0 to 3333 ON and 3333 to =
=A06666 OFF
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 out_clock <=3D '0'; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0clk_count <=3D clk_count + '1'=
;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if(clk_count =3D "10000010=
001010000") then
> =A0 =A0 =A0 =A0 clk_count <=3D "00000000000000000" ; > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end if; > =A0 =A0 =A0 =A0 =A0 end if ; > > =A0 end if ; > =A0 =A0 =A0 =A0 end process Clock ; > end Clk_divider_arch ; > > Waiting fr =A0replies .. > > with Advance Thanks > Joshi
Several things are wrong, which you would be able to find quite easily by running a simulation and debugging the output. (a) you haven't included clk_count in your reset clause, so asserting the reset signal might not do what you expect - and the synthesis tool might have to insert a latch in your design in order to match exactly the behaviour you've specified. (b) your condition in 'if(clk_count =3D "10000010001010000")' will never be true, because it's nested inside another if statement that already determined that clk_count is less than that number. So your counter will reach it, and just stop. You probably meant to write "elsif" here, and lose one of the 'end if's. (c) I think your clock maths is out by a factor of two (and maybe a rounding error). To create a 1.2KHz square wave from a 40MHz counter, you need about 16666 cycles high and 16666 cycles low. Also you're using asynchronous reset, which isn't really the best solution in FPGAs, and four comparison operations where really you could get away with one (so the circuit will probably be quite inefficient). Why not just count N cycles then flip the output bit (x <=3D not x)? I didn't really understand your other two questions. -Ben-
What Ben said, except the asynchronous reset part. If you need
asynchronous reset (e.g. reset will work even if clock is not
working), FPGA's handle it fine.  If you keep it asyncrhonous,  you
need to synchronoize the deasserting edge of it; if you make it
synchronous,  you need to synchronize both edges.

You won't get a latch from the missing reset on clk_count, but you
will get a "clock enable" or feedback mux on the clk_count register
because even though the description does not reset the clk_count
contents while reset is active, it does not increment or change them
either.

Other hints:

Use numeric_std library data types and operators for arithmetic.
std_logic_arith and std_logic_unsigned may reside in the ieee library,
but they are NOT standard IEEE packages.

numeric_standard defines signed and unsigned data types, for which
operators and conversion functions are appropriately defined.

In your design, clk_count could be of type unsigned, then you can
compare or add it to integer literals rather than binary bit strings.

Alternatively, clk_count could be just an integer range (0 to 2**16 -
1). Just remember that integer math does not "roll over" like vector
based math.

You can use the language to calculate your counter range. If you want
to account for uneven half cycles that will add to a total period
closest to 1200 Hz, you can calculate:

constant input_f : integer := 40000000;
constant output_f : integer := 1200;
constant period : integer := (input_f + output_f / 2) / output_f; --
round up
constant high : integer := (period + 1) / 2; -- round up
constant low : integer := period - high;
variable clk_cnt : integer range 0 to high - 1;
...
if clk_cnt = 0 then
  if out_clk = '1' then
     clk_cnt := low - 1; -- load low half-period
  else
     clk_cnt := high - 1; -- load high half_period
  end if;
  out_clk <= not out_clk;
else
  clk_cnt := clk_cnt - 1;
end if;

Use rising_edge() or falling_edge() functions to detect the edge of a
clock; it is safer and more readable.

Assign an SLV with the value (others => '0') when you just want to set
it to all zeroes.

Andy
On Dec 10, 7:08=A0pm, Andy <jonesa...@comcast.net> wrote:
> What Ben said, except the asynchronous reset part. If you need > asynchronous reset (e.g. reset will work even if clock is not > working), FPGA's handle it fine. =A0If you keep it asyncrhonous, =A0you > need to synchronoize the deasserting edge of it; if you make it > synchronous, =A0you need to synchronize both edges.
I still maintain that asynchronous reset "isn't the best solution", but everything Andy says is certainly true. Sometimes, you have an external requirement for it, and in most cases the FPGA silicon and tools will cope with it. But note that in more complex designs and on some devices, certain blocks (e.g. DSPs, BRAMs) contain registers that are only resetable synchronously. Usually asynchronous resets are only needed for registers that feed an external signal (i.e. something that goes to another chip), to prevent problems at the board level. Internally, your design will be much more reliable if you use synchronous resets everywhere, because the propagation time and skew of asynchronous resets usually isn't taken into account by static timing analysis tools. So, you can end up with some registers coming out of reset on a different cycle from other registers elsewhere, without warning, even when you logically deasserted the reset at the same time. Hence, Andy's very good advice about synchronizing that trailing edge. Cheers, -Ben-
On Dec 11, 12:08=A0am, Andy <jonesa...@comcast.net> wrote:
> What Ben said, except the asynchronous reset part. If you need > asynchronous reset (e.g. reset will work even if clock is not > working), FPGA's handle it fine. =A0If you keep it asyncrhonous, =A0you > need to synchronoize the deasserting edge of it; if you make it > synchronous, =A0you need to synchronize both edges. > > You won't get a latch from the missing reset on clk_count, but you > will get a "clock enable" or feedback mux on the clk_count register > because even though the description does not reset the clk_count > contents while reset is active, it does not increment or change them > either. > > Other hints: > > Use numeric_std library data types and operators for arithmetic. > std_logic_arith and std_logic_unsigned may reside in the ieee library, > but they are NOT standard IEEE packages. > > numeric_standard defines signed and unsigned data types, for which > operators and conversion functions are appropriately defined. > > In your design, clk_count could be of type unsigned, then you can > compare or add it to integer literals rather than binary bit strings. > > Alternatively, clk_count could be just an integer range (0 to 2**16 - > 1). Just remember that integer math does not "roll over" like vector > based math. > > You can use the language to calculate your counter range. If you want > to account for uneven half cycles that will add to a total period > closest to 1200 Hz, you can calculate: > > constant input_f : integer :=3D 40000000; > constant output_f : integer :=3D 1200; > constant period : integer :=3D (input_f + output_f / 2) / output_f; -- > round up > constant high : integer :=3D (period + 1) / 2; -- round up > constant low : integer :=3D period - high; > variable clk_cnt : integer range 0 to high - 1; > ... > if clk_cnt =3D 0 then > =A0 if out_clk =3D '1' then > =A0 =A0 =A0clk_cnt :=3D low - 1; -- load low half-period > =A0 else > =A0 =A0 =A0clk_cnt :=3D high - 1; -- load high half_period > =A0 end if; > =A0 out_clk <=3D not out_clk; > else > =A0 clk_cnt :=3D clk_cnt - 1; > end if; > > Use rising_edge() or falling_edge() functions to detect the edge of a > clock; it is safer and more readable. > > Assign an SLV with the value (others =3D> '0') when you just want to set > it to all zeroes. > > Andy
thanks lot for all yur Inputs ... ya its asynchnous reset i synthsised already but problm in Simulaton ... pls Correct my Code it will make me Some Correction for future Designig
Ben Jones wrote:

> I still maintain that asynchronous reset "isn't the best solution", > but everything Andy says is certainly true. Sometimes, you have an > external requirement for it, and in most cases the FPGA silicon and > tools will cope with it. But note that in more complex designs and on > some devices, certain blocks (e.g. DSPs, BRAMs) contain registers that > are only resetable synchronously.
True, but it simplifies simulation having a reset for the input and output registers, even if (especially if ?) the rams and some shifters don't have one. The reset can always be tied inactive if it is not needed in the system. But it does help me on the front end, and is always there if I need it. There is also value for me in using the same design rules every time. -- Mike Treseler
Joshi & Joshi wrote:

> thanks a lot for all your inputs ... > the asynchronous reset i synthesized already > but the problem is in simulaton ... > please correct my Code ..
Here's my take on Andy's clever idea. Untested, but compiles and should be close. -- Mike Treseler __________________________________________________________________ package period_pkg is -- idea from Andy -- To account for uneven half cycles: constant input_f : integer := 40000000; constant output_f : integer := 1200; constant period : integer := (input_f + output_f / 2) / output_f; -- round up constant high : integer := (period + 1) / 2; constant low : integer := period - high; end package period_pkg; ------------------------------------------------------------------ use work.period_pkg.all; library ieee; use ieee.std_logic_1164.all; entity period is port ( in_clk, rst : in std_ulogic; out_clk : out std_ulogic); end entity period; architecture period of period is -- Fri Dec 11 09:47:27 2009 mtreseler begin -- architecture period p : process(in_clk, rst) is variable clk_cnt_v : integer range 0 to high - 1; variable out_clk_v : std_ulogic; begin if rst = '1' then ------------------------------------------------------------------ -- init regs out_clk_v := '0'; clk_cnt_v := 0; elsif rising_edge(in_clk) then ------------------------------------------------------------------ -- update regs roll:if clk_cnt_v = 0 then load:if out_clk_v = '1' then clk_cnt_v := low - 1; -- load low half-period else clk_cnt_v := high - 1; -- load high half_period end if load; toggle:out_clk_v := not out_clk_v; else decr:clk_cnt_v := clk_cnt_v - 1; end if roll; end if; ------------------------------------------------------------------ -- update ports: ports:out_clk <= out_clk_v; end process p; end architecture period;
Joshi & Joshi wrote:
> Hello to all > > i have master Clock 40 Mhz and from master Clock want Generate 1.2 K > hz Suare wave pulses at output > > (1) what is problm with my Code > (2) how Counter works and how to take decide the Counter values like > these designs > (3) without Counter can we use Shift ?? > > my code is as below > library ieee; > use ieee.std_logic_1164.all; > use ieee.std_logic_arith.all; > use ieee.std_logic_unsigned.all; > > entity Clk_divider is > port( > resetn : in std_logic; -- Reset > MHZ_clock : in std_logic; > Out_clock : out std_logic > > ); > end Clk_divider; > > architecture Clk_divider_arch of Clk_divider is > > signal clk_count : std_logic_vector(16 downto 0) := > "00000000000000000"; -- 16 Bit Counter > > begin > > Clock : process(resetn, MHZ_clock) -- 0.025uSec > begin > if(resetn = '0') then > Out_clock <= '0'; > > elsif(MHZ_clock'event and MHZ_clock = '1') then > if(clk_count <= "01000001000101000") then --- want Generate > Delay (40M Hz /1.2K Hz = 3320) > clk_count <= clk_count + '1'; > out_clock <= '1'; > > elsif(( clk_count > "01000001000101000") AND (clk_count < > "10000010001010000"))then > -- 0 to 3333 ON and 3333 to 6666 OFF > > out_clock <= '0'; > clk_count <= clk_count + '1'; > if(clk_count = "10000010001010000") then > clk_count <= "00000000000000000" ; > > end if; > end if ; > > end if ; > end process Clock ; > end Clk_divider_arch ; > > Waiting fr replies .. > > with Advance Thanks > Joshi
Homework?
On Dec 11, 6:07=A0pm, Mike Treseler <mtrese...@gmail.com> wrote:

> True, but it simplifies simulation having a reset > for the input and output registers, even if (especially if ?) > the rams and some shifters don't have one.
I agree that it's a Very Good Idea to have a reset, but I don't see why it has to be an asynchronous one. By default I try to make everything synchronous, including resets, unless there is a strong case to do otherwise. I have found that this leads to fewer problems throughout implementation. -Ben-
On Mon, 14 Dec 2009 01:02:25 -0800 (PST), Ben Jones <benjjuk@gmail.com> wrote:

>On Dec 11, 6:07&#4294967295;pm, Mike Treseler <mtrese...@gmail.com> wrote: > >> True, but it simplifies simulation having a reset >> for the input and output registers, even if (especially if ?) >> the rams and some shifters don't have one. > >I agree that it's a Very Good Idea to have a reset, but I don't see >why it has to be an asynchronous one. By default I try to make >everything synchronous, including resets, unless there is a strong >case to do otherwise. I have found that this leads to fewer problems >throughout implementation.
For most of the design I would agree. I confess I once had trouble with synchronous resets on clock generators, DCMs and the like. (The clock stops, so they never come out of reset.) So there are occasional roles for asynch reset... - Brian