editing for shard

master
openpowerwtf 1 year ago
parent b330c5d2f1
commit cf9c7b623e

@ -0,0 +1,57 @@
// © IBM Corp. 2022
// Licensed under the Apache License, Version 2.0 (the "License"), as modified by the terms below; you may not use the files in this
// repository except in compliance with the License as modified.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Modified Terms:
//
// 1) For the purpose of the patent license granted to you in Section 3 of the License, the "Work" hereby includes implementations of
// the work of authorship in physical form.
//
// Unless required by applicable law or agreed to in writing, the reference design 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 & limitations under the License.
//
// Brief explanation of modifications:
//
// Modification 1: This modification extends the patent license to an implementation of the Work in physical form i.e.,
// it unambiguously permits a user to make & use the physical chip.

`timescale 1 ps / 1 ps

// Custom local eval cell (domino precharge and L/R subarray bit select)
module local_eval (

input PRE_b,
input RBL_L,
input RBL_R,
output RLB_O_b

);

sky130_fd_pr__pfet_01v8 PRE_L (.G(PRE_b), .S(RBL_L));
sky130_fd_pr__pfet_01v8 PRE_R (.G(PRE_b), .S(RBL_R));
sky130_fd_sc_hd__nand2_1 SEL (.A(RBL_L), .B(RBL_R), .Y(RBL_O_b));

endmodule

// 2 reads x 12 bits x 2 ports (one quad)
module local_eval_comp (

input PRE0_b,
input [0:11] RBL0_L,
input [0:11] RBL0_R,
output [0:11] RLB0_O_b,
input PRE1_b,
input [0:11] RBL1_L,
input [0:11] RBL1_R,
output [0:11] RLB1_O_b

);

for (i = 0; i < 12; i = i + 1) begin
local_eval_eval_0 (.PRE_b(PRE0_b), .RBL_L(RBL0_L[i]), .RBL_R(RBL0_R[i]), .RBL_Ob(RBL0_0_b[i]));
local_eval eval_1 (.PRE_b(PRE1_b), .RBL_L(RBL1_L[i]), .RBL_R(RBL1_R[i]), .RBL_Ob(RBL1_0_b[i]));
end

endmodule

@ -0,0 +1,508 @@
// © IBM Corp. 2022
// Licensed under the Apache License, Version 2.0 (the "License"), as modified by the terms below; you may not use the files in this
// repository except in compliance with the License as modified.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Modified Terms:
//
// 1) For the purpose of the patent license granted to you in Section 3 of the License, the "Work" hereby includes implementations of
// the work of authorship in physical form.
//
// Unless required by applicable law or agreed to in writing, the reference design 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 & limitations under the License.
//
// Brief explanation of modifications:
//
// Modification 1: This modification extends the patent license to an implementation of the Work in physical form i.e.,
// it unambiguously permits a user to make & use the physical chip.


// Behavioral for 64x24 toysram (sdr or ddr), 'shard' (semi-hard, using 16x12 hard subarrays)

`timescale 1 ps / 1 ps

module regfile_shard_2r1w_64x24 (

input rd0_c_na0,
input rd0_c_a0,
input rd0_na1_na2,
input rd0_na1_a2,
input rd0_a1_na2,
input rd0_a1_a2,
input rd0_na3,
input rd0_a3,
input rd0_na4_na5,
input rd0_na4_a5,
input rd0_a4_na5,
input rd0_a4_a5,
output [0:31] rd0_dat,

input rd1_c_na0,
input rd1_c_a0,
input rd1_na1_na2,
input rd1_na1_a2,
input rd1_a1_na2,
input rd1_a1_a2,
input rd1_na3,
input rd1_a3,
input rd1_na4_na5,
input rd1_na4_a5,
input rd1_a4_na5,
input rd1_a4_a5,
output [0:31] rd1_dat,

input wr0_c_na0,
input wr0_c_a0,
input wr0_na1_na2,
input wr0_na1_a2,
input wr0_a1_na2,
input wr0_a1_a2,
input wr0_na3,
input wr0_a3,
input wr0_na4_na5,
input wr0_na4_a5,
input wr0_a4_na5,
input wr0_a4_a5,
input [0:31] wr0_dat

);

// word & bit selects

wire [0:15] rwl0_00_15_00_11;
wire [0:15] rwl0_00_15_12_23;
wire [0:15] rwl1_00_15_00_11;
wire [0:15] rwl1_00_15_12_23;
wire [0:15] wwl_00_15_00_11;
wire [0:15] wwl_00_15_12_23;
wire [0:11] rbl0_00_15_00_11;
wire [0:11] rbl0_00_15_12_23;
wire [0:11] rbl1_00_15_00_11;
wire [0:11] rbl1_00_15_12_23;
wire [0:11] wbl_00_15_00_11;
wire [0:11] wbl_00_15_12_23;

wire [0:15] rwl0_16_31_00_11;
wire [0:15] rwl0_16_31_12_23;
wire [0:15] rwl1_16_31_00_11;
wire [0:15] rwl1_16_31_12_23;
wire [0:15] wwl_16_31_00_11;
wire [0:15] wwl_16_31_12_23;
wire [0:11] rbl0_16_31_00_11;
wire [0:11] rbl0_16_31_12_23;
wire [0:11] rbl1_16_31_00_11;
wire [0:11] rbl1_16_31_12_23;
wire [0:11] wbl_16_31_00_11;
wire [0:11] wbl_16_31_12_23;

wire [0:15] rwl0_32_47_00_11;
wire [0:15] rwl0_32_47_12_23;
wire [0:15] rwl1_32_47_00_11;
wire [0:15] rwl1_32_47_12_23;
wire [0:15] wwl_32_47_00_11;
wire [0:15] wwl_32_47_12_23;
wire [0:11] rbl0_32_47_00_11;
wire [0:11] rbl0_32_47_12_23;
wire [0:11] rbl1_32_47_00_11;
wire [0:11] rbl1_32_47_12_23;
wire [0:11] wbl_32_47_00_11;
wire [0:11] wbl_32_47_12_23;

wire [0:15] rwl0_48_63_00_11;
wire [0:15] rwl0_48_63_12_23;
wire [0:15] rwl1_48_63_00_11;
wire [0:15] rwl1_48_63_12_23;
wire [0:15] wwl_48_63_00_11;
wire [0:15] wwl_48_63_12_23;
wire [0:11] rbl0_48_63_00_11;
wire [0:11] rbl0_48_63_12_23;
wire [0:11] rbl1_48_63_00_11;
wire [0:11] rbl1_48_63_12_23;
wire [0:11] wbl_48_63_00_11;
wire [0:11] wbl_48_63_12_23;

// subarray cells; 4x2 16w/12b subarrays

// words 00:15
toysram_16x12 w00 (
.RWL0(rwl0_00_15_00_11),
.RWL1(rwl1_00_15_00_11),
.WWL(wwl_00_15_00_11),
.RBL0(rbl0_00_15_00_11),
.RBL1(rbl1_00_15_00_11),
.WBL(wbl_00_15_00_11),
.WBLb(~wbl_00_15_00_11)
);
toysram_16x12 w01 (
.RWL0(rwl0_00_15_12_23),
.RWL1(rwl1_00_15_12_23),
.WWL(wwl_00_15_12_23),
.RBL0(rbl0_00_15_12_23),
.RBL1(rbl1_00_15_12_23),
.WBL(wbl_00_15_12_23),
.WBLb(~wbl_00_15_12_23)
);

// words 16:31
toysram_16x12 w10 (
.RWL0(rwl0_16_31_00_11),
.RWL1(rwl1_16_31_00_11),
.WWL(wwl_16_31_00_11),
.RBL0(rbl0_16_31_00_11),
.RBL1(rbl1_16_31_00_11),
.WBL(wbl_16_31_00_11),
.WBL(~wbl_16_31_00_11)
);
toysram_16x12 w11 (
.RWL0(rwl0_16_31_12_23),
.RWL1(rwl1_16_31_12_23),
.WWL(wwl_16_31_12_23),
.RBL0(rbl0_16_31_12_23),
.RBL1(rbl1_16_31_12_23),
.WBL(wbl_16_31_12_23),
.WBL(~wbl_16_31_12_23)
);

// words 32:47
toysram_16x12 w20 (
.RWL0(rwl0_32_47_00_11),
.RWL1(rwl1_32_47_00_11),
.WWL(wwl_32_47_00_11),
.RBL0(rbl0_32_47_00_11),
.RBL1(rbl1_32_47_00_11),
.WBL(wbl_32_47_00_11),
.WBLb(~wbl_32_47_00_11)
);
toysram_16x12 w21 (
.RWL0(rwl0_32_47_12_23),
.RWL1(rwl1_32_47_12_23),
.WWL(wwl_32_47_12_23),
.RBL0(rbl0_32_47_12_23),
.RBL1(rbl1_32_47_12_23),
.WBL(wbl_32_47_12_23),
.WBLb(~wbl_32_47_12_23)
);

// words 48:63
toysram_16x12 w30 (
.RWL0(rwl0_48_63_00_11),
.RWL1(rwl1_48_63_00_11),
.WWL(wwl_48_63_00_11),
.RBL0(rbl0_48_63_00_11),
.RBL1(rbl1_48_63_00_11),
.WBL(wbl_48_63_00_11),
.WBLb(~wbl_48_63_00_11)
);
toysram_16x12 w31 (
.RWL0(rwl0_48_63_12_23),
.RWL1(rwl1_48_63_12_23),
.WWL(wwl_48_63_12_23),
.RBL0(rbl0_48_63_12_23),
.RBL1(rbl1_48_63_12_23),
.WBL(wbl_48_63_12_23),
.WBLb(~wbl_48_63_12_23)
);

// word lines

assign rwl0_00_15_00_11[0] = rd0_c_na0 & rd0_na1_na2 & rd0_na3 & rd0_na4_na5;
assign rwl1_00_15_00_11[0] = rd1_c_na0 & rd1_na1_na2 & rd1_na3 & rd1_na4_na5;
assign wwl_00_15_00_11[0] = wr0_c_na0 & wr0_na1_na2 & wr0_na3 & wr0_na4_na5;

assign rwl0_00_15_00_11[1] = rd0_c_na0 & rd0_na1_na2 & rd0_na3 & rd0_na4_a5;
assign rwl1_00_15_00_11[1] = rd1_c_na0 & rd1_na1_na2 & rd1_na3 & rd1_na4_a5;
assign wwl_00_15_00_11[1] = wr0_c_na0 & wr0_na1_na2 & wr0_na3 & wr0_na4_a5;

assign rwl0_00_15_00_11[2] = rd0_c_na0 & rd0_na1_na2 & rd0_na3 & rd0_a4_na5;
assign rwl1_00_15_00_11[2] = rd1_c_na0 & rd1_na1_na2 & rd1_na3 & rd1_a4_na5;
assign wwl_00_15_00_11[2] = wr0_c_na0 & wr0_na1_na2 & wr0_na3 & wr0_a4_na5;

assign rwl0_00_15_00_11[3] = rd0_c_na0 & rd0_na1_na2 & rd0_na3 & rd0_a4_a5;
assign rwl1_00_15_00_11[3] = rd1_c_na0 & rd1_na1_na2 & rd1_na3 & rd1_a4_a5;
assign wwl_00_15_00_11[3] = wr0_c_na0 & wr0_na1_na2 & wr0_na3 & wr0_a4_a5;

