PHYSICAL_SYNTHESIS = Coriolis
DESIGN_KIT = cmos45
YOSYS_FLATTEN = No
+ YOSYS_BLACKBOXES = pll
CHIP = chip
CORE = add
USE_CLOCKTREE = Yes
# generate add.il ilang file with: python3 add.py
#
-from nmigen import Elaboratable, Signal, Module, Const, DomainRenamer
+from nmigen import (Elaboratable, Signal, Module, Const, DomainRenamer,
+ ClockSignal, ResetSignal)
from nmigen.cli import verilog
# to get c4m-jtag
from c4m.nmigen.jtag.tap import TAP, IOType
from nmigen_soc.wishbone.sram import SRAM
from nmigen import Memory
+from dummypll import DummyPLL
-class ADD(Elaboratable):
+class Core(Elaboratable):
def __init__(self, width):
self.width = width
self.a = Signal(width)
self.memsizes = []
#self.memsizes.append((32, 32)) # width, depth
self.memsizes.append((32, 16)) # width, depth
- self.memsizes.append((32, 16)) # width, depth
+ #self.memsizes.append((32, 16)) # width, depth
# create and connect wishbone(s). okok, a better solution is to
# use a Wishbone Arbiter, and only have one WB bus.
def elaborate(self, platform):
m = Module()
+ # create JTAG module
m.submodules.jtag = jtag = self.jtag
m.d.comb += self.sr.i.eq(self.sr.o) # loopback test
return m
+class ADD(Elaboratable):
+ def __init__(self, width):
+ self.width = width
+ self.a = Signal(width)
+ self.b = Signal(width)
+ self.f = Signal(width)
+ self.jtag_tck = Signal(reset_less=True)
+ self.jtag_tms = Signal(reset_less=True)
+ self.jtag_tdi = Signal(reset_less=True)
+ self.jtag_tdo = Signal(reset_less=True)
+
+ # PLL input mode and test signals
+ self.a0 = Signal()
+ self.a1 = Signal()
+ self.pll_vco = Signal()
+ self.pll_test = Signal()
+
+ # QTY 1, dummy PLL
+ self.dummypll = DummyPLL(instance=True)
+
+ # core
+ self.core = Core(width)
+
+ def elaborate(self, platform):
+ m = Module()
+
+ # create PLL module
+ m.submodules.wrappll = pll = self.dummypll
+
+ # connect up PLL
+ sys_clk = ClockSignal()
+ m.d.comb += pll.clk_24_i.eq(sys_clk)
+ m.d.comb += pll.clk_sel_i[0].eq(self.a0)
+ m.d.comb += pll.clk_sel_i[1].eq(self.a1)
+ m.d.comb += self.pll_vco.eq(pll.pll_vco_o)
+ m.d.comb += self.pll_test.eq(pll.pll_test_o)
+
+ # create core module
+ dr = DomainRenamer("coresync")
+ m.submodules.core = core = dr(self.core)
+
+ # connect reset
+ sys_rst = ResetSignal()
+ core_rst = ResetSignal("coresync")
+ m.d.comb += core_rst.eq(sys_rst)
+
+ # connect core from PLL
+ core_clk = ClockSignal("coresync")
+ m.d.comb += core_clk.eq(pll.clk_pll_o)
+
+ # and now the internal signals to the core
+ m.d.comb += core.a.eq(self.a)
+ m.d.comb += core.b.eq(self.b)
+ m.d.comb += self.f.eq(core.f)
+
+ # and to JTAG
+ m.d.comb += self.jtag_tdo.eq(self.core.jtag.bus.tdo)
+ m.d.comb += self.core.jtag.bus.tdi.eq(self.jtag_tdi)
+ m.d.comb += self.core.jtag.bus.tms.eq(self.jtag_tms)
+ m.d.comb += self.core.jtag.bus.tck.eq(self.jtag_tck)
+
+ # dummy to get a sync clk
+ #x = Signal()
+ #m.d.sync += x.eq(~x ^ self.a)
+
+ return m
+
+ def ports(self):
+ return [#ClockSignal(), ResetSignal(),
+ self.a, self.b, self.f,
+ self.a0, self.a1, # PLL mode
+ self.pll_test, self.pll_vco, # PLL test
+ self.jtag_tck,
+ self.jtag_tms,
+ self.jtag_tdo,
+ self.jtag_tdi]
+
def create_verilog(dut, ports, test_name):
vl = verilog.convert(dut, name=test_name, ports=ports)
f.write(vl)
if __name__ == "__main__":
- alu = DomainRenamer("sys")(ADD(width=4))
- create_verilog(alu, [alu.a, alu.b, alu.f,
- alu.jtag.bus.tck,
- alu.jtag.bus.tms,
- alu.jtag.bus.tdo,
- alu.jtag.bus.tdi], "add")
+ #alu = DomainRenamer("sys")(ADD(width=4))
+ alu = (ADD(width=4))
+ create_verilog(alu, alu.ports(), "add")
Viewer.Graphics.setStyle( 'Alliance.Classic [black]' )
af = CRL.AllianceFramework.get()
env = af.getEnvironment()
- env.setCLOCK( '^sys_clk$|^ck|^jtag_tck$' )
+ env.setCLOCK( '^clk$|^ck|^jtag_tck$' )
env.setPOWER( 'vdd' )
env.setGROUND( 'vss' )
env.addSYSTEM_LIBRARY( library=cellsTop+'/niolib',
, (IoPin.SOUTH, None, 'power_0' , 'vdd' )
, (IoPin.SOUTH, None, 'p_a2' , 'a(2)' , 'a(2)' )
, (IoPin.SOUTH, None, 'p_b3' , 'b(3)' , 'b(3)' )
+ , (IoPin.SOUTH, None, 'p_pll_vco' , 'pll_vco' , 'pll_vco' )
, (IoPin.EAST , None, 'p_jtag_tms' , 'jtag_tms' , 'jtag_tms' )
, (IoPin.EAST , None, 'p_jtag_tdo' , 'jtag_tdo' , 'jtag_tdo' )
, (IoPin.EAST , None, 'ground_0' , 'vss' )
- , (IoPin.EAST , None, 'p_sys_clk' , 'sys_clk' , 'sys_clk' )
+ , (IoPin.EAST , None, 'p_sys_clk' , 'clk' , 'clk' )
, (IoPin.EAST , None, 'p_jtag_tck' , 'jtag_tck' , 'jtag_tck' )
, (IoPin.EAST , None, 'p_jtag_tdi' , 'jtag_tdi' , 'jtag_tdi' )
, (IoPin.EAST , None, 'p_b2' , 'b(2)' , 'b(2)' )
+ , (IoPin.EAST , None, 'p_b0' , 'b(0)' , 'b(0)' )
, (IoPin.NORTH, None, 'ioground_0' , 'iovss' )
, (IoPin.NORTH, None, 'p_b1' , 'b(1)' , 'b(1)' )
, (IoPin.NORTH, None, 'ground_1' , 'vss' )
- , (IoPin.NORTH, None, 'p_b0' , 'b(0)' , 'b(0)' )
- , (IoPin.NORTH, None, 'p_sys_rst' , 'sys_rst' , 'sys_rst' )
+ , (IoPin.NORTH, None, 'p_pll_test' , 'pll_test' , 'pll_test' )
+ , (IoPin.NORTH, None, 'p_pll_a0' , 'a0' , 'a0' )
+ , (IoPin.NORTH, None, 'p_pll_a1' , 'a1' , 'a1' )
+ , (IoPin.NORTH, None, 'p_sys_rst' , 'rst' , 'rst' )
, (IoPin.WEST , None, 'p_f3' , 'f(3)' , 'f(3)' )
, (IoPin.WEST , None, 'p_f2' , 'f(2)' , 'f(2)' )
, (IoPin.WEST , None, 'power_1' , 'vdd' )
+ , (IoPin.WEST , None, 'p_coresync_clk', 'coresync_clk', 'coresync_clk' )
+ #, (IoPin.WEST , None, 'coresync_rst', 'coresync_rst', 'coresync_rst' )
, (IoPin.WEST , None, 'p_f1' , 'f(1)' , 'f(1)' )
, (IoPin.WEST , None, 'p_f0' , 'f(0)' , 'f(0)' )
, (IoPin.WEST , None, 'p_a3' , 'a(3)' , 'a(3)' )
adderConf.editor = editor
adderConf.useSpares = True
adderConf.useClockTree = True
- adderConf.useHFNS = True
+ #adderConf.useHFNS = True
adderConf.cfg.katana.hTracksReservedMin = 9
adderConf.cfg.katana.vTracksReservedMin = 2
adderConf.bColumns = 2
adderConf.chipConf.name = 'chip'
#adderConf.chipConf.ioPadGauge = 'LibreSOCIO'
adderConf.chipConf.ioPadGauge = 'niolib'
+ adderConf.useHTree('coresync_clk')
adderConf.useHTree('jtag_tck_from_pad')
- adderConf.useHTree('sys_clk_from_pad')
+ adderConf.useHTree('clk_from_pad')
adderConf.coreSize = ( l(coreSize), l(coreSize) )
adderConf.chipSize = ( l(coreSize+3500), l(coreSize+3500) )
adderToChip = CoreToChip( adderConf )
with UpdateSession():
cell.setAbutmentBox(Box(
#u(0.0), u(0.0), u(13.5), u(2.025),
- u(0.0), u(0.0), u(space*100), u(space*25),
+ u(0.0), u(0.0), u(space*125), u(space*25),
))
nets = {
#'*': Net.create(cell, '*'),
'a1': Net.create(cell, 'a1'),
'vco_test_ana': Net.create(cell, 'vco_test_ana'),
'out_v': Net.create(cell, 'out_v'),
+ 'vdd': Net.create(cell, 'vdd'),
+ 'vss': Net.create(cell, 'vss'),
}
+ nets['vdd'].setGlobal(True)
+ nets['vss'].setGlobal(True)
# set net directions
nets['ref_v'].setDirection( Net.Direction.IN )
nets['div_out_test'].setDirection( Net.Direction.OUT )
nets['vco_test_ana'].setDirection( Net.Direction.OUT )
nets['out_v'].setDirection( Net.Direction.OUT )
+ nets['vdd'].setType( Net.Type.POWER )
+ nets['vdd'].setDirection( Net.Direction.IN )
+ nets['vss'].setType( Net.Type.GROUND )
+ nets['vss'].setDirection( Net.Direction.IN )
# create series of stepped pins
x = space*20
wid = space
step = wid*5
for cname in ['ref_v', 'div_out_test', 'a0', 'a1', 'vco_test_ana',
- 'out_v']:
+ 'out_v', 'vdd', 'vss']:
net = nets[cname]
pin = Vertical.create(
net, tech.getLayer('metal1'),
nets = {
'*': Net.create(cell, '*'),
'clk': Net.create(cell, 'clk'),
- #'vdd': Net.create(cell, 'vdd'),
- #'vss': Net.create(cell, 'vss'),
+ 'vdd': Net.create(cell, 'vdd'),
+ 'vss': Net.create(cell, 'vss'),
}
+ nets['vss'].setGlobal(True)
+ nets['vdd'].setGlobal(True)
for name, qty in (('a', 9),
('d', 64),
('q', 64),
ls180Conf.chipConf.ioPadGauge = 'niolib'
ls180Conf.coreSize = (l(coreSize ), l(coreSize ))
ls180Conf.chipSize = (l(coreSize+3360), l(coreSize+3360))
- ls180Conf.useHTree('core.por_clk')
+ # ooo, how annoying. nsxlib (only 6 METAL) cannot cope with 3 clocks!
+ #ls180Conf.useHTree('core.por_clk') # output from the PLL, needs to be H-Tree
ls180Conf.useHTree('jtag_tck_from_pad')
+ ls180Conf.useHTree('sys_clk_from_pad')
ls180ToChip = CoreToChip( ls180Conf )
ls180ToChip.buildChip()
with UpdateSession():
cell.setAbutmentBox(Box(
#u(0.0), u(0.0), u(13.5), u(2.025),
- u(0.0), u(0.0), u(space*100), u(space*25),
+ u(0.0), u(0.0), u(space*125), u(space*25),
))
nets = {
#'*': Net.create(cell, '*'),
'a1': Net.create(cell, 'a1'),
'vco_test_ana': Net.create(cell, 'vco_test_ana'),
'out_v': Net.create(cell, 'out_v'),
+ 'vdd': Net.create(cell, 'vdd'),
+ 'vss': Net.create(cell, 'vss'),
}
+ nets['vdd'].setGlobal(True)
+ nets['vss'].setGlobal(True)
# set net directions
nets['ref_v'].setDirection( Net.Direction.IN )
nets['div_out_test'].setDirection( Net.Direction.OUT )
nets['vco_test_ana'].setDirection( Net.Direction.OUT )
nets['out_v'].setDirection( Net.Direction.OUT )
+ nets['vdd'].setType( Net.Type.POWER )
+ nets['vdd'].setDirection( Net.Direction.IN )
+ nets['vss'].setType( Net.Type.GROUND )
+ nets['vss'].setDirection( Net.Direction.IN )
# create series of stepped pins
x = space*20
wid = space
step = wid*5
for cname in ['ref_v', 'div_out_test', 'a0', 'a1', 'vco_test_ana',
- 'out_v']:
+ 'out_v', 'vdd', 'vss']:
net = nets[cname]
pin = Vertical.create(
net, tech.getLayer('metal1'),
ls180Conf.coreSize = (coreSizeX, coreSizeY)
ls180Conf.chipSize = (coreSizeX + chipBorder + u(5.0), coreSizeY + chipBorder - u(0.04) )
#ls180Conf.useHTree( 'core.subckt_12941_test_issuer.ti_coresync_clk' )
+ # XXX this is probably just por_clk not core.por_clk
+ # or, more likely, core.pllclk_clk
ls180Conf.useHTree( 'core.por_clk' )
ls180Conf.useHTree( 'jtag_tck_from_pad' )