Search code examples
verilogsystem-verilogtest-bench

output of the word on the 7 segment indicator by using switch


I want to make an output to a seven-segment indicator so that when the buttons are pressed, the letter on a certain segment is displayed, and when the switch is turned on, the entire word is displayed. The seven-segment units work with a dynamic display.

When switching the switch to the active state, the place bus is connected to the shift register and the 7-segment switches should switch according to it.

On waveforms, when switching the switch to the active state, bus "place" doesn't change and remains equal to the initial value of the shift register(?). The values when the signal is given from the buttons are correct

MODULE

module mux_decoder(
    input btn_fir,
    input btn_sec,
    input btn_thi,
    input btn_fou,
    input sw_for_fullword,
    input clk,
    input rst,
    //input BTNC,
    //input SW[9],
    
    output logic [3:0] place,
    output [7:0] segments
    );
    
    typedef enum bit [7:0]
    {
        D     = 8'b0111_1010,
        N     = 8'b1110_1100,
        Y     = 8'b0111_0110,
        A     = 8'b1110_1110,
        space = 8'b0000_0000
    }
    seven_seg;
    seven_seg letter;
    
    logic [31:0] cnt;
    always_ff@(posedge clk,posedge rst)begin
        if(rst) cnt <= '0;
        else cnt <= cnt+1'b1;
    end
    
    logic enable = (cnt[2:0] == '0);
    
    logic [3:0]shift_reg;
    
    always_ff@(posedge clk, posedge rst)begin
        if (rst) shift_reg <= 4'b1;
        else if(enable) shift_reg <= {shift_reg[0], shift_reg[3:1]};
    end
    
   always_comb begin
        if(sw_for_fullword) place = shift_reg;
        else place = {btn_fir, btn_sec,btn_thi,btn_fou};
     end
     
    always_comb begin
        case (place)
        4'b1000: letter = D;
        4'b0100: letter = A;
        4'b0010: letter = N;
        4'b0001: letter = Y;
        default: letter = space;
        endcase        
    end
    
    assign segments = letter;
    
endmodule

TB

module tb( );
    logic[3:0] x;
    logic[7:0] letter;
    logic[3:0] place;
    logic sw;
    bit clk;
    bit rst;
    
    mux_decoder ms(.btn_fou(x[0]),.btn_fir(x[3]),.btn_sec(x[2]), .btn_thi(x[1]),.sw_for_fullword(sw),
    .place(place), .segments(letter), .clk(clk), .rst(rst));
    
    parameter CLK_PERIOD = 10;
  

    always #(CLK_PERIOD/2) clk = ! clk;
    

    initial begin
      rst <= 1'b1;
      repeat (2) @ (posedge clk);
      rst <= 1'b0;      
      

      
      x = 4'b0001;
      #20
      x = 4'b0010;
      #20
      x=4'b0100;
      #20;
      x = 4'b1000;
      #20
      x='0; 
      sw = '1;  
      repeat (50) @ (posedge clk);
      $finish;
    end
  

At the moment when the switch switches to the active state, "place" is connected to a shift register, which shifts towards the higher digits every 16 cycles (due to enable). But on the waveform "place" stays the same. The question is why the place remains the same, although the shift register performs a shift and changes its value accordingly.

timing diagram


Solution

  • It is not sufficient to only look at signals in the testbench. You also need to look at waveforms inside the mux_decoder module.

    When I looked at the waveform of the enable signal, it was unknown (x). Change:

    logic enable = (cnt[2:0] == '0);
    

    to:

    wire enable = (cnt[2:0] == '0);
    

    Now, I see enable become known:

    waves

    Refer to IEEE Std 1800-2017, section 6.5 Nets and variables. You are driving enable with a continuous assignment, which means it needs to be a "net" type, such as wire. In this context, logic is a "variable" type.