Why is my counter out value producing StX? - verilog

I made a simple counter that goes to 32 and a testbench for it. I'm not sure why the value for the output (co) is still coming out as StX. I've been trying to debug this for many hours now and I'm not sure of the issue.

co is X (unknown) because it is a continuous assignment to an expression dependent on current, which is X. current is X because you declared it as a reg, and reg types default to X at time 0, and then you never assign it to a known value.
Your testbench always drives rst as 0. This means line 8 is never executed. Line 10 will be executed at every rising clk edge, but current will remain at X. X+1 returns X.
You need to reset your design properly. At time 0, you should assert the reset by setting rst=1. After a delay, you should release the reset setting rst=0.
initial begin
clk = 0;
rst = 1; // Assert reset
#20;
rst = 0; // Release reset
#10;
en = 1;
init = 1;
end

The reset of you counter is active high. You never set it to 1. You need to set it to 1 for at least one clock cycle.

Related

Proper way to synchronize two state machines with slightly skewed clock in Verilog

I am implementing a receiver for an ADC in Verilog. One sample is obtained after each 21st clock cycle.
The receiver generates the control signals as well as a duty cycled sampling clock for the ADC. The ADC sends the data back sequentially but in order to account for delay, it also sends back a skew matched copy of the duty cycled sampling clock. This clock is to be used to clock in the data.
The code should work for zero delay between the two clocks as well as larger delays. (But the delay won't be larger than a few clock cycles).
I do not know the best way to do this because:
Synthesis prohibits that variables are written in different always #(posedge...) blocks with (possibly) different clocks.
The part that clocks in the data does not have a real clock (it is duty-cycled!) so it cannot maintain a state on its own. It somehow needs to obtain the information in which cycle it is from the controlling FSM
Once the sampled value has been read, it needs to be transferred back to the original, un-skewed clock domain for further processing.
This shows a minimal example of my approach:
// Used to synchronize state between domains
reg sync_cnv = 0; // toggled by TX side when new sampling cycle starts
reg sync_sdo = 0; // synchronized by the RX side
reg reset_rx = 0; // Notify RX side of a global reset
reg reset_rx_ack = 0; // acknowledgement thereof
reg [4:0] state = 0;
reg [4:0] nextState = 0;
always #(posedge clk) begin
if (reset == 1) begin // global reset
state <= 0;
sync_cnv <= 0;
reset_rx <= 1;
end else begin
state <= nextState;
// new sampling cycle starts. Inform RX logic
if (state == 0) begin
sync_cnv <= ~sync_cnv;
end
// If RX acknowledges the reset, we can turn if off again
if (reset_rx_ack == 1) begin
reset_rx <= 0;
end
end
end
// Normally, would generate all kinds of status/control signal for the ADC here
always #(*) begin
if (state == 20) begin
nextState = 0;
end else begin
nextState = state + 1;
end
end
The state is just implemented as a 21-state counter variable state and nextState
When state if zero, a new sampling interval begins. The receiver logic (see below) will recognize this by the fact that sync_cnv changes.
On global reset, the FSM is brought into a known state. Furthermore, reset_rx is set to 1 to notify the receiver logic (see below) about the reset. It stays at 1 until it is acknowledged (reset_rx_ack).
The receive logic:
reg [14:0] counter = 0; // just for dummy data. Increments every sample interval
reg sampling_done = 0; // raised when sampling is done
reg [15:0] cbuf; // holds data during data reception
always #(posedge rxclk) begin
if ( reset_rx == 1) begin
reset_rx_ack <= 1;
sync_sdo <= sync_cnv;
counter <= 0;
end else begin
reset_rx_ack <= 0;
if (sync_cnv != sync_sdo) begin
// A new sampling interval begins
sync_sdo <= sync_cnv;
counter <= counter + 1;
sampling_done <= 1;
data <= cbuf;
end else begin
// normal operation
cbuf <= counter;
sampling_done <= 0;
end
end
end
// synchronize "sampling_done" back to the unskewed clock.
// if data_valid, then data can be read the next cycle of clk
always #(posedge clk) begin
r1 <= sampling_done; // first stage of 2-stage synchronizer
r2 <= r1; // second stage of 2-stage synchronizer
r3 <= r2; // edge detector memory
end
assign data_valid = (r2 && !r3); // pulse on rising edge
This code works flawlessly in simulation (with and without skew). It also works on the FPGA most of the time. However, the data value after a reset is not predictable: Mostly the data starts with 0 (as expected) but sometimes with 1 and or an arbitrary number (probably from the last cycle before the reset).
Using a NRZ signal between clock domains is a known method. But you do not have a real synchroniser. To safely go between clocks you need two registers and a third one for edge detection:
// Clock domain 1:
nrz <= ~nrz;
// Clock domain 2:
reg nrz_meta,nrz_sync,nrz_old;
....
nrz_meta <= nrz;
nrz_sync <= nrz_meta;
// nrz_sync is the signal you can safely use!
// Do NOT use nrz_sync ^ nrz_meta, it is not reliable!
nrz_old <= nrz_sync; // required to 'find' an edge
if (nrz_old ^ nrz_sync)
begin
// Process data
....
On a reset you set all registers to zero. That way you do not have a 'false' sample at the start. It is simplest to have the same asynchronous reset in all clock domains. Dealing with resets in clock domains is a rather (big) subject which would take an A4 page to tersely explain. In your case nothing happens for 21 clock cycles so you are safe.
Alternative is to use a standard asynchronous FIFO to transfer data between clock domains. It is the best solution if your clocks are totally independent (that is either clock can be slower or faster then the other one)
I am sure you can find code for it on the WWW.
An asynchronous FIFO in the other direction can be used to send control information to your ADC.

How to give a delay of 1 clock cycle in a combinational block verilog

I have a combinational code that I have, In that code I would like to turn off a signal after 1 clock cycle, i.e. initially it is 1, and after one clock cycle it should be 0. Is there any way I can do it and if possible it should be able to synthesize on an FPGA.
The code is as follows:
always#(ao or bo or co or dod or eo or fo or go or ho)
begin
temp_out = {ho,go,fo,eo,dod,co,bo,ao};
out_flag = 1;
//after one clock cycle it should go to 0 ;
//help is required over here
out_flag = 0;
end
You cannot do it in a pure combinational synthesizable manner. You need a flop (which is synthesizable) and a reset to set the signal to a know value, say to 0. So, you can delay 1 clock cycle after reset as the following:
always #(posedge clk) begin
if (reset)
out_flag <= 0;
else
out_flag <= 1;
end
you need to figure out exact timing and use correct number of flops for you particular situation. You might want to have an asynchronous reset versus synchronous as in the above example.

What is the difference between using an initial block vs initializing a reg variable in systemverilog?

What is the difference between the following two examples with regards to simulation?
A)
reg a;
initial a = 1'b0;
and
B)
reg a = 1'b0;
Is it different for logic variables?
The difference is initialization as part of a variable declarations execute before any process started by any initial or always constructs. If you wrote:
bit clk;
initial clk = 1;
always #5 clk++;
always #(posedge clk) ...;
There is a race condition as to whether the #(posedge clk) gets triggered at time 0 or time 10.
However with:
bit clk = 1;
always #5 clk++;
always #(posedge clk) ...;
There is no race with the above. The first posedge will come at 10 time units.
The end result is the same, i.e., there won't be any difference from the end user perspective. The difference is that in the first case you are assigning the value during run time, and in the second case you are assigning the value during compile time.
There is an important distinction: You have tagged your question "verilog" and "system-verilog". Which do you mean? The answer depends on which you mean because the behaviour is different in both.
In verilog:
Both
reg a;
initial a = 1'b0;
and
reg a = 1'b0;
will behave the same way. In both cases, a will be initialised at time 0, ie at run time. This can lead to simulation races and non-deterministic behaviour. For example:
reg a;
initial a = 1'b1;
initial $display(a);
might display 0 or might display 1 - there is a race between the initial blocks. And exactly the same thing will happen with this code:
reg a = 1'b1;
initial $display(a);
In system-verilog:
reg a;
initial a = 1'b0;
and
reg a = 1'b0;
will behave differently. In the first case, a will be initialised at time 0, ie at run time which again can lead to simulation races and non-deterministic behaviour. However, there is no such problem with this code:
reg a = 1'b1;
initial $display(a);
In this case, a will be initialised at compile time and therefore there is no race and therefore 1 will always be displayed.
Variable initialization is done before any other procedural block execution.
As per system Verilog LRM 1800-2012, Topic 6.8
A variable can be declared with an initializer, for example:
int i = 0;
Setting the initial value of a static variable as part of the
variable declaration (including static class members) shall occur
before any initial or always procedures are started (also see 6.21 and
10.5 on variable initialization with static and automatic lifetimes).
On similar note :
int val = 0 ;
int val1 = val + 10 ;
will produce a consistent result as the result is fixed at compile time , where as
initial val = 0 ;
initial val1 = val + 10;
will produce a inconsistent result [ as the ordering of assignment happens at run time and is simulator dependent ]

