Forum Discussion
Altera_Forum
Honored Contributor
13 years agoproblem (?) using shared variables
Hi,
I need your kind opinion. Please, anyone explain me why the following code is not running. VHDL code (sel-explainable)
------------------------------------------------------
entity counter_with_sharedvar is
port (clk: in bit;
digit1, digit2: out integer range 0 to 9);
end entity;
------------------------------------------------------
architecture counter of counter_with_sharedvar is
shared variable temp1, temp2: integer range 0 to 9;
begin
----------------------------------
proc1: process (clk)
begin
if (clk'EVENT and clk='1') then
if (temp1=9) then
temp1 := 0;
else
temp1 := temp1 + 1;
end if;
end if;
end process proc1;
----------------------------------
proc2: process (clk)
begin
if (clk'EVENT and clk='1') then
if (temp1=9) then
if (temp2=9) then
temp2 := 0;
else
temp2 := temp2 + 1;
end if;
end if;
end if;
end process proc2;
----------------------------------
digit1 <= temp1;
digit2 <= temp2;
end architecture;
VHDL testbench code
entity tb_cct is
end entity tb_cct;
architecture arch of tb_cct is
constant T: time := 20 ns;
signal t_clk: bit;
signal t_d1: integer range 0 to 9;
signal t_d2: integer range 0 to 9;
begin
uut: entity work.counter_with_sharedvar(counter)
port map(clk => t_clk, digit1 => t_d1, digit2 => t_d2);
process
begin
t_clk <= '0';
wait for T/2;
t_clk <= '1';
wait for T/2;
end process;
end arch;
simulation result (50 MHz oscilator) https://www.alteraforum.com/forum/attachment.php?attachmentid=7548 Any ideas? Regards Jaraqui26 Replies
- Altera_Forum
Honored Contributor
--- Quote Start --- you shouldnt use clk_en to generate a clock. Forget about generating a 2nd clock. Just use the clk_en directly. --- Quote End --- Hi, Based on your recommendation, I developed the following code:
The simulation of this code produced the following result: https://www.alteraforum.com/forum/attachment.php?attachmentid=7549 A "return to zero" was needed. Also, I would prefer a 50% duty cycle clock generator. So I did some modifications on your recommendation and produced the following code:library ieee; use ieee.std_logic_1164.all; entity clock_gen is generic(N: integer := 10); port( mclk: in std_logic; rst: in std_logic; clk: out std_logic); end clock_gen; architecture arch of clock_gen is signal cnt: integer := 0; begin process(mclk, rst) begin if(rst = '1') then cnt <= 0; clk <= '0'; elsif(rising_edge(mclk)) then cnt <= cnt + 1; if(cnt = N) then -- this will give you an enable rate of clk/N clk <= '1'; else clk <= '0'; end if; end if; end process; end arch;
Regards Jaraquilibrary ieee; use ieee.std_logic_1164.all; entity clock_gen is generic(N: integer := 20); port( mclk: in std_logic; rst: in std_logic; clk: out std_logic); end clock_gen; architecture arch of clock_gen is signal cnt: integer := 0; begin process(mclk, rst) begin if(rst = '1') then cnt <= 0; clk <= '0'; elsif(rising_edge(mclk)) then cnt <= cnt + 1; if(cnt >= (N - 1)/2) then -- this will give you an enable rate of clk/N if(cnt = (N - 1)) then clk <= '0'; cnt <= 0; else clk <= '1'; end if; else clk <= '0'; end if; end if; end process; end arch; - Altera_Forum
Honored Contributor
This is the point, you're not supposed to generate a 50% duty cycle, as the "other" bit of code should also be using mclk as the clock. But it is only enabled with clk_en (hence it only works one in every N clocks)
- Altera_Forum
Honored Contributor
--- Quote Start --- This is the point, you're not supposed to generate a 50% duty cycle, as the "other" bit of code should also be using mclk as the clock. But it is only enabled with clk_en (hence it only works one in every N clocks) --- Quote End --- Sorry Tricky, my English is not so good... I didn´t understand very well this last message. Could you explain in other words, please? - Altera_Forum
Honored Contributor
The problem is, you're generating a clock. You should never generate a clock. You should clock all logic with mclk. Then use clock_en to activate it:
So this way divides your clock without having any problems associated with a generated clock.process(mclk) begin if rising_edge(mclk) then if clk_en = '1' then --only do something when clk_en is active, say 1 in every 50 end if; end if; end process; - Altera_Forum
Honored Contributor
--- Quote Start --- The problem is, you're generating a clock. You should never generate a clock. You should clock all logic with mclk. Then use clock_en to activate it:
So this way divides your clock without having any problems associated with a generated clock. --- Quote End --- Ok! Now I understood! Thank you! Regards Jaraquiprocess(mclk) begin if rising_edge(mclk) then if clk_en = '1' then --only do something when clk_en is active, say 1 in every 50 end if; end if; end process; - Altera_Forum
Honored Contributor
The main use for shared variables is in test benches
have a look at OSVVM. ORG the free packages there make extensive use of SHARED VARIABLES They are also very useful verification packages. creating good stimulus is often a lot of work & is boring. SAVE YOURSELF A LOT OF WORK have a look at intelligent coverage at OSVVM. ORG Those packages can create intelligent random functional coverage stimulus for you. With very little effort from you they can create stimulus for all the functions you ask them to cover in your testbench. They are written by Jim Lewis & he leads the IEEE VHDL standard group who are working on the next version of VHDL after VHDL2008.