verilogsystem-verilogfpgavivado

LED Sequence on Basys3 with Verilog


I need this for a school project. The professor wants an LED sequence if the x is zero (which would mean the sw is 0) that would go:

0000000000000001
0000000000000010
0000000000000100
0000000000001000
0000000000010000
0000000000100000
0000000001000000
0000000010000000
0000000100000000
0000001000000000
0000010000000000
0000100000000000
0001000000000000
0010000000000000
0100000000000000
1000000000000000

from us. If not, it would go the other way around. Now I am stuck at the testbench file because it doesn't show the change in the led vector that would look like steps. Here is my main code:

`timescale 1ns / 1ps

module main(
    output [15:0] led,
    input clk,
    input btnC,
    input sw
);

reg [15:0] state;
reg ovr;
reg x;
wire sec;

zaman timer (sec, clk, btnC);

initial begin
    state = 16'b0000000000000001;
    ovr = 1'b0;
    x = 0;
end

always @ (posedge clk) begin
    x <= sw;
    
    if (btnC == 1) begin
        state = 16'b0000000000000001;
        ovr = 1'b0;
    end
    else if (sec == 1) begin
        if (x == 0) begin
            {ovr,state} <= state << 1;
            if (ovr == 1'b1) begin
                state <= 16'b0000000000000001;
                ovr <= 1'b0;
            end
        end
        else if (x == 1) begin
            {state, ovr} <= state >> 1;
            if (ovr == 1'b1) begin
                state <= 16'b1000000000000000;
                ovr <= 1'b0;
            end
        end
    end
    
end
assign led = state;

endmodule

Its submodule:

module zaman(
output Y,
input clock,
input reset
);

reg elapsed;
reg [25:0] state;

always @(posedge clock)
if (reset == 1) state <= 0;
else if (state == 50000000) state <= 0;// corresponds to 1 sec
else state <= state + 1;

always @(state)
if (state == 50000000) elapsed = 1;
else elapsed = 0;
assign Y = elapsed;

endmodule

and the testbench file:

`timescale 1ns / 1ps

module maintb;

reg clk;
reg btnC;
reg sw;
wire [15:0] led;
    
main uut(.led(led), .btnC(btnC), .sw(sw), .clk(clk));

always #5 clk = ~clk;

initial begin
    clk = 0;
    btnC = 0;
    sw = 0;
    
    btnC = 1;
    #10;
    btnC = 0;
    
    #160000000;
end

endmodule

All I get is this sim result:

simulation results


Solution

  • You either did not let the simulation run for a long enough time, or you did not zoom out your waveforms enough to see led change from 1 to 2.

    You can add this line to your testbench:

    initial $monitor($time,  " led=%b", led);
    

    I see this output:

                       0 led=0000000000000001
               500000015 led=0000000000000010
              1000000025 led=0000000000000100
              1500000035 led=0000000000001000
    

    If your simulation stops after #160000000, you need to add more delay to see led change value. As you can see, the simulation ran for more than 1.5s.

    Here is the testbench initial block that I used:

    initial begin
        $monitor($time,  " led=%b", led);
        clk = 0;
        btnC = 0;
        sw = 0;
        
        btnC = 1;
        #10;
        btnC = 0;
        
        #2s;
        $finish;
    end
    

    I changed the delay to stop the simulation at 2s.

    You can see the simulation running on another simulator on EDA Playground


    To make big integers easier to read, you can use underscores:

    #160_000_000