From 3e06f317f0767f5690f3a39673db754c3041b6d2 Mon Sep 17 00:00:00 2001 From: Tobias Platen Date: Thu, 23 Jan 2020 10:44:44 +0100 Subject: [PATCH] begin axi_rab to nmigen conversion --- src/iommu/axi_rab/axi4_ar_buffer.py | 135 +++++++ src/iommu/axi_rab/rab_core.py | 539 ++++++++++++++++++++++++++++ 2 files changed, 674 insertions(+) create mode 100644 src/iommu/axi_rab/axi4_ar_buffer.py create mode 100644 src/iommu/axi_rab/rab_core.py diff --git a/src/iommu/axi_rab/axi4_ar_buffer.py b/src/iommu/axi_rab/axi4_ar_buffer.py new file mode 100644 index 00000000..1f3a5ff3 --- /dev/null +++ b/src/iommu/axi_rab/axi4_ar_buffer.py @@ -0,0 +1,135 @@ +# Copyright 2018 ETH Zurich and University of Bologna. +# Copyright and related rights are licensed under the Solderpad Hardware +# License, Version 0.51 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +# or agreed to in writing, software, hardware and materials distributed under +# this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +# this file has been generated by sv2nmigen + +from nmigen import Signal, Module, Const, Cat, Elaboratable + +# module axi4_ar_buffer +# #( +# parameter AXI_ID_WIDTH = 4, +# parameter AXI_USER_WIDTH = 4 +# ) +# ( +# input logic axi4_aclk, +# input logic axi4_arstn, +# +# input logic [AXI_ID_WIDTH-1:0] s_axi4_arid, +# input logic [31:0] s_axi4_araddr, +# input logic s_axi4_arvalid, +# output logic s_axi4_arready, +# input logic [7:0] s_axi4_arlen, +# input logic [2:0] s_axi4_arsize, +# input logic [1:0] s_axi4_arburst, +# input logic s_axi4_arlock, +# input logic [2:0] s_axi4_arprot, +# input logic [3:0] s_axi4_arcache, +# input logic [AXI_USER_WIDTH-1:0] s_axi4_aruser, +# +# output logic [AXI_ID_WIDTH-1:0] m_axi4_arid, +# output logic [31:0] m_axi4_araddr, +# output logic m_axi4_arvalid, +# input logic m_axi4_arready, +# output logic [7:0] m_axi4_arlen, +# output logic [2:0] m_axi4_arsize, +# output logic [1:0] m_axi4_arburst, +# output logic m_axi4_arlock, +# output logic [2:0] m_axi4_arprot, +# output logic [3:0] m_axi4_arcache, +# output logic [AXI_USER_WIDTH-1:0] m_axi4_aruser +# ); + + +class axi4_ar_buffer(Elaboratable): + + def __init__(self): + # self.axi4_aclk = Signal() # input + # self.axi4_arstn = Signal() # input + self.s_axi4_arid = Signal(AXI_ID_WIDTH) # input + self.s_axi4_araddr = Signal(32) # input + self.s_axi4_arvalid = Signal() # input + self.s_axi4_arready = Signal() # output + self.s_axi4_arlen = Signal(8) # input + self.s_axi4_arsize = Signal(3) # input + self.s_axi4_arburst = Signal(2) # input + self.s_axi4_arlock = Signal() # input + self.s_axi4_arprot = Signal(3) # input + self.s_axi4_arcache = Signal(4) # input + self.s_axi4_aruser = Signal(AXI_USER_WIDTH) # input + self.m_axi4_arid = Signal(AXI_ID_WIDTH) # output + self.m_axi4_araddr = Signal(32) # output + self.m_axi4_arvalid = Signal() # output + self.m_axi4_arready = Signal() # input + self.m_axi4_arlen = Signal(8) # output + self.m_axi4_arsize = Signal(3) # output + self.m_axi4_arburst = Signal(2) # output + self.m_axi4_arlock = Signal() # output + self.m_axi4_arprot = Signal(3) # output + self.m_axi4_arcache = Signal(4) # output + self.m_axi4_aruser = Signal(AXI_USER_WIDTH) # output + + def elaborate(self, platform=None): + m = Module() + # #TODO use record types here + # wire [AXI_ID_WIDTH+AXI_USER_WIDTH+52:0] data_in; + # wire [AXI_ID_WIDTH+AXI_USER_WIDTH+52:0] data_out; + + # assign data_in [3:0] = s_axi4_arcache; + # assign data_in [6:4] = s_axi4_arprot; + # assign data_in [7] = s_axi4_arlock; + # assign data_in [9:8] = s_axi4_arburst; + # assign data_in [12:10] = s_axi4_arsize; + # assign data_in [20:13] = s_axi4_arlen; + # assign data_in [52:21] = s_axi4_araddr; + # assign data_in [52+AXI_ID_WIDTH:53] = s_axi4_arid; + # assign data_in[52+AXI_ID_WIDTH+AXI_USER_WIDTH:53+AXI_ID_WIDTH] = s_axi4_aruser; + # + # assign m_axi4_arcache = data_out[3:0]; + # assign m_axi4_arprot = data_out[6:4]; + # assign m_axi4_arlock = data_out[7]; + # assign m_axi4_arburst = data_out[9:8]; + # assign m_axi4_arsize = data_out[12:10]; + # assign m_axi4_arlen = data_out[20:13]; + # assign m_axi4_araddr = data_out[52:21]; + # assign m_axi4_arid = data_out[52+AXI_ID_WIDTH:53]; + # assign m_axi4_aruser = data_out[52+AXI_ID_WIDTH+AXI_USER_WIDTH:53+AXI_ID_WIDTH]; + + # m.d.comb += self.m_axi4_arcache.eq(..) + # m.d.comb += self.m_axi4_arprot.eq(..) + # m.d.comb += self.m_axi4_arlock.eq(..) + # m.d.comb += self.m_axi4_arburst.eq(..) + # m.d.comb += self.m_axi4_arsize.eq(..) + # m.d.comb += self.m_axi4_arlen.eq(..) + # m.d.comb += self.m_axi4_araddr.eq(..) + # m.d.comb += self.m_axi4_arid.eq(..) + # m.d.comb += self.m_axi4_aruser.eq(..) + return m + +# TODO convert axi_buffer_rab.sv +# +# axi_buffer_rab +# #( +# .DATA_WIDTH ( AXI_ID_WIDTH+AXI_USER_WIDTH+53 ), +# .BUFFER_DEPTH ( 4 ) +# ) +# u_buffer +# ( +# .clk ( axi4_aclk ), +# .rstn ( axi4_arstn ), +# .valid_out ( m_axi4_arvalid ), +# .data_out ( data_out ), +# .ready_in ( m_axi4_arready ), +# .valid_in ( s_axi4_arvalid ), +# .data_in ( data_in ), +# .ready_out ( s_axi4_arready ) +# ); +# + +# endmodule diff --git a/src/iommu/axi_rab/rab_core.py b/src/iommu/axi_rab/rab_core.py new file mode 100644 index 00000000..7d7494aa --- /dev/null +++ b/src/iommu/axi_rab/rab_core.py @@ -0,0 +1,539 @@ +# // Copyright 2018 ETH Zurich and University of Bologna. +# // Copyright and related rights are licensed under the Solderpad Hardware +# // License, Version 0.51 (the "License"); you may not use this file except in +# // compliance with the License. You may obtain a copy of the License at +# // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +# // or agreed to in writing, software, hardware and materials distributed under +# // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# // CONDITIONS OF ANY KIND, either express or implied. See the License for the +# // specific language governing permissions and limitations under the License. + +# this file has been generated by sv2nmigen + +# +# //`include "pulp_soc_defines.sv" +# +# ////import CfMath::log2; +# +# //`define MY_ARRAY_SUM(MY_ARRAY,ARRAY_SIZE) ( (ARRAY_SIZE==1) ? MY_ARRAY[0] : (ARRAY_SIZE==2) ? MY_ARRAY[0] + MY_ARRAY[1] : (ARRAY_SIZE==3) ? MY_ARRAY[0] + MY_ARRAY[1] + MY_ARRAY[2] : (ARRAY_SIZE==4) ? MY_ARRAY[0] + MY_ARRAY[1] + MY_ARRAY[2] + MY_ARRAY[3] : 0 ) +# + +# module rab_core +# #( +# parameter N_PORTS = 3, +# parameter N_L2_SETS = 32, +# parameter N_L2_SET_ENTRIES = 32, +# parameter AXI_DATA_WIDTH = 64, +# parameter AXI_S_ADDR_WIDTH = 32, +# parameter AXI_M_ADDR_WIDTH = 40, +# parameter AXI_LITE_DATA_WIDTH = 64, +# parameter AXI_LITE_ADDR_WIDTH = 32, +# parameter AXI_ID_WIDTH = 8, +# parameter AXI_USER_WIDTH = 6, +# parameter MH_FIFO_DEPTH = 16 +# ) +# ( +# input logic Clk_CI, +# input logic Rst_RBI, +# +# input logic [AXI_LITE_ADDR_WIDTH-1:0] s_axi_awaddr, +# input logic s_axi_awvalid, +# output logic s_axi_awready, +# +# input logic [AXI_LITE_DATA_WIDTH-1:0] s_axi_wdata, +# input logic [AXI_LITE_DATA_WIDTH/8-1:0] s_axi_wstrb, +# input logic s_axi_wvalid, +# output logic s_axi_wready, +# +# input logic [AXI_LITE_ADDR_WIDTH-1:0] s_axi_araddr, +# input logic s_axi_arvalid, +# output logic s_axi_arready, +# +# input logic s_axi_rready, +# output logic [AXI_LITE_DATA_WIDTH-1:0] s_axi_rdata, +# output logic [1:0] s_axi_rresp, +# output logic s_axi_rvalid, +# +# output logic [1:0] s_axi_bresp, +# output logic s_axi_bvalid, +# input logic s_axi_bready, +# +# output logic [N_PORTS-1:0] int_miss, +# output logic [N_PORTS-1:0] int_prot, +# output logic [N_PORTS-1:0] int_multi, +# output logic [N_PORTS-1:0] int_prefetch, +# output logic int_mhf_full, +# +# output logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] int_axaddr_o, +# output logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] int_axid_o, +# output logic [N_PORTS-1:0] [7:0] int_axlen_o, +# output logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] int_axuser_o, +# +# input logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] port1_addr, +# input logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] port1_id, +# input logic [N_PORTS-1:0] [7:0] port1_len, +# input logic [N_PORTS-1:0] [2:0] port1_size, +# input logic [N_PORTS-1:0] port1_addr_valid, +# input logic [N_PORTS-1:0] port1_type, +# input logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] port1_user, +# input logic [N_PORTS-1:0] port1_sent, +# output logic [N_PORTS-1:0] [AXI_M_ADDR_WIDTH-1:0] port1_out_addr, +# output logic [N_PORTS-1:0] port1_cache_coherent, +# output logic [N_PORTS-1:0] port1_accept, +# output logic [N_PORTS-1:0] port1_drop, +# output logic [N_PORTS-1:0] port1_miss, +# +# input logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] port2_addr, +# input logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] port2_id, +# input logic [N_PORTS-1:0] [7:0] port2_len, +# input logic [N_PORTS-1:0] [2:0] port2_size, +# input logic [N_PORTS-1:0] port2_addr_valid, +# input logic [N_PORTS-1:0] port2_type, +# input logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] port2_user, +# input logic [N_PORTS-1:0] port2_sent, +# output logic [N_PORTS-1:0] [AXI_M_ADDR_WIDTH-1:0] port2_out_addr, +# output logic [N_PORTS-1:0] port2_cache_coherent, +# output logic [N_PORTS-1:0] port2_accept, +# output logic [N_PORTS-1:0] port2_drop, +# output logic [N_PORTS-1:0] port2_miss, +# +# input logic [N_PORTS-1:0] miss_l2_i, +# input logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] miss_l2_addr_i, +# input logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] miss_l2_id_i, +# input logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] miss_l2_user_i, +# +# output logic [N_PORTS-1:0] [AXI_LITE_DATA_WIDTH-1:0] wdata_l2_o, +# output logic [N_PORTS-1:0] [AXI_LITE_ADDR_WIDTH-1:0] waddr_l2_o, +# output logic [N_PORTS-1:0] wren_l2_o +# ); + +from nmigen import Signal, Module, Const, Cat, Elaboratable + + +class rab_core(Elaboratable): + + def __init__(self): + self.s_axi_awaddr = Signal(AXI_LITE_ADDR_WIDTH) # input + self.s_axi_awvalid = Signal() # input + self.s_axi_awready = Signal() # output + self.s_axi_wdata = Signal(AXI_LITE_DATA_WIDTH) # input + self.s_axi_wstrb = Signal(FIXME) # input + self.s_axi_wvalid = Signal() # input + self.s_axi_wready = Signal() # output + self.s_axi_araddr = Signal(AXI_LITE_ADDR_WIDTH) # input + self.s_axi_arvalid = Signal() # input + self.s_axi_arready = Signal() # output + self.s_axi_rready = Signal() # input + self.s_axi_rdata = Signal(AXI_LITE_DATA_WIDTH) # output + self.s_axi_rresp = Signal(2) # output + self.s_axi_rvalid = Signal() # output + self.s_axi_bresp = Signal(2) # output + self.s_axi_bvalid = Signal() # output + self.s_axi_bready = Signal() # input + self.int_miss = Signal(N_PORTS) # output + self.int_prot = Signal(N_PORTS) # output + self.int_multi = Signal(N_PORTS) # output + self.int_prefetch = Signal(N_PORTS) # output + self.int_mhf_full = Signal() # output + self.int_axaddr_o = Signal() # output + self.int_axid_o = Signal() # output + self.int_axlen_o = Signal() # output + self.int_axuser_o = Signal() # output + self.port1_addr = Signal() # input + self.port1_id = Signal() # input + self.port1_len = Signal() # input + self.port1_size = Signal() # input + self.port1_addr_valid = Signal(N_PORTS) # input + self.port1_type = Signal(N_PORTS) # input + self.port1_user = Signal() # input + self.port1_sent = Signal(N_PORTS) # input + self.port1_out_addr = Signal() # output + self.port1_cache_coherent = Signal(N_PORTS) # output + self.port1_accept = Signal(N_PORTS) # output + self.port1_drop = Signal(N_PORTS) # output + self.port1_miss = Signal(N_PORTS) # output + self.port2_addr = Signal() # input + self.port2_id = Signal() # input + self.port2_len = Signal() # input + self.port2_size = Signal() # input + self.port2_addr_valid = Signal(N_PORTS) # input + self.port2_type = Signal(N_PORTS) # input + self.port2_user = Signal() # input + self.port2_sent = Signal(N_PORTS) # input + self.port2_out_addr = Signal() # output + self.port2_cache_coherent = Signal(N_PORTS) # output + self.port2_accept = Signal(N_PORTS) # output + self.port2_drop = Signal(N_PORTS) # output + self.port2_miss = Signal(N_PORTS) # output + self.miss_l2_i = Signal(N_PORTS) # input + self.miss_l2_addr_i = Signal() # input + self.miss_l2_id_i = Signal() # input + self.miss_l2_user_i = Signal() # input + self.wdata_l2_o = Signal() # output + self.waddr_l2_o = Signal() # output + self.wren_l2_o = Signal(N_PORTS) # output + + def elaborate(self, platform=None): + m = Module() + return m + + +""" + + + // ███████╗██╗ ██████╗ ███╗ ██╗ █████╗ ██╗ ███████╗ + // ██╔════╝██║██╔════╝ ████╗ ██║██╔══██╗██║ ██╔════╝ + // ███████╗██║██║ ███╗██╔██╗ ██║███████║██║ ███████╗ + // ╚════██║██║██║ ██║██║╚██╗██║██╔══██║██║ ╚════██║ + // ███████║██║╚██████╔╝██║ ╚████║██║ ██║███████╗███████║ + // ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝╚══════╝╚══════╝ + // signals + + localparam integer ENABLE_L2TLB[N_PORTS-1:0] = `EN_L2TLB_ARRAY; + + localparam integer N_SLICES[N_PORTS-1:0] = `N_SLICES_ARRAY; + localparam N_SLICES_TOT = `MY_ARRAY_SUM(N_SLICES,N_PORTS); + localparam N_SLICES_MAX = `N_SLICES_MAX; + + localparam N_REGS = 4*N_SLICES_TOT + 4; + localparam AXI_SIZE_WIDTH = log2(AXI_DATA_WIDTH/8); + + localparam PORT_ID_WIDTH = (N_PORTS < 2) ? 1 : log2(N_PORTS); + localparam MISS_META_WIDTH = PORT_ID_WIDTH + AXI_USER_WIDTH + AXI_ID_WIDTH; + + logic [N_PORTS-1:0] [15:0] p1_burst_size; + logic [N_PORTS-1:0] [15:0] p2_burst_size; + + logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] p1_align_addr; + logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] p2_align_addr; + + logic [N_PORTS-1:0] [AXI_SIZE_WIDTH-1:0] p1_mask; + logic [N_PORTS-1:0] [AXI_SIZE_WIDTH-1:0] p2_mask; + + logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] p1_max_addr; + logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] p2_max_addr; + + logic [N_PORTS-1:0] p1_prefetch; + logic [N_PORTS-1:0] p2_prefetch; + + logic [N_PORTS-1:0] int_rw; + logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] int_addr_min; + logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] int_addr_max; + logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] int_id; + logic [N_PORTS-1:0] [7:0] int_len; + logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] int_user; + + logic [N_PORTS-1:0] hit; + logic [N_PORTS-1:0] prot; + logic [N_PORTS-1:0] prefetch; + + logic [N_PORTS-1:0] no_hit; + logic [N_PORTS-1:0] no_prot; + + logic [N_PORTS-1:0] [N_SLICES_MAX-1:0] hit_slices; + logic [N_PORTS-1:0] [N_SLICES_MAX-1:0] prot_slices; + + logic [N_PORTS-1:0] [AXI_M_ADDR_WIDTH-1:0] out_addr; + logic [N_PORTS-1:0] [AXI_M_ADDR_WIDTH-1:0] out_addr_reg; + + logic [N_PORTS-1:0] cache_coherent; + logic [N_PORTS-1:0] cache_coherent_reg; + + logic [N_PORTS-1:0] select; + reg [N_PORTS-1:0] curr_priority; + + reg [N_PORTS-1:0] multi_hit; + + logic [N_PORTS-1:0] miss_valid_mhf; + logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] miss_addr_mhf; + logic [N_PORTS-1:0] [MISS_META_WIDTH-1:0] miss_meta_mhf; + + logic [N_REGS-1:0] [63:0] int_cfg_regs; + logic [N_PORTS-1:0] [4*N_SLICES_MAX-1:0] [63:0] int_cfg_regs_slices; + + logic L1AllowMultiHit_S; + + genvar z; + + // █████╗ ███████╗███████╗██╗ ██████╗ ███╗ ██╗███╗ ███╗███████╗███╗ ██╗████████╗███████╗ + // ██╔══██╗██╔════╝██╔════╝██║██╔════╝ ████╗ ██║████╗ ████║██╔════╝████╗ ██║╚══██╔══╝██╔════╝ + // ███████║███████╗███████╗██║██║ ███╗██╔██╗ ██║██╔████╔██║█████╗ ██╔██╗ ██║ ██║ ███████╗ + // ██╔══██║╚════██║╚════██║██║██║ ██║██║╚██╗██║██║╚██╔╝██║██╔══╝ ██║╚██╗██║ ██║ ╚════██║ + // ██║ ██║███████║███████║██║╚██████╔╝██║ ╚████║██║ ╚═╝ ██║███████╗██║ ╚████║ ██║ ███████║ + // ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝ + // assignments + + always_comb + begin : PORT_SELECT + var integer idx; + + for (idx=0; idx port1 active + // select = 0 -> port2 active + select[idx] = (curr_priority[idx] & port1_addr_valid[idx]) | ~port2_addr_valid[idx]; + + p1_burst_size[idx] = (port1_len[idx] + 1) << port1_size[idx]; + p2_burst_size[idx] = (port2_len[idx] + 1) << port2_size[idx]; + + // align min addr for max addr computation to allow for smart AXI bursts around the 4k boundary + if (port1_size[idx] == 3'b001) + p1_mask[idx] = 3'b110; + else if (port1_size[idx] == 3'b010) + p1_mask[idx] = 3'b100; + else if (port1_size[idx] == 3'b011) + p1_mask[idx] = 3'b000; + else + p1_mask[idx] = 3'b111; + + p1_align_addr[idx][AXI_S_ADDR_WIDTH-1:AXI_SIZE_WIDTH] = port1_addr[idx][AXI_S_ADDR_WIDTH-1:AXI_SIZE_WIDTH]; + p1_align_addr[idx][AXI_SIZE_WIDTH-1:0] = port1_addr[idx][AXI_SIZE_WIDTH-1:0] & p1_mask[idx]; + + if (port2_size[idx] == 3'b001) + p2_mask[idx] = 3'b110; + else if (port2_size[idx] == 3'b010) + p2_mask[idx] = 3'b100; + else if (port2_size[idx] == 3'b011) + p2_mask[idx] = 3'b000; + else + p2_mask[idx] = 3'b111; + + if (port1_user[idx] == {AXI_USER_WIDTH{1'b1}}) + p1_prefetch[idx] = 1'b1; + else + p1_prefetch[idx] = 1'b0; + + if (port2_user[idx] == {AXI_USER_WIDTH{1'b1}}) + p2_prefetch[idx] = 1'b1; + else + p2_prefetch[idx] = 1'b0; + + p2_align_addr[idx][AXI_S_ADDR_WIDTH-1:AXI_SIZE_WIDTH] = port2_addr[idx][AXI_S_ADDR_WIDTH-1:AXI_SIZE_WIDTH]; + p2_align_addr[idx][AXI_SIZE_WIDTH-1:0] = port2_addr[idx][AXI_SIZE_WIDTH-1:0] & p2_mask[idx]; + + p1_max_addr[idx] = p1_align_addr[idx] + p1_burst_size[idx] - 1; + p2_max_addr[idx] = p2_align_addr[idx] + p2_burst_size[idx] - 1; + + int_addr_min[idx] = select[idx] ? port1_addr[idx] : port2_addr[idx]; + int_addr_max[idx] = select[idx] ? p1_max_addr[idx] : p2_max_addr[idx]; + int_rw[idx] = select[idx] ? port1_type[idx] : port2_type[idx]; + int_id[idx] = select[idx] ? port1_id[idx] : port2_id[idx]; + int_len[idx] = select[idx] ? port1_len[idx] : port2_len[idx]; + int_user[idx] = select[idx] ? port1_user[idx] : port2_user[idx]; + prefetch[idx] = select[idx] ? p1_prefetch[idx] : p2_prefetch[idx]; + + hit [idx] = | hit_slices [idx]; + prot[idx] = | prot_slices[idx]; + + no_hit [idx] = ~hit [idx]; + no_prot[idx] = ~prot[idx]; + + port1_out_addr[idx] = out_addr_reg[idx]; + port2_out_addr[idx] = out_addr_reg[idx]; + + port1_cache_coherent[idx] = cache_coherent_reg[idx]; + port2_cache_coherent[idx] = cache_coherent_reg[idx]; + end + end + + always_comb + begin + var integer idx_port, idx_slice; + var integer reg_num; + reg_num=0; + for ( idx_port = 0; idx_port < N_PORTS; idx_port++ ) begin + for ( idx_slice = 0; idx_slice < 4*N_SLICES[idx_port]; idx_slice++ ) begin + int_cfg_regs_slices[idx_port][idx_slice] = int_cfg_regs[4+reg_num]; + reg_num++; + end + // int_cfg_regs_slices[idx_port][N_SLICES_MAX:N_SLICES[idx_port]] will be dangling + // Fix to zero. Synthesis will remove these signals. + // int_cfg_regs_slices[idx_port][4*N_SLICES_MAX-1:4*N_SLICES[idx_port]] = 0; + end + end + + always @(posedge Clk_CI or negedge Rst_RBI) + begin : PORT_PRIORITY + var integer idx; + if (Rst_RBI == 1'b0) + curr_priority = 'h0; + else begin + for (idx=0; idx