64x72 sim

master
openpowerwtf 11 months ago
parent 3ae2375de3
commit edaeae2350

@ -18,7 +18,7 @@ SIM ?= icarus

# icarus

VERILOG_ROOT = src
VERILOG_ROOT = src/array

COMPILE_ARGS = -I$(VERILOG_ROOT) -y$(VERILOG_ROOT)

@ -26,12 +26,11 @@ COMPILE_ARGS = -I$(VERILOG_ROOT) -y$(VERILOG_ROOT)

# rtl
TOPLEVEL_LANG = verilog
# top-level to enable trace, etc.
VERILOG_SOURCES = ./test_ra_sdr_64x72.v
TOPLEVEL = test_ra_sdr_64x72
VERILOG_SOURCES = ./tb_ra_64x72_2r1w.v
TOPLEVEL = tb_ra_64x72_2r1w

# python test
MODULE = tb
MODULE = tb_ra_64x72
TESTCASE = tb

# cocotb make rules
@ -42,5 +41,5 @@ build: clean sim fst
run: sim fst

fst:
vcd2fst test_ra_sdr_64x72.vcd test_ra_sdr_64x72.fst
rm test_ra_sdr_64x72.vcd
vcd2fst tb_ra_64x72.vcd tb_ra_64x72.fst
rm tb_ra_64x72.vcd

@ -18,7 +18,6 @@ SIM ?= icarus

# icarus
#
#VERILOG_ROOT = ../src/array_behav
VERILOG_ROOT = src/array_shard
COMPILE_ARGS = -I$(VERILOG_ROOT) -y$(VERILOG_ROOT)

@ -26,8 +25,7 @@ COMPILE_ARGS = -I$(VERILOG_ROOT) -y$(VERILOG_ROOT)

# rtl
TOPLEVEL_LANG = verilog
# top-level to enable trace, etc.
VERILOG_SOURCES = ./tb_ra_64x72_2r1w.v
VERILOG_SOURCES = ./tb_ra_64x72_2r1w.v $(VERILOG_ROOT)/wordlines_comp.v $(VERILOG_ROOT)/sky130_hd.v $(VERILOG_ROOT)/sky130_fd.v
TOPLEVEL = tb_ra_64x72_2r1w

# python test

@ -1,22 +1,25 @@
[*]
[*] GTKWave Analyzer v3.4.0 (w)1999-2022 BSI
[*] Tue Nov 8 18:51:49 2022
[*] Tue Nov 8 22:24:20 2022
[*]
[dumpfile] "/data/projects/toy-sram/rtl/sim/coco/tb_ra_64x72.fst"
[dumpfile_mtime] "Tue Nov 8 18:34:46 2022"
[dumpfile_size] 12534
[dumpfile_mtime] "Tue Nov 8 22:21:18 2022"
[dumpfile_size] 99552
[savefile] "/data/projects/toy-sram/rtl/sim/coco/ra_64x72_2r1w.gtkw"
[timestart] 23310
[size] 1699 1047
[pos] 192 243
*-12.000000 28000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[timestart] 77630
[size] 1699 1029
[pos] 205 240
*-12.000000 92530 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] tb_ra_64x72_2r1w.
[treeopen] tb_ra_64x72_2r1w.ra.
[treeopen] tb_ra_64x72_2r1w.ra.ra0.
[treeopen] tb_ra_64x72_2r1w.ra.ra0.eval_0x0.
[treeopen] tb_ra_64x72_2r1w.ra.ra0.io.
[treeopen] tb_ra_64x72_2r1w.ra.ra0.io.genblk1[0].
[sst_width] 218
[signals_width] 257
[sst_expanded] 1
[sst_vpaned_height] 301
[sst_vpaned_height] 296
@28
tb_ra_64x72_2r1w.clk
tb_ra_64x72_2r1w.rd_enb_0
@ -52,31 +55,29 @@ tb_ra_64x72_2r1w.ra.wr_adr_0_q[0:5]
tb_ra_64x72_2r1w.ra.wr_dat_0_q[0:71]
@200
-RA0
-W0x
@28
tb_ra_64x72_2r1w.ra.ra0.rd0_c_a0
tb_ra_64x72_2r1w.ra.ra0.rd0_a1_a2
tb_ra_64x72_2r1w.ra.ra0.rd0_a3
tb_ra_64x72_2r1w.ra.ra0.rd0_a4_a5
@200
-R000
@22
tb_ra_64x72_2r1w.ra.ra0.w00.mem_00[0:11]
tb_ra_64x72_2r1w.ra.ra0.w00.mem_01[0:11]
tb_ra_64x72_2r1w.ra.ra0.w00.mem_02[0:11]
tb_ra_64x72_2r1w.ra.ra0.w00.mem_03[0:11]
tb_ra_64x72_2r1w.ra.ra0.w01.mem_00[0:11]
tb_ra_64x72_2r1w.ra.ra0.w01.mem_01[0:11]
tb_ra_64x72_2r1w.ra.ra0.w01.mem_02[0:11]
@23
tb_ra_64x72_2r1w.ra.ra0.w01.mem_03[0:11]
tb_ra_64x72_2r1w.ra.ra0.r000.mem_00[0:11]
tb_ra_64x72_2r1w.ra.ra0.r000.mem_01[0:11]
tb_ra_64x72_2r1w.ra.ra0.r000.RWL0[0:15]
tb_ra_64x72_2r1w.ra.ra0.r000.RWL1[0:15]
@200
-R001
@22
tb_ra_64x72_2r1w.ra.ra0.w00.RWL0[0:15]
tb_ra_64x72_2r1w.ra.ra0.w00.RWL1[0:15]
tb_ra_64x72_2r1w.ra.ra0.w00.RBL0[0:11]
tb_ra_64x72_2r1w.ra.ra0.w00.RBL1[0:11]
tb_ra_64x72_2r1w.ra.ra0.w00.WWL[0:15]
tb_ra_64x72_2r1w.ra.ra0.w01.RWL0[0:15]
tb_ra_64x72_2r1w.ra.ra0.w01.RWL1[0:15]
tb_ra_64x72_2r1w.ra.ra0.w01.RBL0[0:11]
tb_ra_64x72_2r1w.ra.ra0.w01.RBL1[0:11]
tb_ra_64x72_2r1w.ra.ra0.w01.WWL[0:15]
tb_ra_64x72_2r1w.ra.ra0.w00.mem_08[0:11]
tb_ra_64x72_2r1w.ra.ra0.w01.mem_08[0:11]
tb_ra_64x72_2r1w.ra.ra0.w00.WWL[0:15]
tb_ra_64x72_2r1w.ra.ra0.w01.WWL[0:15]
tb_ra_64x72_2r1w.ra.ra0.r001.mem_00[0:11]
tb_ra_64x72_2r1w.ra.ra0.r001.mem_01[0:11]
@200
-Eval
@22
tb_ra_64x72_2r1w.ra.ra0.eval_0x0.RBL0_L[0:11]
tb_ra_64x72_2r1w.ra.ra0.eval_0x0.RBL0_R[0:11]
@23
tb_ra_64x72_2r1w.ra.ra0.eval_0x0.RBL0_O_b[0:11]
[pattern_trace] 1
[pattern_trace] 0

