diff --git a/src/axis/rtl/taxi_axis_demux.sv b/src/axis/rtl/taxi_axis_demux.sv index 42daec1..782f6d2 100644 --- a/src/axis/rtl/taxi_axis_demux.sv +++ b/src/axis/rtl/taxi_axis_demux.sv @@ -1,7 +1,7 @@ // SPDX-License-Identifier: CERN-OHL-S-2.0 /* -Copyright (c) 2018-2025 FPGA Ninja, LLC +Copyright (c) 2018-2026 FPGA Ninja, LLC Authors: - Alex Forencich @@ -19,6 +19,8 @@ module taxi_axis_demux # ( // Number of AXI stream outputs parameter M_COUNT = 4, + // route via tid + parameter logic TID_ROUTE = 1'b0, // route via tdest parameter logic TDEST_ROUTE = 1'b0 ) @@ -53,6 +55,8 @@ localparam logic LAST_EN = s_axis.LAST_EN && m_axis[0].LAST_EN; localparam logic ID_EN = s_axis.ID_EN && m_axis[0].ID_EN; localparam ID_W = s_axis.ID_W; localparam logic DEST_EN = s_axis.DEST_EN && m_axis[0].DEST_EN; +localparam S_ID_W = s_axis.ID_W; +localparam M_ID_W = m_axis[0].ID_W; localparam S_DEST_W = s_axis.DEST_W; localparam M_DEST_W = m_axis[0].DEST_W; localparam logic USER_EN = s_axis.USER_EN && m_axis[0].USER_EN; @@ -61,6 +65,7 @@ localparam USER_W = s_axis.USER_W; localparam CL_M_COUNT = $clog2(M_COUNT); localparam M_DEST_W_INT = M_DEST_W > 0 ? M_DEST_W : 1; +localparam M_ID_W_INT = M_ID_W > 0 ? M_ID_W : 1; // check configuration if (m_axis[0].DATA_W != DATA_W) @@ -69,6 +74,17 @@ if (m_axis[0].DATA_W != DATA_W) if (KEEP_EN && m_axis[0].KEEP_W != KEEP_W) $fatal(0, "Error: Interface KEEP_W parameter mismatch (instance %m)"); +if (TID_ROUTE) begin + if (!ID_EN) + $fatal(0, "Error: TID_ROUTE set requires ID_EN set (instance %m)"); + + if (S_ID_W < CL_M_COUNT) + $fatal(0, "Error: S_ID_W too small for port count (instance %m)"); + + if (TDEST_ROUTE) + $fatal(0, "Error: Cannot enable both TID_ROUTE and TDEST_ROUTE (instance %m)"); +end + if (TDEST_ROUTE) begin if (!DEST_EN) $fatal(0, "Error: TDEST_ROUTE set requires DEST_EN set (instance %m)"); @@ -90,7 +106,7 @@ logic [KEEP_W-1:0] m_axis_tstrb_int; logic [M_COUNT-1:0] m_axis_tvalid_int; logic m_axis_tready_int_reg = 1'b0; logic m_axis_tlast_int; -logic [ID_W-1:0] m_axis_tid_int; +logic [M_ID_W-1:0] m_axis_tid_int; logic [M_DEST_W-1:0] m_axis_tdest_int; logic [USER_W-1:0] m_axis_tuser_int; wire m_axis_tready_int_early; @@ -115,7 +131,15 @@ always_comb begin if (!frame_reg && s_axis.tvalid && s_axis.tready) begin // start of frame, grab select value - if (TDEST_ROUTE) begin + if (TID_ROUTE) begin + if (M_COUNT > 1) begin + select_ctl = s_axis.tid[S_ID_W-1:S_ID_W-CL_M_COUNT]; + drop_ctl = (CL_M_COUNT+1)'(select_ctl) >= (CL_M_COUNT+1)'(M_COUNT); + end else begin + select_ctl = '0; + drop_ctl = 1'b0; + end + end else if (TDEST_ROUTE) begin if (M_COUNT > 1) begin select_ctl = s_axis.tdest[S_DEST_W-1:S_DEST_W-CL_M_COUNT]; drop_ctl = (CL_M_COUNT+1)'(select_ctl) >= (CL_M_COUNT+1)'(M_COUNT); @@ -141,7 +165,7 @@ always_comb begin m_axis_tvalid_int = '0; m_axis_tvalid_int[select_ctl] = s_axis.tvalid && s_axis.tready && !drop_ctl; m_axis_tlast_int = s_axis.tlast; - m_axis_tid_int = s_axis.tid; + m_axis_tid_int = M_ID_W'(s_axis.tid); m_axis_tdest_int = M_DEST_W'(s_axis.tdest); m_axis_tuser_int = s_axis.tuser; end @@ -170,7 +194,7 @@ logic [KEEP_W-1:0] m_axis_tkeep_reg = '0; logic [KEEP_W-1:0] m_axis_tstrb_reg = '0; logic [M_COUNT-1:0] m_axis_tvalid_reg = '0, m_axis_tvalid_next; logic m_axis_tlast_reg = 1'b0; -logic [ID_W-1:0] m_axis_tid_reg = '0; +logic [M_ID_W-1:0] m_axis_tid_reg = '0; logic [M_DEST_W-1:0] m_axis_tdest_reg = '0; logic [USER_W-1:0] m_axis_tuser_reg = '0; @@ -179,7 +203,7 @@ logic [KEEP_W-1:0] temp_m_axis_tkeep_reg = '0; logic [KEEP_W-1:0] temp_m_axis_tstrb_reg = '0; logic [M_COUNT-1:0] temp_m_axis_tvalid_reg = '0, temp_m_axis_tvalid_next; logic temp_m_axis_tlast_reg = 1'b0; -logic [ID_W-1:0] temp_m_axis_tid_reg = '0; +logic [M_ID_W-1:0] temp_m_axis_tid_reg = '0; logic [M_DEST_W-1:0] temp_m_axis_tdest_reg = '0; logic [USER_W-1:0] temp_m_axis_tuser_reg = '0; diff --git a/src/axis/tb/taxi_axis_demux/Makefile b/src/axis/tb/taxi_axis_demux/Makefile index 86b59e0..d557f90 100644 --- a/src/axis/tb/taxi_axis_demux/Makefile +++ b/src/axis/tb/taxi_axis_demux/Makefile @@ -40,12 +40,14 @@ export PARAM_KEEP_W := $(shell expr \( $(PARAM_DATA_W) + 7 \) / 8 ) export PARAM_STRB_EN := 0 export PARAM_LAST_EN := 1 export PARAM_ID_EN := 1 -export PARAM_ID_W := 8 +export PARAM_M_ID_W := 8 +export PARAM_S_ID_W := $(shell python -c "print($(PARAM_M_ID_W) + ($(PARAM_M_COUNT)-1).bit_length())") export PARAM_DEST_EN := 1 export PARAM_M_DEST_W := 8 export PARAM_S_DEST_W := $(shell python -c "print($(PARAM_M_DEST_W) + ($(PARAM_M_COUNT)-1).bit_length())") export PARAM_USER_EN := 1 export PARAM_USER_W := 1 +export PARAM_TID_ROUTE := 0 export PARAM_TDEST_ROUTE := 1 ifeq ($(SIM), icarus) diff --git a/src/axis/tb/taxi_axis_demux/test_taxi_axis_demux.py b/src/axis/tb/taxi_axis_demux/test_taxi_axis_demux.py index e87a619..11b0d03 100644 --- a/src/axis/tb/taxi_axis_demux/test_taxi_axis_demux.py +++ b/src/axis/tb/taxi_axis_demux/test_taxi_axis_demux.py @@ -65,11 +65,11 @@ async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=N tb = TB(dut) - id_width = len(tb.source.bus.tid) + id_width = len(tb.sink[0].bus.tid) id_count = 2**id_width id_mask = id_count-1 - dest_width = len(tb.sink[0].bus.tid) + dest_width = len(tb.sink[0].bus.tdest) dest_count = 2**dest_width dest_mask = dest_count-1 @@ -183,12 +183,14 @@ def test_taxi_axis_demux(request, m_count, data_w, tdest_route): parameters['STRB_EN'] = 0 parameters['LAST_EN'] = 1 parameters['ID_EN'] = 1 - parameters['ID_W'] = 8 + parameters['M_ID_W'] = 8 + parameters['S_ID_W'] = parameters['M_ID_W'] + (m_count-1).bit_length() parameters['DEST_EN'] = 1 parameters['M_DEST_W'] = 8 parameters['S_DEST_W'] = parameters['M_DEST_W'] + (m_count-1).bit_length() parameters['USER_EN'] = 1 parameters['USER_W'] = 1 + parameters['TID_ROUTE'] = 0 parameters['TDEST_ROUTE'] = tdest_route extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} diff --git a/src/axis/tb/taxi_axis_demux/test_taxi_axis_demux.sv b/src/axis/tb/taxi_axis_demux/test_taxi_axis_demux.sv index 6c08269..661403a 100644 --- a/src/axis/tb/taxi_axis_demux/test_taxi_axis_demux.sv +++ b/src/axis/tb/taxi_axis_demux/test_taxi_axis_demux.sv @@ -25,12 +25,14 @@ module test_taxi_axis_demux # parameter logic STRB_EN = 1'b0, parameter logic LAST_EN = 1'b1, parameter logic ID_EN = 1'b0, - parameter ID_W = 8, + parameter M_ID_W = 8, + parameter S_ID_W = M_ID_W+$clog2(M_COUNT), parameter logic DEST_EN = 1'b0, parameter M_DEST_W = 8, parameter S_DEST_W = M_DEST_W+$clog2(M_COUNT), parameter logic USER_EN = 1'b1, parameter USER_W = 1, + parameter logic TID_ROUTE = 1'b0, parameter logic TDEST_ROUTE = 1'b0 /* verilator lint_on WIDTHTRUNC */ ) @@ -46,7 +48,7 @@ taxi_axis_if #( .STRB_EN(STRB_EN), .LAST_EN(LAST_EN), .ID_EN(ID_EN), - .ID_W(ID_W), + .ID_W(S_ID_W), .DEST_EN(DEST_EN), .DEST_W(S_DEST_W), .USER_EN(USER_EN), @@ -60,7 +62,7 @@ taxi_axis_if #( .STRB_EN(STRB_EN), .LAST_EN(LAST_EN), .ID_EN(ID_EN), - .ID_W(ID_W), + .ID_W(M_ID_W), .DEST_EN(DEST_EN), .DEST_W(M_DEST_W), .USER_EN(USER_EN), @@ -73,6 +75,7 @@ logic [$clog2(M_COUNT)-1:0] select; taxi_axis_demux #( .M_COUNT(M_COUNT), + .TID_ROUTE(TID_ROUTE), .TDEST_ROUTE(TDEST_ROUTE) ) uut (