File: ctrlport_if_clk_cross.sv

package info (click to toggle)
uhd 4.9.0.0%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 184,180 kB
  • sloc: cpp: 262,887; python: 112,011; ansic: 102,670; vhdl: 57,031; tcl: 19,924; xml: 8,581; makefile: 3,028; sh: 2,812; pascal: 230; javascript: 120; csh: 94; asm: 20; perl: 11
file content (84 lines) | stat: -rw-r--r-- 2,834 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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