issues 13,14: single clk, no more nclk

pull/18/head
openpowerwtf 1 year ago
parent 24d56dc84b
commit af556071b0

@ -32,7 +32,8 @@

module a2owb (

input [0:`NCLK_WIDTH-1] nclk,
input clk,
input rst,
input scan_in,
output scan_out,

@ -183,7 +184,8 @@ wire [0:`THREADS-1] an_ac_sync_ack;
wire [0:`THREADS-1] an_ac_reservation_vld;

c c0(
.nclk(nclk),
.clk(clk),
.rst(rst),
.scan_in(scan_in),
.scan_out(scan_out),

@ -308,7 +310,7 @@ c c0(
);

a2l2wb n0(
.clk(clk_1x),
.clk(clk),
.rst(rst),

// request
@ -437,11 +439,4 @@ a2l2wb n0(

);

wire clk_1x, clk_2x, clk_4x, rst;

assign clk_1x = nclk[0];
assign clk_2x = nclk[2];
assign clk_4x = nclk[3];
assign rst = nclk[1];

endmodule

@ -34,7 +34,8 @@

module a2owb (

input [0:`NCLK_WIDTH-1] nclk,
input clk,
input rst,
input scan_in,
output scan_out,

@ -251,7 +252,8 @@ assign an_ac_lbist_ary_wrt_thru_dc = 0;


c c0(
.nclk(nclk),
.clk(clk),
.rst(rst),
.scan_in(scan_in),
.scan_out(scan_out),

@ -376,7 +378,7 @@ c c0(
);

a2l2wb n0(
.clk(clk_1x),
.clk(clk),
.rst(rst),

// request
@ -505,11 +507,4 @@ a2l2wb n0(

);

wire clk_1x, clk_2x, clk_4x, rst;

assign clk_1x = nclk[0];
assign clk_2x = nclk[2];
assign clk_4x = nclk[3];
assign rst = nclk[1];

endmodule

@ -1,427 +0,0 @@
#!/usr/bin/python3
#
# Parse table comments and create equations.

from optparse import OptionParser
import re
from shutil import copyfile

#--------------------------------------------------------------------------------------------------
# Initialize

TYPE_INPUT = 0
TYPE_OUTPUT = 1
TYPE_SKIP = 99

lines = []
tableMatches = []
tableNames = []
tableLines = []
tables = {}

failOnError = True
inFile = 'test.vhdl'
outFileExt = 'vtable'
overwrite = True
backupExt = 'orig'
backup = True
noisy = False
quiet = False
verilog = False

#--------------------------------------------------------------------------------------------------
# Handle command line

usage = 'vtable [options] inFile'

parser = OptionParser(usage)
parser.add_option('-f', '--outfile', dest='outFile', help='output file, default=[inFile]' + outFileExt)
parser.add_option('-o', '--overwrite', dest='overwrite', help='overwrite inFile, default=' + str(overwrite))
parser.add_option('-b', '--backup', dest='backup', help='backup original file, default=' + str(backup))
parser.add_option('-q', '--quiet', dest='quiet', action='store_true', help='quiet messages, default=' + str(quiet))
parser.add_option('-n', '--noisy', dest='noisy', action='store_true', help='noisy messages, default=' + str(noisy))
parser.add_option('-V', '--verilog', dest='verilog', action='store_true', help='source is verilog, default=' + str(verilog))

options, args = parser.parse_args()

if len(args) != 1:
parser.error(usage)
quit(-1)
else:
inFile = args[0]

if options.overwrite == '0':
overwrite = False
elif options.overwrite == '1':
overwrite == True
if options.outFile is not None:
parser.error('Can\'t specify outfile and overrite!')
quit(-1)
elif options.overwrite is not None:
parser.error('overwrite: 0|1')
quit(-1)

if options.quiet is not None:
quiet = True

if options.noisy is not None:
noisy = True

if options.verilog is not None:
verilog = True

if options.backup == '0':
backup = False
elif options.backup == '1':
backup == True
elif options.backup is not None:
parser.error('backup: 0|1')
quit(-1)

if options.outFile is not None:
outFile = options.outFile
elif overwrite:
outFile = inFile
else:
outFile = inFile + '.' + outFileExt

backupFile = inFile + '.' + backupExt

#--------------------------------------------------------------------------------------------------
# Objects

class Signal:

def __init__(self, name, type):
self.name = name;
self.type = type;

class Table:

def __init__(self, name):
self.name = name
self.source = []
self.signals = {}
self.signalsByCol = {}
self.typesByCol = {}
self.specs = [] # list of specsByCol
self.equations = []
self.added = False

def validate(self):
# check that all signals have a good type
for col in self.signalsByCol:
if col not in self.typesByCol:
error('Table ' + self.name + ': no signal type for ' + self.signalsByCol[col])
elif self.typesByCol[col] == None:
error('Table ' + self.name + ': bad signal type (' + str(self.typesByCol[col]) + ') for ' + str(self.signalsByCol[col]))

def makeRTL(self, form=None):
outputsByCol = {}


#for col,type in self.typesByCol.items():
for col in sorted(self.typesByCol):
type = self.typesByCol[col]
if type == TYPE_OUTPUT:
if col in self.signalsByCol:
outputsByCol[col] = self.signalsByCol[col]
else:
print(self.signalsByCol)
print(self.typesByCol)
error('Table ' + self.name + ': output is specified in col ' + str(col) + ' but no signal exists')

#for sigCol,sig in outputsByCol.items():
for sigCol in sorted(outputsByCol):
sig = outputsByCol[sigCol]
if not verilog:
line = sig + ' <= '
else:
line = 'assign ' + sig + ' = '
nonzero = False
for specsByCol in self.specs:
terms = []
if sigCol not in specsByCol:
#error('* Output ' + sig + ' has no specified value for column ' + str(col))
1 # no error, can be dontcare
elif specsByCol[sigCol] == '1':
for col,val in specsByCol.items():
if col not in self.typesByCol:
if noisy:
error('Table ' + self.name +': unexpected value in spec column ' + str(col) + ' (' + str(val) + ') - no associated signal', False) #wtf UNTIL CAN HANDLE COMMENTS AT END!!!!!!!!!!!!!!!!!!!
elif self.typesByCol[col] == TYPE_INPUT:
if val == '0':
terms.append(opNot + self.signalsByCol[col])
if nonzero and len(terms) == 1:
line = line + ') ' + opOr + '\n (';
elif len(terms) == 1:
line = line + '\n ('
nonzero = True
elif val == '1':
terms.append(self.signalsByCol[col])
if nonzero and len(terms) == 1:
line = line + ') ' + opOr + '\n (';
elif len(terms) == 1:
line = line + '\n ('
nonzero = True
else:
error('Table ' + self.name +': unexpected value in spec column ' + str(col) + ' (' + str(val) + ')')
if len(terms) > 0:
line = line + (' ' + opAnd + ' ').join(terms)
if not nonzero:
line = line + zero + ";";
else:
line = line + ');'
self.equations.append(line)

return self.equations

def printv(self):
self.makeRTL()
print('\n'.join(self.equations))

def printinfo(self):
print('Table: ' + self.name)
print
for l in self.source:
print(l)
print
print('Signals by column:')
for col in sorted(self.signalsByCol):
print('{0:>3}. {1:} ({2:}) '.format(col, self.signalsByCol[col], 'in' if self.typesByCol[col] == TYPE_INPUT else 'out'))


#--------------------------------------------------------------------------------------------------
# Functions

def error(msg, quitOverride=None):
print('*** ' + msg)
if quitOverride == False:
1
elif (quitOverride == None) or failOnError:
quit(-10)
elif quitOverride:
quit(-10)

#--------------------------------------------------------------------------------------------------
# Do something

if not verilog:
openBracket = '('
closeBracket = ')'
opAnd = 'and'
opOr = 'or'
opNot = 'not '
zero = "'0'"
tablePattern = re.compile(r'^\s*?--tbl(?:\s+([^\s]+).*$|\s*$)')
tableGenPattern = re.compile(r'^\s*?--vtable(?:\s+([^\s]+).*$)')
commentPattern = re.compile(r'^\s*?(--.*$|\s*$)')
tableLinePattern = re.compile(r'^.*?--(.*)')
namePattern = re.compile(r'([a-zA-z\d_\(\)\.\[\]]+)')
else:
openBracket = '['
closeBracket = ']'
opAnd = '&'
opOr = '|'
opNot = '~'
zero = "'b0"
tablePattern = re.compile(r'^\s*?\/\/tbl(?:\s+([^\s]+).*$|\s*$)')
tableGenPattern = re.compile(r'^\s*?\/\/vtable(?:\s+([^\s]+).*$)')
commentPattern = re.compile(r'^\s*?(\/\/.*$|\s*$)')
tableLinePattern = re.compile(r'^.*?\/\/(.*)')
namePattern = re.compile(r'([a-zA-z\d_\(\)\.\[\]]+)')

# find the lines with table spec
try:
inf = open(inFile)
for i, line in enumerate(inf):
lines.append(line.strip('\n'))
for match in re.finditer(tablePattern, line):
tableMatches.append(i)
inf.close()
except Exception as e:
error('Error opening input file ' + inFile + '\n' + str(e), True)

# validate matches; should be paired, nothing but comments and empties; table may be named
# between them

for i in range(0, len(tableMatches), 2):

if i + 1 > len(tableMatches) - 1:
error('Mismatched table tags.\nFound so far: ' + ', '.join(tableNames), True)

tLines = lines[tableMatches[i]:tableMatches[i+1]+1]
tableLines.append(tLines)
tName = re.match(tablePattern, lines[tableMatches[i]]).groups()[0]
if tName is None:
tName = 'noname_' + str(tableMatches[i] + 1)
tableNames.append(tName)

for line in tLines:
if not re.match(commentPattern, line):
error('Found noncomment, nonempty line in table ' + tName + ':\n' + line, True)

print('Found tables: ' + ', '.join(tableNames))

# build table objects

for table, tName in zip(tableLines, tableNames):
print('Parsing ' + tName + '...')
namesByCol = {}
colsByName = {}
bitsByCol = {}
typesByCol = {}
specs = []

# parse the table - do by Table.parse()
tLines = table[1:-1] # exclude --tbl
for line in tLines:
if line.strip() == '':
continue
try:
spec = re.search(tableLinePattern, line).groups()[0]
except Exception as e:
error('Problem parsing table line:\n' + line, True)
if len(spec) > 0:
if spec[0] == 'n':
for match in re.finditer(namePattern, spec[1:]):
# col 0 is first col after n
namesByCol[match.start()] = match.groups()[0]
colsByName[match.groups()[0]] = match.start()
elif spec[0] == 'b':
for i, c in enumerate(spec[1:]):
if c == ' ' or c == '|':
continue
try:
bit = int(c)
except:
error('Unexpected char in bit line at position ' + str(i) + ' (' + c + ')\n' + line)
bit = None
if i in bitsByCol and bitsByCol[i] is not None:
bitsByCol[i] = bitsByCol[i]*10+bit
else:
bitsByCol[i] = bit
elif spec[0] == 't':
for i, c in enumerate(spec[1:]):
if c.lower() == 'i':
typesByCol[i] = TYPE_INPUT
elif c.lower() == 'o':
typesByCol[i] = TYPE_OUTPUT
elif c.lower() == '*':
typesByCol[i] = TYPE_SKIP
elif c != ' ':
error('Unexpected char in type line at position ' + str(i) + ' (' + c + ')\n' + line)
typesByCol[i] = None
else:
typesByCol[i] = None
elif spec[0] == 's':
specsByCol = {}
for i, c in enumerate(spec[1:]):
if c == '0' or c == '1':
specsByCol[i] = c
specs.append(specsByCol)
else:
#print('other:')
#print(line)
1

# create table object

# add strand to name where defined; don't combine for now into vector
# consecutive strands belong to the last defined name
lastName = None
lastCol = 0
signalsByCol = {}

for col,name in namesByCol.items(): # load with unstranded names
signalsByCol[col] = name

# sort by col so consecutive columns can be easily tracked
#for col,val in bitsByCol.items(): # update with stranded names
for col in sorted(bitsByCol):
val = bitsByCol[col]

if col > lastCol + 1:
lastName = None
if val is None:
lastName = None
if col in namesByCol:
if val is None:
signalsByCol[col] = namesByCol[col]
else:
lastName = namesByCol[col]
signalsByCol[col] = lastName + openBracket + str(val) + closeBracket
elif lastName is not None:
signalsByCol[col] = lastName + openBracket + str(val) + closeBracket
else:
error('Can\'t associate bit number ' + str(val) + ' in column ' + str(col) + ' with a signal name.')
lastCol = col

t = Table(tName)
t.source = table
t.signalsByCol = signalsByCol
t.typesByCol = typesByCol
t.specs = specs

tables[tName] = t

for name in tables:
t = tables[name]
t.validate()
t.makeRTL()

print()
print('Results:')

# find the lines with generate spec and replace them with new version
outLines = []
inTable = False
for i, line in enumerate(lines):
if not inTable:
match = re.search(tableGenPattern, line)
if match is not None:
tName = match.groups(1)[0]
if tName not in tables:
if tName == 1:
tName = '<blank>'
error('Found vtable start for \'' + tName + '\' but didn\'t generate that table: line ' + str(i+1) + '\n' + line, True)
else:
outLines.append(line)
outLines += tables[tName].equations
tables[tName].added = True
inTable = True
else:
outLines.append(line)
else:
match = re.search(tableGenPattern, line)
if match is not None:
if match.groups(1)[0] != tName:
error('Found vtable end for \'' + match.groups(1)[0] + '\' but started table \'' + tName + '\': line ' + str(i+1) + '\n' + line, True)
outLines.append(line)
inTable = False
else:
1#print('stripped: ' + line)

if backup:
try:
copyfile(inFile, backupFile)
except Exception as e:
error('Error creating backup file!\n' + str(e), True)

try:
of = open(outFile, 'w')
for line in outLines:
of.write("%s\n" % line)
except Exception as e:
error('Error writing output file ' + outFile + '!\n' + str(e), True)

print('Generated ' + str(len(tables)) + ' tables: ' + ', '.join(tableNames))
notAdded = {}
for table in tables:
if not tables[table].added:
notAdded[table] = True
print('Output file: ' + outFile)
if backup:
print('Backup file: ' + backupFile)
if len(notAdded) != 0:
error('Tables generated but not added to file! ' + ', '.join(notAdded))

@ -34,7 +34,8 @@

module a2owb (

input [0:`NCLK_WIDTH-1] nclk,
input clk,
input rst,
input scan_in,
output scan_out,

@ -251,7 +252,8 @@ assign an_ac_lbist_ary_wrt_thru_dc = 0;


c c0(
.nclk(nclk),
.clk(clk),
.rst(rst),
.scan_in(scan_in),
.scan_out(scan_out),

@ -505,11 +507,4 @@ a2l2wb n0(

);

wire clk_1x, clk_2x, clk_4x, rst;

assign clk_1x = nclk[0];
assign clk_2x = nclk[2];
assign clk_4x = nclk[3];
assign rst = nclk[1];

endmodule

@ -60,8 +60,7 @@

module a2owb (

input clk_1x,
input clk_2x,
input clk,
input rst,

input [0:31] cfg_dat,
@ -83,7 +82,6 @@ module a2owb (
input [31:0] wb_datr
);

wire [0:`NCLK_WIDTH-1] nclk;
wire [0:`THREADS-1] an_ac_stcx_complete /*verilator public */;
wire [0:`THREADS-1] an_ac_stcx_pass;
wire an_ac_icbi_ack;
@ -206,8 +204,6 @@ wire an_ac_hang_pulse;
//wire ac_an_reset_3_request;
//wire ac_an_reset_wd_request;

assign nclk = {clk_1x, rst, clk_2x, 3'b00};

assign mem_dat = 0;

assign an_ac_chipid_dc = 4'h0;
@ -251,7 +247,8 @@ assign an_ac_uncond_dbg_event = 0;


c c0(
.nclk(nclk),
.clk(clk),
.rst(rst),
.scan_in(scan_in),
.scan_out(),

@ -379,7 +376,7 @@ c c0(
);

a2l2wb n0(
.clk(clk_1x),
.clk(clk),
.rst(rst),

.cfg_wr(cfg_wr),

@ -49,6 +49,9 @@
`define EXPAND_TLB_TYPE 2 // 0 = erat-only, 1 = tlb logic, 2 = tlb array
//`define EXPAND_TLB_TYPE 0 // doesn't work in sim

// 0: none 1: DP
//`define FLOAT_TYPE 0 // fails with completion x's in sim
`define FLOAT_TYPE 1

/*wtf these are a mess; need to be doc'd and create dependency reqts and legal ranges;
shrinking values causes lots of bit sel vector problems, and sim fails

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,10 +1,8 @@
# RTL


## fpga/sim arrays

* created sim-only (not fpga?) clk1x versions in trilib_clk1x to eliminate any possible problems with iverilog
and verilator dealing with multiple clocks
* arrays that had 2x/4x clks

```
trilib/tri_144x78_2r4w.v
@ -19,6 +17,18 @@ trilib/tri_512x16_1r1w_1.v
trilib/tri_128x16_1r1w_1.v
```

* also got rid of reset_q usages (clk and reset in same nclk vector)
***i doubt reset is needed in any of the array components***

```
trilib/tri_128x16_1r1w_1.v: reg reset_q;
trilib/tri_512x16_1r1w_1.v: reg reset_q;
trilib/tri_64x72_1r1w.v: reg reset_q;
trilib/tri_cam_16x143_1r1w1c.v: reg sreset_q;
trilib/tri_cam_32x143_1r1w1c.v: reg sreset_q;
trilib/tri_iuq_cpl_arr.v: reg reset_q;
```

### arrays using clk4x

* 4W was done with clk4x
@ -27,7 +37,6 @@ trilib/tri_128x16_1r1w_1.v
```
grep "nclk\[3\]" trilib/*
trilib/tri_144x78_2r4w.v: .WCLK(nclk[3]), // Port A write clock input : clk4x
trilib/tri_144x78_2r4w.v: .WCLK(nclk[3]), // Port A write clock input : clk4x
```

### arrays using clk2x

@ -1,4 +1,4 @@
// © IBM Corp. 2022
// © IBM Corp. 2020
// 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.
@ -33,6 +33,10 @@

// Use this line for 1 thread. Comment out for 2 thread design.
//`define THREADS1
`define RESET_VECTOR 32'h00000000

// 0: none 1: DP
`define FLOAT_TYPE 1

`define gpr_t 3'b000
`define cr_t 3'b001
@ -111,7 +115,7 @@
`define IBUFF_INSTR_WIDTH 70
`define IBUFF_IFAR_WIDTH 20
`define IBUFF_DEPTH 16
`define PF_IAR_BITS 12 // number of IAR bits used by prefetch
`define PF_IAR_BITS 12 // number of IAR bits used by prefetch
`define FXU0_PIPE_START 1
`define FXU0_PIPE_END 8
`define FXU1_PIPE_START 1
@ -121,7 +125,7 @@
`define LQ_REL_PIPE_START 2
`define LQ_REL_PIPE_END 4
`define LOAD_CREDITS 8
`define STORE_CREDITS 4
`define STORE_CREDITS 4 //wtf 32 is normal; fpga bug needed 4
`define IUQ_ENTRIES 4 // Instruction Fetch Queue Size
`define MMQ_ENTRIES 2 // MMU Queue Size
`define CR_WIDTH 4
@ -133,16 +137,32 @@
`define INCLUDE_IERAT_BYPASS 1 // 0 => Removes IERAT Bypass logic, 1=> includes (power savings)
`define XER_WIDTH 10

`define INIT_BHT 0 // 0=> array init time set to 16 clocks, 1=> increased to 512 to init BHT
`define INIT_IUCR0 16'h00FA // BP enabled
//wtf: change for verilatorsim - didnt help
//`define INIT_BHT 1 // 0=> array init time set to 16 clocks, 1=> increased to 512 to init BHT
`define INIT_BHT 0 // 0=> array init time set to 16 clocks, 1=> increased to 512 to init BHT

//`define INIT_IUCR0 16'h0000 // BP disabled
`define INIT_IUCR0 16'h00FA // BP enabled
`define INIT_XUCR0 32'h00000460 // normal

`define INIT_MASK 2'b10
`define RELQ_INCLUDE 0 // Reload Queue Included

`define G_BRANCH_LEN `EFF_IFAR_WIDTH + 1 + 1 + `EFF_IFAR_WIDTH + 3 + 18 + 1

//wtf: add completion stuff
/*
assign spr_cpcr0_fx0_cnt = cpcr0_l2[35:39];
assign spr_cpcr0_fx1_cnt = cpcr0_l2[43:47];
assign spr_cpcr0_lq_cnt = cpcr0_l2[51:55];
assign spr_cpcr0_sq_cnt = cpcr0_l2[59:63];
*/
`define INIT_CPCR0 32'h0C0C100C // 000a aaaa 000b bbbb 000c cccc 000d dddd watermarks: a=fx0 b=fx1 c=ls d=sq ---- um p.543 wrong!; was this in vlog: hex 0C0C100C = 202117132
//`define INIT_CPCR0 32'h01010201 // 1/1/2/1

/*
assign spr_cpcr1_fu0_cnt = cpcr1_l2[43:47];
assign spr_cpcr1_fu1_cnt = cpcr1_l2[51:55];
*/
`define INIT_CPCR1 32'h000C0C00 // 0000 0000 000a aaaa 000b bbbb 0000 0000 credits: a=fx0 b=fx1 c=ls d=sq ---- um p.544 wrong!; was this in vlog: hex 000C0C00 = 789504
//`define INIT_CPCR1 32'h00010100 // 1/1

@ -36,11 +36,12 @@

`include "tri_a2o.vh"

module tri_128x168_1w_0(
module tri_128x168_1w_0 (
gnd,
vdd,
vcs,
nclk,
clk,
rst,
act,
ccflush_dc,
scan_dis_dc_b,
@ -102,7 +103,8 @@ module tri_128x168_1w_0(
inout vcs;

// CLOCK and CLOCKCONTROL ports
input [0:`NCLK_WIDTH-1] nclk;
input clk;
input rst;
input act;
input ccflush_dc;
input scan_dis_dc_b;
@ -227,7 +229,7 @@ module tri_128x168_1w_0(
.DOPB(unused_dob[x * ramb_base_width + 32:x * ramb_base_width + 35]),
.ADDRA(ramb_addr),
.ADDRB(ramb_addr),
.CLKA(nclk[0]),
.CLKA(clk),
.CLKB(tidn),
.DIA(ramb_data_in[x * ramb_base_width:x * ramb_base_width + 31]),
.DIB(ramb_data_in[x * ramb_base_width:x * ramb_base_width + 31]),
@ -235,7 +237,7 @@ module tri_128x168_1w_0(
.DIPB(ramb_data_in[x * ramb_base_width + 32:x * ramb_base_width + 35]),
.ENA(act),
.ENB(tidn),
.SSRA(nclk[1]),
.SSRA(rst),
.SSRB(tidn),
.WEA(write[w]),
.WEB(tidn)
@ -252,5 +254,5 @@ module tri_128x168_1w_0(
assign bo_pc_failout = 1'b0;
assign bo_pc_diagloop = 1'b0;

assign unused = |({ramb_data_out[0][port_bitwidth:ramb_base_width * ramb_width_mult - 1], ccflush_dc, scan_dis_dc_b, scan_diag_dc, lcb_d_mode_dc, lcb_clkoff_dc_b, lcb_act_dis_dc, lcb_mpw1_dc_b, lcb_mpw2_dc_b, lcb_delay_lclkr_dc, lcb_sg_1, lcb_time_sg_0, lcb_repr_sg_0, lcb_abst_sl_thold_0, lcb_repr_sl_thold_0, lcb_time_sl_thold_0, lcb_ary_nsl_thold_0, lcb_bolt_sl_thold_0, tc_lbist_ary_wrt_thru_dc, abist_en_1, din_abist, abist_cmp_en, abist_raw_b_dc, data_cmp_abist, addr_abist, r_wb_abist, pc_bo_enable_2, pc_bo_reset, pc_bo_unload, pc_bo_repair, pc_bo_shdata, pc_bo_select, tri_lcb_mpw1_dc_b, tri_lcb_mpw2_dc_b, tri_lcb_delay_lclkr_dc, tri_lcb_clkoff_dc_b, tri_lcb_act_dis_dc, gnd, vdd, vcs, nclk, unused_dob});
assign unused = |({ramb_data_out[0][port_bitwidth:ramb_base_width * ramb_width_mult - 1], ccflush_dc, scan_dis_dc_b, scan_diag_dc, lcb_d_mode_dc, lcb_clkoff_dc_b, lcb_act_dis_dc, lcb_mpw1_dc_b, lcb_mpw2_dc_b, lcb_delay_lclkr_dc, lcb_sg_1, lcb_time_sg_0, lcb_repr_sg_0, lcb_abst_sl_thold_0, lcb_repr_sl_thold_0, lcb_time_sl_thold_0, lcb_ary_nsl_thold_0, lcb_bolt_sl_thold_0, tc_lbist_ary_wrt_thru_dc, abist_en_1, din_abist, abist_cmp_en, abist_raw_b_dc, data_cmp_abist, addr_abist, r_wb_abist, pc_bo_enable_2, pc_bo_reset, pc_bo_unload, pc_bo_repair, pc_bo_shdata, pc_bo_select, tri_lcb_mpw1_dc_b, tri_lcb_mpw2_dc_b, tri_lcb_delay_lclkr_dc, tri_lcb_clkoff_dc_b, tri_lcb_act_dis_dc, gnd, vdd, vcs, unused_dob});
endmodule

@ -1,4 +1,4 @@
// © IBM Corp. 2020
// © 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.
@ -33,13 +33,16 @@
//
//*****************************************************************************

// sim version, clk1x

`include "tri_a2o.vh"

module tri_128x16_1r1w_1(
module tri_128x16_1r1w_1 (
vdd,
vcs,
gnd,
nclk,
clk,
rst,
rd_act,
wr_act,
lcb_d_mode_dc,
@ -106,7 +109,8 @@ module tri_128x16_1r1w_1(
inout vcs;
inout gnd;

input [0:`NCLK_WIDTH-1] nclk;
input clk;
input rst;

input rd_act;
input wr_act;
@ -179,67 +183,38 @@ module tri_128x16_1r1w_1(
//for all:ramb16_s36_s36 use entity unisim.RAMB16_S36_S36;

wire clk;
wire clk2x;
wire [0:8] b0addra;
wire [0:8] b0addrb;
wire wea;
wire web;
wire wren_a;
// Latches
reg reset_q;
reg gate_fq;
wire gate_d;
wire [0:35] r_data_out_1_d;
reg [0:35] r_data_out_1_fq;
wire [0:35] w_data_in_0;
wire [0:15] w_data_in_0;
wire [0:15] r_data_out_0_bram;

wire [0:35] r_data_out_0_bram;
wire [0:35] r_data_out_1_bram;
// Latches
reg [0:15] r_data_out_1_q;

wire toggle_d;
reg toggle_q;
wire toggle2x_d;
reg toggle2x_q;

(* analysis_not_referenced="true" *)
wire unused;

assign clk = nclk[0];
assign clk2x = nclk[2];

// sim array
reg [0:15] mem[0:127];

always @(posedge clk)
begin: rlatch
reset_q <= nclk[1];
end

//
// NEW clk2x gate logic start
//

always @(posedge nclk[0])
begin: tlatch
if (reset_q == 1'b1)
toggle_q <= 1'b1;
else
toggle_q <= toggle_d;
end
integer i;
initial begin
for (i = 0; i < 128; i = i + 1)
mem[i] = 0;
end


always @(posedge nclk[2])
begin: flatch
toggle2x_q <= toggle2x_d;
gate_fq <= gate_d;
r_data_out_1_fq <= r_data_out_1_d;
end

assign toggle_d = (~toggle_q);
assign toggle2x_d = toggle_q;

// should force gate_fq to be on during odd 2x clock (second half of 1x clock).
//gate_d <= toggle_q xor toggle2x_q;
// if you want the first half do the following
assign gate_d = (~(toggle_q ^ toggle2x_q));
//wtf:icarus $dumpvars cannot dump a vpiMemory
generate
genvar j;
for (j = 0; j < 128; j=j+1) begin: loc
wire [0:15] dat;
assign dat = mem[j][0:15];
end
endgenerate

assign b0addra[2:8] = wr_adr;
assign b0addrb[2:8] = rd_adr;
@ -249,72 +224,37 @@ module tri_128x16_1r1w_1(
assign b0addrb[0:1] = 2'b00;

// port a is a read-modify-write port
assign wren_a = ((bw != 16'b0000000000000000 & wr_act == 1'b1)) ? 1'b1 :
1'b0;
assign wea = wren_a & (~(gate_fq)); // write in 2nd half of nclk
assign wren_a = (bw != 0) & wr_act;
assign wea = wren_a;
assign web = 1'b0;
assign w_data_in_0[0] = (bw[0] == 1'b1) ? di[0] :
r_data_out_0_bram[0];
assign w_data_in_0[1] = (bw[1] == 1'b1) ? di[1] :
r_data_out_0_bram[1];
assign w_data_in_0[2] = (bw[2] == 1'b1) ? di[2] :
r_data_out_0_bram[2];
assign w_data_in_0[3] = (bw[3] == 1'b1) ? di[3] :
r_data_out_0_bram[3];
assign w_data_in_0[4] = (bw[4] == 1'b1) ? di[4] :
r_data_out_0_bram[4];
assign w_data_in_0[5] = (bw[5] == 1'b1) ? di[5] :
r_data_out_0_bram[5];
assign w_data_in_0[6] = (bw[6] == 1'b1) ? di[6] :
r_data_out_0_bram[6];
assign w_data_in_0[7] = (bw[7] == 1'b1) ? di[7] :
r_data_out_0_bram[7];
assign w_data_in_0[8] = (bw[8] == 1'b1) ? di[8] :
r_data_out_0_bram[8];
assign w_data_in_0[9] = (bw[9] == 1'b1) ? di[9] :
r_data_out_0_bram[9];
assign w_data_in_0[10] = (bw[10] == 1'b1) ? di[10] :
r_data_out_0_bram[10];
assign w_data_in_0[11] = (bw[11] == 1'b1) ? di[11] :
r_data_out_0_bram[11];
assign w_data_in_0[12] = (bw[12] == 1'b1) ? di[12] :
r_data_out_0_bram[12];
assign w_data_in_0[13] = (bw[13] == 1'b1) ? di[13] :
r_data_out_0_bram[13];
assign w_data_in_0[14] = (bw[14] == 1'b1) ? di[14] :
r_data_out_0_bram[14];
assign w_data_in_0[15] = (bw[15] == 1'b1) ? di[15] :
r_data_out_0_bram[15];
assign w_data_in_0[16:35] = {20{1'b0}};

assign r_data_out_1_d = r_data_out_1_bram;



RAMB16_S36_S36
#(.SIM_COLLISION_CHECK("NONE")) // all, none, warning_only, generate_x_only
bram0a(
.CLKA(clk2x),
.CLKB(clk2x),
.SSRA(reset_q),
.SSRB(reset_q),
.ADDRA(b0addra),
.ADDRB(b0addrb),
.DIA(w_data_in_0[0:31]),
.DIB({32{1'b0}}),
.DOA(r_data_out_0_bram[0:31]),
.DOB(r_data_out_1_bram[0:31]),
.DOPA(r_data_out_0_bram[32:35]),
.DOPB(r_data_out_1_bram[32:35]),
.DIPA(w_data_in_0[32:35]),
.DIPB(4'b0000),
.ENA(1'b1),
.ENB(1'b1),
.WEA(wea),
.WEB(web)
);

assign dout = r_data_out_1_fq[0:15];
assign w_data_in_0[0] = bw[0] ? di[0] : r_data_out_0_bram[0];
assign w_data_in_0[1] = bw[1] ? di[1] : r_data_out_0_bram[1];
assign w_data_in_0[2] = bw[2] ? di[2] : r_data_out_0_bram[2];
assign w_data_in_0[3] = bw[3] ? di[3] : r_data_out_0_bram[3];
assign w_data_in_0[4] = bw[4] ? di[4] : r_data_out_0_bram[4];
assign w_data_in_0[5] = bw[5] ? di[5] : r_data_out_0_bram[5];
assign w_data_in_0[6] = bw[6] ? di[6] : r_data_out_0_bram[6];
assign w_data_in_0[7] = bw[7] ? di[7] : r_data_out_0_bram[7];
assign w_data_in_0[8] = bw[8] ? di[8] : r_data_out_0_bram[8];
assign w_data_in_0[9] = bw[9] ? di[9] : r_data_out_0_bram[9];
assign w_data_in_0[10] = bw[10] ? di[10] : r_data_out_0_bram[10];
assign w_data_in_0[11] = bw[11] ? di[11] : r_data_out_0_bram[11];
assign w_data_in_0[12] = bw[12] ? di[12] : r_data_out_0_bram[12];
assign w_data_in_0[13] = bw[13] ? di[13] : r_data_out_0_bram[13];
assign w_data_in_0[14] = bw[14] ? di[14] : r_data_out_0_bram[14];
assign w_data_in_0[15] = bw[15] ? di[15] : r_data_out_0_bram[15];

always @(posedge clk) begin

r_data_out_1_q <= mem[b0addrb];
if (wea) begin
mem[b0addra] <= w_data_in_0;
end

end

assign r_data_out_0_bram = mem[b0addra];
assign dout = r_data_out_1_q[0:15];

assign func_scan_out = func_scan_in;
assign time_scan_out = time_scan_in;
@ -324,12 +264,12 @@ module tri_128x16_1r1w_1(
assign bo_pc_failout = 1'b0;
assign bo_pc_diagloop = 1'b0;

assign unused = |{vdd, vcs, gnd, nclk, lcb_d_mode_dc, lcb_clkoff_dc_b, lcb_mpw1_dc_b, lcb_mpw2_dc_b,
assign unused = |{vdd, vcs, gnd, lcb_d_mode_dc, lcb_clkoff_dc_b, lcb_mpw1_dc_b, lcb_mpw2_dc_b,
lcb_delay_lclkr_dc, ccflush_dc, scan_dis_dc_b, scan_diag_dc, lcb_sg_0, lcb_sl_thold_0_b,
lcb_time_sl_thold_0, lcb_abst_sl_thold_0, lcb_ary_nsl_thold_0, lcb_repr_sl_thold_0,
abist_di, abist_bw_odd, abist_bw_even, abist_wr_adr, wr_abst_act, abist_rd0_adr, rd0_abst_act,
tc_lbist_ary_wrt_thru_dc, abist_ena_1, abist_g8t_rd0_comp_ena, abist_raw_dc_b, obs0_abist_cmp,
lcb_bolt_sl_thold_0, pc_bo_enable_2, pc_bo_reset, pc_bo_unload, pc_bo_repair, pc_bo_shdata,
pc_bo_select, tri_lcb_mpw1_dc_b, tri_lcb_mpw2_dc_b, tri_lcb_delay_lclkr_dc, tri_lcb_clkoff_dc_b,
tri_lcb_act_dis_dc, rd_act, r_data_out_0_bram[16:35], r_data_out_1_bram[16:35], r_data_out_1_fq[16:35]};
tri_lcb_act_dis_dc, rd_act};
endmodule

@ -14,17 +14,17 @@
// necessary for implementation of the Work that are available from OpenPOWER
// via the Power ISA End User License Agreement (EULA) are explicitly excluded
// hereunder, and may be obtained from OpenPOWER under the terms and conditions
// of the EULA.
// of the EULA.
//
// 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.
//
//
// Additional rights, including the ability to physically implement a softcore that
// is compliant with the required sections of the Power ISA Specification, are
// available at no cost under the terms of the OpenPOWER Power ISA EULA, which can be
// obtained (along with the Power ISA) here: https://openpowerfoundation.org.
// obtained (along with the Power ISA) here: https://openpowerfoundation.org.

`timescale 1 ns / 1 ns

@ -37,11 +37,12 @@

`include "tri_a2o.vh"

module tri_128x34_4w_1r1w(
module tri_128x34_4w_1r1w (
gnd,
vdd,
vcs,
nclk,
clk,
rst,
rd_act,
wr_act,
sg_0,
@ -110,7 +111,8 @@ module tri_128x34_4w_1r1w(
(* analysis_not_referenced="true" *)
inout vcs;
// CLOCK and CLOCKCONTROL ports
input [0:`NCLK_WIDTH-1] nclk;
input clk;
input rst;
input rd_act;
input wr_act;
input sg_0;
@ -254,16 +256,16 @@ module tri_128x34_4w_1r1w(
.DOPB(dopb),
.ADDRA(ramb_rd_addr),
.ADDRB(ramb_wr_addr),
.CLKA(nclk[0]),
.CLKB(nclk[0]),
.CLKA(clk),
.CLKB(clk),
.DIA(ramb_data_in[w][x * ramb_base_width:x * ramb_base_width + 31]),
.DIB(ramb_data_in[w][x * ramb_base_width:x * ramb_base_width + 31]),
.DIPA(ramb_data_in[w][x * ramb_base_width + 32:x * ramb_base_width + 35]),
.DIPB(ramb_data_in[w][x * ramb_base_width + 32:x * ramb_base_width + 35]),
.ENA(rd_act),
.ENB(wr_act),
.SSRA(nclk[1]),
.SSRB(nclk[1]),
.SSRA(rst),
.SSRB(rst),
.WEA(tidn),
.WEB(wr_way[w])
);
@ -278,7 +280,8 @@ module tri_128x34_4w_1r1w(
tri_rlmlatch_p #(.INIT(0), .NEEDS_SRESET(0)) rd_act_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.clk(clk),
.rst(rst),
.act(1'b1),
.thold_b(func_sl_thold_0_b),
.sg(sg_0),
@ -296,7 +299,8 @@ module tri_128x34_4w_1r1w(
tri_rlmreg_p #(.WIDTH(port_bitwidth*ways), .INIT(0), .NEEDS_SRESET(0)) data_out_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.clk(clk),
.rst(rst),
.act(rd_act_l2),
.thold_b(func_sl_thold_0_b),
.sg(sg_0),
@ -319,6 +323,6 @@ module tri_128x34_4w_1r1w(
assign bo_pc_failout = {tidn, tidn};
assign bo_pc_diagloop = {tidn, tidn};

assign unused = | ({nclk[2:`NCLK_WIDTH-1], sg_0, abst_sl_thold_0, ary_nsl_thold_0, time_sl_thold_0, repr_sl_thold_0, clkoff_dc_b, ccflush_dc, scan_dis_dc_b, scan_diag_dc, d_mode_dc, mpw1_dc_b, mpw2_dc_b, delay_lclkr_dc, wr_abst_act, rd0_abst_act, abist_di, abist_bw_odd, abist_bw_even, abist_wr_adr, abist_rd0_adr, tc_lbist_ary_wrt_thru_dc, abist_ena_1, abist_g8t_rd0_comp_ena, abist_raw_dc_b, obs0_abist_cmp, abst_scan_in, time_scan_in, repr_scan_in, func_scan_in, lcb_bolt_sl_thold_0, pc_bo_enable_2, pc_bo_reset, pc_bo_unload, pc_bo_repair, pc_bo_shdata, pc_bo_select, tri_lcb_mpw1_dc_b, tri_lcb_mpw2_dc_b, tri_lcb_delay_lclkr_dc, tri_lcb_clkoff_dc_b, tri_lcb_act_dis_dc, dob, dopb, func_sov, ramb_data_out[0][34:35], ramb_data_out[1][34:35], ramb_data_out[2][34:35], ramb_data_out[3][34:35]});
assign unused = | ({sg_0, abst_sl_thold_0, ary_nsl_thold_0, time_sl_thold_0, repr_sl_thold_0, clkoff_dc_b, ccflush_dc, scan_dis_dc_b, scan_diag_dc, d_mode_dc, mpw1_dc_b, mpw2_dc_b, delay_lclkr_dc, wr_abst_act, rd0_abst_act, abist_di, abist_bw_odd, abist_bw_even, abist_wr_adr, abist_rd0_adr, tc_lbist_ary_wrt_thru_dc, abist_ena_1, abist_g8t_rd0_comp_ena, abist_raw_dc_b, obs0_abist_cmp, abst_scan_in, time_scan_in, repr_scan_in, func_scan_in, lcb_bolt_sl_thold_0, pc_bo_enable_2, pc_bo_reset, pc_bo_unload, pc_bo_repair, pc_bo_shdata, pc_bo_select, tri_lcb_mpw1_dc_b, tri_lcb_mpw2_dc_b, tri_lcb_delay_lclkr_dc, tri_lcb_clkoff_dc_b, tri_lcb_act_dis_dc, dob, dopb, func_sov, ramb_data_out[0][34:35], ramb_data_out[1][34:35], ramb_data_out[2][34:35], ramb_data_out[3][34:35]});

endmodule

@ -1,4 +1,4 @@
// © IBM Corp. 2020
// © 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.
@ -26,22 +26,25 @@
// available at no cost under the terms of the OpenPOWER Power ISA EULA, which can be
// obtained (along with the Power ISA) here: https://openpowerfoundation.org.

`timescale 1 ps / 1 ps
`timescale 1 ns / 1 ns

//*****************************************************************************
// Description: Tri-Lam Array Wrapper
//
//*****************************************************************************

// sim version, clk1x

`include "tri_a2o.vh"

module tri_144x78_2r4w(
module tri_144x78_2r4w (
// Inputs
// Power
inout vdd,
inout gnd,
// Clock & Scan
input [0:`NCLK_WIDTH-1] nclk,
input clk,
input rst,

//-------------------------------------------------------------------
// Pervasive
@ -84,554 +87,72 @@ module tri_144x78_2r4w(
input [64-`GPR_WIDTH:77] w_data_in_4
);

// Configuration Statement for NCsim
//for all:RAM64X1D use entity unisim.RAM64X1D;

parameter tiup = 1'b1;
parameter tidn = 1'b0;
wire unused;

//-------------------------------------------------------------------
// Signals
//-------------------------------------------------------------------
//reg write_en;
//reg [0:`GPR_POOL_ENC+`THREADS_POOL_ENC-1] write_addr;
//reg [64-`GPR_WIDTH:77] write_data;
wire write_en;
wire [0:`GPR_POOL_ENC+`THREADS_POOL_ENC-1] write_addr;
wire [64-`GPR_WIDTH:77] write_data;
// sim array
reg [64-`GPR_WIDTH:77] mem[0:143];

wire [0:(`GPR_POOL*`THREADS-1)/64] write_en_arr;
wire [0:5] write_addr_arr;
wire [0:1] wr_mux_ctrl;

//-------------------------------------------------------------------
// Latch Signals
//-------------------------------------------------------------------
wire w1e_q;
wire [0:`GPR_POOL_ENC+`THREADS_POOL_ENC-1] w1a_q;
wire [64-`GPR_WIDTH:77] w1d_q;
wire w2e_q;
wire [0:`GPR_POOL_ENC+`THREADS_POOL_ENC-1] w2a_q;
wire [64-`GPR_WIDTH:77] w2d_q;
wire w3e_q;
wire [0:`GPR_POOL_ENC+`THREADS_POOL_ENC-1] w3a_q;
wire [64-`GPR_WIDTH:77] w3d_q;
wire w4e_q;
wire [0:`GPR_POOL_ENC+`THREADS_POOL_ENC-1] w4a_q;
wire [64-`GPR_WIDTH:77] w4d_q;
wire [0:`GPR_POOL_ENC+`THREADS_POOL_ENC-1] r1a_q;
wire [0:`GPR_POOL_ENC+`THREADS_POOL_ENC-1] r2a_q;
wire [0:5] read1_addr_arr;
wire [0:5] read2_addr_arr;
wire [0:(`GPR_POOL*`THREADS-1)/64] read1_en_arr;
wire [0:(`GPR_POOL*`THREADS-1)/64] read2_en_arr;
reg [64-`GPR_WIDTH:77] read1_data;
reg [64-`GPR_WIDTH:77] read2_data;
wire [64-`GPR_WIDTH:77] r1d_array[0:(`GPR_POOL*`THREADS-1)/64];
wire [64-`GPR_WIDTH:77] r2d_array[0:(`GPR_POOL*`THREADS-1)/64];
wire [64-`GPR_WIDTH:77] r1d_d;
wire [64-`GPR_WIDTH:77] r2d_d;
wire [64-`GPR_WIDTH:77] r1d_q;
wire [64-`GPR_WIDTH:77] r2d_q;
reg [0:`GPR_POOL_ENC+`THREADS_POOL_ENC-1] r1a_q;
wire [0:`GPR_POOL_ENC+`THREADS_POOL_ENC-1] r1a_d;
reg [0:`GPR_POOL_ENC+`THREADS_POOL_ENC-1] r2a_q;
wire [0:`GPR_POOL_ENC+`THREADS_POOL_ENC-1] r2a_d;

(* analysis_not_referenced="true" *)
wire unused;
wire [64-`GPR_WIDTH:77] unused_port;
wire [64-`GPR_WIDTH:77] unused_port2;
reg [64-`GPR_WIDTH:77] r1d_q;
wire [64-`GPR_WIDTH:77] r1d_d;
reg [64-`GPR_WIDTH:77] r2d_q;
wire [64-`GPR_WIDTH:77] r2d_d;

//-------------------------------------------------------------------
// Scanchain
//-------------------------------------------------------------------
parameter w1e_offset = 0;
parameter w1a_offset = w1e_offset + 1;
parameter w1d_offset = w1a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC;
parameter w2e_offset = w1d_offset + (`GPR_WIDTH+14);
parameter w2a_offset = w2e_offset + 1;
parameter w2d_offset = w2a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC;
parameter w3e_offset = w2d_offset + (`GPR_WIDTH+14);
parameter w3a_offset = w3e_offset + 1;
parameter w3d_offset = w3a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC;
parameter w4e_offset = w3d_offset + (`GPR_WIDTH+14);
parameter w4a_offset = w4e_offset + 1;
parameter w4d_offset = w4a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC;
parameter r1a_offset = w4d_offset + (`GPR_WIDTH+14);
parameter r2a_offset = r1a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC;
parameter r1d_offset = r2a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC;
parameter r2d_offset = r1d_offset + (`GPR_WIDTH+14);
parameter scan_right = r2d_offset + (`GPR_WIDTH+14);
wire [0:scan_right-1] siv;
wire [0:scan_right-1] sov;
integer i;
initial begin
for (i = 0; i < 144; i = i + 1)
mem[i] = 0;
end

//wtf:icarus $dumpvars cannot dump a vpiMemory
generate
begin

// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// Read Control
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// BYPASS

assign r1d_d = read1_data;

assign r2d_d = read2_data;

assign r_data_out_1 = r1d_q;
assign r_data_out_2 = r2d_q;

// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// Write Control
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
assign wr_mux_ctrl = {nclk[0], nclk[2]};

//wtf moved these here to try to get them to work in icarus - they seem to now
assign write_en = ((wr_mux_ctrl == 2'b00) ? w_late_en_1 :
(wr_mux_ctrl == 2'b01) ? w_late_en_2 :
(wr_mux_ctrl == 2'b10) ? w_late_en_3 :
w_late_en_4);

assign write_addr = ((wr_mux_ctrl == 2'b00) ? w_addr_in_1 :
(wr_mux_ctrl == 2'b01) ? w_addr_in_2 :
(wr_mux_ctrl == 2'b10) ? w_addr_in_3 :
w_addr_in_4);

assign write_data = ((wr_mux_ctrl == 2'b00) ? w_data_in_1 :
(wr_mux_ctrl == 2'b01) ? w_data_in_2 :
(wr_mux_ctrl == 2'b10) ? w_data_in_3 :
w_data_in_4);


//always @ ( * )
//begin
//write_addr = #10 ((wr_mux_ctrl == 2'b00) ? w_addr_in_1 :
// (wr_mux_ctrl == 2'b01) ? w_addr_in_2 :
// (wr_mux_ctrl == 2'b10) ? w_addr_in_3 :
// w_addr_in_4);

//write_en = #10 ((wr_mux_ctrl == 2'b00) ? w_late_en_1 :
// (wr_mux_ctrl == 2'b01) ? w_late_en_2 :
// (wr_mux_ctrl == 2'b10) ? w_late_en_3 :
// w_late_en_4);

// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// Depth Control
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

//write_data = #10 ((wr_mux_ctrl == 2'b00) ? w_data_in_1 :
// (wr_mux_ctrl == 2'b01) ? w_data_in_2 :
// (wr_mux_ctrl == 2'b10) ? w_data_in_3 :
// w_data_in_4);
//end

if (((`GPR_POOL*`THREADS - 1)/64) == 0)
begin : depth1
if (`GPR_POOL_ENC+`THREADS_POOL_ENC < 6)
begin
assign write_addr_arr[0:(6 - `GPR_POOL_ENC+`THREADS_POOL_ENC) - 1] = {6-`GPR_POOL_ENC+`THREADS_POOL_ENC{1'b0}};
assign read1_addr_arr[0:(6 - `GPR_POOL_ENC+`THREADS_POOL_ENC) - 1] = {6-`GPR_POOL_ENC+`THREADS_POOL_ENC{1'b0}};
assign read2_addr_arr[0:(6 - `GPR_POOL_ENC+`THREADS_POOL_ENC) - 1] = {6-`GPR_POOL_ENC+`THREADS_POOL_ENC{1'b0}};
end

assign write_addr_arr[6 - `GPR_POOL_ENC+`THREADS_POOL_ENC:5] = write_addr;
assign read1_addr_arr[6 - `GPR_POOL_ENC+`THREADS_POOL_ENC:5] = r1a_q;
assign read2_addr_arr[6 - `GPR_POOL_ENC+`THREADS_POOL_ENC:5] = r2a_q;
assign write_en_arr[0] = write_en;
assign read1_en_arr[0] = 1'b1;
assign read2_en_arr[0] = 1'b1;
end

if (((`GPR_POOL*`THREADS - 1)/64) != 0)
begin : depthMulti
assign write_addr_arr = write_addr[`GPR_POOL_ENC+`THREADS_POOL_ENC - 6:`GPR_POOL_ENC+`THREADS_POOL_ENC - 1];
assign read1_addr_arr = r1a_q[`GPR_POOL_ENC+`THREADS_POOL_ENC - 6:`GPR_POOL_ENC+`THREADS_POOL_ENC - 1];
assign read2_addr_arr = r2a_q[`GPR_POOL_ENC+`THREADS_POOL_ENC - 6:`GPR_POOL_ENC+`THREADS_POOL_ENC - 1];

genvar wen;
for (wen = 0; wen <= ((`GPR_POOL*`THREADS - 1)/64); wen = wen + 1)
begin : wrenGen
wire wen_match = wen;
assign write_en_arr[wen] = write_en & (write_addr[0:(`GPR_POOL_ENC+`THREADS_POOL_ENC - 6) - 1] == wen_match);
assign read1_en_arr[wen] = r1a_q[0:(`GPR_POOL_ENC+`THREADS_POOL_ENC - 6) - 1] == wen_match;
assign read2_en_arr[wen] = r2a_q[0:(`GPR_POOL_ENC+`THREADS_POOL_ENC - 6) - 1] == wen_match;
end
end

always @( * )
begin: rdDataMux
reg [64-`GPR_WIDTH:77] rd1_data;
reg [64-`GPR_WIDTH:77] rd2_data;
//(* analysis_not_referenced="true" *)
integer rdArr;
rd1_data = {`GPR_WIDTH+14{1'b0}};
rd2_data = {`GPR_WIDTH+14{1'b0}};

for (rdArr = 0; rdArr <= ((`GPR_POOL*`THREADS - 1)/64); rdArr = rdArr + 1)
begin
rd1_data = (r1d_array[rdArr] & {`GPR_WIDTH+14{read1_en_arr[rdArr]}}) | rd1_data;
rd2_data = (r2d_array[rdArr] & {`GPR_WIDTH+14{read2_en_arr[rdArr]}}) | rd2_data;
end
read1_data = rd1_data;
read2_data = rd2_data;
end

genvar depth;
for (depth = 0; depth <= ((`GPR_POOL*`THREADS - 1)/64); depth = depth + 1)
begin : depth_loop
genvar i;
for (i = 64 - `GPR_WIDTH; i < 78; i = i + 1)
begin : r1
RAM64X1D #(.INIT(64'h0000000000000000)) RAM64X1D_1(
.SPO(unused_port[i]),
.DPO(r1d_array[depth][i]), // Port A 1-bit data output

.A0(write_addr_arr[5]), // Port A - Write Address (A0-A5)
.A1(write_addr_arr[4]),
.A2(write_addr_arr[3]),
.A3(write_addr_arr[2]),
.A4(write_addr_arr[1]),
.A5(write_addr_arr[0]),

//.A(write_addr_arr),
.D(write_data[i]), // Port A 1-bit data input

.DPRA0(read1_addr_arr[5]), // Port B - Read Address (DPRA0-DPRA5)
.DPRA1(read1_addr_arr[4]),
.DPRA2(read1_addr_arr[3]),
.DPRA3(read1_addr_arr[2]),
.DPRA4(read1_addr_arr[1]),
.DPRA5(read1_addr_arr[0]),

//.DPRA(read1_addr_arr),
.WCLK(nclk[3]), // Port A write clock input : clk4x
.WE(write_en_arr[depth]) // Port A write enable input
);
genvar j;
for (j = 0; j < 144; j=j+1) begin: loc
wire [64-`GPR_WIDTH:63] dat;
wire [0:7] par;
// 4b0
assign dat = mem[j][64-`GPR_WIDTH:63];
assign par = mem[j][64:63 + `GPR_WIDTH/8];
end

//genvar i;
for (i = 64 - `GPR_WIDTH; i < 78; i = i + 1)
begin : r2
RAM64X1D #(.INIT(64'h0000000000000000)) RAM64X1D_2(
.SPO(unused_port2[i]),
.DPO(r2d_array[depth][i]), // Port A 1-bit data output

.A0(write_addr_arr[5]), // Port A - Write Address (A0-A5)
.A1(write_addr_arr[4]),
.A2(write_addr_arr[3]),
.A3(write_addr_arr[2]),
.A4(write_addr_arr[1]),
.A5(write_addr_arr[0]),

//.A(write_addr_arr),
.D(write_data[i]), // Port A 1-bit data input

.DPRA0(read2_addr_arr[5]), // Port B - Read Address (DPRA0-DPRA5)
.DPRA1(read2_addr_arr[4]),
.DPRA2(read2_addr_arr[3]),
.DPRA3(read2_addr_arr[2]),
.DPRA4(read2_addr_arr[1]),
.DPRA5(read2_addr_arr[0]),

//.DPRA(read2_addr_arr),
.WCLK(nclk[3]), // Port A write clock input : clk4x
.WE(write_en_arr[depth]) // Port A write enable input
);
end
end
end
endgenerate

//----------------------------------------------------------------------------------------------------------------------------------------
// Latches
//----------------------------------------------------------------------------------------------------------------------------------------

tri_rlmlatch_p #(.INIT(0), .NEEDS_SRESET(1)) w1e_latch(
.nclk(nclk),
.vd(vdd),
.gd(gnd),
.act(tiup),
.force_t(func_sl_force),
.delay_lclkr(delay_lclkr_dc),
.mpw1_b(mpw1_dc_b),
.mpw2_b(mpw2_dc_b),
.thold_b(func_sl_thold_0_b),
.d_mode(1'b0),
.sg(sg_0),
.scin(siv[w1e_offset]),
.scout(sov[w1e_offset]),
.din(w_late_en_1),
.dout(w1e_q)
);

tri_rlmreg_p #(.WIDTH(`GPR_POOL_ENC+`THREADS_POOL_ENC), .INIT(0), .NEEDS_SRESET(1)) w1a_latch(
.nclk(nclk),
.vd(vdd),
.gd(gnd),
.act(tiup),
.force_t(func_sl_force),
.delay_lclkr(delay_lclkr_dc),
.mpw1_b(mpw1_dc_b),
.mpw2_b(mpw2_dc_b),
.thold_b(func_sl_thold_0_b),
.d_mode(1'b0),
.sg(sg_0),
.scin(siv[w1a_offset:w1a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC - 1]),
.scout(sov[w1a_offset:w1a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC - 1]),
.din(w_addr_in_1),
.dout(w1a_q)
);

tri_rlmreg_p #(.WIDTH(`GPR_WIDTH+14), .INIT(0), .NEEDS_SRESET(1)) w1d_latch(
.nclk(nclk),
.vd(vdd),
.gd(gnd),
.act(tiup),
.force_t(func_sl_force),
.delay_lclkr(delay_lclkr_dc),
.mpw1_b(mpw1_dc_b),
.mpw2_b(mpw2_dc_b),
.thold_b(func_sl_thold_0_b),
.d_mode(1'b0),
.sg(sg_0),
.scin(siv[w1d_offset:w1d_offset + `GPR_WIDTH+14 - 1]),
.scout(sov[w1d_offset:w1d_offset + `GPR_WIDTH+14 - 1]),
.din(w_data_in_1[64 - `GPR_WIDTH:77]),
.dout(w1d_q)
);

tri_rlmlatch_p #(.INIT(0), .NEEDS_SRESET(1)) w2e_latch(
.nclk(nclk),
.vd(vdd),
.gd(gnd),
.act(tiup),
.force_t(func_sl_force),
.delay_lclkr(delay_lclkr_dc),
.mpw1_b(mpw1_dc_b),
.mpw2_b(mpw2_dc_b),
.thold_b(func_sl_thold_0_b),
.d_mode(1'b0),
.sg(sg_0),
.scin(siv[w2e_offset]),
.scout(sov[w2e_offset]),
.din(w_late_en_2),
.dout(w2e_q)
);
assign r1a_d = r_addr_in_1;
assign r2a_d = r_addr_in_2;

tri_rlmreg_p #(.WIDTH(`GPR_POOL_ENC+`THREADS_POOL_ENC), .INIT(0), .NEEDS_SRESET(1)) w2a_latch(
.nclk(nclk),
.vd(vdd),
.gd(gnd),
.act(tiup),
.force_t(func_sl_force),
.delay_lclkr(delay_lclkr_dc),
.mpw1_b(mpw1_dc_b),
.mpw2_b(mpw2_dc_b),
.thold_b(func_sl_thold_0_b),
.d_mode(1'b0),
.sg(sg_0),
.scin(siv[w2a_offset:w2a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC - 1]),
.scout(sov[w2a_offset:w2a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC - 1]),
.din(w_addr_in_2),
.dout(w2a_q)
);
always @(posedge clk) begin

tri_rlmreg_p #(.WIDTH(`GPR_WIDTH+14), .INIT(0), .NEEDS_SRESET(1)) w2d_latch(
.nclk(nclk),
.vd(vdd),
.gd(gnd),
.act(tiup),
.force_t(func_sl_force),
.delay_lclkr(delay_lclkr_dc),
.mpw1_b(mpw1_dc_b),
.mpw2_b(mpw2_dc_b),
.thold_b(func_sl_thold_0_b),
.d_mode(1'b0),
.sg(sg_0),
.scin(siv[w2d_offset:w2d_offset + `GPR_WIDTH+14 - 1]),
.scout(sov[w2d_offset:w2d_offset + `GPR_WIDTH+14 - 1]),
.din(w_data_in_2[64 - `GPR_WIDTH:77]),
.dout(w2d_q)
);
r1a_q <= r1a_d;
r2a_q <= r2a_d;

tri_rlmlatch_p #(.INIT(0), .NEEDS_SRESET(1)) w3e_latch(
.nclk(nclk),
.vd(vdd),
.gd(gnd),
.act(tiup),
.force_t(func_sl_force),
.delay_lclkr(delay_lclkr_dc),
.mpw1_b(mpw1_dc_b),
.mpw2_b(mpw2_dc_b),
.thold_b(func_sl_thold_0_b),
.d_mode(1'b0),
.sg(sg_0),
.scin(siv[w3e_offset]),
.scout(sov[w3e_offset]),
.din(w_late_en_3),
.dout(w3e_q)
);
r1d_q <= r1d_d;
r2d_q <= r2d_d;

tri_rlmreg_p #(.WIDTH(`GPR_POOL_ENC+`THREADS_POOL_ENC), .INIT(0), .NEEDS_SRESET(1)) w3a_latch(
.nclk(nclk),
.vd(vdd),
.gd(gnd),
.act(tiup),
.force_t(func_sl_force),
.delay_lclkr(delay_lclkr_dc),
.mpw1_b(mpw1_dc_b),
.mpw2_b(mpw2_dc_b),
.thold_b(func_sl_thold_0_b),
.d_mode(1'b0),
.sg(sg_0),
.scin(siv[w3a_offset:w3a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC - 1]),
.scout(sov[w3a_offset:w3a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC - 1]),
.din(w_addr_in_3),
.dout(w3a_q)
);
if (w_late_en_1) begin
mem[w_addr_in_1] <= w_data_in_1;
end
if (w_late_en_2) begin
mem[w_addr_in_2] <= w_data_in_2;
end
if (w_late_en_3) begin
mem[w_addr_in_3] <= w_data_in_3;
end
if (w_late_en_4) begin
mem[w_addr_in_4] <= w_data_in_4;
end

tri_rlmreg_p #(.WIDTH(`GPR_WIDTH+14), .INIT(0), .NEEDS_SRESET(1)) w3d_latch(
.nclk(nclk),
.vd(vdd),
.gd(gnd),
.act(tiup),
.force_t(func_sl_force),
.delay_lclkr(delay_lclkr_dc),
.mpw1_b(mpw1_dc_b),
.mpw2_b(mpw2_dc_b),
.thold_b(func_sl_thold_0_b),
.d_mode(1'b0),
.sg(sg_0),
.scin(siv[w3d_offset:w3d_offset + `GPR_WIDTH+14 - 1]),
.scout(sov[w3d_offset:w3d_offset + `GPR_WIDTH+14 - 1]),
.din(w_data_in_3[64 - `GPR_WIDTH:77]),
.dout(w3d_q)
);

tri_rlmlatch_p #(.INIT(0), .NEEDS_SRESET(1)) w4e_latch(
.nclk(nclk),
.vd(vdd),
.gd(gnd),
.act(tiup),
.force_t(func_sl_force),
.delay_lclkr(delay_lclkr_dc),
.mpw1_b(mpw1_dc_b),
.mpw2_b(mpw2_dc_b),
.thold_b(func_sl_thold_0_b),
.d_mode(1'b0),
.sg(sg_0),
.scin(siv[w4e_offset]),
.scout(sov[w4e_offset]),
.din(w_late_en_4),
.dout(w4e_q)
);

tri_rlmreg_p #(.WIDTH(`GPR_POOL_ENC+`THREADS_POOL_ENC), .INIT(0), .NEEDS_SRESET(1)) w4a_latch(
.nclk(nclk),
.vd(vdd),
.gd(gnd),
.act(tiup),
.force_t(func_sl_force),
.delay_lclkr(delay_lclkr_dc),
.mpw1_b(mpw1_dc_b),
.mpw2_b(mpw2_dc_b),
.thold_b(func_sl_thold_0_b),
.d_mode(1'b0),
.sg(sg_0),
.scin(siv[w4a_offset:w4a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC - 1]),
.scout(sov[w4a_offset:w4a_offset + `GPR_POOL_ENC+`THREADS_POOL_ENC - 1]),
.din(w_addr_in_4),
.dout(w4a_q)
);

tri_rlmreg_p #(.WIDTH(`GPR_WIDTH+14), .INIT(0), .NEEDS_SRESET(1)) w4d_latch(
.nclk(nclk),
.vd(vdd),
.gd(gnd),