?? clkx_bus.v
字號:
//-----------------------------------------------------------------------------// // Copyright (c) 2008 Xilinx Inc.//// Project : Programmable Wave Generator// Module : clkx_bus.v// Parent : Various// Children : meta_harden.v//// Description: // This module brings a bus of signals across a clock boundary. The // bus must not change more often than once every 8+ destination clocks.// The change of the bus must be accompanied by a "new" signal which is// valid for one source clock cycle//// Parameters:// PW : Minumum pulse length, measured in source clock periods, to// accurately cross between domains. For clock crossings// between similar frequency domains, should be set to 3// WIDTH : Width of the bus to cross//// Notes : // This module is only expected to be used for "infrequently" updating// signals.//// Multicycle and False Paths, Timing Exceptions// The metastibility hardener meta_harden used in this module should have// a tighter timing constraint placed on its internal net.//`timescale 1ns/1psmodule clkx_bus #( parameter PW = 3, parameter WIDTH = 16) ( input clk_src, // Source clock input rst_clk_src, // Reset - synchronous to source clock input clk_dst, // Destination clock input rst_clk_dst, // Reset - synchronous to dest clock input [WIDTH-1:0] bus_src, // Bus input, sync to source clock input bus_new_src, // bus_src has changed this clock output reg [WIDTH-1:0] bus_dst, // Bus output, sync to dest clock output reg bus_new_dst // bus_dst has changed this clock );`include "clogb2.txt"//***************************************************************************// Register declarations//*************************************************************************** reg [clogb2(PW)-1:0] bus_new_cnt_src; // Counts from PW-1 to 0 reg bus_new_stretch_src; // bus_new_src stretched to PW wire bus_new_stretch_dst; // Stretched pulse sync'd to dest reg bus_new_stretch_old_dst; // value on previous clock // for edge detect reg [WIDTH-1:0] bus_samp_src; // Bus input sampled when // bus_new_src is asserted //***************************************************************************// Code//*************************************************************************** // Generate the stretched version of bus_new_src // To assert for PW clocks, we use the one where the bus_src_new is detected // and the PW-1 following clocks. To do that, we count from PW-1 to 0, and // keep the output asserted whenever the counter is not 0 always @(posedge clk_src) begin if (rst_clk_src) begin bus_new_cnt_src <= 0; bus_new_stretch_src <= 1'b0; end else if (bus_new_cnt_src != 0) // If not zero, in a count, so decrement begin bus_new_cnt_src <= bus_new_cnt_src - 1'b1; bus_new_stretch_src <= 1'b1; end else if (bus_new_src) // We have a new pulse to generate begin bus_new_cnt_src <= PW - 1'b1; bus_new_stretch_src <= 1'b1; end else // We didn't see a new one, and we aren't counting a pulse begin bus_new_stretch_src <= 1'b0; end end // always // Sample the incoming bus whenever the "new" signal is asserted to ensure // that we have a stable version of it between assertions of "new" always @(posedge clk_src) begin if (rst_clk_src) begin bus_samp_src <= 0; end else if (bus_new_src) begin bus_samp_src <= bus_src; end end // always // Metastability harden the bus_new_stretch_src meta_harden meta_harden_bus_new_i0 ( .clk_dst (clk_dst), .rst_dst (rst_clk_dst), .signal_src (bus_new_stretch_src), .signal_dst (bus_new_stretch_dst) ); // Capture the value of bus_new_stretch_dst for edge detection always @(posedge clk_dst) begin if (rst_clk_dst) begin bus_new_stretch_old_dst <= 1'b0; end else begin bus_new_stretch_old_dst <= bus_new_stretch_dst; end end // always // Now generate the outputs always @(posedge clk_dst) begin if (rst_clk_dst) begin bus_dst <= bus_src; bus_new_dst <= 1'b0; end else if (bus_new_stretch_dst && !bus_new_stretch_old_dst) begin // This is the first clock that bus_new_stretch_dst is asserted // We know that bus_samp_src is stable, so we can sample it on the // destination clock even though it is on the other clock domain. // We also need to pulse the bus_new_dst for one clock bus_dst <= bus_samp_src; bus_new_dst <= 1'b1; end else begin bus_new_dst <= 1'b0; end end // alwaysendmodule
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -