mor1kx-bemicrocv/ip/altera/ddr3/altera_avalon_st_clock_crosser.v
2016-08-04 19:22:38 +02:00

142 lines
4.8 KiB
Verilog

// (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.
// $File: //acds/rel/15.1/ip/avalon_st/altera_avalon_st_handshake_clock_crosser/altera_avalon_st_clock_crosser.v $
// $Revision: #1 $
// $Date: 2015/08/09 $
// $Author: swbranch $
//------------------------------------------------------------------------------
`timescale 1ns / 1ns
module altera_avalon_st_clock_crosser(
in_clk,
in_reset,
in_ready,
in_valid,
in_data,
out_clk,
out_reset,
out_ready,
out_valid,
out_data
);
parameter SYMBOLS_PER_BEAT = 1;
parameter BITS_PER_SYMBOL = 8;
parameter FORWARD_SYNC_DEPTH = 2;
parameter BACKWARD_SYNC_DEPTH = 2;
parameter USE_OUTPUT_PIPELINE = 1;
localparam DATA_WIDTH = SYMBOLS_PER_BEAT * BITS_PER_SYMBOL;
input in_clk;
input in_reset;
output in_ready;
input in_valid;
input [DATA_WIDTH-1:0] in_data;
input out_clk;
input out_reset;
input out_ready;
output out_valid;
output [DATA_WIDTH-1:0] out_data;
// Data is guaranteed valid by control signal clock crossing. Cut data
// buffer false path.
(* altera_attribute = {"-name SUPPRESS_DA_RULE_INTERNAL \"D101,D102\""} *) reg [DATA_WIDTH-1:0] in_data_buffer;
reg [DATA_WIDTH-1:0] out_data_buffer;
reg in_data_toggle;
wire in_data_toggle_returned;
wire out_data_toggle;
reg out_data_toggle_flopped;
wire take_in_data;
wire out_data_taken;
wire out_valid_internal;
wire out_ready_internal;
assign in_ready = ~(in_data_toggle_returned ^ in_data_toggle);
assign take_in_data = in_valid & in_ready;
assign out_valid_internal = out_data_toggle ^ out_data_toggle_flopped;
assign out_data_taken = out_ready_internal & out_valid_internal;
always @(posedge in_clk or posedge in_reset) begin
if (in_reset) begin
in_data_buffer <= {DATA_WIDTH{1'b0}};
in_data_toggle <= 1'b0;
end else begin
if (take_in_data) begin
in_data_toggle <= ~in_data_toggle;
in_data_buffer <= in_data;
end
end //in_reset
end //in_clk always block
always @(posedge out_clk or posedge out_reset) begin
if (out_reset) begin
out_data_toggle_flopped <= 1'b0;
out_data_buffer <= {DATA_WIDTH{1'b0}};
end else begin
out_data_buffer <= in_data_buffer;
if (out_data_taken) begin
out_data_toggle_flopped <= out_data_toggle;
end
end //end if
end //out_clk always block
altera_std_synchronizer_nocut #(.depth(FORWARD_SYNC_DEPTH)) in_to_out_synchronizer (
.clk(out_clk),
.reset_n(~out_reset),
.din(in_data_toggle),
.dout(out_data_toggle)
);
altera_std_synchronizer_nocut #(.depth(BACKWARD_SYNC_DEPTH)) out_to_in_synchronizer (
.clk(in_clk),
.reset_n(~in_reset),
.din(out_data_toggle_flopped),
.dout(in_data_toggle_returned)
);
generate if (USE_OUTPUT_PIPELINE == 1) begin
altera_avalon_st_pipeline_base
#(
.BITS_PER_SYMBOL(BITS_PER_SYMBOL),
.SYMBOLS_PER_BEAT(SYMBOLS_PER_BEAT)
) output_stage (
.clk(out_clk),
.reset(out_reset),
.in_ready(out_ready_internal),
.in_valid(out_valid_internal),
.in_data(out_data_buffer),
.out_ready(out_ready),
.out_valid(out_valid),
.out_data(out_data)
);
end else begin
assign out_valid = out_valid_internal;
assign out_ready_internal = out_ready;
assign out_data = out_data_buffer;
end
endgenerate
endmodule