diff --git a/src/main/resources/vsrc/el2_lsu_dccm_mem.scala b/src/main/resources/vsrc/el2_lsu_dccm_mem.scala deleted file mode 100644 index 93b40fb2..00000000 --- a/src/main/resources/vsrc/el2_lsu_dccm_mem.scala +++ /dev/null @@ -1,99 +0,0 @@ -package lsu -import include._ -import lib._ -import snapshot._ -import scala.math._ -import chisel3._ -import chisel3.util._ -class el2_lsu_dccm_mem extends Module { - val io = IO(new Bundle{ - //implicit clk and rst_l - val clk_override = Input(UInt(1.W)) - val scan_mode = Input(UInt(1.W)) - val dccm_wren = Input(UInt(1.W)) - val dccm_rden = Input(UInt(1.W)) - val dccm_wr_addr_lo = Input(UInt(pt1.DCCM_BITS.W)) - val dccm_wr_addr_hi = Input(UInt(pt1.DCCM_BITS.W)) - val dccm_rd_addr_lo = Input(UInt(pt1.DCCM_BITS.W)) - val dccm_rd_addr_hi = Input(UInt(pt1.DCCM_BITS.W)) - val dccm_wr_data_lo = Input(UInt(pt1.DCCM_FDATA_WIDTH.W)) - val dccm_wr_data_hi = Input(UInt(pt1.DCCM_FDATA_WIDTH.W)) - val dccm_rd_data_lo = Output(UInt(pt1.DCCM_FDATA_WIDTH.W)) - val dccm_rd_data_hi = Output(UInt(pt1.DCCM_FDATA_WIDTH.W)) - }) - //DCCM_BYTE_WIDTH = 4 - //DCCM_WIDTH_BITS = 2 - - //DCCM_NUM_BANKS = 4 - //DCCM_BANK_BITS = 2 - - //DCCM_BITS = 16 - //DCCM_FDATA_WIDTH = 39 - - //DCCM_SIZE = 64 - - //DCCM_INDEX_BITS = 12 - //DCCM_INDEX_DEPTH = 4K - - - val DCCM_WIDTH_BITS = log2Ceil(pt1.DCCM_BYTE_WIDTH) - val DCCM_INDEX_BITS = pt1.DCCM_BITS - pt1.DCCM_BANK_BITS - pt1.DCCM_WIDTH_BITS - val DCCM_INDEX_DEPTH = (pt1.DCCM_SIZE*1024)/(pt1.DCCM_BYTE_WIDTH*pt1.DCCM_NUM_BANKS) - - val addr_bank = Wire(Vec(pt1.DCCM_NUM_BANKS,UInt((pt1.DCCM_BITS-pt1.DCCM_BANK_BITS+2).W))) //[15:4] => [11:0] 12 bits per bank => - - //val rd_addr_even = Wire(UInt((pt1.DCCM_BITS-(pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS)).W)) //[15:4] - //val rd_addr_odd = Wire(UInt((pt1.DCCM_BITS-(pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS)).W)) //[15:4] - - // val dccm_bank_dout = Wire(Vec(pt1.DCCM_NUM_BANKS,UInt(pt1.DCCM_FDATA_WIDTH.W))) // 3:0, 38:0 - val wr_data_bank = Wire(Vec(pt1.DCCM_NUM_BANKS,UInt(pt1.DCCM_FDATA_WIDTH.W))) // 3:0, 38:0 - - val dccm_rd_addr_lo_q = RegNext(io.dccm_rd_addr_lo(DCCM_WIDTH_BITS+pt1.DCCM_BANK_BITS-1,DCCM_WIDTH_BITS),0.U) //[3:2] => [1:0] - val dccm_rd_addr_hi_q = RegNext(io.dccm_rd_addr_hi(DCCM_WIDTH_BITS+pt1.DCCM_BANK_BITS-1,DCCM_WIDTH_BITS),0.U) - - - //2+2:2 => 4:2rd_unaligned - val rd_unaligned = io.dccm_rd_addr_lo(pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS-1,DCCM_WIDTH_BITS) =/= io.dccm_rd_addr_hi(pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS-1,DCCM_WIDTH_BITS) - val wr_unaligned = io.dccm_wr_addr_lo(pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS-1,DCCM_WIDTH_BITS) =/= io.dccm_wr_addr_hi(pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS-1,DCCM_WIDTH_BITS) - - - - val wren_bank = Reverse(Cat(VecInit.tabulate(pt1.DCCM_NUM_BANKS)(i=> io.dccm_wren & ((io.dccm_wr_addr_hi(pt1.DCCM_BANK_BITS+1,2) === i.U) | (io.dccm_wr_addr_lo(pt1.DCCM_BANK_BITS+1,2) === i.U)).asUInt))) - val rden_bank = Reverse(Cat(VecInit.tabulate(pt1.DCCM_NUM_BANKS)(i=> io.dccm_rden & ((io.dccm_rd_addr_hi(pt1.DCCM_BANK_BITS+1,2) === i.U) | (io.dccm_rd_addr_lo(pt1.DCCM_BANK_BITS+1,2) === i.U)).asUInt))) - val dccm_clken = Reverse(Cat(VecInit.tabulate(pt1.DCCM_NUM_BANKS)(i=> wren_bank(i) | rden_bank(i) | io.clk_override))) - - - //[15:4] => [11:0] 12 bits per bank - addr_bank := VecInit.tabulate(pt1.DCCM_NUM_BANKS)(i=> Mux(wren_bank(i).asBool, - Mux(((io.dccm_wr_addr_hi(pt1.DCCM_BANK_BITS+1,2) === i.U) & wr_unaligned), - io.dccm_wr_addr_hi(DCCM_INDEX_BITS+pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS-1, pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS), - io.dccm_wr_addr_lo(DCCM_INDEX_BITS+pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS-1, pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS)), - - Mux(((io.dccm_rd_addr_hi(pt1.DCCM_BANK_BITS+1,2) === i.U) & rd_unaligned), - io.dccm_rd_addr_hi(DCCM_INDEX_BITS+pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS-1, pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS), - io.dccm_rd_addr_lo(DCCM_INDEX_BITS+pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS-1, pt1.DCCM_BANK_BITS+DCCM_WIDTH_BITS)))) - - wr_data_bank := VecInit.tabulate(pt1.DCCM_NUM_BANKS)(i=> - Mux(((io.dccm_wr_addr_hi(pt1.DCCM_BANK_BITS+1,2) === i.U) & wr_unaligned), - io.dccm_wr_data_hi(pt1.DCCM_FDATA_WIDTH-1,0), - io.dccm_wr_data_lo(pt1.DCCM_FDATA_WIDTH-1,0))) - - - - - val mem =SyncReadMem(DCCM_INDEX_DEPTH, Vec(pt1.DCCM_NUM_BANKS, UInt(39.W))) - // Create one write port and one read port - (0 to pt1.DCCM_NUM_BANKS-1).foreach(i => - when(wren_bank(i)& dccm_clken(i)){ - mem.write(addr_bank(i), wr_data_bank)}) - - val dccm_bank_dout = VecInit.tabulate(pt1.DCCM_NUM_BANKS)(i => mem.read(addr_bank(i), ~wren_bank(i)& dccm_clken(i)))//ME && ~WE - - io.dccm_rd_data_lo := dccm_bank_dout(dccm_rd_addr_lo_q).asUInt - io.dccm_rd_data_hi := dccm_bank_dout(dccm_rd_addr_hi_q).asUInt -} - -object DCCM extends App{ - println("Generate Verilog") - chisel3.Driver.execute(args, ()=> new el2_lsu_dccm_mem) -} diff --git a/src/main/resources/vsrc/el2_lsu_dccm_mem.v b/src/main/resources/vsrc/el2_lsu_dccm_mem.v new file mode 100644 index 00000000..1608a603 --- /dev/null +++ b/src/main/resources/vsrc/el2_lsu_dccm_mem.v @@ -0,0 +1,235 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or it's 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. + +//******************************************************************************** +// $Id$ +// +// +// Owner: +// Function: DCCM for LSU pipe +// Comments: Single ported memory +// +// +// DC1 -> DC2 -> DC3 -> DC4 (Commit) +// +// //******************************************************************************** + + +module el2_lsu_dccm_mem +#( + parameter DCCM_BYTE_WIDTH, + parameter DCCM_BITS, + parameter DCCM_NUM_BANKS, + parameter DCCM_BANK_BITS, + parameter DCCM_SIZE, + parameter DCCM_FDATA_WIDTH )( + input logic clk, // clock + input logic rst_l, + input logic clk_override, // clock override + + input logic dccm_wren, // write enable + input logic dccm_rden, // read enable + input logic [DCCM_BITS-1:0] dccm_wr_addr_lo, // write address + input logic [DCCM_BITS-1:0] dccm_wr_addr_hi, // write address + input logic [DCCM_BITS-1:0] dccm_rd_addr_lo, // read address + input logic [DCCM_BITS-1:0] dccm_rd_addr_hi, // read address for the upper bank in case of a misaligned access + input logic [DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo, // write data + input logic [DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, // write data + + output logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // read data from the lo bank + output logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // read data from the hi bank + + input logic scan_mode +); + + + localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH); + localparam DCCM_INDEX_BITS = (DCCM_BITS - DCCM_BANK_BITS - DCCM_WIDTH_BITS); + localparam DCCM_INDEX_DEPTH = ((DCCM_SIZE)*1024)/((DCCM_BYTE_WIDTH)*(DCCM_NUM_BANKS)); // Depth of memory bank + + logic [DCCM_NUM_BANKS-1:0] wren_bank; + logic [DCCM_NUM_BANKS-1:0] rden_bank; + logic [DCCM_NUM_BANKS-1:0] [DCCM_BITS-1:(DCCM_BANK_BITS+2)] addr_bank; + logic [DCCM_BITS-1:(DCCM_BANK_BITS+DCCM_WIDTH_BITS)] rd_addr_even, rd_addr_odd; + logic rd_unaligned, wr_unaligned; + logic [DCCM_NUM_BANKS-1:0] [DCCM_FDATA_WIDTH-1:0] dccm_bank_dout; + logic [DCCM_FDATA_WIDTH-1:0] wrdata; + + logic [DCCM_NUM_BANKS-1:0][DCCM_FDATA_WIDTH-1:0] wr_data_bank; + + logic [(DCCM_WIDTH_BITS+DCCM_BANK_BITS-1):DCCM_WIDTH_BITS] dccm_rd_addr_lo_q; + logic [(DCCM_WIDTH_BITS+DCCM_BANK_BITS-1):DCCM_WIDTH_BITS] dccm_rd_addr_hi_q; + + logic [DCCM_NUM_BANKS-1:0] dccm_clken; + + assign rd_unaligned = (dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] != dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]); + assign wr_unaligned = (dccm_wr_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] != dccm_wr_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]); + + // Align the read data + assign dccm_rd_data_lo[DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]][DCCM_FDATA_WIDTH-1:0]; + assign dccm_rd_data_hi[DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]][DCCM_FDATA_WIDTH-1:0]; + + // Generate even/odd address + + // 8 Banks, 16KB each (2048 x 72) + for (genvar i=0; i<32'(DCCM_NUM_BANKS); i++) begin: mem_bank + assign wren_bank[i] = dccm_wren & ((dccm_wr_addr_hi[2+:DCCM_BANK_BITS] == i) | (dccm_wr_addr_lo[2+:DCCM_BANK_BITS] == i)); + assign rden_bank[i] = dccm_rden & ((dccm_rd_addr_hi[2+:DCCM_BANK_BITS] == i) | (dccm_rd_addr_lo[2+:DCCM_BANK_BITS] == i)); + assign addr_bank[i][(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = wren_bank[i] ? (((dccm_wr_addr_hi[2+:DCCM_BANK_BITS] == i) & wr_unaligned) ? + dccm_wr_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] : + dccm_wr_addr_lo[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS]) : + (((dccm_rd_addr_hi[2+:DCCM_BANK_BITS] == i) & rd_unaligned) ? + dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] : + dccm_rd_addr_lo[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS]); + + assign wr_data_bank[i] = ((dccm_wr_addr_hi[2+:DCCM_BANK_BITS] == i) & wr_unaligned) ? dccm_wr_data_hi[DCCM_FDATA_WIDTH-1:0] : dccm_wr_data_lo[DCCM_FDATA_WIDTH-1:0]; + + // clock gating section + assign dccm_clken[i] = (wren_bank[i] | rden_bank[i] | clk_override) ; + // end clock gating section + +`ifdef VERILATOR + el2_ram #(DCCM_INDEX_DEPTH,39) ram ( + // Primary ports + .ME(dccm_clken[i]), + .CLK(clk), + .WE(wren_bank[i]), + .ADR(addr_bank[i]), + .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), + .Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]), + .* + ); + +`else + if (DCCM_INDEX_DEPTH == 32768) begin : dccm + ram_32768x39 dccm_bank ( + // Primary ports + .ME(dccm_clken[i]), + .CLK(clk), + .WE(wren_bank[i]), + .ADR(addr_bank[i]), + .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), + .Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]), + .* + ); + end + else if (DCCM_INDEX_DEPTH == 16384) begin : dccm + ram_16384x39 dccm_bank ( + // Primary ports + .ME(dccm_clken[i]), + .CLK(clk), + .WE(wren_bank[i]), + .ADR(addr_bank[i]), + .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), + .Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]), + .* + ); + end + else if (DCCM_INDEX_DEPTH == 8192) begin : dccm + ram_8192x39 dccm_bank ( + // Primary ports + .ME(dccm_clken[i]), + .CLK(clk), + .WE(wren_bank[i]), + .ADR(addr_bank[i]), + .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), + .Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]), + .* + ); + end + else if (DCCM_INDEX_DEPTH == 4096) begin : dccm + ram_4096x39 dccm_bank ( + // Primary ports + .ME(dccm_clken[i]), + .CLK(clk), + .WE(wren_bank[i]), + .ADR(addr_bank[i]), + .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), + .Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]), + .* + ); + end + else if (DCCM_INDEX_DEPTH == 3072) begin : dccm + ram_3072x39 dccm_bank ( + // Primary ports + .ME(dccm_clken[i]), + .CLK(clk), + .WE(wren_bank[i]), + .ADR(addr_bank[i]), + .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), + .Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]), + .* + ); + end + else if (DCCM_INDEX_DEPTH == 2048) begin : dccm + ram_2048x39 dccm_bank ( + // Primary ports + .ME(dccm_clken[i]), + .CLK(clk), + .WE(wren_bank[i]), + .ADR(addr_bank[i]), + .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), + .Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]), + .* + ); + end + else if (DCCM_INDEX_DEPTH == 1024) begin : dccm + ram_1024x39 dccm_bank ( + // Primary ports + .ME(dccm_clken[i]), + .CLK(clk), + .WE(wren_bank[i]), + .ADR(addr_bank[i]), + .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), + .Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]), + .* + ); + end + else if (DCCM_INDEX_DEPTH == 512) begin : dccm + ram_512x39 dccm_bank ( + // Primary ports + .ME(dccm_clken[i]), + .CLK(clk), + .WE(wren_bank[i]), + .ADR(addr_bank[i]), + .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), + .Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]), + .* + ); + end + else if (DCCM_INDEX_DEPTH == 256) begin : dccm + ram_256x39 dccm_bank ( + // Primary ports + .ME(dccm_clken[i]), + .CLK(clk), + .WE(wren_bank[i]), + .ADR(addr_bank[i]), + .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), + .Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]), + .* + ); + end +`endif // VERILATOR + end : mem_bank + + // Flops + rvdffs #(DCCM_BANK_BITS) rd_addr_lo_ff (.*, .din(dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(1'b1)); + rvdffs #(DCCM_BANK_BITS) rd_addr_hi_ff (.*, .din(dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(1'b1)); + +`undef EL2_LOCAL_DCCM_RAM_TEST_PORTS + +endmodule // el2_lsu_dccm_mem + +