build/efinix: Minor initial cleanups.
This commit is contained in:
parent
eafa0fe83e
commit
a99b4cac48
|
@ -10,24 +10,24 @@ from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||||
|
|
||||||
from litex.build.io import *
|
from litex.build.io import *
|
||||||
|
|
||||||
# Efinix AsyncResetSynchronizer ---------------------------------------------------------------------
|
# Efinix AsyncResetSynchronizer --------------------------------------------------------------------
|
||||||
|
|
||||||
class EfinixAsyncResetSynchronizerImpl(Module):
|
class EfinixAsyncResetSynchronizerImpl(Module):
|
||||||
def __init__(self, cd, async_reset):
|
def __init__(self, cd, async_reset):
|
||||||
rst1 = Signal()
|
rst1 = Signal()
|
||||||
self.specials += [
|
self.specials += [
|
||||||
Instance("EFX_FF",
|
Instance("EFX_FF",
|
||||||
i_D = 0,
|
i_D = 0,
|
||||||
i_SR = async_reset,
|
i_SR = async_reset,
|
||||||
i_CLK = cd.clk,
|
i_CLK = cd.clk,
|
||||||
i_CE = 1,
|
i_CE = 1,
|
||||||
o_Q = rst1),
|
o_Q = rst1),
|
||||||
Instance("EFX_FF",
|
Instance("EFX_FF",
|
||||||
i_D = rst1,
|
i_D = rst1,
|
||||||
i_SR = async_reset,
|
i_SR = async_reset,
|
||||||
i_CLK = cd.clk,
|
i_CLK = cd.clk,
|
||||||
i_CE = 1,
|
i_CE = 1,
|
||||||
o_Q = cd.rst)
|
o_Q = cd.rst)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class EfinixAsyncResetSynchronizer:
|
||||||
def lower(dr):
|
def lower(dr):
|
||||||
return EfinixAsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
|
return EfinixAsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
|
||||||
|
|
||||||
# Gowin Special Overrides --------------------------------------------------------------------------
|
# Efinix Special Overrides -------------------------------------------------------------------------
|
||||||
|
|
||||||
efinix_special_overrides = {
|
efinix_special_overrides = {
|
||||||
AsyncResetSynchronizer: EfinixAsyncResetSynchronizer
|
AsyncResetSynchronizer: EfinixAsyncResetSynchronizer
|
||||||
|
|
|
@ -1,13 +1,24 @@
|
||||||
|
#
|
||||||
|
# This file is part of LiteX.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 Franck Jullien <franck.jullien@collshade.fr>
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import csv
|
import csv
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import xml.etree.ElementTree as et
|
import xml.etree.ElementTree as et
|
||||||
|
|
||||||
namespaces = { 'efxpt' : 'http://www.efinixinc.com/peri_device_db',
|
# NameSpaces ---------------------------------------------------------------------------------------
|
||||||
'xi' : 'http://www.w3.org/2001/XInclude'
|
|
||||||
|
namespaces = {
|
||||||
|
'efxpt' : "http://www.efinixinc.com/peri_device_db",
|
||||||
|
'xi' : "http://www.w3.org/2001/XInclude"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Efinix Database Parser ---------------------------------------------------------------------------
|
||||||
|
|
||||||
class EfinixDbParser():
|
class EfinixDbParser():
|
||||||
def __init__(self, efinity_path, device):
|
def __init__(self, efinity_path, device):
|
||||||
self.efinity_db_path = efinity_path + '/pt/db/'
|
self.efinity_db_path = efinity_path + '/pt/db/'
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
#
|
||||||
|
# This file is part of LiteX.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 Franck Jullien <franck.jullien@collshade.fr>
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
# FIXME: Cleanup/Move.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
|
@ -9,15 +17,17 @@ from litex.soc.interconnect import axi
|
||||||
|
|
||||||
from litex.build import tools
|
from litex.build import tools
|
||||||
|
|
||||||
|
# Efinix DDR ---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class EfinixDDR(Module):
|
class EfinixDDR(Module):
|
||||||
def __init__(self, platform, config, cd):
|
def __init__(self, platform, config, cd):
|
||||||
self.blocks = []
|
self.blocks = []
|
||||||
self.platform = platform
|
self.platform = platform
|
||||||
self.config = config
|
self.config = config
|
||||||
self.nb_ports = 1
|
self.nb_ports = 1
|
||||||
|
|
||||||
if config['ports'] != None:
|
if config["ports"] != None:
|
||||||
self.nb_ports = self.config['ports']
|
self.nb_ports = self.config["ports"]
|
||||||
|
|
||||||
# TODO: set clock_domain ?
|
# TODO: set clock_domain ?
|
||||||
self.port0 = port0 = axi.AXIInterface(data_width=256, address_width=32, id_width=8)
|
self.port0 = port0 = axi.AXIInterface(data_width=256, address_width=32, id_width=8)
|
||||||
|
@ -25,32 +35,32 @@ class EfinixDDR(Module):
|
||||||
if self.nb_ports == 2:
|
if self.nb_ports == 2:
|
||||||
self.port1 = port1 = axi.AXIInterface(data_width=256, address_width=32, id_width=8)
|
self.port1 = port1 = axi.AXIInterface(data_width=256, address_width=32, id_width=8)
|
||||||
|
|
||||||
for i in range (0, self.nb_ports):
|
for i in range(self.nb_ports):
|
||||||
ios = [('axi', i,
|
ios = [('axi', i,
|
||||||
Subsignal('wdata', Pins(256)),
|
Subsignal('wdata', Pins(256)),
|
||||||
Subsignal('wready', Pins(1)),
|
Subsignal('wready', Pins(1)),
|
||||||
Subsignal('wid', Pins(8)),
|
Subsignal('wid', Pins(8)),
|
||||||
Subsignal('bready', Pins(1)),
|
Subsignal('bready', Pins(1)),
|
||||||
Subsignal('rdata', Pins(256)),
|
Subsignal('rdata', Pins(256)),
|
||||||
Subsignal('aid', Pins(8)),
|
Subsignal('aid', Pins(8)),
|
||||||
Subsignal('bvalid', Pins(1)),
|
Subsignal('bvalid', Pins(1)),
|
||||||
Subsignal('rlast', Pins(1)),
|
Subsignal('rlast', Pins(1)),
|
||||||
Subsignal('bid', Pins(8)),
|
Subsignal('bid', Pins(8)),
|
||||||
Subsignal('asize', Pins(3)),
|
Subsignal('asize', Pins(3)),
|
||||||
Subsignal('atype', Pins(1)),
|
Subsignal('atype', Pins(1)),
|
||||||
Subsignal('aburst', Pins(2)),
|
Subsignal('aburst', Pins(2)),
|
||||||
Subsignal('wvalid', Pins(1)),
|
Subsignal('wvalid', Pins(1)),
|
||||||
Subsignal('aaddr', Pins(32)),
|
Subsignal('aaddr', Pins(32)),
|
||||||
Subsignal('rid', Pins(8)),
|
Subsignal('rid', Pins(8)),
|
||||||
Subsignal('avalid', Pins(1)),
|
Subsignal('avalid', Pins(1)),
|
||||||
Subsignal('rvalid', Pins(1)),
|
Subsignal('rvalid', Pins(1)),
|
||||||
Subsignal('alock', Pins(2)),
|
Subsignal('alock', Pins(2)),
|
||||||
Subsignal('rready', Pins(1)),
|
Subsignal('rready', Pins(1)),
|
||||||
Subsignal('rresp', Pins(2)),
|
Subsignal('rresp', Pins(2)),
|
||||||
Subsignal('wstrb', Pins(32)),
|
Subsignal('wstrb', Pins(32)),
|
||||||
Subsignal('aready', Pins(1)),
|
Subsignal('aready', Pins(1)),
|
||||||
Subsignal('alen', Pins(8)),
|
Subsignal('alen', Pins(8)),
|
||||||
Subsignal('wlast', Pins(1)),
|
Subsignal('wlast', Pins(1)),
|
||||||
)]
|
)]
|
||||||
|
|
||||||
io = platform.add_iface_ios(ios)
|
io = platform.add_iface_ios(ios)
|
||||||
|
@ -60,34 +70,35 @@ class EfinixDDR(Module):
|
||||||
port = port1
|
port = port1
|
||||||
|
|
||||||
is_read = port.ar.valid
|
is_read = port.ar.valid
|
||||||
self.comb += [io.aaddr.eq(Mux(is_read, port.ar.addr, port.aw.addr)),
|
self.comb += [
|
||||||
io.aid.eq(Mux(is_read, port.ar.id, port.aw.id)),
|
io.aaddr.eq(Mux(is_read, port.ar.addr, port.aw.addr)),
|
||||||
io.alen.eq(Mux(is_read, port.ar.len, port.aw.len)),
|
io.aid.eq(Mux(is_read, port.ar.id, port.aw.id)),
|
||||||
io.asize.eq(Mux(is_read, port.ar.size[0:4], port.aw.size[0:4])), #TODO: check
|
io.alen.eq(Mux(is_read, port.ar.len, port.aw.len)),
|
||||||
io.aburst.eq(Mux(is_read, port.ar.burst, port.aw.burst)),
|
io.asize.eq(Mux(is_read, port.ar.size[0:4], port.aw.size[0:4])), #TODO: check
|
||||||
io.alock.eq(Mux(is_read, port.ar.lock, port.aw.lock)),
|
io.aburst.eq(Mux(is_read, port.ar.burst, port.aw.burst)),
|
||||||
io.avalid.eq(Mux(is_read, port.ar.valid, port.aw.valid)),
|
io.alock.eq(Mux(is_read, port.ar.lock, port.aw.lock)),
|
||||||
|
io.avalid.eq(Mux(is_read, port.ar.valid, port.aw.valid)),
|
||||||
|
|
||||||
io.atype.eq(~is_read),
|
io.atype.eq(~is_read),
|
||||||
port.aw.ready.eq(io.aready),
|
port.aw.ready.eq(io.aready),
|
||||||
port.ar.ready.eq(io.aready),
|
port.ar.ready.eq(io.aready),
|
||||||
|
|
||||||
io.wid.eq(port.w.id),
|
io.wid.eq(port.w.id),
|
||||||
io.wstrb.eq(port.w.strb),
|
io.wstrb.eq(port.w.strb),
|
||||||
io.wdata.eq(port.w.data),
|
io.wdata.eq(port.w.data),
|
||||||
io.wlast.eq(port.w.last),
|
io.wlast.eq(port.w.last),
|
||||||
io.wvalid.eq(port.w.valid),
|
io.wvalid.eq(port.w.valid),
|
||||||
port.w.ready.eq(io.wready),
|
port.w.ready.eq(io.wready),
|
||||||
|
|
||||||
port.r.id.eq(io.rid),
|
port.r.id.eq(io.rid),
|
||||||
port.r.data.eq(io.rdata),
|
port.r.data.eq(io.rdata),
|
||||||
port.r.last.eq(io.rlast),
|
port.r.last.eq(io.rlast),
|
||||||
port.r.resp.eq(io.rresp),
|
port.r.resp.eq(io.rresp),
|
||||||
port.r.valid.eq(io.rvalid),
|
port.r.valid.eq(io.rvalid),
|
||||||
io.rready.eq(port.r.ready),
|
io.rready.eq(port.r.ready),
|
||||||
|
|
||||||
port.b.id.eq(io.bid),
|
port.b.id.eq(io.bid),
|
||||||
port.b.valid.eq(io.bvalid),
|
port.b.valid.eq(io.bvalid),
|
||||||
io.bready.eq(port.b.ready),
|
io.bready.eq(port.b.ready),
|
||||||
# port.b.resp ??
|
# port.b.resp ??
|
||||||
]
|
]
|
||||||
|
|
|
@ -29,6 +29,8 @@ from litex.build import tools
|
||||||
|
|
||||||
from litex.build.efinix import InterfaceWriter
|
from litex.build.efinix import InterfaceWriter
|
||||||
|
|
||||||
|
# FIXME: Avoid duplication with verilog.py.
|
||||||
|
|
||||||
_reserved_keywords = {
|
_reserved_keywords = {
|
||||||
"always", "and", "assign", "automatic", "begin", "buf", "bufif0", "bufif1",
|
"always", "and", "assign", "automatic", "begin", "buf", "bufif0", "bufif1",
|
||||||
"case", "casex", "casez", "cell", "cmos", "config", "deassign", "default",
|
"case", "casex", "casez", "cell", "cmos", "config", "deassign", "default",
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
#
|
||||||
|
# This file is part of LiteX.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 Franck Jullien <franck.jullien@collshade.fr>
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import csv
|
import csv
|
||||||
import re
|
import re
|
||||||
|
@ -8,17 +14,20 @@ import xml.etree.ElementTree as et
|
||||||
|
|
||||||
from litex.build import tools
|
from litex.build import tools
|
||||||
|
|
||||||
namespaces = { 'efxpt' : 'http://www.efinixinc.com/peri_design_db',
|
namespaces = {
|
||||||
'xi' : 'http://www.w3.org/2001/XInclude'
|
"efxpt" : "http://www.efinixinc.com/peri_design_db",
|
||||||
|
"xi" : "http://www.w3.org/2001/XInclude"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Interface Writer --------------------------------------------------------------------------------
|
||||||
|
|
||||||
class InterfaceWriter():
|
class InterfaceWriter():
|
||||||
def __init__(self, efinity_path):
|
def __init__(self, efinity_path):
|
||||||
self.efinity_path = efinity_path
|
self.efinity_path = efinity_path
|
||||||
self.blocks = []
|
self.blocks = []
|
||||||
self.xml_blocks = []
|
self.xml_blocks = []
|
||||||
self.filename = ''
|
self.filename = ''
|
||||||
self.platform = None
|
self.platform = None
|
||||||
|
|
||||||
def set_build_params(self, platform, build_name):
|
def set_build_params(self, platform, build_name):
|
||||||
self.filename = build_name
|
self.filename = build_name
|
||||||
|
@ -47,10 +56,10 @@ class InterfaceWriter():
|
||||||
def add_ddr_lvds(self, root, params):
|
def add_ddr_lvds(self, root, params):
|
||||||
lvds_info = root.find('efxpt:lvds_info', namespaces)
|
lvds_info = root.find('efxpt:lvds_info', namespaces)
|
||||||
if params['mode'] == 'OUTPUT':
|
if params['mode'] == 'OUTPUT':
|
||||||
dir = 'tx'
|
dir = 'tx'
|
||||||
mode = 'out'
|
mode = 'out'
|
||||||
else:
|
else:
|
||||||
dir = 'rx'
|
dir = 'rx'
|
||||||
mode = 'in'
|
mode = 'in'
|
||||||
|
|
||||||
pad = self.platform.parser.get_gpio_instance_from_pin(params['location'][0])
|
pad = self.platform.parser.get_gpio_instance_from_pin(params['location'][0])
|
||||||
|
@ -64,38 +73,42 @@ class InterfaceWriter():
|
||||||
pad = pad.rsplit('_', 1)[0]
|
pad = pad.rsplit('_', 1)[0]
|
||||||
|
|
||||||
lvds = et.SubElement(lvds_info, 'efxpt:lvds',
|
lvds = et.SubElement(lvds_info, 'efxpt:lvds',
|
||||||
name = params['name'],
|
name = params['name'],
|
||||||
lvds_def = pad,
|
lvds_def = pad,
|
||||||
ops_type = dir)
|
ops_type = dir
|
||||||
|
)
|
||||||
|
|
||||||
et.SubElement(lvds, 'efxpt:ltx_info', pll_instance = '',
|
et.SubElement(lvds, 'efxpt:ltx_info',
|
||||||
fast_clock_name = '{}'.format(params['fast_clk']),
|
pll_instance = '',
|
||||||
slow_clock_name = '{}'.format(params['slow_clk']),
|
fast_clock_name = '{}'.format(params['fast_clk']),
|
||||||
reset_name = '',
|
slow_clock_name = '{}'.format(params['slow_clk']),
|
||||||
out_bname = '{}'.format(params['name']),
|
reset_name = '',
|
||||||
oe_name = '',
|
out_bname = '{}'.format(params['name']),
|
||||||
clock_div = '1',
|
oe_name = '',
|
||||||
mode = '{}'.format(mode),
|
clock_div = '1',
|
||||||
serialization = '{}'.format(params['serialisation']),
|
mode = '{}'.format(mode),
|
||||||
reduced_swing = 'false',
|
serialization = '{}'.format(params['serialisation']),
|
||||||
load = '3')
|
reduced_swing = 'false',
|
||||||
|
load = '3'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def add_ddr_xml(self, root, params):
|
def add_ddr_xml(self, root, params):
|
||||||
ddr_info = root.find('efxpt:ddr_info', namespaces)
|
ddr_info = root.find('efxpt:ddr_info', namespaces)
|
||||||
|
|
||||||
ddr = et.SubElement(ddr_info, 'efxpt:ddr',
|
ddr = et.SubElement(ddr_info, 'efxpt:ddr',
|
||||||
name = 'ddr_inst1',
|
name = 'ddr_inst1',
|
||||||
ddr_def = 'DDR_0',
|
ddr_def = 'DDR_0',
|
||||||
cs_preset_id = '173',
|
cs_preset_id = '173',
|
||||||
cs_mem_type = 'LPDDR3',
|
cs_mem_type = 'LPDDR3',
|
||||||
cs_ctrl_width = 'x32',
|
cs_ctrl_width = 'x32',
|
||||||
cs_dram_width = 'x32',
|
cs_dram_width = 'x32',
|
||||||
cs_dram_density = '8G',
|
cs_dram_density = '8G',
|
||||||
cs_speedbin = '800',
|
cs_speedbin = '800',
|
||||||
target0_enable = 'true',
|
target0_enable = 'true',
|
||||||
target1_enable = 'false',
|
target1_enable = 'false',
|
||||||
ctrl_type = 'none')
|
ctrl_type = 'none'
|
||||||
|
)
|
||||||
|
|
||||||
axi_suffix = '' # '_1' for second port
|
axi_suffix = '' # '_1' for second port
|
||||||
type_suffix = '_0' # '_1' for second port
|
type_suffix = '_0' # '_1' for second port
|
||||||
|
|
|
@ -10,6 +10,8 @@ import subprocess
|
||||||
|
|
||||||
from litex.build.generic_programmer import GenericProgrammer
|
from litex.build.generic_programmer import GenericProgrammer
|
||||||
|
|
||||||
|
# EfinixProgrammer ---------------------------------------------------------------------------------
|
||||||
|
|
||||||
class EfinixProgrammer(GenericProgrammer):
|
class EfinixProgrammer(GenericProgrammer):
|
||||||
|
|
||||||
def __init__(self, cable_name=""):
|
def __init__(self, cable_name=""):
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
# Copyright (c) 2015-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
# Copyright (c) 2015-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
# RGMII PHY for 7-Series Xilinx FPGA
|
# RGMII PHY for Efinix FPGAs
|
||||||
|
|
||||||
|
# FIXME: Cleanup/Move.
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
from migen.genlib.resetsync import AsyncResetSynchronizer
|
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
# Copyright (c) 2021 Florent Kermarrec <florent@enjoy-digital.fr>
|
# Copyright (c) 2021 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
# FIXME: Cleanup/Move, integrate in soc.cores.video.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue