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

Subversion Repositories tv80

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /tv80/trunk
    from Rev 93 to Rev 94
    Reverse comparison

Rev 93 → Rev 94

/sc_env/sc_env_top.cpp
1,7 → 1,9
#include "systemc.h"
#include "systemperl.h"
#include "env_memory.h"
#include "tv_responder.h"
#include "Vtv80s.h"
#include "SpTraceVcd.h"
 
int sc_main(int argc, char *argv[])
{
53,6 → 55,7
env_memory0.rd_n (rd_n);
env_memory0.wr_n (wr_n);
env_memory0.addr (addr);
env_memory0.reset_n (reset_n);
tv_responder tv_resp0("tv_resp0");
tv_resp0.clk (clk);
73,6 → 76,7
tv_resp0.halt_n (halt_n);
 
// create dumpfile
/*
sc_trace_file *trace_file;
trace_file = sc_create_vcd_trace_file("sc_tv80_env");
sc_trace (trace_file, clk, "clk");
91,10 → 95,28
sc_trace (trace_file, di, "di");
sc_trace (trace_file, dout, "dout");
sc_trace (trace_file, addr, "addr");
// Start Verilator traces
Verilated::traceEverOn(true);
SpTraceFile *tfp = new SpTraceFile;
tv80s.trace (tfp, 99);
tfp->open ("tv80.vcd");
*/
 
// check for command line argument
if (argc > 1) {
env_memory0.load_ihex (argv[1]);
}
// set reset to 0 before sim start
reset_n.write (0);
 
sc_start(8000);
sc_start();
/*
sc_close_vcd_trace_file (trace_file);
tfp->close();
*/
return 0;
}
/sc_env/tv_responder.h
5,6 → 5,24
 
SC_MODULE(tv_responder)
{
private:
char str_buf [256];
int buf_ptr;
int timeout_ctl;
int cur_timeout;
int max_timeout;
int int_countdown;
int nmi_countdown;
uint8_t checksum;
int ior_value; // increment-on-read value
int nmi_trigger; // trigger nmi when IR = this value
int reset_time;
bool last_iowrite;
public:
sc_in<bool> clk;
sc_out<bool> reset_n;
26,8 → 44,18
void event();
SC_CTOR(tv_responder) {
SC_THREAD(event);
SC_METHOD(event);
sensitive << clk.pos();
buf_ptr = 0;
cur_timeout = 0;
max_timeout = 10000;
timeout_ctl = 1;
int_countdown = 0;
nmi_countdown = 0;
nmi_trigger = 0;
reset_time = 16;
last_iowrite = false;
}
};
/sc_env/env_memory.cpp
6,31 → 6,43
int lcl_cs;
int ad;
// ignore activity during reset
if (!reset_n)
return;
if (!mreq_n && !wr_n && (addr < AM_DEPTH)) {
ad = (int) addr;
memory[ad] = (unsigned char) wr_data.read();
#ifdef DEBUG
printf ("Wrote %x to address %x\n", (int) wr_data.read(), ad);
//printf ("MEM WR %04x=%02x\n", ad, (int) wr_data.read());
#endif
} else if (!mreq_n && !rd_n && (addr < AM_DEPTH)) {
}
// async read output
if (addr < AM_DEPTH) {
ad = (int) addr;
rd_data.write ( (unsigned int) memory[ad] );
#ifdef DEBUG
printf ("Read %x from address %x\n", memory[ad], ad);
#endif
}
}
 
void inline readline(FILE *fh, char *buf)
int inline readline(FILE *fh, char *buf)
{
int c = 1;
int c = 1, cnt = 0;
if (feof(fh)) {
*buf = (char) 0;
return 0;
}
while (c) {
c = fread (buf, 1, 1, fh);
if (c && (*buf == '\n'))
cnt++;
if (c && (*buf == '\n')) {
buf++;
*buf = (char) 0;
c = 0;
}
else buf++;
}
return cnt;
}
 
/*
55,20 → 67,28
{
FILE *fh;
char line[80];
char *lp;
int rlen, addr, rtyp;
char *lp;
int rlen, addr, rtyp, databyte;
int rv;
int dcount = 0;
fh = fopen (filename, "r");
readline (fh, line);
while (strlen(line) > 0) {
printf ("DEBUG: strlen(line)=%d\n", strlen(line));
sscanf (line, "%2x%2x%2x", &rlen, &addr, &rtyp);
printf ("DEBUG: rlen=%d addr=%d rtyp=%d\n", rlen, addr, rtyp);
lp = line + 6;
for (int c=0; c<rlen; c++) {
}
}
rv = readline (fh, line);
while (strlen(line) > 0) {
//printf ("DEBUG: strlen(line)=%d rv=%d line=%s\n", strlen(line), rv, line);
sscanf (line, ":%02x%04x%02x", &rlen, &addr, &rtyp);
//printf ("DEBUG: rlen=%d addr=%d rtyp=%d\n", rlen, addr, rtyp);
lp = line + 9;
for (int c=0; c<rlen; c++) {
sscanf (lp, "%02x", &databyte);
lp += 2;
//printf ("DEBUG: loaded mem[%04x]=%02x\n", addr+c, databyte);
memory[addr+c] = databyte; dcount++;
}
rv = readline (fh, line);
}
fclose (fh);
printf ("ENVMEM : Read %d bytes from %s\n", dcount, filename);
}
/sc_env/env_memory.h
14,6 → 14,7
sc_in<bool> wr_n;
sc_in<uint32_t> addr;
sc_out<uint32_t> rd_data;
sc_in<bool> reset_n;
 
unsigned char *memory;
 
24,7 → 25,7
SC_CTOR(env_memory) {
memory = new unsigned char[AM_DEPTH];
SC_METHOD(event);
sensitive << clk.pos();
sensitive << clk.pos() << addr;
}
};
 
/sc_env/tv_responder.cpp
3,16 → 3,166
void tv_responder::event ()
{
// init
reset_n = 0;
//reset_n = 0;
/*
wait_n = 1;
int_n = 1;
nmi_n = 1;
busrq_n = 1;
di_resp = 0;
*/
for (int c=0; c<10; c++)
wait();
reset_n = 1;
wait();
printf ("Initialization complete.\n");
if (reset_time > 0) {
reset_n = 0;
wait_n = 1;
int_n = 1;
nmi_n = 1;
busrq_n = 1;
di_resp = 0;
reset_time--;
if (reset_time == 0)
printf ("Initialization complete.\n");
return;
} else {
if (reset_time == 0) {
reset_n = 1;
reset_time--;
}
}
if (!iorq_n & !rd_n)
{
switch (addr) {
case (0x82) : di_resp = timeout_ctl; break;
case(0x83) : di_resp = max_timeout & 0xff; break;
case(0x84) : di_resp = max_timeout >> 8; break;
 
case(0x90) : di_resp = int_countdown; break;
case(0x91) : di_resp = checksum; break;
case(0x93) : di_resp = ior_value; break;
case(0x94) : di_resp = rand(); break;
case(0x95) : di_resp = nmi_countdown; break;
case(0xA0) : di_resp = nmi_trigger; break;
default : di_resp = 0;
}
} // if (!iorq_n & !rd_n)
 
// wire wr_stb;
// reg last_iowrite;
 
// assign wr_stb = (!iorq_n & !wr_n);
// always @(posedge clk)
// begin
//last_iowrite <= #1 wr_stb;
//if (!iorq_n && !wr_n)
// printf ("DEBUG: I/O Write detected addr=%02x\n", 0xff & (int) addr.read());
if (!iorq_n && !wr_n && !last_iowrite) {
int l_dout, l_addr;
l_addr = addr.read();
l_dout = dout.read();
last_iowrite = true;
switch ( l_addr & 0xff) {
case(0x80) :
// dump control deprecated
if (l_dout == 1) {
printf ("%8d: --- TEST PASSED ---\n", 0);
sc_stop();
} else if (l_dout == 2) {
printf ("%8d: !!! TEST FAILED !!!\n", 0);
sc_stop();
}
break;
 
case(0x81) :
//printf ("%s: DEBUG : Detected write of character %x\n", sc_time_stamp().to_string(), l_dout);
//cout << sc_time_stamp().to_string() << "DEBUG : Detected write of character " << l_dout << endl;
if (l_dout == 0x0A) {
//printf ("%8d: PROGRAM : ", sc_simulation_time());
cout << sc_time_stamp() << ": PROGRAM : ";
 
for (int i=0; i<buf_ptr; i=i+1)
//printf ("%s", str_buf[i]);
cout << str_buf[i];
//printf ("\n");
cout << endl;
buf_ptr = 0;
} else {
str_buf[buf_ptr] = (char) (l_dout & 0xff);
buf_ptr = buf_ptr + 1;
}
break;
 
case(0x82) :
timeout_ctl = l_dout;
break;
 
case(0x83) :
max_timeout = l_dout | (max_timeout & 0xFF00);
break;
case(0x84) :
max_timeout = l_dout << 8 | (max_timeout & 0x00FF);
break;
 
case(0x90) : int_countdown = dout; break;
case(0x91) : checksum = dout; break;
case(0x92) : checksum = checksum + dout; break;
case(0x93) : ior_value = dout; break;
case(0x95) : nmi_countdown = dout; break;
case(0xA0) : nmi_trigger = dout; break;
}
} else if (iorq_n)
last_iowrite = false;
 