Why a delay of 1 clock period in simple counter

Below is a simple 3-bit counter.
When reset(rst) is 0, counter value is "000", else it increments by 1 for rising edge of each clock.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
---------------------------------------------
ENTITY counter IS
PORT (clk : IN STD_LOGIC;
rst : in std_logic;
digit : out std_logic_vector (2 downto 0)
);
END counter;
---------------------------------------------
ARCHITECTURE counter OF counter IS
BEGIN
count: PROCESS(clk,rst)
VARIABLE temp : std_logic_vector(2 downto 0);
BEGIN
IF (clk'EVENT AND clk='1') THEN
if (rst = '1') then
temp := temp + "001";
else
temp := "000";
END IF;
END IF;
digit <= temp;
END PROCESS count;
END counter;
Below is the simulation result I got :
In the result, output is correct. But there is an one clock delay between the time rst = 1 and output='001'. ie counter doesn't increment instantaneously when rst = '1'.
As per my understanding, whenever a change in clk or rst happens, process is executed. So when rst changes from low to high, an event occurs. Process checks if rising edge of clk, YES. Then check if rst = 1, YES. So normally counter has to increment in that clk itself. But it doesn't.
Questions:
Why one clock period delay between reset = 1 and output = 001?
And what is wrong in my understanding?
The most likely cause in that "rst" is generated by a clocked process, clocked by the same "clk" signal.
So "rst" occurs one delta cycle after "clk". When "rst" changes it will wake the process up, but "clk'event" was on the previous delta cycle, therefore the "if" statement will not execute.
On the next clock edge, rst = 1 so the counter works as expected.
Three minor points:
it would be worth naming the reset signal rst_n to make it clearer that it is an
active-low reset!
rst really doesn't need to be in the sensitivity list
there is no need for parentheses around the boolean expressions
(Disclaimer: It's been long time since I programmed in VHDL, so this only answers to generic logic design.)
Anyway, one can't expect the result of addition to be ready immediately when a process is triggered. The point is, that calculating even the first bit of 000 + 001 is affected by the propagation delay equivalent to one xor operation. The second bit is calculated from the first bit's carry (if both bits were 1) and xor operation of the second bits. And so on.
If one would probe the 'temp' variable asynchronously, one would see something like this:
^ ________________
result_bit_0 __________|
0123456789
_____________
result_bit_1 ^ |____________
0123456789
____________ _____
result_bit_2 ^ |_| |________
0123456789abcde
________
clock: ________| |______|
The figure tries to illustrate in more detail the waveforms of a generic add operation.
At time 0 the process of adding is started.
After a small delay '2' the first bit stabilizes to 1.
At time '5' the second bit stabilizes to 0 and at time '9' the third bit stabilizes to 0.
But also it's quite common, that as in result_bit_2, the output toggles between various states.
It's the total / maximum delay of each temporary variable to take to stabilize, that determines the minimum clock period. At this case the time instant 'e' is that one, where we have decided that the result of counter increment is available.
Still, from the perspective result (which is a vector), everything happens instantly at the next clock cycle.
the "issue" is in the way you have described your "rst".
The way you did it would result in a "synchronous" reset, i.e. the reset would take effect only after a rising edge of the clock.
In general this is just a matter of coding style/preferences.
I usually prefer asynchronous reset (with maybe a reset synchronizer at top-level to avoid meta-stability when releasing the reset), but there is nothing wrong in adopting a synchronous reset approach.
In case of an asynchronous reset, you would need to change your code to something like this:
PROCESS (clk, rst_n) BEGIN
IF rst_n = '0' THEN
...
ELSIF rising_edge(clk) THEN
...
END IF;
END PROCESS;

How to put a 2 sec counter in a for loop

I want to have a 2 sec counter in my for loop such that there is a gap of 2 seconds between every iteration.I am trying to have a shifting LEDR Display
Code:
parameter n =10;
integer i;
always#(*)
begin
for(i=0;i<n;i=i+1)
begin
LEDR[i]=1'b1;
//2 second counter here
end
end
What is your desired functionality? I assume: shifting which LED is on every 2 seconds, keeping all the other LEDs off? "Sliding LED"...
Also, I am assuming your target is an FPGA-type board.
There is no free "wait for X time" in the FPGA world. The key to what you are trying to do it counting clock cycles. You need to know the clock frequency of the clock that you are using for this block. Once you know that, then you can calculate how many clock rising edges you need to count before "an action" needs to be taken.
I recommend two processes. In one, you will watch rising edge of clock, and run a counter of sufficient size, such that it will roll over once every two seconds. Every time your counter is 0, then you set a "flag" for one clock cycle.
The other process will simply watch for the "flag" to occur. When the flag occurs, you shift which LED is turned on, and turn all other LEDs off.
I think this module implements what Josh was describing. This module will create two registers, a counter register (counter_reg) and a shift register (leds_reg). The counter register will increment once per clock cycle until it rolls over. When it rolls over, the "tick" variable will be equal to 1. When this happens, the shift register will rotate by one position to the left.
module led_rotate_2s (
input wire clk,
output wire [N-1:0] leds,
);
parameter N=10; // depends on how many LEDs are on your board
parameter WIDTH=<some integer>; // depends on your clock frequency
localparam TOP=<some integer>; // depends on your clock frequency
reg [WIDTH-1:0] counter_reg = 0, counter_next;
reg [N-1:0] leds_reg = {{N-1{1'b0}}, 1'b1}, leds_next;
wire tick = (counter_reg == 0);
assign leds = leds_reg;
always #* begin : combinational_logic
counter_next = counter_reg + 1'b1;
if (counter_next >= TOP)
counter_next = 0;
leds_next = leds_reg;
if (tick)
leds_next = {leds_reg[N-2:0], leds_reg[N-1]}; // shift register
end
always #(posedge clk) begin : sequential_logic
counter_reg <= counter_next;
leds_reg <= leds_next;
end
endmodule

Resources