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 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.