fpga: lib: redirect old ctrlport modules to interface based ones

Original-commit: bf294111b9f49efb6373908274bc8d31bb8cb11d
This commit is contained in:
Max Köhler
2025-03-21 09:09:09 -05:00
committed by Wade Fife
parent e67d78533c
commit 8dc5d3aeec
16 changed files with 821 additions and 1040 deletions
+125
View File
@@ -0,0 +1,125 @@
//
// Copyright 2019 Ettus Research, A National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: ctrlport_combiner
//
// Description:
//
// This block is an arbiter that merges control-port interfaces. This block is
// used when you have multiple control-port masters that need to access a
// single slave. For example, a NoC block with multiple submodules that each
// need to read and/or write registers outside of themselves.
//
// This module combines the control-port requests from multiple masters into a
// single request for one slave. Simultaneous requests are handled in the order
// specified by PRIORITY. The responding ACK is routed back to the requester.
//
// The module has been designed so that the latency through it is always the
// same when PRIORITY=1 and there is no contention, so that it can be used in
// applications where deterministic behavior is desired.
//
// Parameters:
//
// NUM_MASTERS : The number of control-port masters to connect to a single
// control-port slave.
// PRIORITY : Use PRIORITY = 0 for round robin arbitration, PRIORITY = 1
// for priority arbitration (lowest number port serviced first).
//
module ctrlport_combiner
import ctrlport_pkg::*;
#(
int NUM_MASTERS = 2,
bit PRIORITY = 0
) (
input logic ctrlport_clk,
input logic ctrlport_rst,
// Requests from multiple masters
input logic [ NUM_MASTERS-1:0] s_ctrlport_req_wr,
input logic [ NUM_MASTERS-1:0] s_ctrlport_req_rd,
input logic [ CTRLPORT_ADDR_W*NUM_MASTERS-1:0] s_ctrlport_req_addr,
input logic [ CTRLPORT_PORTID_W*NUM_MASTERS-1:0] s_ctrlport_req_portid,
input logic [CTRLPORT_REM_EPID_W*NUM_MASTERS-1:0] s_ctrlport_req_rem_epid,
input logic [ CTRLPORT_PORTID_W*NUM_MASTERS-1:0] s_ctrlport_req_rem_portid,
input logic [ CTRLPORT_DATA_W*NUM_MASTERS-1:0] s_ctrlport_req_data,
input logic [ CTRLPORT_BYTE_EN_W*NUM_MASTERS-1:0] s_ctrlport_req_byte_en,
input logic [ NUM_MASTERS-1:0] s_ctrlport_req_has_time,
input logic [ CTRLPORT_TIME_W*NUM_MASTERS-1:0] s_ctrlport_req_time,
// Responses to multiple masters
output logic [ NUM_MASTERS-1:0] s_ctrlport_resp_ack,
output logic [ CTRLPORT_STS_W*NUM_MASTERS-1:0] s_ctrlport_resp_status,
output logic [ CTRLPORT_DATA_W*NUM_MASTERS-1:0] s_ctrlport_resp_data,
// Request to a single slave
output logic m_ctrlport_req_wr,
output logic m_ctrlport_req_rd,
output logic [ CTRLPORT_ADDR_W-1:0] m_ctrlport_req_addr,
output logic [ CTRLPORT_PORTID_W-1:0] m_ctrlport_req_portid,
output logic [CTRLPORT_REM_EPID_W-1:0] m_ctrlport_req_rem_epid,
output logic [ CTRLPORT_PORTID_W-1:0] m_ctrlport_req_rem_portid,
output logic [ CTRLPORT_DATA_W-1:0] m_ctrlport_req_data,
output logic [ CTRLPORT_BYTE_EN_W-1:0] m_ctrlport_req_byte_en,
output logic m_ctrlport_req_has_time,
output logic [ CTRLPORT_TIME_W-1:0] m_ctrlport_req_time,
// Response from a single slave
input logic m_ctrlport_resp_ack,
input logic [ CTRLPORT_STS_W-1:0] m_ctrlport_resp_status,
input logic [ CTRLPORT_DATA_W-1:0] m_ctrlport_resp_data
);
// Define interfaces
ctrlport_if slave_ctrlport[NUM_MASTERS](.clk(ctrlport_clk), .rst(ctrlport_rst));
ctrlport_if master_ctrlport(.clk(ctrlport_clk), .rst(ctrlport_rst));
// Map existing ports to ctrlport_if
for (genvar i=0; i<NUM_MASTERS; i++) begin : input_gen
always_comb begin
slave_ctrlport[i].req.wr = s_ctrlport_req_wr[i];
slave_ctrlport[i].req.rd = s_ctrlport_req_rd[i];
slave_ctrlport[i].req.addr = s_ctrlport_req_addr[CTRLPORT_ADDR_W*i +: CTRLPORT_ADDR_W];
slave_ctrlport[i].req.port_id = s_ctrlport_req_portid[CTRLPORT_PORTID_W*i +: CTRLPORT_PORTID_W];
slave_ctrlport[i].req.remote_epid = s_ctrlport_req_rem_epid[CTRLPORT_REM_EPID_W*i +: CTRLPORT_REM_EPID_W];
slave_ctrlport[i].req.remote_portid = s_ctrlport_req_rem_portid[CTRLPORT_PORTID_W*i +: CTRLPORT_PORTID_W];
slave_ctrlport[i].req.data = s_ctrlport_req_data[CTRLPORT_DATA_W*i +: CTRLPORT_DATA_W];
slave_ctrlport[i].req.byte_en = s_ctrlport_req_byte_en[CTRLPORT_BYTE_EN_W*i +: CTRLPORT_BYTE_EN_W];
slave_ctrlport[i].req.has_time = s_ctrlport_req_has_time[i];
slave_ctrlport[i].req.timestamp = s_ctrlport_req_time[CTRLPORT_TIME_W*i +: CTRLPORT_TIME_W];
s_ctrlport_resp_ack[i] = slave_ctrlport[i].resp.ack;
s_ctrlport_resp_status[CTRLPORT_STS_W*i +: CTRLPORT_STS_W] = slave_ctrlport[i].resp.status;
s_ctrlport_resp_data[CTRLPORT_DATA_W*i +: CTRLPORT_DATA_W] = slave_ctrlport[i].resp.data;
end
end
// Instantiate ctrlport_if_combiner module
ctrlport_if_combiner #(
.NUM_MASTERS(NUM_MASTERS),
.PRIORITY(PRIORITY)
) ctrlport_if_combiner_inst (
.s_ctrlport(slave_ctrlport),
.m_ctrlport(master_ctrlport)
);
// Unpack ctrlport_if to output port
always_comb begin
m_ctrlport_req_wr = master_ctrlport.req.wr;
m_ctrlport_req_rd = master_ctrlport.req.rd;
m_ctrlport_req_addr = master_ctrlport.req.addr;
m_ctrlport_req_portid = master_ctrlport.req.port_id;
m_ctrlport_req_rem_epid = master_ctrlport.req.remote_epid;
m_ctrlport_req_rem_portid = master_ctrlport.req.remote_portid;
m_ctrlport_req_data = master_ctrlport.req.data;
m_ctrlport_req_byte_en = master_ctrlport.req.byte_en;
m_ctrlport_req_has_time = master_ctrlport.req.has_time;
m_ctrlport_req_time = master_ctrlport.req.timestamp;
master_ctrlport.resp.ack = m_ctrlport_resp_ack;
master_ctrlport.resp.status = ctrlport_status_t'(m_ctrlport_resp_status);
master_ctrlport.resp.data = m_ctrlport_resp_data;
end
endmodule