OpenCores
URL https://opencores.org/ocsvn/openarty/openarty/trunk

Subversion Repositories openarty

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openarty/trunk
    from Rev 27 to Rev 28
    Reverse comparison

Rev 27 → Rev 28

/bench/cpp/uartsim.cpp
4,7 → 4,7
//
// Project: XuLA2-LX25 SoC based upon the ZipCPU
//
// Purpose:
// Purpose: To forward a Verilator simulated UART link over a TCP/IP pipe.
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
44,6 → 44,7
#include <unistd.h>
#include <arpa/inet.h>
#include <signal.h>
#include <ctype.h>
 
#include "uartsim.h"
 
72,6 → 73,8
 
memset(&my_addr, 0, sizeof(struct sockaddr_in)); // clear structure
my_addr.sin_family = AF_INET;
// Use *all* internet ports to this computer, allowing connections from
// any/every one of them.
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
my_addr.sin_port = htons(port);
87,9 → 90,13
}
 
UARTSIM::UARTSIM(const int port) {
m_con = m_skt = -1;
setup_listener(port);
setup(25);
m_conrd = m_conwr = m_skt = -1;
if (port == 0) {
m_conrd = STDIN_FILENO;
m_conwr = STDOUT_FILENO;
} else
setup_listener(port);
setup(25); // Set us up for (default) 8N1 w/ a baud rate of CLK/25
m_rx_baudcounter = 0;
m_tx_baudcounter = 0;
m_rx_state = RXIDLE;
98,8 → 105,11
 
void UARTSIM::kill(void) {
// Close any active connection
if (m_con >= 0) close(m_con);
if (m_conrd >= 0) close(m_conrd);
if ((m_conwr >= 0)&&(m_conwr != m_conrd)) close(m_conwr);
if (m_skt >= 0) close(m_skt);
 
m_conrd = m_conwr = m_skt = -1;
}
 
void UARTSIM::setup(unsigned isetup) {
114,10 → 124,10
}
}
 
