Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Display different alphabets on 4 seven segment elements (connected in parallel)

Status
Not open for further replies.

emmagood

Member level 4
Joined
Feb 13, 2010
Messages
72
Helped
3
Reputation
6
Reaction score
1
Trophy points
1,288
Activity points
1,825
Hello there,

I have a FPGA board which has 4 seven segment elements having all the elements connected in parallel ie. element 'a' of all four units are in parallel and so on. I wanted to display four distinct characters in the four units viz 'F.P.g.A.'. Is there any way to do so.

I tried the following way:

Described a process A which is level sensitive to clock (level --> high) and activates the unit A of seven segment displaying 'F.' This works.

Then, I described a process B which is level sensitive to clock (level --> low) to activate the unit B of seven segment for displaying 'P.' At this time segment A is switched off.

This part does not work. I was expecting that since the 7 segment elements will be switching at high speed (clk = 8 Mhz.) I will be able to see both 'F.' and 'P.' on the consecutive units.

The code is as below (for all four units) :

-------------------------------

entity fpga_display is
Port ( ca,cb,cc,cd : out STD_LOGIC;
clk,rst : in STD_LOGIC;
segment7 : out STD_LOGIC_VECTOR (7 downto 0));
end fpga_display;

architecture Behavioral of fpga_display is

signal not_clk : std_logic;
signal segment7_temp : std_logic_vector(7 downto 0);
signal ca_temp, cb_temp, cc_temp, cd_temp : std_logic;

begin

not_clk <= not clk ;

A: process (clk, rst)

begin

if(rst = '0')then
ca_temp <= '0'; cb_temp <= '0'; cc_temp <= '0'; cd_temp <= '0';

elsif (clk ='0')then
segment7_temp <= "11100011";
ca_temp <='1'; cb_temp <= '0'; cc_temp <= '0'; cd_temp <= '0';

end if;

end process A;
------------------------------
B: process (clk, rst)

begin

if(rst = '0')then
ca_temp <= '0'; cb_temp <= '0'; cc_temp <= '0'; cd_temp <= '0';

elsif (clk='1') then
segment7_temp <= "11100111";
ca_temp <='0'; cb_temp <= '1'; cc_temp <= '0'; cd_temp <= '0';

end if;

end process B;

------------------------------

C: process (not_clk, rst)

begin

if(rst = '0')then
ca_temp <= '0'; cb_temp <= '0'; cc_temp <= '0'; cd_temp <= '0';

elsif (not_clk = '0') then

segment7_temp <= "11011111";
ca_temp <='0'; cb_temp <= '0'; cc_temp <= '1'; cd_temp <= '0';

end if;

end process C;

-----------------------------

D: process (not_clk, rst)

begin

if(rst = '0')then
ca_temp <= '0'; cb_temp <= '0'; cc_temp <= '0'; cd_temp <= '0';

elsif (not_clk = '1') then

segment7_temp <= "11101111";
ca_temp <='0'; cb_temp <= '0'; cc_temp <= '0'; cd_temp <= '1';

end if;

end process D;

----------------------------

segment7 <= segment7_temp;

ca <= ca_temp;
cb <= cb_temp;
cc <= cc_temp;
cd <= cd_temp;

end Behavioral;

-------------------------------

For 'g.' and 'A.', I tried by using a not_clk.

Pls. advise if this is the right technique / of any other technique to display distinct elements on the 4 parallel connected seven segment display.


BTW though there are no error, there were a few warning :

WARNING:Xst:737 - Found 1-bit latch for signal <cb_temp>.

WARNING:Xst:737 - Found 1-bit latch for signal <cc_temp>.

WARNING:Xst:737 - Found 1-bit latch for signal <cd_temp>.

WARNING:Xst:737 - Found 1-bit latch for signal <ca_temp>.


WARNING:par:276 - The signal clk_IBUF has no load

WARNING:par:276 - The signal rst_IBUF has no load

WARNING:par:284 - There are 2 sourceless or loadless signals in this design.

WARNING:physDesignRules:367 - The signal <clk_IBUF> is incomplete. The signal

WARNING:physDesignRules:367 - The signal <rst_IBUF> is incomplete. The signal

(Only the first warning came when process A was run)

Thanks,
Emma Good.
 

How about using rising_edge(clk) and falling_edge(clk) instead of clk='1' and not_clk='0' ? Might that avoid the latches during synthesis ?
 

This part does not work. I was expecting that since the 7 segment elements will be switching at high speed (clk = 8 Mhz.) I will be able to see both 'F.' and 'P.' on the consecutive units.

Try to change your clk speed at 1Hz; its easy for our visibility of that text in seven segnment; using clk divider to changed the speed of the clk;

elsif (clk ='0')then
segment7_temp <= "11100011";
ca_temp <='1'; cb_temp <= '0'; cc_temp <= '0'; cd_temp <= '0';
end if;

correct your coding syntax of clk; its in level triggering its a bug in ur code so that only these type of warning came here; try to always use clk as a edge triggering; inside of process the signal can be updated at end of the clk edge pulse ok;