if (timeout_ctl & 0x2)
cur_timeout = 0;
else if (timeout_ctl & 0x1)
cur_timeout = cur_timeout + 1;
 
if (cur_timeout >= max_timeout) {
printf ("%8d: ERROR : Reached timeout %d cycles\n", 0, max_timeout);
//tb_top.test_fail;
sc_stop();
}
 
if (int_countdown == 0) {
int_n = 1;
} else if (int_countdown == 1)
int_n = 0;
else if (int_countdown > 1) {
int_countdown = int_countdown - 1;
int_n = 1;
}
 
// when nmi countdown reaches 1, an NMI will be issued.
// to clear the interrupt, write nmi_countdown to 0.
if ((nmi_countdown == 0) && (nmi_trigger == 0))
nmi_n = 1;
else if (nmi_countdown == 1)
nmi_n = 0;
else if (nmi_countdown > 1) {
nmi_countdown = nmi_countdown - 1;
nmi_n = 1;
}
 
// when IR equals the target instruction, an NMI will be
// issued. To clear the interrupt, write nmi_trigger to
// zero.
/* can't do this in systemc
if (nmi_trigger != 0) {
if (nmi_trigger === tb_top.tv80s_inst.i_tv80_core.IR[7:0])
begin
tb_top.nmi_n <= #80 0;
tb_top.nmi_n <= #160 1;
end
} else if (nmi_countdown == 0)
nmi_n = 1;
*/
}
/sc_env/Makefile
1,13 → 1,17
SYSTEMC=/opt/systemc
VERILATOR_ROOT = /opt/verilator/share/verilator
VERIDIR=../obj_dir
INCLUDES=-I$(SYSTEMC)/include -I$(VERIDIR) -I$(VERILATOR_ROOT)/include
INCLUDES=-I$(SYSTEMC)/include -I$(VERIDIR) -I$(VERILATOR_ROOT)/include -I$(SYSTEMPERL)
LINKOPT=-L$(SYSTEMC)/lib-linux64 -lsystemc -lm
DEFINES=-DDEBUG
OBJFILES=sc_env_top.o env_memory.o tv_responder.o \
$(VERIDIR)/Vtv80s.o $(VERIDIR)/Vtv80s__Syms.o verilated.o
$(VERIDIR)/Vtv80s.o $(VERIDIR)/Vtv80s__Syms.o \
$(VERIDIR)/Vtv80s__Trace.o \
$(VERIDIR)/Vtv80s__Trace__Slow.o \
verilated.o Sp.o
OPT_FAST=-O2
 
CXX=g++ -g $(INCLUDES) $(DEFINES)
CXX=g++ -g $(OPT_FAST) $(INCLUDES) $(DEFINES)
 
all: sc_env_top
 
21,11 → 25,23
$(CXX) -c $^
 
$(VERIDIR)/Vtv80s.o:
(cd $(VERIDIR); make -f Vtv80s.mk Vtv80s.o)
make OPT_FAST="$(OPT_FAST)" -f $(VERIDIR)/Vtv80s.mk -C $(VERIDIR) Vtv80s.o
#(cd $(VERIDIR); make -f Vtv80s.mk Vtv80s.o)
 
$(VERIDIR)/Vtv80s__Syms.o:
(cd $(VERIDIR); make -f Vtv80s.mk Vtv80s__Syms.o)
make OPT_FAST="$(OPT_FAST)" -f $(VERIDIR)/Vtv80s.mk -C $(VERIDIR) Vtv80s__Syms.o
#(cd $(VERIDIR); make -f Vtv80s.mk Vtv80s__Syms.o)
 
$(VERIDIR)/Vtv80s__Trace.o:
(cd $(VERIDIR); make -f Vtv80s.mk Vtv80s__Trace.o)
 
$(VERIDIR)/Vtv80s__Trace__Slow.o:
(cd $(VERIDIR); make -f Vtv80s.mk Vtv80s__Trace__Slow.o)
 
Sp.o: $(SYSTEMPERL)/Sp.cpp
$(CXX) -I$(SYSTEMPERL) -c $^
 
clean:
rm -f *.o
rm -f ../obj_dir/*.o
 

powered by: WebSVN 2.1.0

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