Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20638 Discussions

Default latched outputs values

Altera_Forum
Honored Contributor II
1,133 Views

Hi guys, 

I'm working on a multi deck elevator controller using niosII and i thought it's better to relief the processor from handling the displays (floors + car motors display : up,down,1,2...etc u get it ;)). so i came up with this display controller code you see bellow to test it on the 7 segments displays of my DE2 board, it works fine but i'm seeking perfection :p, the only problem i get is at the moment the system get powered up. floor indicators gives random values at first until the floor sensors actualise the block to give a correct reading. the up/down indicators works great cuz the output is unlatched unlike that of the floors. 

so that's it, i'm looking for a manner to initialize LATCHED outputs (say to '0') for power up readings 

 

library ieee; 

use ieee.std_logic_1164.all; 

 

entity display_controller is 

port ( reset_n : in std_logic; 

mc1, mc2 : in std_logic_vector(1 downto 0); 

fsensor1,fsensor2 : in std_logic_vector(2 downto 0); 

floor1_a, floor1_b : out std_logic_vector(6 downto 0); 

floor2_a, floor2_b : out std_logic_vector(6 downto 0); 

mc1_a,mc1_b,mc2_a,mc2_b : out std_logic_vector(6 downto 0)); 

end entity display_controller; 

 

architecture behavioral of display_controller is 

signal f1,f2 : std_logic_vector (6 downto 0); 

signal m1,m2 : std_logic_vector (13 downto 0); 

 

begin 

 

process (mc1,reset_n) begin 

if (reset_n = '0') then m1 <="11111111111111"; -- clear display  

elsif (mc1="10") then m1 <= "01000010101011"; -- display: dn 

elsif (mc1="11") then m1 <= "10000010001100"; -- display: up 

else m1 <= "01111110111111"; -- display: -- 

end if;  

end process; 

 

process (mc2,reset_n) begin 

if (reset_n = '0') then m2 <="11111111111111"; -- clear display 

elsif (mc2="10") then m2 <= "01000010101011"; -- display: dn 

elsif (mc2="11") then m2 <= "10000010001100"; -- display: up 

else m2 <= "01111110111111"; -- display: --  

end if;  

end process; 

 

process (fsensor1,reset_n) begin 

if (reset_n = '0') then f1 <="1111111"; -- clear display 

elsif (fsensor1="001") then f1 <= "1111001"; -- display: 1 

elsif (fsensor1="010") then f1 <= "0100100"; -- display: 2 

elsif (fsensor1="011") then f1 <= "0110000"; -- display: 3 

elsif (fsensor1="100") then f1 <= "0011001"; -- display: 4 

else f1 <= f1; -- latch the output  

end if;  

end process; 

 

process (fsensor2,reset_n) begin 

if (reset_n = '0') then f2 <="1111111"; -- clear display 

elsif (fsensor2="001") then f2 <= "1111001"; -- display: 1 

elsif (fsensor2="010") then f2 <= "0100100"; -- display: 2 

elsif (fsensor2="011") then f2 <= "0110000"; -- display: 3 

elsif (fsensor2="100") then f2 <= "0011001"; -- display: 4 

else f2 <= f2; -- latch the output  

end if;  

end process; 

 

mc1_a <= m1(6 downto 0); 

mc1_b <= m1(13 downto 7); 

mc2_a <= m2(6 downto 0); 

mc2_b <= m2(13 downto 7); 

floor1_a <= f1; 

floor1_b <= "1111111"; 

floor2_a <= f2; 

floor2_b <= "1111111"; 

 

end architecture behavioral; 

 

any suggestions, tips, ideas, jokes, efforts.....aaanything would realy be appreciated. bring it up, let's see what u get :) 

thx in advance you guys, take care :cool:
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
374 Views

your design is all combinatorial with some latches. Not a typical fpga design but fair enough as good as it works. 

 

You can either clock all changes or a quicker way is to have internal reset as clocked register: 

 

signal reset_int : std_logic := '0'; 

 

process(clk) 

begin 

if rising_edge(clk) then 

reset_int <= '1'; 

end if; 

end process; 

 

then connect reset_int with reset_n. That way the latches will start as all ones. for example: 

if reset_int = '0' do this 

elsif reset_n = '0' do this...etc 

 

If the tool optimised away reset_int register then you need to tackle it.
0 Kudos
Altera_Forum
Honored Contributor II
374 Views

The most import point to mention is that the asynchronous latches like above don't hold values reliably, so you should clearly avoid it. 

 

As a simple example, if Fsensor1 advances from "011" to "000", f1 is expected to latch the display3 state. But that's doesn't happen necessarily. Because the "010" or "001" are possible transient input combinations, at least any output bit that has different states for display1, display2 or display3 may latch an arbitrary states. 

 

Only synchronous registers (or possibly a different sensor encoding) can avoid this problem.
0 Kudos
Altera_Forum
Honored Contributor II
374 Views

thx kaz, i liked the little trick you mentioned; u didn't actually force the output to a certain value AT power up but still you managed to make it looks like it is :). i was wondering if some setting exists to initialize the output of a certain block in any design (not even in VHDL). anyway, here is my edition based on your suggestion: 

 

signal initial,rst : std_logic := '0'; -- used for initialization 

 

begin 

 

rst <= reset_n and initial; 

 

process (clk) begin 

if rising_edge(clk) then  

initial <='1'; 

end if; 

end process; 

 

 

i then used rst later instead of reset_n for the whole code the way you mentioned and it works fine. well i guess you're not a guru for nothing :p thanks a lot bro ;) 

 