use this syntaX : elsif (clk='1' and clk'event) then

refer link: https://embdev.net/topic/147804

regards
rajavel.rv
 

I don't understand how you expect to create 4 different "states" from level-sensitive logic using only one clock. What is the difference between clk = '0' and not_clk = '1' ?

Also, 8 MHz can be much higher than the segment/digit drivers can handle.

Do it as a simple state machine in one clocked process, and create a clock enable to do the state changes at a few hundred Hz.

For debugging, you can do as rajavel.rv suggested and lower the freqency even more.

I suggest that you run and debug your code in a simulator before you try to get it running on the board. You will save a lot of time. Both Altera and Xilinx have free simulators (Altera uses a special version of Modelsim).
 

Well, I did as rajavel said. Reduced the clk frequency to 1 Hz (local_clk and not_local_clk) and changed the level sensitive clk to edge sensitive (local_clk'event anc clk ='0' or '1'). Then tried it on fpga (xilinx spartan 3). The same result. It did not work for all four processes. When tried for process A only, 'F.' was getting displayed. Checked the clock by outputting it to a LED. It was glowing slowly (ie clock generation seems to be ok). Have not yet tried it on simulator directly.

Thanks,
Emma

- - - Updated - - -

I don't understand how you expect to create 4 different "states" from level-sensitive logic using only one clock. What is the difference between clk = '0' and not_clk = '1' ?

Also, 8 MHz can be much higher than the segment/digit drivers can handle.

Do it as a simple state machine in one clocked process, and create a clock enable to do the state changes at a few hundred Hz.

For debugging, you can do as rajavel.rv suggested and lower the freqency even more.

I suggest that you run and debug your code in a simulator before you try to get it running on the board. You will save a lot of time. Both Altera and Xilinx have free simulators (Altera uses a special version of Modelsim).

OK... my idea was to get 4 different labeled levels or edges so that I can distinctly switch on/off the 4 elements of seven segment.
Also, time shifted clk does not work with the same idea (not_clk <= local_clk after 1 us;).

Thanks,
Emma

- - - Updated - - -

How about using rising_edge(clk) and falling_edge(clk) instead of clk='1' and not_clk='0' ? Might that avoid the latches during synthesis ?

Did that. No joy.

Thanks,
Emma
 

The problem description is rather unclear, but you seem to implement digit multiplexing.

Instead of "inventing" non-synthesizable logic, you should consider in a first step how a feasible hardware looks like. It will use a multiplex counter with four distinct states (a two-bit counter) that is advanced to the next digit at each clock edge. The digit common anode output and segment multiplexer will be switched according to the counter state. You can implement it in different ways, e.g. multiple if statements, a case structure, a selected assigment, whatsover. But without an explicite counter signal or an equivalent construct, it won't work.
 

A simple rule that helps is to only drive a signal from one process. Having 4 processes is not the right way to go in this case.
 

The problem description is rather unclear, but you seem to implement digit multiplexing.

Instead of "inventing" non-synthesizable logic, you should consider in a first step how a feasible hardware looks like. It will use a multiplex counter with four distinct states (a two-bit counter) that is advanced to the next digit at each clock edge. The digit common anode output and segment multiplexer will be switched according to the counter state. You can implement it in different ways, e.g. multiple if statements, a case structure, a selected assigment, whatsover. But without an explicite counter signal or an equivalent construct, it won't work.

OK. This is what I am trying to do. In the FPGA kit, I have 4 seven segement units each of which have segements connected in parallel (ie. if I try to display 'A' in one of them and enable all 4 segments, 'A' gets displayed in all four segments).
I want to display four distinct alphabets on the 4 units at the same time. So, I am trying by sending different alphabet binary equivalent to all four seven segments and switching on the only the targeted seven segment unit (and switching off the rest).
First, I am sending the binary equivalent of 'F' to segment A at rising edge of local_clk by enabling ca and disabling cb, cc and cd. Then sending binary equivalent of 'P' to segment B at falling edge of local_clk by enabling cb and disabling ca, cc and cd . For g' I am using not_local_clk and sending its binary equivalent and at the same time enabling cc only.

I tried this with on board clock frequency (8 Mhz) and clk divider as well. Also used local_clk & not_local_clk & local_clk and shift_local_clk for all four cases ('F.','P.','g.','A.'). But it does not work.

Thanks,
Emma Good.
 

OK. This is what I am trying to do. In the FPGA kit, I have 4 seven segement units each of which have segements connected in parallel (ie. if I try to display 'A' in one of them and enable all 4 segments, 'A' gets displayed in all four segments).
I want to display four distinct alphabets on the 4 units at the same time. So, I am trying by sending different alphabet binary equivalent to all four seven segments and switching on the only the targeted seven segment unit (and switching off the rest).

Have any selection pin for select a 7-segment display or all pins are connect in parallel, if any selection pins in that board means have possible to multiplexing the output of that display.

post the hardware architecture of that FPGA board,

regards,
rajavel.rv
 

What you are trying to achieve is done with multi-digit 7-segment displays since more than 40 years. It's helpful to understand the method in terms of digital hardware to consider how to implement it in HDL.

The method is called time division multiplex (TDM). Because the LED segment circuit doesn't allow to display different characters actually at the same time, they have to be displayed sequentiallly, fast enough to be percepted as continuous image without flicker. You'll assign equal time slots to each of the four digits to achieve uniform intensity.

The "natural" solution for this problem is a counter with four states that activates the digits in sequence. Depending on the display driver hardware, the multiplex frequency is often selected in a 100 Hz to low kHz range. Using higher frequencies, e.g. a x MHz system clock will generate unwanted RF interferences and possibly digit crosstalk if the driver switching speed doesn't keep up with the multiplex frequency. With fast logic IC display drivers as in most FPGA dev kits MHz multiplex frequencies will work though, at least for a quick prototype design.

Activating digits on the rising and falling clock edge doesn't seem like a suitable solution. It complicates things in an unncessary way and doesn't help to address four digits.
 

First, I am sending the binary equivalent of 'F' to segment A at rising edge of local_clk by enabling ca and disabling cb, cc and cd. Then sending binary equivalent of 'P' to segment B at falling edge of local_clk by enabling cb and disabling ca, cc and cd. For g' I am using not_local_clk and sending its binary equivalent and at the same time enabling cc only.

It seems that you understand what the output signals should look like.
However, you should only use one clock, only rising_edge, only one process.
You also need a divider to create a clock enable, so you only change the outputs with a few hundred Hz.
 

Have any selection pin for select a 7-segment display or all pins are connect in parallel, if any selection pins in that board means have possible to multiplexing the output of that display.

post the hardware architecture of that FPGA board,

regards,
rajavel.rv

all the segments of the 4 units of 7 segment are connected in parallel viz segments dp of A,B,C and D units are connected in parallel, segments G in parallel and so on.

I dont have architecture of the board.

- - - Updated - - -

What you are trying to achieve is done with multi-digit 7-segment displays since more than 40 years. It's helpful to understand the method in terms of digital hardware to consider how to implement it in HDL.

The method is called time division multiplex (TDM). Because the LED segment circuit doesn't allow to display different characters actually at the same time, they have to be displayed sequentiallly, fast enough to be percepted as continuous image without flicker. You'll assign equal time slots to each of the four digits to achieve uniform intensity.

The "natural" solution for this problem is a counter with four states that activates the digits in sequence. Depending on the display driver hardware, the multiplex frequency is often selected in a 100 Hz to low kHz range. Using higher frequencies, e.g. a x MHz system clock will generate unwanted RF interferences and possibly digit crosstalk if the driver switching speed doesn't keep up with the multiplex frequency. With fast logic IC display drivers as in most FPGA dev kits MHz multiplex frequencies will work though, at least for a quick prototype design.

Activating digits on the rising and falling clock edge doesn't seem like a suitable solution. It complicates things in an unncessary way and doesn't help to address four digits.

OK thanks for the idea. Will try it out.

BTW FvM, any reason for mentioning ...."What you are trying to achieve is done with multi-digit 7-segment displays since more than 40 years." and "The "natural" solution for this problem....." :-D

- - - Updated - - -

It seems that you understand what the output signals should look like.
However, you should only use one clock, only rising_edge, only one process.
You also need a divider to create a clock enable, so you only change the outputs with a few hundred Hz.

Well.... I am using a clk divider of 1 HZ... other than that pls. tell me how to implement using 1 process and one clk.

Thanks,
Emma
 

Well.... I am using a clk divider of 1 HZ... other than that pls. tell me how to implement using 1 process and one clk.

example written a sample code; try this;
Code:
library ieee;
use ieee.std_logic_1164.all;

entity fpga_display is
Port ( 
clk,rst         : in STD_LOGIC;
ca,cb,cc,cd : out STD_LOGIC;
segment7    : out STD_LOGIC_VECTOR (7 downto 0));
end fpga_display;

architecture Behavioral of fpga_display is

constant K_F : std_logic_vector(7 downto 0) :=  "11100011"; --F
constant K_P : std_logic_vector(7 downto 0) :=  "11100111"; --P
constant K_G : std_logic_vector(7 downto 0) :=  "11011111"; --G
constant K_A : std_logic_vector(7 downto 0) :=  "11101111"; --A

signal dly_cnt : std_logic_vector(1 downto 0);
begin

process(clk,rst)
begin
     if rst='0' then
         ca <= '0'; cb <= '0'; cc <= '0'; cd  <= '0';
         segment7 <= (others=>'0');
         dly_cnt <= (others=>'0');


     elsif clk='1' and clk'event then

                  dly_cnt <= dly_cnt + "1";
                  ca <= '0'; cb <= '0'; cc <= '0'; cd  <= '0';
       
                 case dly_cnt is
                          when "00"    => ca <= '1'; segment7<= K_F;
		  when "01"    => cb <= '1'; segment7<= K_P;
                          when "10"    => cc <= '1'; segment7<= K_G;
                          when others => cd <= '1'; segment7<= K_A;
                 end case;
     end if;
end process

end Behavioral;
regards
rajavel.rv
 
Last edited:

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top