abstractaccelerator/design/ifu/ifu_iccm_mem.sv

144 lines
6.5 KiB
Systemverilog

//********************************************************************************
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the 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.
//********************************************************************************
//********************************************************************************
// Icache closely coupled memory --- ICCM
//********************************************************************************
module ifu_iccm_mem
import swerv_types::*;
(
input logic clk,
input logic rst_l,
input logic clk_override,
input logic iccm_wren,
input logic iccm_rden,
input logic [`RV_ICCM_BITS-1:2] iccm_rw_addr,
input logic [2:0] iccm_wr_size,
input logic [77:0] iccm_wr_data,
output logic [155:0] iccm_rd_data,
input logic scan_mode
);
`include "global.h"
logic [ICCM_NUM_BANKS/4-1:0] wren_bank;
logic [ICCM_NUM_BANKS/4-1:0] rden_bank;
logic [ICCM_NUM_BANKS/4-1:0] iccm_hi0_clken;
logic [ICCM_NUM_BANKS/4-1:0] iccm_hi1_clken;
logic [ICCM_NUM_BANKS/4-1:0] iccm_lo0_clken;
logic [ICCM_NUM_BANKS/4-1:0] iccm_lo1_clken;
logic [ICCM_NUM_BANKS/4-1:0] iccm_hi0_clk ;
logic [ICCM_NUM_BANKS/4-1:0] iccm_hi1_clk ;
logic [ICCM_NUM_BANKS/4-1:0] iccm_lo0_clk ;
logic [ICCM_NUM_BANKS/4-1:0] iccm_lo1_clk ;
logic [ICCM_NUM_BANKS/4-1:0] wren_bank_hi0;
logic [ICCM_NUM_BANKS/4-1:0] wren_bank_lo0;
logic [ICCM_NUM_BANKS/4-1:0] wren_bank_hi1;
logic [ICCM_NUM_BANKS/4-1:0] wren_bank_lo1;
logic [ICCM_NUM_BANKS/4-1:0] [ICCM_INDEX_BITS-1:0] addr_bank;
logic [ICCM_NUM_BANKS/4-1:0] [77:0] iccm_bank_dout_hi;
logic [ICCM_NUM_BANKS/4-1:0] [77:0] iccm_bank_dout_lo;
logic [5:4] iccm_rw_addr_q;
// assign CLK = clk ;
for (genvar i=0; i<ICCM_NUM_BANKS/4; i++) begin: mem_bank
assign wren_bank[i] = iccm_wren & ( (iccm_rw_addr[ICCM_BANK_HI:4] == i) | (ICCM_BANK_BITS == 2));
assign rden_bank[i] = iccm_rden & ( (iccm_rw_addr[ICCM_BANK_HI:4] == i) | (ICCM_BANK_BITS == 2));
assign wren_bank_hi0[i] = wren_bank[i] & iccm_rw_addr[3] & (~iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
assign wren_bank_hi1[i] = wren_bank[i] & iccm_rw_addr[3] & ( iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
assign wren_bank_lo0[i] = wren_bank[i] & ~iccm_rw_addr[3] & (~iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
assign wren_bank_lo1[i] = wren_bank[i] & ~iccm_rw_addr[3] & ( iccm_rw_addr[2] | (iccm_wr_size[1:0] == 2'b11));
assign iccm_hi0_clken[i] = wren_bank_hi0[i] | (rden_bank[i] | clk_override); // Do not override the writes
assign iccm_hi1_clken[i] = wren_bank_hi1[i] | (rden_bank[i] | clk_override); // Do not override the writes
assign iccm_lo0_clken[i] = wren_bank_lo0[i] | (rden_bank[i] | clk_override); // Do not override the writes
assign iccm_lo1_clken[i] = wren_bank_lo1[i] | (rden_bank[i] | clk_override); // Do not override the writes
rvclkhdr iccm_hi0_c1_cgc ( .en(iccm_hi0_clken[i]), .l1clk(iccm_hi0_clk[i]), .* );
rvclkhdr iccm_hi1_c1_cgc ( .en(iccm_hi1_clken[i]), .l1clk(iccm_hi1_clk[i]), .* );
rvclkhdr iccm_lo0_c1_cgc ( .en(iccm_lo0_clken[i]), .l1clk(iccm_lo0_clk[i]), .* );
rvclkhdr iccm_lo1_c1_cgc ( .en(iccm_lo1_clken[i]), .l1clk(iccm_lo1_clk[i]), .* );
assign addr_bank[i][ICCM_INDEX_BITS-1:0] = iccm_rw_addr[ICCM_BITS-1:(ICCM_BANK_BITS+2)];
`RV_ICCM_DATA_CELL iccm_bank_hi0 (
// Primary ports
.CLK(iccm_hi0_clk[i]),
.WE(wren_bank_hi0[i]),
.ADR(addr_bank[i]),
.D(iccm_wr_data[38:0]),
.Q(iccm_bank_dout_hi[i][38:0])
);
`RV_ICCM_DATA_CELL iccm_bank_hi1 (
// Primary ports
.CLK(iccm_hi1_clk[i]),
.WE(wren_bank_hi1[i]),
.ADR(addr_bank[i]),
.D(iccm_wr_data[77:39]),
.Q(iccm_bank_dout_hi[i][77:39])
);
`RV_ICCM_DATA_CELL iccm_bank_lo0 (
// Primary ports
.CLK(iccm_lo0_clk[i]),
.WE(wren_bank_lo0[i]),
.ADR(addr_bank[i]),
.D(iccm_wr_data[38:0]),
.Q(iccm_bank_dout_lo[i][38:0])
);
`RV_ICCM_DATA_CELL iccm_bank_lo1 (
// Primary ports
.CLK(iccm_lo1_clk[i]),
.WE(wren_bank_lo1[i]),
.ADR(addr_bank[i]),
.D(iccm_wr_data[77:39]),
.Q(iccm_bank_dout_lo[i][77:39])
);
end : mem_bank
assign iccm_rd_data[155:0] = (ICCM_BANK_BITS == 2) ? {iccm_bank_dout_hi[0][77:0], iccm_bank_dout_lo[0][77:0]} :
{ iccm_bank_dout_hi[iccm_rw_addr_q[ICCM_BANK_HI:4]][77:0], iccm_bank_dout_lo[iccm_rw_addr_q[ICCM_BANK_HI:4]][77:0] };
if (ICCM_BANK_BITS == 2) begin
assign iccm_rw_addr_q[5:4] = '0;
end
// 8 banks, each bank 8B, we index as 4 banks
else begin
rvdff #(2) rd_addr_ff (.*, .din(iccm_rw_addr[5:4]), .dout(iccm_rw_addr_q[5:4]) );
end
endmodule // ifu_iccm_mem