Altera DE1 seven segment display

verilog

What I am trying to do is, I want to use Key 0 as a upcounter and key 1 as a downcounter in the same program. I can do that separately. So, when enable is triggered, pressing key 0 will increase the value shown on a seven segment display and pressing key 1 will decrease the value. Following is my code.

/*
This program uses SW0 as the enable swithch.
And Key 0 as a upcounter, Key 1 as a downcounter
*/

module seven_seg_single_up_down ( en, in_up, in_down, a, b, c, d, e, f, g );
input en;
input in_up, in_down;

output a, b, c, d, e, f, g;

reg a, b, c, d, e, f, g;
reg [3:0]i;

always @( posedge in_up, posedge in_down, negedge en ) begin
    if ( ~en )
        begin
            {a, b, c, d, e, f, g} = 7'b1111111;
            i = 0;
        end
    //else if (in_up) 
    //  i = i + 1;
    //else if (in_down and i > 0 )
    //  i = i - 1;
    //else begin

    else begin
        if ( in_up )
            i = i + 1;
        if ( in_down ) begin
            i = i - 1;
        end

        case(i)
            1:{a, b, c, d, e, f, g} = 7'b1001111;
            2:{a, b, c, d, e, f, g} = 7'b0010010;
            3:{a, b, c, d, e, f, g} = 7'b0000110;
            4:{a, b, c, d, e, f, g} = 7'b1001100;
            5:{a, b, c, d, e, f, g} = 7'b0100100;
            6:{a, b, c, d, e, f, g} = 7'b0100000;
            7:{a, b, c, d, e, f, g} = 7'b0001111;
            8:{a, b, c, d, e, f, g} = 7'b0000000;
            9: begin
                {a, b, c, d, e, f, g} = 7'b0000100;
                i = -1;
                end
            default: {a, b, c, d, e, f, g} = 7'b0000001;
        endcase
    end
end
endmodule

I don't understand what is wrong with the code above.

Best Answer

Your code there doesn't look generally synthesizeable to me, as you're not really following any synchronous design conventions. I expect if you inspect your synthesis logs you'll find several warnings and/or errors.

  1. An edge triggered always block should model a flip flop, which means that it has one edge triggered clock, and an optional edge triggered preset and/or reset. It should not be triggering on edge of multiple arbitrary signals. @(posedge clk or negedge en) would be more appropriate, assuming that your fpga is provided with a suitable clock signal.

  2. Inside of an edge triggered block, you should generally use non-blocking assignments: <=, instead of blocking assignments: =, as this more correctly models the behavior of a flip flop. If you don't know what this means then do some research between the difference between blocking and nonblocking assignments.

If you want to use memory elements like a counter, then you need to use clocked logic. On every clock edge you can check if in_up or in_down has changed from the previous value, and then use that to decide if you want to increment or decrement your counter value. You may need to debounce the input signals if they are coming from a button or you may get multiple spurious toggles when it's pressed.