my 2x4 decoder code:
`timescale 1ns/100ps
module decoder(in,out);
input [1:0]in;
output [3:0]out;
reg [3:0]out;
always#(in)
begin
case(in)
2'b00:out = 4'b0001;
2'b01:out = 4'b0010;
2'b10:out = 4'b0100;
2'b11:out = 4'b1000;
default:out = 4'b1111;
endcase
end
endmodule
// **I have written behavior code for 2x4 decoder and test bench. What I am seeing in my output is only it is showing me the output at 11...which is 0011. I want to see output changing continuously whenever my input is changing.
can any body show my mistake ??**
piece of code//
`timescale 1ns / 100ps
module decoder_t;
reg [1:0]in;
wire [3:0] out;
decoder decoder1 ( .in(in),.out(out) );
initial
begin
#10 in=2'b00;
#10 in=2'b01;
#10 in=2'b10;
#10 in=2'b11;
#10 $stop;
end
endmodule
The Verilog runs as expected. Best guess is the user is observing the value of in and out at $stop and not before. My recommendation is to add a $monitor statement to report the value changes.
For example, add $monitor("%t: in:%b out:%b", $realtime, in, out); just before #10 in=2'b00; in the test bench. Then the log file will include the following:
0: in:xx out:xxxx
100: in:00 out:0001
200: in:01 out:0010
300: in:10 out:0100
400: in:11 out:1000
Update: waveform dumping
Assuming you are dumping to a standard value change dump (VCD) file as defined in all version of IEEE Std 1364 and IEEE Std 1800. Add $dumpfile("dump.vcd"); $dumpvars; before driving the stimulus (i.e. just before #10 in=2'b00;). Refer to IEEE Std 1364-1995 section 15 (section 18 for newer version of IEEE 1364), or IEEE Std 1800-2012 (available for free from IEEE) section 21.7, to see usage of all $dump* system tasks.
If you are using a different tool for waveform generation, then refer to the manual. 97% chance the placement of the system task(s) will need to be called before driving the stimulus, just like $dumpvars and $monitor.
Related
In my textbook there is a side note that input or inout ports can never be a reg, as this will result in perpetual 'x' in the port. However, when I wrote a code for AND gate with input ports set as reg types, it worked fine.
AND GATE:
//AND Gate
`timescale 1ns/100ps
module test(output C, input reg A,B);
assign C = A & B;
endmodule
Test Bench:
//AND GATE TEST BENCH
`timescale 1ns/100ps
module AND_tb;
//Declaring Variables
wire Cwatch;
reg [1:0] stim;
initial begin
#1 stim = 2'b00;
#1 stim = 2'b01;
#1 stim = 2'b10;
#1 stim = 2'b11;
#1 $stop;
end
test AND_1 (
.C(Cwatch),
.A(stim[0]),
.B(stim[1])
);
endmodule
And here is the paragraph from the textbook
You have not told which simulator you use.
But yes, I also noticed that some simulators have no problem with a input defined as 'reg'. I regard it as an idiosyncrasy of the simulator.
However as soon as you try to synthesize it is likely1 to fail.
1: I have yet to find a synthesis tool which accepts input reg it but I have not tried all existing ones.
I am quite new to verilog and active-hdl. I have got a problem and I would appreciate it if someone could advise me on this.
I can't see the waveforms of second layer modules on waveform viewer. More precisely, the signals in submodules show either Z or X.
Please note that I have enabled read/write access through tools/preferences/simulation/ access design object.
For example I am generating a clk in tb module and connect it to clk_mod, trying to see the clk in clk_mod, however for clk it shows only "Z" and for "i" only "X".
`timescale 1ns/100ps
module tb;
reg clk;
clk_mod dut(.clk(clk));
initial
begin
clk = 0;
forever
#5 clk = ~clk;
end
endmodule
module clk_mod (input clk);
reg i;
always #(posedge clk)
begin
i=10;
end
endmodule
I think that your tb is lacking exit from simulation. you should add the following statement to the tb module (as a separate statement):
initial #20 $finish;
This would finish simulation at step 20 and should create waveforms for you, if you use right tools.
Also, you declared i as a single-bit reg, so, you cannot fit '10' in to it. So, your waveform should show toggling clock and a single transaction of 'i' from 'x' to '0'.
I guess you should have declared 'i' as this:
reg [3:0] i;
I have been designing a basic full adder with two half adder modules and trying to test it with a testbench. There are no compile errors, but at the output (Waveform), I get Z and X for Sum and Carry. I am stuck and not sure what next to look at to correct this error.
Any advice in what next steps (or some pointers) to be checked in order to rectify this would be helpful.
Here is the Verilog code for the Full Adder:
module half_adder(x,y,S,C);
input x,y;
output S,C;
xor G1(S,x,y);
and G2(C,x,y);
endmodule
module full_adder(x,y,z,S,C);
input x,y,z;
output S,C;
wire S1,C1,C2;
half_adder HA1(S1,C1,x,y);
half_adder HA2(S,C2,S1,z);
or G3(C,C1,C2);
endmodule
Testbench for the above:
module tb_fulladder;
wire S,C;
reg x,y,z;
full_adder DUT(x,y,z,S,C);
initial
begin
x=1'b0;y=1'b0;z=1'b0;
#50
x=1'b0;y=1'b0;z=1'b1;
#50
x=1'b0;y=1'b1;z=1'b0;
#50
x=1'b0;y=1'b1;z=1'b1;
#50
x=1'b1;y=1'b0;z=1'b0;
#50
x=1'b1;y=1'b0;z=1'b1;
#50
x=1'b1;y=1'b1;z=1'b0;
#50
x=1'b1;y=1'b1;z=1'b1;
end
initial
#500
$finish;
endmodule
Here is the waveform:
You made a mistake in your connections to half_adder. You need to change the order of the port signals. Change:
half_adder HA1(S1,C1,x,y);
half_adder HA2(S,C2,S1,z);
to:
half_adder HA1 (x,y,S1,C1);
half_adder HA2 (S1,z,S,C2);
I discovered this by looking at the waveforms for the internal full and half adder signals.
This is why it is better to use connection-by-name instead of connection-by-position. For example, use:
half_adder HA1 (.x(x), .y(y), .S(S1), .C(C1));
Using this syntax, the port order does not matter. Refer to the free IEEE Std 1800-2012, 23.3.2 Module instantiation syntax.
What I'm trying to do: I wish to count numbers from 0 to hexadecimal F and display these on my FPGA board at different frequencies - my board's clock (CLOCK_50) is at 50 MHz and I wish to alter the frequency/speed of the counting based on two input switches on my board (SW[1:0]).
Verilog Code for top-module & clock divider module:
//top level module
module rate_divider (input CLOCK_50, input [1:0] SW, input [1:0] KEY,output [6:0] HEX0);
//Declare parameters that define the # of clock cycles needed to generate an enable pulse
according to the desired frequency.
parameter FREQ_5MHz = 4'd9; //To divide to 5 MHz we need (10-1) cycles,
//since the pulse needs to start at the 9th cycle.
parameter FULL50_MHz = (4'd1); //The CLOCK_50's Frequency.
//Select the desired parameter based on the input switches
reg [3:0] cycles_countdown;
wire enable_display_count;
wire [3:0] selected_freq;
always #(*)
case (SW)
2'b00: cycles_countdown = FULL50_MHz;
2'b01: cycles_countdown = FREQ_5MHz;
default : cycles_countdown = FULL50_MHz;
endcase
assign selected_freq = cycles_countdown;
//wire that is the output of the display_counter and input to the 7 segment
wire [3:0] hex_value;
// instantiate my other modules
clock_divider_enable freq_divider (.d(selected_freq), .clk(CLOCK_50), .reset(KEY[0]),
.enable(enable_display_count));
display_counter count_hex (.enable(enable_display_count), .clk(CLOCK_50), .hex_out(hex_value), .reset(KEY[1]));
hex_decoder HX0 (.hex_digit(hex_value), .segments(HEX0[6:0]));
endmodule
//the clock_divider sub-circuit.
module clock_divider_enable (input [3:0] d, input clk, reset,
output enable);
reg [3:0] q;
always #(posedge clk)
begin
if (!reset || !q)
q <= d;
else
q <= q - 4'd1;
end
assign enable = (q == 4'h0) ? 1'b1 : 1'b0;
endmodule
ModelSim Code:
vlib work
vlog rate_divider.v
vsim rate_divider
log {/*}
add wave {/*}
#initial reset - using KEY[1:0]. Note: active low synchronous reset.
force {CLOCK_50} 1
force {KEY[0]} 0
force {KEY[1]} 0
run 10ns
#choose 5 MHz as the desired frequency - turn SW[0] high.
force {CLOCK_50} 0 0ns, 1 {10ns} -r 20ns
force {KEY[0]} 1
force {KEY[1]} 1
force {SW[0]} 1
force {SW[1]} 0
run 600ns
Problems I am facing:
Here's the thing - when I don't use the always block to select a parameter, and pass a desired parameter to the wire selected_freq, my simulation works fine - I can see the expected enable pulse.
HOWEVER, if I use the always block, the reg cycles_countdown does get the correct value assigned, BUT for some reason the enable signal is just a red line. When I select my clock_divider_enable module and add it's 'q' signal onto my waveform, it is red too and shows no data, and the object q is "not logged". As such, I'm unable to debug and figure out what exactly the problem with my code is.
It'd be great if someone could help with how to fix the simulation issue rather than just point out the issue with my Verilog code since I want to learn how to use ModelSim efficiently so that in the future debugging will be easier for me.
Equipment Used:
FPGA: Altera De-1-SoC, Cyclone V chip
CAD/Simulation Tools: Altera Quartus II Lite 17.0 + ModelSim Starter Edition
SW wasn't given an initial value, therefore it is high-Z (X if connected to a reg).
I'm guessing when you used the parameter approach you were parameterizing cycles_countdown. Some simulators do not trigger #* at time-0. So if there isn't a change on the senctivity list, then the block may not execute; leaving cycles_countdown as its initial value (4'hX).
Instead of driving your test with TCL commands, you can use create a testbench in with verilog. This testbench should only be used in simulation, not synthesis.
module rate_devider_tb;
reg CLOCK_50;
reg [1:0] SW;
reg [1:0] KEY;
wire [6:0] HEX0;
rate_divider dut( .CLOCK_50(CLOCK_50), .SW(SW), .KEY(KEY), .HEX0(HEX0));
always begin
CLOCK_50 = 1'b1;
#10;
CLOCK_50 = 1'b0;
#10;
end
initial begin
// init input signals
SW <= 2'b01;
KEY <= 2'b00;
// Log file reporting
$monitor("SW:%b KEY:%b HEX0:%h # %t", SW, KEY, HEX0, $time);
// waveform dumping
$dumpfile("test.vcd");
$dumpvars(0, rate_devider_tb);
wait(CLOCK_50 === 1'b0); // initialization x->1 will trigger an posedge
#(posedge CLOCK_50);
KEY <= 2'b01; // remove reset after SW was sampled
#600; // 600ns assuming timescale is in 1ns steps
$finish();
end
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