Search code examples
verilogxilinxvivado

vivado having trouble with X waveform from outputs, taking an array and making it waveform on a 7 segment led counter finite state machine


I am trying to create a 7 segment led counter and the two issues I am having is that a through g only display to be X in a simulation waveform and I have no idea how to take q which is the present state and make it waveform to the testbench. I thought it would be something like create wires in the testbench called Q2, Q1, and Q0 and add them like .q[2] (Q2) and so on but it does not seem to like that. I am very new to this so it may be something very simple. Thank you!

`timescale 1ns / 1ps

//inputs, outputs

module Counter(
input u,
input clrn,
input clk,
output reg a,
output reg b,
output reg c,
output reg d,
output reg e,
output reg f,
output reg g);

reg [2:0] ns; //next state
reg [2:0] q; //present state
//declaration of the states    
parameter [2:0] S0 = 3'b000, S1 = 3'b001, S2 = 3'b010, S3 = 3'b011, S4 = 3'b100, S5 = 3'b101;

always @ (negedge clk or posedge clrn)
begin
if(clrn) //if reset present state q goes to 0
    q = S0;
else
begin
    case(q) //tests present state
        S0:
        if (u==1) begin
            ns = S1;
            a = 1'b0;
            b = 1'b1;
            c = 1'b1;
            d = 1'b0;
            e = 1'b0;
            f = 1'b0;
            g = 1'b0;
        end
        else begin
            ns = S5;
            a = 1'b1;
            b = 1'b0;
            c = 1'b1;
            d = 1'b1;
            e = 1'b0;
            f = 1'b1;
            g = 1'b1;
        end

        S1:
        if (u==1) begin
            ns = S2;
            a = 1'b1;
            b = 1'b1;
            c = 1'b0;
            d = 1'b1;
            e = 1'b1;
            f = 1'b0;
            g = 1'b1;
        end
        else begin
            ns = S0;
            a = 1'b1;
            b = 1'b1;
            c = 1'b1;
            d = 1'b1;
            e = 1'b1;
            f = 1'b1;
            g = 1'b0;
        end

        S2:
        if (u==1) begin
            ns = S3;
            a = 1'b1;
            b = 1'b1;
            c = 1'b1;
            d = 1'b1;
            e = 1'b0;
            f = 1'b0;
            g = 1'b1;
        end
        else begin
            ns = S1;
            a = 1'b0;
            b = 1'b1;
            c = 1'b1;
            d = 1'b0;
            e = 1'b0;
            f = 1'b0;
            g = 1'b0;
        end            

        S3:
        if (u==1) begin
            ns = S4;
            a = 1'b0;
            b = 1'b1;
            c = 1'b1;
            d = 1'b0;
            e = 1'b0;
            f = 1'b1;
            g = 1'b1;
        end
        else begin
            ns = S2;
            a = 1'b1;
            b = 1'b0;
            c = 1'b1;
            d = 1'b1;
            e = 1'b0;
            f = 1'b1;
            g = 1'b1;
        end   

        S4:
        if (u==1) begin
            ns = S5;
            a = 1'b1;
            b = 1'b0;
            c = 1'b1;
            d = 1'b1;
            e = 1'b0;
            f = 1'b1;
            g = 1'b1;
        end
        else begin
            ns = S3;
            a = 1'b1;
            b = 1'b1;
            c = 1'b1;
            d = 1'b1;
            e = 1'b0;
            f = 1'b0;
            g = 1'b1;
        end

        S5:
        if (u==1) begin
            ns = S0;
            a = 1'b1;
            b = 1'b1;
            c = 1'b1;
            d = 1'b1;
            e = 1'b1;
            f = 1'b1;
            g = 1'b0;
        end
        else begin
            ns = S4;
            a = 1'b0;
            b = 1'b1;
            c = 1'b1;
            d = 1'b0;
            e = 1'b0;
            f = 1'b1;
            g = 1'b1;
        end

    endcase

    q = ns;

end

end

endmodule

Testbench:

`timescale 1ns / 1ps


module testbench;

reg U, CLK, CLRN;
wire A, B, C, D, E, F, G;

Counter inst(

.clk (CLK),
.u (U),
.clrn (CLRN),
.a (A),
.b (B),
.c (C),
.d (D),
.e (E),
.f (F),
.g (G));

initial

begin //CLRN starts low, CLK starts high, U starts high

CLRN = 1'b0;

CLK = 1'b1;

U = 1'b1;

//CLK will change every ns

#1 CLRN = 1'b1;
CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0; //On the ns 17 u will change to low
U = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

#1 CLK = 1'b0;

#1 CLK = 1'b1;

end

endmodule

Solution

  • You have two primary issues that you need to tweek.

    1. You have a CLRn, but you say if(clrn). Negative polarity reset you need a if (~clrn)

    2. Your reset in the always statement is looking for a positive edge transition in the sensitivity list. You need a negedge sensitivity on clrn at least, like so...

    always @ (negedge clk or negedge clrn)

    But I would recommend the following as being more standard with a positive clock edge sensitivity as well...

    always @ (posedge clk or negedge clrn)