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.
When I run the simulation and look at waveforms in the
BCDtoSSegmodule, I see theBCDinput signal transition from 0 tozat time 17ns, and it remains at that value for the remainder of the simulation. Sincezdoes not match any of the items in thecasestatement, thecasedefaultis executed, andSSegis assigned to 0.The simulator I used showed this compile warning which identifies the problem:
Perhaps the simulator you use generates a similar message. Look in the simulation log file, etc.
The solution is to drive the
numinput in the testbench. Change:to:
After that fix,
SSegtakes on other values.