I have a simple Verilog code for a sequential logic network. It consists of a design and a testbench file; it compiles, but it runs for too long. I'm not sure why; apart from the clk, I didn't put any loops in it. Maybe I have some syntax mistakes using the binary numbers. I ran it using the online EDA Playground software; I didn't try it on Xilinx.
Simulator: Icarus Verilog 0.9.7, compile options: -Wall. "Execution
interrupted or reached maximum runtime."
This is what the log wrote.
Design file:
module hazimodul(
input clk,
input rst,
input ce,
input x,
output z
);
reg[1:0] all;
reg[3:0] y;
reg[0:0] zout;
always#(posedge clk)
begin
if(rst)
begin
zout <= 1'b0;
all <= 2'b00;
y <= 4'b0111;
end
else if(ce)
begin
if(all == 2'b00)
begin
if(x== 1'b0)
zout<=1'b0;
else
all <=2'b01;
end
if(all==2'b01)
begin
zout <= y[3:3];
y <= {y[2:0],y[3:3]};
if (y == 4'b0111)
all <= 2'b10;
end
if(all==2'b10)
begin
if(x == 1'b0)
all <= 2'b00;
end
end
end
assign z = zout;
endmodule
Test file:
module test;
reg clk;
reg rst;
reg x;
reg ce;
// Outputs
wire z;
// Instantiate the Unit Under Test (UUT)
hazimodul uut (
.clk(clk),
.rst(rst),
.x(x),
.ce(ce),
.z(z)
);
initial begin
// Initialize Inputs
clk = 0;
rst = 0;
x=0;
ce=0;
#10;
rst<=1;
#20;
rst<=0;
#30
ce<=1;
#40
x<=1;
#80
x<=0;
#90
x<=1;
end
always #5
clk <=~clk;
endmodule
You need to tell the simulator when to stop running. One way is to use the $finish system task, which you can add to your testbench:
initial #1000 $finish;
Now, the simulation finishes on edaplayground. You can change the #1000 delay to something more meaningful to your design.
Here is an explanation of why your code continues to run. Your testbench has 2 parallel threads: one initial block and one always block. In both threads, you add events to the Verilog event queue. The initial block ends after the last assignment to x.
However, the always block continues to add events to the event queue, so the simulation never ends.
Adding the second initial block with the $finish forces the simulation to end, regardless of the infinite always block.
Related
I am trying to generate a pulse from a signal ext_sample_clk. My design currently has 2 clock signals, clk and ext_sample_clk, which I am generating through a testbench. The following is my simplified code. Besides this, I also have the clk and reset generation logic, which I have not shown for simplicity. I can share those if needed.
module tb;
reg clk;
reg rst;
reg ext_sample_clk;
reg ext_sample_clk_r1;
wire ext_sample_pulse_orig;
//clock gen logic
always
begin
clk = 1'b1;
#5; // 10 ns
clk = 1'b0;
#5;
end
// reset gen logic
initial
begin
rst = 1;
#(100);
rst = 0;
end
// ext_sample_clk logic
always
begin
ext_sample_clk = 1'b1;
#50;
ext_sample_clk = 1'b0;
#50;
end
// register the ext_sample_clk logic, should infer a flip flop
always #(posedge clk) begin
if (rst)
ext_sample_clk_r1 <= 0;
else
ext_sample_clk_r1 <= ext_sample_clk; // lhs doesn't appear to be delayed by 1 clock cycle wrt to rhs
end
assign ext_sample_pulse_orig = ext_sample_clk && !ext_sample_clk_r1;
endmodule
I am expecting to see ext_sample_clk_r1 delayed by one clock pulse compared to ext_sample_clk. But the following is what I observe when I run a simulation on Vivado.
Can anyone explain why I am not seeing a clock cycle delay in ext_sample_clk_r1 with reference to ext_sample_clk. Am I missing something ?
Since you want ext_sample_clk_r1 and ext_sample_clk to be synchronous to the same clock (clk), you need to drive them both off of posedge clk, using nonblocking assignments (<=):
initial begin
ext_sample_clk = 1'b1;
forever begin
repeat (10) #(posedge clk);
ext_sample_clk <= ~ext_sample_clk;
end
end
Here is a running example on edaplayground.
The most probably way of getting the results you see is by using a blocking assignment to ext_sample_clk instead of a non-blocking assignment. Your testbench needs to follow the same rules as if it were part of the design to avoid race conditions. Use a non-blocking assignment or have your testbench apply signals on the opposite edge.
I am struggling to understand why the output flickers between 0 and 1, when the output should constantly remain 0 since the reduction OR gate of 000 is 0 not 1.
When I tried a different bit width, the problem suddenly disappeared. However, I would like to know what is going on rather than relying on randomness for correctness.
project_test .sv
`timescale 1ns/1ns
module project_test
( input logic clk, rst,
input logic in,
output logic [2:0] c
);
logic [2:0] out;
always#(posedge clk or posedge rst) begin
if(rst)
out <= 'b0;
else if(in) begin
if(|out)
out <= 'b0;
end
else
out <= out + 1'b1;
end
assign c = out;
endmodule: project_test
testbench.sv
`timescale 1ns/1ns
module testbench;
logic clk, rst;
logic in;
logic [2:0] c;
project_test project_test(
.clk(clk),
.rst(rst),
.in(in),
.c(c)
);
initial begin
clk = 0;
rst = 1;
in = 0 ;
#30
rst = 0;
#20;
in = 1;
#500;
rst=1;
#100ns;
$stop();
end
always#(clk) begin
#10ns clk <= !clk;
end
endmodule
Simulation output:
RTL viewer:
That is an improper way to generate a clock signal in the testbench. You should not have the clk signal in the sensitivity list because it keeps re-triggerring the always block. Your clock generator potentially adds events to the Verilog event queue, which can cause odd behavior. In fact, when I ran your code on the Cadence simulator, I did not see the clock toggling at all.
This is a more standard way to generate a clock:
always begin
#10ns clk = !clk;
end
You are using a very verbose implementation. Why can't you do something like below.
always#(posedge clk or posedge rst)
begin
if(rst)
out <= 'd0;
else
out <= (in) ? 'd0 : (out + 1'b1);
end
module rff_try_1(q,inp,clk);
input clk,inp;
output q;
reg q;
DFF dff0(q,inp,clk);
endmodule
module DFF(q,inp,clk);
input inp,clk;
output q;
reg q;
always # (posedge clk)begin
if(clk)begin
q=inp;
end
end
endmodule
here I'm using two modules but output is not coming
I'm trying to make two bit right shift register but 1st i have to make one single bit register but even this is not working
There are several mistakes in the code.
1) The line if(clk)begin and relevant end should be removed, posedge clk already describes trigger condition of the flip-flop.
2) A non-blocking assignment (<=) is required for the sequential logic.
The always block should be as follows:
always # (posedge clk) begin
q <= inp;
end
3) Some simulators don't complain, but signal q should be wire in module rff_try_1.
wire q;
Simulation
I simulated the code (after the modifications) on EDA Playground with the testbench below. Used Icarus Verilog 0.9.7 as simulator.
module tb();
reg clk = 1;
always clk = #5 ~clk;
reg inp;
wire q;
rff_try_1 dut(q, inp, clk);
initial begin
inp = 0;
#12;
inp = 1;
#27;
inp = 0;
#24;
inp = 1;
end
initial begin
$dumpfile("dump.vcd"); $dumpvars;
#200;
$finish;
end
endmodule
The signal q is as expected as seen on the waveform.
I'm new to verilog development and am having trouble seeing where I'm going wrong on a relatively simple counter and trigger output type design.
Here's the verilog code
Note the code returns the same result whether or not the reg is declared on the output_signal without the internal_output_buffer
`timescale 1ns / 1ps
module testcounter(
input wire clk,
input wire resetn,
input wire [31:0] num_to_count,
output reg [7:0] output_signal
);
reg [31:0] counter;
initial begin
output_signal = 0;
end
always#(negedge resetn) begin
counter = 0;
end
always#(posedge clk) begin
if (counter == num_to_count) begin
counter = 0;
if (output_signal == 0) begin
output_signal = 8'hff;
end
else begin
output_signal = 8'h00;
end
end
else begin
counter = counter + 1;
end
end
assign output_signal = internal_output_buffer;
endmodule
And the code is tested by
`timescale 1ns / 1ps
module testcounter_testbench(
);
reg clk;
reg resetn;
reg [31:0] num_to_count;
wire [7:0] output_signal;
initial begin
clk = 0;
forever #1 clk = ~clk;
end
initial begin
num_to_count = 20;
end
initial begin
#7 resetn = 1;
#35 resetn = 0;
end
testcounter A1(.clk(clk),.resetn(resetn),.num_to_count(num_to_count),.output_signal(output_signal));
endmodule
Behavioral simulation looks as I expected
But the timing simulation explodes
And for good measure: the actual probed execution blows up and looks like
Any tips would be appreciated. Thanks all.
The difference between the timing and functional simulations is that a timing simulation models the actual delay of logic gates while the functional simulation just checks if values are correct.
For e.g. if you have a simple combinational adder with two inputs a and b, and output c. A functional simulation will tell you that c=a+b. and c will change in the exact microsecond that a or b changes.
However, a timing simulation for the same circuit will only show you the result (a+b) on c after some time t, where t is the delay of the adder.
What is your platform? If you are using an FPGA it is very difficult to hit 500 MHz. Your clock statement:
forever #1 clk = ~clk;
shows that you toggle the clock every 1ns, meaning that your period is 2ns and your frequency is 500MHz.
The combinational delay through FPGA resources such as lookup tables, multiplexers and wire segments is probably more than 2ns. So your circuit violates timing constraints and gives wrong behaviour.
The first thing I would try is to use a much lower clock frequency, for example 100 MHz and test the circuit again. I expect it to produce the correct results.
forever #5 clk = ~clk;
Then to know the maximum safe frequency you can run at, look at your compilation reports in your design tools by running timing analysis. It is available in any FPGA CAD tool.
Your code seems working fine using Xilinx Vivado 14.2 but there is only one error which is the following line
assign output_signal = internal_output_buffer;
You can't assign registers by using "assign" and also "internal_output_buffer" is not defined.
I also personally recommend to set all registers to some values at initial. Your variables "resetn" and "counter" are not assigned initially. Basicly change your code like this for example
reg [31:0] counter = 32'b0;
Here is my result with your code:
Your verilog code in the testcounter looks broken: (a) you're having multiple drivers, and (b) like #StrayPointer notices, you're using blocking assignments for assigning Register (Flip-Flop) values.
I'm guessing your intent was the following, which could fix a lot of simulation mismatches:
module testcounter
(
input wire clk,
input wire resetn,
input wire [31:0] num_to_count,
output reg [7:0] output_signal
);
reg [31:0] counter;
always#(posedge clk or negedge resetn) begin
if (!resetn) begin
counter <= 0;
end else begin
if (counter == num_to_count) begin
counter <= 0;
end else begin
counter <= counter + 1;
end
end
end
assign output_signal = (counter == num_to_count) ? 8'hff : 8'h00;
endmodule
I'm trying to create connection from BCD to 7-segment decoder. When I press button UP_* or DOWN_*, it should counting up or counting down. But my simulation only displays 0000001 even when I press button UP or DOWN.
BCD module code:
module BCDcountmod(
input Clock, Clear, up, down,
output reg [3:0] BCD1,
output reg [3:0] BCD0);
//reg [3:0] BCD1_1, BCD0_0;
always #(posedge Clock or negedge Clear) begin
//---- IS IT CLEAR? --------------
if (~Clear) begin
BCD1 <= 'b0;
BCD0 <= 'b0;
end
//---- IS IT UP? --------------
else if (up == 1'b1) begin
if (BCD0 == 4'b1001) begin
BCD0 <= 0;
if (BCD1 == 4'b1001)
BCD1 <= 0;
else
BCD1 <= BCD1 + 1;
end
end
//---- IS IT DOWN? --------------
else if (down==1'b1) begin
if (BCD0 == 4'b0000) begin
BCD0 <= 4'b1001;
if (BCD1 == 4'b0000)
BCD1 <= 4'b1001;
else
BCD1 <= BCD1 - 1;
end
else
BCD0 <= BCD0 - 1;
end
end
endmodule
7-segment module:
module segment7dec (output reg [6:0] display, input [3:0] bcd);
always #* begin
case(bcd)
4'b0000: display = 7'b1111110;
4'b0001: display = 7'b0110000;
4'b0010: display = 7'b1101101;
4'b0011: display = 7'b1111001;
4'b0100: display = 7'b0110011;
4'b0101: display = 7'b1011011;
4'b0110: display = 7'b1011111;
4'b0111: display = 7'b1110000;
4'b1000: display = 7'b1111111;
4'b1001: display = 7'b1111011;
default: display = 7'b0000000;
endcase
display = ~display;
end
endmodule
My testbench:
module scoreboard_testbench;
// Inputs
reg UP_A;
reg DOWN_A;
reg UP_B;
reg DOWN_B;
reg Reset;
reg CLK;
// Outputs
wire [6:0] disp1A;
wire [6:0] disp0A;
wire [6:0] disp1B;
wire [6:0] disp0B;
// Instantiate the Unit Under Test (UUT)
socreboard_top uut (
.UP_A(UP_A),
.DOWN_A(DOWN_A),
.UP_B(UP_B),
.DOWN_B(DOWN_B),
.Reset(Reset),
.CLK(CLK),
.disp1A(disp1A),
.disp0A(disp0A),
.disp1B(disp1B),
.disp0B(disp0B)
);
initial begin
// Initialize Inputs
UP_A = 0;
DOWN_A = 0;
UP_B = 0;
DOWN_B = 0;
Reset = 1;
CLK = 0;
// Wait 100 ns for global reset to finish
#100;
Reset = 0;
UP_A = 1'b1;
#500
UP_A='b0;
#500
UP_A=1'b1;
#500
DOWN_A=1'b1;
#4000 $finish;
// Add stimulus here
end
always #5 CLK=!CLK;
endmodule
Simulation picture:
Simulation Picture Result-Click Here
Any suggestions?
General entry level debugging procedure
Always run code in simulation before loading it onto a FPGA.
Determiner which module has a bug(s):
Make sure the stimulus for the module matches your intentions.
Make sure the output for a module makes sense for its input.
Step through line-by-line:
Make sure each branch is reachable and executing as intended.
Dump everything in the debug scope into waveform.
Add debug messages using $display.
Add small delays such as #0.1 into the design. This may require changing the time precision of the time scale.
After the potential bug is found:
Correct it and add a note on the same line with a searchable keyword (ex: //FIXED). Run simulation to validate the fix.
If the bug seems resolved. Comment-out (not remove) the debug messages and injected delays. Run simulation again.
Repeat step 4 until all the bugs are resolved.
It is now safe to remove the commented-out messages and delays.
RUN SIMULATION AGAIN!
Hint:
There is one design bug and one potential test bench issue.
The stimulus you are using is not consistent with how you designed your module to work. The problem is in your testbench. Since this is homework I'll let you take it from there.
EDIT: I'm going to assume that the homework deadline has passed. For the benefit of future readers, note that the Verilog module uses an active-low Clear signal that resets everything when it is at a logic 0. The testbench incorrectly assumes an active-high Reset signal, so Reset (and hence Clear) are being held low for almost the entire testbench. There's no way the Verilog module can do anything useful...it's being continuously cleared.
Actually i've already implemented such connection, you could see it in my github project: https://github.com/MossbauerLab/RomChipReader It works not only in simulation but also in hardware (i made short video with demo). You could see my impl of output to 7-seg in https://github.com/MossbauerLab/RomChipReader/blob/master/RomReader/src/address_display.v
don't forget to see testbenches also and it is important to use debouncer (https://github.com/MossbauerLab/RomChipReader/blob/master/RomReader/src/debouncer.v) if you are planning to change codes from buttons.