Search code examples
verilogfpgaquartusintel-fpgaquestasim

Verilog module always going to default case when assigning value to input


I'm just starting to use Verilog. One of my first projects has been a module that controls 4 7-segment displays with a 16-bit input. My BCDtoSSeg module is the following:

module BCDtoSSeg (BCD, SSeg);

  input [3:0] BCD;
  output reg [0:6] SSeg;
always @ ( * ) begin
  case (BCD)
   4'b0000: SSeg = 7'b0000001; // "0"  
    4'b0001: SSeg = 7'b1001111; // "1" 
    4'b0010: SSeg = 7'b0010010; // "2" 
    4'b0011: SSeg = 7'b0000110; // "3" 
    4'b0100: SSeg = 7'b1001100; // "4" 
    4'b0101: SSeg = 7'b0100100; // "5" 
    4'b0110: SSeg = 7'b0100000; // "6" 
    4'b0111: SSeg = 7'b0001111; // "7" 
    4'b1000: SSeg = 7'b0000000; // "8"  
    4'b1001: SSeg = 7'b0000100; // "9" 
   4'ha: SSeg = 7'b0001000;  
   4'hb: SSeg = 7'b1100000;
   4'hc: SSeg = 7'b0110001;
   4'hd: SSeg = 7'b1000010;
   4'he: SSeg = 7'b0110000;
   4'hf: SSeg = 7'b0111000;
    default:
    SSeg = 0;
  endcase
end

endmodule

Where the default case makes SSeg = 0. My module to control the display based on the current value of the 4-bit anode an looks like this:

`timescale 1ns / 1ps
module display(
    input [15:0] num,
    input clk,
    output [0:6] sseg,
    output reg [3:0] an,
     input rst,
     output led
    );

reg [3:0] bcd = 0;

BCDtoSSeg bcdtosseg(.BCD(bcd), .SSeg(sseg));

reg [26:0] cfreq = 0;
wire enable;

// Divisor de frecuecia

assign enable = cfreq[2];
assign led = enable;
always @(posedge clk) begin
  if(rst==1) begin
        cfreq <= 0;
    end else begin
        cfreq <= cfreq+1;
    end
end

reg [1:0] count = 0;
always @(posedge enable) begin
        if(rst==1) begin
            count <= 0;
            an <= 4'b1111; 
        end else begin 
            count <= count+1;
            case (count) 
                2'h0: begin bcd <= num[3:0];   an <= 4'b1110; end 
                2'h1: begin bcd <= num[7:4];   an <= 4'b1101; end 
                2'h2: begin bcd <= num[11:8];  an <= 4'b1011; end 
                2'h3: begin bcd <= num[15:12]; an <= 4'b0111; end 
            endcase
        end
end

endmodule

The thing is, whenever I try to simulate it with a testbench, the value for SSeg goes straight to the default (0) when the counter starts. I have tried replacing bcd <= num[#:#] for random 4-bit values such as bcd <= b´####and the simulation runs fine. The value for SSeg changes accordingly with the value of the anode, but whenever I use any expression that includes num it goes to default. It may be an error as to how I'm defining variables or inputs but I honestly have no idea. Here's the testbench as well in case it's any use:

`timescale 1ns / 1ps

module testbench;

    // Inputs
    reg [15:0] num;
    reg clk2;
    reg rst;

    // Outputs
    wire [0:6] sseg;
    wire [3:0] an;

    // Instantiate the Unit Under Test (UUT)
    display uut (
    //  .num(num), 
        .clk(clk2), 
        .sseg(sseg), 
        .an(an), 
        .rst(rst)
    );

    initial begin
        // Initialize Inputs
        clk2= 0;
        rst = 1;
        #10 rst =0;

        num = 16'h4321;
        
    end
      
    always #1 clk2 = ~clk2;
    
endmodule

Any help is greatly appreciated.


Solution

  • When I run the simulation and look at waveforms in the BCDtoSSeg module, I see the BCD input signal transition from 0 to z at time 17ns, and it remains at that value for the remainder of the simulation. Since z does not match any of the items in the case statement, the case default is executed, and SSeg is assigned to 0.

    The simulator I used showed this compile warning which identifies the problem:

        display uut (
                  |
    xmelab: *W,CUVWSI : 1 input port was not connected:
    xmelab:  num
    

    Perhaps the simulator you use generates a similar message. Look in the simulation log file, etc.

    The solution is to drive the num input in the testbench. Change:

    //  .num(num), 
    

    to:

        .num(num), 
    

    After that fix, SSeg takes on other values.

    waves