mirror of https://github.com/openXC7/prjxray.git
Merge pull request #971 from litghost/ologic_update
Add some additional OLOGIC bits.
This commit is contained in:
commit
4fd53f65a8
|
|
@ -5,6 +5,13 @@ from prjxray import verilog
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
def bitfilter(frame, word):
|
||||||
|
if frame < 30 or frame > 37:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def handle_data_width(segmk, d):
|
def handle_data_width(segmk, d):
|
||||||
if 'DATA_WIDTH' not in d:
|
if 'DATA_WIDTH' not in d:
|
||||||
return
|
return
|
||||||
|
|
@ -31,6 +38,7 @@ def main():
|
||||||
handle_data_width(segmk, d)
|
handle_data_width(segmk, d)
|
||||||
|
|
||||||
if d['use_oserdese2']:
|
if d['use_oserdese2']:
|
||||||
|
segmk.add_site_tag(site, 'OQUSED', 1)
|
||||||
if 'SRTYPE' in d:
|
if 'SRTYPE' in d:
|
||||||
for opt in ['ASYNC', 'SYNC']:
|
for opt in ['ASYNC', 'SYNC']:
|
||||||
segmk.add_site_tag(
|
segmk.add_site_tag(
|
||||||
|
|
@ -47,41 +55,53 @@ def main():
|
||||||
site, 'OSERDESE.DATA_RATE_TQ.{}'.format(opt),
|
site, 'OSERDESE.DATA_RATE_TQ.{}'.format(opt),
|
||||||
verilog.unquote(d['DATA_RATE_TQ']) == opt)
|
verilog.unquote(d['DATA_RATE_TQ']) == opt)
|
||||||
|
|
||||||
if d['oddr_mux_config'] != 'none':
|
for opt in ['SRVAL_OQ', 'SRVAL_TQ', 'INIT_OQ', 'INIT_TQ']:
|
||||||
segmk.add_site_tag(site, 'OFF.ZINIT_Q', not d['QINIT'])
|
segmk.add_site_tag(site, opt, d[opt])
|
||||||
|
segmk.add_site_tag(site, 'Z' + opt, 1 ^ d[opt])
|
||||||
|
|
||||||
|
for opt in ['CLK', 'CLKDIV']:
|
||||||
|
k = 'IS_{}_INVERTED'.format(opt)
|
||||||
|
segmk.add_site_tag(site, k, d[k])
|
||||||
|
segmk.add_site_tag(site, 'ZINV_{}'.format(opt), 1 ^ d[k])
|
||||||
|
|
||||||
|
for idx in range(4):
|
||||||
|
k = 'IS_T{}_INVERTED'.format(idx + 1)
|
||||||
|
segmk.add_site_tag(site, k, d[k])
|
||||||
|
segmk.add_site_tag(
|
||||||
|
site, 'ZINV_T{}'.format(idx + 1), 1 ^ d[k])
|
||||||
|
|
||||||
|
for idx in range(8):
|
||||||
|
k = 'IS_D{}_INVERTED'.format(idx + 1)
|
||||||
|
segmk.add_site_tag(site, k, d[k])
|
||||||
|
segmk.add_site_tag(
|
||||||
|
site, 'ZINV_D{}'.format(idx + 1), 1 ^ d[k])
|
||||||
|
|
||||||
|
if d['oddr_mux_config'] == 'direct' and d[
|
||||||
|
'tddr_mux_config'] == 'direct':
|
||||||
for opt in ['OPPOSITE_EDGE', 'SAME_EDGE']:
|
for opt in ['OPPOSITE_EDGE', 'SAME_EDGE']:
|
||||||
segmk.add_site_tag(
|
segmk.add_site_tag(
|
||||||
site, 'ODDR.DDR_CLK_EDGE.{}'.format(opt),
|
site, 'ODDR.DDR_CLK_EDGE.{}'.format(opt),
|
||||||
verilog.unquote(d['ODDR_CLK_EDGE']) == opt)
|
verilog.unquote(d['ODDR_CLK_EDGE']) == opt)
|
||||||
|
|
||||||
if d['tddr_mux_config'] != 'none':
|
segmk.add_site_tag(
|
||||||
segmk.add_site_tag(site, 'TFF.ZINIT_Q', not d['TINIT'])
|
site, 'TDDR.DDR_CLK_EDGE.INV',
|
||||||
# Note: edge settings seem to be ignored for TFF
|
d['ODDR_CLK_EDGE'] != d['TDDR_CLK_EDGE'])
|
||||||
for opt in ['OPPOSITE_EDGE', 'SAME_EDGE']:
|
segmk.add_site_tag(
|
||||||
segmk.add_site_tag(
|
site, 'TDDR.DDR_CLK_EDGE.ZINV',
|
||||||
site, 'TDDR.DDR_CLK_EDGE.{}'.format(opt),
|
d['ODDR_CLK_EDGE'] == d['TDDR_CLK_EDGE'])
|
||||||
verilog.unquote(d['TDDR_CLK_EDGE']) != opt)
|
|
||||||
|
|
||||||
# all the bellow mux configs give 0 candidates
|
if not d['use_oserdese2']:
|
||||||
# this is wierd, as they are set when DDR output is used
|
if d['oddr_mux_config'] == 'lut':
|
||||||
# something's fishy here
|
segmk.add_site_tag(site, 'OMUX.D1', 1)
|
||||||
if d['oddr_mux_config'] == 'direct':
|
segmk.add_site_tag(site, 'OQUSED', 1)
|
||||||
segmk.add_site_tag(site, 'OMUXE2', 0)
|
elif d['oddr_mux_config'] == 'direct':
|
||||||
|
segmk.add_site_tag(site, 'OMUX.D1', 0)
|
||||||
|
elif d['oddr_mux_config'] == 'none' and not d['io']:
|
||||||
|
segmk.add_site_tag(site, 'OQUSED', 0)
|
||||||
|
|
||||||
elif d['oddr_mux_config'] == 'none':
|
segmk.add_site_tag(site, 'TQUSED', d['io'])
|
||||||
segmk.add_site_tag(site, 'OMUXE2', 1)
|
|
||||||
else:
|
|
||||||
assert False, d['oddr_mux_config']
|
|
||||||
|
|
||||||
if d['tddr_mux_config'] == 'direct':
|
segmk.compile(bitfilter=bitfilter)
|
||||||
segmk.add_site_tag(site, 'TMUXE2', 0)
|
|
||||||
|
|
||||||
elif d['tddr_mux_config'] == 'none':
|
|
||||||
segmk.add_site_tag(site, 'TMUXE2', 1)
|
|
||||||
else:
|
|
||||||
assert False, d['tddr_mux_config']
|
|
||||||
|
|
||||||
segmk.compile()
|
|
||||||
segmk.write(allow_empty=True)
|
segmk.write(allow_empty=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,40 @@ def use_oserdese2(p, luts, connects):
|
||||||
p['TRISTATE_WIDTH'] = tristate_width
|
p['TRISTATE_WIDTH'] = tristate_width
|
||||||
p['OSERDES_MODE'] = verilog.quote(random.choice(('MASTER', 'SLAVE')))
|
p['OSERDES_MODE'] = verilog.quote(random.choice(('MASTER', 'SLAVE')))
|
||||||
|
|
||||||
|
if p['io']:
|
||||||
|
p['TFB'] = '.TFB(tfb_{site}),'.format(**p)
|
||||||
|
p['TQ'] = '.TQ({twire}),'.format(**p)
|
||||||
|
p['t1net'] = luts.get_next_output_net()
|
||||||
|
p['t2net'] = luts.get_next_output_net()
|
||||||
|
p['t3net'] = luts.get_next_output_net()
|
||||||
|
p['t4net'] = luts.get_next_output_net()
|
||||||
|
p['tcenet'] = luts.get_next_output_net()
|
||||||
|
|
||||||
|
for idx in range(4):
|
||||||
|
p['IS_T{}_INVERTED'.format(idx + 1)] = random.randint(0, 1)
|
||||||
|
else:
|
||||||
|
p['TFB'] = '.TFB(),'
|
||||||
|
p['TQ'] = '.TQ(),'
|
||||||
|
p['t1net'] = ''
|
||||||
|
p['t2net'] = ''
|
||||||
|
p['t3net'] = ''
|
||||||
|
p['t4net'] = ''
|
||||||
|
p['tcenet'] = ''
|
||||||
|
|
||||||
|
for idx in range(4):
|
||||||
|
p['IS_T{}_INVERTED'.format(idx + 1)] = 0
|
||||||
|
|
||||||
|
p['SRVAL_OQ'] = random.randint(0, 1)
|
||||||
|
p['SRVAL_TQ'] = random.randint(0, 1)
|
||||||
|
p['INIT_OQ'] = random.randint(0, 1)
|
||||||
|
p['INIT_TQ'] = random.randint(0, 1)
|
||||||
|
|
||||||
|
for idx in range(8):
|
||||||
|
p['IS_D{}_INVERTED'.format(idx + 1)] = random.randint(0, 1)
|
||||||
|
|
||||||
|
p['IS_CLK_INVERTED'] = random.randint(0, 1)
|
||||||
|
p['IS_CLKDIV_INVERTED'] = random.randint(0, 1)
|
||||||
|
|
||||||
print(
|
print(
|
||||||
'''
|
'''
|
||||||
(* KEEP, DONT_TOUCH, LOC = "{ologic_loc}" *)
|
(* KEEP, DONT_TOUCH, LOC = "{ologic_loc}" *)
|
||||||
|
|
@ -77,11 +111,29 @@ def use_oserdese2(p, luts, connects):
|
||||||
.DATA_RATE_TQ({DATA_RATE_TQ}),
|
.DATA_RATE_TQ({DATA_RATE_TQ}),
|
||||||
.DATA_RATE_OQ({DATA_RATE_OQ}),
|
.DATA_RATE_OQ({DATA_RATE_OQ}),
|
||||||
.DATA_WIDTH({DATA_WIDTH}),
|
.DATA_WIDTH({DATA_WIDTH}),
|
||||||
.TRISTATE_WIDTH({TRISTATE_WIDTH})
|
.TRISTATE_WIDTH({TRISTATE_WIDTH}),
|
||||||
|
.SRVAL_OQ({SRVAL_OQ}),
|
||||||
|
.SRVAL_TQ({SRVAL_TQ}),
|
||||||
|
.INIT_OQ({INIT_OQ}),
|
||||||
|
.INIT_TQ({INIT_TQ}),
|
||||||
|
.IS_T1_INVERTED({IS_T1_INVERTED}),
|
||||||
|
.IS_T2_INVERTED({IS_T2_INVERTED}),
|
||||||
|
.IS_T3_INVERTED({IS_T3_INVERTED}),
|
||||||
|
.IS_T4_INVERTED({IS_T4_INVERTED}),
|
||||||
|
.IS_D1_INVERTED({IS_D1_INVERTED}),
|
||||||
|
.IS_D2_INVERTED({IS_D2_INVERTED}),
|
||||||
|
.IS_D3_INVERTED({IS_D3_INVERTED}),
|
||||||
|
.IS_D4_INVERTED({IS_D4_INVERTED}),
|
||||||
|
.IS_D5_INVERTED({IS_D5_INVERTED}),
|
||||||
|
.IS_D6_INVERTED({IS_D6_INVERTED}),
|
||||||
|
.IS_D7_INVERTED({IS_D7_INVERTED}),
|
||||||
|
.IS_D8_INVERTED({IS_D8_INVERTED}),
|
||||||
|
.IS_CLK_INVERTED({IS_CLK_INVERTED}),
|
||||||
|
.IS_CLKDIV_INVERTED({IS_CLKDIV_INVERTED})
|
||||||
) oserdese2_{site} (
|
) oserdese2_{site} (
|
||||||
.OQ({owire}),
|
.OQ({owire}),
|
||||||
.TFB(tfb_{site}),
|
{TFB}
|
||||||
.TQ({twire}),
|
{TQ}
|
||||||
.CLK({clknet}),
|
.CLK({clknet}),
|
||||||
.CLKDIV({clkdivnet}),
|
.CLKDIV({clkdivnet}),
|
||||||
.D1({d1net}),
|
.D1({d1net}),
|
||||||
|
|
@ -111,11 +163,6 @@ def use_oserdese2(p, luts, connects):
|
||||||
d6net=luts.get_next_output_net(),
|
d6net=luts.get_next_output_net(),
|
||||||
d7net=luts.get_next_output_net(),
|
d7net=luts.get_next_output_net(),
|
||||||
d8net=luts.get_next_output_net(),
|
d8net=luts.get_next_output_net(),
|
||||||
t1net=luts.get_next_output_net(),
|
|
||||||
t2net=luts.get_next_output_net(),
|
|
||||||
t3net=luts.get_next_output_net(),
|
|
||||||
t4net=luts.get_next_output_net(),
|
|
||||||
tcenet=luts.get_next_output_net(),
|
|
||||||
ocenet=luts.get_next_output_net(),
|
ocenet=luts.get_next_output_net(),
|
||||||
ofb_wire=luts.get_next_input_net(),
|
ofb_wire=luts.get_next_input_net(),
|
||||||
**p),
|
**p),
|
||||||
|
|
@ -125,18 +172,30 @@ def use_oserdese2(p, luts, connects):
|
||||||
def use_direct_and_oddr(p, luts, connects):
|
def use_direct_and_oddr(p, luts, connects):
|
||||||
p['oddr_mux_config'] = random.choice((
|
p['oddr_mux_config'] = random.choice((
|
||||||
'direct',
|
'direct',
|
||||||
|
'lut',
|
||||||
'none',
|
'none',
|
||||||
))
|
))
|
||||||
|
|
||||||
p['tddr_mux_config'] = random.choice((
|
if p['io']:
|
||||||
'direct',
|
if p['oddr_mux_config'] != 'lut':
|
||||||
'none',
|
p['tddr_mux_config'] = random.choice((
|
||||||
))
|
'direct',
|
||||||
|
'lut',
|
||||||
|
'none',
|
||||||
|
))
|
||||||
|
else:
|
||||||
|
p['tddr_mux_config'] = random.choice((
|
||||||
|
'lut',
|
||||||
|
'none',
|
||||||
|
))
|
||||||
|
else:
|
||||||
|
p['tddr_mux_config'] = 'none'
|
||||||
|
|
||||||
# toddr and oddr share the same clk
|
# toddr and oddr share the same clk
|
||||||
clknet = luts.get_next_output_net()
|
clknet = luts.get_next_output_net()
|
||||||
|
p['IS_CLK_INVERTED'] = 0
|
||||||
|
|
||||||
if p['tddr_mux_config'] != 'none':
|
if p['tddr_mux_config'] == 'direct':
|
||||||
p['TINIT'] = random.randint(0, 1)
|
p['TINIT'] = random.randint(0, 1)
|
||||||
p['TSRTYPE'] = verilog.quote(random.choice(('SYNC', 'ASYNC')))
|
p['TSRTYPE'] = verilog.quote(random.choice(('SYNC', 'ASYNC')))
|
||||||
p['TDDR_CLK_EDGE'] = verilog.quote('OPPOSITE_EDGE')
|
p['TDDR_CLK_EDGE'] = verilog.quote('OPPOSITE_EDGE')
|
||||||
|
|
@ -150,7 +209,8 @@ def use_direct_and_oddr(p, luts, connects):
|
||||||
ODDR #(
|
ODDR #(
|
||||||
.INIT({TINIT}),
|
.INIT({TINIT}),
|
||||||
.SRTYPE({TSRTYPE}),
|
.SRTYPE({TSRTYPE}),
|
||||||
.DDR_CLK_EDGE({TDDR_CLK_EDGE})
|
.DDR_CLK_EDGE({TDDR_CLK_EDGE}),
|
||||||
|
.IS_C_INVERTED({IS_CLK_INVERTED})
|
||||||
) toddr_{site} (
|
) toddr_{site} (
|
||||||
.C({cnet}),
|
.C({cnet}),
|
||||||
.D1({d1net}),
|
.D1({d1net}),
|
||||||
|
|
@ -171,12 +231,18 @@ def use_direct_and_oddr(p, luts, connects):
|
||||||
'''
|
'''
|
||||||
assign {twire} = tddr_d_{site};'''.format(**p, ),
|
assign {twire} = tddr_d_{site};'''.format(**p, ),
|
||||||
file=connects)
|
file=connects)
|
||||||
|
elif p['tddr_mux_config'] == 'lut':
|
||||||
|
print(
|
||||||
|
'''
|
||||||
|
assign {twire} = {lut};'''.format(lut=luts.get_next_output_net(), **p),
|
||||||
|
file=connects)
|
||||||
|
pass
|
||||||
elif p['tddr_mux_config'] == 'none':
|
elif p['tddr_mux_config'] == 'none':
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
assert False, p['tddr_mux_config']
|
assert False, p['tddr_mux_config']
|
||||||
|
|
||||||
if p['oddr_mux_config'] != 'none':
|
if p['oddr_mux_config'] == 'direct':
|
||||||
p['QINIT'] = random.randint(0, 1)
|
p['QINIT'] = random.randint(0, 1)
|
||||||
p['SRTYPE'] = verilog.quote(random.choice(('SYNC', 'ASYNC')))
|
p['SRTYPE'] = verilog.quote(random.choice(('SYNC', 'ASYNC')))
|
||||||
p['ODDR_CLK_EDGE'] = verilog.quote(
|
p['ODDR_CLK_EDGE'] = verilog.quote(
|
||||||
|
|
@ -191,7 +257,8 @@ def use_direct_and_oddr(p, luts, connects):
|
||||||
ODDR #(
|
ODDR #(
|
||||||
.INIT({QINIT}),
|
.INIT({QINIT}),
|
||||||
.SRTYPE({SRTYPE}),
|
.SRTYPE({SRTYPE}),
|
||||||
.DDR_CLK_EDGE({ODDR_CLK_EDGE})
|
.DDR_CLK_EDGE({ODDR_CLK_EDGE}),
|
||||||
|
.IS_C_INVERTED({IS_CLK_INVERTED})
|
||||||
) oddr_{site} (
|
) oddr_{site} (
|
||||||
.C({cnet}),
|
.C({cnet}),
|
||||||
.D1({d1net}),
|
.D1({d1net}),
|
||||||
|
|
@ -212,6 +279,12 @@ def use_direct_and_oddr(p, luts, connects):
|
||||||
'''
|
'''
|
||||||
assign {owire} = oddr_d_{site};'''.format(**p, ),
|
assign {owire} = oddr_d_{site};'''.format(**p, ),
|
||||||
file=connects)
|
file=connects)
|
||||||
|
elif p['oddr_mux_config'] == 'lut':
|
||||||
|
print(
|
||||||
|
'''
|
||||||
|
assign {owire} = {lut};'''.format(lut=luts.get_next_output_net(), **p),
|
||||||
|
file=connects)
|
||||||
|
pass
|
||||||
elif p['oddr_mux_config'] == 'none':
|
elif p['oddr_mux_config'] == 'none':
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|
@ -240,6 +313,9 @@ def run():
|
||||||
|
|
||||||
tile_params = []
|
tile_params = []
|
||||||
params = []
|
params = []
|
||||||
|
|
||||||
|
ndio = 0
|
||||||
|
ndo = 0
|
||||||
for idx, (tile, site) in enumerate(gen_sites()):
|
for idx, (tile, site) in enumerate(gen_sites()):
|
||||||
if idx == 0:
|
if idx == 0:
|
||||||
continue
|
continue
|
||||||
|
|
@ -254,10 +330,18 @@ def run():
|
||||||
p['DRIVE'] = random.choice(drives)
|
p['DRIVE'] = random.choice(drives)
|
||||||
p['SLEW'] = verilog.quote(random.choice(slews))
|
p['SLEW'] = verilog.quote(random.choice(slews))
|
||||||
|
|
||||||
p['pad_wire'] = 'dio[{}]'.format(idx - 1)
|
p['io'] = random.randint(0, 1)
|
||||||
p['owire'] = 'do_buf[{}]'.format(idx - 1)
|
p['owire'] = 'do_buf[{}]'.format(idx - 1)
|
||||||
p['iwire'] = 'di_buf[{}]'.format(idx - 1)
|
|
||||||
p['twire'] = 't[{}]'.format(idx - 1)
|
if p['io']:
|
||||||
|
p['pad_wire'] = 'dio[{}]'.format(ndio)
|
||||||
|
ndio += 1
|
||||||
|
|
||||||
|
p['iwire'] = 'di_buf[{}]'.format(idx - 1)
|
||||||
|
p['twire'] = 't[{}]'.format(idx - 1)
|
||||||
|
else:
|
||||||
|
p['pad_wire'] = 'do[{}]'.format(ndo)
|
||||||
|
ndo += 1
|
||||||
|
|
||||||
params.append(p)
|
params.append(p)
|
||||||
tile_params.append(
|
tile_params.append(
|
||||||
|
|
@ -270,13 +354,14 @@ def run():
|
||||||
|
|
||||||
print(
|
print(
|
||||||
'''
|
'''
|
||||||
`define N_DI {n_di}
|
`define N_DO {n_do}
|
||||||
|
`define N_DIO {n_dio}
|
||||||
|
|
||||||
module top(input clk, inout wire [`N_DI-1:0] dio);
|
module top(input clk, output wire [`N_DO-1:0] do, inout wire [`N_DIO-1:0] dio);
|
||||||
wire [`N_DI-1:0] di_buf;
|
wire [(`N_DIO+`N_DO)-1:0] di_buf;
|
||||||
wire [`N_DI-1:0] do_buf;
|
wire [(`N_DIO+`N_DO)-1:0] do_buf;
|
||||||
wire [`N_DI-1:0] t;
|
wire [(`N_DIO+`N_DO)-1:0] t;
|
||||||
'''.format(n_di=idx))
|
'''.format(n_dio=ndio, n_do=ndo))
|
||||||
|
|
||||||
# Always output a LUT6 to make placer happy.
|
# Always output a LUT6 to make placer happy.
|
||||||
print(
|
print(
|
||||||
|
|
@ -286,8 +371,9 @@ module top(input clk, inout wire [`N_DI-1:0] dio);
|
||||||
''')
|
''')
|
||||||
|
|
||||||
for p in params:
|
for p in params:
|
||||||
print(
|
if p['io']:
|
||||||
'''
|
print(
|
||||||
|
'''
|
||||||
wire oddr_d_{site};
|
wire oddr_d_{site};
|
||||||
|
|
||||||
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
|
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
|
||||||
|
|
@ -300,7 +386,21 @@ module top(input clk, inout wire [`N_DI-1:0] dio);
|
||||||
.T({twire})
|
.T({twire})
|
||||||
);
|
);
|
||||||
'''.format(**p),
|
'''.format(**p),
|
||||||
file=connects)
|
file=connects)
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
'''
|
||||||
|
wire oddr_d_{site};
|
||||||
|
|
||||||
|
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
|
||||||
|
OBUF #(
|
||||||
|
.IOSTANDARD({IOSTANDARD})
|
||||||
|
) obuf_{site} (
|
||||||
|
.O({pad_wire}),
|
||||||
|
.I({owire})
|
||||||
|
);
|
||||||
|
'''.format(**p),
|
||||||
|
file=connects)
|
||||||
|
|
||||||
p['use_oserdese2'] = random.randint(0, 1)
|
p['use_oserdese2'] = random.randint(0, 1)
|
||||||
if p['use_oserdese2']:
|
if p['use_oserdese2']:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue