Forum Discussion
problem (?) 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
Im sure I answered this the other day, with the exact same code.
Anyway, its because there are no 'events on variables, and signals need a 'event to update outside a process. Hence they are loaded with the initial value of the shared variables and are never updated again. Solution - never use shared variables. - Altera_Forum
Honored Contributor
Hi Tricky,
It´s me. lol. As I explained to you, this code is present in a book. Before I contact the author, I would prefer to listen (read) more opinions. Regards Jaraqui - Altera_Forum
Honored Contributor
Its not really an opinion, its a fact. Hence why its not working.
- Altera_Forum
Honored Contributor
--- Quote Start --- Its not really an opinion, its a fact. Hence why its not working. --- Quote End --- Tricky, It seemed to be a simulation bug. Implementing the code, it worked well surprisingly. The only modifications needed were: converting input/output to std_logic and dividing the 50 MHz frequency oscillator to a 1 Hz (to be visually observable). Here it´s the modificated version:
Best regards Jaraquilibrary ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; ------------------------------------------------------ entity counter_with_sharedvar is port (mclk: in std_logic; rst: in std_logic; digit1, digit2: out std_logic_vector(3 downto 0)); end entity; ------------------------------------------------------ architecture counter of counter_with_sharedvar is shared variable temp1, temp2: integer range 0 to 9; signal clk: std_logic; begin ---------------------------------- proc0: process(mclk, rst) variable count: integer := 0; begin if(rst = '1') then count := 0; elsif(mclk'event and mclk='1') then if(count < 25_000_000) then clk <= '0'; count := count + 1; elsif(count >= 25_000_000) then if(count = 50_000_000) then count := 0; clk <= '0'; else count := count + 1; clk <= '1'; end if; end if; end if; end process proc0; ---------------------------------- proc1: process (clk, rst) begin if(rst = '1') then temp1 := 0; elsif (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, rst) begin if(rst = '1') then temp2 := 0; elsif (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 <= conv_std_logic_vector(temp1, 4); digit2 <= conv_std_logic_vector(temp2, 4); end architecture; - Altera_Forum
Honored Contributor
When you say implementing, you mean with quartus? As I think I already stated, it would synthesise fine with quartus, as it just converts it to wires and will connect it up how you expect.
And you've done the conversion via std_logic_arith, which is non-standard VHDL. - Altera_Forum
Honored Contributor
I am testing with others target device/EDA tool.
In this week, not sure, I will have at hands a DE0, and I will try with it too. The reset on DE0 is '0' sensitive (not '1', as the rst presented in this version). The internal oscillator has the same frequency (50 MHz). Here is the version with numeric...
regards Jaraquilibrary ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; ------------------------------------------------------ entity counter_with_sharedvar is port (mclk: in std_logic; rst: in std_logic; digit1, digit2: out std_logic_vector(3 downto 0)); end entity; ------------------------------------------------------ architecture counter of counter_with_sharedvar is shared variable temp1, temp2: integer range 0 to 9; signal clk: std_logic; begin ---------------------------------- proc0: process(mclk, rst) variable count: integer := 0; begin if(rst = '1') then count := 0; elsif(mclk'event and mclk='1') then if(count < 25_000_000) then clk <= '0'; count := count + 1; elsif(count >= 25_000_000) then if(count = 50_000_000) then count := 0; clk <= '0'; else count := count + 1; clk <= '1'; end if; end if; end if; end process proc0; ---------------------------------- proc1: process (clk, rst) begin if(rst = '1') then temp1 := 0; elsif (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, rst) begin if(rst = '1') then temp2 := 0; elsif (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 <= std_logic_vector(to_unsigned(temp1, 4)); digit2 <= std_logic_vector(to_unsigned(temp2, 4)); end architecture; - Altera_Forum
Honored Contributor
All synthesis tools will synthesise it "correctly". I still dont see why you are sticking with shared variables. They are of no benefit in almost all situations (and prone to errors by inexperienced users, as you have found - its not a simulation bug).
On a point about this design - generating a clock like this is not recommended. It can be prone to timing problems from temperature due to the high skew from non-clock nets. It is recommended to generate clock enables instead, unless this is a slow clock for an external device (and no internal logic). - Altera_Forum
Honored Contributor
I am studying a VHDL book. There are a lot of codes in this book and one of them is this. For some of them, I practice some simulation or implement it on board.
This code with shared variables was presented to explain their functioning. Simulating this code, it didn´t present expected results. Curious about this, I posted on forum. It´s not a matter of choosing or preferring to use anything. I was just interested to understand if it works. If not, how the log files present to me what´s going on. In future designs I will consider you recommendation regarding clocks. Could you recommend some good books with practical examples of clock enabling? Regards Jaraqui - Altera_Forum
Honored Contributor
--- Quote Start --- I am studying a VHDL book. There are a lot of codes in this book and one of them is this. For some of them, I practice some simulation or implement it on board. This code with shared variables was presented to explain their functioning. Simulating this code, it didn´t present expected results. Curious about this, I posted on forum. It´s not a matter of choosing or preferring to use anything. I was just interested to understand if it works. If not, how the log files present to me what´s going on. In future designs I will consider you recommendation regarding clocks. Could you recommend some good books with practical examples of clock enabling? Regards Jaraqui --- Quote End --- I myself don't use shared variables but it could be your first code example need to initialise temp1, temp2. - Altera_Forum
Honored Contributor
I agree with you. I was trying to change the minimum.
For instance, the reset (rst) I´ve put only to watcth repeatedly the passages from nine to ten and from 99 to 00.