Clock Domain Crossing for Pulse and Level Signal - verilog

For pulse we use Pulse-Synchronizer and for Level Signal we use 2-flop synchronizer but what if the signal can be of Pulse or Level behaviour. Is there any way to synchronize that?

Yes, you can but the solution needs to be based on the width of the input pulse relative to the output clock.
When the output clock is very slow, and you have a pulse, you need to add an inline pulse stretcher that operates in the input clock domain. The stretch is defined by the bit width of stretch_out below and "MUST" be greater than one clock on the output clk domain.
reg [3:0] stretch_out;
always # (posedge inclk)
begin
stretch_out <= in_signal ? 4'b1111 : {stretch_out[2:0],1'b0};
end
Now you can just use your double flop synchronizer.
reg [1:0] out_sync;
always # (posedge outclk)
begin
out_sync <= {out_sync[0],stretch_out[3]};
end
This should synchronize a level and pulse from a fast domain into a slow domain.
The only issue, is that you will be adding more than just your usual two flop latency.

You could asynchronously set using the signal in the destination domain, synchronize using dual flops, and then detect the rising edge. Should work for both short pulses and long levels.
// Prevent DRC violations if using scan
wire in_signal_n = scan_mode ? 1'b1 : !signal_in;
// Following code creates a flop with both async setb and resetb
reg sig_n_async;
always # ( posedge outclk or negedge reset_n or negedge in_signal_n)
if (!reset_n)
sig_n_async <= 0;
else if (!in_signal_n)
sig_n_async <= 1;
else
sig_n_async <= 0;
// Synchronizer
reg [1:0] out_sync;
always # (posedge outclk or negedge reset_n)
if (!reset_n)
out_sync <= 0;
else
out_sync <= {out_sync[0],sig_n_async};
// Rising edge
reg out_sync_del;
always # (posedge outclk or negedge reset_n)
if (!reset_n)
out_sync_del <= 0;
else
out_sync_del <= out_sync[1];
wire signal_out = out_sync[1] & !out_sync_del;

Related

Timers and LEDs in Verilog

I have a question about using timers and clocks in Verilog. I want to set up a custom reg to compare to an accumulator, which will control the state of an LED. The board uses inverse logic, so 0 is high on the LED. There are a few concepts I just need some clarification on. The clock is 100 MHz.
always #(posedge clk100 or negedge reset_)
begin
cust_LED_counter <= (cust_LED_counter<cust_LED_timer) ? cust_LED_counter + 1'b1 : 16'd0;
cust_LED_timer1 <= (cust_LED_counter == cust_LED_timer);
if(!reset_)
begin
cust_LED1 <= 'b0;
cust_LED_timer <= 'd0;
cust_LED_timer1 <= 'd0;
end
else
begin
cust_LED1 <= ~cust_LED_timer1;
end
end
For the accumulator, what is the action that resets it and allows for blinking to happen? Would it not hit the cust_LED_timer value and stay at that high reading?
I think I'm misunderstanding how a FPGA clock operates. Assuming this would cause a blinking action in the LED, it would mean some timer hit the upper limit and reset; however, I'm not sure if this would take place in the counter portion of the code, or instead would occur where the clock/reset is defined.
Also, based on how this layout looks it wouldn't be a uniform blink, in terms of equal time on and off. Is there a way to implement such a system for custom input?
Here's a simple module that should blink the LED with a 50-50 duty cycle for an arbitrary number of clocks (up to 2^26)
module blink(input clk, input rst, input [25:0] count_max, output LED);
reg [25:0] counter, next_count;
assign LED = counter < count_max >> 1;
always #(posedge clk or posedge rst)
begin
if (rst)
counter <= 0;
else
counter <= next_count;
end
always #* begin
if (counter < count_max - 1)
next_count = counter + 1;
else
next_count = 0;
end
endmodule // blink
Let me know if this doesn't compile! I don't have a verilog compiler where I'm writing this from at the moment!

ice40 clock delay, output timing analysis

