166 lines
5.5 KiB
Coq
166 lines
5.5 KiB
Coq
|
// (C) 2001-2015 Altera Corporation. All rights reserved.
|
||
|
// Your use of Altera Corporation's design tools, logic functions and other
|
||
|
// software and tools, and its AMPP partner logic functions, and any output
|
||
|
// files any of the foregoing (including device programming or simulation
|
||
|
// files), and any associated documentation or information are expressly subject
|
||
|
// to the terms and conditions of the Altera Program License Subscription
|
||
|
// Agreement, Altera MegaCore Function License Agreement, or other applicable
|
||
|
// license agreement, including, without limitation, that your use is for the
|
||
|
// sole purpose of programming logic devices manufactured by Altera and sold by
|
||
|
// Altera or its authorized distributors. Please refer to the applicable
|
||
|
// agreement for further details.
|
||
|
|
||
|
|
||
|
// $Id: //acds/main/ip/sopc/components/primitives/altera_std_synchronizer/altera_std_synchronizer.v#8 $
|
||
|
// $Revision: #8 $
|
||
|
// $Date: 2009/02/18 $
|
||
|
// $Author: pscheidt $
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// File: altera_std_synchronizer_nocut.v
|
||
|
//
|
||
|
// Abstract: Single bit clock domain crossing synchronizer. Exactly the same
|
||
|
// as altera_std_synchronizer.v, except that the embedded false
|
||
|
// path constraint is removed in this module. If you use this
|
||
|
// module, you will have to apply the appropriate timing
|
||
|
// constraints.
|
||
|
//
|
||
|
// We expect to make this a standard Quartus atom eventually.
|
||
|
//
|
||
|
// Composed of two or more flip flops connected in series.
|
||
|
// Random metastable condition is simulated when the
|
||
|
// __ALTERA_STD__METASTABLE_SIM macro is defined.
|
||
|
// Use +define+__ALTERA_STD__METASTABLE_SIM argument
|
||
|
// on the Verilog simulator compiler command line to
|
||
|
// enable this mode. In addition, define the macro
|
||
|
// __ALTERA_STD__METASTABLE_SIM_VERBOSE to get console output
|
||
|
// with every metastable event generated in the synchronizer.
|
||
|
//
|
||
|
// Copyright (C) Altera Corporation 2009, All Rights Reserved
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
`timescale 1ns / 1ns
|
||
|
|
||
|
module altera_std_synchronizer_nocut (
|
||
|
clk,
|
||
|
reset_n,
|
||
|
din,
|
||
|
dout
|
||
|
);
|
||
|
|
||
|
parameter depth = 3; // This value must be >= 2 !
|
||
|
|
||
|
input clk;
|
||
|
input reset_n;
|
||
|
input din;
|
||
|
output dout;
|
||
|
|
||
|
// QuartusII synthesis directives:
|
||
|
// 1. Preserve all registers ie. do not touch them.
|
||
|
// 2. Do not merge other flip-flops with synchronizer flip-flops.
|
||
|
// QuartusII TimeQuest directives:
|
||
|
// 1. Identify all flip-flops in this module as members of the synchronizer
|
||
|
// to enable automatic metastability MTBF analysis.
|
||
|
|
||
|
(* altera_attribute = {"-name SYNCHRONIZER_IDENTIFICATION FORCED_IF_ASYNCHRONOUS; -name DONT_MERGE_REGISTER ON; -name PRESERVE_REGISTER ON "} *) reg din_s1;
|
||
|
|
||
|
(* altera_attribute = {"-name SYNCHRONIZER_IDENTIFICATION FORCED_IF_ASYNCHRONOUS; -name DONT_MERGE_REGISTER ON; -name PRESERVE_REGISTER ON"} *) reg [depth-2:0] dreg;
|
||
|
|
||
|
//synthesis translate_off
|
||
|
initial begin
|
||
|
if (depth <2) begin
|
||
|
$display("%m: Error: synchronizer length: %0d less than 2.", depth);
|
||
|
end
|
||
|
end
|
||
|
|
||
|
// the first synchronizer register is either a simple D flop for synthesis
|
||
|
// and non-metastable simulation or a D flop with a method to inject random
|
||
|
// metastable events resulting in random delay of [0,1] cycles
|
||
|
|
||
|
`ifdef __ALTERA_STD__METASTABLE_SIM
|
||
|
|
||
|
reg[31:0] RANDOM_SEED = 123456;
|
||
|
wire next_din_s1;
|
||
|
wire dout;
|
||
|
reg din_last;
|
||
|
reg random;
|
||
|
event metastable_event; // hook for debug monitoring
|
||
|
|
||
|
initial begin
|
||
|
$display("%m: Info: Metastable event injection simulation mode enabled");
|
||
|
end
|
||
|
|
||
|
always @(posedge clk) begin
|
||
|
if (reset_n == 0)
|
||
|
random <= $random(RANDOM_SEED);
|
||
|
else
|
||
|
random <= $random;
|
||
|
end
|
||
|
|
||
|
assign next_din_s1 = (din_last ^ din) ? random : din;
|
||
|
|
||
|
always @(posedge clk or negedge reset_n) begin
|
||
|
if (reset_n == 0)
|
||
|
din_last <= 1'b0;
|
||
|
else
|
||
|
din_last <= din;
|
||
|
end
|
||
|
|
||
|
always @(posedge clk or negedge reset_n) begin
|
||
|
if (reset_n == 0)
|
||
|
din_s1 <= 1'b0;
|
||
|
else
|
||
|
din_s1 <= next_din_s1;
|
||
|
end
|
||
|
|
||
|
`else
|
||
|
|
||
|
//synthesis translate_on
|
||
|
always @(posedge clk or negedge reset_n) begin
|
||
|
if (reset_n == 0)
|
||
|
din_s1 <= 1'b0;
|
||
|
else
|
||
|
din_s1 <= din;
|
||
|
end
|
||
|
//synthesis translate_off
|
||
|
|
||
|
`endif
|
||
|
|
||
|
`ifdef __ALTERA_STD__METASTABLE_SIM_VERBOSE
|
||
|
always @(*) begin
|
||
|
if (reset_n && (din_last != din) && (random != din)) begin
|
||
|
$display("%m: Verbose Info: metastable event @ time %t", $time);
|
||
|
->metastable_event;
|
||
|
end
|
||
|
end
|
||
|
`endif
|
||
|
|
||
|
//synthesis translate_on
|
||
|
|
||
|
// the remaining synchronizer registers form a simple shift register
|
||
|
// of length depth-1
|
||
|
generate
|
||
|
if (depth < 3) begin
|
||
|
always @(posedge clk or negedge reset_n) begin
|
||
|
if (reset_n == 0)
|
||
|
dreg <= {depth-1{1'b0}};
|
||
|
else
|
||
|
dreg <= din_s1;
|
||
|
end
|
||
|
end else begin
|
||
|
always @(posedge clk or negedge reset_n) begin
|
||
|
if (reset_n == 0)
|
||
|
dreg <= {depth-1{1'b0}};
|
||
|
else
|
||
|
dreg <= {dreg[depth-3:0], din_s1};
|
||
|
end
|
||
|
end
|
||
|
endgenerate
|
||
|
|
||
|
assign dout = dreg[depth-2];
|
||
|
|
||
|
endmodule
|
||
|
|
||
|
|
||
|
|