Saturday, 22 December 2012

Scrolling or Moving Text Using 7 Segment LED's in Verilog | FPGA

This one is going to be a quick easy project. The objective here is to get use the 7-segment LED display on the board to display a scrolling text. it should be slow enough so that it can be easily read.

I have made the delay between each word shift to be 1 second. This is long enough to read the text comfortably without missing anything. I have explained in my previous post how to create an accurate delay using verilog, you can read about it there: Create accurate delay in Verilog. Now since I need a 1 second delay here the counter monitoring this count must count to 50,000,000. And the register needed to hold this count must be 29 bits wide.

Using this method you can scroll and display anything. Here I have chosen to display the text "Hello There" to scroll across the LED's and appear to be continuous without any stops. The concept is pretty simple. I create a separate counter that increments every time a count of 50,000,000 is reached. This counter will count till 8, display the entire text, and then reset back to 0 so that the text can be scrolled again. For every count increment it will match it with a case statement. This case will instruct the display for that second.

Now since 7 segment LED's are being used here you must have a proper understanding of them before trying to read and understand the code. I have detailed the topic in detail here: 7 Segment LED Multiplexing in Verilog. Be sure to read and understand it.

So instead of displaying numbers the plan is to display letters on the LED's. This can be achieved by changing the case statement to our requirements.

As usual the code is commented in detail and should be self explanatory even without the above rant. A video demonstration has been added at the end.

module scrolling_name(
    input clock,
    input reset,
    output a,
    output b,
    output c,
    output d,
    output e,
    output f,
    output g,
    output dp,
    output [3:0] an
    );

reg [28:0] ticker; //to hold a count of 50M
wire click;
reg [3:0] fourth, third, second, first; // registers to hold the LED values

always @ (posedge clock or posedge reset) //always block for the ticker
begin
 if(reset)
  ticker <= 0;
 else if(ticker == 50000000) //reset after 1 second
  ticker <= 0;
 else
  ticker <= ticker + 1;
end

reg [3:0] clickcount; //register to hold the count upto 9. That is why a 4 bit register is used. 3 bit would not have been enough.

assign click = ((ticker == 50000000)?1'b1:1'b0); //click every second

always @ (posedge click or posedge reset)
begin
 if(reset)
  clickcount <= 0;
 else if(clickcount == 8)
   clickcount <= 0;
  else 
  clickcount <= clickcount + 1;

end

always @ (*) //always block that will scroll or move the text. Accomplished with case
begin
    case(clickcount)
    0:
    begin
     fourth = 4; //H
     third = 3; //E
     second = 7; //L
     first = 7; //L
    end
    
    1:
    begin
     fourth = 3; //E
     third = 7; //L
     second = 7; //L
     first = 0; //O
    end
    
    2:
    begin
     fourth = 7; //L
     third = 7; //L
     second = 0; //O
     first = 2; //-
    end
    
    3:
    begin
     fourth = 7; //L
     third = 0; //O
     second = 2; //-
     first = 1; //T
    end
    
    4:
    begin
     fourth = 0; //O
     third = 2; //-
     second = 1; //T
     first = 4; //H
    end
    
    5:
    begin
     fourth = 2; //-
     third = 1; //T
     second = 4; //H
     first = 3; //E
    end
    
    6:
    begin
     fourth = 1; //T
     third = 4; //H
     second = 3; //E
     first = 8; //R
    end
    
    7:
    begin
     fourth = 4; //H
     third = 3; //E
     second = 8; //R
     first = 3; //E
    end
    
    8:
    begin
     fourth = 3; //E
     third = 8; //R
     second = 3; //E
     first = 2; //blank
    end
  endcase
  
end

//see my other post on explanation of LED multiplexing.

localparam N = 18;

reg [N-1:0]count;

always @ (posedge clock or posedge reset)
 begin
  if (reset)
   count <= 0;
  else
   count <= count + 1;
 end

reg [6:0]sseg;
reg [3:0]an_temp;

always @ (*)
 begin
  case(count[N-1:N-2])
   
   2'b00 : 
    begin
     sseg = first;
     an_temp = 4'b1110;
    end
   
   2'b01:
    begin
     sseg = second;
     an_temp = 4'b1101;
    end
   
   2'b10:
    begin
     sseg = third;
     an_temp = 4'b1011;
    end
    
   2'b11:
    begin
     sseg = fourth;
     an_temp = 4'b0111;
    end
  endcase
 end
assign an = an_temp;

reg [6:0] sseg_temp; 
always @ (*)
 begin
  case(sseg)
   4 : sseg_temp = 7'b0001001; //to display H
   3 : sseg_temp = 7'b0000110; //to display E
   7 : sseg_temp = 7'b1000111; //to display L
   0 : sseg_temp = 7'b1000000; //to display O
   1 : sseg_temp = 7'b0000111; //to display T
   8 : sseg_temp = 7'b0001000; //to display R
   
   default : sseg_temp = 7'b1111111; //blank
  endcase
 end
assign {g, f, e, d, c, b, a} = sseg_temp; 
assign dp = 1'b1;

endmodule

19 comments:

  1. i want ucf code for the above verilog code

    ReplyDelete
    Replies
    1. Hi,

      the .ucf file for the BASYS2 board can be found here:

      http://simplefpga.blogspot.co.uk/2012/06/user-constraint-file-ucf-for-basys2.html

      Do note that if your board is not BASYS2 this will not work.

      Delete
  2. Nice, this helped a lot! Hope you don't mind I posted a modified version of your code to stack overflow - http://stackoverflow.com/questions/15194206/seven-segment-multiplexing-on-basys2/15301085#15301085

    ReplyDelete
    Replies
    1. Thats alright, Nathan. I really like what you've done thanks for letting me know. I'm happy this helped you out :)

      Delete
  3. Nice, very useful content you got there, mate. I went through all of it but I am doing on a altera cyclone board. But we can't find the output pins configured would be mind providing that. I tried only on 7 segment display works and isn't shifting.

    ReplyDelete
    Replies
    1. I use the BASYS2 board, the ucf file I have for my board wont work with your board. You have to find the .UCF file for your ALTERA board from either the manufacturers website or from Google.

      Delete
    2. Can you at least tell which one is the output register so I can assign the pin accordingly. Cheers

      Delete
    3. Rahat, the output register is the "sseg_temp" in the code. But in terms of hardware this register is connected to the seven individual LED's of the seven segment display via the line: "assign {g, f, e, d, c, b, a} = sseg_temp; "

      So you need to assign {a, b ,c, d, e, f, g} in your ucf file

      Delete
  4. I tried going through the whole web in three weeks it seems there aren't any documents on how to scroll the seven segment display on Altera cyclone iv board. I tried going through your code and try to replicate it but I can't make the seven segment move for one to another.

    ReplyDelete
    Replies
    1. Are you sure your ucf file is accurate?

      Delete
    2. No worries I found a solution for the scrolling text for later cyclone DE115 board. I would be happy if you can upload it on your blogspot.

      Delete
    3. Thats great. No thanks, all my posts are related to the BASYS2. But I'm sure if someone needs the code they would know how to contact you. :)

      Delete
  5. Very well written and informative article, thank you :-)

    Moving Display Board

    ReplyDelete
  6. Found it very helpful indeed! However, if I want to scroll or shift my text both ways (from left to right and vice versa) what modification will be required in your above mentioned code?

    ReplyDelete
  7. can you please help me assigning the pins?

    ReplyDelete
    Replies
    1. Hi, Please refer to this post for pin assignment. You will need the .ucf file for your board. http://simplefpga.blogspot.co.uk/2012/06/user-constraint-file-ucf-for-basys2.html

      Delete
  8. sir i need your help urgently please reply me. What is dp output?

    ReplyDelete
    Replies
    1. dp is the output for decimal point on the 7 segment display. Please refer to this post for a detailed description: http://simplefpga.blogspot.co.uk/2012/07/seven-segment-led-multiplexing-circuit.html

      Delete
    2. Thanks for replying. Can you tell me that what is 5M i mean to say that either it is the frequency of clock that we have to store in a register or either it is the time in Nano Seconds. Please explain this thing.

      Delete