assign rwl0_00_15_00_11[4] = rd0_c_na0 & rd0_na1_na2 & rd0_a3 & rd0_na4_na5;
assign rwl1_00_15_00_11[4] = rd1_c_na0 & rd1_na1_na2 & rd1_a3 & rd1_na4_na5;
assign wwl_00_15_00_11[4] = wr0_c_na0 & wr0_na1_na2 & wr0_a3 & wr0_na4_na5;

assign rwl0_00_15_00_11[5] = rd0_c_na0 & rd0_na1_na2 & rd0_a3 & rd0_na4_a5;
assign rwl1_00_15_00_11[5] = rd1_c_na0 & rd1_na1_na2 & rd1_a3 & rd1_na4_a5;
assign wwl_00_15_00_11[5] = wr0_c_na0 & wr0_na1_na2 & wr0_a3 & wr0_na4_a5;

assign rwl0_00_15_00_11[6] = rd0_c_na0 & rd0_na1_na2 & rd0_a3 & rd0_a4_na5;
assign rwl1_00_15_00_11[6] = rd1_c_na0 & rd1_na1_na2 & rd1_a3 & rd1_a4_na5;
assign wwl_00_15_00_11[6] = wr0_c_na0 & wr0_na1_na2 & wr0_a3 & wr0_a4_na5;

assign rwl0_00_15_00_11[7] = rd0_c_na0 & rd0_na1_na2 & rd0_a3 & rd0_a4_a5;
assign rwl1_00_15_00_11[7] = rd1_c_na0 & rd1_na1_na2 & rd1_a3 & rd1_a4_a5;
assign wwl_00_15_00_11[7] = wr0_c_na0 & wr0_na1_na2 & wr0_a3 & wr0_a4_a5;

assign rwl0_00_15_00_11[8] = rd0_c_na0 & rd0_na1_a2 & rd0_na3 & rd0_na4_na5;
assign rwl1_00_15_00_11[8] = rd1_c_na0 & rd1_na1_a2 & rd1_na3 & rd1_na4_na5;
assign wwl_00_15_00_11[8] = wr0_c_na0 & wr0_na1_a2 & wr0_na3 & wr0_na4_na5;

assign rwl0_00_15_00_11[9] = rd0_c_na0 & rd0_na1_a2 & rd0_na3 & rd0_na4_a5;
assign rwl1_00_15_00_11[9] = rd1_c_na0 & rd1_na1_a2 & rd1_na3 & rd1_na4_a5;
assign wwl_00_15_00_11[9] = wr0_c_na0 & wr0_na1_a2 & wr0_na3 & wr0_na4_a5;

assign rwl0_00_15_00_11[10] = rd0_c_na0 & rd0_na1_a2 & rd0_na3 & rd0_a4_na5;
assign rwl1_00_15_00_11[10] = rd1_c_na0 & rd1_na1_a2 & rd1_na3 & rd1_a4_na5;
assign wwl_00_15_00_11[10] = wr0_c_na0 & wr0_na1_a2 & wr0_na3 & wr0_a4_na5;

assign rwl0_00_15_00_11[11] = rd0_c_na0 & rd0_na1_a2 & rd0_na3 & rd0_a4_a5;
assign rwl1_00_15_00_11[11] = rd1_c_na0 & rd1_na1_a2 & rd1_na3 & rd1_a4_a5;
assign wwl_00_15_00_11[11] = wr0_c_na0 & wr0_na1_a2 & wr0_na3 & wr0_a4_a5;

assign rwl0_00_15_00_11[12] = rd0_c_na0 & rd0_na1_a2 & rd0_a3 & rd0_na4_na5;
assign rwl1_00_15_00_11[12] = rd1_c_na0 & rd1_na1_a2 & rd1_a3 & rd1_na4_na5;
assign wwl_00_15_00_11[12] = wr0_c_na0 & wr0_na1_a2 & wr0_a3 & wr0_na4_na5;

assign rwl0_00_15_00_11[13] = rd0_c_na0 & rd0_na1_a2 & rd0_a3 & rd0_na4_a5;
assign rwl1_00_15_00_11[13] = rd1_c_na0 & rd1_na1_a2 & rd1_a3 & rd1_na4_a5;
assign wwl_00_15_00_11[13] = wr0_c_na0 & wr0_na1_a2 & wr0_a3 & wr0_na4_a5;

assign rwl0_00_15_00_11[14] = rd0_c_na0 & rd0_na1_a2 & rd0_a3 & rd0_a4_na5;
assign rwl1_00_15_00_11[14] = rd1_c_na0 & rd1_na1_a2 & rd1_a3 & rd1_a4_na5;
assign wwl_00_15_00_11[14] = wr0_c_na0 & wr0_na1_a2 & wr0_a3 & wr0_a4_na5;

assign rwl0_00_15_00_11[15] = rd0_c_na0 & rd0_na1_a2 & rd0_a3 & rd0_a4_a5;
assign rwl1_00_15_00_11[15] = rd1_c_na0 & rd1_na1_a2 & rd1_a3 & rd1_a4_a5;
assign wwl_00_15_00_11[15] = wr0_c_na0 & wr0_na1_a2 & wr0_a3 & wr0_a4_a5;

assign rwl0_00_15_12_23 = rwl0_00_15_00_11;
assign rwl1_00_15_12_23 = rwl1_00_15_00_11;
assign wwl_00_15_12_23 = wwl_00_15_00_11;

assign rwl0_16_31_00_11[0] = rd0_c_na0 & rd0_a1_na2 & rd0_na3 & rd0_na4_na5;
assign rwl1_16_31_00_11[0] = rd1_c_na0 & rd1_a1_na2 & rd1_na3 & rd1_na4_na5;
assign wwl_16_31_00_11[0] = wr0_c_na0 & wr0_a1_na2 & wr0_na3 & wr0_na4_na5;

assign rwl0_16_31_00_11[1] = rd0_c_na0 & rd0_a1_na2 & rd0_na3 & rd0_na4_a5;
assign rwl1_16_31_00_11[1] = rd1_c_na0 & rd1_a1_na2 & rd1_na3 & rd1_na4_a5;
assign wwl_16_31_00_11[1] = wr0_c_na0 & wr0_a1_na2 & wr0_na3 & wr0_na4_a5;

assign rwl0_16_31_00_11[2] = rd0_c_na0 & rd0_a1_na2 & rd0_na3 & rd0_a4_na5;
assign rwl1_16_31_00_11[2] = rd1_c_na0 & rd1_a1_na2 & rd1_na3 & rd1_a4_na5;
assign wwl_16_31_00_11[2] = wr0_c_na0 & wr0_a1_na2 & wr0_na3 & wr0_a4_na5;

assign rwl0_16_31_00_11[3] = rd0_c_na0 & rd0_a1_na2 & rd0_na3 & rd0_a4_a5;
assign rwl1_16_31_00_11[3] = rd1_c_na0 & rd1_a1_na2 & rd1_na3 & rd1_a4_a5;
assign wwl_16_31_00_11[3] = wr0_c_na0 & wr0_a1_na2 & wr0_na3 & wr0_a4_a5;

assign rwl0_16_31_00_11[4] = rd0_c_na0 & rd0_a1_na2 & rd0_a3 & rd0_na4_na5;
assign rwl1_16_31_00_11[4] = rd1_c_na0 & rd1_a1_na2 & rd1_a3 & rd1_na4_na5;
assign wwl_16_31_00_11[4] = wr0_c_na0 & wr0_a1_na2 & wr0_a3 & wr0_na4_na5;

assign rwl0_16_31_00_11[5] = rd0_c_na0 & rd0_a1_na2 & rd0_a3 & rd0_na4_a5;
assign rwl1_16_31_00_11[5] = rd1_c_na0 & rd1_a1_na2 & rd1_a3 & rd1_na4_a5;
assign wwl_16_31_00_11[5] = wr0_c_na0 & wr0_a1_na2 & wr0_a3 & wr0_na4_a5;

assign rwl0_16_31_00_11[6] = rd0_c_na0 & rd0_a1_na2 & rd0_a3 & rd0_a4_na5;
assign rwl1_16_31_00_11[6] = rd1_c_na0 & rd1_a1_na2 & rd1_a3 & rd1_a4_na5;
assign wwl_16_31_00_11[6] = wr0_c_na0 & wr0_a1_na2 & wr0_a3 & wr0_a4_na5;

assign rwl0_16_31_00_11[7] = rd0_c_na0 & rd0_a1_na2 & rd0_a3 & rd0_a4_a5;
assign rwl1_16_31_00_11[7] = rd1_c_na0 & rd1_a1_na2 & rd1_a3 & rd1_a4_a5;
assign wwl_16_31_00_11[7] = wr0_c_na0 & wr0_a1_na2 & wr0_a3 & wr0_a4_a5;

assign rwl0_16_31_00_11[8] = rd0_c_na0 & rd0_a1_a2 & rd0_na3 & rd0_na4_na5;
assign rwl1_16_31_00_11[8] = rd1_c_na0 & rd1_a1_a2 & rd1_na3 & rd1_na4_na5;
assign wwl_16_31_00_11[8] = wr0_c_na0 & wr0_a1_a2 & wr0_na3 & wr0_na4_na5;

assign rwl0_16_31_00_11[9] = rd0_c_na0 & rd0_a1_a2 & rd0_na3 & rd0_na4_a5;
assign rwl1_16_31_00_11[9] = rd1_c_na0 & rd1_a1_a2 & rd1_na3 & rd1_na4_a5;
assign wwl_16_31_00_11[9] = wr0_c_na0 & wr0_a1_a2 & wr0_na3 & wr0_na4_a5;

assign rwl0_16_31_00_11[10] = rd0_c_na0 & rd0_a1_a2 & rd0_na3 & rd0_a4_na5;
assign rwl1_16_31_00_11[10] = rd1_c_na0 & rd1_a1_a2 & rd1_na3 & rd1_a4_na5;
assign wwl_16_31_00_11[10] = wr0_c_na0 & wr0_a1_a2 & wr0_na3 & wr0_a4_na5;

assign rwl0_16_31_00_11[11] = rd0_c_na0 & rd0_a1_a2 & rd0_na3 & rd0_a4_a5;
assign rwl1_16_31_00_11[11] = rd1_c_na0 & rd1_a1_a2 & rd1_na3 & rd1_a4_a5;
assign wwl_16_31_00_11[11] = wr0_c_na0 & wr0_a1_a2 & wr0_na3 & wr0_a4_a5;

assign rwl0_16_31_00_11[12] = rd0_c_na0 & rd0_a1_a2 & rd0_a3 & rd0_na4_na5;
assign rwl1_16_31_00_11[12] = rd1_c_na0 & rd1_a1_a2 & rd1_a3 & rd1_na4_na5;
assign wwl_16_31_00_11[12] = wr0_c_na0 & wr0_a1_a2 & wr0_a3 & wr0_na4_na5;

assign rwl0_16_31_00_11[13] = rd0_c_na0 & rd0_a1_a2 & rd0_a3 & rd0_na4_a5;
assign rwl1_16_31_00_11[13] = rd1_c_na0 & rd1_a1_a2 & rd1_a3 & rd1_na4_a5;
assign wwl_16_31_00_11[13] = wr0_c_na0 & wr0_a1_a2 & wr0_a3 & wr0_na4_a5;

assign rwl0_16_31_00_11[14] = rd0_c_na0 & rd0_a1_a2 & rd0_a3 & rd0_a4_na5;
assign rwl1_16_31_00_11[14] = rd1_c_na0 & rd1_a1_a2 & rd1_a3 & rd1_a4_na5;
assign wwl_16_31_00_11[14] = wr0_c_na0 & wr0_a1_a2 & wr0_a3 & wr0_a4_na5;

assign rwl0_16_31_00_11[15] = rd0_c_na0 & rd0_a1_a2 & rd0_a3 & rd0_a4_a5;
assign rwl1_16_31_00_11[15] = rd1_c_na0 & rd1_a1_a2 & rd1_a3 & rd1_a4_a5;
assign wwl_16_31_00_11[15] = wr0_c_na0 & wr0_a1_a2 & wr0_a3 & wr0_a4_a5;

assign rwl0_16_31_12_23 = rwl0_16_31_00_11;
assign rwl1_16_31_12_23 = rwl1_16_31_00_11;
assign wwl_16_31_12_23 = wwl_16_31_00_11;

assign rwl0_32_47_00_11[0] = rd0_c_a0 & rd0_na1_na2 & rd0_na3 & rd0_na4_na5;
assign rwl1_32_47_00_11[0] = rd1_c_a0 & rd1_na1_na2 & rd1_na3 & rd1_na4_na5;
assign wwl_32_47_00_11[0] = wr0_c_a0 & wr0_na1_na2 & wr0_na3 & wr0_na4_na5;

assign rwl0_32_47_00_11[1] = rd0_c_a0 & rd0_na1_na2 & rd0_na3 & rd0_na4_a5;
assign rwl1_32_47_00_11[1] = rd1_c_a0 & rd1_na1_na2 & rd1_na3 & rd1_na4_a5;
assign wwl_32_47_00_11[1] = wr0_c_a0 & wr0_na1_na2 & wr0_na3 & wr0_na4_a5;

assign rwl0_32_47_00_11[2] = rd0_c_a0 & rd0_na1_na2 & rd0_na3 & rd0_a4_na5;
assign rwl1_32_47_00_11[2] = rd1_c_a0 & rd1_na1_na2 & rd1_na3 & rd1_a4_na5;
assign wwl_32_47_00_11[2] = wr0_c_a0 & wr0_na1_na2 & wr0_na3 & wr0_a4_na5;

assign rwl0_32_47_00_11[3] = rd0_c_a0 & rd0_na1_na2 & rd0_na3 & rd0_a4_a5;
assign rwl1_32_47_00_11[3] = rd1_c_a0 & rd1_na1_na2 & rd1_na3 & rd1_a4_a5;
assign wwl_32_47_00_11[3] = wr0_c_a0 & wr0_na1_na2 & wr0_na3 & wr0_a4_a5;

assign rwl0_32_47_00_11[4] = rd0_c_a0 & rd0_na1_na2 & rd0_a3 & rd0_na4_na5;
assign rwl1_32_47_00_11[4] = rd1_c_a0 & rd1_na1_na2 & rd1_a3 & rd1_na4_na5;
assign wwl_32_47_00_11[4] = wr0_c_a0 & wr0_na1_na2 & wr0_a3 & wr0_na4_na5;

assign rwl0_32_47_00_11[5] = rd0_c_a0 & rd0_na1_na2 & rd0_a3 & rd0_na4_a5;
assign rwl1_32_47_00_11[5] = rd1_c_a0 & rd1_na1_na2 & rd1_a3 & rd1_na4_a5;
assign wwl_32_47_00_11[5] = wr0_c_a0 & wr0_na1_na2 & wr0_a3 & wr0_na4_a5;

assign rwl0_32_47_00_11[6] = rd0_c_a0 & rd0_na1_na2 & rd0_a3 & rd0_a4_na5;
assign rwl1_32_47_00_11[6] = rd1_c_a0 & rd1_na1_na2 & rd1_a3 & rd1_a4_na5;
assign wwl_32_47_00_11[6] = wr0_c_a0 & wr0_na1_na2 & wr0_a3 & wr0_a4_na5;

assign rwl0_32_47_00_11[7] = rd0_c_a0 & rd0_na1_na2 & rd0_a3 & rd0_a4_a5;
assign rwl1_32_47_00_11[7] = rd1_c_a0 & rd1_na1_na2 & rd1_a3 & rd1_a4_a5;
assign wwl_32_47_00_11[7] = wr0_c_a0 & wr0_na1_na2 & wr0_a3 & wr0_a4_a5;

assign rwl0_32_47_00_11[8] = rd0_c_a0 & rd0_na1_a2 & rd0_na3 & rd0_na4_na5;
assign rwl1_32_47_00_11[8] = rd1_c_a0 & rd1_na1_a2 & rd1_na3 & rd1_na4_na5;
assign wwl_32_47_00_11[8] = wr0_c_a0 & wr0_na1_a2 & wr0_na3 & wr0_na4_na5;

assign rwl0_32_47_00_11[9] = rd0_c_a0 & rd0_na1_a2 & rd0_na3 & rd0_na4_a5;
assign rwl1_32_47_00_11[9] = rd1_c_a0 & rd1_na1_a2 & rd1_na3 & rd1_na4_a5;
assign wwl_32_47_00_11[9] = wr0_c_a0 & wr0_na1_a2 & wr0_na3 & wr0_na4_a5;

assign rwl0_32_47_00_11[10] = rd0_c_a0 & rd0_na1_a2 & rd0_na3 & rd0_a4_na5;
assign rwl1_32_47_00_11[10] = rd1_c_a0 & rd1_na1_a2 & rd1_na3 & rd1_a4_na5;
assign wwl_32_47_00_11[10] = wr0_c_a0 & wr0_na1_a2 & wr0_na3 & wr0_a4_na5;

assign rwl0_32_47_00_11[11] = rd0_c_a0 & rd0_na1_a2 & rd0_na3 & rd0_a4_a5;
assign rwl1_32_47_00_11[11] = rd1_c_a0 & rd1_na1_a2 & rd1_na3 & rd1_a4_a5;
assign wwl_32_47_00_11[11] = wr0_c_a0 & wr0_na1_a2 & wr0_na3 & wr0_a4_a5;

assign rwl0_32_47_00_11[12] = rd0_c_a0 & rd0_na1_a2 & rd0_a3 & rd0_na4_na5;
assign rwl1_32_47_00_11[12] = rd1_c_a0 & rd1_na1_a2 & rd1_a3 & rd1_na4_na5;
assign wwl_32_47_00_11[12] = wr0_c_a0 & wr0_na1_a2 & wr0_a3 & wr0_na4_na5;

assign rwl0_32_47_00_11[13] = rd0_c_a0 & rd0_na1_a2 & rd0_a3 & rd0_na4_a5;
assign rwl1_32_47_00_11[13] = rd1_c_a0 & rd1_na1_a2 & rd1_a3 & rd1_na4_a5;
assign wwl_32_47_00_11[13] = wr0_c_a0 & wr0_na1_a2 & wr0_a3 & wr0_na4_a5;

assign rwl0_32_47_00_11[14] = rd0_c_a0 & rd0_na1_a2 & rd0_a3 & rd0_a4_na5;
assign rwl1_32_47_00_11[14] = rd1_c_a0 & rd1_na1_a2 & rd1_a3 & rd1_a4_na5;
assign wwl_32_47_00_11[14] = wr0_c_a0 & wr0_na1_a2 & wr0_a3 & wr0_a4_na5;

assign rwl0_32_47_00_11[15] = rd0_c_a0 & rd0_na1_a2 & rd0_a3 & rd0_a4_a5;
assign rwl1_32_47_00_11[15] = rd1_c_a0 & rd1_na1_a2 & rd1_a3 & rd1_a4_a5;
assign wwl_32_47_00_11[15] = wr0_c_a0 & wr0_na1_a2 & wr0_a3 & wr0_a4_a5;

assign rwl0_32_47_12_23 = rwl0_32_47_00_11;
assign rwl1_32_47_12_23 = rwl1_32_47_00_11;
assign wwl_32_47_12_23 = wwl_32_47_00_11;

assign rwl0_48_63_00_11[0] = rd0_c_a0 & rd0_a1_na2 & rd0_na3 & rd0_na4_na5;
assign rwl1_48_63_00_11[0] = rd1_c_a0 & rd1_a1_na2 & rd1_na3 & rd1_na4_na5;
assign wwl_48_63_00_11[0] = wr0_c_a0 & wr0_a1_na2 & wr0_na3 & wr0_na4_na5;

assign rwl0_48_63_00_11[1] = rd0_c_a0 & rd0_a1_na2 & rd0_na3 & rd0_na4_a5;
assign rwl1_48_63_00_11[1] = rd1_c_a0 & rd1_a1_na2 & rd1_na3 & rd1_na4_a5;
assign wwl_48_63_00_11[1] = wr0_c_a0 & wr0_a1_na2 & wr0_na3 & wr0_na4_a5;

assign rwl0_48_63_00_11[2] = rd0_c_a0 & rd0_a1_na2 & rd0_na3 & rd0_a4_na5;
assign rwl1_48_63_00_11[2] = rd1_c_a0 & rd1_a1_na2 & rd1_na3 & rd1_a4_na5;
assign wwl_48_63_00_11[2] = wr0_c_a0 & wr0_a1_na2 & wr0_na3 & wr0_a4_na5;

assign rwl0_48_63_00_11[3] = rd0_c_a0 & rd0_a1_na2 & rd0_na3 & rd0_a4_a5;
assign rwl1_48_63_00_11[3] = rd1_c_a0 & rd1_a1_na2 & rd1_na3 & rd1_a4_a5;
assign wwl_48_63_00_11[3] = wr0_c_a0 & wr0_a1_na2 & wr0_na3 & wr0_a4_a5;

assign rwl0_48_63_00_11[4] = rd0_c_a0 & rd0_a1_na2 & rd0_a3 & rd0_na4_na5;
assign rwl1_48_63_00_11[4] = rd1_c_a0 & rd1_a1_na2 & rd1_a3 & rd1_na4_na5;
assign wwl_48_63_00_11[4] = wr0_c_a0 & wr0_a1_na2 & wr0_a3 & wr0_na4_na5;

assign rwl0_48_63_00_11[5] = rd0_c_a0 & rd0_a1_na2 & rd0_a3 & rd0_na4_a5;
assign rwl1_48_63_00_11[5] = rd1_c_a0 & rd1_a1_na2 & rd1_a3 & rd1_na4_a5;
assign wwl_48_63_00_11[5] = wr0_c_a0 & wr0_a1_na2 & wr0_a3 & wr0_na4_a5;

assign rwl0_48_63_00_11[6] = rd0_c_a0 & rd0_a1_na2 & rd0_a3 & rd0_a4_na5;
assign rwl1_48_63_00_11[6] = rd1_c_a0 & rd1_a1_na2 & rd1_a3 & rd1_a4_na5;
assign wwl_48_63_00_11[6] = wr0_c_a0 & wr0_a1_na2 & wr0_a3 & wr0_a4_na5;

assign rwl0_48_63_00_11[7] = rd0_c_a0 & rd0_a1_na2 & rd0_a3 & rd0_a4_a5;
assign rwl1_48_63_00_11[7] = rd1_c_a0 & rd1_a1_na2 & rd1_a3 & rd1_a4_a5;
assign wwl_48_63_00_11[7] = wr0_c_a0 & wr0_a1_na2 & wr0_a3 & wr0_a4_a5;

assign rwl0_48_63_00_11[8] = rd0_c_a0 & rd0_a1_a2 & rd0_na3 & rd0_na4_na5;
assign rwl1_48_63_00_11[8] = rd1_c_a0 & rd1_a1_a2 & rd1_na3 & rd1_na4_na5;
assign wwl_48_63_00_11[8] = wr0_c_a0 & wr0_a1_a2 & wr0_na3 & wr0_na4_na5;

assign rwl0_48_63_00_11[9] = rd0_c_a0 & rd0_a1_a2 & rd0_na3 & rd0_na4_a5;
assign rwl1_48_63_00_11[9] = rd1_c_a0 & rd1_a1_a2 & rd1_na3 & rd1_na4_a5;
assign wwl_48_63_00_11[9] = wr0_c_a0 & wr0_a1_a2 & wr0_na3 & wr0_na4_a5;

assign rwl0_48_63_00_11[10] = rd0_c_a0 & rd0_a1_a2 & rd0_na3 & rd0_a4_na5;
assign rwl1_48_63_00_11[10] = rd1_c_a0 & rd1_a1_a2 & rd1_na3 & rd1_a4_na5;
assign wwl_48_63_00_11[10] = wr0_c_a0 & wr0_a1_a2 & wr0_na3 & wr0_a4_na5;

assign rwl0_48_63_00_11[11] = rd0_c_a0 & rd0_a1_a2 & rd0_na3 & rd0_a4_a5;
assign rwl1_48_63_00_11[11] = rd1_c_a0 & rd1_a1_a2 & rd1_na3 & rd1_a4_a5;
assign wwl_48_63_00_11[11] = wr0_c_a0 & wr0_a1_a2 & wr0_na3 & wr0_a4_a5;

assign rwl0_48_63_00_11[12] = rd0_c_a0 & rd0_a1_a2 & rd0_a3 & rd0_na4_na5;
assign rwl1_48_63_00_11[12] = rd1_c_a0 & rd1_a1_a2 & rd1_a3 & rd1_na4_na5;
assign wwl_48_63_00_11[12] = wr0_c_a0 & wr0_a1_a2 & wr0_a3 & wr0_na4_na5;

assign rwl0_48_63_00_11[13] = rd0_c_a0 & rd0_a1_a2 & rd0_a3 & rd0_na4_a5;
assign rwl1_48_63_00_11[13] = rd1_c_a0 & rd1_a1_a2 & rd1_a3 & rd1_na4_a5;
assign wwl_48_63_00_11[13] = wr0_c_a0 & wr0_a1_a2 & wr0_a3 & wr0_na4_a5;

assign rwl0_48_63_00_11[14] = rd0_c_a0 & rd0_a1_a2 & rd0_a3 & rd0_a4_na5;
assign rwl1_48_63_00_11[14] = rd1_c_a0 & rd1_a1_a2 & rd1_a3 & rd1_a4_na5;
assign wwl_48_63_00_11[14] = wr0_c_a0 & wr0_a1_a2 & wr0_a3 & wr0_a4_na5;

assign rwl0_48_63_00_11[15] = rd0_c_a0 & rd0_a1_a2 & rd0_a3 & rd0_a4_a5;
assign rwl1_48_63_00_11[15] = rd1_c_a0 & rd1_a1_a2 & rd1_a3 & rd1_a4_a5;
assign wwl_48_63_00_11[15] = wr0_c_a0 & wr0_a1_a2 & wr0_a3 & wr0_a4_a5;

assign rwl0_48_63_12_23 = rwl0_48_63_00_11;
assign rwl1_48_63_12_23 = rwl1_48_63_00_11;
assign wwl_48_63_12_23 = wwl_48_63_00_11;


// bit lines

genvar i;
generate

for (i = 0; i < 12; i = i + 1) begin
assign rd0_dat[i] = (|rbl0_00_15_00_11[i]) | (|rbl0_16_31_00_11[i]) | (|rbl0_32_47_00_11[i]) | (|rbl0_48_63_00_11[i]);
assign rd1_dat[i] = (|rbl1_00_15_00_11[i]) | (|rbl1_16_31_00_11[i]) | (|rbl1_32_47_00_11[i]) | (|rbl1_48_63_00_11[i]);
end

for (i = 0; i < 12; i = i + 1) begin
assign rd0_dat[i+12] = (|rbl0_00_15_12_23[i]) | (|rbl0_16_31_12_23[i]) | (|rbl0_32_47_12_23[i]) | (|rbl0_48_63_12_23[i]);
assign rd1_dat[i+12] = (|rbl1_00_15_12_23[i]) | (|rbl1_16_31_12_23[i]) | (|rbl1_32_47_12_23[i]) | (|rbl1_48_63_12_23[i]);
end

endgenerate

assign wbl_00_15_00_11 = wr0_dat[0:11];
assign wbl_00_15_12_23 = wr0_dat[12:23];
assign wbl_16_31_00_11 = wr0_dat[0:11];
assign wbl_16_31_12_23 = wr0_dat[12:23];
assign wbl_32_47_00_11 = wr0_dat[0:11];
assign wbl_32_47_12_23 = wr0_dat[12:23];
assign wbl_48_63_00_11 = wr0_dat[0:11];
assign wbl_48_63_12_23 = wr0_dat[12:23];

endmodule

@ -0,0 +1,542 @@
// © IBM Corp. 2022
// Licensed under the Apache License, Version 2.0 (the "License"), as modified by the terms below; you may not use the files in this
// repository except in compliance with the License as modified.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Modified Terms:
//
// 1) For the purpose of the patent license granted to you in Section 3 of the License, the "Work" hereby includes implementations of
// the work of authorship in physical form.
//
// Unless required by applicable law or agreed to in writing, the reference design 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 & limitations under the License.
//
// Brief explanation of modifications:
//
// Modification 1: This modification extends the patent license to an implementation of the Work in physical form i.e.,
// it unambiguously permits a user to make & use the physical chip.


// Behavioral for 64x24 toysram (sdr or ddr), 'shard' (semi-hard)
// 16x12 hard subarrays plus decoder, eval, io comps