@ -0,0 +1,81 @@
[*]
[*] GTKWave Analyzer v3.4.0 (w)1999-2022 BSI
[*] Tue Nov 8 22:49:44 2022
[*]
[dumpfile] "/data/projects/toy-sram/rtl/sim/coco/tb_ra_64x72.fst"
[dumpfile_mtime] "Tue Nov 8 22:25:44 2022"
[dumpfile_size] 98436
[savefile] "/data/projects/toy-sram/rtl/sim/coco/ra_shard_64x72_2r1w.gtkw"
[timestart] 75590
[size] 1699 1047
[pos] 188 268
*-12.000000 90500 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] tb_ra_64x72_2r1w.
[treeopen] tb_ra_64x72_2r1w.ra.
[treeopen] tb_ra_64x72_2r1w.ra.ra0.
[treeopen] tb_ra_64x72_2r1w.ra.ra0.r000.
[sst_width] 242
[signals_width] 257
[sst_expanded] 1
[sst_vpaned_height] 301
@28
tb_ra_64x72_2r1w.clk
tb_ra_64x72_2r1w.rd_enb_0
@22
tb_ra_64x72_2r1w.rd_adr_0[0:5]
tb_ra_64x72_2r1w.rd_dat_0[0:71]
@28
tb_ra_64x72_2r1w.rd_enb_1
@22
tb_ra_64x72_2r1w.rd_adr_1[0:5]
tb_ra_64x72_2r1w.rd_dat_1[0:71]
@28
tb_ra_64x72_2r1w.wr_enb_0
@22
tb_ra_64x72_2r1w.wr_adr_0[0:5]
tb_ra_64x72_2r1w.wr_dat_0[0:71]
@200
-RA
@28
tb_ra_64x72_2r1w.ra.rd_enb_0_q
@22
tb_ra_64x72_2r1w.ra.rd_adr_0_q[0:5]
tb_ra_64x72_2r1w.ra.rd_dat_0_q[0:71]
@28
tb_ra_64x72_2r1w.ra.rd_enb_1_q
@22
tb_ra_64x72_2r1w.ra.rd_adr_1_q[0:5]
tb_ra_64x72_2r1w.ra.rd_dat_1_q[0:71]
@28
tb_ra_64x72_2r1w.ra.wr_enb_0_q
@22
tb_ra_64x72_2r1w.ra.wr_adr_0_q[0:5]
tb_ra_64x72_2r1w.ra.wr_dat_0_q[0:71]
@200
-RA0
@28
tb_ra_64x72_2r1w.ra.ra0.rd1_c_a0
tb_ra_64x72_2r1w.ra.ra0.rd1_c_a0_i
tb_ra_64x72_2r1w.ra.ra0.rd1_c_na0_i
@22
tb_ra_64x72_2r1w.ra.ra0.rbl1_000[0:11]
@200
-R000
@22
tb_ra_64x72_2r1w.ra.ra0.r000.mem_00[0:11]
tb_ra_64x72_2r1w.ra.ra0.r000.RWL0[0:15]
tb_ra_64x72_2r1w.ra.ra0.r000.RWL1[0:15]
tb_ra_64x72_2r1w.ra.ra0.r000.RBL0[0:11]
tb_ra_64x72_2r1w.ra.ra0.r000.RBL1[0:11]
tb_ra_64x72_2r1w.ra.ra0.r000.WWL[0:15]
tb_ra_64x72_2r1w.ra.ra0.r000.WBL[0:11]
tb_ra_64x72_2r1w.ra.ra0.r000.WBLb[0:11]
@200
-Eval
@22
tb_ra_64x72_2r1w.ra.ra0.eval_0x0.RBL1_L[0:11]
tb_ra_64x72_2r1w.ra.ra0.eval_0x0.RBL1_R[0:11]
@23
tb_ra_64x72_2r1w.ra.ra0.eval_0x0.RBL1_O_b[0:11]
[pattern_trace] 1
[pattern_trace] 0

@ -10,7 +10,7 @@

```
make RANDOM_SEED=8675309 -f Makefile_64x72_shard build
gtkwave tb_ra_64x72.fst ra_64x72_2r1w.gtkw
gtkwave tb_ra_64x72.fst ra_shard_64x72_2r1w.gtkw
```

* just run

@ -1,6 +1,6 @@
<testsuites name="results">
<testsuite name="all" package="all">
<property name="random_seed" value="8675309" />
<testcase name="tb" classname="tb_ra_64x72" file="/data/projects/toy-sram/rtl/sim/coco/tb_ra_64x72.py" lineno="291" time="43.35837435722351" sim_time_ns="50089.001" ratio_time="1155.232449153278" />
<property name="random_seed" value="1667950274" />
<testcase name="tb" classname="tb_ra_64x72" file="/data/projects/toy-sram/rtl/sim/coco/tb_ra_64x72.py" lineno="291" time="57.49161696434021" sim_time_ns="50089.001" ratio_time="871.2400806376386" />
</testsuite>
</testsuites>

Binary file not shown.

File diff suppressed because it is too large Load Diff

@ -28,7 +28,7 @@
`include "defines.v"
`include "toysram.vh"

module test_site (
module tb_site (

`ifdef USE_POWER_PINS
inout vccd1, // User area 1 1.8V supply

@ -1,148 +0,0 @@
// © 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) wrapper for cocotb/icarus
// 64 word 72 bit array
// LCB for strobe generation
// Config, BIST, etc.

`timescale 1 ns / 1 ns

`include "toysram.vh"

module test_ra_sdr_64x72 (

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;


initial begin
$dumpfile ("test_ra_sdr_64x72.vcd");
$dumpvars;
#1;
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)

);

endmodule

@ -1,189 +0,0 @@
// © 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 32 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_32 (

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

// 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,
rd1_a4,

// 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,
wr0_a4

);

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

input strobe;

// address ports and associated enable signals
input rd_enb_0;
input [0:4] rd_adr_0;
input rd_enb_1;
input [0:4] rd_adr_1;
input wr_enb_0;
input [0:4] 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;
output rd0_a4;

// 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;
output rd1_a4;

// 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;
output wr0_a4;

// one predecoder per port

predecode_sdr_32 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(rd0_na4),
.a4(rd0_a4)
);

predecode_sdr_32 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(rd1_na4),
.a4(rd1_a4)
);

predecode_sdr_32 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(wr0_na4),
.a4(wr0_a4)
);

endmodule

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

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

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

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