mirror of https://github.com/openXC7/prjxray.git
103 lines
3.1 KiB
Python
103 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import json
|
|
|
|
from prjxray.segmaker import Segmaker
|
|
from prjxray import verilog
|
|
from prjxray import segmaker
|
|
|
|
|
|
def isinv_tags(segmk, ps, site):
|
|
# all of these bits are inverted
|
|
ks = [
|
|
('IS_CLKARDCLK_INVERTED', 'ZINV_CLKARDCLK'),
|
|
('IS_CLKBWRCLK_INVERTED', 'ZINV_CLKBWRCLK'),
|
|
('IS_ENARDEN_INVERTED', 'ZINV_ENARDEN'),
|
|
('IS_ENBWREN_INVERTED', 'ZINV_ENBWREN'),
|
|
('IS_RSTRAMARSTRAM_INVERTED', 'ZINV_RSTRAMARSTRAM'),
|
|
('IS_RSTRAMB_INVERTED', 'ZINV_RSTRAMB'),
|
|
('IS_RSTREGARSTREG_INVERTED', 'ZINV_RSTREGARSTREG'),
|
|
('IS_RSTREGB_INVERTED', 'ZINV_RSTREGB'),
|
|
]
|
|
for param, tagname in ks:
|
|
segmk.add_site_tag(site, tagname, 1 ^ verilog.parsei(ps[param]))
|
|
|
|
|
|
def bus_tags(segmk, ps, site):
|
|
for param in ("DOA_REG", "DOB_REG"):
|
|
segmk.add_site_tag(site, param, verilog.parsei(ps[param]))
|
|
|
|
for param, tagname in [('SRVAL_A', 'ZSRVAL_A'), ('SRVAL_B', 'ZSRVAL_B'),
|
|
('INIT_A', 'ZINIT_A'), ('INIT_B', 'ZINIT_B')]:
|
|
bitstr = verilog.parse_bitstr(ps[param])
|
|
ab = param[-1]
|
|
# Are all bits present?
|
|
hasparity = ps['READ_WIDTH_' + ab] == 18
|
|
for i in range(18):
|
|
# Magic bit positions from experimentation
|
|
# we could just only solve when parity, but this check documents the fine points a bit better
|
|
if hasparity or i not in (1, 9):
|
|
segmk.add_site_tag(site, '%s[%u]' % (param, i), 1 ^ bitstr[i])
|
|
|
|
|
|
def rw_width_tags(segmk, ps, site):
|
|
'''
|
|
Y0.READ_WIDTH_A
|
|
width 001_03 001_04 001_05
|
|
1 0 0 0
|
|
2 1 0 0
|
|
4 0 1 0
|
|
9 1 1 0
|
|
18 0 0 1
|
|
'''
|
|
for param in ["READ_WIDTH_A", "READ_WIDTH_B", "WRITE_WIDTH_A",
|
|
"WRITE_WIDTH_B"]:
|
|
set_val = int(ps[param])
|
|
|
|
def mk(x):
|
|
return '%s_%u' % (param, x)
|
|
|
|
segmaker.add_site_group_zero(
|
|
segmk, site, "",
|
|
[mk(1), mk(2), mk(4), mk(9), mk(18)], mk(1), mk(set_val))
|
|
|
|
|
|
def write_mode_tags(segmk, ps, site):
|
|
for param in ["WRITE_MODE_A", "WRITE_MODE_B"]:
|
|
set_val = verilog.unquote(ps[param])
|
|
# WRITE_FIRST: no bits set
|
|
segmk.add_site_tag(
|
|
site, '%s_READ_FIRST' % (param), set_val == "READ_FIRST")
|
|
segmk.add_site_tag(
|
|
site, '%s_NO_CHANGE' % (param), set_val == "NO_CHANGE")
|
|
|
|
|
|
def run():
|
|
|
|
segmk = Segmaker("design.bits")
|
|
#segmk.set_def_bt('BLOCK_RAM')
|
|
|
|
print("Loading tags")
|
|
f = open('params.jl', 'r')
|
|
f.readline()
|
|
for l in f:
|
|
j = json.loads(l)
|
|
ps = j['params']
|
|
assert j['module'] == 'my_RAMB18E1'
|
|
site = verilog.unquote(ps['LOC'])
|
|
|
|
isinv_tags(segmk, ps, site)
|
|
bus_tags(segmk, ps, site)
|
|
rw_width_tags(segmk, ps, site)
|
|
write_mode_tags(segmk, ps, site)
|
|
|
|
def bitfilter(frame, bit):
|
|
# rw_width_tags() aliasing interconnect on large widths
|
|
return frame not in (20, 21)
|
|
|
|
segmk.compile(bitfilter=bitfilter)
|
|
segmk.write()
|
|
|
|
|
|
run()
|