rfnoc: lib: introduce ctrl-port interface and BFM
Original-commit: 886cf97ad5d494b20c6fff0a53113f6096d458c7
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// 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
|
||||
Reference in New Issue
Block a user