85 lines
2.8 KiB
Systemverilog
85 lines
2.8 KiB
Systemverilog
//
|
|
// Copyright 2025 Ettus Research, a National Instruments Brand
|
|
//
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
//
|
|
// Module: ctrlport_if_clk_cross
|
|
//
|
|
// Description:
|
|
//
|
|
// Crosses control-port interface between different clock domains.
|
|
//
|
|
|
|
|
|
module ctrlport_if_clk_cross
|
|
(
|
|
ctrlport_if.slave s_ctrlport,
|
|
ctrlport_if.master m_ctrlport
|
|
|
|
);
|
|
import ctrlport_pkg::*;
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Slave to Master Clock Crossing (Request)
|
|
//---------------------------------------------------------------------------
|
|
ctrlport_request_t m_req_hs;
|
|
logic m_req_hs_valid;
|
|
|
|
// Busy flag can be ignored as the response handshake takes at least the same
|
|
// amount of cycles to transfer the response as this handshake instance needs
|
|
// to release the busy flag as they are configured with the same amount of
|
|
// synchronization stages. Furthermore the ctrlport protocol just allows for
|
|
// one transaction to be active at the same time. A request can only be issued
|
|
// once the response is provided.
|
|
handshake #(
|
|
.WIDTH($bits(ctrlport_request_t))
|
|
) req_handshake_inst (
|
|
.clk_a(s_ctrlport.clk),
|
|
.rst_a(s_ctrlport.rst),
|
|
.valid_a((s_ctrlport.req.rd | s_ctrlport.req.wr) & ~s_ctrlport.rst),
|
|
.data_a(s_ctrlport.req),
|
|
.busy_a(),
|
|
.clk_b(m_ctrlport.clk),
|
|
.valid_b(m_req_hs_valid),
|
|
.data_b(m_req_hs)
|
|
);
|
|
|
|
always_comb begin
|
|
m_ctrlport.req = m_req_hs;
|
|
// mask read and write flags
|
|
m_ctrlport.req.wr = m_req_hs.wr & m_req_hs_valid & ~m_ctrlport.rst;
|
|
m_ctrlport.req.rd = m_req_hs.rd & m_req_hs_valid & ~m_ctrlport.rst;
|
|
end
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Master to Slave Clock Crossing (Response)
|
|
//---------------------------------------------------------------------------
|
|
ctrlport_response_t s_resp_hs;
|
|
logic s_resp_hs_valid;
|
|
|
|
// Busy flag can be ignored as the request handshake takes at least the same
|
|
// amount of cycles to transfer the request as this handshake instance needs
|
|
// to release the busy flag as they are configured with the same amount of
|
|
// synchronization stages. Furthermore the ctrlport protocol just allows for
|
|
// one transaction to be active at the same time. A response can only be
|
|
// issued once the request is available.
|
|
handshake #(
|
|
.WIDTH($bits(ctrlport_response_t))
|
|
) resp_handshake_inst (
|
|
.clk_a(m_ctrlport.clk),
|
|
.rst_a(m_ctrlport.rst),
|
|
.valid_a(m_ctrlport.resp.ack & ~m_ctrlport.rst),
|
|
.data_a(m_ctrlport.resp),
|
|
.busy_a(),
|
|
.clk_b(s_ctrlport.clk),
|
|
.valid_b(s_resp_hs_valid),
|
|
.data_b(s_resp_hs)
|
|
);
|
|
|
|
always_comb begin
|
|
s_ctrlport.resp = s_resp_hs;
|
|
s_ctrlport.resp.ack = s_resp_hs.ack & s_resp_hs_valid & ~s_ctrlport.rst;
|
|
end
|
|
|
|
endmodule
|