FvM, i couldn't really see the problem you're refering to, if you're talking about encoding the floor sensors not to read 1 and 2 in going from 0 to 3 than it's done. an encoder is instantiated on the top level for this purpose together with the keypads' inputs. i hope that's the point you're talking about, let me know if i'm wrong. merci a toi :cool:
0 Kudos
Altera_Forum
Honored Contributor II
374 Views

Im glad this works for you now. But adding to what others have said, combinatorial logic and latches are also prone to glitches, poor timing and temperature variations. Its quite common for a circuit like this to work fine, then the next time you compile it, it doesnt work at all, probably because the routing delays have got too long on that build (ok, maybe not for a simple circuit like this, but fill the chip with say 50%, and you'll have problems). Timequest cannot analyse async logic and latches, so you can run into these problems easily. 

 

Solution, go with synchronous design (thats how FPGAs are architected)
0 Kudos
Altera_Forum
Honored Contributor II
374 Views

 

--- Quote Start ---  

FvM, i couldn't really see the problem you're refering to, if you're talking about encoding the floor sensors not to read 1 and 2 in going from 0 to 3 than it's done. an encoder is instantiated on the top level for this purpose together with the keypads' inputs. i hope that's the point you're talking about, let me know if i'm wrong. merci a toi :cool: 

--- Quote End ---  

When Fsensor1 is "011" the F1 display is set to 3. Then Fsensor1 is going to some value, like "000" or "111" and you expect F1 to hold it's value.The problem is that Fsensor1's 3 bits won't flip all at the exact same time. So, the logic will see stuff like "010" or "001" as FsensorX changes from "011" to "000".And you really can't avoid this problem. You might not be seeing any problem but.. the problem can still occur.In order to have a reliable design, you need to use a clocked design.
0 Kudos
Altera_Forum
Honored Contributor II
374 Views

thx guys i can see the problem with such designs now, i'm editing all project's block to be clocked by the 50MHz standard clock... very glad you had me notice the issue with such desings before expanding the system more. bellow is the displayer code edited the way you want. let me know that's the way you want it to be or if other enhancements can be made. 

 

 

library ieee; 

use ieee.std_logic_1164.all; 

 

entity display_controller is 

port ( clk, reset_n : in std_logic; 

mc1, mc2 : in std_logic_vector(1 downto 0); 

fsensor1,fsensor2 : in std_logic_vector(2 downto 0); 

floor1_a, floor1_b : out std_logic_vector(6 downto 0); 

floor2_a, floor2_b : out std_logic_vector(6 downto 0); 

mc1_a,mc1_b,mc2_a,mc2_b : out std_logic_vector(6 downto 0)); 

end entity display_controller; 

 

architecture behavioral of display_controller is 

signal f1,f2 : std_logic_vector (6 downto 0); 

signal m1,m2 : std_logic_vector (13 downto 0); 

signal initial : std_logic := '0'; -- used for initialization 

 

begin 

 

process (clk) begin 

if rising_edge(clk) then  

initial <='1'; 

end if; 

end process; 

 

process (mc1,reset_n,clk) begin 

if rising_edge(clk) then  

if (initial = '0') then m1 <= "11111111111111"; -- clear display  

elsif (mc1="10") then m1 <= "01000010101011"; -- display: dn 

elsif (mc1="11") then m1 <= "10000010001100"; -- display: up 

else m1 <= "01111110111111"; -- display: -- 

end if; 

end if;  

end process; 

 

process (mc2,reset_n,clk) begin 

if rising_edge(clk) then  

if (initial = '0') then m2 <= "11111111111111"; -- clear display 

elsif (mc2="10") then m2 <= "01000010101011"; -- display: dn 

elsif (mc2="11") then m2 <= "10000010001100"; -- display: up 

else m2 <= "01111110111111"; -- display: --  

end if; 

end if;  

end process; 

 

process (fsensor1,reset_n,clk) begin 

if rising_edge(clk) then  

if (initial = '0') then f1 <= "1111111"; -- clear display 

elsif (fsensor1="001") then f1 <= "1111001"; -- display: 1 

elsif (fsensor1="010") then f1 <= "0100100"; -- display: 2 

elsif (fsensor1="011") then f1 <= "0110000"; -- display: 3 

elsif (fsensor1="100") then f1 <= "0011001"; -- display: 4 

else f1 <= f1; -- latch the output  

end if; 

end if;  

end process; 

 

process (fsensor2,reset_n,clk) begin 

if rising_edge(clk) then  

if (initial = '0') then f2 <= "1111111"; -- clear display 

elsif (fsensor2="001") then f2 <= "1111001"; -- display: 1 

elsif (fsensor2="010") then f2 <= "0100100"; -- display: 2 

elsif (fsensor2="011") then f2 <= "0110000"; -- display: 3 

elsif (fsensor2="100") then f2 <= "0011001"; -- display: 4 

else f2 <= f2; -- latch the output  

end if; 

end if;  

end process; 

 

mc1_a <= m1(6 downto 0); 

mc1_b <= m1(13 downto 7); 

mc2_a <= m2(6 downto 0); 

mc2_b <= m2(13 downto 7); 

floor1_a <= f1; 

floor1_b <= "1111111"; 

floor2_a <= f2; 

floor2_b <= "1111111"; 

 

end architecture behavioral; 

 

 

thx again guys it's really kind of you to give help in such short notice, peace :)
0 Kudos
Altera_Forum
Honored Contributor II
374 Views

much better. But theres no need to have all those signals in the sensitivity lists. All they need is "clk" in there as nothing changes unless the clock rises. you only need the reset in there if you have an async reset.

0 Kudos
Reply