int UARTSIM::tick(int i_tx) {
int UARTSIM::nettick(int i_tx) {
int o_rx = 1;
 
if (m_con < 0) {
if ((m_conrd < 0)&&(m_conwr<0)&&(m_skt>=0)) {
// Can we accept a connection?
struct pollfd pb;
 
126,9 → 136,10
poll(&pb, 1, 0);
 
if (pb.revents & POLLIN) {
m_con = accept(m_skt, 0, 0);
m_conrd = accept(m_skt, 0, 0);
m_conwr = m_conrd;
 
if (m_con < 0)
if (m_conrd < 0)
perror("Accept failed:");
}
}
141,7 → 152,7
if (m_rx_state == RXIDLE) {
if (!i_tx) {
m_rx_state = RXDATA;
m_rx_baudcounter =m_baud_counts+m_baud_counts/2;
m_rx_baudcounter =m_baud_counts+m_baud_counts/2-1;
m_rx_baudcounter -= m_rx_changectr;
m_rx_busy = 0;
m_rx_data = 0;
149,12 → 160,12
} else if (m_rx_baudcounter <= 0) {
if (m_rx_busy >= (1<<(m_nbits+m_nparity+m_nstop-1))) {
m_rx_state = RXIDLE;
if (m_con > 0) {
if (m_conwr >= 0) {
char buf[1];
buf[0] = (m_rx_data >> (32-m_nbits-m_nstop-m_nparity))&0x0ff;
if (1 != send(m_con, buf, 1, 0)) {
close(m_con);
m_con = -1;
if (1 != send(m_conwr, buf, 1, 0)) {
close(m_conwr);
m_conrd = m_conwr = -1;
}
}
} else {
171,28 → 182,31
// stop bit
// (possible secondary stop bit)
m_rx_data = ((i_tx&1)<<31) | (m_rx_data>>1);
} m_rx_baudcounter = m_baud_counts;
} m_rx_baudcounter = m_baud_counts-1;
} else
m_rx_baudcounter--;
 
if (m_tx_state == TXIDLE) {
struct pollfd pb;
pb.fd = m_con;
pb.fd = m_conrd;
pb.events = POLLIN;
if (poll(&pb, 1, 0) < 0)
perror("Polling error:");
if (pb.revents & POLLIN) {
char buf[1];
if (1 == recv(m_con, buf, 1, MSG_DONTWAIT)) {
if (1 == recv(m_conrd, buf, 1, MSG_DONTWAIT)) {
m_tx_data = (-1<<(m_nbits+m_nparity+1))
// << nstart_bits
|((buf[0]<<1)&0x01fe);
if (m_nparity) {
int p;
 
// If m_nparity is set, we need to then
// create the parity bit.
if (m_fixdp)
p = m_evenp;
else {
int p = (m_tx_data >> 1)&0x0ff;
p = (m_tx_data >> 1)&0x0ff;
p = p ^ (p>>4);
p = p ^ (p>>2);
p = p ^ (p>>1);
204,9 → 218,112
m_tx_busy = (1<<(m_nbits+m_nparity+m_nstop+1))-1;
m_tx_state = TXDATA;
o_rx = 0;
m_tx_baudcounter = m_baud_counts;
m_tx_baudcounter = m_baud_counts-1;
}
}
} else if (m_tx_baudcounter <= 0) {
m_tx_data >>= 1;
m_tx_busy >>= 1;
if (!m_tx_busy)
m_tx_state = TXIDLE;
else
m_tx_baudcounter = m_baud_counts-1;
o_rx = m_tx_data&1;
} else {
m_tx_baudcounter--;
o_rx = m_tx_data&1;
}
 
return o_rx;
}
 
int UARTSIM::fdtick(int i_tx) {
int o_rx = 1;
 
if ((!i_tx)&&(m_last_tx))
m_rx_changectr = 0;
else m_rx_changectr++;
m_last_tx = i_tx;
 
if (m_rx_state == RXIDLE) {
if (!i_tx) {
m_rx_state = RXDATA;
m_rx_baudcounter =m_baud_counts+m_baud_counts/2-1;
m_rx_baudcounter -= m_rx_changectr;
m_rx_busy = 0;
m_rx_data = 0;
}
} else if (m_rx_baudcounter <= 0) {
if (m_rx_busy >= (1<<(m_nbits+m_nparity+m_nstop-1))) {
m_rx_state = RXIDLE;
if (m_conwr >= 0) {
char buf[1];
buf[0] = (m_rx_data >> (32-m_nbits-m_nstop-m_nparity))&0x0ff;
if (1 != write(m_conwr, buf, 1)) {
fprintf(stderr, "ERR while attempting to write out--closing output port\n");
perror("UARTSIM::write() ");
m_conrd = m_conwr = -1;
}
}
} else {
m_rx_busy = (m_rx_busy << 1)|1;
// Low order bit is transmitted first, in this
// order:
// Start bit (1'b1)
// bit 0
// bit 1
// bit 2
// ...
// bit N-1
// (possible parity bit)
// stop bit
// (possible secondary stop bit)
m_rx_data = ((i_tx&1)<<31) | (m_rx_data>>1);
} m_rx_baudcounter = m_baud_counts-1;
} else
m_rx_baudcounter--;
 
if ((m_tx_state == TXIDLE)&&(m_conrd >= 0)) {
struct pollfd pb;
pb.fd = m_conrd;
pb.events = POLLIN;
if (poll(&pb, 1, 0) < 0)
perror("Polling error:");
if (pb.revents & POLLIN) {
char buf[1];
int nr;
if (1==(nr = read(m_conrd, buf, 1))) {
m_tx_data = (-1<<(m_nbits+m_nparity+1))
// << nstart_bits
|((buf[0]<<1)&0x01fe);
if (m_nparity) {
int p;
 
// If m_nparity is set, we need to then
// create the parity bit.
if (m_fixdp)
p = m_evenp;
else {
p = (m_tx_data >> 1)&0x0ff;
p = p ^ (p>>4);
p = p ^ (p>>2);
p = p ^ (p>>1);
p &= 1;
p ^= m_evenp;
}
m_tx_data |= (p<<(m_nbits+m_nparity));
}
m_tx_busy = (1<<(m_nbits+m_nparity+m_nstop+1))-1;
m_tx_state = TXDATA;
o_rx = 0;
m_tx_baudcounter = m_baud_counts-1;
} else if (nr < 0) {
fprintf(stderr, "ERR while attempting to read in--closing input port\n");
perror("UARTSIM::read() ");
m_conrd = -1;
} // and we really don't care if nr == 0 except that
// the poll above is supposed to keep it from happening
}
} else if (m_tx_baudcounter == 0) {
m_tx_data >>= 1;
m_tx_busy >>= 1;
213,7 → 330,7
if (!m_tx_busy)
m_tx_state = TXIDLE;
else
m_tx_baudcounter = m_baud_counts;
m_tx_baudcounter = m_baud_counts-1;
o_rx = m_tx_data&1;
} else {
m_tx_baudcounter--;
/bench/cpp/uartsim.h
4,8 → 4,11
//
// Project: XuLA2-LX25 SoC based upon the ZipCPU
//
// Purpose:
// Purpose: To forward a Verilator simulated UART link over a TCP/IP pipe.
//
// This file provides the description of the interface between the UARTSIM
// and the rest of the world. See below for more detailed descriptions.
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
54,23 → 57,74
#define RXDATA 1
 
class UARTSIM {
int m_skt, m_con;
// The file descriptors:
// m_skt is the socket/port we are listening on
// m_conrd is the file descriptor to read from
// m_conwr is the file descriptor to write to
int m_skt, m_conrd, m_conwr;
//
// The m_setup register is the 29'bit control register used within
// the core.
unsigned m_setup;
// And the pieces of the setup register broken out.
int m_nparity, m_fixdp, m_evenp, m_nbits, m_nstop, m_baud_counts;
 
// UART state
int m_rx_baudcounter, m_rx_state, m_rx_busy,
m_rx_changectr, m_last_tx;
int m_tx_baudcounter, m_tx_state, m_tx_busy;
unsigned m_rx_data, m_tx_data;
 
// setup_listener is an attempt to encapsulate all of the network
// related setup stuff.
void setup_listener(const int port);
int tick(const int i_tx);
 
// nettick() gets called if we are connected to a network, and
int nettick(const int i_tx);
// fdtick() if we are not.
int fdtick(const int i_tx);
 
// We'll use the file descriptor for the listener socket to determine
// whether we are connected to the network or not. If not connected
// to the network, then we assume m_conrd and m_conwr refer to
// your more traditional file descriptors, and use them as such.
int tick(const int i_tx) {
if (m_skt >= 0)
return nettick(i_tx);
else
return fdtick(i_tx);
}
 
public:
//
// The UARTSIM constructor takes one argument: the port on the
// localhost to listen in on. Once started, connections may be made
// to this port to get the output from the port.
UARTSIM(const int port);
 
// kill() closes any active connection and the socket. Once killed,
// no further output will be sent to the port.
void kill(void);
 
// setup() busts out the bits from isetup to the various internal
// parameters. It is ideally only called between bits at appropriate
// transition intervals.
void setup(unsigned isetup);
 
// The operator() function is called on every tick. The input is the
// the output txuart transmit wire from the device. The output is to
// be connected to the the rxuart receive wire into the device. This
// makes hookup and operation very simple.
//
// This is the most appropriate simulation entry function if the
// setup register will never change.
//
int operator()(int i_tx) {
return tick(i_tx); }
 
// If there is a possibility that the core might change the UART setup,
// then it makes sense to include that current setup when calling the
// tick operator.
int operator()(int i_tx, unsigned isetup) {
setup(isetup); return tick(i_tx); }
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.