0
\$\begingroup\$

I'm designing a number exchange module, and so far I've been able to make it display on Seven Segment Display (S-S-D), like if I press 0 it shows 0... etc. I'm using 2 sets of 4-bits S-S-D (Common Anode).

Now I want to do like:

  • default states : 0000_0000
  • Now if I press 1 : 0000_0001
  • If I press 2 : 0000_0012
  • etc.

Whichever key I press, the display will not erase the already displaying number, it will shift it to the left...

And when all 8 S-S-D is full of displaying numbers like: 486C_8763, at this moment, when I press a key enter a number, like 1 it should be like : 86C8_7631; it should keep shifting to the left.

Here's my attempted code, and only been able to display it on S-S-D, and display all S-S-D 0000_0000... still not able to do what's been describe above...

Photo explain

module keydata 
(
  input clk, //input clk 50MHz
  output reg [3:0]keyout=4'b1110, //Default scan value 4bits 
  input [3:0]keyin, //Keypad receive value
  output reg [7:0]SegOut, //Seven Segment Display output
  output reg [15:0]scano //Seven Segment Display Scans
);

integer z1=0,zz=0; //Registers for frequency dividing
reg dclk; //Divided frequency clock
reg [7:0]bcdz; //register for saving keypad's number value
reg [3:0]scan; //scan states 



always@(posedge clk)
begin

//---------------------
if(z1==50000)   //frequency divider 
    begin
    z1<=0;
    scan<={scan[2:0],scan[3]}; //scanning pattern shifting resgister
    keyout<={keyout[2:0],keyout[3]};  //keypad column scanning 1110->1101->1011->0111->1110(loop)
    end
else
    z1<=z1+1;
//---------------------


//---------------------
if(zz==10000) //frequency divider for scanning
    begin
    zz<=0;
    dclk<=~dclk;
    end
else
    zz<=zz+1;
//--------------------- 
end

always@(posedge dclk)  //Seven Segment Scanning
    begin
        case(scan)
                0: scano<=scano[3:0];
                1: scano<=scano[7:4];
                2: scano<=scano[11:8];
                3: scano<=scano[15:12];
        endcase
    end

always@(posedge dclk) //4x4 Keypad detecting 
begin


    if (keyout==4'b1110) //Detecting which keyout is currently at scanning
        begin
        if(keyin==4'b0111) //Tell which key it is
            begin
            bcdz<=4'b1100;//C //the key's value,save by a register
            end
        else if(keyin==4'b1011)
            begin
            bcdz<=4'b1101; //D
            end
        else if(keyin==4'b1101)
            begin
            bcdz<=4'b1110; //E
            end
        else if(keyin==4'b1110)
            begin
            bcdz<=4'b1111;//F
            end
        end

    else if (keyout==4'b1101) //Using **else if** to differentiate priorities.
        begin
        if(keyin==4'b0111)
            begin
            bcdz<=4'b1000; //8
            end
        else if(keyin==4'b1011)
            begin
            bcdz<=4'b1001; //9
            end
        else if(keyin==4'b1101)
            begin
            bcdz<=4'b1010; //A
            end
        else if(keyin==4'b1110)
            begin
            bcdz<=4'b1011; //B
            end
        end

    else if (keyout==4'b1011) //4 scanning possibilities
        begin
        if(keyin==4'b0111)
            begin
            bcdz<=4'b0100; //4
            end
        else if(keyin==4'b1011)
            begin
            bcdz<=4'b0101; //5
            end
        else if(keyin==4'b1101)
            begin
            bcdz<=4'b0110; //6
            end
        else if(keyin==4'b1110)
            begin
            bcdz<=4'b0111; //7
            end
        end

    else if (keyout==4'b0111)
        begin
        if(keyin==4'b0111)
            begin
            bcdz<=4'b0000; //0
            end
        else if(keyin==4'b1011)
            begin
            bcdz<=4'b0001; //1
            end
        else if(keyin==4'b1101)
            begin
            bcdz<=4'b0010; //2
            end
        else if(keyin==4'b1110)
            begin
            bcdz<=4'b0011; //3
            end
        end
    end

always@(bcdz) //Seven Segment Decoder
begin
    case(bcdz)
            0   :   SegOut <=   8'hC0;
            1   :   SegOut <=   8'hF9;
            2   :   SegOut <=   8'hA4;
            3   :   SegOut <=   8'hB0;
            4   :   SegOut <=   8'h99;
            5   :   SegOut <=   8'h92;
            6   :   SegOut <=   8'h82;
            7   :   SegOut <=   8'hF8;
            8   :   SegOut <=   8'h80;
            9   :   SegOut <=   8'h98;
            10    : SegOut <=   8'h88;
            11  :   SegOut <=   8'h83;
            12  :   SegOut <=   8'hC6;
            13  :   SegOut <=   8'hA1;
            14  :   SegOut <=   8'h86;
            15    : SegOut <=   8'h8E;
            default :   SegOut <= 8'hFF;
    endcase
end
endmodule
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

I can see several problems. First, scan is never initialized, and you're shifting it and not incrementing it, so it doesn't match the case statement that looks at scan and sets scano. Second, scano is also not initialized, and the case statement that sets scano from segments of scano makes no sense. Third, you never actually store and shift the values anywhere. You'll need to have a memory location per digit, and I don't see that. They key scanning code also needs work. You'll want to have some delay between when keyout is changed and when you check keyin. Perhaps what you could do is have 'shift' and 'check' control lines that get pulses at different times, and you update keyout when 'shift' pulses and you check for a key press when 'check' pulses. You also need to detect both when a key is pressed and when a key is released, so you can register the key presses as separate events as opposed to just filling all the displays with '7' the moment the '7' key is pressed. Baasically, you need to detect the press, then ignore the keypad until the key is released. You could also turn that nested if statement into a single case statement by concatenating keyout and keyin like so: case ({keyout, keyin})

Try writing some code that just displays '123456' or simiar, ignoring the keyboard. Make that work first, then build on top of it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.