- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 :)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page