I have an ice40 that drives the clock and data inputs of an ASIC.
The ice40 drives the ASIC's clock with the same clock that drives the ice40's internal logic. The problem is that the rising clock triggers the ice40's internal logic and changes the ice40's data outputs a few nanoseconds before the rising clock reaches the ASIC, and therefore the ASIC observes the wrong data at its rising clock.
I've solved this issue by using an inverter chain to delay the ice40's internal clock without delaying the clock driving the ASIC. That way, the rising clock reaches the ASIC before the ice40's data outputs change. But that raises a few questions:
Is my strategy -- using an inverter chain to delay the ice40 internal clock -- a good strategy?
To diagnose the problem, I used Lattice's iCEcube2 to analyze the min/max delays between the internal clock and output pins:
Notice that the asic_dataX delays are shorter than the clk_out delay, indicating the problem.
Is there a way to get this information from yosys/nextpnr?
Thank you for any insight!
Instead of tinkering with the delays I would recommend to use established techniques. For example SPI simple clocks the data on the one edge and changes them on the other: .
The logic to implement that is rather simple. Here an example implementation for an SPI slave:
module SPI_slave #(parameter WIDTH = 6'd16, parameter phase = 1'b0,
parameter polarity = 1'b0, parameter bits = 5) (
input wire rst,
input wire CS,
input wire SCLK,
input wire MOSI,
output reg MISO,
output wire data_avbl,
input wire [WIDTH-1:0] data_tx,
output reg [WIDTH-1:0] data_rx
);
reg [bits:0] bitcount;
reg [WIDTH-1:0] buf_send;
assign clk = phase ^ polarity ^ SCLK;
assign int_rst = rst | CS;
assign tx_clk = clk | CS;
assign data_avbl = bitcount == 0;
always #(negedge tx_clk or posedge rst) begin
MISO <= rst ? 1'b0 : buf_send[WIDTH-1];
end
always #(posedge clk or posedge int_rst) begin
if (int_rst) begin
bitcount <= WIDTH;
data_rx <= 0;
buf_send <= 0;
end else begin
bitcount <= (data_avbl ? WIDTH : bitcount) - 1'b1;
data_rx <= { data_rx[WIDTH-2:0], MOSI };
buf_send <= bitcount == 1 ? data_tx[WIDTH-1:0] : { buf_send[WIDTH-2:0], 1'b0};
end
end
endmodule
As one can see the data are captured at the positive edge and changed on the negative edge. If one wants to avoid the mixing of edge sensistivies a doubled clock can be used instead.

Why using two flip-flops instead of one in this Verilog HDL code?

This code is a button debouncer.
But I can't understand why there are two flips flops :
reg PB_sync_0; always #(posedge clk) PB_sync_0 <= ~PB; // invert PB to make PB_sync_0 active high
reg PB_sync_1; always #(posedge clk) PB_sync_1 <= PB_sync_0;
Why the autor of this code did not write this ?
reg PB_sync_1; always #(posedge clk) PB_sync_1 <= ~PB;
Here is the full code:
module PushButton_Debouncer(
input clk,
input PB, // "PB" is the glitchy, asynchronous to clk, active low push-button signal
// from which we make three outputs, all synchronous to the clock
output reg PB_state, // 1 as long as the push-button is active (down)
output PB_down, // 1 for one clock cycle when the push-button goes down (i.e. just pushed)
output PB_up // 1 for one clock cycle when the push-button goes up (i.e. just released)
);
// First use two flip-flops to synchronize the PB signal the "clk" clock domain
reg PB_sync_0; always #(posedge clk) PB_sync_0 <= ~PB; // invert PB to make PB_sync_0 active high
reg PB_sync_1; always #(posedge clk) PB_sync_1 <= PB_sync_0;
// Next declare a 16-bits counter
reg [15:0] PB_cnt;
// When the push-button is pushed or released, we increment the counter
// The counter has to be maxed out before we decide that the push-button state has changed
wire PB_idle = (PB_state==PB_sync_1);
wire PB_cnt_max = &PB_cnt; // true when all bits of PB_cnt are 1's
always #(posedge clk)
if(PB_idle)
PB_cnt <= 0; // nothing's going on
else
begin
PB_cnt <= PB_cnt + 16'd1; // something's going on, increment the counter
if(PB_cnt_max) PB_state <= ~PB_state; // if the counter is maxed out, PB changed!
end
assign PB_down = ~PB_idle & PB_cnt_max & ~PB_state;
assign PB_up = ~PB_idle & PB_cnt_max & PB_state;
endmodule
Thanks !
The autor of this code uses 2 flip-flops in order to synchronize PB signal into clk domain.
As he mentioned in a comment "PB" is the glitchy, asynchronous to clk.
Not synchronizing a signal on a clock domain transition may cause metastability in the system, as toolic referenced en.wikipedia.org/wiki/Metastability_in_electronics

Frequency divisor in verilog

i need a frequency divider in verilog, and i made the code below. It works, but i want to know if is the best solution, thanks!
module frquency_divider_by2 ( clk ,clk3 );
output clk3 ;
reg clk2, clk3 ;
input clk ;
wire clk ;
initial clk2 = 0;
initial clk3 = 0;
always # (posedge (clk)) begin
clk2 <= ~clk2;
end
always # (posedge (clk2)) begin
clk3 <= ~clk3;
end
endmodule
the circuit generated by quartus:
Your block divides the frequency by 4 not 2. There is actually quite a good description of this on Wikipedia Digital Dividers. Your code can be tidied up a bit but only 1 D-Type is required, which is smaller than a JK Flip-flop so is optimal.
module frquency_divider_by2(
input rst_n,
input clk_rx,
output reg clk_tx
);
always # (posedge clk_rx) begin
if (~rst_n) begin
clk_tx <= 1'b0;
end
else begin
clk_tx <= ~clk_tx;
end
end
endmodule
When chaining these types of clock dividers together be aware that there is a clk to q latency which is compounded every time you go through one of these dividers. IF this is not managed correctly by synthesis the clocks can not be considered synchronous.
Example on EDAplayground, should open the waveform when run.

gate control clock generation

Here is the code first...
always#(posedge clk)
begin
if(cstate==idle) rclk<=1;
else rclk<=0;
end
always#(negedge clk)
rclk<=0;
What I want to achieve is this: every time at the rising edge of clock signal, if the signal cstate equals idle(4'b0000), the the rclk goes to one, else to zero, at the same time, every time the falling edge of clk will set the rclk to zero. THIS CODE IS NOT SYNTHESIZABLE since the compiler gives the error " the rclk signal is driven by multiple drivers".
How can I achieve the same function by other techniques?
It looks like you want a clock gate cell. Based on a 1 cycle wide enable signal generate a clock pulse which has the same high time as the input clock.
A naive way of doing this might be :
assign rclk = (cstate==idle) ? clk : 1'b0 ;
Which could easily be synthesised assign rclk = (cstate==idle) & clk ;
cstate == idle is going to glitch which is why it would normally be used by a flip-flop allowing the answer to settle before being used.
Using a clock gate cell stops you from creating glitches on the (rclk) clock line. It is common to instantiate your libraries clock gate cell in the rtl for this. In RTL it might be similar to :
reg result;
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
result <= 1'b0;
end
else begin
result <= (cstate == idle);
end
end
assign rclk = (result) ? clk : 1'b0 ;
This means result will be stable for each clock cycle, not allowing glitches through from the comparator.
Expanded answer
I have included my example again below with waveform, I have replaced your state comparison with a simple counter which overflows to reset itself. Not the comparison is matching to 2'b10; which means the clock appears on the following count (2'b11). If the clock was to appear in exactly the same time your comparison matched then you have no glitch suppression on your clock and will likely generate unreliable hardware.
reg [1:0] counter = 0;
always #(posedge clk)
counter <= counter+1;
reg result;
wire result_a = (counter == 2'b10 );
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
result <= 1'b0;
end
else begin
result <= result_a;
end
end
assign rclk = (result) ? clk : 1'b0 ;

Resources