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];

assign na1_a2 = inv_address[1] & address[2];

assign a1_na2 = address[1] & inv_address[2];

assign a1_a2 = address[1] & address[2];


// A(3) address predecode

assign na3 = inv_address[3];
assign a3 = address[3];

// A(4) address predecode

assign na4 = inv_address[4];
assign a4 = address[4];

endmodule

@ -0,0 +1,124 @@
// © 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 6 address bits into 4 one hot encodings

`timescale 1 ns / 1 ns

module predecode_sdr_64(

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_na5,// not address(4) and not address(5)
na4_a5, // not address(4) address(5)
a4_na5, // address(4) and not address(5)
a4_a5 // address(4) and address(5)

);
input strobe;
input enable;
input [0:5] 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_na5;// not address(4) and not address(5)
output na4_a5; // not address(4) address(5)
output a4_na5; // address(4) and not address(5)
output a4_a5; // address(4) and address(5)

wire clock_enable;
wire [0:5] 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_na5;
wire n_na4_a5;
wire n_a4_na5;
wire n_a4_a5;

// 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]));
assign inv_address[5] = (~(address[5]));

// 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];
assign na1_a2 = inv_address[1] & address[2];
assign a1_na2 = address[1] & inv_address[2];
assign a1_a2 = address[1] & address[2];

// A(3) address predecode

assign na3 = inv_address[3];
assign a3 = address[3];
// A(4:5) address predecode
assign na4_na5 = inv_address[4] & inv_address[5];

assign na4_a5 = inv_address[4] & address[5];
assign a4_na5 = address[4] & inv_address[5];
assign a4_a5 = address[4] & address[5];

endmodule

@ -0,0 +1,267 @@
// © 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.


// Logical wrapper for 32x72 array (SDR)
// Configurable for read latching

`timescale 1 ns / 1 ns

`include "toysram.vh"

module ra_2r1w_32x32_sdr(

clk,
reset,
strobe,
rd_enb_0,
rd_adr_0,
rd_dat_0,
rd_enb_1,
rd_adr_1,
rd_dat_1,
wr_enb_0,
wr_adr_0,
wr_dat_0

);

parameter GENMODE = `GENMODE; // 0=NoDelay, 1=Delay
parameter LATCHRD = 1; // 1=latch read data, 0=unlatched

input clk;
input reset;
input strobe;

input rd_enb_0;
input [0:4] rd_adr_0;
output [0:31] rd_dat_0;

input rd_enb_1;
input [0:4] rd_adr_1;
output [0:31] rd_dat_1;

input wr_enb_0;
input [0:4] wr_adr_0;
input [0:31] wr_dat_0;

reg rd_enb_0_q;
reg [0:4] rd_adr_0_q;
//generate
// if (LATCHRD)
reg [0:31] rd_dat_0_q;
//endgenerate

reg rd_enb_1_q;
reg [0:4] rd_adr_1_q;
//generate
// if (LATCHRD)
reg [0:31] rd_dat_1_q;
//endgenerate

reg wr_enb_0_q;
reg [0:4] wr_adr_0_q;
reg [0:31] wr_dat_0_q;

// -- read 0
wire rd0_c_na0;
wire rd0_c_a0;
wire rd0_na1_na2;
wire rd0_na1_a2;
wire rd0_a1_na2;
wire rd0_a1_a2;
wire rd0_na3;
wire rd0_a3;
wire rd0_na4;
wire rd0_a4;
wire [0:31] ra_rd_dat_0;

// -- read 1
wire rd1_c_na0;
wire rd1_c_a0;
wire rd1_na1_na2;
wire rd1_na1_a2;
wire rd1_a1_na2;
wire rd1_a1_a2;
wire rd1_na3;
wire rd1_a3;
wire rd1_na4;
wire rd1_a4;
wire [0:31] ra_rd_dat_1;

// -- write 0
wire wr0_c_na0;
wire wr0_c_a0;
wire wr0_na1_na2;
wire wr0_na1_a2;
wire wr0_a1_na2;
wire wr0_a1_a2;
wire wr0_na3;
wire wr0_a3;
wire wr0_na4;
wire wr0_a4;
wire ra_wr_enb_0;
wire [0:4] ra_wr_adr_0;
wire [0:31] ra_wr_dat_0;
wire strobe_int;

