I spent quite a long time debugging some Verilog code only to realize that the design was correct the entire time and for whatever reason Verilog's display
function was having unexpected behavior.
I have the following testbench file:
`timescale 1ns / 1ps
module tb ();
logic signed [7:0] Y;
logic signed [15:0] X;
logic signed [23:0] Z;
logic clk;
reg [8:0] counter;
// instantiate device under test
CSAM dut (Z,X,Y);
// 2 ns clock
initial
begin
clk = 1'b1;
assign counter = 8'b0;
forever #10 clk = ~clk;
end
initial
begin
//while (1)
//begin
#10 X = 16'b0000000001111011;
#0 Y = 8'b11110011;
#20 X = 16'b0000000001111011;
#0 Y = 8'b11110011;
$display ("Test data:\ninput A is 0b'%16b or 0h'%4h or %d\ninput B is 0b'%8b or 0h'%2h or %d\noutput is 0b'%24b or 0h'%6h or %d\n", X,X,X,Y,Y,Y,Z,Z,Z);
#20 X = 16'b0000000000001111;
#0 Y = 8'b00000000;
$display ("Test data:\ninput A is 0b'%16b or 0h'%4h or %d\ninput B is 0b'%8b or 0h'%2h or %d\noutput is 0b'%24b or 0h'%6h or %d\n", X,X,X,Y,Y,Y,Z,Z,Z);
#20 X = 16'b0000000000001111;
#0 Y = 8'b11111111;
$display ("Test data:\ninput A is 0b'%16b or 0h'%4h or %d\ninput B is 0b'%8b or 0h'%2h or %d\noutput is 0b'%24b or 0h'%6h or %d\n", X,X,X,Y,Y,Y,Z,Z,Z);
#20 X = 16'b11111111111111;
#0 Y = 8'b11111111;
$display ("Test data:\ninput A is 0b'%16b or 0h'%4h or %d\ninput B is 0b'%8b or 0h'%2h or %d\noutput is 0b'%24b or 0h'%6h or %d\n", X,X,X,Y,Y,Y,Z,Z,Z);
#20 X = 16'b1010101010101010;
#0 Y = 8'b01010101;
$display ("Test data:\ninput A is 0b'%16b or 0h'%4h or %d\ninput B is 0b'%8b or 0h'%2h or %d\noutput is 0b'%24b or 0h'%6h or %d\n", X,X,X,Y,Y,Y,Z,Z,Z);
#20 X = 16'b0101010101010101;
#0 Y = 8'b00101010;
$display ("Test data:\ninput A is 0b'%16b or 0h'%4h or %d\ninput B is 0b'%8b or 0h'%2h or %d\noutput is 0b'%24b or 0h'%6h or %d\n", X,X,X,Y,Y,Y,Z,Z,Z);
end
endmodule
You can see that I am running some tests of inputs X,Y and Z is the output.
My display function prints X,Y,Z in decimal, hex, and binary for readability.
$display ("Test data:\ninput A is 0b'%16b or 0h'%4h or %d\ninput B is 0b'%8b or 0h'%2h or %d\noutput is 0b'%24b or 0h'%6h or %d\n", X,X,X,Y,Y,Y,Z,Z,Z);
The output looks like this in Modelsim's terminal:
# Test data:
# input A is 0b'0000000001111011 or 0h'007b or 123
# input B is 0b'11110011 or 0h'f3 or -13
# output is 0b'111111111111100111000001 or 0h'fff9c1 or -1599
#
# Test data:
# input A is 0b'0000000000001111 or 0h'000f or 15
# input B is 0b'00000000 or 0h'00 or 0
# output is 0b'111111111111111100111101 or 0h'ffff3d or -195
#
# Test data:
# input A is 0b'0000000000001111 or 0h'000f or 15
# input B is 0b'11111111 or 0h'ff or -1
# output is 0b'000000000000000000000000 or 0h'000000 or 0
You can see that for 15x0, and 15x-1 the results are actually incorrect. However, if I inspect the Z waveform manually in Modelsim's waveform viewer I can see the answer is actually correct. So somehow, the display function is not behaving as intended and I would like to know what I can do to fix that. It is particularly weird to me that the inputs X,Y display properly for all tests but Z does not.