1`timescale 1ns / 1ps 2/* 3 * This software is Copyright (c) 2016 Denis Burykin 4 * [denis_burykin yahoo com], [denis-burykin2014 yandex ru] 5 * and it is hereby released to the general public under the following terms: 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted. 8 * 9 */ 10 11 12// 2-stage FF synchronizer 13module sync_sig #( 14 parameter INIT = 0, 15 // if input signal is 1-2 clk cycles 16 // and CLK1 is set, result would be 1 cycle long 17 // * if input is longer than 2 cycles, it would produce extra result 18 // * if less than 1 cycle, there might be no result (consider usage of sync_short_sig) 19 parameter CLK1 = 0 20 )( 21 input sig, 22 input clk, 23 //input en, 24 output out 25 ); 26 27 (* SHREG_EXTRACT="NO" *) 28 reg [1:0] ff = {2{INIT[0]}}; 29 assign out = ff[1]; 30 31 if (CLK1) begin 32 33 always @(posedge clk) 34 if (ff[1] ^ INIT[0]) 35 ff[1:0] <= {2{INIT[0]}}; 36 else 37 ff[1:0] <= { ff[0], sig }; 38 39 end else begin // ! CLK1 40 41 always @(posedge clk) 42 ff[1:0] <= { ff[0], sig }; 43 44 end 45 46endmodule 47 48 49// 3-stage FF synchronizer 50module sync_sig3( 51 input sig, 52 input clk, 53 output out 54 ); 55 56 (* SHREG_EXTRACT="NO" *) 57 reg [2:0] ff = 0; 58 assign out = ff[2]; 59 60 always @(posedge clk) 61 ff[2:0] <= { ff[1:0], sig }; 62 63endmodule 64 65/* 66// For synchronizing short-duration signals (less than clk cycle), 67// 2-stage FF synchronizer is prepended with async register 68module sync_short_sig #( 69 parameter INIT = 0, 70 parameter CLK1 = 0 71 )( 72 input sig, 73 input clk, 74 output out 75 ); 76 77 // There's no such registers in Spartan 6 architecture, 78 // with a warning tools produce an equvalent item from 3 parts 79 reg async_r = INIT[0]; 80 81 always @(posedge clk or posedge sig) 82 if (sig) 83 async_r <= ~INIT[0]; 84 else 85 if (out) 86 async_r <= INIT[0]; 87 88 sync_sig #(.INIT(INIT), .CLK1(CLK1)) sync(.sig(async_r), .clk(clk), .out(out)); 89 90endmodule 91*/ 92 93// Any frequency relation between wr_clk and rd_clk 94// 'out' duration is 1 clock cycle (repeats after 'busy' deasserts) 95module sync_pulse ( 96 input wr_clk, 97 input sig, 98 output busy, 99 100 input rd_clk, 101 // 'out' must be OK in terms of metastability 102 output out 103 ); 104 105 reg flag_wr = 0; 106 always @(posedge wr_clk) flag_wr <= flag_wr ^ (sig & ~busy); 107 108 (* SHREG_EXTRACT="NO" *) 109 reg [2:0] sync_rd = 3'b000; 110 always @(posedge rd_clk) sync_rd <= {sync_rd[1:0], flag_wr}; 111 112 (* SHREG_EXTRACT="NO" *) 113 reg [1:0] sync_wr = 2'b00; 114 always @(posedge wr_clk) sync_wr <= {sync_wr[0], sync_rd[2]}; 115 116 assign busy = flag_wr ^ sync_wr[1]; 117 assign out = sync_rd[2] ^ sync_rd[1]; 118 119endmodule 120 121 122// Any frequency relation between wr_clk and rd_clk 123// 'out' duration is 1 clock cycle (repeats after 'busy' deasserts) 124// 3 FFs 125module sync_pulse3 ( 126 input wr_clk, 127 input sig, 128 output busy, 129 130 input rd_clk, 131 // 'out' must be OK in terms of metastability 132 output out 133 ); 134 135 reg flag_wr = 0; 136 always @(posedge wr_clk) flag_wr <= flag_wr ^ (sig & ~busy); 137 138 (* SHREG_EXTRACT="NO" *) 139 reg [3:0] sync_rd = 4'b0000; 140 always @(posedge rd_clk) sync_rd <= {sync_rd[2:0], flag_wr}; 141 142 (* SHREG_EXTRACT="NO" *) 143 reg [2:0] sync_wr = 3'b000; 144 always @(posedge wr_clk) sync_wr <= {sync_wr[1:0], sync_rd[3]}; 145 146 assign busy = flag_wr ^ sync_wr[2]; 147 assign out = sync_rd[3] ^ sync_rd[2]; 148 149endmodule 150 151/* 152// Any frequency relation between wr_clk and rd_clk 153module sync_ack( 154 input wr_clk, 155 input sig, 156 output busy, // asserts on the next cycle 157 158 input rd_clk, 159 output out, 160 input done 161 ); 162 163 reg flag_wr = 0; 164 always @(posedge wr_clk) flag_wr <= flag_wr ^ (sig & ~busy); 165 166 (* SHREG_EXTRACT="NO" *) 167 reg [2:0] sync_rd = 3'b0; 168 always @(posedge rd_clk) 169 if (~out | done) 170 sync_rd <= {sync_rd[1:0], flag_wr}; 171 172 (* SHREG_EXTRACT="NO" *) 173 reg [1:0] sync_wr = 2'b0; 174 always @(posedge wr_clk) 175 if (out | done | done_r) 176 sync_wr <= {sync_wr[0], sync_rd[2]}; 177 178 assign out = sync_rd[2] ^ sync_rd[1]; 179 assign busy = flag_wr ^ sync_wr[1]; 180 181 reg done_r = 0; 182 always @(posedge rd_clk) 183 if (out & done) 184 done_r <= 1; 185 else if (done_r) 186 done_r <= 0; 187 188endmodule 189*/ 190/* 191// sig is active for no more than 1 cycle 192module pulse1( 193 input CLK, 194 input sig, 195 output out 196 ); 197 198 reg done = 0; 199 always @(posedge CLK) 200 done <= sig; 201 202 assign out = sig & ~done; 203 204endmodule 205*/ 206 207