Search code examples
verilogintel-fpgaquartus

How to display decimal equivalent (0-63) on two 7-segment displays using 6 switches as bits?


I recently did a skills test wherein the problem was described as: "Create a .v (verilog hdl) file that uses sw [6:1] to represent 0 to 63 in the 7-segment displays hex2 and hex1 while showing "--" for any number divisible by 4."

I finished it by hardcoding (since I was under a time limit) all the values using a case statement from 0-63 taking note of those divisible by 4 to show just "--"

Of course that isn't the optimal solution and I hate to leave a problem solved by means of hardcoding values.

This is for a Cyclone-II FPGA (what we have in university) and am using Quartus II to compile. For the "--" for every number divisible by 4, I solved it by adding a conditional operator and did "(sw % 4) == 0 ? n : ...". I've done the hardcoding and my attempt to solve it another way by taking note of the pattern for every 16 intervals and "shifting up" the value of the 7-segment display to what '0000' is for that value (at 16, 10000 = h6, 17 10001 = h7, etc.):

module sk10(sw,hex1,hex2,hex3,hex0);
input [5:0] sw;
output [6:0] hex1,hex2,hex3 = 7'h7F, hex0 = 7'h7F; 

reg [6:0] hex1;

parameter h0 = 7'b0000001; 
parameter h1 = 7'b1001111;
parameter h2 = 7'b0010010; 
parameter h3 = 7'b0000110;
parameter h4 = 7'b1001100;
parameter h5 = 7'b0100100;
parameter h6 = 7'b0100000;
parameter h7 = 7'b0001111;
parameter h8 = 7'b0000000;
parameter h9 = 7'b0000100;
parameter n =  7'b1111110;

assign hex2 = (sw % 4 == 0) ? n :
                    (sw < 10) ? h0 : 
                    (sw < 20 && sw >= 10) ? h1 :
                    (sw < 30 && sw >= 20) ? h2 :
                    (sw < 40 && sw >= 30) ? h3 :
                    (sw < 50 && sw >= 40) ? h4 :
                    (sw < 60 && sw >= 50) ? h5 :
                    (sw < 70 && sw >= 60 ) ? h6 : n;

always @ (sw)
begin
    if (sw < 16) begin 
            case (sw[3:0])
            0 : hex1 = h0; 
            1 : hex1 = h1;
            2 : hex1 = h2; 
            3 : hex1 = h3;
            4 : hex1 = h4;
            5 : hex1 = h5;
            6 : hex1 = h6;
            7 : hex1 = h7;
            8 : hex1 = h8;
            9 : hex1 = h9;
            10 : hex1 = h0;
            11 : hex1 = h1;
            12 : hex1 = h2;
            13 : hex1 = h3;
            14 : hex1 = h4;
            15 : hex1 = h5;
            endcase
            end
    else if (sw >= 16 && sw < 32) begin
            case (sw[3:0])
            0 : hex1 = h6; 
            1 : hex1 = h7;
            2 : hex1 = h8; 

... and so on for every 16 intervals until 64

It works but it is hardly optimal and I might as well have hardcoded all 64 case statements since this new, alternative code I made is longer than that. I'd like to ask for help for a better alternative than hardcoding each one or my attempt above. Any answer is much appreciated!


Solution

  • Since the result is for displaying, it should be acceptable to spend some clock cycles to get the result.

    Check the "double dabble" algorithm.

    Nanland site has some examples too: https://www.nandland.com/vhdl/modules/double-dabble.html