`timescale 1 ps / 1 ps

module regfile_shard_2r1w_64x24_comp (

input rd0_c_na0,
input rd0_c_a0,
input rd0_na1_na2,
input rd0_na1_a2,
input rd0_a1_na2,
input rd0_a1_a2,
input rd0_na3,
input rd0_a3,
input rd0_na4_na5,
input rd0_na4_a5,
input rd0_a4_na5,
input rd0_a4_a5,
output [0:31] rd0_dat,

input rd1_c_na0,
input rd1_c_a0,
input rd1_na1_na2,
input rd1_na1_a2,
input rd1_a1_na2,
input rd1_a1_a2,
input rd1_na3,
input rd1_a3,
input rd1_na4_na5,
input rd1_na4_a5,
input rd1_a4_na5,
input rd1_a4_a5,
output [0:31] rd1_dat,

input wr0_c_na0,
input wr0_c_a0,
input wr0_na1_na2,
input wr0_na1_a2,
input wr0_a1_na2,
input wr0_a1_a2,
input wr0_na3,
input wr0_a3,
input wr0_na4_na5,
input wr0_na4_a5,
input wr0_a4_na5,
input wr0_a4_a5,
input [0:31] wr0_dat

);

// internal passed from io to decoders
wire rd0_c_na0_i;
wire rd0_c_a0_i;
wire rd0_na1_na2_i;
wire rd0_na1_a2_i;
wire rd0_a1_na2_i;
wire rd0_a1_a2_i;
wire rd0_na3_i;
wire rd0__a3_i;
wire rd0_na4_na5_i;
wire rd0_na4_a5_i;
wire rd0_a4_na5_i;
wire rd0_a4_a5_i;

wire rd1_c_na0_i;
wire rd1_c_a0_i;
wire rd1_na1_na2_i;
wire rd1_na1_a2_i;
wire rd1_a1_na2_i;
wire rd1_a1_a2_i;
wire rd1_na3_i;
wire rd1__a3_i;
wire rd1_na4_na5_i;
wire rd1_na4_a5_i;
wire rd1_a4_na5_i;
wire rd1_a4_a5_i;

wire wr0_c_na0_i;
wire wr0_c_a0_i;
wire wr0_na1_na2_i;
wire wr0_na1_a2_i;
wire wr0_a1_na2_i;
wire wr0_a1_a2_i;
wire wr0_na3_i;
wire wr0_a3_i;
wire wr0_na4_na5_i;
wire wr0_na4_a5_i;
wire wr0_a4_na5_i;
wire wr0_a4_a5_i;

// word selects
wire [0:31] rwl0_0x0;
wire [0:31] rwl1_0x0;
wire [0:31] wwl0_0x0;
wire [0:31] rwl0_0x1;
wire [0:31] rwl1_0x1;
wire [0:31] wwl0_0x1;

wire [0:31] rwl0_1x0;
wire [0:31] rwl1_1x0;
wire [0:31] wwl0_1x0;
wire [0:31] rwl0_1x1;
wire [0:31] rwl1_1x1;
wire [0:31] wwl0_1x1;

// subarray ins/outs
wire [0:11] rwl0_000;
wire [0:11] rwl1_000;
wire [0:11] wwl_000;
wire [0:11] rbl0_000;
wire [0:11] rbl1_000;
wire [0:11] wbl_000;
wire [0:11] wbl_b_000;

wire [0:11] rwl0_001;
wire [0:11] rwl1_001;
wire [0:11] wwl_001;
wire [0:11] rbl0_001;
wire [0:11] rbl1_001;
wire [0:11] wbl_001;
wire [0:11] wbl_b_001;

wire [0:11] rwl0_010;
wire [0:11] rwl1_010;
wire [0:11] wwl_010;
wire [0:11] rbl0_010;
wire [0:11] rbl1_010;
wire [0:11] wbl_010;
wire [0:11] wbl_b_010;

wire [0:11] rwl0_011;
wire [0:11] rwl1_011;
wire [0:11] wwl_011;
wire [0:11] rbl0_011;
wire [0:11] rbl1_011;
wire [0:11] wbl_011;
wire [0:11] wbl_b_011;

wire [0:11] rwl0_100;
wire [0:11] rwl1_100;
wire [0:11] wwl_100;
wire [0:11] rbl0_100;
wire [0:11] rbl1_100;
wire [0:11] wbl_100;
wire [0:11] wbl_b_100;

wire [0:11] rwl0_101;
wire [0:11] rwl1_101;
wire [0:11] wwl_101;
wire [0:11] rbl0_101;
wire [0:11] rbl1_101;
wire [0:11] wbl_101;
wire [0:11] wbl_b_101;

wire [0:11] rwl0_110;
wire [0:11] rwl1_110;
wire [0:11] wwl_110;
wire [0:11] rbl0_110;
wire [0:11] rbl1_110;
wire [0:11] wbl_110;
wire [0:11] wbl_b_110;

wire [0:11] rwl0_111;
wire [0:11] rwl1_111;
wire [0:11] wwl_111;
wire [0:11] rbl0_111;
wire [0:11] rbl1_111;
wire [0:11] wbl_111;
wire [0:11] wbl_b_111;

// subarray cells; 4x2 16w/12b subarrays
//
// bits are stacked vertically, words horizontally
// gap-d = dcd
// gap-e = local eval
// gap-i = i/o
//
// b---> e <---b
// --------> i
// ^
// |
// wwwww wwwww
// gap-d produces 64 wordlines per port
// gap-e(2) produce 24 L-R bitlines per port
// gap-i produces 24 bitlines per port
//
// subarrays
//
// 000 e 010 i 100 e 110
// ddddddddddddddddddddddd
// 001 e 011 i 101 e 111
//
// @1,2,4,5 are subarray word-selects
// @0,3 are final 2 data selects (gap-e, gap-i)
//
// if @0 is final select, subarrays:
// 00x=W0xx0xx 01x=W0xx1xx 10x=W1xx0xx 11x=W1xx1xx (0xx=W0xxxxx, 1xx=W1xxxxx)
// if @3 is final select, subarrays:
// 00x=W0xx0xx 01x=W1xx0xx 10x=W0xx1xx 11x=W1xx1xx (0xx=Wxxx0xx, 1xx=Wxxx1xx)

toysram_16x12 r000 (
.RWL0(rwl0_000),
.RWL1(rwl1_000),
.WWL(wwl_000),
.RBL0(rbl0_000),
.RBL1(rbl1_000),
.WBL(wbl_000),
.WBLb(wbl_b_000)
);
toysram_16x12 r001 (
.RWL0(rwl0_001),
.RWL1(rwl1_001),
.WWL(wwl_001),
.RBL0(rbl0_001),
.RBL1(rbl1_001),
.WBL(wbl_001),
.WBLb(wbl_b_001)
);

toysram_16x12 r010 (
.RWL0(rwl0_010),
.RWL1(rwl1_010),
.WWL(wwl_010),
.RBL0(rbl0_010),
.RBL1(rbl1_010),
.WBL(wbl_010),
.WBLb(wbl_b_010)
);

toysram_16x12 r011 (
.RWL0(rwl0_011),
.RWL1(rwl1_011),
.WWL(wwl_011),
.RBL0(rbl0_011),
.RBL1(rbl1_011),
.WBL(wbl_011),
.WBLb(wbl_b_011)
);

toysram_16x12 r100 (
.RWL0(rwl0_100),
.RWL1(rwl1_100),
.WWL(wwl_100),
.RBL0(rbl0_100),
.RBL1(rbl1_100),
.WBL(wbl_100),
.WBLb(wbl_b_100)
);

toysram_16x12 r101 (
.RWL0(rwl0_101),
.RWL1(rwl1_101),
.WWL(wwl_101),
.RBL0(rbl0_101),
.RBL1(rbl1_101),
.WBL(wbl_101),
.WBLb(wbl_b_101)
);

toysram_16x12 r110 (
.RWL0(rwl0_110),
.RWL1(rwl1_110),
.WWL(wwl_110),
.RBL0(rbl0_110),
.RBL1(rbl1_110),
.WBL(wbl_110),
.WBLb(wbl_b_110)
);

toysram_16x12 r111 (
.RWL0(rwl0_111),
.RWL1(rwl1_111),
.WWL(wwl_111),
.RBL0(rbl0_111),
.RBL1(rbl1_111),
.WBL(wbl_111),
.WBLb(wbl_b_111)
);

// wordline decodes to one-hots; separate copies for up/down
// separate comps for L/R so i/o macro can divide the center; a3
// distinguishes L/R
wordlines_comp dcd_0 (

.rd0_c_na0(rd0_c_na0_i),
.rd0_c_a0(rd0_c_a0_i),
.rd0_na1_na2(rd0_na1_na2_i),
.rd0_na1_a2(rd0_na1_a2_i),
.rd0_a1_na2(rd0_a1_na2_i),
.rd0_a1_a2(rd0_a1_a2_i),
.rd0_xa3(rd0_na3_i),
//.rd0_na3(rd0_na3_i),
//.rd0_a3(rd0_a3_i),
.rd0_na4_na5(rd0_na4_na5_i),
.rd0_na4_a5(rd0_na4_a5_i),
.rd0_a4_na5(rd0_a4_na5_i),
.rd0_a4_a5(rd0_a4_a5_i),
.rwl0_0(rwl0_0x0),
.rwl0_1(rwl0_0x1),
.rd1_c_na0(rd1_c_na0_i),
.rd1_c_a0(rd1_c_a0_i),
.rd1_na1_na2(rd1_na1_na2_i),
.rd1_na1_a2(rd1_na1_a2_i),
.rd1_a1_na2(rd1_a1_na2_i),
.rd1_a1_a2(rd1_a1_a2_i),
.rd1_xa3(rd1_na3_i),
//.rd1_na3(rd1_na3_i),
//.rd1_a3(rd1_a3_i),
.rd1_na4_na5(rd1_na4_na5_i),
.rd1_na4_a5(rd1_na4_a5_i),
.rd1_a4_na5(rd1_a4_na5_i),
.rd1_a4_a5(rd1_a4_a5_i),
.rwl1_0(rwl1_0x0),
.rwl1_1(rwl1_0x1),
.wr0_c_na0(wr0_c_na0_i),
.wr0_c_a0(wr0_c_a0_i),
.wr0_na1_na2(wr0_na1_na2_i),
.wr0_na1_a2(wr0_na1_a2_i),
.wr0_a1_na2(wr0_a1_na2_i),
.wr0_a1_a2(wr0_a1_a2_i),
.wr0_xa3(wr0_na3_i),
//.wr0_na3(wr0_na3_i),
//.wr0_a3(wr0_a3_i),
.wr0_na4_na5(wr0_na4_na5_i),
.wr0_na4_a5(wr0_na4_a5_i),
.wr0_a4_na5(wr0_a4_na5_i),
.wr0_a4_a5(wr0_a4_a5_i),
.wwl0_0(wwl0_0x0),
.wwl0_1(wwl0_0x1)

);

wordlines_comp dcd_1 (

.rd0_c_na0(rd0_c_na0_i),
.rd0_c_a0(rd0_c_a0_i),
.rd0_na1_na2(rd0_na1_na2_i),
.rd0_na1_a2(rd0_na1_a2_i),
.rd0_a1_na2(rd0_a1_na2_i),
.rd0_a1_a2(rd0_a1_a2_i),
.rd0_xa3(rd0_a3_i),
//.rd0_na3(rd0_na3_i),
//.rd0_a3(rd0_a3_i),
.rd0_na4_na5(rd0_na4_na5_i),
.rd0_na4_a5(rd0_na4_a5_i),
.rd0_a4_na5(rd0_a4_na5_i),
.rd0_a4_a5(rd0_a4_a5_i),
.rwl0_0(rwl0_1x0),
.rwl0_1(rwl0_1x1),
.rd1_c_na0(rd1_c_na0_i),
.rd1_c_a0(rd1_c_a0_i),
.rd1_na1_na2(rd1_na1_na2_i),
.rd1_na1_a2(rd1_na1_a2_i),
.rd1_a1_na2(rd1_a1_na2_i),
.rd1_a1_a2(rd1_a1_a2_i),
.rd1_xa3(rd1_a3_i),
//.rd1_na3(rd1_na3_i),
//.rd1_a3(rd1_a3_i),
.rd1_na4_na5(rd1_na4_na5_i),
.rd1_na4_a5(rd1_na4_a5_i),
.rd1_a4_na5(rd1_a4_na5_i),
.rd1_a4_a5(rd1_a4_a5_i),
.rwl1_0(rwl1_1x0),
.rwl1_1(rwl1_1x1),
.wr0_c_na0(wr0_c_na0_i),
.wr0_c_a0(wr0_c_a0_i),
.wr0_na1_na2(wr0_na1_na2_i),
.wr0_na1_a2(wr0_na1_a2_i),
.wr0_a1_na2(wr0_a1_na2_i),
.wr0_a1_a2(wr0_a1_a2_i),
.wr0_xa3(wr0_a3_i),
//.wr0_na3(wr0_na3_i),
//.wr0_a3(wr0_a3_i),
.wr0_na4_na5(wr0_na4_na5_i),
.wr0_na4_a5(wr0_na4_a5_i),
.wr0_a4_na5(wr0_a4_na5_i),
.wr0_a4_a5(wr0_a4_a5_i),
.wwl0_0(wwl0_1x0),
.wwl0_1(wwl0_1x1)

);

assign rwl0_000 = rwl0_0x0[0:15];
assign rwl0_001 = rwl0_0x1[0:15];
assign rwl0_010 = rwl0_0x0[16:31];
assign rwl0_011 = rwl0_0x1[16:31];
assign rwl0_100 = rwl0_1x0[0:15];
assign rwl0_101 = rwl0_1x1[0:15];
assign rwl0_110 = rwl0_1x0[16:31];
assign rwl0_111 = rwl0_1x1[16:31];

assign rwl1_000 = rwl1_0x0[0:15];
assign rwl1_001 = rwl1_0x1[0:15];
assign rwl1_010 = rwl1_0x0[16:31];
assign rwl1_011 = rwl1_0x1[16:31];
assign rwl1_100 = rwl1_1x0[0:15];
assign rwl1_101 = rwl1_1x1[0:15];
assign rwl1_110 = rwl1_1x0[16:31];
assign rwl1_111 = rwl1_1x1[16:31];

assign wwl0_000 = wwl0_0x0[0:15];
assign wwl0_001 = wwl0_0x1[0:15];
assign wwl0_010 = wwl0_0x0[16:31];
assign wwl0_011 = wwl0_0x1[16:31];
assign wwl0_100 = wwl0_1x0[0:15];
assign wwl0_101 = wwl0_1x1[0:15];
assign wwl0_110 = wwl0_1x0[16:31];
assign wwl0_111 = wwl0_1x1[16:31];

// local eval

// precharge repower
// during precharge c_na0 = c_a0 = 0
// 4 copies to 000/010, 001/011, 100/110, 101,111 quads
// rd0
sky130_fd_sc_hd__inv_8 pre0_0x0_b (.A(rd0_c_na0), .Y(pre0_0x0_b);
sky130_fd_sc_hd__inv_8 pre0_0x0 (.A(pre0_0x0_b), .Y(pre0_0x0);
sky130_fd_sc_hd__inv_8 pre0_0x1_b (.A(rd0_c_na0), .Y(pre0_0x1_b);
sky130_fd_sc_hd__inv_8 pre0_0x1 (.A(pre0_0x1_b), .Y(pre0_0x1);
sky130_fd_sc_hd__inv_8 pre0_1x0_b (.A(rd0_c_a0), .Y(pre0_1x0_b);
sky130_fd_sc_hd__inv_8 pre0_1x0 (.A(pre0_1x0_b), .Y(pre0_1x0);
sky130_fd_sc_hd__inv_8 pre0_1x1_b (.A(rd0_c_a0), .Y(pre0_1x1_b);
sky130_fd_sc_hd__inv_8 pre0_1x1 (.A(pre0_1x1_b), .Y(pre0_1x1);
// rd1
sky130_fd_sc_hd__inv_8 pre1_0x0_b (.A(rd0_c_na0), .Y(pre1_0x0_b);
sky130_fd_sc_hd__inv_8 pre1_0x0 (.A(pre1_0x0_b), .Y(pre1_0x0);
sky130_fd_sc_hd__inv_8 pre1_0x1_b (.A(rd0_c_na0), .Y(pre1_0x1_b);
sky130_fd_sc_hd__inv_8 pre1_0x1 (.A(pre1_0x1_b), .Y(pre1_0x1);
sky130_fd_sc_hd__inv_8 pre1_1x0_b (.A(rd0_c_a0), .Y(pre1_1x0_b);
sky130_fd_sc_hd__inv_8 pre1_1x0 (.A(pre1_1x0_b), .Y(pre1_1x0);
sky130_fd_sc_hd__inv_8 pre1_1x1_b (.A(rd0_c_a0), .Y(pre1_1x1_b);
sky130_fd_sc_hd__inv_8 pre1_1x1 (.A(pre1_1x1_b), .Y(pre1_1x1);

// quad local evals, 2 ports
local_eval_comp eval_0x0 (
.PRE0_b(pre0_0x0), .RBL0_L(rbl0_000), .RBL0_R(rbl0_010), .RBL0_Ob(rbl0_0x0),
.PRE1_b(pre1_0x0), .RBL1_L(rbl1_000), .RBL1_R(rbl1_010), .RBL1_Ob(rbl1_0x0),
);
local_eval_comp eval_0x1 (
.PRE0_b(pre0_0x1), .RBL0_L(rbl0_001), .RBL0_R(rbl0_011), .RBL0_Ob(rbl0_0x1),
.PRE1_b(pre1_0x1), .RBL1_L(rbl1_001), .RBL1_R(rbl1_011), .RBL1_Ob(rbl1_0x1),
);
local_eval_comp eval_1x0 (
.PRE0_b(pre0_1x0), .RBL0_L(rbl0_100), .RBL0_R(rbl0_110), .RBL0_Ob(rbl0_1x0),
.PRE1_b(pre1_1x0), .RBL1_L(rbl1_100), .RBL1_R(rbl1_110), .RBL1_Ob(rbl1_1x0),
);
local_eval_comp eval_1x1 (
.PRE0_b(pre0_1x1), .RBL0_L(rbl0_101), .RBL0_R(rbl0_111), .RBL0_Ob(rbl0_1x1),
.PRE1_b(pre1_1x1), .RBL1_L(rbl1_101), .RBL1_R(rbl1_111), .RBL1_Ob(rbl1_1x1),
);

// separate ports by quads for placement
// address passes through - should start decode here
// final 2:1 select for reads
// fanout +/- for writes
// wtf do wbl get another level buffering for far pairs? where? local eval col?
inout_comp io (

.rd0_c_na0(rd0_c_na0_i),
.rd0_c_a0(rd0_c_a0_i),
.rd0_na1_na2(rd0_na1_na2_i),
.rd0_na1_a2(rd0_na1_a2_i),
.rd0_a1_na2(rd0_a1_na2_i),
.rd0_a1_a2(rd0_a1_a2_i),
.rd0_na3(rd0_na3_i),
.rd0_a3(rd0_a3_i),
.rd0_na4_na5(rd0_na4_na5_i),
.rd0_na4_a5(rd0_na4_a5_i),
.rd0_a4_na5(rd0_a4_na5_i),
.rd0_a4_a5(rd0_a4_a5_i),

.rd1_c_na0(rd1_c_na0_i),
.rd1_c_a0(rd1_c_a0_i),
.rd1_na1_na2(rd1_na1_na2_i),
.rd1_na1_a2(rd1_na1_a2_i),
.rd1_a1_na2(rd1_a1_na2_i),
.rd1_a1_a2(rd1_a1_a2_i),
.rd1_na3(rd1_na3_i),
.rd1_a3(rd1_a3_i),
.rd1_na4_na5(rd1_na4_na5_i),
.rd1_na4_a5(rd1_na4_a5_i),
.rd1_a4_na5(rd1_a4_na5_i),
.rd1_a4_a5(rd1_a4_a5_i),

.wr0_c_na0(wr0_c_na0_i),
.wr0_c_a0(wr0_c_a0_i),
.wr0_na1_na2(wr0_na1_na2_i),
.wr0_na1_a2(wr0_na1_a2_i),
.wr0_a1_na2(wr0_a1_na2_i),
.wr0_a1_a2(wr0_a1_a2_i),
.wr0_na3(wr0_na3_i),
.wr0_a3(wr0_a3_i),
.wr0_na4_na5(wr0_na4_na5_i),
.wr0_na4_a5(wr0_na4_a5_i),
.wr0_a4_na5(wr0_a4_na5_i),
.wr0_a4_a5(wr0_a4_a5_i),

.rd0_dat_0x0(rbl0_0x0),
.rd0_dat_0x1(rbl0_0x1),
.rd0_dat_1x0(rbl0_1x0),
.rd0_dat_1x1(rbl0_1x1),
.rd0_dat(rd0_dat),

.rd1_dat_0x0(rbl1_0x0),
.rd1_dat_0x1(rbl1_0x1),
.rd1_dat_1x0(rbl1_1x0),
.rd1_dat_1x1(rbl1_1x1),
.rd1_dat(rd1_dat),

.wr0_dat_0x0(wbl_0x0),
.wr0_dat_b_000(wbl_b_0x0),
.wr0_dat_0x1(wbl_0x1),
.wr0_dat_b_0x1(wbl_b_0x1),
.wr0_dat_1x0(wbl_1x0),
.wr0_dat_b_1x0(wbl_b_1x0),
.wr0_dat_1x1(wbl_1x1),
.wr0_dat_b_1x1(wbl_b_1x1)

);

endmodule

@ -0,0 +1,78 @@
// © IBM Corp. 2022
// Licensed under the Apache License, Version 2.0 (the "License"), as modified by the terms below; you may not use the files in this
// repository except in compliance with the License as modified.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Modified Terms:
//
// 1) For the purpose of the patent license granted to you in Section 3 of the License, the "Work" hereby includes implementations of
// the work of authorship in physical form.
//
// Unless required by applicable law or agreed to in writing, the reference design 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.
//
// Brief explanation of modifications:
//
// Modification 1: This modification extends the patent license to an implementation of the Work in physical form i.e.,
// it unambiguously permits a user to make and use the physical chip.

// Behavioral for 16x12 toysram subarray

`timescale 1 ps / 1 ps

module toysram_16x12 (

input [0:15] RWL0,
input [0:15] RWL1,
input [0:15] WWL,
output [0:11] RBL0,
output [0:11] RBL1,
input [0:11] WBL,
input [0:11] WBLb,
);

reg [0:11] mem[0:15];

for (i = 0; i < 15; i = i + 1) begin
always @(posedge WWL[i]) begin
mem[i] <= not WBLb; // 00=1 01=0 10=1 11=0
end
end

// word-select
assign RBL0 = (mem[0] and {12{RWL0[0]}}) |
(mem[1] and {12{RWL0[1]}}) |
(mem[2] and {12{RWL0[2]}}) |
(mem[3] and {12{RWL0[3]}}) |
(mem[4] and {12{RWL0[4]}}) |
(mem[5] and {12{RWL0[5]}}) |
(mem[6] and {12{RWL0[6]}}) |
(mem[7] and {12{RWL0[7]}}) |
(mem[8] and {12{RWL0[8]}}) |
(mem[9] and {12{RWL0[9]}}) |
(mem[10] and {12{RWL0[10]}}) |
(mem[11] and {12{RWL0[11]}}) |
(mem[12] and {12{RWL0[12]}}) |
(mem[13] and {12{RWL0[13]}}) |
(mem[14] and {12{RWL0[14]}}) |
(mem[15] and {12{RWL0[15]}});

assign RBL1 = (mem[0] and {12{RWL1[0]}}) |
(mem[1] and {12{RWL1[1]}}) |
(mem[2] and {12{RWL1[2]}}) |
(mem[3] and {12{RWL1[3]}}) |
(mem[4] and {12{RWL1[4]}}) |
(mem[5] and {12{RWL1[5]}}) |
(mem[6] and {12{RWL1[6]}}) |
(mem[7] and {12{RWL1[7]}}) |
(mem[8] and {12{RWL1[8]}}) |
(mem[9] and {12{RWL1[9]}}) |
(mem[10] and {12{RWL1[10]}}) |
(mem[11] and {12{RWL1[11]}}) |
(mem[12] and {12{RWL1[12]}}) |
(mem[13] and {12{RWL1[13]}}) |
(mem[14] and {12{RWL1[14]}}) |
(mem[15] and {12{RWL1[15]}});

endmodule

@ -0,0 +1,35 @@
// © IBM Corp. 2022
// Licensed under the Apache License, Version 2.0 (the "License"), as modified by the terms below; you may not use the files in this
// repository except in compliance with the License as modified.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Modified Terms:
//
// 1) For the purpose of the patent license granted to you in Section 3 of the License, the "Work" hereby includes implementations of
// the work of authorship in physical form.
//
// Unless required by applicable law or agreed to in writing, the reference design 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.
//
// Brief explanation of modifications:
//
// Modification 1: This modification extends the patent license to an implementation of the Work in physical form i.e.,
// it unambiguously permits a user to make and use the physical chip.

// Empty wrapper for 16x12 toysram subarray

`timescale 1 ps / 1 ps

module toysram_16x12 (

input [0:15] RWL0,
input [0:15] RWL1,
input [0:15] WWL,
output [0:11] RBL0,
output [0:11] RBL1,
input [0:11] WBL,
input [0:11] WBLb,
);

endmodule

@ -0,0 +1,269 @@
// © IBM Corp. 2022
// Licensed under the Apache License, Version 2.0 (the "License"), as modified by the terms below; you may not use the files in this
// repository except in compliance with the License as modified.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Modified Terms:
//
// 1) For the purpose of the patent license granted to you in Section 3 of the License, the "Work" hereby includes implementations of
// the work of authorship in physical form.
//
// Unless required by applicable law or agreed to in writing, the reference design 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 & limitations under the License.
//
// Brief explanation of modifications:
//
// Modification 1: This modification extends the patent license to an implementation of the Work in physical form i.e.,
// it unambiguously permits a user to make & use the physical chip.


// Wordline decodes, 12-in -> 64 one-hot

`timescale 1 ps / 1 ps

// (c0)(12) -> 8 one-hots A0:A7
// (3)(45) -> 8 one-hots B0:B7
// A x B -> 64 one-hots W00:W63
module decode_wordlines_64 (

input c_na0,
input c_a0,
input na1_na2,
input na1_a2,
input a1_na2,
input a1_a2,
input na3,
input a3,
input na4_na5,
input na4_a5,
input a4_na5,
input a4_a5,
output [0:31] wl

);

wire [0:7] dcd_a_b;
wire [0:7] dcd_a;
wire [0:7] dcd_b_b;
wire [0:7] dcd_b;
wire [0:63] wl_b;
wire [0:63] wl;

