EmbDev.net

Forum: FPGA, VHDL & Verilog Scrolling a text on a 7-seg display


Author: Giorgia (Guest)
Posted on:

Rate this post
0 useful
not useful
Hi to everyone! I write because I need help: I have to write a code to 
scroll a text (such as "dE1") on a 7-seg display using four 7-bit 
registers connected in a queue-like fashion, such that the outputs of 
the
first register feed the inputs of the second, the second feeds the 
third, and so on (pipeline). Each register’s outputs should directly 
drive the seven segments of one display. A finite state machine controls 
the pipeline in this way:
1. the FSM inserts the correct characters (d, E or 1) into the first of 
the 7-bit registers in the pipeline.
2. After step 1 is complete, the FSM configures the pipeline into a loop 
that connects the last register back to the first one, so that the 
letters continue to scroll indefinitely.

My code is:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity Scroll is
    Port ( clk : in STD_LOGIC;
           rst : in STD_LOGIC;
           z1 : inout STD_LOGIC_VECTOR (6 downto 0);
           z2 : inout STD_LOGIC_VECTOR (6 downto 0);
           z3 : inout STD_LOGIC_VECTOR (6 downto 0);
           z4 : inout STD_LOGIC_VECTOR (6 downto 0));
end Scroll;

architecture Behavioral of Scroll is

signal o1: std_logic_vector(6 downto 0) :="0000000";
signal o2: std_logic_vector(6 downto 0) :="0000000";
signal o3: std_logic_vector(6 downto 0) :="0000000";

type state_type is (A,B,C,D);
signal y: state_type:=A;

begin

z1<="111101" when y=B else
"1001111" when y=C else
"0110000" when y=D else
"0000000" when y=A else
"XXXXXXX";

process(rst,clk)
    begin
    if rst='0' then
        y<=A;
    elsif(clk'event and clk='1') then
    
    case y is
        when A =>
            y<=B;
            
       
        when B =>
            y<=C;
          
         when C =>
                y<=D;

         when D =>
            y<=B;
             
        end case;
        
        end if;

end process;


pipeline: process(clk,rst)
begin
   if rst='0' then
   
   o1<="0000000";
   o2<="0000000";
   o3<="0000000";
  
  for i in 6 downto 0 loop
  z2(i)<=o1(i);
  z3(i)<=o2(i);
  z4(i)<=o3(i);
  end loop;
   
 elsif(clk'event and clk='1') then
 --effettuo lo shift
for k in 6 downto 0 loop
   o1(k)<=z1(k);
   o2(k)<=o1(k);
   o3(k)<=o2(k);
 end loop;
 --aggiornamento dei segnali in uscita
    
  for j in 6 downto 0 loop
  z2(j)<=o1(j);
  z3(j)<=o2(j);
  z4(j)<=o3(j);
  end loop;
  end if;
  end process;

end Behavioral;
This code doesn't work because the second, the third and the fourth 
display are late compared to the first one of one clock cycle. Could you 
help me please? Thank you very much.

: Edited by Moderator
Author: Lothar M. (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Giorgia wrote:
> This code doesn't work because the second, the third and the fourth
> display are late compared to the first one of one clock cycle. Could you
> help me please?
Congratulations, you found what's called "latency". The most easy 
solution for that "problem" is, to supply them one clock cycle earlier. 
But in the real world with a 50MHz clock its not problem to have one 
clock cycle latency here, because then the display is delayed by 20ns. 
Your eye will not recognize that...

A few hints beyond that:
z1 : inout STD_LOGIC_VECTOR (6 downto 0);
Are those really inout ports? If not: why do you declare it that way? 
Just for laziness? That's no good idea, believe me.
for k in 6 downto 0 loop
   o1(k)<=z1(k);
   o2(k)<=o1(k);
   o3(k)<=o2(k);
 end loop;
You can skip the loop and cut this down to
   o1 <= z1;
   o2 <= o1;
   o3 <= o2;

Giorgia wrote:
> I have to write a code to scroll a text (such as "dE1") on a 7-seg
> display using four 7-bit registers connected in a queue-like fashion
Why do you do that so complicated with additional FSM and so on?
Why not the easy way?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity Scroll is
    Port ( clk : in STD_LOGIC;
           rst : in STD_LOGIC;
           z1 : out STD_LOGIC_VECTOR (6 downto 0);
           z2 : out STD_LOGIC_VECTOR (6 downto 0);
           z3 : out STD_LOGIC_VECTOR (6 downto 0);
           z4 : out STD_LOGIC_VECTOR (6 downto 0));
end Scroll;

architecture Behavioral of Scroll is

  signal o1: std_logic_vector(6 downto 0) :="0111101"; -- d
  signal o2: std_logic_vector(6 downto 0) :="1001111"; -- E
  signal o3: std_logic_vector(6 downto 0) :="0110000"; -- 1
  signal o4: std_logic_vector(6 downto 0) :="0000000"; -- blank

begin

  pipeline: process(clk,rst)
  begin
    if rst='0' then
      o1<="0111101";
      o2<="1001111";
      o3<="0110000";
      o4<="0000000";   
    elsif(clk'event and clk='1') then
      o1 <= o2; -- scroll the text (fairly fast at some MHz clock...)
      o2 <= o3;
      o3 <= o4;
      o4 <= o1;
    end if;
  end process;

  z1 <= o1;
  z2 <= o2;
  z3 <= o3;
  z4 <= o4;

end Behavioral;


BTW: pls wrap your VHDL code with the [vhdl] tokens as described a few 
lines over each edit-box.

BTW2: with proper indention your code gets more readable.

: Edited by Moderator
Author: Giorgia (Guest)
Posted on:

Rate this post
0 useful
not useful
Now it's working! Thank you very much!
I added a FSM because the exercise requires it. Do you think it's too 
complicated?

Author: Lothar M. (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Giorgia wrote:
> I added a FSM because the exercise requires it.
Each simple counter is a FSM.

> Do you think it's too complicated?
No, it's a nice exercise.

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig