1
0
mirror of synced 2026-02-27 01:00:10 +00:00

added pli code

This commit is contained in:
brad
2010-04-13 14:02:34 +00:00
parent e91720db24
commit a04447387a
7 changed files with 1823 additions and 0 deletions

20
pli/ide/Makefile Normal file
View File

@@ -0,0 +1,20 @@
#
INCS = -I../../cver/gplcver-2.12a.src/pli_incs
CFLAGS= -fPIC -Wall -g $(INCS) -D__CVER__
LFLAGS= -G -shared -export-dynamic
all: pli_ide.so pli_ide.vpi
pli_ide.o: pli_ide.c
$(CC) $(CFLAGS) -c pli_ide.c
pli_ide.so: pli_ide.o
$(LD) $(LFLAGS) pli_ide.o -o pli_ide.so
pli_ide.vpi: pli_ide.o
$(LD) $(LFLAGS) pli_ide.o -o pli_ide.vpi
clean:
rm -f *.o *.so *.vpi

406
pli/ide/pli_ide.c Normal file
View File

@@ -0,0 +1,406 @@
/* pli_ide.c */
/*
* simple IDE/ATA drive bus level emulation
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#ifdef unix
#include <unistd.h>
#endif
#ifdef _WIN32
typedef int off_t;
#endif
#include "vpi_user.h"
#ifdef __CVER__
#include "cv_vpi_user.h"
#endif
#ifdef __MODELSIM__
#include "veriuser.h"
#endif
PLI_INT32 pli_ide(void);
extern void register_my_systfs(void);
extern void register_my_systfs(void);
char *instnam_tab[10];
int last_evh;
char last_dior_bit;
char last_diow_bit;
static struct state_s {
vpiHandle bus_aref;
unsigned short reg_seccnt, reg_secnum, reg_cyllow, reg_cylhigh, reg_drvhead;
unsigned short status;
int fifo_rd;
int fifo_wr;
int fifo_depth;
unsigned short fifo[256 * 64];
int file_inited;
int file_fd;
unsigned int lba;
} state[10];
static int getadd_inst_id(vpiHandle mhref)
{
register int i;
char *chp;
chp = vpi_get_str(vpiFullName, mhref);
//vpi_printf("getadd_inst_id() %s\n", chp);
for (i = 1; i <= last_evh; i++) {
if (strcmp(instnam_tab[i], chp) == 0)
return(i);
}
instnam_tab[++last_evh] = malloc(strlen(chp) + 1);
strcpy(instnam_tab[last_evh], chp);
//vpi_printf("getadd_inst_id() done %d\n", last_evh);
return(last_evh);
}
#define ATA_ALTER 0x0e
#define ATA_DEVCTRL 0x1e
#define ATA_DATA 0x10
#define ATA_ERROR 0x11
#define ATA_FEATURE 0x11
#define ATA_SECCNT 0x12
#define ATA_SECNUM 0x13
#define ATA_CYLLOW 0x14
#define ATA_CYLHIGH 0x15
#define ATA_DRVHEAD 0x16
#define ATA_STATUS 0x17
#define ATA_COMMAND 0x17
#define IDE_STATUS_BSY 7
#define IDE_STATUS_DRDY 6
#define IDE_STATUS_DWF 5
#define IDE_STATUS_DSC 4
#define IDE_STATUS_DRQ 3
#define IDE_STATUS_CORR 2
#define IDE_STATUS_IDX 1
#define IDE_STATUS_ERR 0
#define ATA_CMD_READ 0x0020
#define ATA_CMD_WRITE 0x0030
static void
do_ide_setup(struct state_s *s)
{
s->file_fd = open("rf.dsk", O_RDWR);
s->status = (1<<IDE_STATUS_DRDY)|(1<<IDE_STATUS_DSC);
s->fifo_depth = 0;
s->fifo_rd = 0;
s->fifo_wr = 0;
}
static void
do_ide_read(struct state_s *s)
{
int ret;
s->lba =
((s->reg_drvhead & 0x0f) << 24) |
((s->reg_cylhigh & 0xff) << 16) |
((s->reg_cyllow & 0xff) << 8) |
(s->reg_secnum & 0xff);
vpi_printf("pli_ide: lba %08x (%d), seccnt %d\n",
s->lba, s->lba*512,s->reg_seccnt);
ret = lseek(s->file_fd, (off_t)s->lba*512, SEEK_SET);
ret = read(s->file_fd, (char *)s->fifo, 512 * s->reg_seccnt);
if (ret < 0)
perror("read");
s->fifo_depth = (512 * s->reg_seccnt) / 2;
s->fifo_rd = 0;
s->fifo_wr = 0;
s->status = (1<<IDE_STATUS_DRDY)|(1<<IDE_STATUS_DSC) | (1<<IDE_STATUS_DRQ);
}
/*
*
*/
PLI_INT32 pli_ide(void)
{
vpiHandle href, iter, mhref;
vpiHandle busref, diorref, diowref, csref, daref;
struct state_s *s;
int numargs, inst_id;
s_vpi_value tmpval, outval;
char bus_bits[17], cs_bits[3], da_bits[4], diow_bit, dior_bit;
unsigned int cs, da, bus;
int read_start, read_stop, write_start, write_stop;
//vpi_printf("pli_ide:\n");
href = vpi_handle(vpiSysTfCall, NULL);
if (href == NULL) {
vpi_printf("** ERR: $pli_ide PLI 2.0 can't get systf call handle\n");
return(0);
}
mhref = vpi_handle(vpiScope, href);
if (vpi_get(vpiType, mhref) != vpiModule)
mhref = vpi_handle(vpiModule, mhref);
inst_id = getadd_inst_id(mhref);
//vpi_printf("pli_ide: inst_id %d\n", inst_id);
s = &state[inst_id];
if (!s->file_inited) {
s->file_inited = 1;
do_ide_setup(s);
}
iter = vpi_iterate(vpiArgument, href);
numargs = vpi_get(vpiSize, iter);
/* data_bus[15:0], ide_dior, ide_diow, ide_cs[1:0], ide_da[2:0] */
busref = vpi_scan(iter);
diorref = vpi_scan(iter);
diowref = vpi_scan(iter);
csref = vpi_scan(iter);
daref = vpi_scan(iter);
if (busref == NULL || diorref == NULL || diowref == NULL ||
csref == NULL || daref == NULL)
{
vpi_printf("**ERR: $pli_ide bad args\n");
return(0);
}
tmpval.format = vpiBinStrVal;
vpi_get_value(busref, &tmpval);
strcpy(bus_bits, tmpval.value.str);
tmpval.format = vpiIntVal;
vpi_get_value(busref, &tmpval);
bus = tmpval.value.integer;
tmpval.format = vpiBinStrVal;
vpi_get_value(csref, &tmpval);
strcpy(cs_bits, tmpval.value.str);
tmpval.format = vpiIntVal;
vpi_get_value(csref, &tmpval);
cs = tmpval.value.integer;
tmpval.format = vpiBinStrVal;
vpi_get_value(daref, &tmpval);
strcpy(da_bits, tmpval.value.str);
tmpval.format = vpiIntVal;
vpi_get_value(daref, &tmpval);
da = tmpval.value.integer;
tmpval.format = vpiBinStrVal;
vpi_get_value(diorref, &tmpval);
dior_bit = tmpval.value.str[0];
tmpval.format = vpiBinStrVal;
vpi_get_value(diowref, &tmpval);
diow_bit = tmpval.value.str[0];
/* */
read_start = 0;
read_stop = 0;
write_start = 0;
write_stop = 0;
if (dior_bit != last_dior_bit) {
if (dior_bit == '0') read_start = 1;
if (dior_bit == '1') read_stop = 1;
}
if (diow_bit != last_diow_bit) {
if (diow_bit == '0') write_start = 1;
if (diow_bit == '1') write_stop = 1;
}
last_dior_bit = dior_bit;
last_diow_bit = diow_bit;
if (0) {
if (read_start) vpi_printf("pli_ide: read start\n");
if (read_stop) vpi_printf("pli_ide: read stop\n");
if (write_start) vpi_printf("pli_ide: write start\n");
if (write_stop) vpi_printf("pli_ide: write stop\n");
}
/* */
if (write_start) {
if (0) vpi_printf("pli_ide: write %s %s %d\n", cs_bits, da_bits, da);
switch (cs << 3 | da) {
case ATA_ALTER:
case ATA_DEVCTRL:
break;
case ATA_FEATURE:
break;
case ATA_SECCNT: s->reg_seccnt = bus; break;
case ATA_SECNUM: s->reg_secnum = bus; break;
case ATA_CYLLOW:
if (0) vpi_printf("pli_ide: cyllow %04x %s\n", bus, bus_bits);
s->reg_cyllow = bus;
break;
case ATA_CYLHIGH:
if (0) vpi_printf("pli_ide: cylhigh %04x %s\n", bus, bus_bits);
s->reg_cylhigh = bus;
break;
case ATA_DRVHEAD:
if (0) vpi_printf("pli_ide: drvhead %04x %s\n", bus, bus_bits);
s->reg_drvhead = bus;
break;
case ATA_DATA:
if (1) vpi_printf("pli_ide: write data %04x %s\n", bus, bus_bits);
break;
case ATA_COMMAND:
vpi_printf("pli_ide: command %04x %s\n", bus, bus_bits);
switch (bus) {
case 0x0020:
vpi_printf("pli_ide: XXX READ\n");
do_ide_read(s);
break;
case 0x0030:
vpi_printf("pli_ide: XXX WRITE\n");
break;
}
break;
}
}
if (read_start) {
if (0) vpi_printf("pli_ide: read %s %s %d\n", cs_bits, da_bits, da);
switch (cs << 3 | da) {
case ATA_DATA:
bus = s->fifo[s->fifo_rd];
if (0) vpi_printf("pli_ide: read data [%d/%d] %04o\n",
s->fifo_rd, s->fifo_depth, bus);
if (s->fifo_rd < s->fifo_depth)
s->fifo_rd++;
if (s->fifo_rd >= s->fifo_depth) {
vpi_printf("pli_ide: fifo empty\n");
s->status = (1<<IDE_STATUS_DRDY)|(1<<IDE_STATUS_DSC);
}
break;
case ATA_STATUS:
bus = s->status;
vpi_printf("pli_ide: read status %04x\n", bus);
break;
}
#ifdef __CVER__
if (s->bus_aref == 0)
s->bus_aref = vpi_put_value(busref, NULL, NULL, vpiAddDriver);
#else
s->bus_aref = busref;
#endif
outval.format = vpiIntVal;
outval.value.integer = bus;
vpi_put_value(s->bus_aref, &outval, NULL, vpiNoDelay);
}
if (read_stop) {
outval.format = vpiBinStrVal;
outval.value.str = "zzzzzzzzzzzzzzzz";
// outval.value.str = "0000000000000000";
if (s->bus_aref)
vpi_put_value(s->bus_aref, &outval, NULL, vpiNoDelay);
}
return(0);
}
/*
* register all vpi_ PLI 2.0 style user system tasks and functions
*/
void register_my_systfs(void)
{
p_vpi_systf_data systf_data_p;
/* use predefined table form - could fill systf_data_list dynamically */
static s_vpi_systf_data systf_data_list[] = {
{ vpiSysTask, 0, "$pli_ide", pli_ide, NULL, NULL, NULL },
{ 0, 0, NULL, NULL, NULL, NULL, NULL }
};
systf_data_p = &(systf_data_list[0]);
while (systf_data_p->type != 0) vpi_register_systf(systf_data_p++);
}
#ifdef __CVER__
static void (*ide_vlog_startup_routines[]) () =
{
register_my_systfs,
0
};
/* dummy +loadvpi= boostrap routine - mimics old style exec all routines */
/* in standard PLI vlog_startup_routines table */
void ide_vpi_compat_bootstrap(void)
{
int i;
for (i = 0;; i++)
{
if (ide_vlog_startup_routines[i] == NULL) break;
ide_vlog_startup_routines[i]();
}
}
void vpi_compat_bootstrap(void)
{
ide_vpi_compat_bootstrap();
}
void __stack_chk_fail_local(void) {}
#endif
#ifdef __MODELSIM__
static void (*vlog_startup_routines[]) () =
{
register_my_systfs,
0
};
#endif
/*
* Local Variables:
* indent-tabs-mode:nil
* c-basic-offset:4
* End:
*/

6
pli/ide/win32.bat Normal file
View File

@@ -0,0 +1,6 @@
rem c:\program files\microsoft visual studio\vcvars32.bat
set MTI_HOME=c:\Modeltech_6.2g
cl -c -I%MTI_HOME%\include -D__MODELSIM__ pli_ide.c
link -dll -export:vlog_startup_routines pli_ide.obj %MTI_HOME%\win32\mtipli.lib

25
pli/rf/Makefile Normal file
View File

@@ -0,0 +1,25 @@
#
INCS = -I../../cver/gplcver-2.12a.src/pli_incs
CFLAGS= -fPIC -Wall -g $(INCS) -D__CVER__
LFLAGS= -G -shared -export-dynamic
all: pli_rf.so pli_rf.vpi
pli_rf.o: pli_rf.c
$(CC) $(CFLAGS) -c pli_rf.c
pli_ram.o: pli_ram.c
$(CC) $(CFLAGS) -c pli_ram.c
pli_rf.so: pli_rf.o pli_ram.o
$(LD) $(LFLAGS) pli_rf.o pli_ram.o -o pli_rf.so
pli_rf.vpi: pli_rf.o pli_ram.o
$(LD) $(LFLAGS) pli_rf.o pli_ram.o -o pli_rf.vpi
clean:
rm -f *.o *.so *.vpi

279
pli/rf/pli_ram.c Normal file
View File

@@ -0,0 +1,279 @@
/* pli_ram.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#ifdef unix
#include <unistd.h>
#endif
#include "vpi_user.h"
#ifdef __CVER__
#include "cv_vpi_user.h"
#endif
#ifdef __MODELSIM__
#include "veriuser.h"
#endif
typedef unsigned short u16;
static char last_ce_bit;
static char last_we_bit;
static unsigned last_addr;
static vpiHandle do_aref;
static int mem_init;
u16 *M;
static char *instnam_tab[10];
static int last_evh;
void do_mem_preload(char *fn)
{
FILE *f;
f = fopen(fn, "r");
if (f) {
unsigned int a, v;
while (fscanf(f, "%o %o\n", &a, &v) == 2) {
vpi_printf("[%06o] <- %06o\n", a, v);
M[a] = v;
}
fclose(f);
}
}
void do_mem_init(void)
{
int i;
vpi_printf("pli_ram: allocate memory array\n");
M = (u16 *)malloc(1024*32);
mem_init = 1;
for (i = 0; i < 32768; i++)
M[i] = 0;
if (0) do_mem_preload("test1.mem");
}
static int getadd_inst_id(vpiHandle mhref)
{
register int i;
char *chp;
chp = vpi_get_str(vpiFullName, mhref);
//vpi_printf("getadd_inst_id() %s\n", chp);
for (i = 1; i <= last_evh; i++) {
if (strcmp(instnam_tab[i], chp) == 0)
return(i);
}
vpi_printf("pli_ram: adding instance %d, %s\n", last_evh+1, chp);
instnam_tab[++last_evh] = malloc(strlen(chp) + 1);
strcpy(instnam_tab[last_evh], chp);
return(last_evh);
}
PLI_INT32 pli_ram(void)
{
vpiHandle href, iter, mhref;
vpiHandle clkref, resetref, aref, diref, doref, ceref, weref;
s_vpi_value tmpval, outval;
int numargs, inst_id;
char clk_bit, reset_bit;
char di_bits[17], do_bits[17];
char ce_bit, we_bit;
unsigned int a, datai;
int read_start, read_stop, write_start, write_stop, addr_change;
if (M == 0/*!mem_init*/) {
do_mem_init();
}
href = vpi_handle(vpiSysTfCall, NULL);
if (href == NULL) {
vpi_printf("** ERR: $pli_ram PLI 2.0 can't get systf call handle\n");
return(0);
}
#if 0
mhref = vpi_handle(vpiScope, href);
if (vpi_get(vpiType, mhref) != vpiModule) {
vpiHandle old_mhref = mhref;
mhref = vpi_handle(vpiModule, mhref);
// vpi_free_object(old_mhref);
}
inst_id = getadd_inst_id(mhref);
#else
inst_id = 1;
#endif
//vpi_printf("pli_ram: inst_id %d\n", inst_id);
iter = vpi_iterate(vpiArgument, href);
numargs = vpi_get(vpiSize, iter);
/* clk, reset, a, di, do, ce, we */
clkref = vpi_scan(iter);
resetref = vpi_scan(iter);
aref = vpi_scan(iter);
diref = vpi_scan(iter);
doref = vpi_scan(iter);
ceref = vpi_scan(iter);
weref = vpi_scan(iter);
vpi_free_object(iter);
vpi_free_object(href);
if (clkref == NULL || resetref == NULL || aref == NULL ||
diref == NULL || doref == NULL || ceref == NULL ||
weref == NULL)
{
vpi_printf("**ERR: $pli_ram bad args\n");
return(0);
}
/* */
tmpval.format = vpiBinStrVal;
vpi_get_value(clkref, &tmpval);
clk_bit = tmpval.value.str[0];
tmpval.format = vpiBinStrVal;
vpi_get_value(resetref, &tmpval);
reset_bit = tmpval.value.str[0];
tmpval.format = vpiIntVal;
vpi_get_value(aref, &tmpval);
a = tmpval.value.integer;
tmpval.format = vpiBinStrVal;
vpi_get_value(diref, &tmpval);
strcpy(di_bits, tmpval.value.str);
tmpval.format = vpiIntVal;
vpi_get_value(diref, &tmpval);
datai = tmpval.value.integer;
tmpval.format = vpiBinStrVal;
vpi_get_value(doref, &tmpval);
strcpy(do_bits, tmpval.value.str);
tmpval.format = vpiBinStrVal;
vpi_get_value(ceref, &tmpval);
ce_bit = tmpval.value.str[0];
tmpval.format = vpiBinStrVal;
vpi_get_value(weref, &tmpval);
we_bit = tmpval.value.str[0];
/* */
read_start = 0;
read_stop = 0;
write_start = 0;
write_stop = 0;
addr_change = 0;
if (a != last_addr)
addr_change = 1;
if (we_bit != last_we_bit || addr_change) {
if (we_bit == '0') write_start = 1;
if (we_bit == '1') write_stop = 1;
}
if (ce_bit != last_ce_bit || write_stop || addr_change) {
if (ce_bit == '0') read_start = 1;
if (ce_bit == '1') read_stop = 1;
}
last_ce_bit = ce_bit;
last_we_bit = we_bit;
last_addr = a;
if (0) vpi_printf("pli_ram: clk %c ce %c we %c\n", clk_bit, ce_bit, we_bit);
if (reset_bit == '1') vpi_printf("pli_ram: reset\n");
if (0) {
if (read_start) vpi_printf("pli_ram: read start\n");
if (read_stop) vpi_printf("pli_ram: read stop\n");
if (write_start) vpi_printf("pli_ram: write start\n");
if (write_stop) vpi_printf("pli_ram: write stop\n");
}
/* */
if (write_start) {
//vpi_printf("pli_ram: write %o <- %o\n", a, datai);
if (a > 1024*1024) {
vpi_printf("pli_ram: write, address error %x\n", a);
while (1);
}
M[a] = datai;
}
if (read_start) {
u16 value;
if (a > 1024*32) {
vpi_printf("pli_ram: write, address error %x\n", a);
while (1);
}
value = M[a];
//vpi_printf("pli_ram: read %o -> %o\n", a, value);
#ifdef __CVER__
if (do_aref == 0)
do_aref = vpi_put_value(doref, NULL, NULL, vpiAddDriver);
#else
do_aref = doref;
#endif
outval.format = vpiIntVal;
outval.value.integer = value;
vpi_put_value(do_aref, &outval, NULL, vpiNoDelay);
}
if (read_stop) {
outval.format = vpiBinStrVal;
// outval.value.str = "16'bzzzzzzzzzzzzzzzz";
outval.value.str = "16'b0000000000000000";
if (do_aref)
vpi_put_value(do_aref, &outval, NULL, vpiNoDelay);
}
vpi_free_object(clkref);
vpi_free_object(resetref);
vpi_free_object(aref);
vpi_free_object(diref);
vpi_free_object(doref);
vpi_free_object(ceref);
vpi_free_object(weref);
return(0);
}
/*
* Local Variables:
* indent-tabs-mode:nil
* c-basic-offset:4
* End:
*/

1080
pli/rf/pli_rf.c Normal file

File diff suppressed because it is too large Load Diff

7
pli/rf/win32.bat Normal file
View File

@@ -0,0 +1,7 @@
rem c:\program files\microsoft visual studio\vcvars32.bat
set MTI_HOME=c:\Modeltech_6.2g
cl -c -I%MTI_HOME%\include -D__MODELSIM__ pli_rf.c
cl -c -I%MTI_HOME%\include -D__MODELSIM__ pli_ram.c
link -dll -export:vlog_startup_routines pli_rf.obj pli_ram.obj %MTI_HOME%\win32\mtipli.lib