mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
mibuild/sim: add support for pty
This commit is contained in:
parent
aa609bee15
commit
70a3e8081c
2 changed files with 97 additions and 16 deletions
|
@ -47,12 +47,16 @@ struct sim {
|
||||||
clock_t end;
|
clock_t end;
|
||||||
float speed;
|
float speed;
|
||||||
|
|
||||||
#ifdef WITH_SERIAL
|
#ifndef WITH_SERIAL_PTY
|
||||||
char rx_serial_stb;
|
char rx_serial_stb;
|
||||||
char rx_serial_data;
|
char rx_serial_data;
|
||||||
char rx_serial_presented;
|
char rx_serial_presented;
|
||||||
|
#else
|
||||||
|
const char *serial_dev;
|
||||||
|
int serial_fd;
|
||||||
|
unsigned char serial_rx_data;
|
||||||
|
unsigned char serial_tx_data;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_ETH
|
#ifdef WITH_ETH
|
||||||
const char *eth_dev;
|
const char *eth_dev;
|
||||||
const char *eth_tap;
|
const char *eth_tap;
|
||||||
|
@ -67,7 +71,7 @@ struct sim {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Serial functions */
|
/* Serial functions */
|
||||||
#ifdef WITH_SERIAL
|
#ifndef WITH_SERIAL_PTY
|
||||||
struct termios orig_termios;
|
struct termios orig_termios;
|
||||||
|
|
||||||
void reset_terminal_mode(void)
|
void reset_terminal_mode(void)
|
||||||
|
@ -155,12 +159,12 @@ int eth_close(struct sim *s)
|
||||||
close(s->eth_fd);
|
close(s->eth_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eth_write_tap(struct sim *s, unsigned char *buf, int len)
|
void eth_write(struct sim *s, unsigned char *buf, int len)
|
||||||
{
|
{
|
||||||
write (s->eth_fd, buf, len);
|
write(s->eth_fd, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int eth_read_tap (struct sim *s, unsigned char *buf)
|
int eth_read(struct sim *s, unsigned char *buf)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct pollfd fds[1];
|
struct pollfd fds[1];
|
||||||
|
@ -183,7 +187,7 @@ int eth_read_tap (struct sim *s, unsigned char *buf)
|
||||||
Vdut* dut;
|
Vdut* dut;
|
||||||
VerilatedVcdC* tfp;
|
VerilatedVcdC* tfp;
|
||||||
|
|
||||||
#ifdef WITH_SERIAL
|
#ifndef WITH_SERIAL_PTY
|
||||||
int console_service(struct sim *s)
|
int console_service(struct sim *s)
|
||||||
{
|
{
|
||||||
/* fpga --> console */
|
/* fpga --> console */
|
||||||
|
@ -211,6 +215,64 @@ int console_service(struct sim *s)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void console_open(struct sim *s, const char *dev)
|
||||||
|
{
|
||||||
|
s->serial_fd = open(dev, O_RDWR);
|
||||||
|
if(s->serial_fd < 0) {
|
||||||
|
fprintf (stderr, " Could not open dev %s\n", s->serial_dev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int console_close(struct sim *s)
|
||||||
|
{
|
||||||
|
if (s->serial_fd < 0)
|
||||||
|
close(s->serial_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_write(struct sim *s, unsigned char *buf, int len)
|
||||||
|
{
|
||||||
|
write(s->serial_fd, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int console_read(struct sim *s, unsigned char *buf)
|
||||||
|
{
|
||||||
|
struct pollfd fds[1];
|
||||||
|
int n;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
fds[0].fd = s->serial_fd;
|
||||||
|
fds[0].events = POLLIN;
|
||||||
|
|
||||||
|
n = poll(fds, 1, 0);
|
||||||
|
if ((n > 0) && ((fds[0].revents & POLLIN) == POLLIN)) {
|
||||||
|
len = read(s->serial_fd, buf, 1);
|
||||||
|
} else {
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int console_service(struct sim *s)
|
||||||
|
{
|
||||||
|
/* fpga --> console */
|
||||||
|
SERIAL_SOURCE_ACK = 1;
|
||||||
|
if(SERIAL_SOURCE_STB == 1) {
|
||||||
|
s->serial_tx_data = SERIAL_SOURCE_DATA;
|
||||||
|
console_write(s, &(s->serial_tx_data), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* console --> fpga */
|
||||||
|
SERIAL_SINK_STB = 0;
|
||||||
|
if (console_read(s, &(s->serial_rx_data)))
|
||||||
|
{
|
||||||
|
SERIAL_SINK_STB = 1;
|
||||||
|
SERIAL_SINK_DATA = s->serial_rx_data;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_ETH
|
#ifdef WITH_ETH
|
||||||
|
@ -222,7 +284,7 @@ int ethernet_service(struct sim *s) {
|
||||||
s->eth_txbuffer_len++;
|
s->eth_txbuffer_len++;
|
||||||
} else {
|
} else {
|
||||||
if (s->eth_last_source_stb) {
|
if (s->eth_last_source_stb) {
|
||||||
eth_write_tap(s, s->eth_txbuffer, s->eth_txbuffer_len);
|
eth_write(s, s->eth_txbuffer, s->eth_txbuffer_len);
|
||||||
s->eth_txbuffer_len = 0;
|
s->eth_txbuffer_len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +294,7 @@ int ethernet_service(struct sim *s) {
|
||||||
if (s->eth_rxbuffer_len == 0) {
|
if (s->eth_rxbuffer_len == 0) {
|
||||||
ETH_SINK_STB = 0;
|
ETH_SINK_STB = 0;
|
||||||
s->eth_rxbuffer_pos = 0;
|
s->eth_rxbuffer_pos = 0;
|
||||||
s->eth_rxbuffer_len = eth_read_tap(s, s->eth_rxbuffer);
|
s->eth_rxbuffer_len = eth_read(s, s->eth_rxbuffer);
|
||||||
} else {
|
} else {
|
||||||
if (s->eth_rxbuffer_pos < MAX(s->eth_rxbuffer_len, 60)) {
|
if (s->eth_rxbuffer_pos < MAX(s->eth_rxbuffer_len, 60)) {
|
||||||
ETH_SINK_STB = 1;
|
ETH_SINK_STB = 1;
|
||||||
|
@ -274,7 +336,9 @@ int main(int argc, char **argv, char **env)
|
||||||
{
|
{
|
||||||
float speed;
|
float speed;
|
||||||
|
|
||||||
|
#ifndef WITH_SERIAL_PTY
|
||||||
set_conio_terminal_mode();
|
set_conio_terminal_mode();
|
||||||
|
#endif
|
||||||
|
|
||||||
Verilated::commandArgs(argc, argv);
|
Verilated::commandArgs(argc, argv);
|
||||||
dut = new Vdut;
|
dut = new Vdut;
|
||||||
|
@ -287,8 +351,12 @@ int main(int argc, char **argv, char **env)
|
||||||
struct sim s;
|
struct sim s;
|
||||||
sim_init(&s);
|
sim_init(&s);
|
||||||
|
|
||||||
|
#ifdef WITH_SERIAL_PTY
|
||||||
|
console_open(&s, "/dev/pts/3"); // XXX get this from /tmp/simserial
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_ETH
|
#ifdef WITH_ETH
|
||||||
eth_init(&s, "/dev/net/tap0", "tap0");
|
eth_init(&s, "/dev/net/tap0", "tap0"); // XXX get this from /tmp/simethernet
|
||||||
eth_open(&s);
|
eth_open(&s);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -311,8 +379,15 @@ int main(int argc, char **argv, char **env)
|
||||||
|
|
||||||
printf("average speed: %3.3f MHz\n\r", speed/1000000);
|
printf("average speed: %3.3f MHz\n\r", speed/1000000);
|
||||||
|
|
||||||
|
|
||||||
tfp->close();
|
tfp->close();
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WITH_SERIAL_PTY
|
||||||
|
console_close(&s);
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_ETH
|
||||||
|
eth_close(&s);
|
||||||
|
#endif
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ from migen.fhdl.std import *
|
||||||
from migen.fhdl.structure import _Fragment
|
from migen.fhdl.structure import _Fragment
|
||||||
from mibuild.generic_platform import *
|
from mibuild.generic_platform import *
|
||||||
|
|
||||||
def _build_tb(platform, template):
|
def _build_tb(platform, serial, template):
|
||||||
|
|
||||||
def io_name(ressource, subsignal=None):
|
def io_name(ressource, subsignal=None):
|
||||||
res = platform.lookup_request(ressource)
|
res = platform.lookup_request(ressource)
|
||||||
|
@ -19,6 +19,12 @@ def _build_tb(platform, template):
|
||||||
#define SYS_CLK dut->{sys_clk}
|
#define SYS_CLK dut->{sys_clk}
|
||||||
""".format(sys_clk=io_name("sys_clk"))
|
""".format(sys_clk=io_name("sys_clk"))
|
||||||
|
|
||||||
|
if serial == "pty":
|
||||||
|
ios += "#define WITH_SERIAL_PTY"
|
||||||
|
elif serial == "console":
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise ValueError
|
||||||
try:
|
try:
|
||||||
ios += """
|
ios += """
|
||||||
#define SERIAL_SOURCE_STB dut->{serial_source_stb}
|
#define SERIAL_SOURCE_STB dut->{serial_source_stb}
|
||||||
|
@ -73,7 +79,7 @@ def _build_tb(platform, template):
|
||||||
f.close()
|
f.close()
|
||||||
tools.write_to_file("dut_tb.cpp", content)
|
tools.write_to_file("dut_tb.cpp", content)
|
||||||
|
|
||||||
def _build_sim(platform, build_name, include_paths, sim_path, dut, verbose):
|
def _build_sim(platform, build_name, include_paths, sim_path, serial, verbose):
|
||||||
include = ""
|
include = ""
|
||||||
for path in include_paths:
|
for path in include_paths:
|
||||||
include += "-I"+path+" "
|
include += "-I"+path+" "
|
||||||
|
@ -89,7 +95,7 @@ make -j -C obj_dir/ -f Vdut.mk Vdut
|
||||||
build_script_file = "build_" + build_name + ".sh"
|
build_script_file = "build_" + build_name + ".sh"
|
||||||
tools.write_to_file(build_script_file, build_script_contents, force_unix=True)
|
tools.write_to_file(build_script_file, build_script_contents, force_unix=True)
|
||||||
|
|
||||||
_build_tb(platform, os.path.join("../", sim_path, dut + ".cpp")) # XXX
|
_build_tb(platform, serial, os.path.join("../", sim_path,"dut_tb.cpp"))
|
||||||
if verbose:
|
if verbose:
|
||||||
r = subprocess.call(["bash", build_script_file])
|
r = subprocess.call(["bash", build_script_file])
|
||||||
else:
|
else:
|
||||||
|
@ -109,7 +115,7 @@ def _run_sim(build_name):
|
||||||
class VerilatorPlatform(GenericPlatform):
|
class VerilatorPlatform(GenericPlatform):
|
||||||
# XXX fir sim_path
|
# XXX fir sim_path
|
||||||
def build(self, soc, build_dir="build", build_name="top",
|
def build(self, soc, build_dir="build", build_name="top",
|
||||||
sim_path="../migen/mibuild/sim/", dut="dut_tb",
|
sim_path="../migen/mibuild/sim/", serial="console",
|
||||||
run=True, verbose=False):
|
run=True, verbose=False):
|
||||||
tools.mkdir_noerror(build_dir)
|
tools.mkdir_noerror(build_dir)
|
||||||
os.chdir(build_dir)
|
os.chdir(build_dir)
|
||||||
|
@ -129,7 +135,7 @@ class VerilatorPlatform(GenericPlatform):
|
||||||
if path not in include_paths:
|
if path not in include_paths:
|
||||||
include_paths.append(path)
|
include_paths.append(path)
|
||||||
include_paths += self.verilog_include_paths
|
include_paths += self.verilog_include_paths
|
||||||
_build_sim(self, build_name, include_paths, sim_path, dut, verbose)
|
_build_sim(self, build_name, include_paths, sim_path, serial, verbose)
|
||||||
|
|
||||||
if run:
|
if run:
|
||||||
_run_sim(build_name)
|
_run_sim(build_name)
|
||||||
|
|
Loading…
Reference in a new issue