sky130_fd_sc_hd__nand2_2 DCD_A0b (.A(c_na0), .B(na1_na2), .Y(dcd_a_b[0]));
sky130_fd_sc_hd__nand2_2 DCD_A1b (.A(c_na0), .B(na1_a2), .Y(dcd_a_b[1]));
sky130_fd_sc_hd__nand2_2 DCD_A2b (.A(c_na0), .B(a1_na2), .Y(dcd_a_b[2]));
sky130_fd_sc_hd__nand2_2 DCD_A3b (.A(c_na0), .B(a1_a2), .Y(dcd_a_b[3]));
sky130_fd_sc_hd__nand2_2 DCD_A4b (.A(c_a0), .B(na1_na2), .Y(dcd_a_b[4]));
sky130_fd_sc_hd__nand2_2 DCD_A5b (.A(c_a0), .B(na1_a2), .Y(dcd_a_b[5]));
sky130_fd_sc_hd__nand2_2 DCD_A6b (.A(c_a0), .B(a1_na2), .Y(dcd_a_b[6]));
sky130_fd_sc_hd__nand2_2 DCD_A7b (.A(c_a0), .B(a1_a2), .Y(dcd_a_b[7]));

sky130_fd_sc_hd__inv_2 DCD_A0 (.A(dcd_a_b[0]), .Y(dcd_a[0]));
sky130_fd_sc_hd__inv_2 DCD_A1 (.A(dcd_a_b[1]), .Y(dcd_a[1]));
sky130_fd_sc_hd__inv_2 DCD_A2 (.A(dcd_a_b[2]), .Y(dcd_a[2]));
sky130_fd_sc_hd__inv_2 DCD_A3 (.A(dcd_a_b[3]), .Y(dcd_a[3]));
sky130_fd_sc_hd__inv_2 DCD_A4 (.A(dcd_a_b[4]), .Y(dcd_a[4]));
sky130_fd_sc_hd__inv_2 DCD_A5 (.A(dcd_a_b[5]), .Y(dcd_a[5]));
sky130_fd_sc_hd__inv_2 DCD_A6 (.A(dcd_a_b[6]), .Y(dcd_a[6]));
sky130_fd_sc_hd__inv_2 DCD_A7 (.A(dcd_a_b[7]), .Y(dcd_a[7]));

sky130_fd_sc_hd__nand2_2 DCD_B0b (.A(na3), .B(na4_na5), .Y(dcd_b_b[0]));
sky130_fd_sc_hd__nand2_2 DCD_B1b (.A(na3), .B(na4_a5), .Y(dcd_b_b[1]));
sky130_fd_sc_hd__nand2_2 DCD_B2b (.A(na3), .B(a4_na5), .Y(dcd_b_b[2]));
sky130_fd_sc_hd__nand2_2 DCD_B3b (.A(na3), .B(a4_a5), .Y(dcd_b_b[3]));
sky130_fd_sc_hd__nand2_2 DCD_B4b (.A(a3), .B(na4_na5), .Y(dcd_b_b[4]));
sky130_fd_sc_hd__nand2_2 DCD_B5b (.A(a3), .B(na4_a5), .Y(dcd_b_b[5]));
sky130_fd_sc_hd__nand2_2 DCD_B6b (.A(a3), .B(a4_na5), .Y(dcd_b_b[6]));
sky130_fd_sc_hd__nand2_2 DCD_B7b (.A(a3), .B(a4_a5), .Y(dcd_b_b[6]));

sky130_fd_sc_hd__inv_2 DCD_B0 (.A(dcd_b_b[0]), .Y(dcd_b[0]));
sky130_fd_sc_hd__inv_2 DCD_B1 (.A(dcd_b_b[1]), .Y(dcd_b[1]));
sky130_fd_sc_hd__inv_2 DCD_B2 (.A(dcd_b_b[2]), .Y(dcd_b[2]));
sky130_fd_sc_hd__inv_2 DCD_B3 (.A(dcd_b_b[3]), .Y(dcd_b[3]));
sky130_fd_sc_hd__inv_2 DCD_B4 (.A(dcd_b_b[4]), .Y(dcd_b[4]));
sky130_fd_sc_hd__inv_2 DCD_B5 (.A(dcd_b_b[5]), .Y(dcd_b[5]));
sky130_fd_sc_hd__inv_2 DCD_B6 (.A(dcd_b_b[6]), .Y(dcd_b[6]));
sky130_fd_sc_hd__inv_2 DCD_B7 (.A(dcd_b_b[7]), .Y(dcd_b[7]));

genvar i, j;
generate
for (i = 0; i < 8; i = i + 1) begin
for (j = 0; j < 8; j = j + 1) begin
sky130_fd_sc_hd__nand2_2 DCD_Cb (.A(dcd_a[i]), .B(dcd_b[j]), .Y(wl_b[i*8+j]));
sky130_fd_sc_hd__inv_2 DCD_C (.A(wl_b[i*8+j]), .Y(wl[i*8+j]));
end
end
end generate

endmodule

// (c0)(12) -> 8 one-hots A0:A7
// (xa3)(45)-> 4 one-hots B0:B3 (xa3 is na3 for one decoder, a3 for the other)
// A x B -> 32 one-hots W00:W31
module decode_wordlines_32 (

input c_na0,
input c_a0,
input na1_na2,
input na1_a2,
input a1_na2,
input a1_a2,
input xa3,
input na4_na5,
input na4_a5,
input a4_na5,
input a4_a5,
output [0:31] wl

);

wire [0:7] dcd_a_b;
wire [0:7] dcd_a;
wire [0:3] dcd_b_b;
wire [0:3] dcd_b;
wire [0:31] wl_b;
wire [0:31] wl;

sky130_fd_sc_hd__nand2_2 DCD_A0b (.A(c_na0), .B(na1_na2), .Y(dcd_a_b[0]));
sky130_fd_sc_hd__nand2_2 DCD_A1b (.A(c_na0), .B(na1_a2), .Y(dcd_a_b[1]));
sky130_fd_sc_hd__nand2_2 DCD_A2b (.A(c_na0), .B(a1_na2), .Y(dcd_a_b[2]));
sky130_fd_sc_hd__nand2_2 DCD_A3b (.A(c_na0), .B(a1_a2), .Y(dcd_a_b[3]));
sky130_fd_sc_hd__nand2_2 DCD_A4b (.A(c_a0), .B(na1_na2), .Y(dcd_a_b[4]));
sky130_fd_sc_hd__nand2_2 DCD_A5b (.A(c_a0), .B(na1_a2), .Y(dcd_a_b[5]));
sky130_fd_sc_hd__nand2_2 DCD_A6b (.A(c_a0), .B(a1_na2), .Y(dcd_a_b[6]));
sky130_fd_sc_hd__nand2_2 DCD_A7b (.A(c_a0), .B(a1_a2), .Y(dcd_a_b[7]));

sky130_fd_sc_hd__inv_2 DCD_A0 (.A(dcd_a_b[0]), .Y(dcd_a[0]));
sky130_fd_sc_hd__inv_2 DCD_A1 (.A(dcd_a_b[1]), .Y(dcd_a[1]));
sky130_fd_sc_hd__inv_2 DCD_A2 (.A(dcd_a_b[2]), .Y(dcd_a[2]));
sky130_fd_sc_hd__inv_2 DCD_A3 (.A(dcd_a_b[3]), .Y(dcd_a[3]));
sky130_fd_sc_hd__inv_2 DCD_A4 (.A(dcd_a_b[4]), .Y(dcd_a[4]));
sky130_fd_sc_hd__inv_2 DCD_A5 (.A(dcd_a_b[5]), .Y(dcd_a[5]));
sky130_fd_sc_hd__inv_2 DCD_A6 (.A(dcd_a_b[6]), .Y(dcd_a[6]));
sky130_fd_sc_hd__inv_2 DCD_A7 (.A(dcd_a_b[7]), .Y(dcd_a[7]));

sky130_fd_sc_hd__nand2_2 DCD_B0b (.A(xa3), .B(na4_na5), .Y(dcd_b_b[0]));
sky130_fd_sc_hd__nand2_2 DCD_B1b (.A(xa3), .B(na4_a5), .Y(dcd_b_b[1]));
sky130_fd_sc_hd__nand2_2 DCD_B2b (.A(xa3), .B(a4_na5), .Y(dcd_b_b[2]));
sky130_fd_sc_hd__nand2_2 DCD_B3b (.A(xa3), .B(a4_a5), .Y(dcd_b_b[3]));

sky130_fd_sc_hd__inv_2 DCD_B0 (.A(dcd_b_b[0]), .Y(dcd_b[0]));
sky130_fd_sc_hd__inv_2 DCD_B1 (.A(dcd_b_b[1]), .Y(dcd_b[1]));
sky130_fd_sc_hd__inv_2 DCD_B2 (.A(dcd_b_b[2]), .Y(dcd_b[2]));
sky130_fd_sc_hd__inv_2 DCD_B3 (.A(dcd_b_b[3]), .Y(dcd_b[3]));

genvar i, j;
generate
for (i = 0; i < 8; i = i + 1) begin
for (j = 0; j < 4; j = j + 1) begin
sky130_fd_sc_hd__nand2_2 DCD_Cb (.A(dcd_a[i]), .B(dcd_b[j]), .Y(wl_b[i*8+j]));
sky130_fd_sc_hd__inv_2 DCD_C (.A(wl_b[i*8+j]), .Y(wl[i*8+j]));
end
end
end generate

endmodule

module wordlines_comp (

input rd0_c_na0,
input rd0_c_a0,
input rd0_na1_na2,
input rd0_na1_a2,
input rd0_a1_na2,
input rd0_a1_a2,
input rd0_na3,
input rd0_a3,
input rd0_na4_na5,
input rd0_na4_a5,
input rd0_a4_na5,
input rd0_a4_a5,
output [0:31] rwl0_0,
output [0:31] rwl0_1,

input rd1_c_na0,
input rd1_c_a0,
input rd1_na1_na2,
input rd1_na1_a2,
input rd1_a1_na2,
input rd1_a1_a2,
input rd1_na3,
input rd1_a3,
input rd1_na4_na5,
input rd1_na4_a5,
input rd1_a4_na5,
input rd1_a4_a5,
output [0:31] rwl1_0,
output [0:31] rwl1_1,

input wr0_c_na0,
input wr0_c_a0,
input wr0_na1_na2,
input wr0_na1_a2,
input wr0_a1_na2,
input wr0_a1_a2,
input wr0_na3,
input wr0_a3,
input wr0_na4_na5,
input wr0_na4_a5,
input wr0_a4_na5,
input wr0_a4_a5,
output [0:31] wwl0_0,
output [0:31] wwl0_1

);

// 64 wordlines per port
// if center sel is a0, 00:31 to left, 32:63 to right
// if center sel is a3, xxx0xx to left, xxx1xx to right

decode_wordlines rd0 (
.c_na0(rd0_c_na0),
.c_a0(rd0_c_a0),
.na1_na2(rd0_na1_na2),
.na1_a2(rd0_na1_a2),
.a1_na2(rd0_a1_na2),
.a1_a2(rd0_a1_a2),
.na3(rd0_na3),
.a3(rd0_a3),
.na4_na5(rd0_na4_na5),
.na4_a5(rd0_na4_a5),
.a4_na5(rd0_a4_na5),
.a4_a5(rd0_a4_a5),
.wl(rwl0),
);

