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
Please Help me
Started by ●December 10, 2009
Reply by ●December 10, 20092009-12-10
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 > JoshiSeveral 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-
Reply by ●December 10, 20092009-12-10
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
Reply by ●December 11, 20092009-12-11
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-
Reply by ●December 11, 20092009-12-11
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. > > Andythanks 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
Reply by ●December 11, 20092009-12-11
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
Reply by ●December 11, 20092009-12-11
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;
Reply by ●December 12, 20092009-12-12
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 > JoshiHomework?
Reply by ●December 14, 20092009-12-14
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-
Reply by ●December 14, 20092009-12-14
On Mon, 14 Dec 2009 01:02:25 -0800 (PST), Ben Jones <benjjuk@gmail.com> wrote:>On Dec 11, 6:07�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






