Vivado Behavioral Simulations showing undefined (XX) output - verilog

I'm attempting to run a behavioral simulation on my Verilog code in Vivado. However, after the simulation runs, instead of getting outputs, they are shown as red lines with XX, which I believe means they are undefined.
I've attempted to change the timescale at the top of the Verilog files, as shown in Xilinx forum post, but this did not fix my issue.
Here is my Verilog program:
module ctrl(
input clk,
input [5:0] A,
input [5:0] B,
input [3:0] C,
output reg [6:0] led
);
always #(posedge clk)
begin
case(C)
4'b0000:
//A + B
led <= A + B;
4'b0001:
//A - B
led <= A - B;
4'b0010:
//A++
led <= A + 1'b1;
4'b0011:
//A--
led <= A - 1'b1;
4'b0100:
//B++
led <= B + 1'b1;
4'b0101:
//B--
led <= B - 1'b1;
4'b0110:
//A & B
led = (A & B);
4'b0111:
//A | B
led = (A | B);
4'b1000:
//A ^ B
led = (A ^ B);
4'b1001:
//~A
led = {1'b0,~A[5:0]
4'b1010:
//~B
led = {1'b0,~B[5:0]};
4'b1011:
//A << B
led = A << B;
4'b1100:
//B << A
led = B << A;
4'b1101:
//Light LED[0] if A > B
if(A > B)
led = 7'b0000001;
else
led = 7'b0000000;
4'b1110:
//Light LED[0] if A < B
if(A < B)
led = 7'b00000001;
else
led = 7'b0000000;
4'b1111:
//Light LED[0] if A=B
if(A == B)
led = 7'b0000001;
else
led = 7'b0000000;
default:
//Unimplemented opcode
led <= 7'b1111111;
endcase
end
endmodule
The testbench
module ctrl_testbench();
reg[5:0] A;
reg[5:0] B;
reg[3:0] C;
wire[6:0] led;
ctrl dut (
.A(A),
.B(B),
.C(C),
.led(led)
);
initial begin
A = 6'b000001;
B = 6'b000001;
C = 4'b0000;
#100;
A = 6'b000000;
B = 6'b000000;
C = 4'b0000;
#100;
A = 6'b000010;
B = 6'b000010;
C = 4'b0001;
end
endmodule
The timing diagram then gives this after the behavioral simulation is run. As you can see A-C (The inputs) are populated correctly, however LED (the output) is red and shows XX.
I'm trying to show the actual outputs.

You need to create a clock signal and drive the clk input of your DUT:
module ctrl_testbench();
reg[5:0] A;
reg[5:0] B;
reg[3:0] C;
wire[6:0] led;
reg clk;
initial begin
clk = 0;
forever #5 clk = ~clk;
end
ctrl dut (
.clk(clk),
.A(A),
.B(B),
.C(C),
.led(led)
);
initial begin
A = 6'b000001;
B = 6'b000001;
C = 4'b0000;
#100;
A = 6'b000000;
B = 6'b000000;
C = 4'b0000;
#100;
A = 6'b000010;
B = 6'b000010;
C = 4'b0001;
$finish;
end
endmodule
It was convenient for me to create 2 initial blocks. The first never ends due to forever, and the second is necessary to end the simulation with $finish. It is common to separate out distinct functionality using multiple initial blocks.

Related

Unresolved reference to 'fulladder' in Verilog

I am having some issues when attempting to run a simulation. It seems there is an issue with my instances of my first 2 modules inside of my 3rd module. The code is compiling okay, but I am running into trouble when I try to run a simulation.
I am not really sure if the problem is in my code or my test bench.
module fulladder
(
input [15:0] x,
input [15:0] y,
output [15:0] O
);
assign O = y + x;
endmodule
module shifter
(
input [15:0] in,
input [2:0] N,
output [15:0] O
);
reg [7:0] out_reg;
assign O = out_reg;
always #(N or in) begin
case (N)
7 : out_reg <= { in[7:0],7'b0};
6 : out_reg <= { in[7:0],6'b0};
5 : out_reg <= { in[7:0],5'b0};
4 : out_reg <= { in[7:0],4'b0};
3 : out_reg <= { in[7:0],3'b0};
2 : out_reg <= { in[7:0],2'b0};
1 : out_reg <= { in[7:0],1'b0};
0 : out_reg <= in[7:0];
endcase
end
endmodule
module my_multiplier(Rst, Ld, clk, A, B, O);
input clk;
input [7:0]A, B;
input Rst, Ld;
output [15:0] O;
reg Done;
reg [15:0] Otemp;
reg [15:0] O;
reg [7:0] Atemp;
reg [1:0] state;
reg [1:0] C;
parameter S0 = 2'b00, S1 = 2'b01, S2 = 2'b10, S3 = 2'b11;
always #(posedge clk or posedge Rst)
begin
case(state)
S0: begin
Done <= 0;
if (Ld == 1)
begin
C <= 0;
Atemp <= A;
state <= S1;
end
else
state <= S0;
end
S1: if (B[C] == 1)
begin
shifter ( A, C, Atemp);
O <= Otemp;
C <= C + 1;
state <= S2;
end
else
begin
Atemp <= 0;
O <= Otemp;
C <= C + 1;
state <= S2;
end
S2: begin
O <= Otemp;
if (C == 3)
state <= S3;
else
state <= S2;
end
S3: begin
Done <= 1;
state <= S0;
end
default
state <= S0;
endcase
fulladder (Atemp, O, Otemp);
end
endmodule
module my_multiplier_tb;
reg clk_tb;
reg [7:0]A_tb, B_tb;
reg Rst_tb, Ld_tb;
wire [15:0] O_tb;
my_multiplier dut( Rst_tb, Ld_tb, clk_tb, A_tb, B_tb, O_tb );
always #5 clk_tb = ~clk_tb;
initial begin
A_tb = 8'd8;
B_tb = 8'd7;
#15 Ld_tb = 1; // set Load to begin multiplication
#10 Ld_tb = 0; // wait 1 clock cycle
#300
$monitor($time, "\t A=%d,\t B=%d,\t O=%d", A_tb, B_tb, O_tb);
$finish;
end
endmodule
The problem is in the my_multiplier module where you have multiple syntax errors. If you sign up for a free account on edaplayground and post your code there, you may see more helpful compile errors there.
You must not place a module instance inside an always block. These 2 lines must be moved outside the always:
fulladder (Atemp, O, Otemp);
shifter ( A, C, Atemp);
Once you do that, you need to add instance names, like i0 and i1 below:
fulladder i0 (Atemp, O, Otemp);
shifter i1 ( A, C, Atemp);

Why is the timer output unknown?

I just started building up-count timer in Verilog, and I keep getting unknown as output.
I'm using 50MHz osciliator and these variables for the code:
min : sec : 1/100 sec
a b : c d : e f
For example, I want the timer to be:
00:00:99 > 00:01:00
...
00:59:99 > 1:00:00
module timer (clk,
a,
b,
c,
d,
e,
f,
count);
input clk;
input [18:0]count;
output reg[3:0]a;
output reg[3:0]b;
output reg[3:0]c;
output reg[3:0]d;
output reg[3:0]e;
output reg[3:0]f;
always#(posedge clk)
begin
if (f == 4'b1010) f = 4'b0000;
else if (count == 19'd500000) f = f+4'b0001;
end
always#(posedge clk)
begin
if (e == 4'b1010) e = 4'b0000;
else if (f == 4'b1010) e = e +4'b0001;
end
always#(posedge clk)
begin
if (d == 4'b1010) d = 4'b0000;
else if (e == 4'b1010) d = d +4'b0001;
end
always#(posedge clk)
begin
if (c == 4'b1010) c = 4'b0000;
else if (d == 4'b1010) c = c +4'b0001;
end
always#(posedge clk)
begin
if (b == 4'b1010) b = 4'b0000;
else if (c == 4'b0101) b = b +4'b0001;
end
always#(posedge clk)
begin
if (a == 4'b1010) a = 4'b0000;
else if (c == 4'b1010) a = a +4'b0001;
end
endmodule
< test bench >
`timescale 1ns / 1ps
module tb_timer();
parameter clk_period = 10;
parameter N = 19;
reg clk;
reg [N-1:0]count;
wire [3:0]a;
wire [3:0]b;
wire [3:0]c;
wire [3:0]d;
wire [3:0]e;
wire [3:0]f;
//instatiate the module
timer U0(
.count(count),
.clk(clk),
.a(a),
.b(b),
.c(c),
.d(d),
.e(e),
.f(f));
// clk signal
always begin
clk =0;
forever #(clk_period/2)clk = ~clk;
end
// count signal
always begin
f = 1'b0
count = 1'b0;
forever #clk_period count = ~count;
end
//reset signal
initial begin
reset = 1;
#12 reset = 0;
#(clk_period) reset = 0;
end
endmodule
Assuming you declared f as wire in the testbench and connected it to the f output of timer, my simulator gives me a compile error on this line:
f = 1'b0;
It is illegal to drive a wire with a procedural assignment.
Your instinct is correct; you need to initialize f. It is declared as reg inside timer, which means that it initializes to X.
This is typically done by adding a reset input signal to your design which you drive from your testbench. Assert the reset for the first few clock cycles, then release it. You should probably reset all your registers in the design.
always#(posedge clk or posedge reset)
begin
if (reset) f = 4'b0000;
else if (f == 4'b1010) f = 4'b0000;
else if (count == 19'd500000) f = f+4'b0001;
end
These are the Verilog code that worked.
Thank you for the help!
module timer (clk,
reset,
a,
b,
c,
d,
e,
f,
count);
input clk;
input reset;
input [18:0]count;
output reg[3:0]a;
output reg[3:0]b;
output reg[3:0]c;
output reg[3:0]d;
output reg[3:0]e;
output reg[3:0]f;
always#(posedge clk or negedge reset)
begin
if (~reset) f <= 4'b0000;
else if (f == 4'b1010) f <= 4'b0000;
else if (count == 19'd500000) f <= f + 4'b0001;
end
always#(posedge clk or negedge reset)
begin
if (~reset) e <= 4'b0000;
else if (e == 4'b1010) e <= 4'b0000;
else if (f == 4'b1010) e <= e +4'b0001;
end
always#(posedge clk or negedge reset)
begin
if (~reset) d <= 4'b0000;
else if (d == 4'b1010) d <= 4'b0000;
else if (e == 4'b1010) d <= d +4'b0001;
end
always#(posedge clk or negedge reset)
begin
if (~reset) c <= 4'b0000;
else if (c == 4'b1010) c <= 4'b0000;
else if (d == 4'b1010) c <= c +4'b0001;
end
always#(posedge clk or negedge reset)
begin
if (~reset) b <= 4'b0000;
if (b == 4'b1010) b <= 4'b0000;
else if (c == 4'b0101) b <= b +4'b0001;
end
always#(posedge clk or negedge reset)
begin
if (~reset) a <= 4'b0000;
if (a == 4'b1010) a <= 4'b0000;
else if (b == 4'b1010) a <= a +4'b0001;
end
endmodule
// <test bench>
`timescale 1ns / 1ps
module tb_timer();
parameter clk_period = 10;
parameter N = 19;
reg clk;
reg [N-1:0]count;
reg reset;
wire [3:0]a;
wire [3:0]b;
wire [3:0]c;
wire [3:0]d;
wire [3:0]e;
wire [3:0]f;
//instatiate the module
timer U0(
.reset(reset),
.count(count),
.clk(clk),
.a(a),
.b(b),
.c(c),
.d(d),
.e(e),
.f(f));
//reset signal
initial begin
reset = 1;
#13 reset = 0;
#(clk_period)reset =1;
end
// clk signal
always begin
clk =0;
forever #(clk_period/2)clk = ~clk;
end
// count signal
always begin
count = 0;
forever #(clk_period/5)count = count + 19'b0000000000000000001;
end
//reset signal
initial begin
reset = 1;
#12 reset = 0;
#(clk_period) reset = 0;
end
endmodule
< Things that I've missed >
The initial value of Flip Flop must be set only when there is reset input.
In testbench, counter should be
// count signal
always begin
count = 0;
forever #(clk_period/5)count = count + 19'b0000000000000000001;
end
The initial block is only executed once and it doesn't synthesis as hardware.

D Flip Flop Verilog Behavioral Implementation has compile errors

I have a d flip flop tutorial, and when I try to compile, some errors occur. I've taken this tutorial from technobyte.org, and anything changed, but it doesn't work. D Flip Flop and Test Bench Code is below.
Can you find the problem?
D Flip Flop
module D_Flip_Flop(d,clk,clear,q,qbar);
input d, clk, clear;
output reg q, qbar;
always#(posedge clk)
begin
if(clear== 1)
q <= 0;
qbar <= 1;
else
q <= d;
qbar = !d;
end
endmodule
Test Bench for D Flip Flop
//test bench for d flip flop
//1. Declare module and ports
module dff_test;
reg D, CLK,reset;
wire Q, QBAR;
//2. Instantiate the module we want to test. We have instantiated the dff_behavior
D_Flip_Flop dut(.q(Q), .qbar(QBAR), .clear(reset), .d(D), .clk(CLK)); // instantiation by port name.
//3. Monitor TB ports
$monitor("simtime = %g, CLK = %b, D = %b,reset = %b, Q = %b, QBAR = %b", $time, CLK, D, reset, Q, QBAR);
//4. apply test vectors
initial begin
clk=0;
forever #10 clk = ~clk;
end
initial begin
reset=1; D <= 0;
#100; reset=0; D <= 1;
#100; D <= 0;
#100; D <= 1;
end
endmodule
Errors
There are 3 types of syntax errors in your code:
You need begin/end around multiple statements in your if/else.
The $monitor statement should be inside an initial block.
Verilog is case-sensitive. clk was not declared. Change all CLK to clk.
You should report these errors to the person who created that tutorial.
Here is code that compiles cleanly for me. I also added proper indentation to your DFF:
module D_Flip_Flop(d,clk,clear,q,qbar);
input d, clk, clear;
output reg q, qbar;
always#(posedge clk) begin
if(clear== 1) begin
q <= 0;
qbar <= 1;
end else begin
q <= d;
qbar = !d;
end
end
endmodule
module dff_test;
reg D, clk,reset;
wire Q, QBAR;
//2. Instantiate the module we want to test. We have instantiated the dff_behavior
D_Flip_Flop dut(.q(Q), .qbar(QBAR), .clear(reset), .d(D), .clk(clk)); // instantiation by port name.
//3. Monitor TB ports
initial $monitor("simtime = %g, clk = %b, D = %b,reset = %b, Q = %b, QBAR = %b", $time, clk, D, reset, Q, QBAR);
//4. apply test vectors
initial begin
clk=0;
forever #10 clk = ~clk;
end
initial begin
reset=1; D <= 0;
#100; reset=0; D <= 1;
#100; D <= 0;
#100; D <= 1;
end
endmodule
Good coding practice recommends using nonblocking assignments for sequential logic. Change:
qbar = !d;
to
qbar <= !d;

Designed a D FF using Strucural Verilog but the Q output is showing up as 'Z'

I want it to show the output of the flip flop but instead it lists the output as 'Z'. How can I get it to do this?
Code:
module d_flip_flop_edge_triggered(Q, Qn, C, D);
output Q;
output Qn;
input C;
input D;
wire Q;
wire Qn;
wire Cn;
wire Cnn;
wire DQ;
wire DQn;
not(Cn, C);
not(Cnn, Cn);
endmodule
This is the test bench - I think the problem lies here.
TestBench:
module ffTB;
// Inputs
reg C;
reg D;
// Outputs
wire Q;
wire Qn;
// Instantiate the Unit Under Test (UUT)
d_flip_flop_edge_triggered uut (
.Q(Q),
.Qn(Qn),
.C(C),
.D(D)
);
initial begin
// Initialize Inputs
C = 0;
D = 0;
// Wait 100 ns for global reset to finish
#100;
C = 1;
D = 1;
#100;
C = 0;
#100;
C = 1;
#100;
C = 0;
#100;
C = 1;
#100;
C = 0;
end
endmodule
Thank you my grade depends on it!
Your model for the flip-flop is completely wrong. (Sorry, but it's true.) With the exception of the input C, none of the inputs or outputs are connected to anything! As a result, the testbench shows that the outputs are floating, which is denoted by the value Z.
Your D flip-flop RTL,
module d_flip_flop_edge_triggered( output reg Q,
output wire Qn,
input wire clk,
input wire rst_n,
input wire D
);
always # (posedge clk or negedge rst_n)
begin
if (~rst_n)
begin
Q <= 1'b0;
end
else
begin
Q <= D;
end
end
assign Qn = ~Q;
endmodul
And Testbench,
module ffTB;
reg clk;
reg rst_n;
reg D;
wire Q, Qn;
d_flip_flop_edge_triggered d_flip_flop_edge_triggered_inst (Q, Qn, clk, rst_n, D);
initial
begin
clk = 1'b0;
rst_n = 1'b0;
D = 1'b0;
#10 rst_n = 1'b1;
#600 $finish;
end
always clk = #5 ~clk;
initial
begin
repeat (100)
begin
D = $random;
#5;
end
end
endmodule
with simulation,

Modelsim Testbench not generating console output

I've designed a unit for my homework here,
module homework1(a, b, sel, y);
input signed [7:0] a, b;
input [1:0] sel;
output reg signed [7:0] y;
always #(a or b or sel) begin
case (sel)
2'b00: y = a + b;
2'b01: y = a - b;
2'b10: y = (a > b) ? a : b;
2'b11: y = (a > b) ? b : a;
endcase
end
endmodule
I've designed a pretty simple testbench file to run with Modelsim here,
module testbench();
reg signed [7:0] a, b;
reg [1:0] sel;
wire signed [7:0] y;
homework1 target(a, b, sel, y);
initial begin
$display("Hello!");
$monitor($time, "a = %d, b = %d, sel = %b, y = %d", a, b, sel, y);
#10 sel = 0; a = 32; b = 25;
#10 a = 46; b = 0;
#10 a = 18; b = 52;
#10 a = 37; b = 37;
#10 a = 37; b = 37;
#10 $stop;
end
endmodule
I used Modelsim to run the test bench, and while the waveform came out as expected, but not the text output. Any ideas?
It seems to work in older version of Modelsim. I'm using 10.3d now. Any settings that might cause this?
Try running your simulations with the -displaymsgmode=both optional argument. The messages may be hidden from your transcript because displaymsgmode is set to wlf.
See the modelsim manual on page 581 for more information.

Resources