Search code examples
verilogmicroprocessorsintel-fpga

Increment and Decrement using verilog codes in quartus


My project is to design a verilog code that gives an output on the 7segments (HEX0,HEX1,HEX2,HEX3) and output must increase when the button KEY0 is pressed on the board 1 by 1, and decrease when the button KEY1 is pressed using Altera Board (Cyclone II-EP2C35F672).

I achieve to increase 1 by 1 but when I try to decrease with the same logic, I take irrelevant outputs. Is it possible to give me a way solving the problem.

My verilog code is that:


module sevensegment (KEY,HEX0,HEX1,HEX2,HEX3);

  input [3:0]KEY;

  output [0:6]HEX0;
  output [0:6]HEX1;
  output [0:6]HEX2;
  output [0:6]HEX3;

  counter D1(~KEY,HEX0,HEX1,HEX2,HEX3);

endmodule

module counter(in,out,out1,out2,out3);
  input  [3:0]in;
  output [6:0]out;
  output [6:0]out1;
  output [6:0]out2;
  output [6:0]out3;
  reg[15:0] tmp;

  always @(posedge in)
  begin
    if(~in[0])
    begin
      tmp <= tmp + 1'b1;
    end
    else if(~in[1])
    begin
      tmp <= tmp - 1'b1;
    end
   end

   displaysevensegment first_digit(tmp[3:0],out);
   displaysevensegment second_digit(tmp[7:4],out1);
   displaysevensegment third_digit(tmp[11:8],out2);
   displaysevensegment fourth_digit(tmp[15:12],out3);
endmodule

module displaysevensegment(in,out);
//                   abcdefg
parameter BLANK    = 7'b1111111;
parameter ZERO     = 7'b0000001; 
parameter ONE      = 7'b1001111;
parameter TWO      = 7'b0010010; 
parameter THREE    = 7'b0000110; 
parameter FOUR     = 7'b1001100; 
parameter FIVE     = 7'b0100100; 
parameter SIX      = 7'b0100000; 
parameter SEVEN    = 7'b0001111;
parameter EIGHT    = 7'b0000000; 
parameter NINE     = 7'b0000100; 
parameter TEN      = 7'b0001000; 
parameter ELEVEN   = 7'b1100000; 
parameter TWELVE   = 7'b0110001; 
parameter THIRTEEN = 7'b1000010; 
parameter FOURTEEN = 7'b0110000; 
parameter FIFTEEN  = 7'b0111000; 

input [3:0]in;
output [6:0]out;

assign out = (in == 0)  ? ZERO: 
             (in == 1)  ? ONE:
             (in == 2)  ? TWO:
             (in == 3)  ? THREE:
             (in == 4)  ? FOUR:
             (in == 5)  ? FIVE:
             (in == 6)  ? SIX: 
             (in == 7)  ? SEVEN:
             (in == 8)  ? EIGHT:
             (in == 9)  ? NINE:
             (in == 10) ? TEN:
             (in == 11) ? ELEVEN:
             (in == 12) ? TWELVE:
             (in == 13) ? THIRTEEN:
             (in == 14) ? FOURTEEN:
             (in == 15) ? FIFTEEN:BLANK;


endmodule

Solution

  • The simulate will not recognize the raising edge of in[1] when the sensitivity list is describes as posedge in. Only the LSB will be monitored. Instead use a bitwise operation to detect when a key is pressed and use this as the clocking signal.

    wire gen_clk = |in; // bitwise OR
    always @(posedge gen_clk) begin
      if (in[0]) tmp <= tmp + 1'b1;
      else if (in[1) tmp <= tmp - 1'b1;
    end
    
    wire gen_clk = &in; // bitwise AND
    always @(posedge gen_clk) begin
      if (in[0]) tmp <= tmp + 1'b1;
      else if (in[1) tmp <= tmp - 1'b1;
    end
    

    Side note: Deep nested muxes often result in lower performance more area then a case statement. This is because most synthesizer will not optimize inline muxes (?:). Recommend re-coding displaysevensegment with a case statement like:

    input [3:0] in;
    output [6:0] out;
    reg [6:0] out; // out needs to be a reg
    
    always @* begin
      case(in)
        4'h0 : out = ZERO;
        4'h1 : out = ONE;
        // ...
        4'hE : out = FOURTEEN;
        4'hF : out = FIFTEEN;
        default: out = BLANK;
      endcase
    end