mibuild/sim: add support for pty

This commit is contained in:
Florent Kermarrec 2015-03-09 23:31:11 +01:00
parent aa609bee15
commit 70a3e8081c
2 changed files with 97 additions and 16 deletions

View File

@ -47,12 +47,16 @@ struct sim {
clock_t end;
float speed;
#ifdef WITH_SERIAL
#ifndef WITH_SERIAL_PTY
char rx_serial_stb;
char rx_serial_data;
char rx_serial_presented;
#else
const char *serial_dev;
int serial_fd;
unsigned char serial_rx_data;
unsigned char serial_tx_data;
#endif
#ifdef WITH_ETH
const char *eth_dev;
const char *eth_tap;
@ -67,7 +71,7 @@ struct sim {
};
/* Serial functions */
#ifdef WITH_SERIAL
#ifndef WITH_SERIAL_PTY
struct termios orig_termios;
void reset_terminal_mode(void)
@ -155,12 +159,12 @@ int eth_close(struct sim *s)
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];
@ -183,7 +187,7 @@ int eth_read_tap (struct sim *s, unsigned char *buf)
Vdut* dut;
VerilatedVcdC* tfp;
#ifdef WITH_SERIAL
#ifndef WITH_SERIAL_PTY
int console_service(struct sim *s)
{
/* fpga --> console */
@ -211,6 +215,64 @@ int console_service(struct sim *s)
}
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
#ifdef WITH_ETH
@ -222,7 +284,7 @@ int ethernet_service(struct sim *s) {
s->eth_txbuffer_len++;
} else {
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;
}
}
@ -232,7 +294,7 @@ int ethernet_service(struct sim *s) {
if (s->eth_rxbuffer_len == 0) {
ETH_SINK_STB = 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 {
if (s->eth_rxbuffer_pos < MAX(s->eth_rxbuffer_len, 60)) {
ETH_SINK_STB = 1;
@ -274,7 +336,9 @@ int main(int argc, char **argv, char **env)
{
float speed;
#ifndef WITH_SERIAL_PTY
set_conio_terminal_mode();
#endif
Verilated::commandArgs(argc, argv);
dut = new Vdut;
@ -287,8 +351,12 @@ int main(int argc, char **argv, char **env)
struct sim s;
sim_init(&s);
#ifdef WITH_SERIAL_PTY
console_open(&s, "/dev/pts/3"); // XXX get this from /tmp/simserial
#endif
#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);
#endif
@ -311,8 +379,15 @@ int main(int argc, char **argv, char **env)
printf("average speed: %3.3f MHz\n\r", speed/1000000);
tfp->close();
#ifdef WITH_SERIAL_PTY
console_close(&s);
#endif
#ifdef WITH_ETH
eth_close(&s);
#endif
exit(0);
}

View File

@ -7,7 +7,7 @@ from migen.fhdl.std import *
from migen.fhdl.structure import _Fragment
from mibuild.generic_platform import *
def _build_tb(platform, template):
def _build_tb(platform, serial, template):
def io_name(ressource, subsignal=None):
res = platform.lookup_request(ressource)
@ -19,6 +19,12 @@ def _build_tb(platform, template):
#define SYS_CLK dut->{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:
ios += """
#define SERIAL_SOURCE_STB dut->{serial_source_stb}
@ -73,7 +79,7 @@ def _build_tb(platform, template):
f.close()
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 = ""
for path in include_paths:
include += "-I"+path+" "
@ -89,7 +95,7 @@ make -j -C obj_dir/ -f Vdut.mk Vdut
build_script_file = "build_" + build_name + ".sh"
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:
r = subprocess.call(["bash", build_script_file])
else:
@ -109,7 +115,7 @@ def _run_sim(build_name):
class VerilatorPlatform(GenericPlatform):
# XXX fir sim_path
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):
tools.mkdir_noerror(build_dir)
os.chdir(build_dir)
@ -129,7 +135,7 @@ class VerilatorPlatform(GenericPlatform):
if path not in include_paths:
include_paths.append(path)
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:
_run_sim(build_name)