build/efinix: Minor initial cleanups.

This commit is contained in:
Florent Kermarrec 2021-10-13 09:42:39 +02:00
parent eafa0fe83e
commit a99b4cac48
8 changed files with 146 additions and 103 deletions

View File

@ -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

View File

@ -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/'

View File

@ -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 ??
] ]

View File

@ -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",

View File

@ -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

View File

@ -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=""):

View File

@ -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

View File

@ -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