// latch inputs
// reset all; only enb required
always @ (posedge clk) begin
if (reset == 1'b1) begin
rd_enb_0_q <= 0;
rd_adr_0_q <= 0;
rd_enb_1_q <= 0;
rd_adr_1_q <= 0;
wr_enb_0_q <= 0;
wr_adr_0_q <= 0;
wr_dat_0_q <= 0;
end else begin
rd_enb_0_q <= rd_enb_0;
rd_adr_0_q <= rd_adr_0;
rd_enb_1_q <= rd_enb_1;
rd_adr_1_q <= rd_adr_1;
wr_enb_0_q <= wr_enb_0;
wr_adr_0_q <= wr_adr_0;
wr_dat_0_q <= wr_dat_0;
end
end

// latch read data conditionally
generate
if (LATCHRD) begin
always @ (posedge clk) begin
rd_dat_0_q <= ra_rd_dat_0;
rd_dat_1_q <= ra_rd_dat_1;
end
assign rd_dat_0 = rd_dat_0_q;
assign rd_dat_1 = rd_dat_1_q;
end else begin
assign rd_dat_0 = ra_rd_dat_0;
assign rd_dat_1 = ra_rd_dat_1;
end
endgenerate

// don't use the clock as data in sim mode
if (`GENMODE == 0)
assign strobe_int = 1'b1;
else
assign strobe_int = strobe;

// generate the controls for the array

address_clock_sdr_2r1w_32 #(
.GENMODE(GENMODE)
) add_clk (
.strobe (strobe_int),

.rd_enb_0 (rd_enb_0_q),
.rd_adr_0 (rd_adr_0_q),
.rd_enb_1 (rd_enb_1_q),
.rd_adr_1 (rd_adr_1_q),
.wr_enb_0 (wr_enb_0_q),
.wr_adr_0 (wr_adr_0_q),

// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4 (rd0_na4),
.rd0_a4 (rd0_a4),

// read 1
.rd1_c_na0 (rd1_c_na0),
.rd1_c_a0 (rd1_c_a0),
.rd1_na1_na2 (rd1_na1_na2),
.rd1_na1_a2 (rd1_na1_a2),
.rd1_a1_na2 (rd1_a1_na2),
.rd1_a1_a2 (rd1_a1_a2),
.rd1_na3 (rd1_na3),
.rd1_a3 (rd1_a3),
.rd1_na4 (rd1_na4),
.rd1_a4 (rd1_a4),

// write 0
.wr0_c_na0 (wr0_c_na0),
.wr0_c_a0 (wr0_c_a0),
.wr0_na1_na2 (wr0_na1_na2),
.wr0_na1_a2 (wr0_na1_a2),
.wr0_a1_na2 (wr0_a1_na2),
.wr0_a1_a2 (wr0_a1_a2),
.wr0_na3 (wr0_na3),
.wr0_a3 (wr0_a3),
.wr0_na4 (wr0_na4),
.wr0_a4 (wr0_a4)

);

// one hard array

regfile_2r1w_32x32 array0(

// predecoded address

// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4 (rd0_na4),
.rd0_a4 (rd0_a4),
.rd0_dat (ra_rd_dat_0),

// read 1
.rd1_c_na0 (rd1_c_na0),
.rd1_c_a0 (rd1_c_a0),
.rd1_na1_na2 (rd1_na1_na2),
.rd1_na1_a2 (rd1_na1_a2),
.rd1_a1_na2 (rd1_a1_na2),
.rd1_a1_a2 (rd1_a1_a2),
.rd1_na3 (rd1_na3),
.rd1_a3 (rd1_a3),
.rd1_na4 (rd1_na4),
.rd1_a4 (rd1_a4),
.rd1_dat (ra_rd_dat_1),

// write 0
.wr0_c_na0 (wr0_c_na0),
.wr0_c_a0 (wr0_c_a0),
.wr0_na1_na2 (wr0_na1_na2),
.wr0_na1_a2 (wr0_na1_a2),
.wr0_a1_na2 (wr0_a1_na2),
.wr0_a1_a2 (wr0_a1_a2),
.wr0_na3 (wr0_na3),
.wr0_a3 (wr0_a3),
.wr0_na4 (wr0_na4),
.wr0_a4 (wr0_a4),
.wr0_dat (wr_dat_0_q)
);


endmodule

@ -0,0 +1,391 @@
// © 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.


// Logical wrapper for 64x72 array (SDR)
// Configurable for read latching

`timescale 1 ns / 1 ns

`include "toysram.vh"

module ra_2r1w_64x72_sdr(

clk,
reset,
strobe,
rd_enb_0,
rd_adr_0,
rd_dat_0,
rd_enb_1,
rd_adr_1,
rd_dat_1,
wr_enb_0,
wr_adr_0,
wr_dat_0

);

parameter GENMODE = `GENMODE; // 0=NoDelay, 1=Delay
parameter LATCHRD = 1; // 1=latch read data, 0=unlatched

input clk;
input reset;
input strobe;

input rd_enb_0;
input [0:5] rd_adr_0;
output [0:71] rd_dat_0;

input rd_enb_1;
input [0:5] rd_adr_1;
output [0:71] rd_dat_1;

input wr_enb_0;
input [0:5] wr_adr_0;
input [0:71] wr_dat_0;

reg rd_enb_0_q;
reg [0:5] rd_adr_0_q;
//generate
// if (LATCHRD)
reg [0:71] rd_dat_0_q;
//endgenerate

reg rd_enb_1_q;
reg [0:5] rd_adr_1_q;
//generate
// if (LATCHRD)
reg [0:71] rd_dat_1_q;
//endgenerate

reg wr_enb_0_q;
reg [0:5] wr_adr_0_q;
reg [0:71] wr_dat_0_q;

// -- read 0
wire rd0_c_na0;
wire rd0_c_a0;
wire rd0_na1_na2;
wire rd0_na1_a2;
wire rd0_a1_na2;
wire rd0_a1_a2;
wire rd0_na3;
wire rd0_a3;
wire rd0_na4_na5;
wire rd0_na4_a5;
wire rd0_a4_na5;
wire rd0_a4_a5;
wire [0:71] ra_rd_dat_0;

// -- read 1
wire rd1_c_na0;
wire rd1_c_a0;
wire rd1_na1_na2;
wire rd1_na1_a2;
wire rd1_a1_na2;
wire rd1_a1_a2;
wire rd1_na3;
wire rd1_a3;
wire rd1_na4_na5;
wire rd1_na4_a5;
wire rd1_a4_na5;
wire rd1_a4_a5;
wire [0:71] ra_rd_dat_1;

// -- write 0
wire wr0_c_na0;
wire wr0_c_a0;
wire wr0_na1_na2;
wire wr0_na1_a2;
wire wr0_a1_na2;
wire wr0_a1_a2;
wire wr0_na3;
wire wr0_a3;
wire wr0_na4_na5;
wire wr0_na4_a5;
wire wr0_a4_na5;
wire wr0_a4_a5;
wire ra_wr_enb_0;
wire [0:5] ra_wr_adr_0;
wire [0:71] ra_wr_dat_0;
wire strobe_int;

// latch inputs
// reset all; only enb required
always @ (posedge clk) begin
if (reset == 1'b1) begin
rd_enb_0_q <= 0;
rd_adr_0_q <= 0;
rd_enb_1_q <= 0;
rd_adr_1_q <= 0;
wr_enb_0_q <= 0;
wr_adr_0_q <= 0;
wr_dat_0_q <= 0;
end else begin
rd_enb_0_q <= rd_enb_0;
rd_adr_0_q <= rd_adr_0;
rd_enb_1_q <= rd_enb_1;
rd_adr_1_q <= rd_adr_1;
wr_enb_0_q <= wr_enb_0;
wr_adr_0_q <= wr_adr_0;
wr_dat_0_q <= wr_dat_0;
end
end

// latch read data conditionally
generate

if (LATCHRD) begin
always @ (posedge clk) begin
rd_dat_0_q <= ra_rd_dat_0;
rd_dat_1_q <= ra_rd_dat_1;
end
assign rd_dat_0 = rd_dat_0_q;
assign rd_dat_1 = rd_dat_1_q;
end else begin
assign rd_dat_0 = ra_rd_dat_0;
assign rd_dat_1 = ra_rd_dat_1;
end

endgenerate

// don't use the clock as data in sim mode
if (`GENMODE == 0)
assign strobe_int = 1'b1;
else
assign strobe_int = strobe;

// generate the controls for the array

address_clock_sdr_2r1w_64

#( .GENMODE(GENMODE)
)

add_clk

(
.strobe (strobe_int),

.rd_enb_0 (rd_enb_0_q),
.rd_adr_0 (rd_adr_0_q),
.rd_enb_1 (rd_enb_1_q),
.rd_adr_1 (rd_adr_1_q),
.wr_enb_0 (wr_enb_0_q),
.wr_adr_0 (wr_adr_0_q),

// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4_na5 (rd0_na4_na5),
.rd0_na4_a5 (rd0_na4_a5),
.rd0_a4_na5 (rd0_a4_na5),
.rd0_a4_a5 (rd0_a4_a5),

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

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

);

// three hard arrays

regfile_2r1w_64x24 array0(

// predecoded address
// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4_na5 (rd0_na4_na5),
.rd0_na4_a5 (rd0_na4_a5),
.rd0_a4_na5 (rd0_a4_na5),
.rd0_a4_a5 (rd0_a4_a5),
.rd0_dat (ra_rd_dat_0[0:23]),

// read 1
.rd1_c_na0 (rd1_c_na0),
.rd1_c_a0 (rd1_c_a0),
.rd1_na1_na2 (rd1_na1_na2),
.rd1_na1_a2 (rd1_na1_a2),
.rd1_a1_na2 (rd1_a1_na2),
.rd1_a1_a2 (rd1_a1_a2),
.rd1_na3 (rd1_na3),
.rd1_a3 (rd1_a3),
.rd1_na4_na5 (rd1_na4_na5),
.rd1_na4_a5 (rd1_na4_a5),
.rd1_a4_na5 (rd1_a4_na5),
.rd1_a4_a5 (rd1_a4_a5),
.rd1_dat (ra_rd_dat_1[0:23]),

// write 0
.wr0_c_na0 (wr0_c_na0),
.wr0_c_a0 (wr0_c_a0),
.wr0_na1_na2 (wr0_na1_na2),
.wr0_na1_a2 (wr0_na1_a2),
.wr0_a1_na2 (wr0_a1_na2),
.wr0_a1_a2 (wr0_a1_a2),
.wr0_na3 (wr0_na3),
.wr0_a3 (wr0_a3),
.wr0_na4_na5 (wr0_na4_na5),
.wr0_na4_a5 (wr0_na4_a5),
.wr0_a4_na5 (wr0_a4_na5),
.wr0_a4_a5 (wr0_a4_a5),
.wr0_dat (wr_dat_0_q[0:23])

);

regfile_2r1w_64x24 array1(

// predecoded address
// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4_na5 (rd0_na4_na5),
.rd0_na4_a5 (rd0_na4_a5),
.rd0_a4_na5 (rd0_a4_na5),
.rd0_a4_a5 (rd0_a4_a5),
.rd0_dat (ra_rd_dat_0[24:47]),

// read 1
.rd1_c_na0 (rd1_c_na0),
.rd1_c_a0 (rd1_c_a0),
.rd1_na1_na2 (rd1_na1_na2),
.rd1_na1_a2 (rd1_na1_a2),
.rd1_a1_na2 (rd1_a1_na2),
.rd1_a1_a2 (rd1_a1_a2),
.rd1_na3 (rd1_na3),
.rd1_a3 (rd1_a3),
.rd1_na4_na5 (rd1_na4_na5),
.rd1_na4_a5 (rd1_na4_a5),
.rd1_a4_na5 (rd1_a4_na5),
.rd1_a4_a5 (rd1_a4_a5),
.rd1_dat (ra_rd_dat_1[24:47]),

// write 0
.wr0_c_na0 (wr0_c_na0),
.wr0_c_a0 (wr0_c_a0),
.wr0_na1_na2 (wr0_na1_na2),
.wr0_na1_a2 (wr0_na1_a2),
.wr0_a1_na2 (wr0_a1_na2),
.wr0_a1_a2 (wr0_a1_a2),
.wr0_na3 (wr0_na3),
.wr0_a3 (wr0_a3),
.wr0_na4_na5 (wr0_na4_na5),
.wr0_na4_a5 (wr0_na4_a5),
.wr0_a4_na5 (wr0_a4_na5),
.wr0_a4_a5 (wr0_a4_a5),
.wr0_dat (wr_dat_0_q[24:47])

);

regfile_2r1w_64x24 array2(

// predecoded address
// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4_na5 (rd0_na4_na5),
.rd0_na4_a5 (rd0_na4_a5),
.rd0_a4_na5 (rd0_a4_na5),
.rd0_a4_a5 (rd0_a4_a5),
.rd0_dat (ra_rd_dat_0[48:71]),

// read 1
.rd1_c_na0 (rd1_c_na0),
.rd1_c_a0 (rd1_c_a0),
.rd1_na1_na2 (rd1_na1_na2),
.rd1_na1_a2 (rd1_na1_a2),
.rd1_a1_na2 (rd1_a1_na2),
.rd1_a1_a2 (rd1_a1_a2),
.rd1_na3 (rd1_na3),
.rd1_a3 (rd1_a3),
.rd1_na4_na5 (rd1_na4_na5),
.rd1_na4_a5 (rd1_na4_a5),
.rd1_a4_na5 (rd1_a4_na5),
.rd1_a4_a5 (rd1_a4_a5),
.rd1_dat (ra_rd_dat_1[48:71]),

// write 0
.wr0_c_na0 (wr0_c_na0),
.wr0_c_a0 (wr0_c_a0),
.wr0_na1_na2 (wr0_na1_na2),
.wr0_na1_a2 (wr0_na1_a2),
.wr0_a1_na2 (wr0_a1_na2),
.wr0_a1_a2 (wr0_a1_a2),
.wr0_na3 (wr0_na3),
.wr0_a3 (wr0_a3),
.wr0_na4_na5 (wr0_na4_na5),
.wr0_na4_a5 (wr0_na4_a5),
.wr0_a4_na5 (wr0_a4_na5),
.wr0_a4_a5 (wr0_a4_a5),
.wr0_dat (wr_dat_0_q[48:71])

);

endmodule

@ -0,0 +1,502 @@
// © 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.


// Logical wrapper for 64x72 array (DDR)

// The encode logic and arrays are the same for sdr and ddr. The ports are
// mux'd between first and second half of cycle using el_sel.

`timescale 1 ns / 1 ns

`include "toysram.vh"

module ra_4r2w_64x72_ddr (

clk,
reset,
strobe,
el_sel,
rd_enb_0,
rd_adr_0,
rd_dat_0,
rd_enb_1,
rd_adr_1,
rd_dat_1,
rd_enb_2,
rd_adr_2,
rd_dat_2,
rd_enb_3,
rd_adr_3,
rd_dat_3,
wr_enb_0,
wr_adr_0,
wr_dat_0,
wr_enb_1,
wr_adr_1,
wr_dat_1

);

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

input clk;
input reset;
input strobe;
input el_sel;

input rd_enb_0;
input [0:5] rd_adr_0;
output [0:71] rd_dat_0;

input rd_enb_1;
input [0:5] rd_adr_1;
output [0:71] rd_dat_1;

input rd_enb_2;
input [0:5] rd_adr_2;
output [0:71] rd_dat_2;

input rd_enb_3;
input [0:5] rd_adr_3;
output [0:71] rd_dat_3;

input wr_enb_0;
input [0:5] wr_adr_0;
input [0:71] wr_dat_0;

input wr_enb_1;
input [0:5] wr_adr_1;
input [0:71] wr_dat_1;

reg rd_enb_0_q;
reg [0:5] rd_adr_0_q;
reg [0:71] rd_dat_0_q;
reg [0:71] rd_dat_0_hold_q;

reg rd_enb_1_q;
reg [0:5] rd_adr_1_q;
reg [0:71] rd_dat_1_q;
reg [0:71] rd_dat_1_hold_q;

reg rd_enb_2_q;
reg [0:5] rd_adr_2_q;
reg [0:71] rd_dat_2_q;

reg rd_enb_3_q;
reg [0:5] rd_adr_3_q;
reg [0:71] rd_dat_3_q;

reg wr_enb_0_q;
reg [0:5] wr_adr_0_q;
reg [0:71] wr_dat_0_q;

reg wr_enb_1_q;
reg [0:5] wr_adr_1_q;
reg [0:71] wr_dat_1_q;

// read 0
wire rd0_c_na0;
wire rd0_c_a0;
wire rd0_na1_na2;
wire rd0_na1_a2;
wire rd0_a1_na2;
wire rd0_a1_a2;
wire rd0_na3;
wire rd0_a3;
wire rd0_na4_na5;
wire rd0_na4_a5;
wire rd0_a4_na5;
wire rd0_a4_a5;
wire [0:71] ra_rd_dat_0;

// read 1
wire rd1_c_na0;
wire rd1_c_a0;
wire rd1_na1_na2;
wire rd1_na1_a2;
wire rd1_a1_na2;
wire rd1_a1_a2;
wire rd1_na3;
wire rd1_a3;
wire rd1_na4_na5;
wire rd1_na4_a5;
wire rd1_a4_na5;
wire rd1_a4_a5;
wire [0:71] ra_rd_dat_1;

// read 2
wire rd2_c_na0;
wire rd2_c_a0;
wire rd2_na1_na2;
wire rd2_na1_a2;
wire rd2_a1_na2;
wire rd2_a1_a2;
wire rd2_na3;
wire rd2_a3;
wire rd2_na4_na5;
wire rd2_na4_a5;
wire rd2_a4_na5;
wire rd2_a4_a5;
wire [0:71] ra_rd_dat_2;

// read 3
wire rd3_c_na0;
wire rd3_c_a0;
wire rd3_na1_na2;
wire rd3_na1_a2;
wire rd3_a1_na2;
wire rd3_a1_a2;
wire rd3_na3;
wire rd3_a3;
wire rd3_na4_na5;
wire rd3_na4_a5;
wire rd3_a4_na5;
wire rd3_a4_a5;
wire [0:71] ra_rd_dat_3;

// write 0
wire wr0_c_na0;
wire wr0_c_a0;
wire wr0_na1_na2;
wire wr0_na1_a2;
wire wr0_a1_na2;
wire wr0_a1_a2;
wire wr0_na3;
wire wr0_a3;
wire wr0_na4_na5;
wire wr0_na4_a5;
wire wr0_a4_na5;
wire wr0_a4_a5;
wire ra_wr_enb_0;
wire [0:5] ra_wr_adr_0;

// write 1
wire wr1_c_na0;
wire wr1_c_a0;
wire wr1_na1_na2;
wire wr1_na1_a2;
wire wr1_a1_na2;
wire wr1_a1_a2;
wire wr1_na3;
wire wr1_a3;
wire wr1_na4_na5;
wire wr1_na4_a5;
wire wr1_a4_na5;
wire wr1_a4_a5;
wire ra_wr_enb_1;
wire [0:5] ra_wr_adr_1;

wire rd_enb_02;
wire [0:5] rd_adr_02;
wire rd_enb_13;
wire [0:5] rd_adr_13;
wire wr_enb_01;
wire [0:5] wr_adr_01;
wire [0:71] wr_dat_01;
wire strobe_int;

// latch inputs
// reset all; only enb required
always @ (posedge clk) begin
if (reset == 1'b1) begin
rd_enb_0_q <= 0;
rd_adr_0_q <= 0;
rd_enb_1_q <= 0;
rd_adr_1_q <= 0;
rd_enb_2_q <= 0;
rd_adr_2_q <= 0;
rd_enb_3_q <= 0;
rd_adr_3_q <= 0;
wr_enb_0_q <= 0;
wr_adr_0_q <= 0;
wr_dat_0_q <= 0;
wr_enb_1_q <= 0;
wr_adr_1_q <= 0;
wr_dat_1_q <= 0;
end else begin
rd_enb_0_q <= rd_enb_0;
rd_adr_0_q <= rd_adr_0;
rd_enb_1_q <= rd_enb_1;
rd_adr_1_q <= rd_adr_1;
rd_enb_2_q <= rd_enb_2;
rd_adr_2_q <= rd_adr_2;
rd_enb_3_q <= rd_enb_3;
rd_adr_3_q <= rd_adr_3;
wr_enb_0_q <= wr_enb_0;
wr_adr_0_q <= wr_adr_0;
wr_dat_0_q <= wr_dat_0;
wr_enb_1_q <= wr_enb_1;
wr_adr_1_q <= wr_adr_1;
wr_dat_1_q <= wr_dat_1;
end
end

// latch read data
// early reads are double latched to hold during next cycle
generate

always @ (posedge strobe) begin
rd_dat_0_q <= (!el_sel) ? ra_rd_dat_0 : rd_dat_0_q;
rd_dat_1_q <= (!el_sel) ? ra_rd_dat_1 : rd_dat_1_q;
rd_dat_2_q <= (el_sel) ? ra_rd_dat_0 : rd_dat_2_q;
rd_dat_3_q <= (el_sel) ? ra_rd_dat_1 : rd_dat_3_q;
end
always @ (posedge clk) begin
rd_dat_0_hold_q <= rd_dat_0_q;
rd_dat_1_hold_q <= rd_dat_1_q;
end
assign rd_dat_0 = rd_dat_0_hold_q;
assign rd_dat_1 = rd_dat_1_hold_q;
assign rd_dat_2 = rd_dat_2_q;
assign rd_dat_3 = rd_dat_3_q;

endgenerate

assign rd_enb_02 = (el_sel) ? rd_enb_2_q : rd_enb_0_q;
assign rd_adr_02 = (el_sel) ? rd_adr_2_q : rd_adr_0_q;
assign rd_enb_13 = (el_sel) ? rd_enb_3_q : rd_enb_1_q;
assign rd_adr_13 = (el_sel) ? rd_adr_3_q : rd_adr_1_q;
assign wr_enb_01 = (el_sel) ? wr_enb_1_q : wr_enb_0_q;
assign wr_adr_01 = (el_sel) ? wr_adr_1_q : wr_adr_0_q;
assign wr_dat_01 = (el_sel) ? wr_dat_1_q : wr_dat_0_q;

// don't use the clock as data in sim mode
if (`GENMODE == 0)
assign strobe_int = 1'b1;
else
assign strobe_int = strobe;

// generate the controls for the array

address_clock_sdr_2r1w_64

#( .GENMODE(GENMODE)
)

add_clk

(
.strobe (strobe_int),

.rd_enb_0 (rd_enb_02),
.rd_adr_0 (rd_adr_02),
.rd_enb_1 (rd_enb_13),
.rd_adr_1 (rd_adr_13),
.wr_enb_0 (wr_enb_01),
.wr_adr_0 (wr_adr_01),

// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4_na5 (rd0_na4_na5),
.rd0_na4_a5 (rd0_na4_a5),
.rd0_a4_na5 (rd0_a4_na5),
.rd0_a4_a5 (rd0_a4_a5),

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

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

);

// three hard arrays

regfile_2r1w_64x24 array0(

// predecoded address
// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4_na5 (rd0_na4_na5),
.rd0_na4_a5 (rd0_na4_a5),
.rd0_a4_na5 (rd0_a4_na5),
.rd0_a4_a5 (rd0_a4_a5),
.rd0_dat (ra_rd_dat_0[0:23]),

// read 1
.rd1_c_na0 (rd1_c_na0),
.rd1_c_a0 (rd1_c_a0),
.rd1_na1_na2 (rd1_na1_na2),
.rd1_na1_a2 (rd1_na1_a2),
.rd1_a1_na2 (rd1_a1_na2),
.rd1_a1_a2 (rd1_a1_a2),
.rd1_na3 (rd1_na3),
.rd1_a3 (rd1_a3),
.rd1_na4_na5 (rd1_na4_na5),
.rd1_na4_a5 (rd1_na4_a5),
.rd1_a4_na5 (rd1_a4_na5),
.rd1_a4_a5 (rd1_a4_a5),
.rd1_dat (ra_rd_dat_1[0:23]),

// write 0
.wr0_c_na0 (wr0_c_na0),
.wr0_c_a0 (wr0_c_a0),
.wr0_na1_na2 (wr0_na1_na2),
.wr0_na1_a2 (wr0_na1_a2),
.wr0_a1_na2 (wr0_a1_na2),
.wr0_a1_a2 (wr0_a1_a2),
.wr0_na3 (wr0_na3),
.wr0_a3 (wr0_a3),
.wr0_na4_na5 (wr0_na4_na5),
.wr0_na4_a5 (wr0_na4_a5),
.wr0_a4_na5 (wr0_a4_na5),
.wr0_a4_a5 (wr0_a4_a5),
.wr0_dat (wr_dat_01[0:23])

);

regfile_2r1w_64x24 array1(

// predecoded address
// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4_na5 (rd0_na4_na5),
.rd0_na4_a5 (rd0_na4_a5),
.rd0_a4_na5 (rd0_a4_na5),
.rd0_a4_a5 (rd0_a4_a5),
.rd0_dat (ra_rd_dat_0[24:47]),

// read 1
.rd1_c_na0 (rd1_c_na0),
.rd1_c_a0 (rd1_c_a0),
.rd1_na1_na2 (rd1_na1_na2),
.rd1_na1_a2 (rd1_na1_a2),
.rd1_a1_na2 (rd1_a1_na2),
.rd1_a1_a2 (rd1_a1_a2),
.rd1_na3 (rd1_na3),
.rd1_a3 (rd1_a3),
.rd1_na4_na5 (rd1_na4_na5),
.rd1_na4_a5 (rd1_na4_a5),
.rd1_a4_na5 (rd1_a4_na5),
.rd1_a4_a5 (rd1_a4_a5),
.rd1_dat (ra_rd_dat_1[24:47]),

// write 0
.wr0_c_na0 (wr0_c_na0),
.wr0_c_a0 (wr0_c_a0),
.wr0_na1_na2 (wr0_na1_na2),
.wr0_na1_a2 (wr0_na1_a2),
.wr0_a1_na2 (wr0_a1_na2),
.wr0_a1_a2 (wr0_a1_a2),
.wr0_na3 (wr0_na3),
.wr0_a3 (wr0_a3),
.wr0_na4_na5 (wr0_na4_na5),
.wr0_na4_a5 (wr0_na4_a5),
.wr0_a4_na5 (wr0_a4_na5),
.wr0_a4_a5 (wr0_a4_a5),
.wr0_dat (wr_dat_01[24:47])

);

regfile_2r1w_64x24 array2(

// predecoded address
// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4_na5 (rd0_na4_na5),
.rd0_na4_a5 (rd0_na4_a5),
.rd0_a4_na5 (rd0_a4_na5),
.rd0_a4_a5 (rd0_a4_a5),
.rd0_dat (ra_rd_dat_0[48:71]),

// read 1
.rd1_c_na0 (rd1_c_na0),
.rd1_c_a0 (rd1_c_a0),
.rd1_na1_na2 (rd1_na1_na2),
.rd1_na1_a2 (rd1_na1_a2),
.rd1_a1_na2 (rd1_a1_na2),
.rd1_a1_a2 (rd1_a1_a2),
.rd1_na3 (rd1_na3),
.rd1_a3 (rd1_a3),
.rd1_na4_na5 (rd1_na4_na5),
.rd1_na4_a5 (rd1_na4_a5),
.rd1_a4_na5 (rd1_a4_na5),
.rd1_a4_a5 (rd1_a4_a5),
.rd1_dat (ra_rd_dat_1[48:71]),

// write 0
.wr0_c_na0 (wr0_c_na0),
.wr0_c_a0 (wr0_c_a0),
.wr0_na1_na2 (wr0_na1_na2),
.wr0_na1_a2 (wr0_na1_a2),
.wr0_a1_na2 (wr0_a1_na2),
.wr0_a1_a2 (wr0_a1_a2),
.wr0_na3 (wr0_na3),
.wr0_a3 (wr0_a3),
.wr0_na4_na5 (wr0_na4_na5),
.wr0_na4_a5 (wr0_na4_a5),
.wr0_a4_na5 (wr0_a4_na5),
.wr0_a4_a5 (wr0_a4_a5),
.wr0_dat (wr_dat_01[48:71])

);

endmodule

@ -0,0 +1,686 @@
// © 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.


// Logical wrapper for 64x72 array (DDR) - uses 1x clock only (but requires 2w regfile component)
// Configurable for read latching

`timescale 1 ns / 1 ns

`include "toysram.vh"

module ra_4r2w_64x72_ddr_1x (

clk,
reset,
strobe,
rd_enb_0,
rd_adr_0,
rd_dat_0,
rd_enb_1,
rd_adr_1,
rd_dat_1,
rd_enb_2,
rd_adr_2,
rd_dat_2,
rd_enb_3,
rd_adr_3,
rd_dat_3,
wr_enb_0,
wr_adr_0,
wr_dat_0,
wr_enb_1,
wr_adr_1,
wr_dat_1

);

parameter GENMODE = `GENMODE; // 0=NoDelay, 1=Delay
parameter LATCHRD = 1; // 1=latch read data, 0=unlatched

input clk;
input reset;
input strobe;

input rd_enb_0;
input [0:5] rd_adr_0;
output [0:71] rd_dat_0;

input rd_enb_1;
input [0:5] rd_adr_1;
output [0:71] rd_dat_1;

input rd_enb_2;
input [0:5] rd_adr_2;
output [0:71] rd_dat_2;

input rd_enb_3;
input [0:5] rd_adr_3;
output [0:71] rd_dat_3;

input wr_enb_0;
input [0:5] wr_adr_0;
input [0:71] wr_dat_0;

input wr_enb_1;
input [0:5] wr_adr_1;
input [0:71] wr_dat_1;

reg rd_enb_0_q;
reg [0:5] rd_adr_0_q;
//generate
// if (LATCHRD)
reg [0:71] rd_dat_0_q;
//endgenerate

reg rd_enb_1_q;
reg [0:5] rd_adr_1_q;
//generate
// if (LATCHRD)
reg [0:71] rd_dat_1_q;
//endgenerate

reg rd_enb_2_q;
reg [0:5] rd_adr_2_q;
//generate
// if (LATCHRD)
reg [0:71] rd_dat_2_q;
//endgenerate

reg rd_enb_3_q;
reg [0:5] rd_adr_3_q;
//generate
// if (LATCHRD)
reg [0:71] rd_dat_3_q;
//endgenerate

reg wr_enb_0_q;
reg [0:5] wr_adr_0_q;
reg [0:71] wr_dat_0_q;

reg wr_enb_1_q;
reg [0:5] wr_adr_1_q;
reg [0:71] wr_dat_1_q;

// -- read 0
wire rd0_c_na0;
wire rd0_c_a0;
wire rd0_na1_na2;
wire rd0_na1_a2;
wire rd0_a1_na2;
wire rd0_a1_a2;
wire rd0_na3;
wire rd0_a3;
wire rd0_na4_na5;
wire rd0_na4_a5;
wire rd0_a4_na5;
wire rd0_a4_a5;
wire [0:71] ra_rd_dat_0;

// -- read 1
wire rd1_c_na0;
wire rd1_c_a0;
wire rd1_na1_na2;
wire rd1_na1_a2;
wire rd1_a1_na2;
wire rd1_a1_a2;
wire rd1_na3;
wire rd1_a3;
wire rd1_na4_na5;
wire rd1_na4_a5;
wire rd1_a4_na5;
wire rd1_a4_a5;
wire [0:71] ra_rd_dat_1;

// -- read 2
wire rd2_c_na0;
wire rd2_c_a0;
wire rd2_na1_na2;
wire rd2_na1_a2;
wire rd2_a1_na2;
wire rd2_a1_a2;
wire rd2_na3;
wire rd2_a3;
wire rd2_na4_na5;
wire rd2_na4_a5;
wire rd2_a4_na5;
wire rd2_a4_a5;
wire [0:71] ra_rd_dat_2;

// -- read 3
wire rd3_c_na0;
wire rd3_c_a0;
wire rd3_na1_na2;
wire rd3_na1_a2;
wire rd3_a1_na2;
wire rd3_a1_a2;
wire rd3_na3;
wire rd3_a3;
wire rd3_na4_na5;
wire rd3_na4_a5;
wire rd3_a4_na5;
wire rd3_a4_a5;
wire [0:71] ra_rd_dat_3;

// -- write 0
wire wr0_c_na0;
wire wr0_c_a0;
wire wr0_na1_na2;
wire wr0_na1_a2;
wire wr0_a1_na2;
wire wr0_a1_a2;
wire wr0_na3;
wire wr0_a3;
wire wr0_na4_na5;
wire wr0_na4_a5;
wire wr0_a4_na5;
wire wr0_a4_a5;

// -- write 1
wire wr1_c_na0;
wire wr1_c_a0;
wire wr1_na1_na2;
wire wr1_na1_a2;
wire wr1_a1_na2;
wire wr1_a1_a2;
wire wr1_na3;
wire wr1_a3;
wire wr1_na4_na5;
wire wr1_na4_a5;
wire wr1_a4_na5;
wire wr1_a4_a5;

wire strobe_int;

// latch inputs
// reset all; only enb required
always @ (posedge clk) begin
if (reset == 1'b1) begin
rd_enb_0_q <= 0;
rd_adr_0_q <= 0;
rd_enb_1_q <= 0;
rd_adr_1_q <= 0;
rd_enb_2_q <= 0;
rd_adr_2_q <= 0;
rd_enb_3_q <= 0;
rd_adr_3_q <= 0;
wr_enb_0_q <= 0;
wr_adr_0_q <= 0;
wr_dat_0_q <= 0;
wr_enb_1_q <= 0;
wr_adr_1_q <= 0;
wr_dat_1_q <= 0;
end else begin
rd_enb_0_q <= rd_enb_0;
rd_adr_0_q <= rd_adr_0;
rd_enb_1_q <= rd_enb_1;
rd_adr_1_q <= rd_adr_1;
rd_enb_2_q <= rd_enb_2;
rd_adr_2_q <= rd_adr_2;
rd_enb_3_q <= rd_enb_3;
rd_adr_3_q <= rd_adr_3;
wr_enb_0_q <= wr_enb_0;
wr_adr_0_q <= wr_adr_0;
wr_dat_0_q <= wr_dat_0;
wr_enb_1_q <= wr_enb_1;
wr_adr_1_q <= wr_adr_1;
wr_dat_1_q <= wr_dat_1;
end
end

// latch read data conditionally
generate

if (LATCHRD) begin
always @ (posedge clk) begin
rd_dat_0_q <= ra_rd_dat_0;
rd_dat_1_q <= ra_rd_dat_1;
rd_dat_2_q <= ra_rd_dat_2;
rd_dat_3_q <= ra_rd_dat_3;
end
assign rd_dat_0 = rd_dat_0_q;
assign rd_dat_1 = rd_dat_1_q;
assign rd_dat_2 = rd_dat_2_q;
assign rd_dat_3 = rd_dat_3_q;
end else begin
assign rd_dat_0 = ra_rd_dat_0;
assign rd_dat_1 = ra_rd_dat_1;
assign rd_dat_2 = ra_rd_dat_2;
assign rd_dat_3 = ra_rd_dat_3;
end

endgenerate

if (`GENMODE == 0)
assign strobe_int = !reset;
else
assign strobe_int = strobe;

// generate the controls for the array
// dup controls to use same component
// but need new regfile to support 2 writes

address_clock_sdr_2r1w_64

#( .GENMODE(GENMODE)
)

add_clk_01

(
.strobe (strobe_int),

.rd_enb_0 (rd_enb_0_q),
.rd_adr_0 (rd_adr_0_q),
.rd_enb_1 (rd_enb_1_q),
.rd_adr_1 (rd_adr_1_q),
.wr_enb_0 (wr_enb_0_q),
.wr_adr_0 (wr_adr_0_q),

// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4_na5 (rd0_na4_na5),
.rd0_na4_a5 (rd0_na4_a5),
.rd0_a4_na5 (rd0_a4_na5),
.rd0_a4_a5 (rd0_a4_a5),

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

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

);

address_clock_sdr_2r1w_64

#( .GENMODE(GENMODE)
)

add_clk_23

(
.strobe (strobe_int),

.rd_enb_0 (rd_enb_2_q),
.rd_adr_0 (rd_adr_2_q),
.rd_enb_1 (rd_enb_3_q),
.rd_adr_1 (rd_adr_3_q),
.wr_enb_0 (wr_enb_1_q),
.wr_adr_0 (wr_adr_1_q),

// read 2
.rd0_c_na0 (rd2_c_na0),
.rd0_c_a0 (rd2_c_a0),
.rd0_na1_na2 (rd2_na1_na2),
.rd0_na1_a2 (rd2_na1_a2),
.rd0_a1_na2 (rd2_a1_na2),
.rd0_a1_a2 (rd2_a1_a2),
.rd0_na3 (rd2_na3),
.rd0_a3 (rd2_a3),
.rd0_na4_na5 (rd2_na4_na5),
.rd0_na4_a5 (rd2_na4_a5),
.rd0_a4_na5 (rd2_a4_na5),
.rd0_a4_a5 (rd2_a4_a5),

// read 3
.rd1_c_na0 (rd3_c_na0),
.rd1_c_a0 (rd3_c_a0),
.rd1_na1_na2 (rd3_na1_na2),
.rd1_na1_a2 (rd3_na1_a2),
.rd1_a1_na2 (rd3_a1_na2),
.rd1_a1_a2 (rd3_a1_a2),
.rd1_na3 (rd3_na3),
.rd1_a3 (rd3_a3),
.rd1_na4_na5 (rd3_na4_na5),
.rd1_na4_a5 (rd3_na4_a5),
.rd1_a4_na5 (rd3_a4_na5),
.rd1_a4_a5 (rd3_a4_a5),

// write 1
.wr0_c_na0 (wr1_c_na0),
.wr0_c_a0 (wr1_c_a0),
.wr0_na1_na2 (wr1_na1_na2),
.wr0_na1_a2 (wr1_na1_a2),
.wr0_a1_na2 (wr1_a1_na2),
.wr0_a1_a2 (wr1_a1_a2),
.wr0_na3 (wr1_na3),
.wr0_a3 (wr1_a3),
.wr0_na4_na5 (wr1_na4_na5),
.wr0_na4_a5 (wr1_na4_a5),
.wr0_a4_na5 (wr1_a4_na5),
.wr0_a4_a5 (wr1_a4_a5)

);

// three hard arrays

regfile_4r2w_64x24 array0 (

// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4_na5 (rd0_na4_na5),
.rd0_na4_a5 (rd0_na4_a5),
.rd0_a4_na5 (rd0_a4_na5),
.rd0_a4_a5 (rd0_a4_a5),
.rd0_dat (ra_rd_dat_0[0:23]),

// read 1
.rd1_c_na0 (rd1_c_na0),
.rd1_c_a0 (rd1_c_a0),
.rd1_na1_na2 (rd1_na1_na2),
.rd1_na1_a2 (rd1_na1_a2),
.rd1_a1_na2 (rd1_a1_na2),
.rd1_a1_a2 (rd1_a1_a2),
.rd1_na3 (rd1_na3),
.rd1_a3 (rd1_a3),
.rd1_na4_na5 (rd1_na4_na5),
.rd1_na4_a5 (rd1_na4_a5),
.rd1_a4_na5 (rd1_a4_na5),
.rd1_a4_a5 (rd1_a4_a5),
.rd1_dat (ra_rd_dat_1[0:23]),

// read 2
.rd2_c_na0 (rd2_c_na0),
.rd2_c_a0 (rd2_c_a0),
.rd2_na1_na2 (rd2_na1_na2),
.rd2_na1_a2 (rd2_na1_a2),
.rd2_a1_na2 (rd2_a1_na2),
.rd2_a1_a2 (rd2_a1_a2),
.rd2_na3 (rd2_na3),
.rd2_a3 (rd2_a3),
.rd2_na4_na5 (rd2_na4_na5),
.rd2_na4_a5 (rd2_na4_a5),
.rd2_a4_na5 (rd2_a4_na5),
.rd2_a4_a5 (rd2_a4_a5),
.rd2_dat (ra_rd_dat_2[0:23]),

// read 3
.rd3_c_na0 (rd3_c_na0),
.rd3_c_a0 (rd3_c_a0),
.rd3_na1_na2 (rd3_na1_na2),
.rd3_na1_a2 (rd3_na1_a2),
.rd3_a1_na2 (rd3_a1_na2),
.rd3_a1_a2 (rd3_a1_a2),
.rd3_na3 (rd3_na3),
.rd3_a3 (rd3_a3),
.rd3_na4_na5 (rd3_na4_na5),
.rd3_na4_a5 (rd3_na4_a5),
.rd3_a4_na5 (rd3_a4_na5),
.rd3_a4_a5 (rd3_a4_a5),
.rd3_dat (ra_rd_dat_3[0:23]),

// write 0
.wr0_c_na0 (wr0_c_na0),
.wr0_c_a0 (wr0_c_a0),
.wr0_na1_na2 (wr0_na1_na2),
.wr0_na1_a2 (wr0_na1_a2),
.wr0_a1_na2 (wr0_a1_na2),
.wr0_a1_a2 (wr0_a1_a2),
.wr0_na3 (wr0_na3),
.wr0_a3 (wr0_a3),
.wr0_na4_na5 (wr0_na4_na5),
.wr0_na4_a5 (wr0_na4_a5),
.wr0_a4_na5 (wr0_a4_na5),
.wr0_a4_a5 (wr0_a4_a5),
.wr0_dat (wr_dat_0_q[0:23]),

// write 1
.wr1_c_na0 (wr1_c_na0),
.wr1_c_a0 (wr1_c_a0),
.wr1_na1_na2 (wr1_na1_na2),
.wr1_na1_a2 (wr1_na1_a2),
.wr1_a1_na2 (wr1_a1_na2),
.wr1_a1_a2 (wr1_a1_a2),
.wr1_na3 (wr1_na3),
.wr1_a3 (wr1_a3),
.wr1_na4_na5 (wr1_na4_na5),
.wr1_na4_a5 (wr1_na4_a5),
.wr1_a4_na5 (wr1_a4_na5),
.wr1_a4_a5 (wr1_a4_a5),
.wr1_dat (wr_dat_1_q[0:23])

);

regfile_4r2w_64x24 array1 (

// predecoded address
// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4_na5 (rd0_na4_na5),
.rd0_na4_a5 (rd0_na4_a5),
.rd0_a4_na5 (rd0_a4_na5),
.rd0_a4_a5 (rd0_a4_a5),
.rd0_dat (ra_rd_dat_0[24:47]),

// read 1
.rd1_c_na0 (rd1_c_na0),
.rd1_c_a0 (rd1_c_a0),
.rd1_na1_na2 (rd1_na1_na2),
.rd1_na1_a2 (rd1_na1_a2),
.rd1_a1_na2 (rd1_a1_na2),
.rd1_a1_a2 (rd1_a1_a2),
.rd1_na3 (rd1_na3),
.rd1_a3 (rd1_a3),
.rd1_na4_na5 (rd1_na4_na5),
.rd1_na4_a5 (rd1_na4_a5),
.rd1_a4_na5 (rd1_a4_na5),
.rd1_a4_a5 (rd1_a4_a5),
.rd1_dat (ra_rd_dat_1[24:47]),

// read 2
.rd2_c_na0 (rd2_c_na0),
.rd2_c_a0 (rd2_c_a0),
.rd2_na1_na2 (rd2_na1_na2),
.rd2_na1_a2 (rd2_na1_a2),
.rd2_a1_na2 (rd2_a1_na2),
.rd2_a1_a2 (rd2_a1_a2),
.rd2_na3 (rd2_na3),
.rd2_a3 (rd2_a3),
.rd2_na4_na5 (rd2_na4_na5),
.rd2_na4_a5 (rd2_na4_a5),
.rd2_a4_na5 (rd2_a4_na5),
.rd2_a4_a5 (rd2_a4_a5),
.rd2_dat (ra_rd_dat_2[24:47]),

// read 3
.rd3_c_na0 (rd3_c_na0),
.rd3_c_a0 (rd3_c_a0),
.rd3_na1_na2 (rd3_na1_na2),
.rd3_na1_a2 (rd3_na1_a2),
.rd3_a1_na2 (rd3_a1_na2),
.rd3_a1_a2 (rd3_a1_a2),
.rd3_na3 (rd3_na3),
.rd3_a3 (rd3_a3),
.rd3_na4_na5 (rd3_na4_na5),
.rd3_na4_a5 (rd3_na4_a5),
.rd3_a4_na5 (rd3_a4_na5),
.rd3_a4_a5 (rd3_a4_a5),
.rd3_dat (ra_rd_dat_3[24:47]),

// write 0
.wr0_c_na0 (wr0_c_na0),
.wr0_c_a0 (wr0_c_a0),
.wr0_na1_na2 (wr0_na1_na2),
.wr0_na1_a2 (wr0_na1_a2),
.wr0_a1_na2 (wr0_a1_na2),
.wr0_a1_a2 (wr0_a1_a2),
.wr0_na3 (wr0_na3),
.wr0_a3 (wr0_a3),
.wr0_na4_na5 (wr0_na4_na5),
.wr0_na4_a5 (wr0_na4_a5),
.wr0_a4_na5 (wr0_a4_na5),
.wr0_a4_a5 (wr0_a4_a5),
.wr0_dat (wr_dat_0_q[24:47]),

// write 1
.wr1_c_na0 (wr1_c_na0),
.wr1_c_a0 (wr1_c_a0),
.wr1_na1_na2 (wr1_na1_na2),
.wr1_na1_a2 (wr1_na1_a2),
.wr1_a1_na2 (wr1_a1_na2),
.wr1_a1_a2 (wr1_a1_a2),
.wr1_na3 (wr1_na3),
.wr1_a3 (wr1_a3),
.wr1_na4_na5 (wr1_na4_na5),
.wr1_na4_a5 (wr1_na4_a5),
.wr1_a4_na5 (wr1_a4_na5),
.wr1_a4_a5 (wr1_a4_a5),
.wr1_dat (wr_dat_1_q[24:47])

);

regfile_4r2w_64x24 array2 (

// read 0
.rd0_c_na0 (rd0_c_na0),
.rd0_c_a0 (rd0_c_a0),
.rd0_na1_na2 (rd0_na1_na2),
.rd0_na1_a2 (rd0_na1_a2),
.rd0_a1_na2 (rd0_a1_na2),
.rd0_a1_a2 (rd0_a1_a2),
.rd0_na3 (rd0_na3),
.rd0_a3 (rd0_a3),
.rd0_na4_na5 (rd0_na4_na5),
.rd0_na4_a5 (rd0_na4_a5),
.rd0_a4_na5 (rd0_a4_na5),
.rd0_a4_a5 (rd0_a4_a5),
.rd0_dat (ra_rd_dat_0[48:71]),

// read 1
.rd1_c_na0 (rd1_c_na0),
.rd1_c_a0 (rd1_c_a0),
.rd1_na1_na2 (rd1_na1_na2),
.rd1_na1_a2 (rd1_na1_a2),
.rd1_a1_na2 (rd1_a1_na2),
.rd1_a1_a2 (rd1_a1_a2),
.rd1_na3 (rd1_na3),
.rd1_a3 (rd1_a3),
.rd1_na4_na5 (rd1_na4_na5),
.rd1_na4_a5 (rd1_na4_a5),
.rd1_a4_na5 (rd1_a4_na5),
.rd1_a4_a5 (rd1_a4_a5),
.rd1_dat (ra_rd_dat_1[48:71]),

// read 2
.rd2_c_na0 (rd2_c_na0),
.rd2_c_a0 (rd2_c_a0),
.rd2_na1_na2 (rd2_na1_na2),
.rd2_na1_a2 (rd2_na1_a2),
.rd2_a1_na2 (rd2_a1_na2),
.rd2_a1_a2 (rd2_a1_a2),
.rd2_na3 (rd2_na3),
.rd2_a3 (rd2_a3),
.rd2_na4_na5 (rd2_na4_na5),
.rd2_na4_a5 (rd2_na4_a5),
.rd2_a4_na5 (rd2_a4_na5),
.rd2_a4_a5 (rd2_a4_a5),
.rd2_dat (ra_rd_dat_2[48:71]),

// read 3
.rd3_c_na0 (rd3_c_na0),
.rd3_c_a0 (rd3_c_a0),
.rd3_na1_na2 (rd3_na1_na2),
.rd3_na1_a2 (rd3_na1_a2),
.rd3_a1_na2 (rd3_a1_na2),
.rd3_a1_a2 (rd3_a1_a2),
.rd3_na3 (rd3_na3),
.rd3_a3 (rd3_a3),
.rd3_na4_na5 (rd3_na4_na5),
.rd3_na4_a5 (rd3_na4_a5),
.rd3_a4_na5 (rd3_a4_na5),
.rd3_a4_a5 (rd3_a4_a5),
.rd3_dat (ra_rd_dat_3[48:71]),

// write 0
.wr0_c_na0 (wr0_c_na0),
.wr0_c_a0 (wr0_c_a0),
.wr0_na1_na2 (wr0_na1_na2),
.wr0_na1_a2 (wr0_na1_a2),
.wr0_a1_na2 (wr0_a1_na2),
.wr0_a1_a2 (wr0_a1_a2),
.wr0_na3 (wr0_na3),
.wr0_a3 (wr0_a3),
.wr0_na4_na5 (wr0_na4_na5),
.wr0_na4_a5 (wr0_na4_a5),
.wr0_a4_na5 (wr0_a4_na5),
.wr0_a4_a5 (wr0_a4_a5),
.wr0_dat (wr_dat_0_q[48:71]),

// write 1
.wr1_c_na0 (wr1_c_na0),
.wr1_c_a0 (wr1_c_a0),
.wr1_na1_na2 (wr1_na1_na2),
.wr1_na1_a2 (wr1_na1_a2),
.wr1_a1_na2 (wr1_a1_na2),
.wr1_a1_a2 (wr1_a1_a2),
.wr1_na3 (wr1_na3),
.wr1_a3 (wr1_a3),
.wr1_na4_na5 (wr1_na4_na5),
.wr1_na4_a5 (wr1_na4_a5),
.wr1_a4_na5 (wr1_a4_na5),
.wr1_a4_a5 (wr1_a4_a5),
.wr1_dat (wr_dat_1_q[48:71])

);

endmodule

@ -0,0 +1,169 @@
// © 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.


// Local BIST for arrays
// Pass array inputs through, or generate locally for test/manual access.
// May want status_valid, ctl_valid sigs.
// Want separate cmds for enter/exit functional?
// ctl:
// 00000000 - functional mode
// 800000aa - read adr aa
// 900000aa - write adr aa (next 3 cycs are data)
// F00000tt - run bist test tt
//
// status:
//
//

`timescale 1 ns / 1 ns

`include "toysram.vh"

module ra_bist_ddr (

clk,
reset,
ctl,
status,
rd0_enb_in,
rd0_adr_in,
rd1_enb_in,
rd1_adr_in,
rd2_enb_in,
rd2_adr_in,
rd3_enb_in,
rd3_adr_in,
wr0_enb_in,
wr0_adr_in,
wr0_dat_in,
wr1_enb_in,
wr1_adr_in,
wr1_dat_in,
rd0_enb_out,
rd0_adr_out,
rd0_dat,
rd1_enb_out,
rd1_adr_out,
rd1_dat,
rd2_enb_out,
rd2_adr_out,
rd2_dat,
rd3_enb_out,
rd3_adr_out,
rd3_dat,
wr0_enb_out,
wr0_adr_out,
wr0_dat_out,
wr1_enb_out,
wr1_adr_out,
wr1_dat_out

);

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

input clk;
input reset;
input [0:31] ctl;

input rd0_enb_in;
input [0:5] rd0_adr_in;
input rd1_enb_in;
input [0:5] rd1_adr_in;
input rd2_enb_in;
input [0:5] rd2_adr_in;
input rd3_enb_in;
input [0:5] rd3_adr_in;
input wr0_enb_in;
input [0:5] wr0_adr_in;
input [0:71] wr0_dat_in;
input wr1_enb_in;
input [0:5] wr1_adr_in;
input [0:71] wr1_dat_in;

output [0:31] status;
output rd0_enb_out;
output [0:5] rd0_adr_out;
input [0:71] rd0_dat;
output rd1_enb_out;
output [0:5] rd1_adr_out;
input [0:71] rd1_dat;
output rd2_enb_out;
output [0:5] rd2_adr_out;
input [0:71] rd2_dat;
output rd3_enb_out;
output [0:5] rd3_adr_out;
input [0:71] rd3_dat;
output wr0_enb_out;
output [0:5] wr0_adr_out;
output [0:71] wr0_dat_out;
output wr1_enb_out;
output [0:5] wr1_adr_out;
output [0:71] wr1_dat_out;

reg [0:5] seq_q;
wire [0:5] seq_d;
wire active;
wire bist_rd0_enb;
wire [0:5] bist_rd0_adr;
wire bist_rd1_enb;
wire [0:5] bist_rd1_adr;
wire bist_rd2_enb;
wire [0:5] bist_rd2_adr;
wire bist_rd3_enb;
wire [0:5] bist_rd3_adr;
wire bist_wr0_enb;
wire [0:5] bist_wr0_adr;
wire [0:71] bist_wr0_dat;
wire bist_wr1_enb;
wire [0:5] bist_wr1_adr;
wire [0:71] bist_wr1_dat;

// ff
always @ (posedge clk) begin
if (reset)
seq_q <= 6'h3F;
else
seq_q <= seq_d;
end

// do something
assign seq_d = seq_q;
assign active = seq_q != 6'h3F;
assign status = 0;

// outputs
assign rd0_enb_out = (active) ? bist_rd0_enb : rd0_enb_in;
assign rd0_adr_out = (active) ? bist_rd0_adr : rd0_adr_in;
assign rd1_enb_out = (active) ? bist_rd1_enb : rd1_enb_in;
assign rd1_adr_out = (active) ? bist_rd1_adr : rd1_adr_in;
assign rd2_enb_out = (active) ? bist_rd2_enb : rd2_enb_in;
assign rd2_adr_out = (active) ? bist_rd2_adr : rd2_adr_in;
assign rd3_enb_out = (active) ? bist_rd3_enb : rd3_enb_in;
assign rd3_adr_out = (active) ? bist_rd3_adr : rd3_adr_in;
assign wr0_enb_out = (active) ? bist_wr0_enb : wr0_enb_in;
assign wr0_adr_out = (active) ? bist_wr0_adr : wr0_adr_in;
assign wr0_dat_out = (active) ? bist_wr0_dat : wr0_dat_in;
assign wr1_enb_out = (active) ? bist_wr1_enb : wr1_enb_in;
assign wr1_adr_out = (active) ? bist_wr1_adr : wr1_adr_in;
assign wr1_dat_out = (active) ? bist_wr1_dat : wr1_dat_in;

endmodule

@ -0,0 +1,123 @@
// © 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.


// Local BIST for arrays
// Pass array inputs through, or generate locally for test/manual access.
// May want status_valid, ctl_valid sigs.
// Want separate cmds for enter/exit functional?
// ctl:
// 00000000 - functional mode
// 800000aa - read adr aa
// 900000aa - write adr aa (next 3 cycs are data)
// F00000tt - run bist test tt
//
// status:
//
//

`timescale 1 ns / 1 ns

`include "toysram.vh"

module ra_bist_sdr (

clk,
reset,
ctl,
status,
rd0_enb_in,
rd0_adr_in,
rd1_enb_in,
rd1_adr_in,
wr0_enb_in,
wr0_adr_in,
wr0_dat_in,
rd0_enb_out,
rd0_adr_out,
rd0_dat,
rd1_enb_out,
rd1_adr_out,
rd1_dat,
wr0_enb_out,
wr0_adr_out,
wr0_dat_out

);

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

input clk;
input reset;
input [31:0] ctl;

input rd0_enb_in;
input [5:0] rd0_adr_in;
input rd1_enb_in;
input [5:0] rd1_adr_in;
input wr0_enb_in;
input [5:0] wr0_adr_in;
input [71:0] wr0_dat_in;

output [31:0] status;
output rd0_enb_out;
output [5:0] rd0_adr_out;
input [71:0] rd0_dat;
output rd1_enb_out;
output [5:0] rd1_adr_out;
input [71:0] rd1_dat;
output wr0_enb_out;
output [5:0] wr0_adr_out;
output [71:0] wr0_dat_out;

reg [5:0] seq_q;
wire [5:0] seq_d;
wire active;
wire bist_rd0_enb;
wire [5:0] bist_rd0_adr;
wire bist_rd1_enb;
wire [5:0] bist_rd1_adr;
wire bist_wr0_enb;
wire [5:0] bist_wr0_adr;
wire [71:0] bist_wr0_dat;

// ff
always @ (posedge clk) begin
if (reset)
seq_q <= 6'h3F;
else
seq_q <= seq_d;
end

// do something
assign seq_d = seq_q;
assign active = seq_q != 6'h3F;
assign status = 0;

// outputs
assign rd0_enb_out = (active) ? bist_rd0_enb : rd0_enb_in;
assign rd0_adr_out = (active) ? bist_rd0_adr : rd0_adr_in;
assign rd1_enb_out = (active) ? bist_rd1_enb : rd1_enb_in;
assign rd1_adr_out = (active) ? bist_rd1_adr : rd1_adr_in;
assign wr0_enb_out = (active) ? bist_wr0_enb : wr0_enb_in;
assign wr0_adr_out = (active) ? bist_wr0_adr : wr0_adr_in;
assign wr0_dat_out = (active) ? bist_wr0_dat : wr0_dat_in;
//assign rd0_dat = (active) ? haven't done anything here yet

endmodule

@ -0,0 +1,154 @@
`timescale 1 ns / 1 ns

`include "toysram.vh"

module ra_bist_sdr_32x32 (

clk,
reset,
ctl,
status,
rd0_enb_in,
rd0_adr_in,
rd1_enb_in,
rd1_adr_in,
wr0_enb_in,
wr0_adr_in,
wr0_dat_in,
rd0_enb_out,
rd0_adr_out,
rd0_dat,
rd1_enb_out,
rd1_adr_out,
rd1_dat,
wr0_enb_out,
wr0_adr_out,
wr0_dat_out,
bist_fail,
bist_passed
);

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

input clk;
input reset;
input [0:31] ctl;

input rd0_enb_in;
input [0:4] rd0_adr_in;
input rd1_enb_in;
input [0:4] rd1_adr_in;
input wr0_enb_in;
input [0:4] wr0_adr_in;
input [0:31] wr0_dat_in;

output [0:31] status;
output rd0_enb_out;
output [0:4] rd0_adr_out;
input [0:31] rd0_dat;
output rd1_enb_out;
output [0:4] rd1_adr_out;
input [0:31] rd1_dat;
output wr0_enb_out;
output [0:4] wr0_adr_out;
output [0:31] wr0_dat_out;

reg [0:5] seq_q;
wire [0:5] seq_d;
wire active;
wire bist_rd0_enb;
wire [0:4] bist_rd0_adr;
wire bist_rd1_enb;
wire [0:4] bist_rd1_adr;
wire bist_wr0_enb;
wire [0:4] bist_wr0_adr;
wire [0:31] bist_wr0_dat;

output bist_fail;
output bist_passed;

// ff
always @ (posedge clk) begin
if (reset)
seq_q <= 6'h3F;
else
seq_q <= seq_d;
end

// do something
assign seq_d = seq_q;
assign active = seq_q != 6'h3F;
assign status = 0;

/*
A more practical implementation:
make an up/down counter for interating through addresses.

state machine for each part of the step: the best part about this is that
states could be added for implementation withb GPIO/wishbone for external
controls/different steps.

s0: write 0s up (Idle)
s1: write 1s down
s2: read 1s down/check
s3: write 0s up
s4: read 0s up/check
s5: write 1s up
s6: read 1s up/check
s7: flags


*/
/*
Outline for BIST
----------------------------------------------------------------------
first off, how I think this thing is supposed to work is that we need a
final flag signifying the BIST is successfully ran, and one where it fa-
ils.
uhhhhhh something's gotta happen here
like:
enable write data
assign all 0s to addr 0x00-0x3F (using signals wr0_adr_in &
wr0_dat_in)

enable read data (rd0_enb_in)

read addr 0x00-0x3f one at a time (rd0_adr_in/out and rd0_dat)

after each read, write all 1s to each addr 0x00-0x3F
^^this happens after each read, so like, read data at 0x00, write all
ones to 0x00, step forward to next address, 0x01 (process A)

for each valid read of all 0s, save output in a 6-bit bus that counts
up for each valid read or something

now, step through the exact same read/write process but replacing
all 1s with all 0s.

read all 0s through same process (NO WRITE CHANGE THIS TIME)

Now, write all 1s to each address 0x3F-0x00.
repeat the process A, reading data at each address,replacing all 1s
with all 0s for each address 0x3F-0x00, and keeping track of whether
working or not.

finally, read all 0s through same process (NO WRITE HERE EITHER)
at the end, there's gotta be some kinda comparison where you check
that the tests were valid for both ascending and descending runs.

if both are valid, flag BIST_PASSED. if one of the runs is invalid,
flag BIST_FAIL_UP, or BIST_FAIL_DOWN or both.

*/

// outputs
assign rd0_enb_out = (active) ? bist_rd0_enb : rd0_enb_in;
assign rd0_adr_out = (active) ? bist_rd0_adr : rd0_adr_in;
assign rd1_enb_out = (active) ? bist_rd1_enb : rd1_enb_in;
assign rd1_adr_out = (active) ? bist_rd1_adr : rd1_adr_in;
assign wr0_enb_out = (active) ? bist_wr0_enb : wr0_enb_in;
assign wr0_adr_out = (active) ? bist_wr0_adr : wr0_adr_in;
assign wr0_dat_out = (active) ? bist_wr0_dat : wr0_dat_in;
//assign rd0_dat = (active) ? haven't done anything here yet

endmodule

@ -0,0 +1,160 @@
`timescale 1 ns / 1 ns

`include "toysram.vh"

module ra_bist_sdr (

clk,
reset, picture,
ctl,
status,
rd0_enb_in,
rd0_adr_in,
rd1_enb_in,
rd1_adr_in,
wr0_enb_in,
wr0_adr_in,
wr0_dat_in,
rd0_enb_out,
rd0_adr_out,
rd0_dat,
rd1_enb_out,
rd1_adr_out,
rd1_dat,
wr0_enb_out,
wr0_adr_out,
wr0_dat_out,
bist_fail,
bist_passed


);

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

input clk;
input reset;
input [31:0] ctl;

input rd0_enb_in;
input [5:0] rd0_adr_in;
input rd1_enb_in;
input [5:0] rd1_adr_in;
input wr0_enb_in;
input [5:0] wr0_adr_in;
input [71:0] wr0_dat_in;

output [31:0] status;
output rd0_enb_out;
output [5:0] rd0_adr_out;
input [71:0] rd0_dat;
output rd1_enb_out;
output [5:0] rd1_adr_out;
input [71:0] rd1_dat;
output wr0_enb_out;
output [5:0] wr0_adr_out;
output [71:0] wr0_dat_out;



reg [5:0] seq_q;
wire [5:0] seq_d;
wire active;
wire bist_rd0_enb;
wire [5:0] bist_rd0_adr;
wire bist_rd1_enb;
wire [5:0] bist_rd1_adr;
wire bist_wr0_enb;
wire [5:0] bist_wr0_adr;
wire [71:0] bist_wr0_dat;

output bist_fail;
output bist_passed;

// ff
always @ (posedge clk) begin
if (reset)
seq_q <= 6'h3F;
else
seq_q <= seq_d;
end

// do something
assign seq_d = seq_q;
assign active = seq_q != 6'h3F;
assign status = 0;

assign wr0_enb_in = 1;

/*
A more practical implementation:
make an up/down counter for interating through addresses.

state machine for each part of the step: the best part about this is that
states could be added for implementation withb GPIO/wishbone for external
controls/different steps.

s0: write 0s up (Idle)
s1: write 1s down
s2: read 1s down/check
s3: write 0s up
s4: read 0s up/check
s5: write 1s up
s6: read 1s up/check
s7: flags


*/
/*
Outline for BIST
----------------------------------------------------------------------
first off, how I think this thing is supposed to work is that we need a
final flag signifying the BIST is successfully ran, and one where it fa-
ils.
uhhhhhh something's gotta happen here
like:
enable write data
assign all 0s to addr 0x00-0x3F (using signals wr0_adr_in &
wr0_dat_in)

enable read data (rd0_enb_in)

read addr 0x00-0x3f one at a time (rd0_adr_in/out and rd0_dat)

after each read, write all 1s to each addr 0x00-0x3F
^^this happens after each read, so like, read data at 0x00, write all
ones to 0x00, step forward to next address, 0x01 (process A)

for each valid read of all 0s, save output in a 6-bit bus that counts
up for each valid read or something

now, step through the exact same read/write process but replacing
all 1s with all 0s.

read all 0s through same process (NO WRITE CHANGE THIS TIME)

Now, write all 1s to each address 0x3F-0x00.
repeat the process A, reading data at each address,replacing all 1s
with all 0s for each address 0x3F-0x00, and keeping track of whether
working or not.

finally, read all 0s through same process (NO WRITE HERE EITHER)
at the end, there's gotta be some kinda comparison where you check
that the tests were valid for both ascending and descending runs.

if both are valid, flag BIST_PASSED. if one of the runs is invalid,
flag BIST_FAIL_UP, or BIST_FAIL_DOWN or both.

*/

// outputs
assign rd0_enb_out = (active) ? bist_rd0_enb : rd0_enb_in;
assign rd0_adr_out = (active) ? bist_rd0_adr : rd0_adr_in;
assign rd1_enb_out = (active) ? bist_rd1_enb : rd1_enb_in;
assign rd1_adr_out = (active) ? bist_rd1_adr : rd1_adr_in;
assign wr0_enb_out = (active) ? bist_wr0_enb : wr0_enb_in;
assign wr0_adr_out = (active) ? bist_wr0_adr : wr0_adr_in;
assign wr0_dat_out = (active) ? bist_wr0_dat : wr0_dat_in;
//assign rd0_dat = (active) ? haven't done anything here yet

endmodule

@ -0,0 +1,65 @@
// © 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.


// Local Configuration for arrays
//

`timescale 1 ns / 1 ns

`include "toysram.vh"

module ra_cfg_ddr (

clk,
reset,
cfg_wr,
cfg_dat,
cfg

);

parameter GENMODE = `GENMODE; // 0=NoDelay, 1=Delay
parameter INIT = `LCBDDR_CONFIGWIDTH'b0;

input clk;
input reset;
input cfg_wr;
input [0:`LCBDDR_CONFIGWIDTH-1] cfg_dat;
output [0:`LCBDDR_CONFIGWIDTH-1] cfg;

reg [0:`LCBDDR_CONFIGWIDTH-1] cfg_q;
wire [0:`LCBDDR_CONFIGWIDTH-1] cfg_d;

// ff
always @ (posedge clk) begin
if (reset)
cfg_q <= INIT;
else
cfg_q <= cfg_d;
end

// do something
assign cfg_d = (cfg_wr) ? cfg_dat : cfg_q;

// outputs
assign cfg = cfg_q;

endmodule

@ -0,0 +1,65 @@
// © 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.


// Local Configuration for arrays
//

`timescale 1 ns / 1 ns

`include "toysram.vh"

module ra_cfg_sdr(

clk,
reset,
cfg_wr,
cfg_dat,
cfg

);

parameter GENMODE = `GENMODE; // 0=NoDelay, 1=Delay
parameter INIT = `LCBSDR_CONFIGWIDTH'b0;

input clk;
input reset;
input cfg_wr;
input [0:`LCBSDR_CONFIGWIDTH-1] cfg_dat;
output [0:`LCBSDR_CONFIGWIDTH-1] cfg;

reg [0:`LCBSDR_CONFIGWIDTH-1] cfg_q;
wire [0:`LCBSDR_CONFIGWIDTH-1] cfg_d;

// ff
always @ (posedge clk) begin
if (reset)
cfg_q <= INIT;
else
cfg_q <= cfg_d;
end

// do something
assign cfg_d = (cfg_wr) ? cfg_dat : cfg_q;

// outputs
assign cfg = cfg_q;

endmodule

@ -0,0 +1,51 @@
// © 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.


// Delay Block for Array Strobe

`timescale 1 ns / 1 ns

`include "toysram.vh"

module ra_delay(

i,
o

);

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

input i;
output o;

// generate strobe
generate

if (GENMODE == 0)
assign o = 1;
else begin
assign o = 1'bX; //wtf this will be a specific tech cell instantiation
end

endgenerate

endmodule

@ -0,0 +1,124 @@
// © 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.


// Local Clock Buffer for arrays
// Generates sim or implementation logic, depending on GENMODE.
// el_sel is early/late select (first/second pulse of cycle)

`timescale 1 ns / 1 ns

`include "toysram.vh"

module ra_lcb_ddr (

clk, // =clk2x for genmode=0
reset, // used for genmode=1? seems not; could kill strobe with it
cfg,
strobe,
el_sel

);

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

input clk;
input reset;
input [0:`LCBDDR_CONFIGWIDTH-1] cfg;
output strobe;
output el_sel;

//generate
// if (GENMODE == 0)
reg el_sel_q;
//endgenerate

wire clk_dly;
wire o0;
wire o1;
wire clk_dly2;

// generate strobe
generate

if (GENMODE == 0)
assign strobe = !clk & !reset; // strobe is inverted clk2x
else begin

// generate a strobe for ddr - is late pulse a delay of this, or gen'd independently from clk??
// clk -> [delay] -> * --------------------- * -- and ---
// | -- [delay] --- inv ---|

// first edge delay
ra_delay d0 (
.i(clk),
.o(o0)
);
// remaining
/*
genvar i;
for (i = 1; i < `MAX_PULSE_DELAYS-1; i = i + 1) begin : d1
ra_delay (
.i()
.o()
)
end
*/
// select tap based on cfg

assign clk_dly = o0;

// first width delay
ra_delay w0 (
.i(clk_dly),
.o(o1)
);

// remaining
// select tap based on cfg

assign clk_dly2 = o1;

// create strobe
assign strobe = clk_dly & !clk_dly2;

end

endgenerate

// generate el_sel
generate

if (GENMODE == 0) begin
always @ (posedge clk)
if (reset)
el_sel_q <= 1'b0;
else
el_sel_q <= !el_sel_q;
assign el_sel = el_sel_q;
end else begin

// el_sel is delayed version of clk

end

endgenerate

endmodule

@ -0,0 +1,99 @@
// © 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.


// Local Clock Buffer for arrays
// Generates sim or implementation logic, depending on GENMODE.

`timescale 1 ns / 1 ns

`include "toysram.vh"

module ra_lcb_sdr (

clk,
reset,
cfg,
strobe

);

parameter GENMODE = `GENMODE; // 0=NoDelay, 1=Delay
input clk;
input reset;
input [0:`LCBSDR_CONFIGWIDTH-1] cfg;
output strobe;

wire clk_dly;
wire i;
wire o0;
wire o1;
wire clk_dly2;

// generate strobe
generate

if (GENMODE == 0)
assign strobe = !clk & !reset;
else begin

// generate a strobe for sdr
// clk -> [delay] -> * --------------------- * -- and ---
// | -- [delay] --- inv ---|

// first edge delay
ra_delay d0 (
.i(i),
.o(o0)
);
// remaining
/*
genvar i;
for (i = 1; i < `MAX_PULSE_DELAYS-1; i = i + 1) begin : d1
ra_delay (
.i()
.o()
)
end
*/
// select tap based on cfg

assign clk_dly = o0;

// first width delay
ra_delay w0 (
.i(clk_dly),
.o(o1)
);

// remaining
// select tap based on cfg

assign clk_dly2 = o1;


// create strobe
assign strobe = clk_dly & !clk_dly2;

end

endgenerate

endmodule

@ -0,0 +1,194 @@
// © 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.


// Behavioral for 32x32 toysram (sdr or ddr)
// I/Os are equivalent to physical macro
// This version has the enables encoded in a0.

`timescale 1 ps / 1 ps

module regfile_2r1w_32x32(

rd0_c_na0,
rd0_c_a0,
rd0_na1_na2,
rd0_na1_a2,
rd0_a1_na2,
rd0_a1_a2,
rd0_na3,
rd0_a3,
rd0_na4,
rd0_a4,
rd0_dat,

rd1_c_na0,
rd1_c_a0,
rd1_na1_na2,
rd1_na1_a2,
rd1_a1_na2,
rd1_a1_a2,
rd1_na3,
rd1_a3,
rd1_na4,
rd1_a4,
rd1_dat,

wr0_c_na0,
wr0_c_a0,
wr0_na1_na2,
wr0_na1_a2,
wr0_a1_na2,
wr0_a1_a2,
wr0_na3,
wr0_a3,
wr0_na4,
wr0_a4,
wr0_dat

);

// -- predecoded address
// -- four groups of one hot encoded signals

// -- read address 0
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;
input rd0_a4;

// -- read address 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;
input rd1_a4;

// -- write address 0
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;
input wr0_a4;

// -- data ports
output [0:31] rd0_dat;
output [0:31] rd1_dat;
input [0:31] wr0_dat;

wire rd0_enable;
wire rd1_enable;
wire wr0_enable;

wire rd0_a0;
wire rd0_a1;
wire rd0_a2;
// wire rd0_a3;
// wire rd0_a4;

wire rd1_a0;
wire rd1_a1;
wire rd1_a2;
// wire rd1_a3;
// wire rd1_a4;

wire wr0_a0;
wire wr0_a1;
wire wr0_a2;
//wire wr0_a3;
// wire wr0_a4;

// array cells
reg[0:31] mem[0:31];

//wtf:icarus $dumpvars cannot dump a vpiMemory
generate
genvar i;
for (i = 0; i < 31; i=i+1) begin: ra
wire [0:31] q;
assign q = mem[i];
end
endgenerate

// decode inputs, rd0
assign rd0_enable = rd0_c_a0 | rd0_c_na0;
assign rd0_a0 = rd0_c_a0;
assign rd0_a1 = rd0_a1_a2 | rd0_a1_na2;
assign rd0_a2 = rd0_a1_a2 | rd0_na1_a2;
// assign rd0_a3 = rd0_a3;
// assign rd0_a4 = rd0_a4;

// deocde inputs, rd1
assign rd1_enable = rd1_c_a0 | rd1_c_na0;
assign rd1_a0 = rd1_c_a0;
assign rd1_a1 = rd1_a1_a2 | rd1_a1_na2;
assign rd1_a2 = rd1_a1_a2 | rd1_na1_a2;
// assign rd1_a3 = rd1_a3;
// assign rd1_a4 = rd1_a4;

// decode inputs, wr0
assign wr0_enable = wr0_c_a0 | wr0_c_na0;
assign wr0_a0 = wr0_c_a0;
assign wr0_a1 = wr0_a1_a2 | wr0_a1_na2;
assign wr0_a2 = wr0_a1_a2 | wr0_na1_a2;
// assign wr0_a3 = wr0_a3;
// assign wr0_a4 = wr0_a4;

// read ports
assign rd0_dat = (rd0_enable) ? mem[{rd0_a0, rd0_a1, rd0_a2, rd0_a3, rd0_a4}] : 31'bX;
assign rd1_dat = (rd1_enable) ? mem[{rd1_a0, rd1_a1, rd1_a2, rd1_a3, rd1_a4}] : 31'bX;

// write port
always @* begin
if (wr0_enable) begin
#10; // make sure addr settles
if (wr0_enable) begin
mem[{wr0_a0, wr0_a1, wr0_a2, wr0_a3, wr0_a4}] <= wr0_dat;
//$display("%0d wr0_en=%h @%0h=%0h", $time, wr0_enable, {wr0_a0, wr0_a1, wr0_a2, wr0_a3, wr0_a4}, mem[{wr0_a0, wr0_a1, wr0_a2, wr0_a3, wr0_a4}]);
end
end
end

endmodule

@ -0,0 +1,204 @@
// © 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.


// Behavioral for 64x24 toysram (sdr or ddr)
// I/Os are equivalent to physical macro
// This version has the enables encoded in a0.

`timescale 1 ps / 1 ps

module regfile_2r1w_64x24(

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,
rd0_dat,

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,
rd1_dat,

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,
wr0_dat

);

// -- predecoded address
// -- four groups of one hot encoded signals
// -- read address 0
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;

// -- read address 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;

// -- write address 0
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;

// -- data ports
output [0:23] rd0_dat;
output [0:23] rd1_dat;
input [0:23] wr0_dat;

wire rd0_enable;
wire rd1_enable;
wire wr0_enable;

wire rd0_a0;
wire rd0_a1;
wire rd0_a2;
// wire rd0_a3;
wire rd0_a4;
wire rd0_a5;

wire rd1_a0;
wire rd1_a1;
wire rd1_a2;
// wire rd1_a3;
wire rd1_a4;
wire rd1_a5;

wire wr0_a0;
wire wr0_a1;
wire wr0_a2;
//wire wr0_a3;
wire wr0_a4;
wire wr0_a5;

// array cells
reg[0:23] mem[0:63];

// decode inputs, rd0
assign rd0_enable = rd0_c_a0 | rd0_c_na0;
assign rd0_a0 = rd0_c_a0;
assign rd0_a1 = rd0_a1_a2 | rd0_a1_na2;
assign rd0_a2 = rd0_a1_a2 | rd0_na1_a2;
// assign rd0_a3 = rd0_a3;
assign rd0_a4 = rd0_a4_a5 | rd0_a4_na5;
assign rd0_a5 = rd0_a4_a5 | rd0_na4_a5;

// deocde inputs, rd1
assign rd1_enable = rd1_c_a0 | rd1_c_na0;
assign rd1_a0 = rd1_c_a0;
assign rd1_a1 = rd1_a1_a2 | rd1_a1_na2;
assign rd1_a2 = rd1_a1_a2 | rd1_na1_a2;
// assign rd1_a3 = rd1_a3;
assign rd1_a4 = rd1_a4_a5 | rd1_a4_na5;
assign rd1_a5 = rd1_a4_a5 | rd1_na4_a5;


// decode inputs, wr0
assign wr0_enable = wr0_c_a0 | wr0_c_na0;
assign wr0_a0 = wr0_c_a0;
assign wr0_a1 = wr0_a1_a2 | wr0_a1_na2;
assign wr0_a2 = wr0_a1_a2 | wr0_na1_a2;
// assign wr0_a3 = wr0_a3;
assign wr0_a4 = wr0_a4_a5 | wr0_a4_na5;
assign wr0_a5 = wr0_a4_a5 | wr0_na4_a5;


// read ports
assign rd0_dat = (rd0_enable) ? mem[{rd0_a0, rd0_a1, rd0_a2, rd0_a3, rd0_a4, rd0_a5}] : 24'bX;
assign rd1_dat = (rd1_enable) ? mem[{rd1_a0, rd1_a1, rd1_a2, rd1_a3, rd1_a4, rd1_a5}] : 24'bX;

// write port
always @* begin
if (wr0_enable) begin
#10; // make sure addr settles
if (wr0_enable) begin
mem[{wr0_a0, wr0_a1, wr0_a2, wr0_a3, wr0_a4, wr0_a5}] <= wr0_dat;
//$display("%0d wr0_en=%h @%0h=%0h", $time, wr0_enable, {wr0_a0, wr0_a1, wr0_a2, wr0_a3, wr0_a4, wr0_a5}, mem[{wr0_a0, wr0_a1, wr0_a2, wr0_a3, wr0_a4, wr0_a5}]);
end
end
end

endmodule

@ -0,0 +1,335 @@
// © 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.


// Behavioral for 64x24 toysram (sdr or ddr)
// I/Os are equivalent to physical macro
// This version has the enables encoded in a0.

`timescale 1 ns / 1 ns

module regfile_4r2w_64x24 (

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,
rd0_dat,

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,
rd1_dat,

rd2_c_na0,
rd2_c_a0,
rd2_na1_na2,
rd2_na1_a2,
rd2_a1_na2,
rd2_a1_a2,
rd2_na3,
rd2_a3,
rd2_na4_na5,
rd2_na4_a5,
rd2_a4_na5,
rd2_a4_a5,
rd2_dat,

rd3_c_na0,
rd3_c_a0,
rd3_na1_na2,
rd3_na1_a2,
rd3_a1_na2,
rd3_a1_a2,
rd3_na3,
rd3_a3,
rd3_na4_na5,
rd3_na4_a5,
rd3_a4_na5,
rd3_a4_a5,
rd3_dat,

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,
wr0_dat,

wr1_c_na0,
wr1_c_a0,
wr1_na1_na2,
wr1_na1_a2,
wr1_a1_na2,
wr1_a1_a2,
wr1_na3,
wr1_a3,
wr1_na4_na5,
wr1_na4_a5,
wr1_a4_na5,
wr1_a4_a5,
wr1_dat

);

// -- predecoded address
// -- four groups of one hot encoded signals
// -- read address 0
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;

// -- read address 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;

// -- read address 2
input rd2_c_na0;
input rd2_c_a0;
input rd2_na1_na2;
input rd2_na1_a2;
input rd2_a1_na2;
input rd2_a1_a2;
input rd2_na3;
input rd2_a3;
input rd2_na4_na5;
input rd2_na4_a5;
input rd2_a4_na5;
input rd2_a4_a5;

// -- read address 3
input rd3_c_na0;
input rd3_c_a0;
input rd3_na1_na2;
input rd3_na1_a2;
input rd3_a1_na2;
input rd3_a1_a2;
input rd3_na3;
input rd3_a3;
input rd3_na4_na5;
input rd3_na4_a5;
input rd3_a4_na5;
input rd3_a4_a5;

// -- write address 0
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;

// -- write address 1
input wr1_c_na0;
input wr1_c_a0;
input wr1_na1_na2;
input wr1_na1_a2;
input wr1_a1_na2;
input wr1_a1_a2;
input wr1_na3;
input wr1_a3;
input wr1_na4_na5;
input wr1_na4_a5;
input wr1_a4_na5;
input wr1_a4_a5;

// -- data ports
output [0:23] rd0_dat;
output [0:23] rd1_dat;
output [0:23] rd2_dat;
output [0:23] rd3_dat;
input [0:23] wr0_dat;
input [0:23] wr1_dat;

wire rd0_enable;
wire rd1_enable;
wire rd2_enable;
wire rd3_enable;
wire wr0_enable;
wire wr1_enable;


wire rd0_a0;
wire rd0_a1;
wire rd0_a2;
// wire rd0_a3;
wire rd0_a4;
wire rd0_a5;

wire rd1_a0;
wire rd1_a1;
wire rd1_a2;
// wire rd1_a3;
wire rd1_a4;
wire rd1_a5;

wire rd2_a0;
wire rd2_a1;
wire rd2_a2;
// wire rd2_a3;
wire rd2_a4;
wire rd2_a5;

wire rd3_a0;
wire rd3_a1;
wire rd3_a2;
// wire rd3_a3;
wire rd3_a4;
wire rd3_a5;

wire wr0_a0;
wire wr0_a1;
wire wr0_a2;
//wire wr0_a3;
wire wr0_a4;
wire wr0_a5;

wire wr1_a0;
wire wr1_a1;
wire wr1_a2;
//wire wr1_a3;
wire wr1_a4;
wire wr1_a5;

// array cells
reg[0:23] mem[0:63];

// decode inputs, rd0
assign rd0_enable = rd0_c_a0 | rd0_c_na0;
assign rd0_a0 = rd0_c_a0;
assign rd0_a1 = rd0_a1_a2 | rd0_a1_na2;
assign rd0_a2 = rd0_a1_a2 | rd0_na1_a2;
// assign rd0_a3 = rd0_a3;
assign rd0_a4 = rd0_a4_a5 | rd0_a4_na5;
assign rd0_a5 = rd0_a4_a5 | rd0_na4_a5;

// deocde inputs, rd1
assign rd1_enable = rd1_c_a0 | rd1_c_na0;
assign rd1_a0 = rd1_c_a0;
assign rd1_a1 = rd1_a1_a2 | rd1_a1_na2;
assign rd1_a2 = rd1_a1_a2 | rd1_na1_a2;
// assign rd1_a3 = rd1_a3;
assign rd1_a4 = rd1_a4_a5 | rd1_a4_na5;
assign rd1_a5 = rd1_a4_a5 | rd1_na4_a5;

// deocde inputs, rd2
assign rd2_enable = rd2_c_a0 | rd2_c_na0;
assign rd2_a0 = rd2_c_a0;
assign rd2_a1 = rd2_a1_a2 | rd2_a1_na2;
assign rd2_a2 = rd2_a1_a2 | rd2_na1_a2;
// assign rd2_a3 = rd2_a3;
assign rd2_a4 = rd2_a4_a5 | rd2_a4_na5;
assign rd2_a5 = rd2_a4_a5 | rd2_na4_a5;

// deocde inputs, rd3
assign rd3_enable = rd3_c_a0 | rd3_c_na0;
assign rd3_a0 = rd3_c_a0;
assign rd3_a1 = rd3_a1_a2 | rd3_a1_na2;
assign rd3_a2 = rd3_a1_a2 | rd3_na1_a2;
// assign rd3_a3 = rd3_a3;
assign rd3_a4 = rd3_a4_a5 | rd3_a4_na5;
assign rd3_a5 = rd3_a4_a5 | rd3_na4_a5;

// decode inputs, wr0
assign wr0_enable = wr0_c_a0 | wr0_c_na0;
assign wr0_a0 = wr0_c_a0;
assign wr0_a1 = wr0_a1_a2 | wr0_a1_na2;
assign wr0_a2 = wr0_a1_a2 | wr0_na1_a2;
// assign wr0_a3 = wr0_a3;
assign wr0_a4 = wr0_a4_a5 | wr0_a4_na5;
assign wr0_a5 = wr0_a4_a5 | wr0_na4_a5;

// decode inputs, wr1
assign wr1_enable = wr1_c_a0 | wr1_c_na0;
assign wr1_a0 = wr1_c_a0;
assign wr1_a1 = wr1_a1_a2 | wr1_a1_na2;
assign wr1_a2 = wr1_a1_a2 | wr1_na1_a2;
// assign wr1_a3 = wr1_a3;
assign wr1_a4 = wr1_a4_a5 | wr1_a4_na5;
assign wr1_a5 = wr1_a4_a5 | wr1_na4_a5;

// read ports
assign rd0_dat = (rd0_enable) ? mem[{rd0_a0, rd0_a1, rd0_a2, rd0_a3, rd0_a4, rd0_a5}] : 24'bX;
assign rd1_dat = (rd1_enable) ? mem[{rd1_a0, rd1_a1, rd1_a2, rd1_a3, rd1_a4, rd1_a5}] : 24'bX;
assign rd2_dat = (rd2_enable) ? mem[{rd2_a0, rd2_a1, rd2_a2, rd2_a3, rd2_a4, rd2_a5}] : 24'bX;
assign rd3_dat = (rd3_enable) ? mem[{rd3_a0, rd3_a1, rd3_a2, rd3_a3, rd3_a4, rd3_a5}] : 24'bX;

//wtf should have checking for collision
always @* begin
if (wr0_enable) begin
mem[{wr0_a0, wr0_a1, wr0_a2, wr0_a3, wr0_a4, wr0_a5}] <= wr0_dat;
//$display("%0d wr0_en=%h @%0h=%0h", $time, wr0_enable, {wr0_a0, wr0_a1, wr0_a2, wr0_a3, wr0_a4, wr0_a5}, mem[{wr0_a0, wr0_a1, wr0_a2, wr0_a3, wr0_a4, wr0_a5}]);
end
if (wr1_enable) begin
mem[{wr1_a0, wr1_a1, wr1_a2, wr1_a3, wr1_a4, wr1_a5}] <= wr1_dat;
//$display("%0d wr1_en=%h @%0h=%0h", $time, wr1_enable, {wr1_a0, wr1_a1, wr1_a2, wr1_a3, wr0_a4, wr1_a5}, mem[{wr1_a0, wr1_a1, wr1_a2, wr1_a3, wr1_a4, wr1_a5}]);
end
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,197 @@
// © 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.

// Test array (SDR)
// 64 word 72 bit array
// LCB for strobe generation
// Config, BIST, etc.

`timescale 1 ns/1 ps
`include "toysram.vh"

module test_ra_ddr ();

logic clk;
logic clk2x;
logic reset;
logic cfg_wr;
logic [0:`LCBDDR_CONFIGWIDTH-1] cfg_dat;
logic [0:31] bist_ctl;
logic [0:31] bist_status;
logic rd_enb_0;
logic [0:5] rd_adr_0;
logic [0:71] rd_dat_0;
logic rd_enb_1;
logic [0:5] rd_adr_1;
logic [0:71] rd_dat_1;
logic rd_enb_2;
logic [0:5] rd_adr_2;
logic [0:71] rd_dat_2;
logic rd_enb_3;
logic [0:5] rd_adr_3;
logic [0:71] rd_dat_3;
logic wr_enb_0;
logic [0:5] wr_adr_0;
logic [0:71] wr_dat_0;
logic wr_enb_1;
logic [0:5] wr_adr_1;
logic [0:71] wr_dat_1;
logic strobe;
logic el_sel;
logic [0:`LCBDDR_CONFIGWIDTH-1] cfg;
logic mux_rd0_enb;
logic [0:5] mux_rd0_adr;
logic mux_rd1_enb;
logic [0:5] mux_rd1_adr;
logic mux_rd2_enb;
logic [0:5] mux_rd2_adr;
logic mux_rd3_enb;
logic [0:5] mux_rd3_adr;
logic mux_wr0_enb;
logic [0:5] mux_wr0_adr;
logic [0:71] mux_wr0_dat;
logic mux_wr1_enb;
logic [0:5] mux_wr1_adr;
logic [0:71] mux_wr1_dat;
initial
begin
clk = 1'b1;
clk2x = 1'b1;
forever #10 clk = ~clk;
forever #5 clk2x = ~clk2x;
end


ra_lcb_ddr lcb (

.clk (clk2x),
.reset (reset),
.cfg (cfg),
.strobe (strobe),
.el_sel (el_sel)

);

ra_cfg_ddr #(.INIT(-1)) cfig (

.clk (clk),
.reset (reset),
.cfg_wr (cfg_wr),
.cfg_dat (cfg_dat),
.cfg (cfg)

);

ra_bist_ddr bist (

.clk (clk),
.reset (reset),
.ctl (bist_ctl),
.status (bist_status),
.rd0_enb_in (rd_enb_0),
.rd0_adr_in (rd_adr_0),
.rd0_dat (rd_dat_0),
.rd1_enb_in (rd_enb_1),
.rd1_adr_in (rd_adr_1),
.rd1_dat (rd_dat_1),
.rd2_enb_in (rd_enb_2),
.rd2_adr_in (rd_adr_2),
.rd2_dat (rd_dat_2),
.rd3_enb_in (rd_enb_3),
.rd3_adr_in (rd_adr_3),
.rd3_dat (rd_dat_3),
.wr0_enb_in (wr_enb_0),
.wr0_adr_in (wr_adr_0),
.wr0_dat_in (wr_dat_0),
.wr1_enb_in (wr_enb_1),
.wr1_adr_in (wr_adr_1),
.wr1_dat_in (wr_dat_1),
.rd0_enb_out (mux_rd0_enb),
.rd0_adr_out (mux_rd0_adr),
.rd1_enb_out (mux_rd1_enb),
.rd1_adr_out (mux_rd1_adr),
.rd2_enb_out (mux_rd2_enb),
.rd2_adr_out (mux_rd2_adr),
.rd3_enb_out (mux_rd3_enb),
.rd3_adr_out (mux_rd3_adr),
.wr0_enb_out (mux_wr0_enb),
.wr0_adr_out (mux_wr0_adr),
.wr0_dat_out (mux_wr0_dat),
.wr1_enb_out (mux_wr1_enb),
.wr1_adr_out (mux_wr1_adr),
.wr1_dat_out (mux_wr1_dat)

);

ra_4r2w_64x72_ddr ra (

.clk (clk),
.reset (reset),
.strobe (strobe),
.el_sel (el_sel),
.rd_enb_0 (mux_rd0_enb),
.rd_adr_0 (mux_rd0_adr),
.rd_dat_0 (rd_dat_0),
.rd_enb_1 (mux_rd1_enb),
.rd_adr_1 (mux_rd1_adr),
.rd_dat_1 (rd_dat_1),
.rd_enb_2 (mux_rd2_enb),
.rd_adr_2 (mux_rd2_adr),
.rd_dat_2 (rd_dat_2),
.rd_enb_3 (mux_rd3_enb),
.rd_adr_3 (mux_rd3_adr),
.rd_dat_3 (rd_dat_3),
.wr_enb_0 (mux_wr0_enb),
.wr_adr_0 (mux_wr0_adr),
.wr_dat_0 (mux_wr0_dat),
.wr_enb_1 (mux_wr1_enb),
.wr_adr_1 (mux_wr1_adr),
.wr_dat_1 (mux_wr1_dat)

);

initial
begin
#0 reset = 1'b1;
#0 wr_enb_0 = 1'b0;
#0 wr_adr_0 = 6'h0;
#0 rd_adr_0 = 6'h0;
#0 rd_adr_1 = 6'h0;
#0 rd_enb_0 = 1'b0;
#0 rd_enb_1 = 1'b0;
#0 bist_ctl = 32'h0;
#0 cfg_wr = 1'b0;
#0 cfg_dat = 16'h0;
#31 reset = 1'b0;

#400 wr_enb_0 = 1'b1;
#0 wr_adr_0 = 6'h0;
#0 wr_adr_0 = 6'b00_0000;
#10 wr_adr_0 = 6'b00_0010;
#10 wr_adr_0 = 6'b00_0100;
#10 wr_adr_0 = 6'b00_0110;
#10 wr_adr_0 = 6'b00_1000;


end

endmodule

@ -0,0 +1,199 @@
// © 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.


// Test array (DDR)
// 64 word 72 bit array
// LCB for strobe generation
// Config, BIST, etc.

`timescale 1 ns / 1 ns

`include "toysram.vh"

module test_ra_ddr (

clk,
clk2x,
reset,
cfg_wr,
cfg_dat,
bist_ctl,
bist_status,

rd_enb_0,
rd_adr_0,
rd_dat_0,

rd_enb_1,
rd_adr_1,
rd_dat_1,

rd_enb_2,
rd_adr_2,
rd_dat_2,

rd_enb_3,
rd_adr_3,
rd_dat_3,

wr_enb_0,
wr_adr_0,
wr_dat_0,

wr_enb_1,
wr_adr_1,
wr_dat_1

);

input clk;
input clk2x;
input reset;
input cfg_wr;
input [0:`LCBDDR_CONFIGWIDTH-1] cfg_dat;
input [0:31] bist_ctl;
output [0:31] bist_status;
input rd_enb_0;
input [0:5] rd_adr_0;
output [0:71] rd_dat_0;
input rd_enb_1;
input [0:5] rd_adr_1;
output [0:71] rd_dat_1;
input rd_enb_2;
input [0:5] rd_adr_2;
output [0:71] rd_dat_2;
input rd_enb_3;
input [0:5] rd_adr_3;
output [0:71] rd_dat_3;
input wr_enb_0;
input [0:5] wr_adr_0;
input [0:71] wr_dat_0;
input wr_enb_1;
input [0:5] wr_adr_1;
input [0:71] wr_dat_1;

wire strobe;
wire el_sel;
wire [0:`LCBDDR_CONFIGWIDTH-1] cfg;
wire mux_rd0_enb;
wire [0:5] mux_rd0_adr;
wire mux_rd1_enb;
wire [0:5] mux_rd1_adr;
wire mux_rd2_enb;
wire [0:5] mux_rd2_adr;
wire mux_rd3_enb;
wire [0:5] mux_rd3_adr;
wire mux_wr0_enb;
wire [0:5] mux_wr0_adr;
wire [0:71] mux_wr0_dat;
wire mux_wr1_enb;
wire [0:5] mux_wr1_adr;
wire [0:71] mux_wr1_dat;


ra_lcb_ddr lcb (

.clk (clk2x),
.reset (reset),
.cfg (cfg),
.strobe (strobe),
.el_sel (el_sel)

);

ra_cfg_ddr #(.INIT(-1)) cfig (

.clk (clk),
.reset (reset),
.cfg_wr (cfg_wr),
.cfg_dat (cfg_dat),
.cfg (cfg)

);

ra_bist_ddr bist (

.clk (clk),
.reset (reset),
.ctl (bist_ctl),
.status (bist_status),
.rd0_enb_in (rd_enb_0),
.rd0_adr_in (rd_adr_0),
.rd0_dat (rd_dat_0),
.rd1_enb_in (rd_enb_1),
.rd1_adr_in (rd_adr_1),
.rd1_dat (rd_dat_1),
.rd2_enb_in (rd_enb_2),
.rd2_adr_in (rd_adr_2),
.rd2_dat (rd_dat_2),
.rd3_enb_in (rd_enb_3),
.rd3_adr_in (rd_adr_3),
.rd3_dat (rd_dat_3),
.wr0_enb_in (wr_enb_0),
.wr0_adr_in (wr_adr_0),
.wr0_dat_in (wr_dat_0),
.wr1_enb_in (wr_enb_1),
.wr1_adr_in (wr_adr_1),
.wr1_dat_in (wr_dat_1),
.rd0_enb_out (mux_rd0_enb),
.rd0_adr_out (mux_rd0_adr),
.rd1_enb_out (mux_rd1_enb),
.rd1_adr_out (mux_rd1_adr),
.rd2_enb_out (mux_rd2_enb),
.rd2_adr_out (mux_rd2_adr),
.rd3_enb_out (mux_rd3_enb),
.rd3_adr_out (mux_rd3_adr),
.wr0_enb_out (mux_wr0_enb),
.wr0_adr_out (mux_wr0_adr),
.wr0_dat_out (mux_wr0_dat),
.wr1_enb_out (mux_wr1_enb),
.wr1_adr_out (mux_wr1_adr),
.wr1_dat_out (mux_wr1_dat)

);

ra_4r2w_64x72_ddr ra (

.clk (clk),
.reset (reset),
.strobe (strobe),
.el_sel (el_sel),
.rd_enb_0 (mux_rd0_enb),
.rd_adr_0 (mux_rd0_adr),
.rd_dat_0 (rd_dat_0),
.rd_enb_1 (mux_rd1_enb),
.rd_adr_1 (mux_rd1_adr),
.rd_dat_1 (rd_dat_1),
.rd_enb_2 (mux_rd2_enb),
.rd_adr_2 (mux_rd2_adr),
.rd_dat_2 (rd_dat_2),
.rd_enb_3 (mux_rd3_enb),
.rd_adr_3 (mux_rd3_adr),
.rd_dat_3 (rd_dat_3),
.wr_enb_0 (mux_wr0_enb),
.wr_adr_0 (mux_wr0_adr),
.wr_dat_0 (mux_wr0_dat),
.wr_enb_1 (mux_wr1_enb),
.wr_adr_1 (mux_wr1_adr),
.wr_dat_1 (mux_wr1_dat)

);

endmodule

@ -0,0 +1,196 @@
// © 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.


// Test array (DDR1x (sim only) - acts like DDR but only uses single clock
// 64 word 72 bit array
// LCB for strobe generation
// Config, BIST, etc.

`timescale 1 ns / 1 ns

`include "toysram.vh"

module test_ra_ddr_1x (

clk,
reset,
cfg_wr,
cfg_dat,
bist_ctl,
bist_status,

rd_enb_0,
rd_adr_0,
rd_dat_0,

rd_enb_1,
rd_adr_1,
rd_dat_1,

rd_enb_2,
rd_adr_2,
rd_dat_2,

rd_enb_3,
rd_adr_3,
rd_dat_3,

wr_enb_0,
wr_adr_0,
wr_dat_0,

wr_enb_1,
wr_adr_1,
wr_dat_1

);

input clk;
input reset;
input cfg_wr;
input [0:`LCBDDR_CONFIGWIDTH-1] cfg_dat;
input [0:31] bist_ctl;
output [0:31] bist_status;
input rd_enb_0;
input [0:5] rd_adr_0;
output [0:71] rd_dat_0;
input rd_enb_1;
input [0:5] rd_adr_1;
output [0:71] rd_dat_1;
input rd_enb_2;
input [0:5] rd_adr_2;
output [0:71] rd_dat_2;
input rd_enb_3;
input [0:5] rd_adr_3;
output [0:71] rd_dat_3;
input wr_enb_0;
input [0:5] wr_adr_0;
input [0:71] wr_dat_0;
input wr_enb_1;
input [0:5] wr_adr_1;
input [0:71] wr_dat_1;

wire strobe;
wire el_sel;
wire [0:`LCBDDR_CONFIGWIDTH-1] cfg;
wire mux_rd0_enb;
wire [0:5] mux_rd0_adr;
wire mux_rd1_enb;
wire [0:5] mux_rd1_adr;
wire mux_rd2_enb;
wire [0:5] mux_rd2_adr;
wire mux_rd3_enb;
wire [0:5] mux_rd3_adr;
wire mux_wr0_enb;
wire [0:5] mux_wr0_adr;
wire [0:71] mux_wr0_dat;
wire mux_wr1_enb;
wire [0:5] mux_wr1_adr;
wire [0:71] mux_wr1_dat;


ra_lcb_ddr lcb (

.clk (clk),
.reset (reset),
.cfg (cfg),
.strobe (strobe), // not used
.el_sel (el_sel)

);

ra_cfg_ddr #(.INIT(-1)) cfig (

.clk (clk),
.reset (reset),
.cfg_wr (cfg_wr),
.cfg_dat (cfg_dat),
.cfg (cfg)

);

ra_bist_ddr bist (

.clk (clk),
.reset (reset),
.ctl (bist_ctl),
.status (bist_status),
.rd0_enb_in (rd_enb_0),
.rd0_adr_in (rd_adr_0),
.rd0_dat (rd_dat_0),
.rd1_enb_in (rd_enb_1),
.rd1_adr_in (rd_adr_1),
.rd1_dat (rd_dat_1),
.rd2_enb_in (rd_enb_2),
.rd2_adr_in (rd_adr_2),
.rd2_dat (rd_dat_2),
.rd3_enb_in (rd_enb_3),
.rd3_adr_in (rd_adr_3),
.rd3_dat (rd_dat_3),
.wr0_enb_in (wr_enb_0),
.wr0_adr_in (wr_adr_0),
.wr0_dat_in (wr_dat_0),
.wr1_enb_in (wr_enb_1),
.wr1_adr_in (wr_adr_1),
.wr1_dat_in (wr_dat_1),
.rd0_enb_out (mux_rd0_enb),
.rd0_adr_out (mux_rd0_adr),
.rd1_enb_out (mux_rd1_enb),
.rd1_adr_out (mux_rd1_adr),
.rd2_enb_out (mux_rd2_enb),
.rd2_adr_out (mux_rd2_adr),
.rd3_enb_out (mux_rd3_enb),
.rd3_adr_out (mux_rd3_adr),
.wr0_enb_out (mux_wr0_enb),
.wr0_adr_out (mux_wr0_adr),
.wr0_dat_out (mux_wr0_dat),
.wr1_enb_out (mux_wr1_enb),
.wr1_adr_out (mux_wr1_adr),
.wr1_dat_out (mux_wr1_dat)

);

ra_4r2w_64x72_ddr_1x ra (

.clk (clk),
.reset (reset),
.strobe (1'b1),
.rd_enb_0 (mux_rd0_enb),
.rd_adr_0 (mux_rd0_adr),
.rd_dat_0 (rd_dat_0),
.rd_enb_1 (mux_rd1_enb),
.rd_adr_1 (mux_rd1_adr),
.rd_dat_1 (rd_dat_1),
.rd_enb_2 (mux_rd2_enb),
.rd_adr_2 (mux_rd2_adr),
.rd_dat_2 (rd_dat_2),
.rd_enb_3 (mux_rd3_enb),
.rd_adr_3 (mux_rd3_adr),
.rd_dat_3 (rd_dat_3),
.wr_enb_0 (mux_wr0_enb),
.wr_adr_0 (mux_wr0_adr),
.wr_dat_0 (mux_wr0_dat),
.wr_enb_1 (mux_wr1_enb),
.wr_adr_1 (mux_wr1_adr),
.wr_dat_1 (mux_wr1_dat)

);

endmodule

@ -0,0 +1,171 @@
// © 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.

// Test array (SDR)
// 64 word 72 bit array
// LCB for strobe generation
// Config, BIST, etc.

`timescale 1 ns/1 ps
`include "toysram.vh"

module test_ra_sdr ();

logic clk;
logic reset;
logic cfg_wr;
logic [0:`LCBSDR_CONFIGWIDTH-1] cfg_dat;
logic [0:31] bist_ctl;
logic [0:31] bist_status;
logic rd_enb_0;
logic [0:5] rd_adr_0;
logic [0:71] rd_dat_0;
logic rd_enb_1;
logic [0:5] rd_adr_1;
logic [0:71] rd_dat_1;
logic wr_enb_0;
logic [0:5] wr_adr_0;
logic [0:71] wr_dat_0;

logic strobe;
logic [0:`LCBSDR_CONFIGWIDTH-1] cfg;
logic mux_rd0_enb;
logic [0:5] mux_rd0_adr;
logic mux_rd1_enb;
logic [0:5] mux_rd1_adr;
logic mux_wr0_enb;
logic [0:5] mux_wr0_adr;
logic [0:71] mux_wr0_dat;

initial
begin
$dumpfile("test_ra_sdr.vcd");
$dumpvars (0,test_ra_sdr.lcb);
$dumpvars (0,test_ra_sdr.cfig);
$dumpvars (0,test_ra_sdr.bist);
$dumpvars (0,test_ra_sdr.ra);
end


initial
begin
clk = 1'b1;
forever #5 clk = ~clk;
end



ra_lcb_sdr lcb (.clk (clk),
.reset (reset),
.cfg (cfg),
.strobe (strobe));

ra_cfg_sdr #(.INIT(-1)) cfig (.clk (clk),
.reset (reset),
.cfg_wr (cfg_wr),
.cfg_dat (cfg_dat),
.cfg (cfg));

ra_bist_sdr bist (.clk (clk),
.reset (reset),
.ctl (bist_ctl),
.status (bist_status),
.rd0_enb_in (rd_enb_0),
.rd0_adr_in (rd_adr_0),
.rd0_dat (rd_dat_0),
.rd1_enb_in (rd_enb_1),
.rd1_adr_in (rd_adr_1),
.rd1_dat (rd_dat_1),
.wr0_enb_in (wr_enb_0),
.wr0_adr_in (wr_adr_0),
.wr0_dat_in (wr_dat_0),
.rd0_enb_out (mux_rd0_enb),
.rd0_adr_out (mux_rd0_adr),
.rd1_enb_out (mux_rd1_enb),
.rd1_adr_out (mux_rd1_adr),
.wr0_enb_out (mux_wr0_enb),
.wr0_adr_out (mux_wr0_adr),
.wr0_dat_out (mux_wr0_dat));


ra_2r1w_64x72_sdr ra (.clk (clk),
.reset (reset),
.strobe (strobe),
.rd_enb_0 (mux_rd0_enb),
.rd_adr_0 (mux_rd0_adr),
.rd_dat_0 (rd_dat_0),
.rd_enb_1 (mux_rd1_enb),
.rd_adr_1 (mux_rd1_adr),
.rd_dat_1 (rd_dat_1),
.wr_enb_0 (mux_wr0_enb),
.wr_adr_0 (mux_wr0_adr),
.wr_dat_0 (mux_wr0_dat));

initial
begin
#0 reset = 1'b1;
#0 wr_enb_0 = 1'b0;
#0 wr_adr_0 = 6'h0;
#0 rd_adr_0 = 6'h0;
#0 rd_adr_1 = 6'h0;
#0 rd_enb_0 = 1'b0;
#0 rd_enb_1 = 1'b0;
#0 bist_ctl = 32'h0;
#0 cfg_wr = 1'b0;
#0 cfg_dat = 16'h0;
#15 reset = 1'b0;

#400 wr_enb_0 = 1'b1;
#0 wr_adr_0 = 6'h0;

#0 wr_adr_0 = 6'b00_0000;
#0 wr_dat_0 = 6'b00_1111;

#10 wr_adr_0 = 6'b00_0010;
#0 wr_dat_0 = 6'b00_1001;

#10 wr_adr_0 = 6'b00_0100;
#0 wr_dat_0 = 6'b00_1100;

#10 wr_adr_0 = 6'b00_0110;
#0 wr_adr_0 = 6'b00_1101;

#10 wr_adr_0 = 6'b00_1000;
#0 wr_adr_0 = 6'b00_1000;

#5 wr_enb_0 = 0;

#5 rd_enb_0 = 1;
#0 rd_enb_1 = 1;

#10 rd_adr_0 = 6'b00_0000;
#0 rd_adr_1 = 6'b00_0010;

#10 rd_adr_0 = 6'b00_0100;
#0 rd_adr_1 = 6'b00_0110;

#10 rd_adr_0 = 6'b00_1000;

#5 rd_enb_0 = 0;
#0 rd_enb_1 = 0;


end

endmodule

@ -0,0 +1,143 @@
// © 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.


// Test array (SDR)
// 32 word 32 bit array
// LCB for strobe generation
// Config, BIST, etc.

`timescale 1 ns / 1 ns

`include "toysram.vh"

module test_ra_sdr_32x32 (

clk,
reset,
cfg_wr,
cfg_dat,
bist_ctl,
bist_status,

rd_enb_0,
rd_adr_0,
rd_dat_0,

rd_enb_1,
rd_adr_1,
rd_dat_1,

wr_enb_0,
wr_adr_0,
wr_dat_0

);

input clk;
input reset;
input cfg_wr;
input [0:`LCBSDR_CONFIGWIDTH-1] cfg_dat;
input [0:31] bist_ctl;
output [0:31] bist_status;
input rd_enb_0;
input [0:4] rd_adr_0;
output [0:31] rd_dat_0;
input rd_enb_1;
input [0:4] rd_adr_1;
output [0:31] rd_dat_1;
input wr_enb_0;
input [0:4] wr_adr_0;
input [0:31] wr_dat_0;

wire strobe;
wire [0:`LCBSDR_CONFIGWIDTH-1] cfg;
wire mux_rd0_enb;
wire [0:4] mux_rd0_adr;
wire mux_rd1_enb;
wire [0:4] mux_rd1_adr;
wire mux_wr0_enb;
wire [0:4] mux_wr0_adr;
wire [0:31] mux_wr0_dat;

ra_lcb_sdr lcb (

.clk (clk),
.reset (reset),
.cfg (cfg),
.strobe (strobe)

);

ra_cfg_sdr #(.INIT(-1)) cfig (

.clk (clk),
.reset (reset),
.cfg_wr (cfg_wr),
.cfg_dat (cfg_dat),
.cfg (cfg)

);

ra_bist_sdr_32x32 bist (

.clk (clk),
.reset (reset),
.ctl (bist_ctl),
.status (bist_status),
.rd0_enb_in (rd_enb_0),
.rd0_adr_in (rd_adr_0),
.rd0_dat (rd_dat_0),
.rd1_enb_in (rd_enb_1),
.rd1_adr_in (rd_adr_1),
.rd1_dat (rd_dat_1),
.wr0_enb_in (wr_enb_0),
.wr0_adr_in (wr_adr_0),
.wr0_dat_in (wr_dat_0),
.rd0_enb_out (mux_rd0_enb),
.rd0_adr_out (mux_rd0_adr),
.rd1_enb_out (mux_rd1_enb),
.rd1_adr_out (mux_rd1_adr),
.wr0_enb_out (mux_wr0_enb),
.wr0_adr_out (mux_wr0_adr),
.wr0_dat_out (mux_wr0_dat)

);

ra_2r1w_32x32_sdr ra (

.clk (clk),
.reset (reset),
.strobe (strobe),
.rd_enb_0 (mux_rd0_enb),
.rd_adr_0 (mux_rd0_adr),
.rd_dat_0 (rd_dat_0),
.rd_enb_1 (mux_rd1_enb),
.rd_adr_1 (mux_rd1_adr),
.rd_dat_1 (rd_dat_1),
.wr_enb_0 (mux_wr0_enb),
.wr_adr_0 (mux_wr0_adr),
.wr_dat_0 (mux_wr0_dat)

);



endmodule

@ -0,0 +1,143 @@
// © 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.


// Test array (SDR)
// 64 word 72 bit array
// LCB for strobe generation
// Config, BIST, etc.

`timescale 1 ns / 1 ns

`include "toysram.vh"

module test_ra_sdr (

clk,
reset,
cfg_wr,
cfg_dat,
bist_ctl,
bist_status,

rd_enb_0,
rd_adr_0,
rd_dat_0,

rd_enb_1,
rd_adr_1,
rd_dat_1,

wr_enb_0,
wr_adr_0,
wr_dat_0

);

input clk;
input reset;
input cfg_wr;
input [0:`LCBSDR_CONFIGWIDTH-1] cfg_dat;
input [0:31] bist_ctl;
output [0:31] bist_status;
input rd_enb_0;
input [0:5] rd_adr_0;
output [0:71] rd_dat_0;
input rd_enb_1;
input [0:5] rd_adr_1;
output [0:71] rd_dat_1;
input wr_enb_0;
input [0:5] wr_adr_0;
input [0:71] wr_dat_0;

wire strobe;
wire [0:`LCBSDR_CONFIGWIDTH-1] cfg;
wire mux_rd0_enb;
wire [0:5] mux_rd0_adr;
wire mux_rd1_enb;
wire [0:5] mux_rd1_adr;
wire mux_wr0_enb;
wire [0:5] mux_wr0_adr;
wire [0:71] mux_wr0_dat;

ra_lcb_sdr lcb (

.clk (clk),
.reset (reset),
.cfg (cfg),
.strobe (strobe)

);

ra_cfg_sdr #(.INIT(-1)) cfig (

.clk (clk),
.reset (reset),
.cfg_wr (cfg_wr),
.cfg_dat (cfg_dat),
.cfg (cfg)

);

ra_bist_sdr bist (

.clk (clk),
.reset (reset),
.ctl (bist_ctl),
.status (bist_status),
.rd0_enb_in (rd_enb_0),
.rd0_adr_in (rd_adr_0),
.rd0_dat (rd_dat_0),
.rd1_enb_in (rd_enb_1),
.rd1_adr_in (rd_adr_1),
.rd1_dat (rd_dat_1),
.wr0_enb_in (wr_enb_0),
.wr0_adr_in (wr_adr_0),
.wr0_dat_in (wr_dat_0),
.rd0_enb_out (mux_rd0_enb),
.rd0_adr_out (mux_rd0_adr),
.rd1_enb_out (mux_rd1_enb),
.rd1_adr_out (mux_rd1_adr),
.wr0_enb_out (mux_wr0_enb),
.wr0_adr_out (mux_wr0_adr),
.wr0_dat_out (mux_wr0_dat)

);

ra_2r1w_64x72_sdr ra (

.clk (clk),
.reset (reset),
.strobe (strobe),
.rd_enb_0 (mux_rd0_enb),
.rd_adr_0 (mux_rd0_adr),
.rd_dat_0 (rd_dat_0),
.rd_enb_1 (mux_rd1_enb),
.rd_adr_1 (mux_rd1_adr),
.rd_dat_1 (rd_dat_1),
.wr_enb_0 (mux_wr0_enb),
.wr_adr_0 (mux_wr0_adr),
.wr_dat_0 (mux_wr0_dat)

);



endmodule

@ -0,0 +1,8 @@
// Global Parameters for ToySRAM Testsite

`define GENMODE 0 // 0=NoDelay, 1=Delay

// RA LCB
`define LCBSDR_CONFIGWIDTH 16
`define LCBDDR_CONFIGWIDTH 32

@ -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,130 @@
# // Questa Sim-64
# // Version 2020.3_1 linux_x86_64 Aug 25 2020
# //
# // Copyright 1991-2020 Mentor Graphics Corporation
# // All Rights Reserved.
# //
# // QuestaSim and its associated documentation contain trade
# // secrets and commercial or financial information that are the property of
# // Mentor Graphics Corporation and are privileged, confidential,
# // and exempt from disclosure under the Freedom of Information Act,
# // 5 U.S.C. Section 552. Furthermore, this information
# // is prohibited from disclosure under the Trade Secrets Act,
# // 18 U.S.C. Section 1905.
# //
pwd
# /home/ptikals/IBM/osu-toy-sram/src
do top.do
# Cannot open macro file: top.do
cd ../sim
do top.do
# QuestaSim-64 vlog 2020.3_1 Compiler 2020.08 Aug 25 2020
# Start time: 11:20:19 on Dec 14,2021
# vlog -reportprogress 300 -lint ../src/address_clock_sdr_2r1w_64.v ../src/ra_bist_ddr.v ../src/predecode_sdr_64.v ../src/ra_bist_sdr.v ../src/ra_2r1w_64x72_sdr.v ../src/ra_cfg_ddr.v ../src/regfile_2r1w_64x24.v ../src/toysram.vh ../src/ra_4r2w_64x72_ddr_1x.v ../src/ra_cfg_sdr.v ../src/regfile_4r2w_64x24.v ../src/ra_4r2w_64x72_ddr.v ../src/ra_delay.v ../src/ra_lcb_sdr.v ../src/ra_lcb_ddr.v ../src/test_ra_ddr.v ../src/test_ra_sdr.sv ../src/test_ra_ddr_1x.v
# -- Compiling module address_clock_sdr_2r1w_64
# -- Compiling module ra_bist_ddr
# -- Compiling module predecode_sdr_64
# -- Compiling module ra_bist_sdr
# -- Compiling module ra_2r1w_64x72_sdr
# -- Compiling module ra_cfg_ddr
# -- Compiling module regfile_2r1w_64x24
# -- Compiling module ra_4r2w_64x72_ddr_1x
# -- Compiling module ra_cfg_sdr
# -- Compiling module regfile_4r2w_64x24
# -- Compiling module ra_4r2w_64x72_ddr
# -- Compiling module ra_delay
# -- Compiling module ra_lcb_sdr
# ** Warning: ../src/ra_lcb_sdr.v(61): (vlog-2623) Undefined variable: i.
# -- Compiling module ra_lcb_ddr
# -- Compiling module test_ra_ddr
# -- Compiling module test_ra_sdr
# ** Warning: ../src/test_ra_sdr.sv(28): (vlog-2605) empty port name in port list.
# -- Compiling module test_ra_ddr_1x
#
# Top level modules:
# ra_bist_sdr
# test_ra_ddr
# test_ra_sdr
# test_ra_ddr_1x
# End time: 11:20:19 on Dec 14,2021, Elapsed time: 0:00:00
# Errors: 0, Warnings: 2
# vsim -debugdb -voptargs="+acc" work.test_ra_sdr
# Start time: 11:20:19 on Dec 14,2021
# ** Note: (vsim-3812) Design is being optimized...
# ** Note: (vsim-8611) Generating debug db.
# ** Error: ../src/test_ra_sdr.sv(85): Module 'ra_bist_sdr_osu' is not defined.
# Optimization failed
# ** Note: (vsim-12126) Error and warning message counts have been restored: Errors=1, Warnings=0.
# Error loading design
# Error: Error loading design
# Pausing macro execution
# MACRO ./top.do PAUSED at line 33
do top.do
# QuestaSim-64 vlog 2020.3_1 Compiler 2020.08 Aug 25 2020
# Start time: 11:29:26 on Dec 14,2021
# vlog -reportprogress 300 -lint ../src/address_clock_sdr_2r1w_64.v ../src/ra_bist_ddr.v ../src/predecode_sdr_64.v ../src/ra_bist_sdr_osu.v ../src/ra_2r1w_64x72_sdr.v ../src/ra_cfg_ddr.v ../src/regfile_2r1w_64x24.v ../src/toysram.vh ../src/ra_4r2w_64x72_ddr_1x.v ../src/ra_cfg_sdr.v ../src/regfile_4r2w_64x24.v ../src/ra_4r2w_64x72_ddr.v ../src/ra_delay.v ../src/ra_lcb_sdr.v ../src/ra_lcb_ddr.v ../src/test_ra_ddr.v ../src/test_ra_sdr.sv ../src/test_ra_ddr_1x.v
# -- Compiling module address_clock_sdr_2r1w_64
# -- Compiling module ra_bist_ddr
# -- Compiling module predecode_sdr_64
# -- Compiling module ra_bist_sdr
# ** Error: ../src/ra_bist_sdr_osu.v(88): (vlog-2730) Undefined variable: 'int'.
# ** Error: (vlog-13069) ../src/ra_bist_sdr_osu.v(88): near "i": syntax error, unexpected IDENTIFIER, expecting '='.
# ** Error: (vlog-13036) ../src/ra_bist_sdr_osu.v(88): near "++": Operator only allowed in SystemVerilog.
# ** Error: ../src/ra_bist_sdr_osu.v(88): (vlog-13205) Syntax error found in the scope following 'i'. Is there a missing '::'?
# -- Compiling module ra_2r1w_64x72_sdr
# -- Compiling module ra_cfg_ddr
# -- Compiling module regfile_2r1w_64x24
# -- Compiling module ra_4r2w_64x72_ddr_1x
# -- Compiling module ra_cfg_sdr
# -- Compiling module regfile_4r2w_64x24
# -- Compiling module ra_4r2w_64x72_ddr
# -- Compiling module ra_delay
# -- Compiling module ra_lcb_sdr
# ** Warning: ../src/ra_lcb_sdr.v(61): (vlog-2623) Undefined variable: i.
# -- Compiling module ra_lcb_ddr
# -- Compiling module test_ra_ddr
# -- Compiling module test_ra_sdr
# ** Warning: ../src/test_ra_sdr.sv(28): (vlog-2605) empty port name in port list.
# -- Compiling module test_ra_ddr_1x
# End time: 11:29:26 on Dec 14,2021, Elapsed time: 0:00:00
# Errors: 4, Warnings: 2
# ** Error: /opt/Mentor/questasim/linux_x86_64/vlog failed.
# Error in macro ./top.do line 30
# /opt/Mentor/questasim/linux_x86_64/vlog failed.
# while executing
# "vlog -lint ../src/address_clock_sdr_2r1w_64.v ../src/ra_bist_ddr.v ../src/predecode_sdr_64.v ../src/ra_bist_sdr_osu.v ../src/ra_2r1w_64x72_sdr.v ../sr..."
do top.do
# QuestaSim-64 vlog 2020.3_1 Compiler 2020.08 Aug 25 2020
# Start time: 11:49:53 on Dec 14,2021
# vlog -reportprogress 300 -lint ../src/address_clock_sdr_2r1w_64.v ../src/ra_bist_ddr.v ../src/predecode_sdr_64.v ../src/ra_bist_sdr_osu.v ../src/ra_2r1w_64x72_sdr.v ../src/ra_cfg_ddr.v ../src/regfile_2r1w_64x24.v ../src/toysram.vh ../src/ra_4r2w_64x72_ddr_1x.v ../src/ra_cfg_sdr.v ../src/regfile_4r2w_64x24.v ../src/ra_4r2w_64x72_ddr.v ../src/ra_delay.v ../src/ra_lcb_sdr.v ../src/ra_lcb_ddr.v ../src/test_ra_ddr.v ../src/test_ra_sdr.sv ../src/test_ra_ddr_1x.v
# -- Compiling module address_clock_sdr_2r1w_64
# -- Compiling module ra_bist_ddr
# -- Compiling module predecode_sdr_64
# -- Compiling module ra_bist_sdr
# ** Error: ../src/ra_bist_sdr_osu.v(88): (vlog-2730) Undefined variable: 'int'.
# ** Error: (vlog-13069) ../src/ra_bist_sdr_osu.v(88): near "i": syntax error, unexpected IDENTIFIER, expecting '='.
# ** Error: ../src/ra_bist_sdr_osu.v(88): (vlog-13205) Syntax error found in the scope following 'i'. Is there a missing '::'?
# -- Compiling module ra_2r1w_64x72_sdr
# -- Compiling module ra_cfg_ddr
# -- Compiling module regfile_2r1w_64x24
# -- Compiling module ra_4r2w_64x72_ddr_1x
# -- Compiling module ra_cfg_sdr
# -- Compiling module regfile_4r2w_64x24
# -- Compiling module ra_4r2w_64x72_ddr
# -- Compiling module ra_delay
# -- Compiling module ra_lcb_sdr
# ** Warning: ../src/ra_lcb_sdr.v(61): (vlog-2623) Undefined variable: i.
# -- Compiling module ra_lcb_ddr
# -- Compiling module test_ra_ddr
# -- Compiling module test_ra_sdr
# ** Warning: ../src/test_ra_sdr.sv(28): (vlog-2605) empty port name in port list.
# -- Compiling module test_ra_ddr_1x
# End time: 11:49:53 on Dec 14,2021, Elapsed time: 0:00:00
# Errors: 3, Warnings: 2
# ** Error: /opt/Mentor/questasim/linux_x86_64/vlog failed.
# Error in macro ./top.do line 30
# /opt/Mentor/questasim/linux_x86_64/vlog failed.
# while executing
# "vlog -lint ../src/address_clock_sdr_2r1w_64.v ../src/ra_bist_ddr.v ../src/predecode_sdr_64.v ../src/ra_bist_sdr_osu.v ../src/ra_2r1w_64x72_sdr.v ../sr..."
# End time: 12:39:15 on Dec 14,2021, Elapsed time: 1:18:56
# Errors: 3, Warnings: 0

@ -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
Loading…
Cancel
Save