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.
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
i want ucf code for the above verilog code
ReplyDeleteHi,
Deletethe .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.
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
ReplyDeleteThats alright, Nathan. I really like what you've done thanks for letting me know. I'm happy this helped you out :)
DeleteNice, 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.
ReplyDeleteI 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.
DeleteCan you at least tell which one is the output register so I can assign the pin accordingly. Cheers
DeleteRahat, 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; "
DeleteSo you need to assign {a, b ,c, d, e, f, g} in your ucf file
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.
ReplyDeleteAre you sure your ucf file is accurate?
DeleteNo 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.
DeleteThats 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. :)
DeleteVery well written and informative article, thank you :-)
ReplyDeleteMoving Display Board
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?
ReplyDeletecan you please help me assigning the pins?
ReplyDeleteHi, 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
Deletesir i need your help urgently please reply me. What is dp output?
ReplyDeletedp 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
DeleteThanks 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.
Deletewill your code work in basys 3?
ReplyDeleteHow can I modify it so that it only displayed 1 2 3 4
ReplyDelete