diff options
Diffstat (limited to 'fpga/usrp3/lib/rfnoc/utils/ctrlport_clk_cross.v')
-rw-r--r-- | fpga/usrp3/lib/rfnoc/utils/ctrlport_clk_cross.v | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/rfnoc/utils/ctrlport_clk_cross.v b/fpga/usrp3/lib/rfnoc/utils/ctrlport_clk_cross.v new file mode 100644 index 000000000..6aa74c74f --- /dev/null +++ b/fpga/usrp3/lib/rfnoc/utils/ctrlport_clk_cross.v @@ -0,0 +1,167 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// Module: ctrlport_clk_cross +// +// Description: +// +// Crosses a CTRL Port request and response between two clock domains. +// + + +module ctrlport_clk_cross ( + + input wire rst, // Can be either clock domain, but must be glitch-free + + //--------------------------------------------------------------------------- + // Input Clock Domain (Slave Interface) + //--------------------------------------------------------------------------- + + input wire s_ctrlport_clk, + input wire s_ctrlport_req_wr, + input wire s_ctrlport_req_rd, + input wire [19:0] s_ctrlport_req_addr, + input wire [ 9:0] s_ctrlport_req_portid, + input wire [15:0] s_ctrlport_req_rem_epid, + input wire [ 9:0] s_ctrlport_req_rem_portid, + input wire [31:0] s_ctrlport_req_data, + input wire [ 3:0] s_ctrlport_req_byte_en, + input wire s_ctrlport_req_has_time, + input wire [63:0] s_ctrlport_req_time, + output wire s_ctrlport_resp_ack, + output wire [ 1:0] s_ctrlport_resp_status, + output wire [31:0] s_ctrlport_resp_data, + + //--------------------------------------------------------------------------- + // Output Clock Domain (Master Interface) + //--------------------------------------------------------------------------- + + input wire m_ctrlport_clk, + output wire m_ctrlport_req_wr, + output wire m_ctrlport_req_rd, + output wire [19:0] m_ctrlport_req_addr, + output wire [ 9:0] m_ctrlport_req_portid, + output wire [15:0] m_ctrlport_req_rem_epid, + output wire [ 9:0] m_ctrlport_req_rem_portid, + output wire [31:0] m_ctrlport_req_data, + output wire [ 3:0] m_ctrlport_req_byte_en, + output wire m_ctrlport_req_has_time, + output wire [63:0] m_ctrlport_req_time, + input wire m_ctrlport_resp_ack, + input wire [ 1:0] m_ctrlport_resp_status, + input wire [31:0] m_ctrlport_resp_data +); + + //--------------------------------------------------------------------------- + // Slave to Master Clock Crossing (Request) + //--------------------------------------------------------------------------- + + localparam REQ_W = + 1 + // ctrlport_req_wr + 1 + // ctrlport_req_rd + 20 + // ctrlport_req_addr + 10 + // ctrlport_req_portid + 16 + // ctrlport_req_rem_epid + 10 + // ctrlport_req_rem_portid + 32 + // ctrlport_req_data + 4 + // ctrlport_req_byte_en + 1 + // ctrlport_req_has_time + 64; // ctrlport_req_time + + wire [ REQ_W-1:0] s_req_flat; + wire [ REQ_W-1:0] m_req_flat; + wire m_req_flat_valid; + wire m_ctrlport_req_wr_tmp; + wire m_ctrlport_req_rd_tmp; + + assign s_req_flat = { + s_ctrlport_req_wr, + s_ctrlport_req_rd, + s_ctrlport_req_addr, + s_ctrlport_req_portid, + s_ctrlport_req_rem_epid, + s_ctrlport_req_rem_portid, + s_ctrlport_req_data, + s_ctrlport_req_byte_en, + s_ctrlport_req_has_time, + s_ctrlport_req_time + }; + + axi_fifo_2clk #( + .WIDTH (REQ_W), + .SIZE (3) + ) req_fifo ( + .reset (rst), + .i_aclk (s_ctrlport_clk), + .i_tdata (s_req_flat), + .i_tvalid (s_ctrlport_req_wr | s_ctrlport_req_rd), + .i_tready (), + .o_aclk (m_ctrlport_clk), + .o_tdata (m_req_flat), + .o_tready (1'b1), + .o_tvalid (m_req_flat_valid) + ); + + assign { + m_ctrlport_req_wr_tmp, + m_ctrlport_req_rd_tmp, + m_ctrlport_req_addr, + m_ctrlport_req_portid, + m_ctrlport_req_rem_epid, + m_ctrlport_req_rem_portid, + m_ctrlport_req_data, + m_ctrlport_req_byte_en, + m_ctrlport_req_has_time, + m_ctrlport_req_time + } = m_req_flat; + + assign m_ctrlport_req_wr = m_ctrlport_req_wr_tmp & m_req_flat_valid; + assign m_ctrlport_req_rd = m_ctrlport_req_rd_tmp & m_req_flat_valid; + + + //--------------------------------------------------------------------------- + // Master to Slave Clock Crossing (Response) + //--------------------------------------------------------------------------- + + localparam RESP_W = + 1 + // ctrlport_resp_ack, + 2 + // ctrlport_resp_status, + 32; // ctrlport_resp_data + + wire [RESP_W-1:0] m_resp_flat; + wire [RESP_W-1:0] s_resp_flat; + wire s_resp_flat_valid; + wire s_ctrlport_resp_ack_tmp; + + assign m_resp_flat = { + m_ctrlport_resp_ack, + m_ctrlport_resp_status, + m_ctrlport_resp_data + }; + + axi_fifo_2clk #( + .WIDTH (RESP_W), + .SIZE (3) + ) resp_fifo ( + .reset (rst), + .i_aclk (m_ctrlport_clk), + .i_tdata (m_resp_flat), + .i_tvalid (m_ctrlport_resp_ack), + .i_tready (), + .o_aclk (s_ctrlport_clk), + .o_tdata (s_resp_flat), + .o_tready (1'b1), + .o_tvalid (s_resp_flat_valid) + ); + + assign { + s_ctrlport_resp_ack_tmp, + s_ctrlport_resp_status, + s_ctrlport_resp_data + } = s_resp_flat; + + assign s_ctrlport_resp_ack = s_ctrlport_resp_ack_tmp & s_resp_flat_valid; + +endmodule |