build/sim/litex_sim: Add initial video module/support in simulation.
Simulation with framebuffer: litex_sim --with-sdram --with-video-framebuffer Simulation with video terminal: litex_sim --with-sdram --with-video-terminal
This commit is contained in:
parent
42f46c9c95
commit
1f08fe3286
|
@ -14,7 +14,7 @@ ifeq ($(UNAME_S),Darwin)
|
||||||
else
|
else
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
CFLAGS += -ggdb
|
CFLAGS += -ggdb
|
||||||
LDFLAGS += -lpthread -Wl,--no-as-needed -ljson-c -lz -lm -lstdc++ -Wl,--no-as-needed -ldl -levent
|
LDFLAGS += -lpthread -Wl,--no-as-needed -ljson-c -lz -lm -lstdc++ -Wl,--no-as-needed -ldl -levent -lSDL2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS += -Wall -$(OPT_LEVEL) $(if $(COVERAGE), -DVM_COVERAGE) $(if $(TRACE_FST), -DTRACE_FST)
|
CFLAGS += -Wall -$(OPT_LEVEL) $(if $(COVERAGE), -DVM_COVERAGE) $(if $(TRACE_FST), -DTRACE_FST)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
include ../variables.mak
|
include ../variables.mak
|
||||||
MODULES = xgmii_ethernet ethernet serial2console serial2tcp clocker spdeeprom gmii_ethernet
|
MODULES = xgmii_ethernet ethernet serial2console serial2tcp clocker spdeeprom gmii_ethernet video
|
||||||
|
|
||||||
.PHONY: $(MODULES) $(EXTRA_MOD_LIST)
|
.PHONY: $(MODULES) $(EXTRA_MOD_LIST)
|
||||||
all: $(MODULES) $(EXTRA_MOD_LIST)
|
all: $(MODULES) $(EXTRA_MOD_LIST)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
include ../../variables.mak
|
||||||
|
include $(SRC_DIR)/modules/rules.mak
|
|
@ -0,0 +1,58 @@
|
||||||
|
// Simple framebuffer windows for visualizations
|
||||||
|
// Copyright (C) 2022 Victor Suarez Rovere <suarezvictor@gmail.com>
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include "sim_fb.h"
|
||||||
|
|
||||||
|
bool fb_init(unsigned width, unsigned height, bool vsync, fb_handle_t *handle)
|
||||||
|
{
|
||||||
|
if(SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
handle->win = SDL_CreateWindow("LiteX Sim Video Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_SHOWN);
|
||||||
|
if (!handle->win)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
handle->renderer = SDL_CreateRenderer(handle->win, -1, vsync ? SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_PRESENTVSYNC : 0);
|
||||||
|
if (!handle->renderer)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
handle->texture = SDL_CreateTexture(handle->renderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_TARGET, width, height);
|
||||||
|
if (!handle->texture)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fb_should_quit(void)
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
while(SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
case SDL_QUIT:
|
||||||
|
return true;
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
if(event.key.keysym.sym == SDLK_ESCAPE)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fb_update(fb_handle_t *handle, const void *buf, size_t stride_bytes)
|
||||||
|
{
|
||||||
|
SDL_UpdateTexture(handle->texture, NULL, buf, stride_bytes);
|
||||||
|
SDL_RenderCopy(handle->renderer, handle->texture, NULL, NULL);
|
||||||
|
SDL_RenderPresent(handle->renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fb_deinit(fb_handle_t *handle)
|
||||||
|
{
|
||||||
|
SDL_DestroyTexture(handle->texture);
|
||||||
|
SDL_DestroyRenderer(handle->renderer);
|
||||||
|
SDL_DestroyWindow(handle->win);
|
||||||
|
handle->win = NULL;
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright (C) 2022 Victor Suarez Rovere <suarezvictor@gmail.com>
|
||||||
|
|
||||||
|
#ifndef __SIM_FB_H__
|
||||||
|
#define __SIM_FB_H__
|
||||||
|
|
||||||
|
struct SDL_Window;
|
||||||
|
struct SDL_Renderer;
|
||||||
|
struct SDL_Texture;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SDL_Window* win;
|
||||||
|
SDL_Renderer* renderer;
|
||||||
|
SDL_Texture* texture;
|
||||||
|
} fb_handle_t;
|
||||||
|
|
||||||
|
bool fb_init(unsigned width, unsigned height, bool vsync, fb_handle_t *handle);
|
||||||
|
void fb_update(fb_handle_t *handle, const void *buf, size_t stride_bytes);
|
||||||
|
void fb_deinit(fb_handle_t *handle);
|
||||||
|
bool fb_should_quit(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
uint64_t SDL_GetPerformanceCounter(void);
|
||||||
|
uint64_t SDL_GetPerformanceFrequency(void);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline uint64_t higres_ticks() { return SDL_GetPerformanceCounter(); }
|
||||||
|
inline uint64_t higres_ticks_freq() { return SDL_GetPerformanceFrequency(); }
|
||||||
|
|
||||||
|
#endif //__SIM_FB_H__
|
|
@ -0,0 +1,205 @@
|
||||||
|
// Copyright (c) 2023 Victor Suarez Rovere <suarezvictor@gmail.com>
|
||||||
|
// Copyright (c) LiteX developers
|
||||||
|
// FIXME: add license
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "error.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <event2/listener.h>
|
||||||
|
#include <event2/util.h>
|
||||||
|
#include <event2/event.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
#include "modules.h"
|
||||||
|
#include "sim_fb.c" //from https://github.com/suarezvictor/CflexHDL/blob/main/src/sim_fb.c
|
||||||
|
|
||||||
|
struct session_s {
|
||||||
|
char *hsync;
|
||||||
|
char *vsync;
|
||||||
|
char *de;
|
||||||
|
char *valid;
|
||||||
|
char *pix_clk;
|
||||||
|
uint8_t *r;
|
||||||
|
uint8_t *g;
|
||||||
|
uint8_t *b;
|
||||||
|
short hres, vres;
|
||||||
|
short x, y;
|
||||||
|
unsigned frame, stride;
|
||||||
|
uint8_t *buf, *pbuf;
|
||||||
|
fb_handle_t fb;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int litex_sim_module_pads_get(struct pad_s *pads, char *name, void **signal)
|
||||||
|
{
|
||||||
|
int ret = RC_OK;
|
||||||
|
void *sig = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(!pads || !name || !signal) {
|
||||||
|
ret=RC_INVARG;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while(pads[i].name) {
|
||||||
|
if(!strcmp(pads[i].name, name)) {
|
||||||
|
sig = (void*)pads[i].signal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
*signal = sig;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int videosim_start(void *b)
|
||||||
|
{
|
||||||
|
printf("[video] loaded (%p)\n", (struct event_base *)b);
|
||||||
|
return RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int videosim_new(void **sess, char *args)
|
||||||
|
{
|
||||||
|
int ret = RC_OK;
|
||||||
|
struct session_s *s = NULL;
|
||||||
|
|
||||||
|
if(!sess) {
|
||||||
|
ret = RC_INVARG;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = (struct session_s*) malloc(sizeof(struct session_s));
|
||||||
|
if(!s) {
|
||||||
|
ret=RC_NOENMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
memset(s, 0, sizeof(struct session_s));
|
||||||
|
|
||||||
|
out:
|
||||||
|
*sess = (void*) s;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int videosim_add_pads(void *sess, struct pad_list_s *plist)
|
||||||
|
{
|
||||||
|
int ret = RC_OK;
|
||||||
|
struct session_s *s = (struct session_s*) sess;
|
||||||
|
struct pad_s *pads;
|
||||||
|
|
||||||
|
if(!sess || !plist) {
|
||||||
|
ret = RC_INVARG;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
pads = plist->pads;
|
||||||
|
if(!strcmp(plist->name, "vga")) {
|
||||||
|
litex_sim_module_pads_get(pads, "hsync", (void**)&s->hsync);
|
||||||
|
litex_sim_module_pads_get(pads, "vsync", (void**)&s->vsync);
|
||||||
|
litex_sim_module_pads_get(pads, "de", (void**)&s->de);
|
||||||
|
litex_sim_module_pads_get(pads, "valid", (void**)&s->valid);
|
||||||
|
litex_sim_module_pads_get(pads, "r", (void**)&s->r);
|
||||||
|
litex_sim_module_pads_get(pads, "g", (void**)&s->g);
|
||||||
|
litex_sim_module_pads_get(pads, "b", (void**)&s->b);
|
||||||
|
char *clk_pad = NULL;
|
||||||
|
litex_sim_module_pads_get(pads, "clk", (void**) &clk_pad);
|
||||||
|
if(clk_pad != NULL)
|
||||||
|
s->pix_clk = clk_pad; //overrides sys_clk if previously set
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!strcmp(plist->name, "sys_clk"))
|
||||||
|
{
|
||||||
|
if(!s->pix_clk) //not selected if vga clk was already used
|
||||||
|
litex_sim_module_pads_get(pads, "sys_clk", (void**) &s->pix_clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t *alloc_buf(unsigned short hres, unsigned short vres)
|
||||||
|
{
|
||||||
|
return (uint8_t *) malloc(hres*vres*sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int videosim_tick(void *sess, uint64_t time_ps) {
|
||||||
|
static clk_edge_state_t edge;
|
||||||
|
struct session_s *s = (struct session_s*)sess;
|
||||||
|
|
||||||
|
if(!clk_pos_edge(&edge, *s->pix_clk)) {
|
||||||
|
return RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*s->vsync)
|
||||||
|
{
|
||||||
|
if(s->y != 0) //new frame
|
||||||
|
{
|
||||||
|
if(!s->vres)
|
||||||
|
{
|
||||||
|
s->vres = s->y;
|
||||||
|
s->buf = alloc_buf(s->hres, s->vres);
|
||||||
|
//printf("[video] start, resolution %dx%d\n", s->hres, s->vres);
|
||||||
|
fb_init(s->hres, s->vres, false, &s->fb);
|
||||||
|
s->stride = s->hres*sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
s->y = 0;
|
||||||
|
s->pbuf = s->buf;
|
||||||
|
++s->frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*s->de)
|
||||||
|
{
|
||||||
|
if(s->pbuf)
|
||||||
|
{
|
||||||
|
if(*s->valid) //mitigate underflow
|
||||||
|
{
|
||||||
|
*s->pbuf++ = *s->r;
|
||||||
|
*s->pbuf++ = *s->g;
|
||||||
|
*s->pbuf++ = *s->b;
|
||||||
|
s->pbuf++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(*s->valid)
|
||||||
|
s->x = s->x + 1;
|
||||||
|
}
|
||||||
|
else if(s->x != 0)
|
||||||
|
{
|
||||||
|
if(s->buf) //update each horizontal line
|
||||||
|
{
|
||||||
|
if(fb_should_quit())
|
||||||
|
{
|
||||||
|
fb_deinit(&s->fb);
|
||||||
|
exit(1); //FIXME: end gracefully
|
||||||
|
}
|
||||||
|
fb_update(&s->fb, s->buf, s->stride);
|
||||||
|
s->pbuf = s->buf + s->y*s->stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->hres = s->x; //this is set many times until settled
|
||||||
|
if(!s->hres) //avoid initial counting
|
||||||
|
s->y = 0;
|
||||||
|
s->y = s->y + 1;
|
||||||
|
s->x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ext_module_s ext_mod = {
|
||||||
|
"video",
|
||||||
|
videosim_start,
|
||||||
|
videosim_new,
|
||||||
|
videosim_add_pads,
|
||||||
|
NULL,
|
||||||
|
videosim_tick
|
||||||
|
};
|
||||||
|
|
||||||
|
int litex_sim_ext_module_init(int (*register_module) (struct ext_module_s *))
|
||||||
|
{
|
||||||
|
int ret = RC_OK;
|
||||||
|
ret = register_module(&ext_mod);
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
# Copyright (c) 2015-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
# Copyright (c) 2015-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
# Copyright (c) 2020 Antmicro <www.antmicro.com>
|
# Copyright (c) 2020 Antmicro <www.antmicro.com>
|
||||||
# Copyright (c) 2017 Pierre-Olivier Vauboin <po@lambdaconcept>
|
# Copyright (c) 2017 Pierre-Olivier Vauboin <po@lambdaconcept>
|
||||||
|
# Copyright (c) 2023 Victor Suarez Rovere <suarezvictor@gmail.com>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
@ -124,6 +125,17 @@ _io = [
|
||||||
Subsignal("oe", Pins(32)),
|
Subsignal("oe", Pins(32)),
|
||||||
Subsignal("o", Pins(32)),
|
Subsignal("o", Pins(32)),
|
||||||
Subsignal("i", Pins(32)),
|
Subsignal("i", Pins(32)),
|
||||||
|
),
|
||||||
|
|
||||||
|
# Video
|
||||||
|
("vga", 0,
|
||||||
|
Subsignal("hsync", Pins(1)),
|
||||||
|
Subsignal("vsync", Pins(1)),
|
||||||
|
Subsignal("de", Pins(1)),
|
||||||
|
Subsignal("valid", Pins(1)),
|
||||||
|
Subsignal("r", Pins(8)),
|
||||||
|
Subsignal("g", Pins(8)),
|
||||||
|
Subsignal("b", Pins(8)),
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -133,6 +145,36 @@ class Platform(SimPlatform):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
SimPlatform.__init__(self, "SIM", _io)
|
SimPlatform.__init__(self, "SIM", _io)
|
||||||
|
|
||||||
|
# Video
|
||||||
|
from litex.soc.cores.video import video_data_layout, video_timing_layout
|
||||||
|
class VideoPHYModel(Module, AutoCSR):
|
||||||
|
def __init__(self, pads, clock_domain="sys"):
|
||||||
|
self.sink = sink = stream.Endpoint(video_data_layout)
|
||||||
|
|
||||||
|
# # #
|
||||||
|
|
||||||
|
# Always ack Sink, no backpressure.
|
||||||
|
self.comb += sink.ready.eq(1)
|
||||||
|
|
||||||
|
# Drive Clk.
|
||||||
|
if hasattr(pads, "clk"):
|
||||||
|
self.comb += pads.clk.eq(ClockSignal(clock_domain))
|
||||||
|
|
||||||
|
# Drive Controls.
|
||||||
|
self.comb += pads.valid.eq(1) #may be overriden with underflow from the framebuffer
|
||||||
|
self.comb += pads.de.eq(sink.de)
|
||||||
|
self.comb += pads.hsync.eq(sink.hsync)
|
||||||
|
self.comb += pads.vsync.eq(sink.vsync)
|
||||||
|
|
||||||
|
# Drive Datas.
|
||||||
|
cbits = len(pads.r)
|
||||||
|
cshift = (8 - cbits)
|
||||||
|
for i in range(cbits):
|
||||||
|
self.comb += pads.r[i].eq(sink.r[cshift + i] & sink.de)
|
||||||
|
self.comb += pads.g[i].eq(sink.g[cshift + i] & sink.de)
|
||||||
|
self.comb += pads.b[i].eq(sink.b[cshift + i] & sink.de)
|
||||||
|
|
||||||
|
|
||||||
# Simulation SoC -----------------------------------------------------------------------------------
|
# Simulation SoC -----------------------------------------------------------------------------------
|
||||||
|
|
||||||
class SimSoC(SoCCore):
|
class SimSoC(SoCCore):
|
||||||
|
@ -155,6 +197,8 @@ class SimSoC(SoCCore):
|
||||||
with_spi_flash = False,
|
with_spi_flash = False,
|
||||||
spi_flash_init = [],
|
spi_flash_init = [],
|
||||||
with_gpio = False,
|
with_gpio = False,
|
||||||
|
with_video_framebuffer = False,
|
||||||
|
with_video_terminal = False,
|
||||||
sim_debug = False,
|
sim_debug = False,
|
||||||
trace_reset_on = False,
|
trace_reset_on = False,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
|
@ -291,6 +335,18 @@ class SimSoC(SoCCore):
|
||||||
self.gpio = GPIOTristate(platform.request("gpio"), with_irq=True)
|
self.gpio = GPIOTristate(platform.request("gpio"), with_irq=True)
|
||||||
self.irq.add("gpio", use_loc_if_exists=True)
|
self.irq.add("gpio", use_loc_if_exists=True)
|
||||||
|
|
||||||
|
# Video Framebuffer ------------------------------------------------------------------------
|
||||||
|
if with_video_framebuffer:
|
||||||
|
video_pads = platform.request("vga")
|
||||||
|
self.submodules.videophy = VideoPHYModel(video_pads)
|
||||||
|
self.add_video_framebuffer(phy=self.videophy, timings="640x480@60Hz", format="rgb888")
|
||||||
|
self.videophy.comb += video_pads.valid.eq(~self.video_framebuffer.underflow)
|
||||||
|
|
||||||
|
# Video Terminal ---------------------------------------------------------------------------
|
||||||
|
if with_video_terminal:
|
||||||
|
self.submodules.videophy = VideoPHYModel(platform.request("vga"))
|
||||||
|
self.add_video_terminal(phy=self.videophy, timings="640x480@60Hz")
|
||||||
|
|
||||||
# Simulation debugging ----------------------------------------------------------------------
|
# Simulation debugging ----------------------------------------------------------------------
|
||||||
if sim_debug:
|
if sim_debug:
|
||||||
platform.add_debug(self, reset=1 if trace_reset_on else 0)
|
platform.add_debug(self, reset=1 if trace_reset_on else 0)
|
||||||
|
@ -400,6 +456,10 @@ def sim_args(parser):
|
||||||
# Analyzer.
|
# Analyzer.
|
||||||
parser.add_argument("--with-analyzer", action="store_true", help="Enable Analyzer support.")
|
parser.add_argument("--with-analyzer", action="store_true", help="Enable Analyzer support.")
|
||||||
|
|
||||||
|
# Video.
|
||||||
|
parser.add_argument("--with-video-framebuffer", action="store_true", help="Enable Video Framebuffer.")
|
||||||
|
parser.add_argument("--with-video-terminal", action="store_true", help="Enable Video Terminal.")
|
||||||
|
|
||||||
# Debug/Waveform.
|
# Debug/Waveform.
|
||||||
parser.add_argument("--sim-debug", action="store_true", help="Add simulation debugging modules.")
|
parser.add_argument("--sim-debug", action="store_true", help="Add simulation debugging modules.")
|
||||||
parser.add_argument("--gtkwave-savefile", action="store_true", help="Generate GTKWave savefile.")
|
parser.add_argument("--gtkwave-savefile", action="store_true", help="Generate GTKWave savefile.")
|
||||||
|
@ -476,6 +536,10 @@ def main():
|
||||||
if args.with_i2c:
|
if args.with_i2c:
|
||||||
sim_config.add_module("spdeeprom", "i2c")
|
sim_config.add_module("spdeeprom", "i2c")
|
||||||
|
|
||||||
|
# Video.
|
||||||
|
if args.with_video_framebuffer or args.with_video_terminal:
|
||||||
|
sim_config.add_module("video", "vga")
|
||||||
|
|
||||||
# SoC ------------------------------------------------------------------------------------------
|
# SoC ------------------------------------------------------------------------------------------
|
||||||
soc = SimSoC(
|
soc = SimSoC(
|
||||||
with_sdram = args.with_sdram,
|
with_sdram = args.with_sdram,
|
||||||
|
@ -488,6 +552,8 @@ def main():
|
||||||
with_sdcard = args.with_sdcard,
|
with_sdcard = args.with_sdcard,
|
||||||
with_spi_flash = args.with_spi_flash,
|
with_spi_flash = args.with_spi_flash,
|
||||||
with_gpio = args.with_gpio,
|
with_gpio = args.with_gpio,
|
||||||
|
with_video_framebuffer = args.with_video_framebuffer,
|
||||||
|
with_video_terminal = args.with_video_terminal,
|
||||||
sim_debug = args.sim_debug,
|
sim_debug = args.sim_debug,
|
||||||
trace_reset_on = int(float(args.trace_start)) > 0 or int(float(args.trace_end)) > 0,
|
trace_reset_on = int(float(args.trace_start)) > 0 or int(float(args.trace_end)) > 0,
|
||||||
spi_flash_init = None if args.spi_flash_init is None else get_mem_data(args.spi_flash_init, endianness="big"),
|
spi_flash_init = None if args.spi_flash_init is None else get_mem_data(args.spi_flash_init, endianness="big"),
|
||||||
|
|
Loading…
Reference in New Issue