Gigaxalus
Gigaxalus

Reputation: 107

Seven Segment Display

I'm having some problems coding a seven seg display in verilog. I want to increment 1 digit by 1 and have it roll over to 0 after 9. I have done lots of debugging and looked at examples but I can't seem to find the problem. My code:

module counter(output sega, segb, segc, segd, sege, segf, segg);

OSCH #("2.08") osc_int (                    //"2.03" specifies the operating frequency, 2.03 MHz. Other clock frequencies can be found in the MachX02's documentation
        .STDBY(1'b0),                           //Specifies active state
        .OSC(clk),                              //Outputs clock signal to 'clk' net
        .SEDSTDBY());

reg [21:0] cnt;
wire clk_slow = cnt[21];  //clock at 1 Hz

reg [3:0] BCD;   //represents the states of the counter
always @(posedge clk) 
begin
    begin
        cnt <= cnt+1;  
    end

    begin
        if(clk_slow) BCD <= (BCD ==4'h9 ? 4'h0 : BCD+4'b0001);   //increments state by 1
    end
end

reg [6:0] seg;  
always @(*)
begin
    case(BCD)
                    //gfedcba

    4'b0000: seg = 7'b1000000; //0
    4'b0001: seg = 7'b1111001; //1
    4'b0010: seg = 7'b0100100; //2
    4'b0011: seg = 7'b0110000; //3
    4'b0100: seg = 7'b0011001; //4
    4'b0101: seg = 7'b0010010; //5
    4'b0110: seg = 7'b0000010; //6
    4'b0111: seg = 7'b1111000; //7
    4'b1000: seg = 7'b0000000; //8
    4'b1001: seg = 7'b0011000; //9
    default seg = 7'b0111111;

    endcase
end

assign {segg, segf, sege, segd, segc, segb, sega} = seg;

endmodule

So when its running, my LEDs light up the correct digit every other time. In this case, it lights up on 0, 2, 4, 6, 8 and repeats. In between each number, the LEDs are lit, but not as brightly ( a dim '8'). When I switched the order of the cases but kept the numbers in the same spot (i.e. case b0000 is now for number 9), the LEDs light up 9, 7, 5, 3, 1.... For some reason, my LEDs arnt responding for any of the "odd" cases (i.e. 0001, 0011...). Any help sorting this out is greatly appreciated, as I have spent lots of hours trying to debug already.

I am using a Diamond Lattice FPGA. It has an onboard clock (the first module in my code). I slow it down to 1 hz at clock_slow.

Upvotes: 0

Views: 2723

Answers (1)

Qiu
Qiu

Reputation: 5761

Your problem is related to those lines:

always @(posedge clk) 
begin
    cnt <= cnt+1; 
    if(clk_slow) BCD <= (BCD ==4'h9 ? 4'h0 : BCD+4'b0001);   //increments state by 1
end

Because clk is faster than clk_slow, the if condition will be true for more than one clock cycle ('cause clk_slow is high for couple clk cycles). That's why BCD will be incremented more than once. I'd recommend you to divide this two instructions into two separate always blocks:

always @(posedge clk) begin
  cnt <= cnt + 1;
end

always @(posedge clk_slow) begin
  BCD <= (BCD ==4'h9 ? 4'h0 : BCD+4'b0001);   //increments state by 1
end

Upvotes: 4

Related Questions