Skip to content

Commit

Permalink
litex: sim: Get sim working in litex-buildenv
Browse files Browse the repository at this point in the history
Changes needed to get PLATFORM=sim to work again.

The platforms/sim was basically copied from litex.boards.platforms.sim
but then updated to properly handle sending the SimConfig details to the
toolchain needed during building and running of the verilog backend.

The changes in gateware/firmware are needed to allow the firmware to be
loaded lazily at build time.  This is because during build we use a
single SoC for firmware and gateware build.  Since the old code was
looking for the firmware during SoC construction it didnt work.
  • Loading branch information
stffrdhrn committed Oct 5, 2018
1 parent 1a111fa commit b9d27ec
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 37 deletions.
46 changes: 25 additions & 21 deletions gateware/firmware.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,38 @@


class MemoryMustHaveContents(Memory):
def load_init_data(self):
assert os.path.exists(self.filename), (
"ROM contents not found! {}".format(self.filename))

data = []
with open(self.filename, "rb") as firmware_file:
while True:
w = firmware_file.read(4)
if not w:
break
data.append(struct.unpack(">I", w)[0])
data_size = len(data)*4
assert data_size > 0
assert data_size < self.size, (
"Firmware is too big! {} bytes > {} bytes".format(
data_size, self.size))
print("Firmware {} bytes ({} bytes left)".format(
data_size, self.size-data_size))

self.init = data

@staticmethod
def emit_verilog(memory, ns, add_data_file):
assert memory.init, "ROM contents not found! {}".format(memory.filename)
memory.load_init_data()
return Memory.emit_verilog(memory, ns, add_data_file)


class FirmwareROM(wishbone.SRAM):
def __init__(self, size, filename):
if os.path.exists(filename):
data = []
with open(filename, "rb") as firmware_file:
while True:
w = firmware_file.read(4)
if not w:
break
data.append(struct.unpack(">I", w)[0])
data_size = len(data)*4
assert data_size > 0
assert data_size < size, (
"Firmware is too big! {} bytes > {} bytes".format(
data_size, size))
print("Firmware {} bytes ({} bytes left)".format(
data_size, size-data_size))
wishbone.SRAM.__init__(self, size, init=data)
else:
print("No firmware found! ({}) Won't compile.".format(
filename))
wishbone.SRAM.__init__(self, size)
wishbone.SRAM.__init__(self, size)

# Switch the rom memory class to be able to lazy load contents.
self.mem.__class__ = MemoryMustHaveContents
self.mem.filename = filename
self.mem.size = size
65 changes: 62 additions & 3 deletions platforms/sim.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,62 @@
from litex.boards.platforms import sim
from litex.boards.platforms.sim import *
__all__ = ['SimPins', 'Platform']
from litex.build.generic_platform import *
from litex.build.sim import SimPlatform

from litex.build.sim.config import SimConfig

class SimPins(Pins):
def __init__(self, n):
Pins.__init__(self, "s "*n)

_io = [
("sys_clk", 0, SimPins(1)),
("sys_rst", 0, SimPins(1)),
("serial", 0,
Subsignal("source_valid", SimPins(1)),
Subsignal("source_ready", SimPins(1)),
Subsignal("source_data", SimPins(8)),

Subsignal("sink_valid", SimPins(1)),
Subsignal("sink_ready", SimPins(1)),
Subsignal("sink_data", SimPins(8)),
),
("eth_clocks", 0,
Subsignal("none", SimPins(1)),
),
("eth", 0,
Subsignal("source_valid", SimPins(1)),
Subsignal("source_ready", SimPins(1)),
Subsignal("source_data", SimPins(8)),

Subsignal("sink_valid", SimPins(1)),
Subsignal("sink_ready", SimPins(1)),
Subsignal("sink_data", SimPins(8)),
),
("vga", 0,
Subsignal("de", SimPins(1)),
Subsignal("hsync", SimPins(1)),
Subsignal("vsync", SimPins(1)),
Subsignal("r", SimPins(8)),
Subsignal("g", SimPins(8)),
Subsignal("b", SimPins(8)),
),
]


class Platform(SimPlatform):
default_clk_name = "sys_clk"
default_clk_period = 1000 # on modern computers simulate at ~ 1MHz

def __init__(self):
SimPlatform.__init__(self, "SIM", _io)

def do_finalize(self, fragment):
pass

def build(self, fragment, **kwargs):
scfg = SimConfig(default_clk="sys_clk")
scfg.add_module("serial2console", "serial")
if hasattr(fragment, 'localip'):
scfg.add_module('ethernet', "eth", args={ "interface": "tap1",
"ip": fragment.localip })
kwargs['sim_config'] = scfg
return SimPlatform.build(self, fragment, **kwargs)
19 changes: 8 additions & 11 deletions targets/sim/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Support for simulation via verilator
import os

from migen import *
from migen.genlib.io import CRG

Expand All @@ -17,11 +19,6 @@


class BaseSoC(SoCSDRAM):
csr_peripherals = (
,
)
csr_map_update(SoCSDRAM.csr_map, csr_peripherals)

mem_map = {
"firmware_ram": 0x20000000, # (default shadow @0xa0000000)
}
Expand All @@ -32,11 +29,12 @@ def __init__(self, platform, **kwargs):
kwargs['integrated_rom_size']=0x8000
if 'integrated_sram_size' not in kwargs:
kwargs['integrated_sram_size']=0x8000
if 'firmware_ram_size' not in kwargs:
kwargs['firmware_ram_size']=0x10000
if 'firmware_filename' not in kwargs:
kwargs['firmware_filename'] = "build/sim_{}_{}/software/firmware/firmware.fbi".format(
self.__class__.__name__.lower()[:-3], kwargs.get('cpu_type', 'lm32'))

firmware_ram_size=0x20000
firmware_filename="{}/build/sim_{}_{}/software/firmware/firmware.fbi".format(
os.getcwd(),
self.__class__.__name__.lower()[:-3],
kwargs.get('cpu_type', 'lm32'))

clk_freq = int((1/(platform.default_clk_period))*1000000000)
SoCSDRAM.__init__(self, platform, clk_freq, with_uart=False, **kwargs)
Expand Down Expand Up @@ -76,5 +74,4 @@ def __init__(self, platform, **kwargs):
self.add_constant("MEMTEST_ADDR_SIZE", 1024)
self.add_constant("SIMULATION", 1)


SoC = BaseSoC
6 changes: 4 additions & 2 deletions targets/sim/net.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class NetSoC(BaseSoC):
csr_map.update(BaseSoC.csr_map)

interrupt_map = {
"ethmac": 2,
"ethmac": 3,
}
interrupt_map.update(BaseSoC.interrupt_map)

Expand All @@ -48,7 +48,9 @@ def configure_iprange(self, iprange):
while len(iprange) < 4:
iprange.append(0)
# Our IP address
self._configure_ip("LOCALIP", iprange[:-1]+[50])
localip = iprange[:-1]+[50]
self._configure_ip("LOCALIP", localip)
self.localip = ".".join(map(str, localip))
# IP address of tftp host
self._configure_ip("REMOTEIP", iprange[:-1]+[100])

Expand Down

0 comments on commit b9d27ec

Please sign in to comment.