mirror of
https://github.com/aap/pdp6.git
synced 2026-03-03 02:08:32 +00:00
lots of additions and changes
This commit is contained in:
@@ -364,7 +364,7 @@ static int char_q[] = {
|
||||
static int char_r[] = {
|
||||
I, U|I, U|I, U|I, U|I,
|
||||
D|R|I, U|R|I, R|I, D|R|I,
|
||||
D|R, D|R, D|R,
|
||||
D|R, D|R, D,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
|
||||
@@ -477,6 +477,8 @@ cpu_printflags(void)
|
||||
|
||||
void fe_svc(void) {}
|
||||
|
||||
void initcrt(const char *host) {}
|
||||
|
||||
void
|
||||
init6(void)
|
||||
{
|
||||
|
||||
105
fe6/6/real6.c
105
fe6/6/real6.c
@@ -81,12 +81,17 @@ enum
|
||||
REG6_PTR = 035,
|
||||
REG6_PTR_LT = 036,
|
||||
REG6_PTR_RT = 037,
|
||||
|
||||
REG6_DIS1 = 040,
|
||||
REG6_DIS2 = 041,
|
||||
REG6_DIS3 = 042,
|
||||
};
|
||||
|
||||
enum {
|
||||
FEREG_REQ = 0,
|
||||
FEREG_PTR,
|
||||
FEREG_PTP
|
||||
FEREG_PTP,
|
||||
FEREG_DIS
|
||||
};
|
||||
|
||||
|
||||
@@ -106,6 +111,7 @@ static volatile u32 *h2f_cmemif, *h2f_cmemif2;
|
||||
static volatile u32 *h2f_fmemif, *h2f_fmemif2;
|
||||
static volatile u32 *h2f_apr;
|
||||
static volatile u32 *h2f_fe;
|
||||
static volatile u32 *h2f_csl;
|
||||
static volatile u32 *h2f_lw_led_addr;
|
||||
static volatile u32 *h2f_lw_sw_addr;
|
||||
|
||||
@@ -137,13 +143,16 @@ deposit(hword a, word w)
|
||||
h2f_fmemif[1] = w & RT;
|
||||
h2f_fmemif[2] = (w >> 18) & RT;
|
||||
}else if(a < 01000020){
|
||||
void dep64(u32, u64);
|
||||
if(0 && a < 01000){
|
||||
printf("dep %o %llo\r\n", a, w);
|
||||
fflush(stdout);
|
||||
}
|
||||
// dep64(a, w);
|
||||
|
||||
h2f_cmemif[0] = a & RT;
|
||||
h2f_cmemif[1] = w & RT;
|
||||
h2f_cmemif[2] = (w >> 18) & RT;
|
||||
}else if(a >= 02000000){
|
||||
h2f_cmemif2[0] = a & 01777777;
|
||||
h2f_cmemif2[1] = w & RT;
|
||||
h2f_cmemif2[2] = (w >> 18) & RT;
|
||||
}else switch(a){
|
||||
case APR_DS:
|
||||
h2f_apr[REG6_DSLT] = w>>18 & RT;
|
||||
@@ -179,6 +188,8 @@ deposit(hword a, word w)
|
||||
*h2f_lw_led_addr = w;
|
||||
break;
|
||||
}
|
||||
|
||||
// usleep(5);
|
||||
}
|
||||
|
||||
word
|
||||
@@ -217,15 +228,13 @@ examine(hword a)
|
||||
w <<= 18;
|
||||
w |= h2f_fmemif[1] & RT;
|
||||
}else if(a < 01000020){
|
||||
//u64 ex64(u32);
|
||||
// w = ex64(a);
|
||||
|
||||
h2f_cmemif[0] = a & RT;
|
||||
w = h2f_cmemif[2] & RT;
|
||||
w <<= 18;
|
||||
w |= h2f_cmemif[1] & RT;
|
||||
}else if(a >= 02000000){
|
||||
h2f_cmemif2[0] = a & 01777777;
|
||||
w = h2f_cmemif2[2] & RT;
|
||||
w <<= 18;
|
||||
w |= h2f_cmemif2[1] & RT;
|
||||
}else switch(a){
|
||||
case APR_DS:
|
||||
w = h2f_apr[REG6_DSLT];
|
||||
@@ -556,6 +565,33 @@ prflags(const char *fmt, u8 flags)
|
||||
l[!!(flags&02)], l[!!(flags&01)]);
|
||||
}
|
||||
|
||||
void
|
||||
prdis(void)
|
||||
{
|
||||
u32 dis1, dis2, dis3;
|
||||
dis1 = h2f_apr[REG6_DIS1];
|
||||
dis2 = h2f_apr[REG6_DIS2];
|
||||
dis3 = h2f_apr[REG6_DIS3];
|
||||
printf("\r\nDIS\r\n");
|
||||
printf("BR/%06o\r\n", dis1);
|
||||
printf("X/%04o Y/%04o BRM/%03o S/%02o I/%o SZ/%o MODE/%o\r\n",
|
||||
dis2&01777, (dis2>>10)&01777, (dis2>>20)&0177,
|
||||
(dis3>>8)&017, (dis3>>5)&7, (dis3>>3)&3, dis3&7);
|
||||
printf("DATA REQ/%o STOP/%o EDGE/%o LP/%o LP ON/%o LP FIND/%o\r\n",
|
||||
!!(dis3 & 04000000),
|
||||
!!(dis3 & 0400000),
|
||||
!!(dis3 & 02000000),
|
||||
!!(dis3 & 040000),
|
||||
!!(dis3 & 020000),
|
||||
!!(dis3 & 010000));
|
||||
printf("MOVE/%o HALT/%o\r\n",
|
||||
!!(dis3 & 0200000),
|
||||
!!(dis3 & 0100000));
|
||||
|
||||
dis3 = h2f_apr[REG6_DIS3+1];
|
||||
printf("%X\r\n", dis3);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_printflags(void)
|
||||
{
|
||||
@@ -589,6 +625,8 @@ cpu_printflags(void)
|
||||
printf("RUN/%o MEM STOP/%o\r\n",
|
||||
!!(ctl1 & MM6_RUN), !!(ctl1 & MM6_MCSTOP));
|
||||
|
||||
prdis();
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
@@ -628,6 +666,25 @@ fflush(stdout);
|
||||
write(fd, &c, 1);
|
||||
}
|
||||
|
||||
int dis_fd = -1;
|
||||
|
||||
static void
|
||||
svc_dis(void)
|
||||
{
|
||||
u32 pnt;
|
||||
pnt = h2f_fe[FEREG_DIS];
|
||||
if((pnt & 0x80000000) == 0)
|
||||
return;
|
||||
if(dis_fd >= 0)
|
||||
write(dis_fd, &pnt, 4);
|
||||
/*
|
||||
else{
|
||||
printf("%X\r\n", pnt);
|
||||
fflush(stdout);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
fe_svc(void)
|
||||
{
|
||||
@@ -637,8 +694,30 @@ fe_svc(void)
|
||||
|
||||
if(req & 1) svc_ptr();
|
||||
if(req & 2) svc_ptp();
|
||||
// if(req & 4) svc_dis();
|
||||
svc_dis();
|
||||
}
|
||||
|
||||
void*
|
||||
wcsl_thread(void *arg)
|
||||
{
|
||||
u32 ctl;
|
||||
while(readn(dis_fd, &ctl, 4) == 0){
|
||||
// printf("%o\r\n", ctl);
|
||||
// fflush(stdout);
|
||||
h2f_csl[ctl>>24] = ctl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
initcrt(const char *host)
|
||||
{
|
||||
dis_fd = dial(host, 3400);
|
||||
if(dis_fd >= 0){
|
||||
printf("display connected\n");
|
||||
threadcreate(wcsl_thread, nil);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
init6(void)
|
||||
@@ -668,11 +747,17 @@ init6(void)
|
||||
h2f_fmemif = getLWH2Faddr(0x10010);
|
||||
h2f_fmemif2 = getLWH2Faddr(0x20010);
|
||||
|
||||
// enable sdram bridge (???)
|
||||
*(u32*)((u8*)virtual_base + 0x5080) = 0xFFFF;
|
||||
|
||||
h2f_apr = getLWH2Faddr(0x10100);
|
||||
h2f_fe = getLWH2Faddr(0x20000);
|
||||
h2f_csl = getLWH2Faddr(0x30000);
|
||||
h2f_lw_sw_addr = getLWH2Faddr(0x10020);
|
||||
h2f_lw_led_addr = getLWH2Faddr(0x10040);
|
||||
|
||||
|
||||
// testshit();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
11
fe6/Makefile
11
fe6/Makefile
@@ -1,21 +1,22 @@
|
||||
XX=/u/aap/de0-nano-soc/gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
|
||||
CFLAGS=-DTEST
|
||||
LDFLAGS=-lpthread
|
||||
|
||||
SRC=fe.c cmd.c util.c pdp6common.c
|
||||
SRC=fe.c cmd.c util.c netmem.c pdp6common.c threading.c
|
||||
|
||||
all: fe6_emu fe6_fake fe6 feka
|
||||
clean:
|
||||
rm fe6_emu fe6_fake fe6
|
||||
|
||||
fe6: $(SRC) 6/real6.c
|
||||
$(XX)gcc -I6 $(CFLAGS) -o $@ $^
|
||||
$(XX)gcc -I6 $(CFLAGS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
fe6_fake: $(SRC) fake.c
|
||||
$(CC) -I6 $(CFLAGS) -o $@ $^
|
||||
$(CC) -I6 $(CFLAGS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
fe6_emu: $(SRC) 6/emu6.c
|
||||
$(CC) -I6 $(CFLAGS) -o $@ $^
|
||||
$(CC) -I6 $(CFLAGS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
|
||||
feka: $(SRC) ka/real.c
|
||||
$(XX)gcc -Ika $(CFLAGS) -o $@ $^
|
||||
$(XX)gcc -Ika $(CFLAGS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
@@ -114,8 +114,9 @@ sblk:
|
||||
|
||||
chk = (chk<<1 | chk>>35) + w & FW;
|
||||
|
||||
if(d)
|
||||
if(d){
|
||||
deposit(right(iowd), w);
|
||||
}
|
||||
iowd += 01000001;
|
||||
}
|
||||
if(readwits(fp) != chk)
|
||||
|
||||
@@ -188,6 +188,8 @@ cpu_printflags(void)
|
||||
|
||||
void fe_svc(void) {}
|
||||
|
||||
void initcrt(const char *host) {}
|
||||
|
||||
void
|
||||
init6(void)
|
||||
{
|
||||
|
||||
16
fe6/fe.c
16
fe6/fe.c
@@ -87,6 +87,7 @@ enum {
|
||||
MODE_ASCII,
|
||||
MODE_SIXBIT,
|
||||
MODE_SQUOZE,
|
||||
MODE_FLOAT,
|
||||
|
||||
/* flags */
|
||||
CF = 1, // one altmode
|
||||
@@ -404,6 +405,7 @@ prword(int mode, word wd)
|
||||
int i;
|
||||
char c;
|
||||
char s[7];
|
||||
double f;
|
||||
|
||||
switch(mode){
|
||||
case MODE_ASCII:
|
||||
@@ -453,6 +455,12 @@ prword(int mode, word wd)
|
||||
typenum((wd>>18)&0777777);
|
||||
break;
|
||||
|
||||
case MODE_FLOAT:
|
||||
f = pdptod(wd);
|
||||
printf("%lf", f);
|
||||
fflush(stdout);
|
||||
break;
|
||||
|
||||
default:
|
||||
typenum(wd);
|
||||
}
|
||||
@@ -553,12 +561,14 @@ quit(void)
|
||||
int started;
|
||||
|
||||
int
|
||||
main()
|
||||
threadmain(int argc, char *argv[])
|
||||
{
|
||||
char chu;
|
||||
word t;
|
||||
|
||||
init6();
|
||||
initcrt("soma");
|
||||
// initnetmem("10.0.0.222", 10006);
|
||||
|
||||
raw(0);
|
||||
erasec = tiosaved.c_cc[VERASE];
|
||||
@@ -603,6 +613,7 @@ main()
|
||||
typestr("/ ");
|
||||
t = examine(t);
|
||||
prword(MODE_SYM, t);
|
||||
q = t;
|
||||
typestr(" ");
|
||||
|
||||
started = 0;
|
||||
@@ -898,6 +909,9 @@ main()
|
||||
case '=':
|
||||
typeout(MODE_NUM);
|
||||
break;
|
||||
case ';':
|
||||
typeout(MODE_FLOAT);
|
||||
break;
|
||||
case '"':
|
||||
if(flags & CF)
|
||||
modechange(MODE_ASCII);
|
||||
|
||||
7
fe6/fe.h
7
fe6/fe.h
@@ -5,6 +5,7 @@
|
||||
#include <ctype.h>
|
||||
#include "util.h"
|
||||
#include "pdp6common.h"
|
||||
#include "threading.h"
|
||||
|
||||
#define nil NULL
|
||||
|
||||
@@ -18,7 +19,8 @@ typedef uint8_t u8;
|
||||
#define FW (LT|RT)
|
||||
#define F0 0400000000000
|
||||
|
||||
#define MAXMEM (16*1024)
|
||||
//#define MAXMEM (16*1024)
|
||||
#define MAXMEM (256*1024)
|
||||
|
||||
#include "regs.h"
|
||||
|
||||
@@ -83,5 +85,8 @@ void cpu_printflags(void);
|
||||
|
||||
void fe_svc(void);
|
||||
|
||||
void initcrt(const char *host);
|
||||
void initnetmem(const char *host, int port);
|
||||
|
||||
void init6(void);
|
||||
void deinit6(void);
|
||||
|
||||
@@ -96,7 +96,8 @@ enum
|
||||
enum {
|
||||
FEREG_REQ = 0,
|
||||
FEREG_PTR,
|
||||
FEREG_PTP
|
||||
FEREG_PTP,
|
||||
FEREG_DIS
|
||||
};
|
||||
|
||||
|
||||
@@ -116,6 +117,7 @@ static volatile u32 *h2f_cmemif;
|
||||
static volatile u32 *h2f_fmemif;
|
||||
static volatile u32 *h2f_apr;
|
||||
static volatile u32 *h2f_fe;
|
||||
static volatile u32 *h2f_csl;
|
||||
|
||||
void
|
||||
deposit(hword a, word w)
|
||||
@@ -661,6 +663,23 @@ fflush(stdout);
|
||||
write(fd, &c, 1);
|
||||
}
|
||||
|
||||
int dis_fd;
|
||||
|
||||
static void
|
||||
svc_dis(void)
|
||||
{
|
||||
u32 pnt;
|
||||
pnt = h2f_fe[FEREG_DIS];
|
||||
if((pnt & 0x80000000) == 0)
|
||||
return;
|
||||
if(dis_fd >= 0)
|
||||
write(dis_fd, &pnt, 4);
|
||||
else{
|
||||
printf("%X\r\n", pnt);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fe_svc(void)
|
||||
{
|
||||
@@ -670,8 +689,30 @@ fe_svc(void)
|
||||
|
||||
if(req & 1) svc_ptr();
|
||||
if(req & 2) svc_ptp();
|
||||
// if(req & 4) svc_dis();
|
||||
svc_dis();
|
||||
}
|
||||
|
||||
void*
|
||||
wcsl_thread(void *arg)
|
||||
{
|
||||
u32 ctl;
|
||||
while(readn(dis_fd, &ctl, 4) == 0){
|
||||
// printf("%o\r\n", ctl);
|
||||
// fflush(stdout);
|
||||
h2f_csl[ctl>>24] = ctl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
initcrt(const char *host)
|
||||
{
|
||||
dis_fd = dial(host, 3400);
|
||||
if(dis_fd >= 0){
|
||||
printf("display connected\n");
|
||||
threadcreate(wcsl_thread, nil);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
init6(void)
|
||||
@@ -699,6 +740,7 @@ init6(void)
|
||||
h2f_fmemif = getLWH2Faddr(0x10010);
|
||||
h2f_apr = getLWH2Faddr(0x10100);
|
||||
h2f_fe = getLWH2Faddr(0x20000);
|
||||
h2f_csl = getLWH2Faddr(0x30000);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
81
fe6/netmem.c
Normal file
81
fe6/netmem.c
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "fe.h"
|
||||
#include <unistd.h>
|
||||
|
||||
int netmemfd = -1;
|
||||
|
||||
enum
|
||||
{
|
||||
WRRQ = 1,
|
||||
RDRQ = 2,
|
||||
ACK = 3,
|
||||
ERR = 4,
|
||||
};
|
||||
|
||||
void*
|
||||
netmemthread(void *arg)
|
||||
{
|
||||
u16 len;
|
||||
word a, d;
|
||||
u8 buf[9];
|
||||
|
||||
while(readn(netmemfd, buf, 2) == 0){
|
||||
len = buf[0]<<8 | buf[1];
|
||||
if(len > 9){
|
||||
fprintf(stderr, "netmem botch(%d), closing\n", len);
|
||||
close(netmemfd);
|
||||
netmemfd = -1;
|
||||
return nil;
|
||||
}
|
||||
memset(buf, 0, sizeof(buf));
|
||||
readn(netmemfd, buf, len);
|
||||
|
||||
a = buf[1] | buf[2]<<8 | buf[3]<<16;
|
||||
d = buf[4] | buf[5]<<8 | buf[6]<<16 |
|
||||
(word)buf[7]<<24 | (word)buf[8]<<32;
|
||||
a &= 0777777;
|
||||
d &= 0777777777777;
|
||||
|
||||
switch(buf[0]){
|
||||
case WRRQ:
|
||||
deposit(a, d);
|
||||
printf("write %06lo %012lo\r\n", a, d);
|
||||
fflush(stdout);
|
||||
buf[0] = 0;
|
||||
buf[1] = 1;
|
||||
buf[2] = ACK;
|
||||
writen(netmemfd, buf, buf[1]+2);
|
||||
break;
|
||||
case RDRQ:
|
||||
d = examine(a);
|
||||
printf("read %06lo %012lo\r\n", a, d);
|
||||
fflush(stdout);
|
||||
buf[0] = 0;
|
||||
buf[1] = 6;
|
||||
buf[2] = ACK;
|
||||
buf[3] = d;
|
||||
buf[4] = d>>8;
|
||||
buf[5] = d>>16;
|
||||
buf[6] = d>>24;
|
||||
buf[7] = d>>32;
|
||||
writen(netmemfd, buf, buf[1]+2);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown netmem message %d\n", buf[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "netmem fd closed\n");
|
||||
netmemfd = -1;
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
initnetmem(const char *host, int port)
|
||||
{
|
||||
netmemfd = dial(host, port);
|
||||
if(netmemfd >= 0){
|
||||
printf("netmem connected\n");
|
||||
threadcreate(netmemthread, nil);
|
||||
}
|
||||
}
|
||||
|
||||
361
fe6/threading.c
Normal file
361
fe6/threading.c
Normal file
@@ -0,0 +1,361 @@
|
||||
#include "threading.h"
|
||||
#include <assert.h>
|
||||
|
||||
#define USED(x) (void)(x)
|
||||
|
||||
/*
|
||||
* Locks
|
||||
*/
|
||||
|
||||
static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static void
|
||||
lockinit(Lock *lk)
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
pthread_mutex_lock(&initmutex);
|
||||
if(lk->init == 0){
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
|
||||
pthread_mutex_init(&lk->mutex, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
lk->init = 1;
|
||||
}
|
||||
pthread_mutex_unlock(&initmutex);
|
||||
}
|
||||
|
||||
void
|
||||
lock(Lock *lk)
|
||||
{
|
||||
if(!lk->init)
|
||||
lockinit(lk);
|
||||
if(pthread_mutex_lock(&lk->mutex) != 0)
|
||||
abort();
|
||||
}
|
||||
|
||||
int
|
||||
canlock(Lock *lk)
|
||||
{
|
||||
int r;
|
||||
|
||||
if(!lk->init)
|
||||
lockinit(lk);
|
||||
r = pthread_mutex_trylock(&lk->mutex);
|
||||
if(r == 0)
|
||||
return 1;
|
||||
if(r == EBUSY)
|
||||
return 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
void
|
||||
unlock(Lock *lk)
|
||||
{
|
||||
if(pthread_mutex_unlock(&lk->mutex) != 0)
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
rendinit(Rendez *r)
|
||||
{
|
||||
pthread_condattr_t attr;
|
||||
|
||||
pthread_mutex_lock(&initmutex);
|
||||
if(r->init == 0){
|
||||
pthread_condattr_init(&attr);
|
||||
pthread_cond_init(&r->cond, &attr);
|
||||
pthread_condattr_destroy(&attr);
|
||||
r->init = 1;
|
||||
}
|
||||
pthread_mutex_unlock(&initmutex);
|
||||
}
|
||||
|
||||
void
|
||||
rsleep(Rendez *r)
|
||||
{
|
||||
if(!r->init)
|
||||
rendinit(r);
|
||||
if(pthread_cond_wait(&r->cond, &r->l->mutex) != 0)
|
||||
abort();
|
||||
}
|
||||
|
||||
void
|
||||
rwakeup(Rendez *r)
|
||||
{
|
||||
if(!r->init)
|
||||
return;
|
||||
if(pthread_cond_signal(&r->cond) != 0)
|
||||
abort();
|
||||
}
|
||||
|
||||
void
|
||||
rwakeupall(Rendez *r)
|
||||
{
|
||||
if(!r->init)
|
||||
return;
|
||||
if(pthread_cond_broadcast(&r->cond) != 0)
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Threads
|
||||
*/
|
||||
|
||||
|
||||
static Lock idlock;
|
||||
static pthread_t *threads;
|
||||
static int numthreads;
|
||||
static int maxthreads;
|
||||
|
||||
static __thread int myid;
|
||||
static __thread void *mypointer;
|
||||
|
||||
static int
|
||||
addthreadid(void)
|
||||
{
|
||||
int id;
|
||||
|
||||
if(numthreads >= maxthreads){
|
||||
maxthreads += 64;
|
||||
threads = realloc(threads, maxthreads*sizeof(*threads));
|
||||
}
|
||||
id = numthreads++;
|
||||
threads[id] = 0;
|
||||
return id;
|
||||
}
|
||||
|
||||
static pthread_t
|
||||
gethandle(int id)
|
||||
{
|
||||
pthread_t th;
|
||||
lock(&idlock);
|
||||
th = threads[id];
|
||||
unlock(&idlock);
|
||||
return th;
|
||||
}
|
||||
|
||||
struct ThreadArg
|
||||
{
|
||||
int id;
|
||||
void *(*f)(void*);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static void*
|
||||
trampoline(void *p)
|
||||
{
|
||||
struct ThreadArg *args;
|
||||
void *(*f)(void*);
|
||||
void *arg;
|
||||
|
||||
args = p;
|
||||
myid = args->id;
|
||||
f = args->f;
|
||||
arg = args->arg;
|
||||
free(args);
|
||||
return f(arg);
|
||||
}
|
||||
|
||||
int
|
||||
threadcreate(void *(*f)(void*), void *arg)
|
||||
{
|
||||
struct ThreadArg *args;
|
||||
int id;
|
||||
|
||||
lock(&idlock);
|
||||
id = addthreadid();
|
||||
args = malloc(sizeof(*args));
|
||||
args->id = id;
|
||||
args->f = f;
|
||||
args->arg = arg;
|
||||
pthread_create(&threads[id], nil, trampoline, args);
|
||||
unlock(&idlock);
|
||||
return id;
|
||||
}
|
||||
|
||||
void
|
||||
threadexits(void *ret)
|
||||
{
|
||||
pthread_exit(ret);
|
||||
}
|
||||
|
||||
int
|
||||
threadid(void)
|
||||
{
|
||||
return myid;
|
||||
}
|
||||
|
||||
void**
|
||||
threaddata(void)
|
||||
{
|
||||
return &mypointer;
|
||||
}
|
||||
|
||||
void
|
||||
threadkill(int id)
|
||||
{
|
||||
assert(id >= 0 && id < numthreads);
|
||||
pthread_cancel(gethandle(id));
|
||||
}
|
||||
|
||||
void
|
||||
threadwait(int id)
|
||||
{
|
||||
pthread_join(gethandle(id), nil);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int id;
|
||||
|
||||
id = addthreadid();
|
||||
threads[id] = pthread_self();
|
||||
return threadmain(argc, argv);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Channels
|
||||
*/
|
||||
|
||||
|
||||
Channel*
|
||||
chancreate(int elemsize, int bufsize)
|
||||
{
|
||||
Channel *c;
|
||||
|
||||
c = malloc(sizeof(Channel) + bufsize*elemsize);
|
||||
if(c == nil)
|
||||
return nil;
|
||||
memset(c, 0, sizeof(Channel));
|
||||
c->elemsize = elemsize;
|
||||
c->bufsize = bufsize;
|
||||
c->nbuf = 0;
|
||||
c->buf = (uchar*)(c+1);
|
||||
c->full.l = &c->lock;
|
||||
c->empty.l = &c->lock;
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
chanclose(Channel *c)
|
||||
{
|
||||
lock(&c->lock);
|
||||
c->closed = 1;
|
||||
rwakeupall(&c->full);
|
||||
rwakeupall(&c->empty);
|
||||
unlock(&c->lock);
|
||||
}
|
||||
|
||||
void
|
||||
chanfree(Channel *c)
|
||||
{
|
||||
// TODO: don't free chans still in use
|
||||
free(c);
|
||||
}
|
||||
|
||||
static int cansend(Channel *c) { return c->nbuf < c->bufsize; }
|
||||
static int canrecv(Channel *c) { return c->nbuf > 0; }
|
||||
|
||||
static void
|
||||
chansend_(Channel *c, void *p)
|
||||
{
|
||||
uchar *pp;
|
||||
|
||||
assert(cansend(c));
|
||||
pp = c->buf + (c->off+c->nbuf)%c->bufsize * c->elemsize;
|
||||
memmove(pp, p, c->elemsize);
|
||||
c->nbuf++;
|
||||
}
|
||||
|
||||
static void
|
||||
chanrecv_(Channel *c, void *p)
|
||||
{
|
||||
uchar *pp;
|
||||
|
||||
assert(canrecv(c));
|
||||
pp = c->buf + c->off*c->elemsize;
|
||||
memmove(p, pp, c->elemsize);
|
||||
c->nbuf--;
|
||||
if(++c->off == c->bufsize)
|
||||
c->off = 0;
|
||||
}
|
||||
|
||||
int
|
||||
chansend(Channel *c, void *p)
|
||||
{
|
||||
lock(&c->lock);
|
||||
while(!(c->closed || cansend(c)))
|
||||
rsleep(&c->full);
|
||||
/* closed or can send */
|
||||
if(c->closed){
|
||||
/* can never send to closed chan */
|
||||
unlock(&c->lock);
|
||||
return -1;
|
||||
}
|
||||
chansend_(c, p);
|
||||
rwakeup(&c->empty);
|
||||
unlock(&c->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
chanrecv(Channel *c, void *p)
|
||||
{
|
||||
lock(&c->lock);
|
||||
while(!(c->closed || canrecv(c)))
|
||||
rsleep(&c->empty);
|
||||
/* closed or can receive */
|
||||
if(canrecv(c)){
|
||||
/* can still receive from closed chan */
|
||||
chanrecv_(c, p);
|
||||
rwakeup(&c->full);
|
||||
unlock(&c->lock);
|
||||
return 1;
|
||||
}
|
||||
unlock(&c->lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
channbsend(Channel *c, void *p)
|
||||
{
|
||||
lock(&c->lock);
|
||||
if(c->closed){
|
||||
/* can never send to closed chan */
|
||||
unlock(&c->lock);
|
||||
return -1;
|
||||
}
|
||||
if(cansend(c)){
|
||||
chansend_(c, p);
|
||||
rwakeup(&c->empty);
|
||||
unlock(&c->lock);
|
||||
return 1;
|
||||
}
|
||||
unlock(&c->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
channbrecv(Channel *c, void *p)
|
||||
{
|
||||
lock(&c->lock);
|
||||
if(canrecv(c)){
|
||||
/* can still receive from closed chan */
|
||||
chanrecv_(c, p);
|
||||
rwakeup(&c->full);
|
||||
unlock(&c->lock);
|
||||
return 1;
|
||||
}
|
||||
if(c->closed){
|
||||
unlock(&c->lock);
|
||||
return -1;
|
||||
}
|
||||
unlock(&c->lock);
|
||||
return 0;
|
||||
}
|
||||
60
fe6/threading.h
Normal file
60
fe6/threading.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define nil NULL
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned int uint;
|
||||
|
||||
typedef struct Lock Lock;
|
||||
struct Lock
|
||||
{
|
||||
int init;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
void lock(Lock *lk);
|
||||
int canlock(Lock *lk);
|
||||
void unlock(Lock *lk);
|
||||
|
||||
|
||||
typedef struct Rendez Rendez;
|
||||
struct Rendez
|
||||
{
|
||||
int init;
|
||||
Lock *l;
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
void rsleep(Rendez *r);
|
||||
void rwakeup(Rendez *r);
|
||||
void rwakeupall(Rendez *r);
|
||||
|
||||
|
||||
typedef struct Channel Channel;
|
||||
struct Channel
|
||||
{
|
||||
int bufsize;
|
||||
int elemsize;
|
||||
uchar *buf;
|
||||
int nbuf;
|
||||
int off;
|
||||
|
||||
int closed;
|
||||
Lock lock;
|
||||
Rendez full, empty;
|
||||
};
|
||||
Channel *chancreate(int elemsize, int bufsize);
|
||||
void chanclose(Channel *chan);
|
||||
void chanfree(Channel *c);
|
||||
int chansend(Channel *c, void *p);
|
||||
int chanrecv(Channel *c, void *p);
|
||||
int channbsend(Channel *c, void *p);
|
||||
int channbrecv(Channel *c, void *p);
|
||||
|
||||
int threadmain(int argc, char *argv[]);
|
||||
int threadcreate(void *(*f)(void*), void *arg);
|
||||
void threadexits(void *ret);
|
||||
int threadid(void);
|
||||
void **threaddata(void);
|
||||
void threadkill(int id);
|
||||
void threadwait(int id);
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
|
||||
11
tools/as6.c
11
tools/as6.c
@@ -1195,8 +1195,8 @@ opline(word w, int io)
|
||||
w |= 0000020000000;
|
||||
w = fw(left(w), right(w)+right(y.val));
|
||||
/* TODO: really warn about this? */
|
||||
if(left(y.val))
|
||||
err(0, "warning: address too large");
|
||||
// if(left(y.val))
|
||||
// err(0, "warning: address too large");
|
||||
w = fw(left(w)+left(x.val), right(w)+right(x.val));
|
||||
if(x.rel)
|
||||
err(0, "warning: X relocation ignored");
|
||||
@@ -1732,9 +1732,9 @@ checkundef(int glob)
|
||||
s->type != Operator && s->type != IoOperator && s->type != Pseudo){
|
||||
unsixbit(s->name, name);
|
||||
if(s->type == Undef){
|
||||
if(glob)
|
||||
s->type |= Extern;
|
||||
else
|
||||
// if(glob)
|
||||
// s->type |= Extern;
|
||||
// else
|
||||
err(1, "undefined symbol: %s\n", name);
|
||||
}
|
||||
}
|
||||
@@ -1909,6 +1909,7 @@ main(int argc, char *argv[])
|
||||
|
||||
|
||||
pass2 = 1;
|
||||
radix = 8;
|
||||
// printf("\n PASS2\n\n");
|
||||
|
||||
startitem(Name);
|
||||
|
||||
111
tools/scon33.c
Normal file
111
tools/scon33.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#define _XOPEN_SOURCE 600 /* for ptys */
|
||||
#define _DEFAULT_SOURCE /* for cfmakeraw */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
struct termios tiosaved;
|
||||
|
||||
int
|
||||
raw(int fd)
|
||||
{
|
||||
struct termios tio;
|
||||
if(tcgetattr(fd, &tio) < 0) return -1;
|
||||
tiosaved = tio;
|
||||
cfsetispeed(&tio, B110);
|
||||
cfsetospeed(&tio, B110);
|
||||
cfmakeraw(&tio);
|
||||
tio.c_cflag |= CSTOPB;
|
||||
if(tcsetattr(fd, TCSAFLUSH, &tio) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
reset(int fd)
|
||||
{
|
||||
if(tcsetattr(0, TCSAFLUSH, &tiosaved) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* tty1: unix tty
|
||||
* tty2: serial port */
|
||||
void
|
||||
readwrite(int tty1in, int tty1out, int tty2in, int tty2out)
|
||||
{
|
||||
int n;
|
||||
struct pollfd pfd[2];
|
||||
char c;
|
||||
|
||||
pfd[0].fd = tty2in;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[1].fd = tty1in;
|
||||
pfd[1].events = POLLIN;
|
||||
while(pfd[0].fd != -1){
|
||||
n = poll(pfd, 2, -1);
|
||||
if(n < 0){
|
||||
perror("error poll");
|
||||
return;
|
||||
}
|
||||
if(n == 0)
|
||||
return;
|
||||
if(pfd[0].revents & POLLHUP)
|
||||
return;
|
||||
/* read from tty2, write to tty1 */
|
||||
if(pfd[0].revents & POLLIN){
|
||||
if(n = read(tty2in, &c, 1), n <= 0)
|
||||
return;
|
||||
else{
|
||||
c &= 0177;
|
||||
//if(c == '\a') c = '.';
|
||||
if(c < 0140)
|
||||
write(tty1out, &c, 1);
|
||||
}
|
||||
}
|
||||
/* read from tty1, write to tty2 */
|
||||
if(pfd[1].revents & POLLIN){
|
||||
if(n = read(tty1in, &c, 1), n <= 0)
|
||||
return;
|
||||
else{
|
||||
if(c == 035)
|
||||
return;
|
||||
/* map character reasonably */
|
||||
if(c == 033) c = 0175; // esc to altmode
|
||||
if(c >= 'a' && c <= 'z') // to upper
|
||||
c &= ~040;
|
||||
c |= 0200; // needed?
|
||||
write(tty2out, &c, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int fd;
|
||||
|
||||
if(argc < 2)
|
||||
return 1;
|
||||
|
||||
fd = open(argv[1], O_RDWR);
|
||||
if(fd < 0)
|
||||
return 1;
|
||||
|
||||
raw(fd);
|
||||
raw(0);
|
||||
|
||||
readwrite(0, 1, fd, fd);
|
||||
printf("\r\n\r\n");
|
||||
close(fd);
|
||||
|
||||
reset(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -155,10 +155,11 @@ module apr(
|
||||
wire key_dp_OR_dp_nxt = key_dep_sync | key_dep_nxt;
|
||||
wire key_run_AND_NOT_ex_OR_dep = run & ~key_ex_OR_dep_st;
|
||||
wire key_ex_OR_ex_nxt = key_ex_sync | key_ex_nxt;
|
||||
wire key_manual = key_ex | key_ex_nxt |
|
||||
wire key_manual = ~key_pwr_clr_enbl &
|
||||
(key_ex | key_ex_nxt |
|
||||
key_dep | key_dep_nxt |
|
||||
key_start | key_inst_cont | key_mem_cont |
|
||||
key_io_reset | key_execute | key_read_in;
|
||||
key_io_reset | key_execute | key_read_in);
|
||||
wire key_ex_OR_dep_st = key_ex_st | key_dep_st;
|
||||
wire key_run_AND_ex_OR_dep = run & key_ex_OR_dep_st;
|
||||
wire key_execute_OR_dp_OR_dp_nxt = key_execute | key_dp_OR_dp_nxt;
|
||||
@@ -185,6 +186,7 @@ module apr(
|
||||
|
||||
wire kt0a_D, kt1_D, kt2_D, kt3_D;
|
||||
`ifdef simulation
|
||||
wire key_pwr_clr_enbl = 0;
|
||||
pg key_pg0(.clk(clk), .reset(reset), .in(sw_power), .p(mr_pwr_clr));
|
||||
`else
|
||||
wire sw_power_pulse;
|
||||
@@ -1207,7 +1209,7 @@ module apr(
|
||||
wire ar_jrst_AND_ir11 = ir_jrst & ir[11];
|
||||
wire ar_flag_set = et1 & ar_jrst_AND_ir11;
|
||||
wire ar_jfcl_clr = et10 & ir_jfcl;
|
||||
wire ar_eq_fp_half = ar == 36'o000400000000;
|
||||
wire ar_eq_fp_half = ar[9:35] == 27'o400000000;
|
||||
wire ar_eq_0 = ar == 0;
|
||||
wire ar0_xor_ar1 = ar[0] ^ ar[1];
|
||||
wire ar_ov_set = ar_cry0 ^ ar_cry1;
|
||||
|
||||
404
verilog/core256k_x.v
Normal file
404
verilog/core256k_x.v
Normal file
@@ -0,0 +1,404 @@
|
||||
module core256k(
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire power,
|
||||
input wire sw_single_step,
|
||||
input wire sw_restart,
|
||||
|
||||
input wire membus_wr_rs_p0,
|
||||
input wire membus_rq_cyc_p0,
|
||||
input wire membus_rd_rq_p0,
|
||||
input wire membus_wr_rq_p0,
|
||||
input wire [21:35] membus_ma_p0,
|
||||
input wire [18:21] membus_sel_p0,
|
||||
input wire membus_fmc_select_p0,
|
||||
input wire [0:35] membus_mb_in_p0,
|
||||
output wire membus_addr_ack_p0,
|
||||
output wire membus_rd_rs_p0,
|
||||
output wire [0:35] membus_mb_out_p0,
|
||||
|
||||
input wire membus_wr_rs_p1,
|
||||
input wire membus_rq_cyc_p1,
|
||||
input wire membus_rd_rq_p1,
|
||||
input wire membus_wr_rq_p1,
|
||||
input wire [21:35] membus_ma_p1,
|
||||
input wire [18:21] membus_sel_p1,
|
||||
input wire membus_fmc_select_p1,
|
||||
input wire [0:35] membus_mb_in_p1,
|
||||
output wire membus_addr_ack_p1,
|
||||
output wire membus_rd_rs_p1,
|
||||
output wire [0:35] membus_mb_out_p1,
|
||||
|
||||
input wire membus_wr_rs_p2,
|
||||
input wire membus_rq_cyc_p2,
|
||||
input wire membus_rd_rq_p2,
|
||||
input wire membus_wr_rq_p2,
|
||||
input wire [21:35] membus_ma_p2,
|
||||
input wire [18:21] membus_sel_p2,
|
||||
input wire membus_fmc_select_p2,
|
||||
input wire [0:35] membus_mb_in_p2,
|
||||
output wire membus_addr_ack_p2,
|
||||
output wire membus_rd_rs_p2,
|
||||
output wire [0:35] membus_mb_out_p2,
|
||||
|
||||
input wire membus_wr_rs_p3,
|
||||
input wire membus_rq_cyc_p3,
|
||||
input wire membus_rd_rq_p3,
|
||||
input wire membus_wr_rq_p3,
|
||||
input wire [21:35] membus_ma_p3,
|
||||
input wire [18:21] membus_sel_p3,
|
||||
input wire membus_fmc_select_p3,
|
||||
input wire [0:35] membus_mb_in_p3,
|
||||
output wire membus_addr_ack_p3,
|
||||
output wire membus_rd_rs_p3,
|
||||
output wire [0:35] membus_mb_out_p3,
|
||||
|
||||
// 36 bit Avalon Master
|
||||
output wire [17:0] m_address,
|
||||
output reg m_write,
|
||||
output reg m_read,
|
||||
output wire [35:0] m_writedata,
|
||||
input wire [35:0] m_readdata,
|
||||
input wire m_waitrequest
|
||||
);
|
||||
// TODO: SP
|
||||
wire cmc_sp = 0;
|
||||
|
||||
reg [18:35] cma;
|
||||
reg cma_rd_rq, cma_wr_rq;
|
||||
reg [0:35] cmb;
|
||||
|
||||
// TODO: interleave
|
||||
|
||||
wire cmpc_p0_rq =
|
||||
~membus_fmc_select_p0 &
|
||||
membus_rq_cyc_p0 &
|
||||
cmc_await_rq;
|
||||
wire cmpc_p1_rq =
|
||||
~membus_fmc_select_p1 &
|
||||
membus_rq_cyc_p1 &
|
||||
cmc_await_rq;
|
||||
wire cmpc_p2_rq =
|
||||
~membus_fmc_select_p2 &
|
||||
membus_rq_cyc_p2 &
|
||||
cmc_await_rq;
|
||||
wire cmpc_p3_rq =
|
||||
~membus_fmc_select_p3 &
|
||||
membus_rq_cyc_p3 &
|
||||
cmc_await_rq;
|
||||
|
||||
wire [18:35] ma_p0 = { membus_sel_p0[18:21], membus_ma_p0[22:35] };
|
||||
wire [18:35] ma_p1 = { membus_sel_p1[18:21], membus_ma_p1[22:35] };
|
||||
wire [18:35] ma_p2 = { membus_sel_p2[18:21], membus_ma_p2[22:35] };
|
||||
wire [18:35] ma_p3 = { membus_sel_p3[18:21], membus_ma_p3[22:35] };
|
||||
|
||||
wire [18:35] ma_in =
|
||||
{18{cmc_p0_sel}}&ma_p0 |
|
||||
{18{cmc_p1_sel}}&ma_p1 |
|
||||
{18{cmc_p2_sel}}&ma_p2 |
|
||||
{18{cmc_p3_sel}}&ma_p3;
|
||||
wire rd_rq_in =
|
||||
cmc_p0_sel&membus_rd_rq_p0 |
|
||||
cmc_p1_sel&membus_rd_rq_p1 |
|
||||
cmc_p2_sel&membus_rd_rq_p2 |
|
||||
cmc_p3_sel&membus_rd_rq_p3;
|
||||
wire wr_rq_in =
|
||||
cmc_p0_sel&membus_wr_rq_p0 |
|
||||
cmc_p1_sel&membus_wr_rq_p1 |
|
||||
cmc_p2_sel&membus_wr_rq_p2 |
|
||||
cmc_p3_sel&membus_wr_rq_p3;
|
||||
wire [0:35] mb_in =
|
||||
{36{cmc_p0_sel}}&membus_mb_in_p0 |
|
||||
{36{cmc_p1_sel}}&membus_mb_in_p1 |
|
||||
{36{cmc_p2_sel}}&membus_mb_in_p2 |
|
||||
{36{cmc_p3_sel}}&membus_mb_in_p3;
|
||||
pa cmpc_pa0(clk, reset, cmc_t1b&cmc_p0_sel, membus_addr_ack_p0);
|
||||
pa cmpc_pa1(clk, reset, cmc_t1b&cmc_p1_sel, membus_addr_ack_p1);
|
||||
pa cmpc_pa2(clk, reset, cmc_t1b&cmc_p2_sel, membus_addr_ack_p2);
|
||||
pa cmpc_pa3(clk, reset, cmc_t1b&cmc_p3_sel, membus_addr_ack_p3);
|
||||
assign membus_rd_rs_p0 = cmc_rd_rs&cmc_p0_sel;
|
||||
assign membus_rd_rs_p1 = cmc_rd_rs&cmc_p1_sel;
|
||||
assign membus_rd_rs_p2 = cmc_rd_rs&cmc_p2_sel;
|
||||
assign membus_rd_rs_p3 = cmc_rd_rs&cmc_p3_sel;
|
||||
assign membus_mb_out_p0 = sa & {36{stb_pulse & cmc_p0_sel}};
|
||||
assign membus_mb_out_p1 = sa & {36{stb_pulse & cmc_p1_sel}};
|
||||
assign membus_mb_out_p2 = sa & {36{stb_pulse & cmc_p2_sel}};
|
||||
assign membus_mb_out_p3 = sa & {36{stb_pulse & cmc_p3_sel}};
|
||||
wire cmpc_rs_set = membus_wr_rs_p0 & cmc_p0_sel |
|
||||
membus_wr_rs_p1 & cmc_p1_sel |
|
||||
membus_wr_rs_p2 & cmc_p2_sel |
|
||||
membus_wr_rs_p3 & cmc_p3_sel;
|
||||
|
||||
|
||||
// TODO: this is all wrong
|
||||
wire pwr_t1, pwr_t2, pwr_t3;
|
||||
wire cmc_await_rq_reset, cmc_pwr_clr, cmc_pwr_start;
|
||||
pg pg0(clk, reset, power, pwr_t1);
|
||||
// 200ms
|
||||
ldly1us dly0(clk, reset, pwr_t1, pwr_t2, cmc_await_rq_reset);
|
||||
// 100μs
|
||||
ldly1us dly1(clk, reset, pwr_t2, pwr_t3, cmc_pwr_clr);
|
||||
pa pa0(clk, reset, pwr_t3, cmc_pwr_start);
|
||||
|
||||
|
||||
// core control, we don't really have a use for it
|
||||
reg cmc_read, cmc_write, cmc_inh;
|
||||
|
||||
reg cmc_rq_sync, cmc_cyc_done;
|
||||
reg cmc_await_rq, cmc_pse_sync, cmc_proc_rs, cmc_stop;
|
||||
|
||||
reg cmc_p0_act, cmc_p1_act, cmc_p2_act, cmc_p3_act;
|
||||
reg cmc_last_proc;
|
||||
|
||||
// TODO: SP
|
||||
wire cmc_p0_sel = cmc_p0_act;
|
||||
wire cmc_p1_sel = cmc_p1_act;
|
||||
wire cmc_p2_sel = cmc_p2_act;
|
||||
wire cmc_p3_sel = cmc_p3_act;
|
||||
|
||||
wire cmc_t0, cmc_t1b, cmc_t1a, cmc_t2, cmc_t3;
|
||||
wire cmc_t4, cmc_t5, cmc_t6, cmc_t6p;
|
||||
wire cmc_t0_D, cmc_t2_D1;
|
||||
wire cmc_t3_D1, cmc_t3_D2;
|
||||
|
||||
wire cmc_restart;
|
||||
wire cmc_start;
|
||||
wire cmc_state_clr;
|
||||
wire cmc_pn_act = cmc_p0_act | cmc_p1_act | cmc_p2_act | cmc_p3_act;
|
||||
wire cmc_aw_rq_set = cmc_t0_D & ~cmc_pn_act;
|
||||
wire cmc_rq_sync_set = cmc_t0_D & ~cmc_sp & cmc_pn_act;
|
||||
wire cmc_jam_cma = cmc_t1b;
|
||||
wire cmc_cmb_clr;
|
||||
wire cmc_read_off;
|
||||
wire cmc_pse_sync_set;
|
||||
wire strobe_sense;
|
||||
wire cmc_rd_rs;
|
||||
wire cmpc_rs_set_D;
|
||||
wire cmc_proc_rs_pulse;
|
||||
|
||||
pa pa1(clk, reset,
|
||||
(cmpc_p0_rq | cmpc_p1_rq | cmpc_p2_rq | cmpc_p3_rq),
|
||||
cmc_t0);
|
||||
pa pa2(clk, reset, cmc_restart | cmc_pwr_start, cmc_start);
|
||||
pa pa3(clk, reset, cmc_start | cmc_t3_D1, cmc_t5);
|
||||
pa pa4(clk, reset, cmc_start | cmc_t3_D2, cmc_t6p);
|
||||
pa pa5(clk, reset,
|
||||
cmc_start | cmc_t3 & ~cma_wr_rq | cmc_proc_rs_pulse,
|
||||
cmc_state_clr);
|
||||
pa pa6(clk, reset, cmc_rq_sync&cmc_cyc_done, cmc_t1b);
|
||||
pa pa7(clk, reset, cmc_t1b, cmc_t1a);
|
||||
pa pa9(clk, reset,
|
||||
cmc_t1b | cmc_pse_sync_set&cma_rd_rq&cma_wr_rq,
|
||||
cmc_cmb_clr);
|
||||
pa pa11(clk, reset, cmc_t2_D1&cma_rd_rq, strobe_sense);
|
||||
pa pa12(clk, reset, stb_pulse, cmc_rd_rs);
|
||||
|
||||
pa pa13(clk, reset, cmc_pse_sync&(cmc_proc_rs | ~cma_wr_rq), cmc_t3);
|
||||
pa pa14(clk, reset, cmc_proc_rs, cmc_proc_rs_pulse);
|
||||
// probably wrong
|
||||
pa pa15(clk, reset, sw_restart, cmc_restart);
|
||||
|
||||
|
||||
dly250ns dly2(clk, reset, cmc_t6p, cmc_t6);
|
||||
dly100ns dly3(clk, reset, cmc_t0, cmc_t0_D);
|
||||
dly250ns dly4(clk, reset, cmc_t1a, cmc_t2);
|
||||
dly200ns dly5(clk, reset, cmc_t2, cmc_read_off);
|
||||
dly100ns dly6(clk, reset, rd_pulse, cmc_pse_sync_set);
|
||||
// Variable 35-100ns
|
||||
dly70ns dly7(clk, reset, cmc_t2, cmc_t2_D1);
|
||||
dly50ns dly9(clk, reset, cmc_t3, cmc_t4);
|
||||
dly500ns dly10(clk, reset, cmc_t4, cmc_t3_D1);
|
||||
dly200ns dly11(clk, reset, cmc_t3_D1, cmc_t3_D2);
|
||||
dly50ns dly12(clk, reset, cmpc_rs_set, cmpc_rs_set_D);
|
||||
|
||||
|
||||
reg [0:35] sa; // "sense amplifiers"
|
||||
wire [17:0] core_addr = cma[18:35];
|
||||
|
||||
assign m_address = core_addr;
|
||||
assign m_writedata = cmb;
|
||||
|
||||
|
||||
reg stb_sync, stb_done;
|
||||
wire stb_pulse;
|
||||
pa pa100(clk, reset, stb_sync&stb_done, stb_pulse);
|
||||
|
||||
reg rd_sync, rd_done;
|
||||
wire rd_pulse;
|
||||
pa pa101(clk, reset, rd_sync&rd_done, rd_pulse);
|
||||
|
||||
reg wr_sync, wr_done;
|
||||
wire wr_pulse;
|
||||
pa pa102(clk, reset, wr_sync&wr_done, wr_pulse);
|
||||
|
||||
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if(reset) begin
|
||||
m_read <= 0;
|
||||
m_write <= 0;
|
||||
sa <= 0;
|
||||
|
||||
stb_sync <= 0;
|
||||
stb_done <= 0;
|
||||
rd_sync <= 0;
|
||||
rd_done <= 0;
|
||||
wr_sync <= 0;
|
||||
wr_done <= 0;
|
||||
|
||||
// value doesn't matter
|
||||
cmc_last_proc <= 0;
|
||||
// these should probably be reset but aren't
|
||||
cmc_proc_rs <= 0;
|
||||
cmc_pse_sync <= 0;
|
||||
end else begin
|
||||
if(m_write & ~m_waitrequest) begin
|
||||
m_write <= 0;
|
||||
wr_done <= 1;
|
||||
end
|
||||
if(m_read & ~m_waitrequest) begin
|
||||
m_read <= 0;
|
||||
sa <= m_readdata;
|
||||
stb_done <= 1;
|
||||
end
|
||||
|
||||
if(cmc_start)
|
||||
wr_done <= 1;
|
||||
|
||||
if(cmc_state_clr) begin
|
||||
cmc_p0_act <= 0;
|
||||
cmc_p1_act <= 0;
|
||||
cmc_p2_act <= 0;
|
||||
cmc_p3_act <= 0;
|
||||
end
|
||||
if(cmpc_p0_rq | cmpc_p1_rq | cmpc_p2_rq | cmpc_p3_rq) begin
|
||||
if(cmpc_p0_rq) begin
|
||||
cmc_p0_act <= 1;
|
||||
cmc_p1_act <= 0;
|
||||
cmc_p2_act <= 0;
|
||||
cmc_p3_act <= 0;
|
||||
end else if(cmpc_p1_rq) begin
|
||||
cmc_p0_act <= 0;
|
||||
cmc_p1_act <= 1;
|
||||
cmc_p2_act <= 0;
|
||||
cmc_p3_act <= 0;
|
||||
end else if(cmpc_p2_rq & cmpc_p3_rq) begin
|
||||
cmc_p0_act <= 0;
|
||||
cmc_p1_act <= 0;
|
||||
cmc_p2_act <= cmc_last_proc;
|
||||
cmc_p3_act <= ~cmc_last_proc;
|
||||
cmc_last_proc <= ~cmc_last_proc;
|
||||
end else if(cmpc_p2_rq) begin
|
||||
cmc_p0_act <= 0;
|
||||
cmc_p1_act <= 0;
|
||||
cmc_p2_act <= 1;
|
||||
cmc_p3_act <= 0;
|
||||
end else if(cmpc_p3_rq) begin
|
||||
cmc_p0_act <= 0;
|
||||
cmc_p1_act <= 0;
|
||||
cmc_p2_act <= 0;
|
||||
cmc_p3_act <= 1;
|
||||
end
|
||||
end
|
||||
if(cmc_t2) begin
|
||||
if(cmc_p2_act)
|
||||
cmc_last_proc <= 0;
|
||||
if(cmc_p3_act)
|
||||
cmc_last_proc <= 1;
|
||||
end
|
||||
|
||||
if(cmc_t0 | cmc_await_rq_reset)
|
||||
cmc_await_rq <= 0;
|
||||
if(cmc_t5 | cmc_aw_rq_set)
|
||||
cmc_await_rq <= 1;
|
||||
|
||||
if(cmc_start | cmc_pwr_clr)
|
||||
cmc_rq_sync <= 0;
|
||||
if(cmc_rq_sync_set | cmc_t0 & cmc_sp)
|
||||
cmc_rq_sync <= 1;
|
||||
|
||||
if(cmc_pwr_clr)
|
||||
cmc_cyc_done <= 0;
|
||||
if(wr_pulse & ~cmc_stop)
|
||||
cmc_cyc_done <= 1;
|
||||
if(cmc_t6)
|
||||
wr_sync <= 1;
|
||||
|
||||
if(cmc_t1b) begin
|
||||
cmc_pse_sync <= 0;
|
||||
cmc_proc_rs <= 0;
|
||||
cmc_stop <= 0;
|
||||
end
|
||||
|
||||
// actually through another PA
|
||||
if(cmc_pse_sync_set)
|
||||
cmc_pse_sync <= 1;
|
||||
|
||||
if(cmpc_rs_set_D)
|
||||
cmc_proc_rs <= 1;
|
||||
|
||||
if(cmc_start)
|
||||
cmc_stop <= 0;
|
||||
if(cmc_t2 & sw_single_step)
|
||||
cmc_stop <= 1;
|
||||
|
||||
if(cmc_t2) begin
|
||||
cmc_rq_sync <= 0;
|
||||
cmc_cyc_done <= 0;
|
||||
end
|
||||
|
||||
|
||||
if(cmc_jam_cma) begin
|
||||
cma <= ma_in;
|
||||
cma_rd_rq <= rd_rq_in;
|
||||
cma_wr_rq <= wr_rq_in;
|
||||
end
|
||||
|
||||
cmb <= cmb | mb_in;
|
||||
if(cmc_cmb_clr)
|
||||
cmb <= 0;
|
||||
if(strobe_sense)
|
||||
stb_sync <= 1;
|
||||
if(stb_pulse) begin
|
||||
stb_sync <= 0;
|
||||
stb_done <= 0;
|
||||
rd_done <= 1;
|
||||
cmb <= cmb | sa;
|
||||
end
|
||||
|
||||
/* Core */
|
||||
if(cmc_pwr_clr | cmc_t5) begin
|
||||
cmc_read <= 0;
|
||||
cmc_write <= 0;
|
||||
cmc_inh <= 0;
|
||||
end
|
||||
if(cmc_t1a) begin
|
||||
cmc_read <= 1;
|
||||
m_read <= cma_rd_rq;
|
||||
stb_done <= 0;
|
||||
rd_done <= ~cma_rd_rq;
|
||||
cmc_write <= 0;
|
||||
end
|
||||
if(cmc_read_off) begin
|
||||
cmc_read <= 0;
|
||||
rd_sync <= 1;
|
||||
end
|
||||
if(rd_pulse) begin
|
||||
rd_sync <= 0;
|
||||
rd_done <= 0;
|
||||
end
|
||||
if(cmc_t3) begin
|
||||
cmc_inh <= 1;
|
||||
m_write <= cma_wr_rq;
|
||||
wr_done <= ~cma_wr_rq;
|
||||
end
|
||||
if(cmc_t4) begin
|
||||
cmc_write <= 1;
|
||||
cmc_read <= 0;
|
||||
end
|
||||
if(wr_pulse) begin
|
||||
wr_sync <= 0;
|
||||
wr_done <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
0
verilog/core32k.v
Normal file → Executable file
0
verilog/core32k.v
Normal file → Executable file
405
verilog/core32k_x.v
Normal file
405
verilog/core32k_x.v
Normal file
@@ -0,0 +1,405 @@
|
||||
module core32k(
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire power,
|
||||
input wire sw_single_step,
|
||||
input wire sw_restart,
|
||||
|
||||
input wire membus_wr_rs_p0,
|
||||
input wire membus_rq_cyc_p0,
|
||||
input wire membus_rd_rq_p0,
|
||||
input wire membus_wr_rq_p0,
|
||||
input wire [21:35] membus_ma_p0,
|
||||
input wire [18:21] membus_sel_p0,
|
||||
input wire membus_fmc_select_p0,
|
||||
input wire [0:35] membus_mb_in_p0,
|
||||
output wire membus_addr_ack_p0,
|
||||
output wire membus_rd_rs_p0,
|
||||
output wire [0:35] membus_mb_out_p0,
|
||||
|
||||
input wire membus_wr_rs_p1,
|
||||
input wire membus_rq_cyc_p1,
|
||||
input wire membus_rd_rq_p1,
|
||||
input wire membus_wr_rq_p1,
|
||||
input wire [21:35] membus_ma_p1,
|
||||
input wire [18:21] membus_sel_p1,
|
||||
input wire membus_fmc_select_p1,
|
||||
input wire [0:35] membus_mb_in_p1,
|
||||
output wire membus_addr_ack_p1,
|
||||
output wire membus_rd_rs_p1,
|
||||
output wire [0:35] membus_mb_out_p1,
|
||||
|
||||
input wire membus_wr_rs_p2,
|
||||
input wire membus_rq_cyc_p2,
|
||||
input wire membus_rd_rq_p2,
|
||||
input wire membus_wr_rq_p2,
|
||||
input wire [21:35] membus_ma_p2,
|
||||
input wire [18:21] membus_sel_p2,
|
||||
input wire membus_fmc_select_p2,
|
||||
input wire [0:35] membus_mb_in_p2,
|
||||
output wire membus_addr_ack_p2,
|
||||
output wire membus_rd_rs_p2,
|
||||
output wire [0:35] membus_mb_out_p2,
|
||||
|
||||
input wire membus_wr_rs_p3,
|
||||
input wire membus_rq_cyc_p3,
|
||||
input wire membus_rd_rq_p3,
|
||||
input wire membus_wr_rq_p3,
|
||||
input wire [21:35] membus_ma_p3,
|
||||
input wire [18:21] membus_sel_p3,
|
||||
input wire membus_fmc_select_p3,
|
||||
input wire [0:35] membus_mb_in_p3,
|
||||
output wire membus_addr_ack_p3,
|
||||
output wire membus_rd_rs_p3,
|
||||
output wire [0:35] membus_mb_out_p3,
|
||||
|
||||
// 36 bit Avalon Master
|
||||
output wire [17:0] m_address,
|
||||
output reg m_write,
|
||||
output reg m_read,
|
||||
output wire [35:0] m_writedata,
|
||||
input wire [35:0] m_readdata,
|
||||
input wire m_waitrequest
|
||||
);
|
||||
/* Jumpers */
|
||||
parameter [3:0] memsel_p0 = 4'b0;
|
||||
parameter [3:0] memsel_p1 = 4'b0;
|
||||
parameter [3:0] memsel_p2 = 4'b0;
|
||||
parameter [3:0] memsel_p3 = 4'b0;
|
||||
|
||||
// TODO: SP
|
||||
wire cmc_sp = 0;
|
||||
|
||||
reg [21:35] cma;
|
||||
reg cma_rd_rq, cma_wr_rq;
|
||||
reg [0:35] cmb;
|
||||
|
||||
// TODO: interleave
|
||||
|
||||
wire cmpc_p0_rq = (membus_sel_p0[18:20] == memsel_p0[3:1]) &
|
||||
~membus_fmc_select_p0 &
|
||||
membus_rq_cyc_p0 &
|
||||
cmc_await_rq;
|
||||
wire cmpc_p1_rq = (membus_sel_p1[18:20] == memsel_p1[3:1]) &
|
||||
~membus_fmc_select_p1 &
|
||||
membus_rq_cyc_p1 &
|
||||
cmc_await_rq;
|
||||
wire cmpc_p2_rq = (membus_sel_p2[18:20] == memsel_p2[3:1]) &
|
||||
~membus_fmc_select_p2 &
|
||||
membus_rq_cyc_p2 &
|
||||
cmc_await_rq;
|
||||
wire cmpc_p3_rq = (membus_sel_p3[18:20] == memsel_p3[3:1]) &
|
||||
~membus_fmc_select_p3 &
|
||||
membus_rq_cyc_p3 &
|
||||
cmc_await_rq;
|
||||
|
||||
wire [21:35] ma_in =
|
||||
{15{cmc_p0_sel}}&membus_ma_p0 |
|
||||
{15{cmc_p1_sel}}&membus_ma_p1 |
|
||||
{15{cmc_p2_sel}}&membus_ma_p2 |
|
||||
{15{cmc_p3_sel}}&membus_ma_p3;
|
||||
wire rd_rq_in =
|
||||
cmc_p0_sel&membus_rd_rq_p0 |
|
||||
cmc_p1_sel&membus_rd_rq_p1 |
|
||||
cmc_p2_sel&membus_rd_rq_p2 |
|
||||
cmc_p3_sel&membus_rd_rq_p3;
|
||||
wire wr_rq_in =
|
||||
cmc_p0_sel&membus_wr_rq_p0 |
|
||||
cmc_p1_sel&membus_wr_rq_p1 |
|
||||
cmc_p2_sel&membus_wr_rq_p2 |
|
||||
cmc_p3_sel&membus_wr_rq_p3;
|
||||
wire [0:35] mb_in =
|
||||
{36{cmc_p0_sel}}&membus_mb_in_p0 |
|
||||
{36{cmc_p1_sel}}&membus_mb_in_p1 |
|
||||
{36{cmc_p2_sel}}&membus_mb_in_p2 |
|
||||
{36{cmc_p3_sel}}&membus_mb_in_p3;
|
||||
pa cmpc_pa0(clk, reset, cmc_t1b&cmc_p0_sel, membus_addr_ack_p0);
|
||||
pa cmpc_pa1(clk, reset, cmc_t1b&cmc_p1_sel, membus_addr_ack_p1);
|
||||
pa cmpc_pa2(clk, reset, cmc_t1b&cmc_p2_sel, membus_addr_ack_p2);
|
||||
pa cmpc_pa3(clk, reset, cmc_t1b&cmc_p3_sel, membus_addr_ack_p3);
|
||||
assign membus_rd_rs_p0 = cmc_rd_rs&cmc_p0_sel;
|
||||
assign membus_rd_rs_p1 = cmc_rd_rs&cmc_p1_sel;
|
||||
assign membus_rd_rs_p2 = cmc_rd_rs&cmc_p2_sel;
|
||||
assign membus_rd_rs_p3 = cmc_rd_rs&cmc_p3_sel;
|
||||
assign membus_mb_out_p0 = sa & {36{stb_pulse & cmc_p0_sel}};
|
||||
assign membus_mb_out_p1 = sa & {36{stb_pulse & cmc_p1_sel}};
|
||||
assign membus_mb_out_p2 = sa & {36{stb_pulse & cmc_p2_sel}};
|
||||
assign membus_mb_out_p3 = sa & {36{stb_pulse & cmc_p3_sel}};
|
||||
wire cmpc_rs_set = membus_wr_rs_p0 & cmc_p0_sel |
|
||||
membus_wr_rs_p1 & cmc_p1_sel |
|
||||
membus_wr_rs_p2 & cmc_p2_sel |
|
||||
membus_wr_rs_p3 & cmc_p3_sel;
|
||||
|
||||
|
||||
// TODO: this is all wrong
|
||||
wire pwr_t1, pwr_t2, pwr_t3;
|
||||
wire cmc_await_rq_reset, cmc_pwr_clr, cmc_pwr_start;
|
||||
pg pg0(clk, reset, power, pwr_t1);
|
||||
// 200ms
|
||||
ldly1us dly0(clk, reset, pwr_t1, pwr_t2, cmc_await_rq_reset);
|
||||
// 100μs
|
||||
ldly1us dly1(clk, reset, pwr_t2, pwr_t3, cmc_pwr_clr);
|
||||
pa pa0(clk, reset, pwr_t3, cmc_pwr_start);
|
||||
|
||||
|
||||
// core control, we don't really have a use for it
|
||||
reg cmc_read, cmc_write, cmc_inh;
|
||||
|
||||
reg cmc_rq_sync, cmc_cyc_done;
|
||||
reg cmc_await_rq, cmc_pse_sync, cmc_proc_rs, cmc_stop;
|
||||
|
||||
reg cmc_p0_act, cmc_p1_act, cmc_p2_act, cmc_p3_act;
|
||||
reg cmc_last_proc;
|
||||
|
||||
// TODO: SP
|
||||
wire cmc_p0_sel = cmc_p0_act;
|
||||
wire cmc_p1_sel = cmc_p1_act;
|
||||
wire cmc_p2_sel = cmc_p2_act;
|
||||
wire cmc_p3_sel = cmc_p3_act;
|
||||
|
||||
wire cmc_t0, cmc_t1b, cmc_t1a, cmc_t2, cmc_t3;
|
||||
wire cmc_t4, cmc_t5, cmc_t6, cmc_t6p;
|
||||
wire cmc_t0_D, cmc_t2_D1;
|
||||
wire cmc_t3_D1, cmc_t3_D2;
|
||||
|
||||
wire cmc_restart;
|
||||
wire cmc_start;
|
||||
wire cmc_state_clr;
|
||||
wire cmc_pn_act = cmc_p0_act | cmc_p1_act | cmc_p2_act | cmc_p3_act;
|
||||
wire cmc_aw_rq_set = cmc_t0_D & ~cmc_pn_act;
|
||||
wire cmc_rq_sync_set = cmc_t0_D & ~cmc_sp & cmc_pn_act;
|
||||
wire cmc_jam_cma = cmc_t1b;
|
||||
wire cmc_cmb_clr;
|
||||
wire cmc_read_off;
|
||||
wire cmc_pse_sync_set;
|
||||
wire strobe_sense;
|
||||
wire cmc_rd_rs;
|
||||
wire cmpc_rs_set_D;
|
||||
wire cmc_proc_rs_pulse;
|
||||
|
||||
pa pa1(clk, reset,
|
||||
(cmpc_p0_rq | cmpc_p1_rq | cmpc_p2_rq | cmpc_p3_rq),
|
||||
cmc_t0);
|
||||
pa pa2(clk, reset, cmc_restart | cmc_pwr_start, cmc_start);
|
||||
pa pa3(clk, reset, cmc_start | cmc_t3_D1, cmc_t5);
|
||||
pa pa4(clk, reset, cmc_start | cmc_t3_D2, cmc_t6p);
|
||||
pa pa5(clk, reset,
|
||||
cmc_start | cmc_t3 & ~cma_wr_rq | cmc_proc_rs_pulse,
|
||||
cmc_state_clr);
|
||||
pa pa6(clk, reset, cmc_rq_sync&cmc_cyc_done, cmc_t1b);
|
||||
pa pa7(clk, reset, cmc_t1b, cmc_t1a);
|
||||
pa pa9(clk, reset,
|
||||
cmc_t1b | cmc_pse_sync_set&cma_rd_rq&cma_wr_rq,
|
||||
cmc_cmb_clr);
|
||||
pa pa11(clk, reset, cmc_t2_D1&cma_rd_rq, strobe_sense);
|
||||
pa pa12(clk, reset, stb_pulse, cmc_rd_rs);
|
||||
|
||||
pa pa13(clk, reset, cmc_pse_sync&(cmc_proc_rs | ~cma_wr_rq), cmc_t3);
|
||||
pa pa14(clk, reset, cmc_proc_rs, cmc_proc_rs_pulse);
|
||||
// probably wrong
|
||||
pa pa15(clk, reset, sw_restart, cmc_restart);
|
||||
|
||||
|
||||
dly250ns dly2(clk, reset, cmc_t6p, cmc_t6);
|
||||
dly100ns dly3(clk, reset, cmc_t0, cmc_t0_D);
|
||||
dly250ns dly4(clk, reset, cmc_t1a, cmc_t2);
|
||||
dly200ns dly5(clk, reset, cmc_t2, cmc_read_off);
|
||||
dly100ns dly6(clk, reset, rd_pulse, cmc_pse_sync_set);
|
||||
// Variable 35-100ns
|
||||
dly70ns dly7(clk, reset, cmc_t2, cmc_t2_D1);
|
||||
dly50ns dly9(clk, reset, cmc_t3, cmc_t4);
|
||||
dly500ns dly10(clk, reset, cmc_t4, cmc_t3_D1);
|
||||
dly200ns dly11(clk, reset, cmc_t3_D1, cmc_t3_D2);
|
||||
dly50ns dly12(clk, reset, cmpc_rs_set, cmpc_rs_set_D);
|
||||
|
||||
|
||||
reg [0:35] sa; // "sense amplifiers"
|
||||
wire [14:0] core_addr = cma[21:35];
|
||||
|
||||
assign m_address = { 3'b0, core_addr };
|
||||
assign m_writedata = cmb;
|
||||
|
||||
|
||||
reg stb_sync, stb_done;
|
||||
wire stb_pulse;
|
||||
pa pa100(clk, reset, stb_sync&stb_done, stb_pulse);
|
||||
|
||||
reg rd_sync, rd_done;
|
||||
wire rd_pulse;
|
||||
pa pa101(clk, reset, rd_sync&rd_done, rd_pulse);
|
||||
|
||||
reg wr_sync, wr_done;
|
||||
wire wr_pulse;
|
||||
pa pa102(clk, reset, wr_sync&wr_done, wr_pulse);
|
||||
|
||||
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if(reset) begin
|
||||
m_read <= 0;
|
||||
m_write <= 0;
|
||||
sa <= 0;
|
||||
|
||||
stb_sync <= 0;
|
||||
stb_done <= 0;
|
||||
rd_sync <= 0;
|
||||
rd_done <= 0;
|
||||
wr_sync <= 0;
|
||||
wr_done <= 0;
|
||||
|
||||
// value doesn't matter
|
||||
cmc_last_proc <= 0;
|
||||
// these should probably be reset but aren't
|
||||
cmc_proc_rs <= 0;
|
||||
cmc_pse_sync <= 0;
|
||||
end else begin
|
||||
if(m_write & ~m_waitrequest) begin
|
||||
m_write <= 0;
|
||||
wr_done <= 1;
|
||||
end
|
||||
if(m_read & ~m_waitrequest) begin
|
||||
m_read <= 0;
|
||||
sa <= m_readdata;
|
||||
stb_done <= 1;
|
||||
end
|
||||
|
||||
if(cmc_start)
|
||||
wr_done <= 1;
|
||||
|
||||
if(cmc_state_clr) begin
|
||||
cmc_p0_act <= 0;
|
||||
cmc_p1_act <= 0;
|
||||
cmc_p2_act <= 0;
|
||||
cmc_p3_act <= 0;
|
||||
end
|
||||
if(cmpc_p0_rq | cmpc_p1_rq | cmpc_p2_rq | cmpc_p3_rq) begin
|
||||
if(cmpc_p0_rq) begin
|
||||
cmc_p0_act <= 1;
|
||||
cmc_p1_act <= 0;
|
||||
cmc_p2_act <= 0;
|
||||
cmc_p3_act <= 0;
|
||||
end else if(cmpc_p1_rq) begin
|
||||
cmc_p0_act <= 0;
|
||||
cmc_p1_act <= 1;
|
||||
cmc_p2_act <= 0;
|
||||
cmc_p3_act <= 0;
|
||||
end else if(cmpc_p2_rq & cmpc_p3_rq) begin
|
||||
cmc_p0_act <= 0;
|
||||
cmc_p1_act <= 0;
|
||||
cmc_p2_act <= cmc_last_proc;
|
||||
cmc_p3_act <= ~cmc_last_proc;
|
||||
cmc_last_proc <= ~cmc_last_proc;
|
||||
end else if(cmpc_p2_rq) begin
|
||||
cmc_p0_act <= 0;
|
||||
cmc_p1_act <= 0;
|
||||
cmc_p2_act <= 1;
|
||||
cmc_p3_act <= 0;
|
||||
end else if(cmpc_p3_rq) begin
|
||||
cmc_p0_act <= 0;
|
||||
cmc_p1_act <= 0;
|
||||
cmc_p2_act <= 0;
|
||||
cmc_p3_act <= 1;
|
||||
end
|
||||
end
|
||||
if(cmc_t2) begin
|
||||
if(cmc_p2_act)
|
||||
cmc_last_proc <= 0;
|
||||
if(cmc_p3_act)
|
||||
cmc_last_proc <= 1;
|
||||
end
|
||||
|
||||
if(cmc_t0 | cmc_await_rq_reset)
|
||||
cmc_await_rq <= 0;
|
||||
if(cmc_t5 | cmc_aw_rq_set)
|
||||
cmc_await_rq <= 1;
|
||||
|
||||
if(cmc_start | cmc_pwr_clr)
|
||||
cmc_rq_sync <= 0;
|
||||
if(cmc_rq_sync_set | cmc_t0 & cmc_sp)
|
||||
cmc_rq_sync <= 1;
|
||||
|
||||
if(cmc_pwr_clr)
|
||||
cmc_cyc_done <= 0;
|
||||
if(wr_pulse & ~cmc_stop)
|
||||
cmc_cyc_done <= 1;
|
||||
if(cmc_t6)
|
||||
wr_sync <= 1;
|
||||
|
||||
if(cmc_t1b) begin
|
||||
cmc_pse_sync <= 0;
|
||||
cmc_proc_rs <= 0;
|
||||
cmc_stop <= 0;
|
||||
end
|
||||
|
||||
// actually through another PA
|
||||
if(cmc_pse_sync_set)
|
||||
cmc_pse_sync <= 1;
|
||||
|
||||
if(cmpc_rs_set_D)
|
||||
cmc_proc_rs <= 1;
|
||||
|
||||
if(cmc_start)
|
||||
cmc_stop <= 0;
|
||||
if(cmc_t2 & sw_single_step)
|
||||
cmc_stop <= 1;
|
||||
|
||||
if(cmc_t2) begin
|
||||
cmc_rq_sync <= 0;
|
||||
cmc_cyc_done <= 0;
|
||||
end
|
||||
|
||||
|
||||
if(cmc_jam_cma) begin
|
||||
cma <= ma_in;
|
||||
cma_rd_rq <= rd_rq_in;
|
||||
cma_wr_rq <= wr_rq_in;
|
||||
end
|
||||
|
||||
cmb <= cmb | mb_in;
|
||||
if(cmc_cmb_clr)
|
||||
cmb <= 0;
|
||||
if(strobe_sense)
|
||||
stb_sync <= 1;
|
||||
if(stb_pulse) begin
|
||||
stb_sync <= 0;
|
||||
stb_done <= 0;
|
||||
rd_done <= 1;
|
||||
cmb <= cmb | sa;
|
||||
end
|
||||
|
||||
/* Core */
|
||||
if(cmc_pwr_clr | cmc_t5) begin
|
||||
cmc_read <= 0;
|
||||
cmc_write <= 0;
|
||||
cmc_inh <= 0;
|
||||
end
|
||||
if(cmc_t1a) begin
|
||||
cmc_read <= 1;
|
||||
m_read <= cma_rd_rq;
|
||||
stb_done <= 0;
|
||||
rd_done <= ~cma_rd_rq;
|
||||
cmc_write <= 0;
|
||||
end
|
||||
if(cmc_read_off) begin
|
||||
cmc_read <= 0;
|
||||
rd_sync <= 1;
|
||||
end
|
||||
if(rd_pulse) begin
|
||||
rd_sync <= 0;
|
||||
rd_done <= 0;
|
||||
end
|
||||
if(cmc_t3) begin
|
||||
cmc_inh <= 1;
|
||||
m_write <= cma_wr_rq;
|
||||
wr_done <= ~cma_wr_rq;
|
||||
end
|
||||
if(cmc_t4) begin
|
||||
cmc_write <= 1;
|
||||
cmc_read <= 0;
|
||||
end
|
||||
if(wr_pulse) begin
|
||||
wr_sync <= 0;
|
||||
wr_done <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
@@ -93,10 +93,10 @@ module core64k(
|
||||
membus_rq_cyc_p3 &
|
||||
cmc_await_rq;
|
||||
|
||||
wire ma_p0 = { membus_sel_p0[18:21], membus_ma_p0[22:35] };
|
||||
wire ma_p1 = { membus_sel_p1[18:21], membus_ma_p1[22:35] };
|
||||
wire ma_p2 = { membus_sel_p2[18:21], membus_ma_p2[22:35] };
|
||||
wire ma_p3 = { membus_sel_p3[18:21], membus_ma_p3[22:35] };
|
||||
wire [18:35] ma_p0 = { membus_sel_p0[18:21], membus_ma_p0[22:35] };
|
||||
wire [18:35] ma_p1 = { membus_sel_p1[18:21], membus_ma_p1[22:35] };
|
||||
wire [18:35] ma_p2 = { membus_sel_p2[18:21], membus_ma_p2[22:35] };
|
||||
wire [18:35] ma_p3 = { membus_sel_p3[18:21], membus_ma_p3[22:35] };
|
||||
|
||||
wire [20:35] ma_in =
|
||||
{16{cmc_p0_sel}}&ma_p0 |
|
||||
|
||||
581
verilog/dis340.v
Normal file
581
verilog/dis340.v
Normal file
@@ -0,0 +1,581 @@
|
||||
module dis340(
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
/* IO bus - 344 interface */
|
||||
input wire iobus_iob_poweron,
|
||||
input wire iobus_iob_reset,
|
||||
input wire iobus_datao_clear,
|
||||
input wire iobus_datao_set,
|
||||
input wire iobus_cono_clear,
|
||||
input wire iobus_cono_set,
|
||||
input wire iobus_iob_fm_datai,
|
||||
input wire iobus_iob_fm_status,
|
||||
input wire iobus_rdi_pulse, // unused on 6
|
||||
input wire [3:9] iobus_ios,
|
||||
input wire [0:35] iobus_iob_in,
|
||||
output wire [1:7] iobus_pi_req,
|
||||
output wire [0:35] iobus_iob_out,
|
||||
output wire iobus_dr_split,
|
||||
output wire iobus_rdi_data, // unused on 6
|
||||
|
||||
/* Indicators */
|
||||
output wire [0:17] br_ind,
|
||||
output wire [0:6] brm_ind,
|
||||
output wire [0:9] x_ind,
|
||||
output wire [0:9] y_ind,
|
||||
output wire [1:4] s_ind,
|
||||
output wire [0:2] i_ind,
|
||||
output wire [0:2] mode_ind,
|
||||
output wire [0:1] sz_ind,
|
||||
output wire [0:8] flags_ind,
|
||||
output wire [0:4] fe_ind,
|
||||
output wire [31:0] foo_ind,
|
||||
|
||||
/* Avalon slave */
|
||||
input wire s_read,
|
||||
output wire [31:0] s_readdata,
|
||||
|
||||
output wire fe_data_rq
|
||||
);
|
||||
assign iobus_dr_split = 0;
|
||||
assign iobus_rdi_data = 0;
|
||||
|
||||
assign br_ind = br;
|
||||
assign brm_ind = brm;
|
||||
assign x_ind = x;
|
||||
assign y_ind = y;
|
||||
assign s_ind = s;
|
||||
assign i_ind = i;
|
||||
assign mode_ind = mode;
|
||||
assign sz_ind = sz;
|
||||
assign flags_ind = {
|
||||
rfd, cf, 1'b0, // TODO: CONT?
|
||||
stop, move, halt,
|
||||
lp_flag, lp_enable, lp_find
|
||||
};
|
||||
|
||||
/* 344 - fantasy */
|
||||
|
||||
wire dis_sel = iobus_ios == 7'b001_011_0;
|
||||
|
||||
wire dis_data_clr;
|
||||
wire dis_data_set;
|
||||
wire dis_ic_clr;
|
||||
wire dis_ic_set;
|
||||
wire iob_reset;
|
||||
wire dis_datai = dis_sel & iobus_iob_fm_datai;
|
||||
wire dis_status = dis_sel & iobus_iob_fm_status;
|
||||
pa ptr_pa0(clk, reset, dis_sel & iobus_datao_clear, dis_data_clr);
|
||||
pa ptr_pa1(clk, reset, dis_sel & iobus_datao_set, dis_data_set);
|
||||
pa ptr_pa2(clk, reset, dis_sel & iobus_cono_clear | iob_reset, dis_ic_clr);
|
||||
pa ptr_pa3(clk, reset, dis_sel & iobus_cono_set, dis_ic_set);
|
||||
pa ptr_pa4(clk, reset, iobus_iob_reset, iob_reset);
|
||||
|
||||
assign iobus_iob_out =
|
||||
dis_datai ? { y, 9'b0, x } :
|
||||
dis_status ? { edge_flag_vert, lp_flag, edge_flag_horiz,
|
||||
stop_inter, done_flag, 1'b0,
|
||||
dis_pia_spec, dis_pia_data } :
|
||||
36'b0;
|
||||
|
||||
wire dis_flag_spec = edge_flag_vert | edge_flag_horiz |
|
||||
lp_flag | stop_inter;
|
||||
wire dis_flag_data = done_flag;
|
||||
wire [1:7] dis_req_spec = { dis_flag_spec, 7'b0 } >> dis_pia_spec;
|
||||
wire [1:7] dis_req_data = { dis_flag_data, 7'b0 } >> dis_pia_data;
|
||||
assign iobus_pi_req = dis_req_spec | dis_req_data;
|
||||
|
||||
reg [30:32] dis_pia_spec;
|
||||
reg [33:35] dis_pia_data;
|
||||
reg [0:35] dis_ib;
|
||||
reg [0:1] dis_ibc;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(dis_ic_clr) begin
|
||||
dis_pia_spec <= 0;
|
||||
dis_pia_data <= 0;
|
||||
|
||||
// not quite sure..
|
||||
dis_ib <= 0;
|
||||
dis_ibc <= 0;
|
||||
end
|
||||
if(dis_ic_set) begin
|
||||
dis_pia_spec <= iobus_iob_in[30:32];
|
||||
dis_pia_data <= iobus_iob_in[33:35];
|
||||
end
|
||||
|
||||
if(dis_data_clr) begin
|
||||
dis_ib <= 0;
|
||||
dis_ibc <= 0;
|
||||
end
|
||||
if(dis_data_set) begin
|
||||
dis_ib <= dis_ib | iobus_iob_in;
|
||||
dis_ibc <= 2'b11;
|
||||
end
|
||||
if(shift_ib) begin
|
||||
dis_ib[0:17] <= dis_ib[18:35];
|
||||
dis_ibc <= { dis_ibc[1], 1'b0 };
|
||||
end
|
||||
end
|
||||
|
||||
wire done_flag = rfd & ~dis_ibc[0];
|
||||
pa dpy_pa100(clk, reset, rfd & dis_ibc[0], data_sync);
|
||||
|
||||
// from interface (?)
|
||||
wire dpy_go = dis_ic_set & iobus_iob_in[29];
|
||||
wire resume = dis_ic_set & ~iobus_iob_in[29];
|
||||
wire data_sync;
|
||||
wire [0:17] br_input = dis_ib[0:17];
|
||||
|
||||
// ??
|
||||
wire clr_flags = 0;
|
||||
|
||||
|
||||
/* light pen */
|
||||
wire lp_pulse = 0;
|
||||
|
||||
|
||||
/* 340 */
|
||||
|
||||
`ifdef simulation
|
||||
initial begin
|
||||
rfd <= 0;
|
||||
halt <= 0;
|
||||
end
|
||||
`endif
|
||||
|
||||
reg rfd;
|
||||
reg stop;
|
||||
reg halt;
|
||||
reg move;
|
||||
wire initiate;
|
||||
wire escape_pulse;
|
||||
wire rfd_pulse;
|
||||
wire idp;
|
||||
wire pm_pulse;
|
||||
wire x_start_pulse;
|
||||
wire y_start_pulse;
|
||||
wire cg_end_pulse;
|
||||
wire next_char;
|
||||
|
||||
wire stop_inter = stop & br[8];
|
||||
|
||||
wire [0:3] inc =
|
||||
{4{s[1]}} & br[2:5] |
|
||||
{4{s[2]}} & br[6:9] |
|
||||
{4{s[3]}} & br[10:13] |
|
||||
{4{s[4]}} & br[14:17];
|
||||
|
||||
wire l = (vm | vcm) & horiz_vec & br[10] |
|
||||
im & inc[0] & inc[1] |
|
||||
cg_l;
|
||||
wire r = (vm | vcm) & horiz_vec & ~br[10] |
|
||||
im & inc[0] & ~inc[1] |
|
||||
cg_r;
|
||||
wire d = (vm | vcm) & vert_vec & br[2] |
|
||||
im & inc[2] & inc[3] |
|
||||
cg_d;
|
||||
wire u = (vm | vcm) & vert_vec & ~br[2] |
|
||||
im & inc[2] & ~inc[3] |
|
||||
cg_u;
|
||||
|
||||
pa dpy_pa0(clk, reset, dpy_go, initiate);
|
||||
pa dpy_pa1(clk, reset,
|
||||
initiate | cg_escape |
|
||||
count_x & br[0] & halt |
|
||||
dly1_pulse & cf,
|
||||
escape_pulse);
|
||||
pa dpy_pa2(clk, reset,
|
||||
dly6_pulse | initiate | cg_escape |
|
||||
count_x & halt |
|
||||
dly1_pulse & cf & vcm | // TODO: ???
|
||||
pm_pulse & ~br[7] |
|
||||
next_char & s[4],
|
||||
rfd_pulse);
|
||||
pa dpy_pa3(clk, reset, data_sync, clr_br);
|
||||
pa dpy_pa4(clk, reset, clr_br, clr_brm);
|
||||
pa dpy_pa5(clk, reset, read_to_s, load_br);
|
||||
wire shift_ib = load_br;
|
||||
// TODO: what's RI?
|
||||
pa dpy_pa7(clk, reset, idp & pm, pm_pulse);
|
||||
pa dpy_pa8(clk, reset, idp & xym & ~lp_flag & br[1], y_start_pulse);
|
||||
pa dpy_pa9(clk, reset, idp & xym & ~lp_flag & ~br[1], x_start_pulse);
|
||||
pa dpy_pa10(clk, reset,
|
||||
pm_pulse | x_start_pulse | y_start_pulse,
|
||||
read_to_mode);
|
||||
pa dpy_pa11(clk, reset, pm_pulse & br[11], store_scale);
|
||||
pa dpy_pa12(clk, reset, pm_pulse & br[14], store_int_level);
|
||||
pa dpy_pa13(clk, reset, y_start_pulse, clr_y);
|
||||
pa dpy_pa14(clk, reset, x_start_pulse | cg_cr, clr_x);
|
||||
pa dpy_pa15(clk, reset, idp & (im | vm | vcm), count_brm);
|
||||
pa dpy_pa16(clk, reset, count_brm | cg_count, count_x);
|
||||
pa dpy_pa17(clk, reset, count_brm | cg_count, count_y);
|
||||
pa dpy_pa18(clk, reset, count_brm | next_char, shift_s);
|
||||
|
||||
pa dpy_pa6(clk, reset, cg_end_level, cg_end_pulse);
|
||||
assign next_char = cg_end_pulse & cm;
|
||||
|
||||
wire int_dly1, int_dly2;
|
||||
wire int_dly = int_dly1 | int_dly2 | cg_intens;
|
||||
wire intensify =
|
||||
int_dly1 & move & br[1] |
|
||||
int_dly2 & br[7] |
|
||||
cg_intens & cg_int;
|
||||
|
||||
wire dly1_pulse; // sequence delay
|
||||
wire dly4_pulse; // 35 deflection delay
|
||||
wire dly6_pulse; // 0.5 after xy intensify
|
||||
ldly500ns intdly_1(clk, reset,
|
||||
load_br | // actually through PA
|
||||
dly1_pulse & ~cf & ~lp_flag & ~rfd |
|
||||
next_char & ~s[4],
|
||||
intdly1_pulse /* idp */, int_dly1);
|
||||
dly2_8us dpy_dly3(clk, reset, clr_br, read_to_s);
|
||||
dly200ns dpy_dly5(clk, reset, x_start_pulse, load_x);
|
||||
dly200ns dpy_dly7(clk, reset, y_start_pulse, load_y);
|
||||
`ifdef simulation
|
||||
dly2_8us dpy_dly4(clk, reset,
|
||||
`else
|
||||
dly35us dpy_dly4(clk, reset,
|
||||
`endif
|
||||
x_start_pulse | y_start_pulse & br[7],
|
||||
dly4_pulse);
|
||||
ldly500ns intdly_2(clk, reset,
|
||||
dly4_pulse | y_start_pulse & ~br[7],
|
||||
intdly2_pulse /* dly6_pulse */, int_dly2);
|
||||
dly1us dpy_dly1(clk, reset,
|
||||
count_brm & ~halt |
|
||||
resume & ~cm,
|
||||
dly1_pulse);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(clr_brm) begin
|
||||
halt <= 0;
|
||||
move <= 0;
|
||||
end
|
||||
if(count_x & im & s[4] |
|
||||
dly1_pulse & vm & brm == 'o177)
|
||||
halt <= 1;
|
||||
|
||||
if(count_x & (l|r|u|d))
|
||||
move <= ~cm;
|
||||
|
||||
if(initiate | clr_flags)
|
||||
stop <= 0;
|
||||
if(pm_pulse & br[7])
|
||||
stop <= 1;
|
||||
|
||||
if(clr_flags | clr_br)
|
||||
rfd <= 0;
|
||||
if(rfd_pulse)
|
||||
rfd <= 1;
|
||||
end
|
||||
|
||||
reg [0:17] br;
|
||||
wire clr_br;
|
||||
wire load_br;
|
||||
|
||||
reg [0:2] mode;
|
||||
wire read_to_mode;
|
||||
wire pm = mode == 3'b000;
|
||||
wire xym = mode == 3'b001;
|
||||
wire sm = mode == 3'b010;
|
||||
wire cm = mode == 3'b011;
|
||||
wire vm = mode == 3'b100;
|
||||
wire vcm = mode == 3'b101;
|
||||
wire im = mode == 3'b110;
|
||||
|
||||
reg [0:1] sz;
|
||||
wire store_scale;
|
||||
wire scx8 = sz == 2'b11;
|
||||
wire scx4 = sz == 2'b10;
|
||||
wire sc = sz[0] | sz[1];
|
||||
|
||||
reg [0:2] i;
|
||||
wire store_int_level;
|
||||
|
||||
reg lp_find;
|
||||
reg lp_enable;
|
||||
reg lp_flag;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(clr_br)
|
||||
br <= 0;
|
||||
if(load_br)
|
||||
br <= br | br_input;
|
||||
|
||||
if(escape_pulse) begin
|
||||
mode <= 0;
|
||||
lp_find <= 0;
|
||||
end
|
||||
if(read_to_mode)
|
||||
mode <= br[2:4];
|
||||
|
||||
if(store_int_level)
|
||||
i <= br[15:17];
|
||||
|
||||
if(store_scale)
|
||||
sz <= br[12:13];
|
||||
|
||||
if(initiate | resume) // initiate not in drawings
|
||||
lp_enable <= 0;
|
||||
if(read_to_mode & br[5])
|
||||
lp_enable <= br[6];
|
||||
|
||||
if(initiate | clr_flags | resume)
|
||||
lp_flag <= 0;
|
||||
if((count_y | read_to_s) & lp_enable & lp_find)
|
||||
lp_flag <= 1;
|
||||
|
||||
if(initiate | resume)
|
||||
lp_find <= 0;
|
||||
if(lp_pulse & lp_enable)
|
||||
lp_find <= 1;
|
||||
end
|
||||
|
||||
|
||||
reg [0:6] brm;
|
||||
wire [0:6] brm_comp;
|
||||
wire clr_brm;
|
||||
wire count_brm;
|
||||
|
||||
assign brm_comp[6] = 1;
|
||||
assign brm_comp[5] = brm[6] | ~br[3]&~br[11];
|
||||
assign brm_comp[4] = (&brm[5:6]) | (&(~br[3:4]))&(&(~br[11:12]));
|
||||
assign brm_comp[3] = (&brm[4:6]) | (&(~br[3:5]))&(&(~br[11:13]));
|
||||
assign brm_comp[2] = (&brm[3:6]) | (&(~br[3:6]))&(&(~br[11:14]));
|
||||
assign brm_comp[1] = (&brm[2:6]);
|
||||
assign brm_comp[0] = (&brm[1:6]);
|
||||
|
||||
wire horiz_vec = (|(~brm[0:6] & brm_comp[0:6] &
|
||||
{ br[17], br[16], br[15], br[14], br[13], br[12], br[11] }));
|
||||
wire vert_vec = (|(~brm[0:6] & brm_comp[0:6] &
|
||||
{ br[9], br[8], br[7], br[6], br[5], br[4], br[3] }));
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(clr_brm)
|
||||
brm <= 0;
|
||||
if(count_brm)
|
||||
brm <= brm ^ brm_comp;
|
||||
end
|
||||
|
||||
reg [1:4] s;
|
||||
wire clr_s = clr_brm; // not on drawings
|
||||
wire shift_s;
|
||||
wire read_to_s;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(clr_s)
|
||||
s <= 0;
|
||||
if(read_to_s & cm)
|
||||
s[2] <= 1;
|
||||
if(read_to_s & im)
|
||||
s[1] <= 1;
|
||||
if(shift_s)
|
||||
s <= { 1'b0, s[1:3] };
|
||||
end
|
||||
|
||||
reg [0:9] x;
|
||||
reg [0:9] y;
|
||||
reg edge_flag_vert;
|
||||
reg edge_flag_horiz;
|
||||
wire clr_x, load_x, count_x;
|
||||
wire clr_y, load_y, count_y;
|
||||
wire clr_cf = clr_brm; // not on drawings
|
||||
|
||||
wire cf = edge_flag_vert | edge_flag_horiz;
|
||||
|
||||
wire [0:9] xyinc = 1<<sz;
|
||||
wire [0:9] xinc = r ? xyinc : l ? -xyinc : 0;
|
||||
wire [0:9] yinc = u ? xyinc : d ? -xyinc : 0;
|
||||
wire [0:9] xsum = x + xinc;
|
||||
wire [0:9] ysum = y + yinc;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(clr_y)
|
||||
y <= 0;
|
||||
if(load_y)
|
||||
y <= y | br[8:17];
|
||||
if(count_y) begin
|
||||
y <= ysum;
|
||||
if((y[0] ^ ysum[0]) & (y[0] ^ yinc[0]))
|
||||
edge_flag_vert <= 1;
|
||||
end
|
||||
|
||||
if(clr_x)
|
||||
x <= 0;
|
||||
if(load_x)
|
||||
x <= x | br[8:17];
|
||||
if(count_x) begin
|
||||
x <= xsum;
|
||||
if((x[0] ^ xsum[0]) & (x[0] ^ xinc[0]))
|
||||
edge_flag_horiz <= 1;
|
||||
end
|
||||
|
||||
if(clr_cf | clr_flags | rfd_pulse) begin
|
||||
edge_flag_vert <= 0;
|
||||
edge_flag_horiz <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
/* 342 char gen - fantasy */
|
||||
wire cg_end_level = cg_end;
|
||||
wire cg_cr;
|
||||
wire cg_count;
|
||||
wire cg_escape;
|
||||
wire cg_intens;
|
||||
wire [0:5] cg_char =
|
||||
{6{s[2]}} & br[0:5] |
|
||||
{6{s[3]}} & br[6:11] |
|
||||
{6{s[4]}} & br[12:17];
|
||||
reg cg_l;
|
||||
reg cg_r;
|
||||
reg cg_d;
|
||||
reg cg_u;
|
||||
reg cg_int;
|
||||
reg cg_end;
|
||||
|
||||
reg cg_so;
|
||||
reg [0:4] cg_pulse;
|
||||
|
||||
reg [31:0] rom_u [0:127];
|
||||
reg [31:0] rom_d [0:127];
|
||||
reg [31:0] rom_l [0:127];
|
||||
reg [31:0] rom_r [0:127];
|
||||
reg [31:0] rom_i [0:127];
|
||||
reg [31:0] rom_end [0:127];
|
||||
reg [29:0] rom_u_q, rom_d_q, rom_l_q, rom_r_q, rom_i_q, rom_end_q;
|
||||
|
||||
initial begin
|
||||
$readmemh("roms/u.rom", rom_u);
|
||||
$readmemh("roms/d.rom", rom_d);
|
||||
$readmemh("roms/l.rom", rom_l);
|
||||
$readmemh("roms/r.rom", rom_r);
|
||||
$readmemh("roms/in.rom", rom_i);
|
||||
$readmemh("roms/end.rom", rom_end);
|
||||
end
|
||||
always @(posedge clk) begin
|
||||
rom_l_q <= rom_l[{cg_so, cg_char}];
|
||||
rom_r_q <= rom_r[{cg_so, cg_char}];
|
||||
rom_d_q <= rom_d[{cg_so, cg_char}];
|
||||
rom_u_q <= rom_u[{cg_so, cg_char}];
|
||||
rom_i_q <= rom_i[{cg_so, cg_char}];
|
||||
rom_end_q <= rom_end[{cg_so, cg_char}];
|
||||
end
|
||||
|
||||
wire cg_start;
|
||||
wire cg_strobe, cg_strobe_0, cg_strobe_1;
|
||||
wire cg_count_0, cg_count_1;
|
||||
|
||||
pa pa_cg0(clk, reset, idp & cm, cg_start);
|
||||
pa pa_cg1(clk, reset, cg_start | cg_count_1, cg_strobe);
|
||||
pa pa_cg2(clk, reset, cg_strobe, cg_strobe_0);
|
||||
pa pa_cg6(clk, reset, cg_strobe_0, cg_strobe_1);
|
||||
pa pa_cg3(clk, reset, cg_strobe_1 & ~cg_end, cg_count);
|
||||
pa pa_cg4(clk, reset, cg_start & (cg_char == 6'o37), cg_escape);
|
||||
pa pa_cg5(clk, reset, cg_start & (cg_char == 6'o34), cg_cr);
|
||||
|
||||
dly1us dly_cg0(clk, reset, cg_count, cg_count_0);
|
||||
ldly500ns intdly_3(clk, reset,
|
||||
cg_count_0, intdly3_pulse /* cg_count_1 */, cg_intens);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(iob_reset | reset) begin
|
||||
cg_l <= 0;
|
||||
cg_r <= 0;
|
||||
cg_d <= 0;
|
||||
cg_u <= 0;
|
||||
cg_int <= 0;
|
||||
cg_end <= 0;
|
||||
|
||||
cg_so <= 0;
|
||||
end
|
||||
|
||||
// TODO: figure out how shift is set
|
||||
if(initiate)
|
||||
cg_so <= 0;
|
||||
|
||||
if(cg_start) begin
|
||||
cg_pulse <= 0;
|
||||
cg_end <= 0; // has to be set before strobe so we can detect an edge
|
||||
if(cg_char == 6'o35)
|
||||
cg_so <= 0;
|
||||
if(cg_char == 6'o36)
|
||||
cg_so <= 1;
|
||||
end
|
||||
|
||||
if(cg_strobe_0) begin
|
||||
cg_l <= rom_l_q[cg_pulse];
|
||||
cg_r <= rom_r_q[cg_pulse];
|
||||
cg_d <= rom_d_q[cg_pulse];
|
||||
cg_u <= rom_u_q[cg_pulse];
|
||||
cg_int <= rom_i_q[cg_pulse];
|
||||
cg_end <= rom_end_q[cg_pulse];
|
||||
cg_pulse <= cg_pulse + 1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
/* FE interface */
|
||||
assign fe_data_rq = fe_req;
|
||||
// assign s_readdata = fe_data;
|
||||
assign s_readdata = { fe_req, 8'b0, i, y, x };
|
||||
reg fe_req;
|
||||
reg fe_rs;
|
||||
// reg [31:0] fe_data;
|
||||
wire int_start;
|
||||
wire intdly1_pulse, intdly2_pulse, intdly3_pulse;
|
||||
reg intdly1_sync, intdly2_sync, intdly3_sync;
|
||||
|
||||
assign fe_ind = { intdly1_sync, intdly2_sync, intdly3_sync, fe_rs, fe_req };
|
||||
|
||||
reg [29:0] foo;
|
||||
always @(posedge clk)
|
||||
foo <= rom_end[{cg_so, cg_char}];
|
||||
assign foo_ind = foo;
|
||||
|
||||
wire fe_reset = reset | iob_reset;
|
||||
|
||||
pa fe_pa0(clk, fe_reset, int_dly, int_start);
|
||||
pa fe_pa1(clk, fe_reset, intdly1_sync & fe_rs, idp);
|
||||
pa fe_pa2(clk, fe_reset, intdly2_sync & fe_rs, dly6_pulse);
|
||||
pa fe_pa3(clk, fe_reset, intdly3_sync & fe_rs, cg_count_1);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(fe_reset) begin
|
||||
intdly1_sync <= 0;
|
||||
intdly2_sync <= 0;
|
||||
intdly3_sync <= 0;
|
||||
fe_req <= 0;
|
||||
fe_rs <= 0;
|
||||
end else begin
|
||||
if(int_start & intensify) begin
|
||||
fe_req <= 1;
|
||||
fe_rs <= 0;
|
||||
// fe_data <= { 1'b1, 8'b0, i, y, x };
|
||||
end
|
||||
if(int_start & ~intensify | s_read) begin
|
||||
fe_req <= 0;
|
||||
fe_rs <= 1;
|
||||
// fe_data <= 0;
|
||||
end
|
||||
|
||||
if(intdly1_pulse)
|
||||
intdly1_sync <= 1;
|
||||
if(idp)
|
||||
intdly1_sync <= 0;
|
||||
|
||||
if(intdly2_pulse)
|
||||
intdly2_sync <= 1;
|
||||
if(dly6_pulse)
|
||||
intdly2_sync <= 0;
|
||||
|
||||
if(intdly3_pulse)
|
||||
intdly3_sync <= 1;
|
||||
if(cg_count_1)
|
||||
intdly3_sync <= 0;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
@@ -143,6 +143,45 @@ module dly450ns(input clk, input reset, input in, output p);
|
||||
endmodule
|
||||
|
||||
|
||||
module dly500ns(input clk, input reset, input in, output p);
|
||||
reg [5-1:0] r;
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if(reset)
|
||||
r <= 0;
|
||||
else begin
|
||||
if(r)
|
||||
r <= r + 5'b1;
|
||||
if(in)
|
||||
r <= 1;
|
||||
end
|
||||
end
|
||||
assign p = r == 25;
|
||||
endmodule
|
||||
|
||||
|
||||
module ldly500ns(input clk, input reset, input in, output p, output reg l);
|
||||
reg [5-1:0] r;
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if(reset) begin
|
||||
r <= 0;
|
||||
l <= 0;
|
||||
end else begin
|
||||
if(r)
|
||||
r <= r + 5'b1;
|
||||
if(in) begin
|
||||
r <= 1;
|
||||
l <= 1;
|
||||
end
|
||||
if(p) begin
|
||||
r <= 0;
|
||||
l <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign p = r == 25;
|
||||
endmodule
|
||||
|
||||
|
||||
module dly550ns(input clk, input reset, input in, output p);
|
||||
reg [5-1:0] r;
|
||||
always @(posedge clk or posedge reset) begin
|
||||
@@ -276,6 +315,38 @@ module ldly2us(input clk, input reset, input in, output p, output reg l);
|
||||
endmodule
|
||||
|
||||
|
||||
module dly2_8us(input clk, input reset, input in, output p);
|
||||
reg [8-1:0] r;
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if(reset)
|
||||
r <= 0;
|
||||
else begin
|
||||
if(r)
|
||||
r <= r + 8'b1;
|
||||
if(in)
|
||||
r <= 1;
|
||||
end
|
||||
end
|
||||
assign p = r == 140;
|
||||
endmodule
|
||||
|
||||
|
||||
module dly35us(input clk, input reset, input in, output p);
|
||||
reg [11-1:0] r;
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if(reset)
|
||||
r <= 0;
|
||||
else begin
|
||||
if(r)
|
||||
r <= r + 11'b1;
|
||||
if(in)
|
||||
r <= 1;
|
||||
end
|
||||
end
|
||||
assign p = r == 1750;
|
||||
endmodule
|
||||
|
||||
|
||||
module dly100us(input clk, input reset, input in, output p);
|
||||
reg [13-1:0] r;
|
||||
always @(posedge clk or posedge reset) begin
|
||||
|
||||
@@ -52,6 +52,12 @@ def gendlyns(ns):
|
||||
nb = ceil(log(n+1,2))
|
||||
print(dly.format(type='%sns' % t, width=nb, n=n))
|
||||
|
||||
def genldlyns(ns):
|
||||
t = str(ns).replace('.', '_')
|
||||
n = int(ns//clock)
|
||||
nb = ceil(log(n+1,2))
|
||||
print(ldly.format(type='%sns' % t, width=nb, n=n))
|
||||
|
||||
def gendlyus(us):
|
||||
t = str(us).replace('.', '_')
|
||||
n = int(us*1000//clock)
|
||||
@@ -93,6 +99,8 @@ gendlyns(250)
|
||||
gendlyns(300)
|
||||
gendlyns(400)
|
||||
gendlyns(450)
|
||||
gendlyns(500)
|
||||
genldlyns(500)
|
||||
gendlyns(550)
|
||||
gendlyns(750)
|
||||
gendlyns(800)
|
||||
@@ -102,6 +110,8 @@ gendlyus(1)
|
||||
genldlyus(1)
|
||||
genldlyus(1.5)
|
||||
genldlyus(2)
|
||||
gendlyus(2.8)
|
||||
gendlyus(35)
|
||||
gendlyus(100)
|
||||
genldlyus(100)
|
||||
|
||||
|
||||
145
verilog/iobus_4_connect.v
Normal file
145
verilog/iobus_4_connect.v
Normal file
@@ -0,0 +1,145 @@
|
||||
// AUTOGEN
|
||||
module iobus_4_connect(
|
||||
// unused
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
// Master
|
||||
input wire m_iob_poweron,
|
||||
input wire m_iob_reset,
|
||||
input wire m_datao_clear,
|
||||
input wire m_datao_set,
|
||||
input wire m_cono_clear,
|
||||
input wire m_cono_set,
|
||||
input wire m_iob_fm_datai,
|
||||
input wire m_iob_fm_status,
|
||||
input wire m_rdi_pulse,
|
||||
input wire [3:9] m_ios,
|
||||
input wire [0:35] m_iob_write,
|
||||
output wire [1:7] m_pi_req,
|
||||
output wire [0:35] m_iob_read,
|
||||
output wire m_dr_split,
|
||||
output wire m_rdi_data,
|
||||
|
||||
// Slave 0
|
||||
output wire s0_iob_poweron,
|
||||
output wire s0_iob_reset,
|
||||
output wire s0_datao_clear,
|
||||
output wire s0_datao_set,
|
||||
output wire s0_cono_clear,
|
||||
output wire s0_cono_set,
|
||||
output wire s0_iob_fm_datai,
|
||||
output wire s0_iob_fm_status,
|
||||
output wire s0_rdi_pulse,
|
||||
output wire [3:9] s0_ios,
|
||||
output wire [0:35] s0_iob_write,
|
||||
input wire [1:7] s0_pi_req,
|
||||
input wire [0:35] s0_iob_read,
|
||||
input wire s0_dr_split,
|
||||
input wire s0_rdi_data,
|
||||
|
||||
// Slave 1
|
||||
output wire s1_iob_poweron,
|
||||
output wire s1_iob_reset,
|
||||
output wire s1_datao_clear,
|
||||
output wire s1_datao_set,
|
||||
output wire s1_cono_clear,
|
||||
output wire s1_cono_set,
|
||||
output wire s1_iob_fm_datai,
|
||||
output wire s1_iob_fm_status,
|
||||
output wire s1_rdi_pulse,
|
||||
output wire [3:9] s1_ios,
|
||||
output wire [0:35] s1_iob_write,
|
||||
input wire [1:7] s1_pi_req,
|
||||
input wire [0:35] s1_iob_read,
|
||||
input wire s1_dr_split,
|
||||
input wire s1_rdi_data,
|
||||
|
||||
// Slave 2
|
||||
output wire s2_iob_poweron,
|
||||
output wire s2_iob_reset,
|
||||
output wire s2_datao_clear,
|
||||
output wire s2_datao_set,
|
||||
output wire s2_cono_clear,
|
||||
output wire s2_cono_set,
|
||||
output wire s2_iob_fm_datai,
|
||||
output wire s2_iob_fm_status,
|
||||
output wire s2_rdi_pulse,
|
||||
output wire [3:9] s2_ios,
|
||||
output wire [0:35] s2_iob_write,
|
||||
input wire [1:7] s2_pi_req,
|
||||
input wire [0:35] s2_iob_read,
|
||||
input wire s2_dr_split,
|
||||
input wire s2_rdi_data,
|
||||
|
||||
// Slave 3
|
||||
output wire s3_iob_poweron,
|
||||
output wire s3_iob_reset,
|
||||
output wire s3_datao_clear,
|
||||
output wire s3_datao_set,
|
||||
output wire s3_cono_clear,
|
||||
output wire s3_cono_set,
|
||||
output wire s3_iob_fm_datai,
|
||||
output wire s3_iob_fm_status,
|
||||
output wire s3_rdi_pulse,
|
||||
output wire [3:9] s3_ios,
|
||||
output wire [0:35] s3_iob_write,
|
||||
input wire [1:7] s3_pi_req,
|
||||
input wire [0:35] s3_iob_read,
|
||||
input wire s3_dr_split,
|
||||
input wire s3_rdi_data
|
||||
);
|
||||
assign m_pi_req = 0 | s0_pi_req | s1_pi_req | s2_pi_req | s3_pi_req;
|
||||
assign m_iob_read = m_iob_write | s0_iob_read | s1_iob_read | s2_iob_read | s3_iob_read;
|
||||
assign m_dr_split = 0 | s0_dr_split | s1_dr_split | s2_dr_split | s3_dr_split;
|
||||
assign m_rdi_data = 0 | s0_rdi_data | s1_rdi_data | s2_rdi_data | s3_rdi_data;
|
||||
|
||||
|
||||
assign s0_iob_poweron = m_iob_poweron;
|
||||
assign s0_iob_reset = m_iob_reset;
|
||||
assign s0_datao_clear = m_datao_clear;
|
||||
assign s0_datao_set = m_datao_set;
|
||||
assign s0_cono_clear = m_cono_clear;
|
||||
assign s0_cono_set = m_cono_set;
|
||||
assign s0_iob_fm_datai = m_iob_fm_datai;
|
||||
assign s0_iob_fm_status = m_iob_fm_status;
|
||||
assign s0_rdi_pulse = m_rdi_pulse;
|
||||
assign s0_ios = m_ios;
|
||||
assign s0_iob_write = m_iob_write;
|
||||
|
||||
assign s1_iob_poweron = m_iob_poweron;
|
||||
assign s1_iob_reset = m_iob_reset;
|
||||
assign s1_datao_clear = m_datao_clear;
|
||||
assign s1_datao_set = m_datao_set;
|
||||
assign s1_cono_clear = m_cono_clear;
|
||||
assign s1_cono_set = m_cono_set;
|
||||
assign s1_iob_fm_datai = m_iob_fm_datai;
|
||||
assign s1_iob_fm_status = m_iob_fm_status;
|
||||
assign s1_rdi_pulse = m_rdi_pulse;
|
||||
assign s1_ios = m_ios;
|
||||
assign s1_iob_write = m_iob_write;
|
||||
|
||||
assign s2_iob_poweron = m_iob_poweron;
|
||||
assign s2_iob_reset = m_iob_reset;
|
||||
assign s2_datao_clear = m_datao_clear;
|
||||
assign s2_datao_set = m_datao_set;
|
||||
assign s2_cono_clear = m_cono_clear;
|
||||
assign s2_cono_set = m_cono_set;
|
||||
assign s2_iob_fm_datai = m_iob_fm_datai;
|
||||
assign s2_iob_fm_status = m_iob_fm_status;
|
||||
assign s2_rdi_pulse = m_rdi_pulse;
|
||||
assign s2_ios = m_ios;
|
||||
assign s2_iob_write = m_iob_write;
|
||||
|
||||
assign s3_iob_poweron = m_iob_poweron;
|
||||
assign s3_iob_reset = m_iob_reset;
|
||||
assign s3_datao_clear = m_datao_clear;
|
||||
assign s3_datao_set = m_datao_set;
|
||||
assign s3_cono_clear = m_cono_clear;
|
||||
assign s3_cono_set = m_cono_set;
|
||||
assign s3_iob_fm_datai = m_iob_fm_datai;
|
||||
assign s3_iob_fm_status = m_iob_fm_status;
|
||||
assign s3_rdi_pulse = m_rdi_pulse;
|
||||
assign s3_ios = m_ios;
|
||||
assign s3_iob_write = m_iob_write;
|
||||
endmodule
|
||||
203
verilog/iobus_6_connect.v
Normal file
203
verilog/iobus_6_connect.v
Normal file
@@ -0,0 +1,203 @@
|
||||
// AUTOGEN
|
||||
module iobus_6_connect(
|
||||
// unused
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
// Master
|
||||
input wire m_iob_poweron,
|
||||
input wire m_iob_reset,
|
||||
input wire m_datao_clear,
|
||||
input wire m_datao_set,
|
||||
input wire m_cono_clear,
|
||||
input wire m_cono_set,
|
||||
input wire m_iob_fm_datai,
|
||||
input wire m_iob_fm_status,
|
||||
input wire m_rdi_pulse,
|
||||
input wire [3:9] m_ios,
|
||||
input wire [0:35] m_iob_write,
|
||||
output wire [1:7] m_pi_req,
|
||||
output wire [0:35] m_iob_read,
|
||||
output wire m_dr_split,
|
||||
output wire m_rdi_data,
|
||||
|
||||
// Slave 0
|
||||
output wire s0_iob_poweron,
|
||||
output wire s0_iob_reset,
|
||||
output wire s0_datao_clear,
|
||||
output wire s0_datao_set,
|
||||
output wire s0_cono_clear,
|
||||
output wire s0_cono_set,
|
||||
output wire s0_iob_fm_datai,
|
||||
output wire s0_iob_fm_status,
|
||||
output wire s0_rdi_pulse,
|
||||
output wire [3:9] s0_ios,
|
||||
output wire [0:35] s0_iob_write,
|
||||
input wire [1:7] s0_pi_req,
|
||||
input wire [0:35] s0_iob_read,
|
||||
input wire s0_dr_split,
|
||||
input wire s0_rdi_data,
|
||||
|
||||
// Slave 1
|
||||
output wire s1_iob_poweron,
|
||||
output wire s1_iob_reset,
|
||||
output wire s1_datao_clear,
|
||||
output wire s1_datao_set,
|
||||
output wire s1_cono_clear,
|
||||
output wire s1_cono_set,
|
||||
output wire s1_iob_fm_datai,
|
||||
output wire s1_iob_fm_status,
|
||||
output wire s1_rdi_pulse,
|
||||
output wire [3:9] s1_ios,
|
||||
output wire [0:35] s1_iob_write,
|
||||
input wire [1:7] s1_pi_req,
|
||||
input wire [0:35] s1_iob_read,
|
||||
input wire s1_dr_split,
|
||||
input wire s1_rdi_data,
|
||||
|
||||
// Slave 2
|
||||
output wire s2_iob_poweron,
|
||||
output wire s2_iob_reset,
|
||||
output wire s2_datao_clear,
|
||||
output wire s2_datao_set,
|
||||
output wire s2_cono_clear,
|
||||
output wire s2_cono_set,
|
||||
output wire s2_iob_fm_datai,
|
||||
output wire s2_iob_fm_status,
|
||||
output wire s2_rdi_pulse,
|
||||
output wire [3:9] s2_ios,
|
||||
output wire [0:35] s2_iob_write,
|
||||
input wire [1:7] s2_pi_req,
|
||||
input wire [0:35] s2_iob_read,
|
||||
input wire s2_dr_split,
|
||||
input wire s2_rdi_data,
|
||||
|
||||
// Slave 3
|
||||
output wire s3_iob_poweron,
|
||||
output wire s3_iob_reset,
|
||||
output wire s3_datao_clear,
|
||||
output wire s3_datao_set,
|
||||
output wire s3_cono_clear,
|
||||
output wire s3_cono_set,
|
||||
output wire s3_iob_fm_datai,
|
||||
output wire s3_iob_fm_status,
|
||||
output wire s3_rdi_pulse,
|
||||
output wire [3:9] s3_ios,
|
||||
output wire [0:35] s3_iob_write,
|
||||
input wire [1:7] s3_pi_req,
|
||||
input wire [0:35] s3_iob_read,
|
||||
input wire s3_dr_split,
|
||||
input wire s3_rdi_data,
|
||||
|
||||
// Slave 4
|
||||
output wire s4_iob_poweron,
|
||||
output wire s4_iob_reset,
|
||||
output wire s4_datao_clear,
|
||||
output wire s4_datao_set,
|
||||
output wire s4_cono_clear,
|
||||
output wire s4_cono_set,
|
||||
output wire s4_iob_fm_datai,
|
||||
output wire s4_iob_fm_status,
|
||||
output wire s4_rdi_pulse,
|
||||
output wire [3:9] s4_ios,
|
||||
output wire [0:35] s4_iob_write,
|
||||
input wire [1:7] s4_pi_req,
|
||||
input wire [0:35] s4_iob_read,
|
||||
input wire s4_dr_split,
|
||||
input wire s4_rdi_data,
|
||||
|
||||
// Slave 5
|
||||
output wire s5_iob_poweron,
|
||||
output wire s5_iob_reset,
|
||||
output wire s5_datao_clear,
|
||||
output wire s5_datao_set,
|
||||
output wire s5_cono_clear,
|
||||
output wire s5_cono_set,
|
||||
output wire s5_iob_fm_datai,
|
||||
output wire s5_iob_fm_status,
|
||||
output wire s5_rdi_pulse,
|
||||
output wire [3:9] s5_ios,
|
||||
output wire [0:35] s5_iob_write,
|
||||
input wire [1:7] s5_pi_req,
|
||||
input wire [0:35] s5_iob_read,
|
||||
input wire s5_dr_split,
|
||||
input wire s5_rdi_data
|
||||
);
|
||||
assign m_pi_req = 0 | s0_pi_req | s1_pi_req | s2_pi_req | s3_pi_req | s4_pi_req | s5_pi_req;
|
||||
assign m_iob_read = m_iob_write | s0_iob_read | s1_iob_read | s2_iob_read | s3_iob_read | s4_iob_read | s5_iob_read;
|
||||
assign m_dr_split = 0 | s0_dr_split | s1_dr_split | s2_dr_split | s3_dr_split | s4_dr_split | s5_dr_split;
|
||||
assign m_rdi_data = 0 | s0_rdi_data | s1_rdi_data | s2_rdi_data | s3_rdi_data | s4_rdi_data | s5_rdi_data;
|
||||
|
||||
|
||||
assign s0_iob_poweron = m_iob_poweron;
|
||||
assign s0_iob_reset = m_iob_reset;
|
||||
assign s0_datao_clear = m_datao_clear;
|
||||
assign s0_datao_set = m_datao_set;
|
||||
assign s0_cono_clear = m_cono_clear;
|
||||
assign s0_cono_set = m_cono_set;
|
||||
assign s0_iob_fm_datai = m_iob_fm_datai;
|
||||
assign s0_iob_fm_status = m_iob_fm_status;
|
||||
assign s0_rdi_pulse = m_rdi_pulse;
|
||||
assign s0_ios = m_ios;
|
||||
assign s0_iob_write = m_iob_write;
|
||||
|
||||
assign s1_iob_poweron = m_iob_poweron;
|
||||
assign s1_iob_reset = m_iob_reset;
|
||||
assign s1_datao_clear = m_datao_clear;
|
||||
assign s1_datao_set = m_datao_set;
|
||||
assign s1_cono_clear = m_cono_clear;
|
||||
assign s1_cono_set = m_cono_set;
|
||||
assign s1_iob_fm_datai = m_iob_fm_datai;
|
||||
assign s1_iob_fm_status = m_iob_fm_status;
|
||||
assign s1_rdi_pulse = m_rdi_pulse;
|
||||
assign s1_ios = m_ios;
|
||||
assign s1_iob_write = m_iob_write;
|
||||
|
||||
assign s2_iob_poweron = m_iob_poweron;
|
||||
assign s2_iob_reset = m_iob_reset;
|
||||
assign s2_datao_clear = m_datao_clear;
|
||||
assign s2_datao_set = m_datao_set;
|
||||
assign s2_cono_clear = m_cono_clear;
|
||||
assign s2_cono_set = m_cono_set;
|
||||
assign s2_iob_fm_datai = m_iob_fm_datai;
|
||||
assign s2_iob_fm_status = m_iob_fm_status;
|
||||
assign s2_rdi_pulse = m_rdi_pulse;
|
||||
assign s2_ios = m_ios;
|
||||
assign s2_iob_write = m_iob_write;
|
||||
|
||||
assign s3_iob_poweron = m_iob_poweron;
|
||||
assign s3_iob_reset = m_iob_reset;
|
||||
assign s3_datao_clear = m_datao_clear;
|
||||
assign s3_datao_set = m_datao_set;
|
||||
assign s3_cono_clear = m_cono_clear;
|
||||
assign s3_cono_set = m_cono_set;
|
||||
assign s3_iob_fm_datai = m_iob_fm_datai;
|
||||
assign s3_iob_fm_status = m_iob_fm_status;
|
||||
assign s3_rdi_pulse = m_rdi_pulse;
|
||||
assign s3_ios = m_ios;
|
||||
assign s3_iob_write = m_iob_write;
|
||||
|
||||
assign s4_iob_poweron = m_iob_poweron;
|
||||
assign s4_iob_reset = m_iob_reset;
|
||||
assign s4_datao_clear = m_datao_clear;
|
||||
assign s4_datao_set = m_datao_set;
|
||||
assign s4_cono_clear = m_cono_clear;
|
||||
assign s4_cono_set = m_cono_set;
|
||||
assign s4_iob_fm_datai = m_iob_fm_datai;
|
||||
assign s4_iob_fm_status = m_iob_fm_status;
|
||||
assign s4_rdi_pulse = m_rdi_pulse;
|
||||
assign s4_ios = m_ios;
|
||||
assign s4_iob_write = m_iob_write;
|
||||
|
||||
assign s5_iob_poweron = m_iob_poweron;
|
||||
assign s5_iob_reset = m_iob_reset;
|
||||
assign s5_datao_clear = m_datao_clear;
|
||||
assign s5_datao_set = m_datao_set;
|
||||
assign s5_cono_clear = m_cono_clear;
|
||||
assign s5_cono_set = m_cono_set;
|
||||
assign s5_iob_fm_datai = m_iob_fm_datai;
|
||||
assign s5_iob_fm_status = m_iob_fm_status;
|
||||
assign s5_rdi_pulse = m_rdi_pulse;
|
||||
assign s5_ios = m_ios;
|
||||
assign s5_iob_write = m_iob_write;
|
||||
endmodule
|
||||
80
verilog/memif_d.v
Normal file
80
verilog/memif_d.v
Normal file
@@ -0,0 +1,80 @@
|
||||
module memif_d(
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
// Avalon Slave
|
||||
input wire [1:0] s_address,
|
||||
input wire s_write,
|
||||
input wire s_read,
|
||||
input wire [31:0] s_writedata,
|
||||
output reg [31:0] s_readdata,
|
||||
output wire s_waitrequest,
|
||||
|
||||
// 64 bit Avalon Master
|
||||
output wire [31:0] m_address,
|
||||
output reg m_write,
|
||||
output reg m_read,
|
||||
output wire [63:0] m_writedata,
|
||||
input wire [63:0] m_readdata,
|
||||
input wire m_waitrequest
|
||||
);
|
||||
|
||||
reg [31:0] addr;
|
||||
reg [63:0] word;
|
||||
|
||||
assign m_address = addr;
|
||||
assign m_writedata = word;
|
||||
|
||||
wire write_edge, read_edge;
|
||||
edgedet e0(clk, reset, s_write, write_edge);
|
||||
edgedet e1(clk, reset, s_read, read_edge);
|
||||
|
||||
reg waiting;
|
||||
wire req = (write_edge|read_edge) & s_address == 2'h2;
|
||||
assign s_waitrequest = req | waiting;
|
||||
|
||||
always @(posedge clk or negedge reset) begin
|
||||
if(~reset) begin
|
||||
m_write <= 0;
|
||||
m_read <= 0;
|
||||
waiting <= 0;
|
||||
|
||||
addr <= 0;
|
||||
word <= 0;
|
||||
end else begin
|
||||
if(write_edge) begin
|
||||
case(s_address)
|
||||
2'h0: addr <= s_writedata[31:0];
|
||||
2'h1: word[31:0] <= s_writedata[31:0];
|
||||
2'h2: word[63:32] <= s_writedata[31:0];
|
||||
endcase
|
||||
end
|
||||
|
||||
if(req) begin
|
||||
waiting <= 1;
|
||||
if(s_write)
|
||||
m_write <= 1;
|
||||
else if(s_read)
|
||||
m_read <= 1;
|
||||
end
|
||||
|
||||
if(m_write & ~m_waitrequest) begin
|
||||
m_write <= 0;
|
||||
waiting <= 0;
|
||||
end
|
||||
if(m_read & ~m_waitrequest) begin
|
||||
m_read <= 0;
|
||||
waiting <= 0;
|
||||
word <= m_readdata;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
case(s_address)
|
||||
2'h1: s_readdata <= word[31:0];
|
||||
2'h2: s_readdata <= word[63:32];
|
||||
default: s_readdata <= 32'b0;
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
29
verilog/memory_256k_dram.v
Executable file
29
verilog/memory_256k_dram.v
Executable file
@@ -0,0 +1,29 @@
|
||||
module memory_256k(
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
// 36 bit Slave
|
||||
input wire [17:0] s_address,
|
||||
input wire s_write,
|
||||
input wire s_read,
|
||||
input wire [35:0] s_writedata,
|
||||
output wire [35:0] s_readdata,
|
||||
output wire s_waitrequest,
|
||||
|
||||
// 64 bit Avalon Master
|
||||
output wire [31:0] m_address,
|
||||
output wire m_write,
|
||||
output wire m_read,
|
||||
output wire [63:0] m_writedata,
|
||||
input wire [63:0] m_readdata,
|
||||
input wire m_waitrequest
|
||||
);
|
||||
parameter [31:0] base_addr = 32'h30000000;
|
||||
|
||||
assign m_address = base_addr | { s_address, 3'b0 };
|
||||
assign m_write = s_write;
|
||||
assign m_read = s_read;
|
||||
assign m_writedata = s_writedata;
|
||||
assign s_readdata = m_readdata;
|
||||
assign s_waitrequest = m_waitrequest;
|
||||
endmodule
|
||||
@@ -46,7 +46,7 @@ module panel_6(
|
||||
input wire reset,
|
||||
|
||||
// Avalon Slave
|
||||
input wire [4:0] s_address,
|
||||
input wire [5:0] s_address,
|
||||
input wire s_write,
|
||||
input wire s_read,
|
||||
input wire [31:0] s_writedata,
|
||||
@@ -141,6 +141,21 @@ module panel_6(
|
||||
input wire [7:0] ptp,
|
||||
input wire [6:0] ptp_status, // also includes motor on
|
||||
|
||||
/*
|
||||
* 340 display
|
||||
*/
|
||||
input wire [0:17] dis_br,
|
||||
input wire [0:6] dis_brm,
|
||||
input wire [0:9] dis_x,
|
||||
input wire [0:9] dis_y,
|
||||
input wire [1:4] dis_s,
|
||||
input wire [0:2] dis_i,
|
||||
input wire [0:2] dis_mode,
|
||||
input wire [0:1] dis_sz,
|
||||
input wire [0:8] dis_flags,
|
||||
input wire [0:4] dis_fe,
|
||||
input wire [31:0] dis_foo,
|
||||
|
||||
/*
|
||||
* External panel
|
||||
*/
|
||||
@@ -159,8 +174,11 @@ module panel_6(
|
||||
3'b010: leds <= tty_status;
|
||||
3'b011: leds <= ptr;
|
||||
3'b100: leds <= ptr_status;
|
||||
3'b101: leds <= ptp;
|
||||
3'b110: leds <= ptp_status;
|
||||
|
||||
// 3'b101: leds <= ptp;
|
||||
// 3'b110: leds <= ptp_status;
|
||||
3'b101: leds <= dis_fe;
|
||||
|
||||
3'b111: leds <= ext;
|
||||
default: leds <= 0;
|
||||
endcase
|
||||
@@ -169,57 +187,62 @@ module panel_6(
|
||||
|
||||
always @(*) begin
|
||||
case(s_address)
|
||||
5'o00: s_readdata <=
|
||||
6'o00: s_readdata <=
|
||||
{ 20'b0,
|
||||
power, mc_stop, run, sw_addr_stop,
|
||||
key_exec, key_io_reset, key_mem_stop, key_inst_stop,
|
||||
key_mem_cont, key_inst_cont, key_read_in, key_start
|
||||
};
|
||||
5'o01: s_readdata <= 0;
|
||||
6'o01: s_readdata <= 0;
|
||||
|
||||
5'o02: s_readdata <=
|
||||
6'o02: s_readdata <=
|
||||
{ 22'b0,
|
||||
sw_mem_disable, sw_repeat,
|
||||
ptr_key_tape_feed, ptp_key_tape_feed,
|
||||
ptr_key_start, ptr_key_stop,
|
||||
key_ex_nxt, key_ex, key_dep_nxt, key_dep
|
||||
};
|
||||
5'o03: s_readdata <= 0;
|
||||
6'o03: s_readdata <= 0;
|
||||
|
||||
5'o04: s_readdata <=
|
||||
6'o04: s_readdata <=
|
||||
{ 26'b0,
|
||||
sw_split_cyc, sw_sct_maint,
|
||||
sw_art3_maint, sw_repeat_bypass, sw_rim_maint,
|
||||
1'b0 // spare?
|
||||
};
|
||||
5'o05: s_readdata <= 0;
|
||||
6'o05: s_readdata <= 0;
|
||||
|
||||
5'o06: s_readdata <= { 14'b0, datasw[0:17] };
|
||||
5'o07: s_readdata <= { 14'b0, datasw[18:35] };
|
||||
5'o10: s_readdata <= { 14'b0, mas };
|
||||
5'o11: s_readdata <= 0; // TODO: repeat
|
||||
5'o12: s_readdata <= { 14'b0, ir };
|
||||
5'o13: s_readdata <= { 14'b0, mi[0:17] };
|
||||
5'o14: s_readdata <= { 14'b0, mi[18:35] };
|
||||
5'o15: s_readdata <= { 14'b0, pc };
|
||||
5'o16: s_readdata <= { 14'b0, ma };
|
||||
5'o17: s_readdata <= { 10'b0, pih, pir, pio, pi_active };
|
||||
5'o20: s_readdata <= { 14'b0, mb[0:17] };
|
||||
5'o21: s_readdata <= { 14'b0, mb[18:35] };
|
||||
5'o22: s_readdata <= { 14'b0, ar[0:17] };
|
||||
5'o23: s_readdata <= { 14'b0, ar[18:35] };
|
||||
5'o24: s_readdata <= { 14'b0, mq[0:17] };
|
||||
5'o25: s_readdata <= { 14'b0, mq[18:35] };
|
||||
5'o26: s_readdata <= { ff0, ff1, ff2, ff3 };
|
||||
5'o27: s_readdata <= { ff4, ff5, ff6, ff7 };
|
||||
5'o30: s_readdata <= { ff8, ff9, ff10, ff11 };
|
||||
5'o31: s_readdata <= { ff12, ff13, 16'b0 };
|
||||
5'o32: s_readdata <= { 8'b0, rla, rlr, pr };
|
||||
5'o33: s_readdata <= { tty_tti, 2'b0, tty_status };
|
||||
5'o34: s_readdata <= { ptp, 2'b0, ptp_status };
|
||||
5'o35: s_readdata <= ptr_status;
|
||||
5'o36: s_readdata <= ptr[35:18];
|
||||
5'o37: s_readdata <= ptr[17:0];
|
||||
6'o06: s_readdata <= { 14'b0, datasw[0:17] };
|
||||
6'o07: s_readdata <= { 14'b0, datasw[18:35] };
|
||||
6'o10: s_readdata <= { 14'b0, mas };
|
||||
6'o11: s_readdata <= 0; // TODO: repeat
|
||||
6'o12: s_readdata <= { 14'b0, ir };
|
||||
6'o13: s_readdata <= { 14'b0, mi[0:17] };
|
||||
6'o14: s_readdata <= { 14'b0, mi[18:35] };
|
||||
6'o15: s_readdata <= { 14'b0, pc };
|
||||
6'o16: s_readdata <= { 14'b0, ma };
|
||||
6'o17: s_readdata <= { 10'b0, pih, pir, pio, pi_active };
|
||||
6'o20: s_readdata <= { 14'b0, mb[0:17] };
|
||||
6'o21: s_readdata <= { 14'b0, mb[18:35] };
|
||||
6'o22: s_readdata <= { 14'b0, ar[0:17] };
|
||||
6'o23: s_readdata <= { 14'b0, ar[18:35] };
|
||||
6'o24: s_readdata <= { 14'b0, mq[0:17] };
|
||||
6'o25: s_readdata <= { 14'b0, mq[18:35] };
|
||||
6'o26: s_readdata <= { ff0, ff1, ff2, ff3 };
|
||||
6'o27: s_readdata <= { ff4, ff5, ff6, ff7 };
|
||||
6'o30: s_readdata <= { ff8, ff9, ff10, ff11 };
|
||||
6'o31: s_readdata <= { ff12, ff13, 16'b0 };
|
||||
6'o32: s_readdata <= { 8'b0, rla, rlr, pr };
|
||||
6'o33: s_readdata <= { tty_tti, 2'b0, tty_status };
|
||||
6'o34: s_readdata <= { ptp, 2'b0, ptp_status };
|
||||
6'o35: s_readdata <= ptr_status;
|
||||
6'o36: s_readdata <= ptr[35:18];
|
||||
6'o37: s_readdata <= ptr[17:0];
|
||||
6'o40: s_readdata <= dis_br;
|
||||
6'o41: s_readdata <= { dis_brm, dis_y, dis_x };
|
||||
6'o42: s_readdata <= { dis_flags, dis_s, dis_i,
|
||||
dis_sz, dis_mode };
|
||||
6'o43: s_readdata <= dis_foo;
|
||||
default: s_readdata <= 0;
|
||||
endcase
|
||||
end
|
||||
@@ -266,7 +289,7 @@ module panel_6(
|
||||
sw_power <= ext_sw_power;
|
||||
|
||||
if(s_write) case(s_address)
|
||||
5'o00: begin
|
||||
6'o00: begin
|
||||
if(s_writedata[0])
|
||||
{ key_read_in, key_start } <= 2'b01;
|
||||
if(s_writedata[1])
|
||||
@@ -286,7 +309,7 @@ module panel_6(
|
||||
if(s_writedata[8])
|
||||
sw_addr_stop <= 1;
|
||||
end
|
||||
5'o01: begin
|
||||
6'o01: begin
|
||||
if(s_writedata[0] | s_writedata[1])
|
||||
{ key_read_in, key_start } <= 2'b00;
|
||||
if(s_writedata[2] | s_writedata[3])
|
||||
@@ -298,7 +321,7 @@ module panel_6(
|
||||
if(s_writedata[8])
|
||||
sw_addr_stop <= 0;
|
||||
end
|
||||
5'o02: begin
|
||||
6'o02: begin
|
||||
if(s_writedata[0])
|
||||
{ key_dep_nxt, key_dep } <= 2'b01;
|
||||
if(s_writedata[1])
|
||||
@@ -320,7 +343,7 @@ module panel_6(
|
||||
if(s_writedata[9])
|
||||
sw_mem_disable <= 1;
|
||||
end
|
||||
5'o03: begin
|
||||
6'o03: begin
|
||||
if(s_writedata[0] | s_writedata[1])
|
||||
{ key_dep_nxt, key_dep } <= 2'b00;
|
||||
if(s_writedata[2] | s_writedata[3])
|
||||
@@ -334,7 +357,7 @@ module panel_6(
|
||||
if(s_writedata[9])
|
||||
sw_mem_disable <= 0;
|
||||
end
|
||||
5'o04: begin
|
||||
6'o04: begin
|
||||
if(s_writedata[1])
|
||||
sw_rim_maint <= 1;
|
||||
if(s_writedata[2])
|
||||
@@ -346,7 +369,7 @@ module panel_6(
|
||||
if(s_writedata[5])
|
||||
sw_split_cyc <= 1;
|
||||
end
|
||||
5'o05: begin
|
||||
6'o05: begin
|
||||
if(s_writedata[1])
|
||||
sw_rim_maint <= 0;
|
||||
if(s_writedata[2])
|
||||
@@ -358,9 +381,9 @@ module panel_6(
|
||||
if(s_writedata[5])
|
||||
sw_split_cyc <= 0;
|
||||
end
|
||||
5'o06: datasw[0:17] <= s_writedata;
|
||||
5'o07: datasw[18:35] <= s_writedata;
|
||||
5'o10: mas <= s_writedata;
|
||||
6'o06: datasw[0:17] <= s_writedata;
|
||||
6'o07: datasw[18:35] <= s_writedata;
|
||||
6'o10: mas <= s_writedata;
|
||||
// TODO: 11 REPEAT
|
||||
endcase
|
||||
end
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
DEP=
|
||||
V=../clk.v ../memory.v ../arbiter.v ../memif.v ../membusif.v ../testcore161c.v ../core161c.v \
|
||||
../core164.v ../core32k.v ../fast162.v ../fast162_dp.v ../modules_50.v \
|
||||
../core164.v ../core32k_x.v ../fast162.v ../fast162_dp.v ../modules_50.v \
|
||||
../dly_50.v ../onchip_ram.v ../memory_16.v ../memory_16k.v ../memory_32k.v \
|
||||
../panel_6.v ../fakeapr.v ../apr.v ../ptr.v ../ptp.v
|
||||
../panel_6.v ../fakeapr.v ../apr.v ../ptr.v ../ptp.v ../dis340.v
|
||||
|
||||
tb_apr: tb_apr.v $(V) $(DEP)
|
||||
iverilog -o $@ tb_apr.v $(V)
|
||||
|
||||
tb_dis: tb_dis.v $(V) $(DEP)
|
||||
iverilog -o $@ tb_dis.v $(V)
|
||||
|
||||
tb_ptp: tb_ptp.v $(V) $(DEP)
|
||||
iverilog -o $@ tb_ptp.v $(V)
|
||||
|
||||
|
||||
@@ -108,11 +108,28 @@ module tb_apr();
|
||||
.iobus_iob_in(iobus_iob_in)
|
||||
);
|
||||
|
||||
wire [17:0] av_address;
|
||||
wire av_write;
|
||||
wire av_read;
|
||||
wire [35:0] av_writedata;
|
||||
wire [35:0] av_readdata;
|
||||
wire av_waitrequest;
|
||||
|
||||
memory_32k mem(
|
||||
.i_clk(clk),
|
||||
.i_reset_n(reset),
|
||||
.i_address(av_address),
|
||||
.i_write(av_write),
|
||||
.i_read(av_read),
|
||||
.i_writedata(av_writedata),
|
||||
.o_readdata(av_readdata),
|
||||
.o_waitrequest(av_waitrequest)
|
||||
);
|
||||
|
||||
wire [0:35] membus_mb_read_0;
|
||||
wire membus_addr_ack_0;
|
||||
wire membus_rd_rs_0;
|
||||
core161c cmem(
|
||||
core32k cmem(
|
||||
.clk(clk),
|
||||
.reset(~reset),
|
||||
.power(1'b1),
|
||||
@@ -156,7 +173,14 @@ module tb_apr();
|
||||
.membus_ma_p3(15'b0),
|
||||
.membus_sel_p3(4'b0),
|
||||
.membus_fmc_select_p3(1'b0),
|
||||
.membus_mb_in_p3(36'b0)
|
||||
.membus_mb_in_p3(36'b0),
|
||||
|
||||
.m_address(av_address),
|
||||
.m_write(av_write),
|
||||
.m_read(av_read),
|
||||
.m_writedata(av_writedata),
|
||||
.m_readdata(av_readdata),
|
||||
.m_waitrequest(av_waitrequest)
|
||||
);
|
||||
|
||||
wire [0:35] membus_mb_read_1;
|
||||
@@ -216,26 +240,29 @@ module tb_apr();
|
||||
$dumpvars();
|
||||
|
||||
for(i = 0; i < 'o40000; i = i + 1)
|
||||
cmem.core[i] <= 0;
|
||||
mem.ram.ram[i] <= 0;
|
||||
|
||||
#10;
|
||||
|
||||
cmem.core['o42] <= 36'o334000_000000;
|
||||
cmem.core['o43] <= 36'o000000_000000;
|
||||
cmem.core['o44] <= 36'o334000_000000;
|
||||
cmem.core['o45] <= 36'o000000_000000;
|
||||
cmem.core['o46] <= 36'o334000_000000;
|
||||
cmem.core['o47] <= 36'o000000_000000;
|
||||
cmem.core['o50] <= 36'o334000_000000;
|
||||
cmem.core['o51] <= 36'o000000_000000;
|
||||
cmem.core['o52] <= 36'o334000_000000;
|
||||
cmem.core['o53] <= 36'o000000_000000;
|
||||
mem.ram.ram['o42] <= 36'o334000_000000;
|
||||
mem.ram.ram['o43] <= 36'o000000_000000;
|
||||
mem.ram.ram['o44] <= 36'o334000_000000;
|
||||
mem.ram.ram['o45] <= 36'o000000_000000;
|
||||
mem.ram.ram['o46] <= 36'o334000_000000;
|
||||
mem.ram.ram['o47] <= 36'o000000_000000;
|
||||
mem.ram.ram['o50] <= 36'o334000_000000;
|
||||
mem.ram.ram['o51] <= 36'o000000_000000;
|
||||
mem.ram.ram['o52] <= 36'o334000_000000;
|
||||
mem.ram.ram['o53] <= 36'o000000_000000;
|
||||
|
||||
cmem.core['o100] <= 36'o173040000000;
|
||||
cmem.core['o101] <= 36'o254200000000;
|
||||
mem.ram.ram['o100] <= 36'o202000001000;
|
||||
mem.ram.ram['o101] <= 36'o254200000000;
|
||||
|
||||
mem.ram.ram['o1000] <= 36'o123321456654;
|
||||
|
||||
fmem.ff[0] <= 36'o611042323251;
|
||||
fmem.ff[1] <= 36'o472340710317;
|
||||
fmem.ff[2] <= 36'o545777777776;
|
||||
mas <= 'o100;
|
||||
|
||||
#200;
|
||||
|
||||
183
verilog/tb/tb_dis.v
Normal file
183
verilog/tb/tb_dis.v
Normal file
@@ -0,0 +1,183 @@
|
||||
`default_nettype none
|
||||
`timescale 1ns/1ns
|
||||
`define simulation
|
||||
|
||||
module tb_dis();
|
||||
|
||||
wire clk, reset;
|
||||
clock clock(clk, reset);
|
||||
|
||||
reg iobus_iob_poweron = 1;
|
||||
reg iobus_iob_reset = 0;
|
||||
reg iobus_datao_clear = 0;
|
||||
reg iobus_datao_set = 0;
|
||||
reg iobus_cono_clear = 0;
|
||||
reg iobus_cono_set = 0;
|
||||
reg iobus_iob_fm_datai = 0;
|
||||
reg iobus_iob_fm_status = 0;
|
||||
reg [3:9] iobus_ios = 0;
|
||||
reg [0:35] iobus_iob_in = 0;
|
||||
wire [1:7] iobus_pi_req;
|
||||
wire [0:35] iobus_iob_out;
|
||||
|
||||
reg read = 0;
|
||||
|
||||
dis340 dis(.clk(clk), .reset(~reset),
|
||||
|
||||
.iobus_iob_poweron(iobus_iob_poweron),
|
||||
.iobus_iob_reset(iobus_iob_reset),
|
||||
.iobus_datao_clear(iobus_datao_clear),
|
||||
.iobus_datao_set(iobus_datao_set),
|
||||
.iobus_cono_clear(iobus_cono_clear),
|
||||
.iobus_cono_set(iobus_cono_set),
|
||||
.iobus_iob_fm_datai(iobus_iob_fm_datai),
|
||||
.iobus_iob_fm_status(iobus_iob_fm_status),
|
||||
.iobus_ios(iobus_ios),
|
||||
.iobus_iob_in(iobus_iob_in),
|
||||
.iobus_pi_req(iobus_pi_req),
|
||||
.iobus_iob_out(iobus_iob_out),
|
||||
|
||||
.s_read(read));
|
||||
|
||||
task cono;
|
||||
input [18:35] data;
|
||||
begin
|
||||
iobus_iob_in <= data;
|
||||
iobus_cono_clear <= 1;
|
||||
#20;
|
||||
iobus_cono_clear <= 0;
|
||||
#20;
|
||||
iobus_cono_set <= 1;
|
||||
#20;
|
||||
iobus_cono_set <= 0;
|
||||
#20;
|
||||
end
|
||||
endtask
|
||||
|
||||
task datao;
|
||||
input [0:35] data;
|
||||
begin
|
||||
@(posedge dis.dis_flag_data);
|
||||
#600;
|
||||
@(posedge clk);
|
||||
iobus_iob_in <= data;
|
||||
iobus_datao_clear <= 1;
|
||||
#20;
|
||||
iobus_datao_clear <= 0;
|
||||
#20;
|
||||
iobus_datao_set <= 1;
|
||||
#20;
|
||||
iobus_datao_set <= 0;
|
||||
#20;
|
||||
end
|
||||
endtask
|
||||
|
||||
task disp;
|
||||
input [0:17] word;
|
||||
begin
|
||||
list[i] = word;
|
||||
i = i + 1;
|
||||
end
|
||||
endtask
|
||||
|
||||
reg [0:17] list[0:1000];
|
||||
integer i, n;
|
||||
|
||||
wire [0:18] Esc = 18'o400000;
|
||||
wire [0:18] Vert = 18'o200000;
|
||||
wire [0:18] Iv = 18'o200000;
|
||||
wire [0:18] Ixy = 18'o002000;
|
||||
wire [0:18] Stop = 18'o002000;
|
||||
wire [0:18] PM = 18'o000000;
|
||||
wire [0:18] XYM = 18'o020000;
|
||||
wire [0:18] CM = 18'o060000;
|
||||
wire [0:18] VM = 18'o100000;
|
||||
wire [0:18] VCM = 18'o120000;
|
||||
wire [0:18] IM = 18'o140000;
|
||||
|
||||
initial begin
|
||||
$dumpfile("dump.vcd");
|
||||
$dumpvars();
|
||||
|
||||
for(i = 0; i < 1000; i = i + 1)
|
||||
list[i] = 0;
|
||||
|
||||
i = 0;
|
||||
/*
|
||||
disp(XYM | 'o100 | 'o17);
|
||||
disp(XYM | 'o77);
|
||||
disp(XYM | Vert | 'o66 | Ixy);
|
||||
disp(VM | Vert | 'o55 | Ixy);
|
||||
disp(Esc | Iv | { 8'o100, 8'o25 });
|
||||
disp(XYM | 'o160);
|
||||
disp(XYM | 'o1000);
|
||||
disp(IM | 'o1000 | Vert);
|
||||
disp(Iv | { 4'b1000, 4'b1000, 4'b1000, 4'b1000 });
|
||||
disp(Iv | { 4'b0010, 4'b0010, 4'b0010, 4'b0010 });
|
||||
disp(Iv | { 4'b1100, 4'b1100, 4'b1100, 4'b1100 });
|
||||
disp(Iv | { 4'b0011, 4'b0011, 4'b0011, 4'b0011 } | Esc);
|
||||
disp(VCM);
|
||||
disp(Esc | Iv | { 8'b1, 8'b1 });
|
||||
*/
|
||||
disp(XYM | 'o160 | 'o17);
|
||||
disp(XYM | 'o400 | Vert);
|
||||
disp(CM | 'o1000);
|
||||
disp({ 6'o01, 6'o36, 6'o03 });
|
||||
disp({ 6'o37, 6'o02, 6'o03 });
|
||||
disp(Stop | 'o1000);
|
||||
n = i;
|
||||
|
||||
for(i = 0; i < n; i = i + 1)
|
||||
$display("list[%d] = %o", i, list[i]);
|
||||
|
||||
|
||||
#100;
|
||||
iobus_iob_reset <= 1;
|
||||
#100;
|
||||
iobus_iob_reset <= 0;
|
||||
#100;
|
||||
iobus_ios <= 7'b001_011_0;
|
||||
|
||||
|
||||
#200;
|
||||
cono(18'o100);
|
||||
|
||||
for(i = 0; i < n; i = i + 2)
|
||||
datao({ list[i], list[i+1] });
|
||||
/*
|
||||
#2000;
|
||||
$display("");
|
||||
|
||||
cono(18'o100);
|
||||
for(i = 0; i < n; i = i + 2)
|
||||
datao({ list[i], list[i+1] });
|
||||
*/
|
||||
end
|
||||
|
||||
initial begin
|
||||
while(1) begin
|
||||
// @(posedge dis.intensify);
|
||||
// $display("%o %o %o", dis.i, dis.x, dis.y);
|
||||
|
||||
@(posedge dis.fe_data_rq);
|
||||
#700;
|
||||
read <= 1;
|
||||
#1;
|
||||
$display("0x%X, // %t", dis.s_readdata, $time);
|
||||
// $display("%o %o %o", dis.i, dis.x, dis.y);
|
||||
@(posedge clk);
|
||||
read <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
@(posedge dis.stop);
|
||||
#100;
|
||||
$finish;
|
||||
end
|
||||
|
||||
initial begin
|
||||
#2000000;
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
59
verilog/wcsl420.v
Normal file
59
verilog/wcsl420.v
Normal file
@@ -0,0 +1,59 @@
|
||||
module wcsl420(
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
/* IO bus */
|
||||
input wire iobus_iob_poweron,
|
||||
input wire iobus_iob_reset,
|
||||
input wire iobus_datao_clear,
|
||||
input wire iobus_datao_set,
|
||||
input wire iobus_cono_clear,
|
||||
input wire iobus_cono_set,
|
||||
input wire iobus_iob_fm_datai,
|
||||
input wire iobus_iob_fm_status,
|
||||
input wire iobus_rdi_pulse, // unused on 6
|
||||
input wire [3:9] iobus_ios,
|
||||
input wire [0:35] iobus_iob_in,
|
||||
output wire [1:7] iobus_pi_req,
|
||||
output wire [0:35] iobus_iob_out,
|
||||
output wire iobus_dr_split,
|
||||
output wire iobus_rdi_data, // unused on 6
|
||||
|
||||
/* Externals */
|
||||
input wire [0:17] ctl1,
|
||||
input wire [0:17] ctl2,
|
||||
input wire [0:17] ctl3,
|
||||
input wire [0:17] ctl4
|
||||
);
|
||||
assign iobus_dr_split = 0;
|
||||
assign iobus_rdi_data = 0;
|
||||
assign iobus_pi_req = 0;
|
||||
|
||||
wire wcnsls_sel = iobus_ios == 7'b100_010_0;
|
||||
wire wcnsls_datai = wcnsls_sel & iobus_iob_fm_datai;
|
||||
|
||||
wire [0:8] ctl1n = {
|
||||
ctl1[12], ctl1[13], ctl1[10]|ctl1[11],
|
||||
ctl1[15], ctl1[14], 1'b0,
|
||||
3'b0
|
||||
};
|
||||
wire [0:8] ctl2n = {
|
||||
ctl2[12], ctl2[13], ctl2[10]|ctl2[11],
|
||||
ctl2[15], ctl2[14], 1'b0,
|
||||
3'b0
|
||||
};
|
||||
wire [0:8] ctl3n = {
|
||||
ctl3[12], ctl3[13], ctl3[10]|ctl3[11],
|
||||
ctl3[15], ctl3[14], 1'b0,
|
||||
3'b0
|
||||
};
|
||||
wire [0:8] ctl4n = {
|
||||
ctl4[12], ctl4[13], ctl4[10]|ctl4[11],
|
||||
ctl4[15], ctl4[14], 1'b0,
|
||||
3'b0
|
||||
};
|
||||
|
||||
assign iobus_iob_out =
|
||||
wcnsls_datai ? ~{ ctl4n, ctl3n, ctl2n, ctl1n } :
|
||||
36'b0;
|
||||
endmodule
|
||||
36
verilog/wcsl724.v
Normal file
36
verilog/wcsl724.v
Normal file
@@ -0,0 +1,36 @@
|
||||
module wcsl724(
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
/* IO bus */
|
||||
input wire iobus_iob_poweron,
|
||||
input wire iobus_iob_reset,
|
||||
input wire iobus_datao_clear,
|
||||
input wire iobus_datao_set,
|
||||
input wire iobus_cono_clear,
|
||||
input wire iobus_cono_set,
|
||||
input wire iobus_iob_fm_datai,
|
||||
input wire iobus_iob_fm_status,
|
||||
input wire iobus_rdi_pulse, // unused on 6
|
||||
input wire [3:9] iobus_ios,
|
||||
input wire [0:35] iobus_iob_in,
|
||||
output wire [1:7] iobus_pi_req,
|
||||
output wire [0:35] iobus_iob_out,
|
||||
output wire iobus_dr_split,
|
||||
output wire iobus_rdi_data, // unused on 6
|
||||
|
||||
/* Externals */
|
||||
input wire [0:17] ctl1,
|
||||
input wire [0:17] ctl2
|
||||
);
|
||||
assign iobus_dr_split = 0;
|
||||
assign iobus_rdi_data = 0;
|
||||
assign iobus_pi_req = 0;
|
||||
|
||||
wire wcnsls_sel = iobus_ios == 7'b111_010_1;
|
||||
wire wcnsls_datai = wcnsls_sel & iobus_iob_fm_datai;
|
||||
|
||||
assign iobus_iob_out =
|
||||
wcnsls_datai ? { ctl2, ctl1 } :
|
||||
36'b0;
|
||||
endmodule
|
||||
32
verilog/wcsl_av.v
Normal file
32
verilog/wcsl_av.v
Normal file
@@ -0,0 +1,32 @@
|
||||
module wcsl_av(
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
|
||||
/* Avalon slave */
|
||||
input wire s_write,
|
||||
input wire [1:0] s_address,
|
||||
input wire [31:0] s_writedata,
|
||||
|
||||
/* Externals */
|
||||
output reg [0:17] ctl1,
|
||||
output reg [0:17] ctl2,
|
||||
output reg [0:17] ctl3,
|
||||
output reg [0:17] ctl4
|
||||
);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(reset) begin
|
||||
ctl1 <= 0;
|
||||
ctl2 <= 0;
|
||||
ctl3 <= 0;
|
||||
ctl4 <= 0;
|
||||
end else begin
|
||||
if(s_write) case(s_address)
|
||||
2'b00: ctl1 <= s_writedata;
|
||||
2'b01: ctl2 <= s_writedata;
|
||||
2'b10: ctl3 <= s_writedata;
|
||||
2'b11: ctl4 <= s_writedata;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
Reference in New Issue
Block a user