I'm using this counter as a mux select pins and I need it to start from 0, but in simulation in the first cycle it is starting from 1 and at the next cycle it starts from 0.
module upcounter(clk,reset,out);
input clk,reset;
output reg [2 : 0]out = 3'b000;
always #(posedge clk or posedge reset)
begin
if(reset)
out <= 3'b000;
else
out <= out + 3'b001;
end
endmodule
This is my testbench codes:
module counter_tst;
reg clk;
wire [2 : 0] out;
reg rst;
upcounter u0(clk,rst,out);
initial
clk = 1'b1;
always
#1 clk = ~clk;
initial
begin
rst=0;
end
endmodule
As #Serge says the test bench is important to explain what you are seeing.
Your testbench only ever sets rst to 0, so we can safely ignore the code that is conditioned on reset entirely. No positive edges or values of 1 to worry about.
At time 0 your testbench forces clk to 1. This is treated as a positive edge, as such immediately after that out is incremented to 1. Since you don't have a <= #n delay when you increment out it appears to take effect immediately. With this sort of thing, I find including simulation delays helps debugging.
Consider this version of the code and testbench. I've slowed down the clock ticking by a factor of 10, and inserted a #1 delay in the out value incrementing. I've also removed all the orphaned rst/reset code to focus on the effect you are seeing:
// code.v
module upcounter(clk,out);
input clk;
output reg [2 : 0] out = 3'b000;
always #(posedge clk)
out <= #1 out + 3'b001;
endmodule
module counter_tst;
reg clk;
wire [2 : 0] out;
upcounter u0(clk,out);
initial
begin
clk = 1'b1;
$monitor("time = %0d", $time, " clk = %b out = %d", clk, out);
$dumpvars();
#1000 $finish();
end
always
#10 clk = ~clk;
endmodule
Compile and run it as follows:
$ iverilog code.v
$ ./a.out
VCD info: dumpfile dump.vcd opened for output.
time = 0 clk = 1 out = 0
time = 1 clk = 1 out = 1
time = 10 clk = 0 out = 1
time = 20 clk = 1 out = 1
time = 21 clk = 1 out = 2
time = 30 clk = 0 out = 2
time = 40 clk = 1 out = 2
time = 41 clk = 1 out = 3
< etc >
You should now be able to see that the first increment to out is happening because of the observed posedge clk.
Related
I intended to write and simulate a module performing MAC operation. My code is shown below
module PE # (
parameter DW = 8
)
(
input clk,
input rst_n,
input [DW-1 : 0] cin,
input [DW-1 : 0] w,
output [DW-1 : 0] cin_out,
output [DW-1 : 0] w_out,
output [2*DW : 0] pe_out
);
reg [DW-1 : 0] cin_reg;
reg [DW-1 : 0] w_reg;
reg [2*DW : 0] m_reg;
reg [2*DW : 0] pe_reg;
always #(posedge clk) begin
if(rst_n==1'b0) begin
pe_reg <= 0;
cin_reg <= 0;
w_reg <= 0;
end
else begin
cin_reg <= cin;
w_reg <= w;
m_reg <= cin_reg * w_reg;
pe_reg <= pe_reg + m_reg;
end
end
assign cin_out = cin_reg;
assign w_out = w_reg;
assign pe_out = pe_reg;
endmodule
I used VCS to simulate, however, pe_out kept xxxxxxxx as shown in fig below.
false wave
I have asked my friend to use verilator to simulate, it can work as expected. And if I delete pe_reg <= pe_reg + m_reg, it still works. Therefore, the issue is likely to be caused by the add operation? But I haven't solved it yet.
I'll be appreciate if anyone can give me some instructions. It have confused me for hours.
My tb is written as below.
module tb_PE;
reg clk;
reg rst_n;
reg [7:0] cin;
reg [7:0] w;
wire [7:0] cin_out;
wire [7:0] w_out;
wire [16:0] pe_out;
wire [16:0] pe_out_tmp;
initial begin
clk = 0;
forever begin
#10;
clk = ~clk;
end
end
initial begin
rst_n = 1'b1;
#5;
rst_n = 1'b0;
#10;
rst_n = 1'b1;
#5;
cin = 8'h01;
w = 8'h02;
#15;
cin = 8'h03;
w = 8'h04;
#20;
cin = 8'h05;
w = 8'h03;
#20;
cin = 8'h90;
w = 8'h88;
#20;
cin = 8'h65;
w = 8'h20;
#100;
$finish;
PE PE_U (
.clk(clk),
.rst_n(rst_n),
.cin(cin),
.w(w),
.cin_out(cin_out),
.w_out(w_out),
.pe_out(pe_out)
);
end
As #mkrieger1 mentioned, you have not initialized m_reg. So, the following is happening:
at the first posedge you initialized some of the variables, including pe_reg, while m_reg is still x.
at the second posedge m_reg is still x. Using nonblocking assignment you schedule it to change later, but in this expression pe_reg <= pe_reg + m_reg; it is still x.
as a result, pe_reg becomes x again because m_reg is still x and it will stays same because it is used recursively in the expression.
So, the easiest way to handle it is to initialize m_reg in the same bucket as pe_reg. If for some reason it is not acceptable, you need to delay evaluation of pe_reg for another cycle.
I am not getting any response from the uut in the testbench. The module exp2_up_down_counter works ok without testbench, but gives output as xxxx when instantiated in the testbench.
Here is the main module of the up-down counter:
`timescale 1ns/1ps
module exp2_up_down_counter (input clk, reset, mode, output reg [3:0] count);
always #(posedge clk)
if (reset == 1)
count <= 0; // reset the counter if reset is high
else if (mode == 1)
count <= count + 1; // works as up counter if mode pin is high
else
count <= count - 1; // works as down counter if mode pin is low
endmodule
Simulation without testbench:
Testbench for up-down counter
`timescale 1ns/1ps
module exp2_up_down_counter_tb;
reg clk, reset, mode;
wire [3:0] count;
exp2_up_down_counter uut(.clk(clk), .reset(reset), .mode(mode), .count(count));
initial begin
clk = 1'b0;
end
always #(*) #5 clk <= ~clk;
initial begin
// initializing the inputs
reset = 1;
mode = 0;
#5;
reset = 0;
#10
mode = 1;
#5000 $finish;
end
endmodule
Simulation with testbench:
In exp2_up_down_counter, count is declared as a reg. This means that its default value is X at time 0. Since the reset signal is synchronous to the clock, you need to wait for the 1st posedge of clock before you release the reset. Currently, the reset is released at the 1st posedge of clock in the testbench, which is a race condition. Therefore, count does not get assigned the value of 0, and it retains the value of X for the whole simulation.
You need to delay the reset release. For example, change:
#5;
reset = 0;
to:
#15;
reset = 0;
However, it is better to drive your synchronous inputs in the testbench the same way you drive your signals in the design: using #(posedge clk) and using nonblocking assignments (<=):
initial begin
reset = 1;
mode = 0;
repeat (2) #(posedge clk);
reset <= 0;
repeat (1) #(posedge clk);
mode <= 1;
#5000 $finish;
end
Also, this is a more standard way to drive the clock in the testbench:
always #5 clk = ~clk;
I am trying to create a second clk counter using a 100 MHz clk input, but when I simulate the clk divider, it just shows the output as an X even though the clk input is correct. What could I be doing wrong?
1 second clk divider:
module clkdiv(
input clk,
input [25:0] terminalcount,
output reg clk_div
);
reg [25:0] count;
wire tc;
assign tc = (count == terminalcount);
always # (posedge(clk)) begin
if (tc) count <= 0;
else count <= count + 1;
end
always # (posedge(clk)) begin
if (tc) clk_div = !clk_div;
end
endmodule
Test Bench:
module clockdivTB;
// inputs
reg clk; // make 100 MHz -- T = 10 ns
// outputs
wire newclk;
// second clock -- connect test signals to clkdiv
clkdiv slowclkCUT (
.clk(clk),
.terminalcount(50000000-1), // 1 Hz
.clk_div(newclk)
);
// initialize inputs
initial begin
clk = 0;
// create input clock 100MHz
forever #5 clk = ~clk;
end
endmodule
Result:
The output is X because reg types are initialized to X (unknown). You need to initialize the output to a known value. For simulation purposes, you can set clk_div and count to 0 as follows:
module clkdiv(
input clk,
input [25:0] terminalcount,
output reg clk_div = 0
);
reg [25:0] count = 0;
However, if you want to synthesize your logic, you likely need to add a reset input. You can drive the input from your testbench.
module clkdiv(
input reset,
input clk,
input [25:0] terminalcount,
output reg clk_div
);
reg [25:0] count;
wire tc;
assign tc = (count == terminalcount);
always # (posedge(clk)) begin
if (reset) count <= 0;
else if (tc) count <= 0;
else count <= count + 1;
end
always # (posedge(clk)) begin
if (reset) clk_div <= 0;
else if (tc) clk_div <= !clk_div;
end
endmodule
I have a problem with designing an up-counter. I am trying to implement a Single-cycle MIPS with Verilog, so I am trying to implement a Program counter.
I just need the main idea about how to built a counter and test it. I am new to Verilog, so I don't know where I've gone wrong.
This is my counter.v:
module PC (Clk, CLR, Q);
input Clk, CLR;
output [31:0] Q;
reg [31:0] tmp;
always #(posedge Clk or posedge CLR)
begin
if (CLR)
tmp = 4'b0000;
else
tmp = tmp + 1'b1;
end
assign Q = tmp;
endmodule
And this is my testbench file:
define DELAY 20
module PC_testbench ();
reg clk ;
reg clr ;
wire [31:0] q;
PC exec ( clk , clr , q );
initial clk = 0;
initial clr = 0;
initial begin
clk=~clk;
#`DELAY;
clk=~clk;
#`DELAY;
clk=~clk;
#`DELAY;
clk=~clk;
end
initial begin
$monitor("clk = %b pc_next = %b ",clk , q );
end
endmodule
I got 32 x's as my result. Any ideas?
This is my result:
# clk = 1 pc_next = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# clk = 0 pc_next = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# clk = 1 pc_next = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# clk = 0 pc_next = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Your problem is that counter tmp is initially 32'bx, and it needs to see a rising edge of CLR or be 1 during a rising edge of Clkbefore being reset to 32'b0.
i got a code like below with clk = #10 ~clk
always# (posedge clk)begin
for (g=0;g<8;g=g+1) begin
ws = 1;
#20
ws = 0;
#20;
end
so is there any other way to make the delay 20 synthesizaeble in the coding above?
A flip-flop is the only way of synthesising a delay:
always #(posedge clk)
q <= d;
With clk = #10 ~clk;, q will be #10 later than d.
The question appear not to be how to synthesis a #20 but how to control the timing for signals in to a RAM. Digital design are based around clock edges, with each positive or negative edge a set distance a part, this is the period of the clock or 1/frequency.
To sequence events as you describe you need a FSM (Finite state machine) to control or sequence it. I have included a small example below:
Available on EDA Playground
module tb;
//Tb component
reg clk;
reg rst_n;
initial begin :clk_and_reset
clk = 0;
rst_n = 0;
#40 rst_n = 1;
#40;
forever begin
#20 clk = ~clk;
end
end
//Design
reg [1:0] state;
reg [1:0] next_state;
reg [31:0] counter;
reg ws;
localparam S_IDLE = 'd0;
localparam S_WAIT = 'd1;
localparam S_OFF = 'd2;
always #(posedge clk, negedge rst_n) begin
if (~rst_n) begin
state <= S_IDLE;
end
else begin
case(state)
S_IDLE : begin
state <= S_WAIT;
counter <= 'b0;
S_WAIT :
if (counter < 32'd10) begin
state <= S_WAIT; //Wait for 10 clock cycles
counter <= counter + 1;
end
else begin
state <= S_OFF;
counter <= 'b0;
end
S_OFF : state <= S_IDLE;
default : state <= S_IDLE; //IDLE
end
end
//Output decode based on state
always #* begin
//ws goes high when in Wait state
ws = (state == S_WAIT);
end
//Test program
initial begin
repeat (10) begin
#(posedge clk);
$display("%4t : State %b: ws :%b", $realtime, state, ws);
end
$finish();
end
endmodule
This could be expanded by staying in idle until triggered then by having counter and staying in wait for x number of clocks, x number of clocks in OFF before going back to idle and waiting to be triggered again.
Update
I have updated the code example to stay in the WAIT state for 10 clock cycles to demonstrate how to control the delay between transitions.