decode_wordlines rd1 (
.c_na0(rd1_c_na0),
.c_a0(rd1_c_a0),
.na1_na2(rd1_na1_na2),
.na1_a2(rd1_na1_a2),
.a1_na2(rd1_a1_na2),
.a1_a2(rd1_a1_a2),
.na3(rd1_na3),
.a3(rd1_a3),
.na4_na5(rd1_na4_na5),
.na4_a5(rd1_na4_a5),
.a4_na5(rd1_a4_na5),
.a4_a5(rd1_a4_a5),
.wl(rwl1),
);

decode_wordlines wr0 (
.c_na0(wr0_c_na0),
.c_a0(wr0_c_a0),
.na1_na2(wr0_na1_na2),
.na1_a2(wr0_na1_a2),
.a1_na2(wr0_a1_na2),
.a1_a2(wr0_a1_a2),
.na3(wr0_na3),
.a3(wr0_a3),
.na4_na5(wr0_na4_na5),
.na4_a5(wr0_na4_a5),
.a4_na5(wr0_a4_na5),
.a4_a5(wr0_a4_a5),
.wl(wwl0),
);

endmodule

@ -0,0 +1,207 @@
// © IBM Corp. 2021
// Licensed under the Apache License, Version 2.0 (the "License"), as modified by the terms below; you may not use the files in this
// repository except in compliance with the License as modified.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Modified Terms:
//
// 1) For the purpose of the patent license granted to you in Section 3 of the License, the "Work" hereby includes implementations of
// the work of authorship in physical form.
//
// Unless required by applicable law or agreed to in writing, the reference design 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.
//
// Brief explanation of modifications:
//
// Modification 1: This modification extends the patent license to an implementation of the Work in physical form i.e.,
// it unambiguously permits a user to make and use the physical chip.


// Address and clocking synthesized logic for SDR 2r1w 64 word array
// Two modes:
// 1. nodelay: for sim, FPGA - clk (SDR) or clk2x (DDR) produce strobe
// 2. delay: for implementation, strobes are configured, and derived from clk

`timescale 1 ns / 1 ns

module address_clock_sdr_2r1w_64 (

strobe,

// address ports and associated enable signals
rd_enb_0,
rd_adr_0,
rd_enb_1,
rd_adr_1,
wr_enb_0,
wr_adr_0,

// predecoded address signal
// four groups of one hot encoded signals
// read address 0
rd0_c_na0,
rd0_c_a0,
rd0_na1_na2,
rd0_na1_a2,
rd0_a1_na2,
rd0_a1_a2,
rd0_na3,
rd0_a3,
rd0_na4_na5,
rd0_na4_a5,
rd0_a4_na5,
rd0_a4_a5,

// read address 1
rd1_c_na0,
rd1_c_a0,
rd1_na1_na2,
rd1_na1_a2,
rd1_a1_na2,
rd1_a1_a2,
rd1_na3,
rd1_a3,
rd1_na4_na5,
rd1_na4_a5,
rd1_a4_na5,
rd1_a4_a5,

// write address 0
wr0_c_na0,
wr0_c_a0,
wr0_na1_na2,
wr0_na1_a2,
wr0_a1_na2,
wr0_a1_a2,
wr0_na3,
wr0_a3,
wr0_na4_na5,
wr0_na4_a5,
wr0_a4_na5,
wr0_a4_a5

);

parameter GENMODE = 0; // 0=NoDelay, 1=Delay

input strobe;

// address ports and associated enable signals
input rd_enb_0;
input [0:5] rd_adr_0;
input rd_enb_1;
input [0:5] rd_adr_1;
input wr_enb_0;
input [0:5] wr_adr_0;

// predecoded address signal
// four groups of one hot encoded signals
// read address 0
output rd0_c_na0;
output rd0_c_a0;

output rd0_na1_na2;
output rd0_na1_a2;
output rd0_a1_na2;
output rd0_a1_a2;

output rd0_na3;
output rd0_a3;

output rd0_na4_na5;
output rd0_na4_a5;
output rd0_a4_na5;
output rd0_a4_a5;

// read address 1
output rd1_c_na0;
output rd1_c_a0;

output rd1_na1_na2;
output rd1_na1_a2;
output rd1_a1_na2;
output rd1_a1_a2;

output rd1_na3;
output rd1_a3;

output rd1_na4_na5;
output rd1_na4_a5;
output rd1_a4_na5;
output rd1_a4_a5;

// write address 0
output wr0_c_na0;
output wr0_c_a0;

output wr0_na1_na2;
output wr0_na1_a2;
output wr0_a1_na2;
output wr0_a1_a2;

output wr0_na3;
output wr0_a3;

output wr0_na4_na5;
output wr0_na4_a5;
output wr0_a4_na5;
output wr0_a4_a5;

// one predecoder per port

predecode_sdr_64 predecode_r0(
.strobe(strobe),
.enable(rd_enb_0),
.address(rd_adr_0),
.c_na0(rd0_c_na0),
.c_a0(rd0_c_a0),
.na1_na2(rd0_na1_na2),
.na1_a2(rd0_na1_a2),
.a1_na2(rd0_a1_na2),
.a1_a2(rd0_a1_a2),
.na3(rd0_na3),
.a3(rd0_a3),
.na4_na5(rd0_na4_na5),
.na4_a5(rd0_na4_a5),
.a4_na5(rd0_a4_na5),
.a4_a5(rd0_a4_a5)
);

predecode_sdr_64 predecode_r1(
.strobe(strobe),
.enable(rd_enb_1),
.address(rd_adr_1),
.c_na0(rd1_c_na0),
.c_a0(rd1_c_a0),
.na1_na2(rd1_na1_na2),
.na1_a2(rd1_na1_a2),
.a1_na2(rd1_a1_na2),
.a1_a2(rd1_a1_a2),
.na3(rd1_na3),
.a3(rd1_a3),
.na4_na5(rd1_na4_na5),
.na4_a5(rd1_na4_a5),
.a4_na5(rd1_a4_na5),
.a4_a5(rd1_a4_a5)
);

predecode_sdr_64 predecode_w0(
.strobe(strobe),
.enable(wr_enb_0),
.address(wr_adr_0),
.c_na0(wr0_c_na0),
.c_a0(wr0_c_a0),
.na1_na2(wr0_na1_na2),
.na1_a2(wr0_na1_a2),
.a1_na2(wr0_a1_na2),
.a1_a2(wr0_a1_a2),
.na3(wr0_na3),
.a3(wr0_a3),
.na4_na5(wr0_na4_na5),
.na4_a5(wr0_na4_a5),
.a4_na5(wr0_a4_na5),
.a4_a5(wr0_a4_a5)
);

endmodule

@ -0,0 +1,57 @@
// © IBM Corp. 2022
// Licensed under the Apache License, Version 2.0 (the "License"), as modified by the terms below; you may not use the files in this
// repository except in compliance with the License as modified.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Modified Terms:
//
// 1) For the purpose of the patent license granted to you in Section 3 of the License, the "Work" hereby includes implementations of
// the work of authorship in physical form.
//
// Unless required by applicable law or agreed to in writing, the reference design 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 & limitations under the License.
//
// Brief explanation of modifications:
//
// Modification 1: This modification extends the patent license to an implementation of the Work in physical form i.e.,
// it unambiguously permits a user to make & use the physical chip.

`timescale 1 ps / 1 ps

// Custom local eval cell (domino precharge and L/R subarray bit select)
module local_eval (

input PRE_b,
input RBL_L,
input RBL_R,
output RLB_O_b

);

sky130_fd_pr__pfet_01v8 PRE_L (.G(PRE_b), .S(RBL_L));
sky130_fd_pr__pfet_01v8 PRE_R (.G(PRE_b), .S(RBL_R));
sky130_fd_sc_hd__nand2_1 SEL (.A(RBL_L), .B(RBL_R), .Y(RBL_O_b));

endmodule

// 2 reads x 12 bits x 2 ports (one quad)
module local_eval_comp (

input PRE0_b,
input [0:11] RBL0_L,
input [0:11] RBL0_R,
output [0:11] RLB0_O_b,
input PRE1_b,
input [0:11] RBL1_L,
input [0:11] RBL1_R,
output [0:11] RLB1_O_b

);

for (i = 0; i < 12; i = i + 1) begin
local_eval_eval_0 (.PRE_b(PRE0_b), .RBL_L(RBL0_L[i]), .RBL_R(RBL0_R[i]), .RBL_Ob(RBL0_0_b[i]));
local_eval eval_1 (.PRE_b(PRE1_b), .RBL_L(RBL1_L[i]), .RBL_R(RBL1_R[i]), .RBL_Ob(RBL1_0_b[i]));
end

endmodule

@ -0,0 +1,109 @@
// © IBM Corp. 2021
// Licensed under the Apache License, Version 2.0 (the "License"), as modified by the terms below; you may not use the files in this
// repository except in compliance with the License as modified.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Modified Terms:
//
// 1) For the purpose of the patent license granted to you in Section 3 of the License, the "Work" hereby includes implementations of
// the work of authorship in physical form.
//
// Unless required by applicable law or agreed to in writing, the reference design 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.
//
// Brief explanation of modifications:
//
// Modification 1: This modification extends the patent license to an implementation of the Work in physical form i.e.,
// it unambiguously permits a user to make and use the physical chip.

// Predecode of 5 address bits into 4 one hot encodings

`timescale 1 ns / 1 ns

module predecode_sdr_32(

strobe,
enable,
address,

// 12 predecoded address lines 2 - 4 - 2 - 4 one hot encoding
c_na0, // clock and not address(0)
c_a0, // clock and address(0)
na1_na2,// not address(1) and not address(2)
na1_a2, // not address(1) and address(2)
a1_na2, // address(1) and not address(2)
a1_a2, // address(1) and address(2)
na3, // not address(3)
a3, // address(3)
na4, // not address(4)
a4 // address(4)
);

input strobe;
input enable;
input [0:4] address;

output c_na0;
output c_a0;
output na1_na2;
output na1_a2;
output a1_na2;
output a1_a2; // address(1) and address(2)
output na3; // not address(3)
output a3; // address(3)
output na4; // not address(4)
output a4; // address(4)

wire clock_enable;

wire [0:4] inv_address;

wire n_c_na0;
wire n_c_a0;
wire n_na1_na2;
wire n_na1_a2;
wire n_a1_na2;
wire n_a1_a2;
wire n_na4;
wire n_a4;

// and read or write enable with clock
// does this need to be SSB placed?
assign clock_enable = strobe & enable;

assign inv_address[0] = (~(address[0]));
assign inv_address[1] = (~(address[1]));
assign inv_address[2] = (~(address[2]));
assign inv_address[3] = (~(address[3]));
assign inv_address[4] = (~(address[4]));

// A(0) address predecode and gating with clock

assign c_na0 = clock_enable & inv_address[0];

assign c_a0 = clock_enable & address[0];


// A(1:2) address predecode

assign na1_na2 = inv_address[1] & inv_address[2];