update to first tested version
This commit is contained in:
parent
de1aaf8161
commit
62b2c48b32
Binary file not shown.
After Width: | Height: | Size: 249 KiB |
|
@ -6,4 +6,4 @@ The goal of this repository is to be able to interface a modern (2021 era) [FPGA
|
|||
|
||||
## Current status
|
||||
|
||||
Early draft version, this has not been built or tested.
|
||||
First prototype is working, implements a basic single-resolution, 8-bits only framebuffer over HDMI or VGA.
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
/*
* Hello World for the CodeWarrior
* © 1997 Metrowerks Corp.
*
* Questions and comments to:
* <mailto:support@metrowerks.com>
* <http://www.metrowerks.com/>
*/
#include <stdio.h>
#include <stdlib.h>
/* #include <stdint.h> */
#include <time.h>
#include <OSUtils.h>
typedef int int32_t;
typedef unsigned int uint32_t;
struct nubusfpga_leds_softc {
uint32_t slotid;
};
struct nubusfpga_leds_softc sc;
uint32_t csr_read_simple(uint32_t offset);
void csr_write_simple(uint32_t value, uint32_t offset);
uint32_t rev(uint32_t d);
uint32_t csr_read_simple(uint32_t offset) {
uint32_t *addr;
addr = (uint32_t*)(((0x000000F0 | sc.slotid) << 24) + offset);
return *addr;
}
void csr_write_simple(uint32_t value, uint32_t offset) {
uint32_t *addr;
addr = (uint32_t*)(((0x000000F0 | sc.slotid) << 24) + offset);
*addr = value;
}
uint32_t rev(uint32_t d) {
uint32_t r;
r = 0;
r |= (d & 0x80808080) >> 7;
r |= (d & 0x40404040) >> 5;
r |= (d & 0x20202020) >> 3;
r |= (d & 0x10101010) >> 1;
r |= (d & 0x08080808) << 1;
r |= (d & 0x04040404) << 3;
r |= (d & 0x02020202) << 5;
r |= (d & 0x01010101) << 7;
return r;
}
#define inline
#include "nubusfpga_csr_leds.h"
#undef inline
int main(void)
{
uint32_t x1 = 0xDEADBEEF, x2 = 0xDEADBEEF;
sc.slotid = 0x9;
printf("Test Application for NuBusFPGA\n\n");
printf("Machine settings: char %d short %d int %d long %d long long %d\n", sizeof(char), sizeof(short int), sizeof(int), sizeof(long int), sizeof(long long int));
printf("Global access struct is located in 0x%08X\n", &sc);
printf("Slot id hardwired to 0x%x, check the ID on the card and the ID allocation for the host.\n", sc.slotid);
printf("MMU Mode is: %s\n", (int)GetMMUMode() ? "32-bits" : "24-bits");
printf("Checking HW access by reading Ethernet ROM...\n");
x1 = *(uint32_t*)0x50F08000;
x2 = *(uint32_t*)0x50F08004;
printf("I got 0x%08x 0x%08x (rev: 0x%08x 0x%08x)\n", x1, x2, rev(x1), rev(x2));
printf("Checking if we see our PROM...\n");
x1 = (0xF0000000 | (sc.slot_id<<24) | 0x00FFFFFC);
x2 = *(uint32_t*)x1;
printf("I got 0x%08x for 0x%08x (rev: 0x%08x for 0x%08x)\n", x2, x1, rev(x2), rev(x1));
return 0;
}
|
|
@ -8,15 +8,15 @@ PROCESS_ROM=${NS816DECLROMDIR}/process_rom
|
|||
|
||||
APPLEINCS=${NS816DECLROMDIR}/atrap.inc ${NS816DECLROMDIR}/declrom.inc ${NS816DECLROMDIR}/globals.inc
|
||||
|
||||
HRES=1152
|
||||
VRES=870
|
||||
HRES=1920
|
||||
VRES=1080
|
||||
|
||||
CSRC=NuBusFPGADrvr_OpenClose.c NuBusFPGADrvr_Ctrl.c NuBusFPGADrvr_Status.c
|
||||
CSRC=NuBusFPGADrvr_OpenClose.c NuBusFPGADrvr_Ctrl.c NuBusFPGADrvr_Status.c NuBusFPGAPrimaryInit_Primary.c
|
||||
CSRC_ASM=${CSRC:.c=.s}
|
||||
|
||||
all: vid_decl_rom.bin vid_decl_rom.srec
|
||||
|
||||
vid_decl_rom.o: vid_decl_rom.s NuBusFPGAPrimaryInit.s NuBusFPGADrvr.s ${APPLEINCS} ${CSRC_ASM} DepVideo.inc
|
||||
vid_decl_rom.o: vid_decl_rom.s NuBusFPGAPrimaryInit.s NuBusFPGAPrimaryInit_Primary.s NuBusFPGASecondaryInit.s NuBusFPGADrvr.s ${APPLEINCS} ${CSRC_ASM} DepVideo.inc
|
||||
rm -f res.inc
|
||||
echo -e "HRES=${HRES}\nVRES=${VRES}\n" | tee res.inc
|
||||
${AS} -march=68020 -mcpu=68020 -I${NS816DECLROMDIR} $< -o $@ -a > vid_decl_rom.l
|
||||
|
@ -36,6 +36,11 @@ NuBusFPGADrvr_Status.s: NuBusFPGADrvr_Status.c NuBusFPGADrvr.h
|
|||
sed -i -e 's/^\([^a-zA-Z0-9_]*\.globl.*\)/# --- \1/' $@
|
||||
sed -i -e 's/\.\(L[0-9][0-9]*\)/.Status_\1/g' $@
|
||||
|
||||
NuBusFPGAPrimaryInit_Primary.s: NuBusFPGAPrimaryInit_Primary.c NuBusFPGADrvr.h
|
||||
${CC} -march=68020 -mcpu=68020 -O2 $< -S -o $@ -DHRES=${HRES} -DVRES=${VRES}
|
||||
sed -i -e 's/^\([^a-zA-Z0-9_]*\.globl.*\)/# --- \1/' $@
|
||||
sed -i -e 's/\.\(L[0-9][0-9]*\)/.PIPrimary_\1/g' $@
|
||||
|
||||
vid_decl_rom.srec: vid_decl_rom.o
|
||||
${OBJCOPY} $^ $@ --input-target=elf32-m68k --output-target=srec
|
||||
|
||||
|
|
|
@ -19,17 +19,30 @@
|
|||
|
||||
#define GOBOFB_BASE 0x00900000
|
||||
|
||||
//#define GOBOFB_REG_BASE 0x00900000
|
||||
//#define GOBOFB_MEM_BASE 0x00000000 /* remapped to 0x8f800000 by HW */
|
||||
|
||||
#define GOBOFB_MODE 0x0
|
||||
#define GOBOFB_VBL_MASK 0x4
|
||||
//#define GOBOFB_VBL_DIS 0x8
|
||||
#define GOBOFB_VIDEOCTRL 0x8
|
||||
#define GOBOFB_INTR_CLEAR 0xc
|
||||
#define GOBOFB_RESET 0x10
|
||||
#define GOBOFB_LUT_ADDR 0x14
|
||||
#define GOBOFB_LUT 0x18
|
||||
#define GOBOFB_DEBUG 0x20
|
||||
#define GOBOFB_DEBUG 0x1c
|
||||
//#define GOBOFB_CURSOR_LUT 0x20
|
||||
//#define GOBOFB_CURSOR_XY 0x24
|
||||
//#define GOBOFB_MASK_BASE 0x80
|
||||
//#define GOBOFB_BITS_BASE 0x100
|
||||
|
||||
#define GOBOFB_INTR_VBL 0x1
|
||||
|
||||
#define GOBOFB_MODE_1BIT 0x0
|
||||
#define GOBOFB_MODE_2BIT 0x1
|
||||
#define GOBOFB_MODE_4BIT 0x2
|
||||
#define GOBOFB_MODE_8BIT 0x3
|
||||
//#define GOBOFB_MODE_24BIT 0x10
|
||||
|
||||
struct MyGammaTbl {
|
||||
short gVersion; /*gamma version number*/
|
||||
short gType; /*gamma data type*/
|
||||
|
@ -71,4 +84,9 @@ OSErr cNuBusFPGAStatus(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce);
|
|||
OSErr cNuBusFPGAOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce);
|
||||
OSErr cNuBusFPGAClose(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce);
|
||||
|
||||
/* primary init */
|
||||
UInt32 Primary(SEBlock* block);
|
||||
|
||||
#define Check32QDTrap 0xAB03
|
||||
|
||||
#endif
|
||||
|
|
|
@ -104,8 +104,8 @@ OSErr cNuBusFPGACtl(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
|
|||
short ret = -1;
|
||||
char busMode = 1;
|
||||
|
||||
write_reg(dce, GOBOFB_DEBUG, 0xBEEF0001);
|
||||
write_reg(dce, GOBOFB_DEBUG, pb->csCode);
|
||||
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0001); */
|
||||
/* write_reg(dce, GOBOFB_DEBUG, pb->csCode); */
|
||||
#if 1
|
||||
switch (pb->csCode)
|
||||
{
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
OSErr cNuBusFPGAOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
|
||||
{
|
||||
OSErr ret = noErr;
|
||||
write_reg(dce, GOBOFB_DEBUG, 0xBEEF0000);
|
||||
write_reg(dce, GOBOFB_DEBUG, (unsigned long)dce->dCtlDevBase);
|
||||
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0000); */
|
||||
/* write_reg(dce, GOBOFB_DEBUG, (unsigned long)dce->dCtlDevBase); */
|
||||
|
||||
if (dce->dCtlStorage == nil)
|
||||
{
|
||||
|
@ -47,6 +47,10 @@ OSErr cNuBusFPGAOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
|
|||
|
||||
linearGamma(*dStoreHdl);
|
||||
|
||||
write_reg(dce, GOBOFB_MODE, GOBOFB_MODE_8BIT);
|
||||
|
||||
write_reg(dce, GOBOFB_VIDEOCTRL, 1);
|
||||
|
||||
ret = changeIRQ(dce, 1, openErr);
|
||||
}
|
||||
|
||||
|
@ -62,7 +66,8 @@ OSErr cNuBusFPGAClose(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
|
|||
if (dce->dCtlStorage != nil)
|
||||
{
|
||||
ret = changeIRQ(dce, 0, openErr);
|
||||
DisposePtr((*(NuBusFPGADriverGlobalsHdl)dce->dCtlStorage)->siqel);
|
||||
write_reg(dce, GOBOFB_VIDEOCTRL, 0);
|
||||
DisposePtr((Ptr)(*(NuBusFPGADriverGlobalsHdl)dce->dCtlStorage)->siqel);
|
||||
DisposeHandle(dce->dCtlStorage);
|
||||
dce->dCtlStorage = nil;
|
||||
}
|
||||
|
|
|
@ -38,8 +38,8 @@ OSErr cNuBusFPGAStatus(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
|
|||
NuBusFPGADriverGlobalsHdl dStoreHdl = (NuBusFPGADriverGlobalsHdl)dce->dCtlStorage;
|
||||
NuBusFPGADriverGlobalsPtr dStore = *dStoreHdl;
|
||||
short ret = -1;
|
||||
write_reg(dce, GOBOFB_DEBUG, 0xBEEF0002);
|
||||
write_reg(dce, GOBOFB_DEBUG, pb->csCode);
|
||||
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0002); */
|
||||
/* write_reg(dce, GOBOFB_DEBUG, pb->csCode); */
|
||||
#if 1
|
||||
switch (pb->csCode)
|
||||
{
|
||||
|
|
|
@ -2,102 +2,12 @@
|
|||
.byte sExec2 /* Code revision (Primary init) */
|
||||
.byte sCPU68020 /* CPU type is 68020 */
|
||||
.short 0 /* Reserved */
|
||||
.long Begin-. /* Offset to code. */
|
||||
.long BeginPrimary-. /* Offset to code. */
|
||||
|
||||
Begin:
|
||||
movew #1,%A0@(seStatus) /* VendorStatus <- 1 {Code was executed} */
|
||||
movel %A0,%A3 /* save param block {A0 is destroyed} */
|
||||
|
||||
/* Turn the slot number into a base address. */
|
||||
moveq #0,%D0 /* D0 <- 00000000 */
|
||||
MOVE.B %A0@(seSlot),%D0 /* D0 <- 0000000s */
|
||||
LSL.W #4,%D0 /* D0 <- 000000s0 */
|
||||
/* OR.B %A0@(seSlot),%D0 /* D0 <- 000000ss */
|
||||
OR.W #0xF00,%D0 /* D0 <- 00000Fss */
|
||||
SWAP %D0 /* D0 <- 0Fss0000 */
|
||||
LSL.L #4,%D0 /* D0 <- Fss00000 */
|
||||
movel %D0,%A2 /* A2 <- Base address to the slot. */
|
||||
|
||||
|
||||
/* Reset the hardware. */
|
||||
/* DO YOUR RESET STUFF HERE */
|
||||
|
||||
/* Set mode to one bit per pixel. ; */
|
||||
/* DO YOUR MODE SETTING HERE */
|
||||
|
||||
/* Disable interrupts. ; */
|
||||
movel %A2,%A0 /* get slot base */
|
||||
ADD.L #0x00900004,%A0 /* Adjust the base */ /* FIXME */
|
||||
CLR.B (%A0) /* Disable interrupt from card */
|
||||
|
||||
/* set the color table to black and white */
|
||||
/* SET THE TABLE HERE */
|
||||
|
||||
|
||||
/* The Apple Video card configuration ROM has two video sResources conforming to the */
|
||||
/* two possible different memory configurations. Now we want to figure out which */
|
||||
/* of the configurations we have, and delete the incorrect video sResource from */
|
||||
/* the slot resource table. */
|
||||
/* */
|
||||
/* size the RAM on the video card. To do this, we look for a nice longword in the second */
|
||||
/* half of the frame buffer array that doesn't show up on the screen. I've selected the */
|
||||
/* last longword of the first scanline that is a multiple of 8 in the second RAM bank (line 264). */
|
||||
/* This alignment guarantees that this memory is off the right edge in all pixel depths */
|
||||
/* when the frame buffer base addr is on a normal page boundary. */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
TestPos = (265*1024)-4 /* */
|
||||
TestPat = 0x4d434132 /* test bit pattern */
|
||||
|
||||
SUBA #smParamBlockSize,%SP /* make an SDM parameter block on stack */
|
||||
movel %SP,%A0 /* get pointer to parm block now */
|
||||
MOVE.B seSlot(%A3),spSlot(%A0) /* put slot in pBlock */
|
||||
CLR.B spExtDev(%A0) /* external device = 0 */
|
||||
|
||||
/* movel #TestPos,%D1 /* get offset in %D1 */
|
||||
/* movel #TestPat,(%A2,%D1.L) /* write to alleged RAM */
|
||||
/* movel #-1,-(%SP) /* write out some garbage to clear data lines */
|
||||
/* ADDQ #4,%SP /* and pitch it */
|
||||
/* movel (%A2,%D1.L),%D0 /* read pattern back */
|
||||
/* CMP.L #TestPat,%D0 /* did it stick? */
|
||||
/* BEQ.S ram /* if equal, we have ram */
|
||||
/* MOVE.B #sRsrc_Video8,spID(%A0) /* if not, remove 8-bit table */
|
||||
/* BRA.S noram
|
||||
/*ram:
|
||||
/* MOVE.B #sRsrc_Video4,spID(%A0) /* remove 4-bit table if we have ram */
|
||||
/*noram:
|
||||
/* _sDeleteSRTRec */ /* remove the invalid entry */
|
||||
/* movel #SDeleteSRTRec,%d0
|
||||
/* _SlotManager
|
||||
/* BNE.S done /* */
|
||||
MOVE #2,seStatus(%A3) /* mark the change */
|
||||
done: ADDA #smParamBlockSize,%SP /* clean up */
|
||||
|
||||
/* Clear video RAM to a nice gray */
|
||||
movel #0xAAAAAAAA,%D0 /* graypat1 := $AAAAAAAA */
|
||||
movel %D0,%D1
|
||||
NOT.L %D1
|
||||
|
||||
MOVE.W #defScrnRow,%D4 /* sRow := defScrnRow {Bytes per pixel line} */
|
||||
MOVE.W #defmBounds_Bs-1,%D3 /* sHei := defScrnHeight {Screen Height in pixels} */
|
||||
|
||||
movel %A2,%A1 /* init row pointer /* REPEAT */
|
||||
NxtRow: movel %A1,%A0 /* get next row */
|
||||
MOVE.W #defScrnRow/4-1,%D2 /* rowlongs := defScrnRow/4 - 1 {How many Longs there are} */
|
||||
NxtLong: movel %D0,(%A0)+ /* (%A0) := graypat(1/2) */
|
||||
DBF %D2,NxtLong /* UNTIL rowlongs < 0 */
|
||||
EXG %D0,%D1 /* graypat1 <-> graypat2 */
|
||||
ADD.W %D4,%A1 /* %A1 := %A1 + sRow */
|
||||
DBF %D3,NxtRow /* UNTIL sHei < 0 */
|
||||
|
||||
/* Exit */
|
||||
Exit: RTS /* Return */
|
||||
|
||||
|
||||
/* <PUT YOUR VALUES FOR INIT TABLE, OTHER TABLES, ETC. HERE IF NEEDED> */
|
||||
|
||||
/* END PrimaryInit */
|
||||
|
||||
|
||||
|
||||
BeginPrimary:
|
||||
MOVE.L %A0, -(%A7)
|
||||
JSR Primary
|
||||
MOVE.L (%A7)+, %a0
|
||||
rts
|
||||
.include "NuBusFPGAPrimaryInit_Primary.s"
|
||||
.text
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
#include "NuBusFPGADrvr.h"
|
||||
|
||||
#include <Traps.h>
|
||||
|
||||
#define PRIM_WRITEREG(reg, val) \
|
||||
*((volatile UInt32*)(a32+GOBOFB_BASE+reg)) = (UInt32)val;
|
||||
|
||||
UInt32 Primary(SEBlock* seblock) {
|
||||
UInt32 a32 = 0xF0000000 | ((UInt32)seblock->seSlot << 24);
|
||||
UInt32 a32_l0, a32_l1;
|
||||
UInt32 a32_4p0, a32_4p1;
|
||||
SpBlock spblock;
|
||||
UInt8 pram[8];
|
||||
OSErr err;
|
||||
UInt16 i,j;
|
||||
char busMode;
|
||||
UniversalProcPtr qd32ptr, unimpptr;
|
||||
|
||||
busMode = 1;
|
||||
SwapMMUMode ( &busMode ); // to32 // this likely won't work on older MacII ???
|
||||
|
||||
PRIM_WRITEREG(GOBOFB_VBL_MASK, 0);// disable interrupts
|
||||
|
||||
/* PRIM_WRITEREG(GOBOFB_DEBUG, busMode);// trace */
|
||||
|
||||
/* grey the screen */
|
||||
a32_l0 = a32;
|
||||
a32_l1 = a32 + HRES;
|
||||
for (j = 0 ; j < VRES ; j+= 2) {
|
||||
a32_4p0 = a32_l0;
|
||||
a32_4p1 = a32_l1;
|
||||
for (i = 0 ; i < HRES ; i += 4) {
|
||||
*((UInt32*)a32_4p0) = 0xAAAAAAAA;
|
||||
*((UInt32*)a32_4p1) = 0x55555555;
|
||||
a32_4p0 += 4;
|
||||
a32_4p1 += 4;
|
||||
}
|
||||
a32_l0 += 2*HRES;
|
||||
a32_l1 += 2*HRES;
|
||||
}
|
||||
|
||||
SwapMMUMode ( &busMode ); // restore
|
||||
|
||||
/* call SVersion to figure out if we have a recent SlotManager */
|
||||
//spblock.spSlot = seblock->seSlot;
|
||||
//spblock.spExtDev = 0;
|
||||
err = SVersion(&spblock);
|
||||
|
||||
busMode = 1;
|
||||
SwapMMUMode ( &busMode ); // to32
|
||||
if (err) {
|
||||
/* DCDMF3 p178: if error, old slot manager*/
|
||||
/* PRIM_WRITEREG(GOBOFB_DEBUG, 0xFFFFFFFF);*/
|
||||
/* PRIM_WRITEREG(GOBOFB_DEBUG, err);*/
|
||||
} else {
|
||||
/* DCDMF3 p178: new slot manager */
|
||||
/* PRIM_WRITEREG(GOBOFB_DEBUG, 0);*/
|
||||
/* PRIM_WRITEREG(GOBOFB_DEBUG, spblock.spResult);*/
|
||||
}
|
||||
SwapMMUMode ( &busMode ); // restore
|
||||
|
||||
/* check for 32-bits QuickDraw */
|
||||
qd32ptr = GetTrapAddress(Check32QDTrap);
|
||||
unimpptr = GetTrapAddress(_Unimplemented);
|
||||
|
||||
busMode = 1;
|
||||
SwapMMUMode ( &busMode ); // to32
|
||||
if (qd32ptr == unimpptr) {
|
||||
/* no 32QD */
|
||||
PRIM_WRITEREG(GOBOFB_DEBUG, 0xFFFFFFFF);
|
||||
PRIM_WRITEREG(GOBOFB_DEBUG, unimpptr);
|
||||
} else {
|
||||
/* yes 32QD */
|
||||
PRIM_WRITEREG(GOBOFB_DEBUG, 0x00C0FFEE);
|
||||
}
|
||||
SwapMMUMode ( &busMode ); // restore
|
||||
|
||||
/* check the content of the PRAM */
|
||||
spblock.spSlot = seblock->seSlot;
|
||||
spblock.spResult = (UInt32)pram;
|
||||
err = SReadPRAMRec(&spblock);
|
||||
|
||||
busMode = 1;
|
||||
SwapMMUMode ( &busMode ); // to32
|
||||
if (err) {
|
||||
/* PRIM_WRITEREG(GOBOFB_DEBUG, 0xFFFFFFFF);*/
|
||||
/* PRIM_WRITEREG(GOBOFB_DEBUG, err);*/
|
||||
} else {
|
||||
/* PRIM_WRITEREG(GOBOFB_DEBUG, 0xC0FFEE00);*/
|
||||
/* for (i = 0 ; i < 8 ; i++) */
|
||||
/* PRIM_WRITEREG(GOBOFB_DEBUG, pram[i]);*/
|
||||
}
|
||||
SwapMMUMode ( &busMode ); // restore
|
||||
|
||||
|
||||
seblock->seStatus = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
.byte sExec2 /* Code revision (Primary init) */
|
||||
.byte sCPU68020 /* CPU type is 68020 */
|
||||
.short 0 /* Reserved */
|
||||
.long BeginSecondary-. /* Offset to code. */
|
||||
|
||||
BeginSecondary:
|
||||
movew #1,%A0@(seStatus) /* VendorStatus <- 1 {Code was executed} */
|
||||
movel %A0,%A3 /* save param block */
|
||||
/* Set up a slot parameter block in %A0 */
|
||||
SUBA #smParamBlockSize,%SP /* make an SDM parameter block on stack */
|
||||
movel %SP,%A0 /* get pointer to parm block now */
|
||||
MOVE.B seSlot(%A3),spSlot(%A0) /* put slot in pBlock */
|
||||
CLR.B spExtDev(%A0) /* external device = 0 */
|
||||
|
||||
moveq #8,%D0 /* _sVersion ; find the Slot Manager version */
|
||||
.word 0xA06E /* _sVersion ; find the Slot Manager version */
|
||||
|
||||
MOVEL spResult(%A0),%D1 /* recover result */
|
||||
ADDA #smParamBlockSize,%SP /* drop the slot Parameter block */
|
||||
|
||||
moveq #0,%D0 /* D0 <- 00000000 */
|
||||
MOVEB %A3@(seSlot),%D0 /* D0 <- 0000000s */
|
||||
LSLW #4,%D0 /* D0 <- 000000s0 */
|
||||
/* OR.B %A3@(seSlot),%D0 /* D0 <- 000000ss */
|
||||
OR.W #0xF00,%D0 /* D0 <- 00000Fs0 */
|
||||
SWAP %D0 /* D0 <- 0Fs00000 */
|
||||
LSLL #4,%D0 /* D0 <- Fs000000 */
|
||||
MOVEAL %D0,%A1
|
||||
|
||||
/* param block in %A3, our HW (32-bits mode) in %A1 */
|
||||
addl #0x00900000, %A1
|
||||
movel #0x0f0f0f0f,%A1@(0x20) /* marker to qemu */
|
||||
movel %D1,%A1@(0x20) /*_sVersion spResult to Qemu */
|
||||
|
||||
ExitSecondary:
|
||||
RTS /* Return */
|
||||
|
Binary file not shown.
|
@ -20,7 +20,7 @@ _sRsrc_Board:
|
|||
DatLstEntry boardId,NuBusFPGAID /* board ID # (assigned by DTS) */
|
||||
OSLstEntry primaryInit,_sPInitRec /* offset to PrimaryInit exec blk */
|
||||
OSLstEntry vendorInfo,_VendorInfo /* offset to vendor info record */
|
||||
/* OSLstEntry SecondaryInit,_sSInitRec */ /* offset to SecondaryInit block */
|
||||
OSLstEntry secondaryInit,_sSInitRec /* offset to SecondaryInit block */
|
||||
OSLstEntry sRsrcVidNames, _VModeName
|
||||
.long EndOfList
|
||||
|
||||
|
@ -40,14 +40,16 @@ _BoardName:
|
|||
_sPInitRec:
|
||||
.long _EndsPInitRec-_sPInitRec /* physical block size */
|
||||
.include "NuBusFPGAPrimaryInit.s" /* the header/code */
|
||||
.text
|
||||
ALIGN 2
|
||||
_EndsPInitRec:
|
||||
_EndsPInitRec:
|
||||
|
||||
/* _sSInitRec */
|
||||
/* .long _EndsSInitRec-_sSInitRec ; physical block size */
|
||||
/* INCLUDE "NuBusFPGASecondaryInit.a" ; the header/code */
|
||||
/* ALIGN 2 */
|
||||
/* _EndsSInitRec */
|
||||
_sSInitRec:
|
||||
.long _EndsSInitRec-_sSInitRec /* physical block size */
|
||||
.include "NuBusFPGASecondaryInit.s" /* the header/code */
|
||||
.text
|
||||
ALIGN 2
|
||||
_EndsSInitRec:
|
||||
|
||||
ALIGN 2
|
||||
_VendorInfo:
|
||||
|
@ -183,7 +185,8 @@ _EndEBVParms:
|
|||
DeclROMDir:
|
||||
OSLstEntry 0, _sRsrcDir
|
||||
.long DeclRomEnd-_sRsrcDir /* Length should be 0x824 */
|
||||
DeclROMCRC: .long 0x0 /* TODO: calculate this */
|
||||
DeclROMCRC:
|
||||
.long 0x0 /* TODO: calculate this */
|
||||
.byte 1 /* Revision Level */
|
||||
.byte appleFormat /* Apple Format */
|
||||
.long testPattern /* magic TestPattern */
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
NuBusFPGAID EQU $BEEF
defMinorBase EQU 0 ; beginning
defMinorLength EQU $C0000 ; 768 KiB
Pages8s EQU 1 ; no idea
defmBounds_Ts EQU 0
defmBounds_Ls EQU 0
defmBounds_Bs EQU 480
defmBounds_Rs EQU 640
DrHwNuBusFPGA EQU $BEEF ; placeholder
defmBaseOffset EQU 0 ; beginning, placeholder
devVersion EQU 0 ; placeholder
defmHRes EQU $480000 ;Horizontal Pixels/inch
defmVRes EQU $480000 ;Vertical pixels/inch
defmDevType EQU 0 ;0 = CLUTType
defmPlaneBytes EQU 0 ;Offset from one plane to the next.
SGammaResID EQU 0
RB8s EQU 640
ChunkyIndexed EQU 0
defVersion EQU 0 ;Version = 0
ROMSize EQU $1000 ;4K byte ROM
|
|
@ -0,0 +1 @@
|
|||
DC.B sExec2 ; code revision
DC.B sCPU68020 ; CPU type is 68020
DC.W 0 ; reserved
DC.L Begin1stInit-* ; offset to code
WITH seBlock,spBlock
Begin1stInit
MOVE.W #1,seStatus(A0) ; assume a good return
MOVE.L #$F0000000,D1 ; Dl <- F0000000
MOVE.B seSlot(A0),D0 ; get slot number
BFINS D0,D1{4:4} ; Dl <- Fs000000
MOVE.L D1,A1 ; copy to address reg
;;; INITIALIZE SOME STUFF HERE
SUBA #spBlockSize,SP ; make an spB10ck
MOVE.L SP,A0 ; get pointer to parms
MOVE.B D0,spSlot(A0) ; identify the slot
CLR.B SpExtDev(A0) ; external device = 0
RTS
ENDWITH
|
|
@ -2,7 +2,7 @@
|
|||
source /opt/Xilinx/Vivado/2020.1/settings64.sh
|
||||
export LD_LIBRARY_PATH=/opt/Xilinx/Vivado/2020.1/lib/lnx64.o/SuSE
|
||||
|
||||
python3 nubus_to_fpga_soc.py --build --csr-csv csr.csv --csr-json csr.json --variant=ztex2.13a --version=V1.0 --goblin --goblin-res 1280x1024@60Hz --sys-clk-freq 100e6
|
||||
python3 nubus_to_fpga_soc.py --build --csr-csv csr.csv --csr-json csr.json --variant=ztex2.13a --version=V1.0 --sys-clk-freq 100e6 --goblin --goblin-res 1920x1080@60Hz --hdmi
|
||||
) 2>&1 | tee build_V1_0.log
|
||||
# --goblin --goblin-res 1280x1024@60Hz
|
||||
# --hdmi
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from math import log2
|
||||
|
||||
from migen import *
|
||||
|
||||
from litedram.frontend.dma import LiteDRAMDMAReader;
|
||||
|
@ -9,15 +11,21 @@ class LiteDRAMFBDMAReader(LiteDRAMDMAReader):
|
|||
def __init__(self, port, fifo_depth=16, default_base=0, default_length=0):
|
||||
LiteDRAMDMAReader.__init__(self = self, port = port, fifo_depth = fifo_depth, fifo_buffered = True, with_csr = False)
|
||||
|
||||
enable = self.enable = Signal(reset = 0)
|
||||
base = self.base = Signal(self.port.address_width, reset = default_base)
|
||||
offset = self.offset = Signal(self.port.address_width, reset = 0)
|
||||
length = self.length = Signal(self.port.address_width, reset = default_length)
|
||||
self.enable = Signal(reset = 0)
|
||||
self.base = Signal(32, reset = default_base)
|
||||
self.length = Signal(32, reset = default_length)
|
||||
|
||||
shift = log2_int(self.port.data_width//8)
|
||||
base = Signal(self.port.address_width)
|
||||
length = Signal(self.port.address_width)
|
||||
offset = Signal(self.port.address_width, reset = 0)
|
||||
self.comb += base.eq(self.base[shift:])
|
||||
self.comb += length.eq(self.length[shift:])
|
||||
|
||||
fsm = FSM(reset_state="IDLE")
|
||||
fsm = ResetInserter()(fsm)
|
||||
self.submodules.fsm = fsm
|
||||
self.comb += fsm.reset.eq(~enable)
|
||||
self.comb += fsm.reset.eq(~self.enable)
|
||||
fsm.act("IDLE",
|
||||
NextValue(offset, 0),
|
||||
NextState("RUN"),
|
||||
|
|
|
@ -12,12 +12,26 @@ from litex.build.io import SDROutput, DDROutput
|
|||
|
||||
from litex.soc.cores.video import *
|
||||
|
||||
video_timing_hwcursor_layout = [
|
||||
# Synchronization signals.
|
||||
("hsync", 1),
|
||||
("vsync", 1),
|
||||
("de", 1),
|
||||
("hwcursor", 1),
|
||||
("hwcursorx", 5),
|
||||
("hwcursory", 5),
|
||||
# Extended/Optional synchronization signals.
|
||||
("hres", hbits),
|
||||
("vres", vbits),
|
||||
("hcount", hbits),
|
||||
("vcount", vbits),
|
||||
]
|
||||
|
||||
# FB Video Timing Generator ---------------------------------------------------------------------------
|
||||
# Same as the normal one except (a) _enable isn't a CSR
|
||||
|
||||
class FBVideoTimingGenerator(Module, AutoCSR):
|
||||
def __init__(self, default_video_timings="800x600@60Hz"):
|
||||
def __init__(self, default_video_timings="800x600@60Hz", hwcursor=False):
|
||||
# Check / Get Video Timings (can be str or dict)
|
||||
if isinstance(default_video_timings, str):
|
||||
try:
|
||||
|
@ -31,7 +45,7 @@ class FBVideoTimingGenerator(Module, AutoCSR):
|
|||
self.video_timings = vt = default_video_timings
|
||||
|
||||
# MMAP Control/Status Registers.
|
||||
self._enable = Signal(reset = 0)
|
||||
self.enable = Signal() # external control signal
|
||||
|
||||
self._hres = CSRStorage(hbits, vt["h_active"])
|
||||
self._hsync_start = CSRStorage(hbits, vt["h_active"] + vt["h_sync_offset"])
|
||||
|
@ -44,14 +58,19 @@ class FBVideoTimingGenerator(Module, AutoCSR):
|
|||
self._vscan = CSRStorage(vbits, vt["v_active"] + vt["v_blanking"])
|
||||
|
||||
# Video Timing Source
|
||||
self.source = source = stream.Endpoint(video_timing_layout)
|
||||
if (hwcursor):
|
||||
self.source = source = stream.Endpoint(video_timing_hwcursor_layout)
|
||||
_hwcursor_x = Signal(12) # 12 out of 16 is enough
|
||||
_hwcursor_y = Signal(12) # 12 out of 16 is enough
|
||||
self.hwcursor_x = Signal(12)
|
||||
self.hwcursor_y = Signal(12)
|
||||
self.specials += MultiReg(self.hwcursor_x, _hwcursor_x)
|
||||
self.specials += MultiReg(self.hwcursor_y, _hwcursor_y)
|
||||
else:
|
||||
self.source = source = stream.Endpoint(video_timing_layout)
|
||||
|
||||
# # #
|
||||
|
||||
# Resynchronize Enable to Video clock domain.
|
||||
self.enable = enable = Signal()
|
||||
self.specials += MultiReg(self._enable, enable)
|
||||
|
||||
# Resynchronize Horizontal Timings to Video clock domain.
|
||||
self.hres = hres = Signal(hbits)
|
||||
self.hsync_start = hsync_start = Signal(hbits)
|
||||
|
@ -78,7 +97,7 @@ class FBVideoTimingGenerator(Module, AutoCSR):
|
|||
fsm = FSM(reset_state="IDLE")
|
||||
fsm = ResetInserter()(fsm)
|
||||
self.submodules.fsm = fsm
|
||||
self.comb += fsm.reset.eq(~enable)
|
||||
self.comb += fsm.reset.eq(~self.enable)
|
||||
fsm.act("IDLE",
|
||||
NextValue(hactive, 0),
|
||||
NextValue(vactive, 0),
|
||||
|
@ -120,3 +139,12 @@ class FBVideoTimingGenerator(Module, AutoCSR):
|
|||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
if (hwcursor):
|
||||
self.sync += source.hwcursor.eq((source.hcount >= _hwcursor_x) &
|
||||
(source.hcount < (_hwcursor_x+32)) &
|
||||
(source.vcount >= _hwcursor_y) &
|
||||
(source.vcount < (_hwcursor_y+32)))
|
||||
self.sync += source.hwcursorx.eq(_hwcursor_x - source.hcount)
|
||||
self.sync += source.hwcursory.eq(_hwcursor_y - source.vcount)
|
||||
|
|
|
@ -8,6 +8,8 @@ from litex.soc.cores.code_tmds import TMDSEncoder
|
|||
|
||||
from litex.build.io import SDROutput, DDROutput
|
||||
|
||||
from migen.genlib.cdc import MultiReg
|
||||
|
||||
from litex.soc.cores.video import *
|
||||
|
||||
from fb_video import *
|
||||
|
@ -27,29 +29,60 @@ omap_layout = [
|
|||
|
||||
def goblin_rounded_size(hres, vres):
|
||||
mib = int(ceil(((hres * vres) + 0) / 1048576))
|
||||
if (mib == 3):
|
||||
mib = 4
|
||||
if (mib > 4 and mib < 8):
|
||||
if (mib > 0 and mib < 8): # FIXME : NuBus
|
||||
mib = 8
|
||||
if (mib > 8 or mib < 1):
|
||||
#if (mib > 0 and mib < 16): # FIXME : SBus
|
||||
# mib = 16
|
||||
if (mib > 16 or mib < 1):
|
||||
print(f"{mib} mebibytes framebuffer not supported")
|
||||
assert(False)
|
||||
return int(1048576 * mib)
|
||||
|
||||
class VideoFrameBuffer256c(Module, AutoCSR):
|
||||
"""Video FrameBuffer256c"""
|
||||
def __init__(self, dram_port, upd_clut_fifo = None, hres=800, vres=600, base=0x00000000, fifo_depth=65536, clock_domain="sys", clock_faster_than_sys=False):
|
||||
class VideoFrameBufferMultiDepth(Module, AutoCSR):
|
||||
"""Video FrameBufferMultiDepth"""
|
||||
def __init__(self, dram_port, upd_clut_fifo = None, hres=800, vres=600, base=0x00000000, fifo_depth=65536, clock_domain="sys", clock_faster_than_sys=False, hwcursor=False, upd_overlay_fifo=False, upd_omap_fifo=False, truecolor=True):
|
||||
|
||||
print(f"FRAMEBUFFER: dram_port.data_width = {dram_port.data_width}, {hres}x{vres}, 0x{base:x}, in {clock_domain}, clock_faster_than_sys={clock_faster_than_sys}")
|
||||
|
||||
npixelsdiv8 = hres * vres // 8
|
||||
vga_sync = getattr(self.sync, clock_domain)
|
||||
|
||||
npixels = hres * vres
|
||||
|
||||
# if 0, 32-bits mode
|
||||
# should only be changed while in reset
|
||||
self.use_indexed = Signal(1, reset = 0x1)
|
||||
# mode, as x in 2^x (so 1, 2, 4, 8 bits)
|
||||
# should only be changed while in reset
|
||||
self.mode = Signal(2, reset = 3)
|
||||
self.indexed_mode = Signal(2, reset = 0x3)
|
||||
self.vblping = Signal(reset = 0)
|
||||
|
||||
if (hwcursor):
|
||||
self.vtg_sink = vtg_sink = stream.Endpoint(video_timing_hwcursor_layout)
|
||||
upd_omap_fifo_dout = Record(omap_layout)
|
||||
self.comb += upd_omap_fifo_dout.raw_bits().eq(upd_omap_fifo.dout)
|
||||
overlay = Array(Array(Array(Signal(1) for x in range(0,32)) for y in range(0,32)) for i in range(0, 2))
|
||||
omap = Array(Array(Signal(8, reset = (255-i)) for i in range(0, 4)) for j in range(0, 3))
|
||||
vga_sync += [
|
||||
If(upd_overlay_fifo.readable,
|
||||
upd_overlay_fifo.re.eq(1),
|
||||
[ overlay[upd_overlay_fifo.dout[0]][upd_overlay_fifo.dout[1:6]][x].eq(upd_overlay_fifo.dout[6+x]) for x in range(0, 32)],
|
||||
).Else(
|
||||
upd_overlay_fifo.re.eq(0),
|
||||
)
|
||||
]
|
||||
vga_sync += [
|
||||
If(upd_omap_fifo.readable,
|
||||
upd_omap_fifo.re.eq(1),
|
||||
omap[upd_omap_fifo_dout.color][upd_omap_fifo_dout.address].eq(upd_omap_fifo_dout.data),
|
||||
).Else(
|
||||
upd_omap_fifo.re.eq(0),
|
||||
)
|
||||
]
|
||||
else:
|
||||
self.vtg_sink = vtg_sink = stream.Endpoint(video_timing_layout)
|
||||
|
||||
self.vtg_sink = vtg_sink = stream.Endpoint(video_timing_layout)
|
||||
|
||||
|
||||
self.source = source = stream.Endpoint(video_data_layout)
|
||||
self.underflow = Signal()
|
||||
|
||||
|
@ -58,7 +91,22 @@ class VideoFrameBuffer256c(Module, AutoCSR):
|
|||
source_buf_de = Signal()
|
||||
source_buf_hsync = Signal()
|
||||
source_buf_vsync = Signal()
|
||||
data_buf = Signal(8)
|
||||
data_buf_index = Signal(8)
|
||||
data_buf_direct = Array(Signal(8) for x in range(3))
|
||||
if (hwcursor):
|
||||
hwcursor_buf = Signal()
|
||||
hwcursorx_buf = Signal(5)
|
||||
hwcursory_buf = Signal(5)
|
||||
|
||||
source_buf_b_valid = Signal()
|
||||
source_buf_b_de = Signal()
|
||||
source_buf_b_hsync = Signal()
|
||||
source_buf_b_vsync = Signal()
|
||||
data_buf_b_index = Signal(8)
|
||||
if (truecolor):
|
||||
data_buf_b_direct = Array(Signal(8) for x in range(3))
|
||||
if (hwcursor):
|
||||
hwcursor_color_idx = Signal(2)
|
||||
|
||||
#source_out_ready = Signal()
|
||||
source_out_valid = Signal()
|
||||
|
@ -70,19 +118,18 @@ class VideoFrameBuffer256c(Module, AutoCSR):
|
|||
source_out_b = Signal(8)
|
||||
|
||||
# # #
|
||||
# First the Color Look-up Table (for all but 1 bit)
|
||||
# First the Color Look-up Table (for all but 1 bit & 32 bits)
|
||||
# updated from the FIFO
|
||||
# 8-and-less-than-8-bits mode used the 2^x first entries
|
||||
clut = Array(Array(Signal(8, reset = (255-i)) for i in range(0, 256)) for j in range(0, 3))
|
||||
### clut = Array(Array(Signal(8, reset = (255-i)) for i in range(0, 256)) for j in range(0, 3))
|
||||
clut = Array(Array(Signal(8, reset = (255-i)) for j in range(0, 3)) for i in range(0, 256))
|
||||
|
||||
upd_clut_fifo_dout = Record(cmap_layout)
|
||||
self.comb += upd_clut_fifo_dout.raw_bits().eq(upd_clut_fifo.dout)
|
||||
|
||||
vga_sync = getattr(self.sync, clock_domain)
|
||||
vga_sync += [
|
||||
If(upd_clut_fifo.readable,
|
||||
upd_clut_fifo.re.eq(1),
|
||||
clut[upd_clut_fifo_dout.color][upd_clut_fifo_dout.address].eq(upd_clut_fifo_dout.data),
|
||||
clut[upd_clut_fifo_dout.address][upd_clut_fifo_dout.color].eq(upd_clut_fifo_dout.data),
|
||||
).Else(
|
||||
upd_clut_fifo.re.eq(0),
|
||||
)
|
||||
|
@ -94,10 +141,13 @@ class VideoFrameBuffer256c(Module, AutoCSR):
|
|||
from fb_dma import LiteDRAMFBDMAReader
|
||||
# length should be changed to match mode
|
||||
self.submodules.fb_dma = LiteDRAMFBDMAReader(dram_port,
|
||||
fifo_depth=fifo_depth//(dram_port.data_width//8),
|
||||
fifo_depth = fifo_depth//(dram_port.data_width//8),
|
||||
default_base = base,
|
||||
default_length = npixelsdiv8 * 8)
|
||||
|
||||
default_length = npixels)
|
||||
##self.submodules.fb_dma = ResetInserter()(self._fb_dma)
|
||||
##self.fb_dma_reset = Signal(reset = 0)
|
||||
##self.comb += self.fb_dma.reset.eq(self.fb_dma_reset)
|
||||
|
||||
# If DRAM Data Width > 8-bit and Video clock is faster than sys_clk:
|
||||
# actually always use that case to simplify the design
|
||||
# if (dram_port.data_width > 8) and clock_faster_than_sys:
|
||||
|
@ -105,69 +155,148 @@ class VideoFrameBuffer256c(Module, AutoCSR):
|
|||
self.submodules.cdc = stream.ClockDomainCrossing([("data", dram_port.data_width)], cd_from="sys", cd_to=clock_domain)
|
||||
self.comb += self.fb_dma.source.connect(self.cdc.sink)
|
||||
# ... and then Data-Width Conversion.
|
||||
# we have 4 possible conversion and mux/connect the appropriate one
|
||||
# we have 5 possible conversion and mux/connect the appropriate one
|
||||
if (truecolor):
|
||||
self.submodules.conv32 = ClockDomainsRenamer({"sys": clock_domain})(stream.Converter(dram_port.data_width, 32))
|
||||
handle_truecolor_sink = [ self.cdc.source.connect(self.conv32.sink) ]
|
||||
handle_truecolor_source = [ source_buf_valid.eq(self.conv32.source.valid),
|
||||
self.conv32.source.connect(source, keep={"ready"}), ]
|
||||
handle_truecolor_databuf = [ data_buf_direct[0].eq(self.conv32.source.data[24:32]),
|
||||
data_buf_direct[1].eq(self.conv32.source.data[16:24]),
|
||||
data_buf_direct[2].eq(self.conv32.source.data[8:16]), ]
|
||||
handle_truecolor_databuf_b = [ data_buf_b_direct[0].eq(data_buf_direct[0]),
|
||||
data_buf_b_direct[1].eq(data_buf_direct[1]),
|
||||
data_buf_b_direct[2].eq(data_buf_direct[2]), ]
|
||||
handle_truecolor_source = [ source_out_r.eq(data_buf_b_direct[2]),
|
||||
source_out_g.eq(data_buf_b_direct[1]),
|
||||
source_out_b.eq(data_buf_b_direct[0]), ]
|
||||
else:
|
||||
handle_truecolor_sink = [ ]
|
||||
handle_truecolor_source = [ ]
|
||||
handle_truecolor_databuf = [ ]
|
||||
handle_truecolor_databuf_b = [ ]
|
||||
handle_truecolor_source = [ ]
|
||||
self.submodules.conv8 = ClockDomainsRenamer({"sys": clock_domain})(stream.Converter(dram_port.data_width, 8))
|
||||
self.submodules.conv4 = ClockDomainsRenamer({"sys": clock_domain})(stream.Converter(dram_port.data_width, 4))
|
||||
self.submodules.conv2 = ClockDomainsRenamer({"sys": clock_domain})(stream.Converter(dram_port.data_width, 2))
|
||||
self.submodules.conv1 = ClockDomainsRenamer({"sys": clock_domain})(stream.Converter(dram_port.data_width, 1))
|
||||
self.comb += Case(self.mode, {
|
||||
0x3: self.cdc.source.connect(self.conv8.sink),
|
||||
0x2: self.cdc.source.connect(self.conv4.sink),
|
||||
0x1: self.cdc.source.connect(self.conv2.sink),
|
||||
0x0: self.cdc.source.connect(self.conv1.sink),
|
||||
})
|
||||
|
||||
self.comb += [
|
||||
If(self.use_indexed,
|
||||
Case(self.indexed_mode, {
|
||||
0x3: self.cdc.source.connect(self.conv8.sink),
|
||||
0x2: self.cdc.source.connect(self.conv4.sink),
|
||||
0x1: self.cdc.source.connect(self.conv2.sink),
|
||||
0x0: self.cdc.source.connect(self.conv1.sink),
|
||||
})
|
||||
).Else(
|
||||
*handle_truecolor_sink
|
||||
)
|
||||
]
|
||||
|
||||
# Video Generation.
|
||||
# buffered by 1 cycle to accomodate the look-ups
|
||||
self.comb += [
|
||||
vtg_sink.ready.eq(1),
|
||||
If(vtg_sink.valid & vtg_sink.de,
|
||||
Case(self.mode, {
|
||||
0x3: [ source_buf_valid.eq(self.conv8.source.valid),
|
||||
self.conv8.source.connect(source, keep={"ready"}),
|
||||
data_buf.eq(self.conv8.source.data),
|
||||
],
|
||||
0x2: [ source_buf_valid.eq(self.conv4.source.valid),
|
||||
self.conv4.source.connect(source, keep={"ready"}),
|
||||
data_buf.eq(Cat(self.conv4.source.data, Signal(4, reset = 0))),
|
||||
],
|
||||
0x1: [ source_buf_valid.eq(self.conv2.source.valid),
|
||||
self.conv2.source.connect(source, keep={"ready"}),
|
||||
data_buf.eq(Cat(self.conv2.source.data, Signal(6, reset = 0))),
|
||||
],
|
||||
0x0: [ source_buf_valid.eq(self.conv1.source.valid),
|
||||
self.conv1.source.connect(source, keep={"ready"}),
|
||||
data_buf.eq(Replicate(self.conv2.source.data, 8)),
|
||||
],
|
||||
}),
|
||||
If(self.use_indexed,
|
||||
Case(self.indexed_mode, {
|
||||
0x3: [ source_buf_valid.eq(self.conv8.source.valid),
|
||||
self.conv8.source.connect(source, keep={"ready"}),
|
||||
],
|
||||
0x2: [ source_buf_valid.eq(self.conv4.source.valid),
|
||||
self.conv4.source.connect(source, keep={"ready"}),
|
||||
],
|
||||
0x1: [ source_buf_valid.eq(self.conv2.source.valid),
|
||||
self.conv2.source.connect(source, keep={"ready"}),
|
||||
],
|
||||
0x0: [ source_buf_valid.eq(self.conv1.source.valid),
|
||||
self.conv1.source.connect(source, keep={"ready"}),
|
||||
],
|
||||
}),
|
||||
).Else(
|
||||
*handle_truecolor_source,
|
||||
),
|
||||
vtg_sink.ready.eq(source_buf_valid & source.ready),
|
||||
),
|
||||
source_buf_de.eq(vtg_sink.de),
|
||||
source_buf_hsync.eq(vtg_sink.hsync),
|
||||
source_buf_vsync.eq(vtg_sink.vsync),
|
||||
Case(self.indexed_mode, {
|
||||
0x3: [ data_buf_index.eq(self.conv8.source.data),
|
||||
],
|
||||
0x2: [ data_buf_index.eq(Cat(self.conv4.source.data, Signal(4, reset = 0))),
|
||||
],
|
||||
0x1: [ data_buf_index.eq(Cat(self.conv2.source.data, Signal(6, reset = 0))),
|
||||
],
|
||||
0x0: [ data_buf_index.eq(Replicate(self.conv1.source.data, 8)),
|
||||
],
|
||||
}),
|
||||
*handle_truecolor_databuf,
|
||||
]
|
||||
|
||||
if (hwcursor):
|
||||
self.comb += [
|
||||
hwcursor_buf.eq(vtg_sink.hwcursor),
|
||||
hwcursorx_buf.eq(vtg_sink.hwcursorx),
|
||||
hwcursory_buf.eq(vtg_sink.hwcursory),
|
||||
]
|
||||
vga_sync += [
|
||||
source_out_de.eq(source_buf_de),
|
||||
source_out_hsync.eq(source_buf_hsync),
|
||||
source_out_vsync.eq(source_buf_vsync),
|
||||
source_out_valid.eq(source_buf_valid),
|
||||
#source_buf_ready.eq(source_out_ready), # ready flow the other way
|
||||
If(source_buf_de,
|
||||
If(self.mode == 0x0,
|
||||
source_out_r.eq(data_buf),
|
||||
source_out_g.eq(data_buf),
|
||||
source_out_b.eq(data_buf)
|
||||
).Else(
|
||||
source_out_r.eq(clut[0][data_buf]),
|
||||
source_out_g.eq(clut[1][data_buf]),
|
||||
source_out_b.eq(clut[2][data_buf])
|
||||
)
|
||||
).Else(source_out_r.eq(0),
|
||||
source_out_g.eq(0),
|
||||
source_out_b.eq(0)
|
||||
) ]
|
||||
|
||||
source_buf_b_de.eq(source_buf_de),
|
||||
source_buf_b_hsync.eq(source_buf_hsync),
|
||||
source_buf_b_vsync.eq(source_buf_vsync),
|
||||
source_buf_b_valid.eq(source_buf_valid),
|
||||
data_buf_b_index.eq(data_buf_index),
|
||||
*handle_truecolor_databuf_b,
|
||||
]
|
||||
if (hwcursor):
|
||||
vga_sync += [
|
||||
If(hwcursor_buf,
|
||||
hwcursor_color_idx.eq(Cat(overlay[0][hwcursory_buf][hwcursorx_buf], overlay[1][hwcursory_buf][hwcursorx_buf])),
|
||||
).Else(
|
||||
hwcursor_color_idx.eq(0),
|
||||
)
|
||||
]
|
||||
|
||||
vga_sync += [
|
||||
source_out_de.eq(source_buf_b_de),
|
||||
source_out_hsync.eq(source_buf_b_hsync),
|
||||
source_out_vsync.eq(source_buf_b_vsync),
|
||||
source_out_valid.eq(source_buf_b_valid),
|
||||
#source_buf_ready.eq(source_out_ready), # ready flow the other way
|
||||
]
|
||||
if (hwcursor):
|
||||
vga_sync += [
|
||||
If(hwcursor_color_idx != 0,
|
||||
source_out_r.eq(omap[0][hwcursor_color_idx]),
|
||||
source_out_g.eq(omap[1][hwcursor_color_idx]),
|
||||
source_out_b.eq(omap[2][hwcursor_color_idx]),
|
||||
).Elif(source_buf_b_de,
|
||||
If(self.use_indexed,
|
||||
source_out_r.eq(clut[data_buf_b_index][2]),
|
||||
source_out_g.eq(clut[data_buf_b_index][1]),
|
||||
source_out_b.eq(clut[data_buf_b_index][0])
|
||||
).Else(
|
||||
*handle_truecolor_source,
|
||||
),
|
||||
).Else(source_out_r.eq(0),
|
||||
source_out_g.eq(0),
|
||||
source_out_b.eq(0)
|
||||
)
|
||||
]
|
||||
else:
|
||||
vga_sync += [
|
||||
If(source_buf_b_de,
|
||||
If(self.use_indexed,
|
||||
source_out_r.eq(clut[data_buf_b_index][2]),
|
||||
source_out_g.eq(clut[data_buf_b_index][1]),
|
||||
source_out_b.eq(clut[data_buf_b_index][0])
|
||||
).Else(
|
||||
*handle_truecolor_source,
|
||||
),
|
||||
).Else(source_out_r.eq(0),
|
||||
source_out_g.eq(0),
|
||||
source_out_b.eq(0)
|
||||
)
|
||||
]
|
||||
|
||||
self.comb += [
|
||||
source.de.eq(source_out_de),
|
||||
source.hsync.eq(source_out_hsync),
|
||||
|
@ -180,31 +309,8 @@ class VideoFrameBuffer256c(Module, AutoCSR):
|
|||
]
|
||||
|
||||
# Underflow.
|
||||
self.comb += self.underflow.eq(~source.valid)
|
||||
|
||||
# track mode changes
|
||||
# in sys cd, not vga cd, as that's where the DMA runs
|
||||
# whenever the mode change, we fully reset the DMA
|
||||
# (we also need to reset the VTG at the same time)
|
||||
old_mode = Signal(2, reset = 3)
|
||||
force_reset = Signal(reset = 0)
|
||||
finish_reset = Signal(reset = 0)
|
||||
old_enable = Signal()
|
||||
self.sync += [
|
||||
old_mode.eq(self.mode),
|
||||
If(old_mode != self.mode,
|
||||
force_reset.eq(1),),
|
||||
If(force_reset == 1,
|
||||
old_enable.eq(self.fb_dma.enable),
|
||||
self.fb_dma.enable.eq(0),
|
||||
self.fb_dma.length.eq(npixelsdiv8 << self.mode),
|
||||
force_reset.eq(0),
|
||||
finish_reset.eq(1),),
|
||||
If(finish_reset == 1,
|
||||
self.fb_dma.enable.eq(old_enable),
|
||||
finish_reset.eq(0)),
|
||||
]
|
||||
|
||||
self.comb += self.underflow.eq(~source.valid & source.de)
|
||||
|
||||
# VBL handling
|
||||
# create a pulse in self.vlbping in sys at the end of the frame
|
||||
from migen.genlib.cdc import PulseSynchronizer
|
||||
|
@ -223,19 +329,28 @@ class VideoFrameBuffer256c(Module, AutoCSR):
|
|||
self.comb += self.vblping.eq(self.vbl_ps.o)
|
||||
|
||||
class goblin(Module, AutoCSR):
|
||||
def __init__(self, soc, phy=None, timings = None, clock_domain="sys"):
|
||||
def __init__(self, soc=None, phy=None, timings=None, clock_domain="sys", irq_line=None, endian="big", truecolor=True):
|
||||
|
||||
# 2 bits for color (0/r, 1/g, 2/b), 8 for @ and 8 for value
|
||||
self.submodules.upd_cmap_fifo = upd_cmap_fifo = ClockDomainsRenamer({"read": "vga", "write": "sys"})(AsyncFIFOBuffered(width=layout_len(cmap_layout), depth=8))
|
||||
self.submodules.upd_cmap_fifo = upd_cmap_fifo = ClockDomainsRenamer({"read": clock_domain, "write": "sys"})(AsyncFIFOBuffered(width=layout_len(cmap_layout), depth=8))
|
||||
upd_cmap_fifo_din = Record(cmap_layout)
|
||||
self.comb += self.upd_cmap_fifo.din.eq(upd_cmap_fifo_din.raw_bits())
|
||||
|
||||
# hw cursor support
|
||||
self.submodules.upd_overlay_fifo = upd_overlay_fifo = ClockDomainsRenamer({"read": clock_domain, "write": "sys"})(AsyncFIFOBuffered(width=1+5+32, depth=8))
|
||||
self.submodules.upd_omap_fifo = upd_omap_fifo = ClockDomainsRenamer({"read": clock_domain, "write": "sys"})(AsyncFIFOBuffered(width=layout_len(omap_layout), depth=8))
|
||||
upd_omap_fifo_din = Record(omap_layout)
|
||||
self.comb += self.upd_omap_fifo.din.eq(upd_omap_fifo_din.raw_bits())
|
||||
|
||||
name = "video_framebuffer"
|
||||
# near duplicate of plaform.add_video_framebuffer
|
||||
# Video Timing Generator.
|
||||
vtg = FBVideoTimingGenerator(default_video_timings=timings if isinstance(timings, str) else timings[1])
|
||||
vtg = FBVideoTimingGenerator(default_video_timings=timings if isinstance(timings, str) else timings[1], hwcursor=True)
|
||||
vtg = ClockDomainsRenamer(clock_domain)(vtg)
|
||||
setattr(self.submodules, f"{name}_vtg", vtg)
|
||||
vtg_enable = Signal(reset = 0)
|
||||
#self.specials += MultiReg(vtg_enable, vtg.enable, clock_domain)
|
||||
self.comb += [ vtg.enable.eq(vtg_enable) ]
|
||||
|
||||
# Video FrameBuffer.
|
||||
timings = timings if isinstance(timings, str) else timings[0]
|
||||
|
@ -245,14 +360,22 @@ class goblin(Module, AutoCSR):
|
|||
vres = int(timings.split("@")[0].split("x")[1])
|
||||
freq = vtg.video_timings["pix_clk"]
|
||||
print(f"goblin: using {hres} x {vres}, {freq/1e6} MHz pixclk")
|
||||
vfb = VideoFrameBuffer256c(dram_port = soc.sdram.crossbar.get_port(),
|
||||
upd_clut_fifo = upd_cmap_fifo,
|
||||
hres = hres,
|
||||
vres = vres,
|
||||
base = base,
|
||||
clock_domain = clock_domain,
|
||||
clock_faster_than_sys = (vtg.video_timings["pix_clk"] > soc.sys_clk_freq))
|
||||
vfb = VideoFrameBufferMultiDepth(dram_port = soc.sdram.crossbar.get_port(),
|
||||
upd_clut_fifo = upd_cmap_fifo,
|
||||
hres = hres,
|
||||
vres = vres,
|
||||
base = base,
|
||||
fifo_depth=(64*1024),
|
||||
clock_domain = clock_domain,
|
||||
clock_faster_than_sys = (vtg.video_timings["pix_clk"] > soc.sys_clk_freq),
|
||||
hwcursor = True,
|
||||
upd_overlay_fifo = upd_overlay_fifo,
|
||||
upd_omap_fifo = upd_omap_fifo,
|
||||
truecolor = truecolor,
|
||||
)
|
||||
setattr(self.submodules, name, vfb)
|
||||
##dma_reset = Signal(reset = 0)
|
||||
##self.comb += self.video_framebuffer.fb_dma_reset.eq(dma_reset)
|
||||
|
||||
# Connect Video Timing Generator to Video FrameBuffer.
|
||||
self.comb += vtg.source.connect(vfb.vtg_sink)
|
||||
|
@ -265,34 +388,35 @@ class goblin(Module, AutoCSR):
|
|||
soc.add_constant("VIDEO_FRAMEBUFFER_HRES", hres)
|
||||
soc.add_constant("VIDEO_FRAMEBUFFER_VRES", vres)
|
||||
|
||||
# goblin registers
|
||||
# struct bt_regs {
|
||||
# u_int bt_addr; /* map address register */
|
||||
# u_int bt_cmap; /* colormap data register */
|
||||
# u_int bt_ctrl; /* control register */
|
||||
# u_int bt_omap; /* overlay (cursor) map register */
|
||||
# };
|
||||
# HW Cursor
|
||||
|
||||
hwcursor_x = Signal(12)
|
||||
hwcursor_y = Signal(12)
|
||||
|
||||
self.comb += vtg.hwcursor_x.eq(hwcursor_x)
|
||||
self.comb += vtg.hwcursor_y.eq(hwcursor_y)
|
||||
|
||||
self.bus = bus = wishbone.Interface()
|
||||
|
||||
# current cmap logic for the goblin, similar to the cg6, minus the HW cursor
|
||||
|
||||
bt_mode = Signal(4, reset = 0) # 0 is 3, 2 is 0, 4 is 1, 8 is 2, and bit depth is 2^
|
||||
bt_mode = Signal(8, reset = 0x3) # bit depth is 2^x ; 0x10 is direct mode (32 bits)
|
||||
bt_addr = Signal(8, reset = 0)
|
||||
bt_cmap_state = Signal(2, reset = 0)
|
||||
m_vbl_disable = Signal(reset = 1)
|
||||
|
||||
videoctrl = Signal()
|
||||
|
||||
vbl_signal = Signal(reset = 0)
|
||||
vbl_irq = soc.platform.request("nmrq_3v3_n")
|
||||
self.comb += vbl_irq.eq(~vbl_signal | m_vbl_disable) # active low
|
||||
|
||||
#self.comb += Case(bt_mode, {
|
||||
# 0x0: self.video_framebuffer.mode.eq(3),
|
||||
# 0x2: self.video_framebuffer.mode.eq(0),
|
||||
# 0x4: self.video_framebuffer.mode.eq(1),
|
||||
# 0x8: self.video_framebuffer.mode.eq(2),
|
||||
# })
|
||||
|
||||
self.comb += irq_line.eq(~vbl_signal | m_vbl_disable) # active low
|
||||
|
||||
if (endian == "big"):
|
||||
low_byte = slice(0, 8)
|
||||
low_bit = slice(0, 1)
|
||||
else:
|
||||
low_byte = slice(24, 32)
|
||||
low_bit = slice(24, 25)
|
||||
|
||||
self.submodules.wishbone_fsm = wishbone_fsm = FSM(reset_state = "Reset")
|
||||
wishbone_fsm.act("Reset",
|
||||
NextValue(bus.ack, 0),
|
||||
|
@ -301,17 +425,25 @@ class goblin(Module, AutoCSR):
|
|||
If(bus.cyc & bus.stb & bus.we & ~bus.ack & upd_cmap_fifo.writable, #write
|
||||
# FIXME: should check for prefix?
|
||||
Case(bus.adr[0:18], {
|
||||
"default": [],
|
||||
# gobofb_mode
|
||||
0x0: [ NextValue(bt_mode, bus.dat_w[0:8]), ],
|
||||
0x0: [ NextValue(bt_mode, bus.dat_w[low_byte]), ],
|
||||
# set vbl
|
||||
0x1: [ NextValue(m_vbl_disable, ~bus.dat_w[low_bit]), ],
|
||||
# gobofb on/off
|
||||
0x2: [ NextValue(videoctrl, bus.dat_w[low_bit]), ],
|
||||
# clear irq
|
||||
0x3: [ NextValue(vbl_signal, 0), ],
|
||||
# 0x4: rest in SW
|
||||
# gobofb_lut_addr
|
||||
0x5: [ NextValue(bt_addr, bus.dat_w[0:8]),
|
||||
0x5: [ NextValue(bt_addr, bus.dat_w[low_byte]),
|
||||
NextValue(bt_cmap_state, 0),
|
||||
],
|
||||
# gobofb_lut
|
||||
0x6: [ upd_cmap_fifo.we.eq(1),
|
||||
upd_cmap_fifo_din.color.eq(bt_cmap_state),
|
||||
upd_cmap_fifo_din.address.eq(bt_addr),
|
||||
upd_cmap_fifo_din.data.eq(bus.dat_w[0:8]),
|
||||
upd_cmap_fifo_din.data.eq(bus.dat_w[low_byte]),
|
||||
Case(bt_cmap_state, {
|
||||
0: [ NextValue(bt_cmap_state, 1), ],
|
||||
1: [ NextValue(bt_cmap_state, 2), ],
|
||||
|
@ -319,17 +451,39 @@ class goblin(Module, AutoCSR):
|
|||
"default": NextValue(bt_cmap_state, 0),
|
||||
}),
|
||||
],
|
||||
# set vbl
|
||||
0x1: [ NextValue(m_vbl_disable, ~bus.dat_w[0:1]), ],
|
||||
# clear irq
|
||||
0x3: [ NextValue(vbl_signal, 0), ],
|
||||
# 0x7: debug in SW
|
||||
# cursor lut
|
||||
0x8: [ upd_omap_fifo.we.eq(1),
|
||||
upd_omap_fifo_din.color.eq(bt_cmap_state),
|
||||
upd_omap_fifo_din.address.eq(bt_addr[0:2]),
|
||||
upd_omap_fifo_din.data.eq(bus.dat_w[low_byte]),
|
||||
Case(bt_cmap_state, {
|
||||
0: [ NextValue(bt_cmap_state, 1), ],
|
||||
1: [ NextValue(bt_cmap_state, 2), ],
|
||||
2: [ NextValue(bt_cmap_state, 0), NextValue(bt_addr, (bt_addr+1) & 0xFF), ],
|
||||
"default": NextValue(bt_cmap_state, 0),
|
||||
}),
|
||||
],
|
||||
# hw cursor x/y
|
||||
0x9: [ NextValue(hwcursor_x, bus.dat_w[16:28]), # FIXME: endianess
|
||||
NextValue(hwcursor_y, bus.dat_w[ 0:12]), # FIXME: endianess
|
||||
],
|
||||
}),
|
||||
Case(bus.adr[5:18], {
|
||||
"default": [],
|
||||
0x1 : [ upd_overlay_fifo.we.eq(1), # 1*32 = 32..63 / 0x20..0x3F
|
||||
upd_overlay_fifo.din.eq(Cat(Signal(1, reset = 0), 31-bus.adr[0:5], bus.dat_w)) # FIXME: endianess
|
||||
],
|
||||
0x2 : [ upd_overlay_fifo.we.eq(1), # 2*32 = 64..95 / 0x40..0x5F
|
||||
upd_overlay_fifo.din.eq(Cat(Signal(1, reset = 1), 31-bus.adr[0:5], bus.dat_w)) # FIXME: endianess
|
||||
],
|
||||
}),
|
||||
NextValue(bus.ack, 1),
|
||||
).Elif(bus.cyc & bus.stb & ~bus.we & ~bus.ack, #read
|
||||
Case(bus.adr[0:18], {
|
||||
# bt_addr
|
||||
0x0: [ NextValue(bus.dat_r, bt_mode), ],
|
||||
0x0: [ NextValue(bus.dat_r[low_byte], bt_mode), ],
|
||||
0x2: [ NextValue(bus.dat_r[low_byte], videoctrl), ],
|
||||
"default": [ NextValue(bus.dat_r, 0xDEADBEEF)],
|
||||
}),
|
||||
NextValue(bus.ack, 1),
|
||||
|
@ -338,28 +492,86 @@ class goblin(Module, AutoCSR):
|
|||
),
|
||||
)
|
||||
# mode switch logic
|
||||
old_bt_mode = Signal(4)
|
||||
vtg_reset_counter = Signal(4, reset = 0) # to put the VTG in reset for a few cyles so that the DMA can restart
|
||||
npixels = hres * vres
|
||||
old_bt_mode = Signal(8) # different from bt_mode
|
||||
in_reset = Signal()
|
||||
post_reset_ctr = Signal(3)
|
||||
previous_videoctrl = Signal()
|
||||
|
||||
if (truecolor):
|
||||
handle_truecolor_bit = [ self.video_framebuffer.use_indexed.eq(~bt_mode[4:5]) ]
|
||||
else:
|
||||
handle_truecolor_bit = [ ]
|
||||
|
||||
# this has grown complicated and should be a FSM...
|
||||
self.sync += [ old_bt_mode.eq(bt_mode),
|
||||
If(old_bt_mode != bt_mode,
|
||||
Case(bt_mode, {
|
||||
0x2: self.video_framebuffer.mode.eq(0),
|
||||
0x4: self.video_framebuffer.mode.eq(1),
|
||||
0x8: self.video_framebuffer.mode.eq(2),
|
||||
0x0: self.video_framebuffer.mode.eq(3),
|
||||
If(old_bt_mode != bt_mode,
|
||||
in_reset.eq(1),
|
||||
videoctrl.eq(0), # start a disabling cycle, or stay disabled
|
||||
previous_videoctrl.eq(videoctrl), # preserve old state for restoration later
|
||||
),
|
||||
If(in_reset & ~vtg_enable, # we asked for a reset and by now, the VTG has been turned off (or was off) so we reset the DMA and change the parameters
|
||||
##dma_reset.eq(1), # hpefully this will clear the FIFO as well
|
||||
self.video_framebuffer.indexed_mode.eq(bt_mode[0:2] & ~(Replicate(bt_mode[4:5], 2))),
|
||||
*handle_truecolor_bit,
|
||||
in_reset.eq(0),
|
||||
post_reset_ctr.eq(7),
|
||||
),
|
||||
##If(post_reset_ctr == 5, # take DMA out of reset
|
||||
## dma_reset.eq(0),
|
||||
##),
|
||||
If(post_reset_ctr == 4, # now reconfigure the DMA
|
||||
If(bt_mode[4:5],
|
||||
self.video_framebuffer.fb_dma.length.eq(npixels * 4),
|
||||
).Else(
|
||||
Case(bt_mode[0:2], {
|
||||
3: self.video_framebuffer.fb_dma.length.eq(npixels ),
|
||||
2: self.video_framebuffer.fb_dma.length.eq(npixels//2),
|
||||
1: self.video_framebuffer.fb_dma.length.eq(npixels//4),
|
||||
0: self.video_framebuffer.fb_dma.length.eq(npixels//8),
|
||||
}),
|
||||
vtg_reset_counter.eq(15),
|
||||
vtg._enable.eq(0),),
|
||||
If(vtg_reset_counter == 1,
|
||||
vtg._enable.eq(1),),
|
||||
If(vtg_reset_counter > 0,
|
||||
vtg_reset_counter.eq(vtg_reset_counter - 1),),
|
||||
]
|
||||
|
||||
),
|
||||
),
|
||||
If(post_reset_ctr == 1, # we've waited for the mode switch so restore video mode
|
||||
videoctrl.eq(previous_videoctrl),
|
||||
),
|
||||
If(post_reset_ctr != 0,
|
||||
post_reset_ctr.eq(post_reset_ctr - 1),
|
||||
),
|
||||
]
|
||||
|
||||
# videoctrl logic
|
||||
old_videoctrl = Signal()
|
||||
videoctrl_starting = Signal()
|
||||
videoctrl_stopping = Signal()
|
||||
self.sync += [
|
||||
If(~videoctrl_starting & ~videoctrl_stopping, # while we're changing state, delay any new request for change
|
||||
old_videoctrl.eq(videoctrl),
|
||||
),
|
||||
# turn on
|
||||
If(videoctrl & ~old_videoctrl, # pos edge
|
||||
self.video_framebuffer.fb_dma.enable.eq(1), # enable DMA
|
||||
videoctrl_starting.eq(1),
|
||||
),
|
||||
If(videoctrl & (self.video_framebuffer.fb_dma.rsv_level != 0),
|
||||
vtg_enable.eq(1), # there's some data requested, good to go
|
||||
videoctrl_starting.eq(0),
|
||||
),
|
||||
# turn off
|
||||
If(~videoctrl & old_videoctrl, # neg edge
|
||||
self.video_framebuffer.fb_dma.enable.eq(0), # disable DMA
|
||||
videoctrl_stopping.eq(1),
|
||||
),
|
||||
If(~videoctrl & (self.video_framebuffer.fb_dma.rsv_level == 0) & (self.video_framebuffer.underflow),
|
||||
vtg_enable.eq(0), # the DMA FIFO is purged, stop vtg
|
||||
videoctrl_stopping.eq(0),
|
||||
),
|
||||
]
|
||||
|
||||
# VBL logic
|
||||
self.sync += [
|
||||
If(self.video_framebuffer.vblping == 1,
|
||||
vbl_signal.eq(1),
|
||||
),]
|
||||
|
||||
|
||||
|
|
|
@ -22,18 +22,17 @@ class NuBus(Module):
|
|||
self.mem_tryagain = Signal()
|
||||
|
||||
# cpu
|
||||
#self.cpu_valid = Signal(reset = 0)
|
||||
#self.cpu_addr = Signal(32)
|
||||
#self.cpu_wdata = Signal(32)
|
||||
#self.cpu_ready = Signal()
|
||||
#self.cpu_write = Signal(4)
|
||||
#self.cpu_rdata = Signal(32)
|
||||
#self.cpu_lock = Signal()
|
||||
#self.cpu_eclr = Signal()
|
||||
#self.cpu_errors = Signal(4)
|
||||
self.cpu_valid = Signal(reset = 0)
|
||||
self.cpu_addr = Signal(32)
|
||||
self.cpu_wdata = Signal(32)
|
||||
self.cpu_ready = Signal()
|
||||
self.cpu_write = Signal(4)
|
||||
self.cpu_rdata = Signal(32)
|
||||
self.cpu_lock = Signal()
|
||||
self.cpu_eclr = Signal()
|
||||
self.cpu_errors = Signal(4)
|
||||
|
||||
# utilities
|
||||
self.tmoen = Signal()
|
||||
# utilities (unused)
|
||||
self.mem_stdslot = Signal()
|
||||
self.mem_super = Signal()
|
||||
self.mem_local = Signal()
|
||||
|
@ -48,7 +47,6 @@ class NuBus(Module):
|
|||
p_SUPERSLOTS_ADDRESS = 0x9,
|
||||
p_WDT_W = 0x8,
|
||||
p_LOCAL_SPACE_EXPOSED_TO_NUBUS = 0,
|
||||
p_NON_ECC_PARITY = 0,
|
||||
i_nub_clkn = ClockSignal(cd_nubus),
|
||||
i_nub_resetn = ~ResetSignal(cd_nubus),
|
||||
i_nub_idn = platform.request("id_3v3_n"),
|
||||
|
@ -60,10 +58,11 @@ class NuBus(Module):
|
|||
io_nub_rqstn = platform.request("rqst_3v3_n"),
|
||||
io_nub_ackn = platform.request("ack_3v3_n"),
|
||||
# io_nub_arbn = platform.request("nubus_arb_n"),
|
||||
o_arb = platform.request("arb"),
|
||||
o_arbcy_n = platform.request("arbcy_n"),
|
||||
i_grant = platform.request("grant"),
|
||||
o_tmoen = platform.request("tmoen"),
|
||||
o_NUBUS_AD_DIR = platform.request("nubus_ad_dir"),
|
||||
o_nubus_master_dir = platform.request("nubus_master_dir"),
|
||||
# io_nub_nmrqn = platform.request("nmrq_3v3_n"),
|
||||
# io_nub_spn = self.nubus_sp_n,
|
||||
# io_nub_spvn = self.nubus_spv_n,
|
||||
|
@ -75,19 +74,21 @@ class NuBus(Module):
|
|||
i_mem_rdata = self.mem_rdata,
|
||||
i_mem_error = self.mem_error,
|
||||
i_mem_tryagain = self.mem_tryagain,
|
||||
#i_cpu_valid = self.cpu_valid,
|
||||
#i_cpu_addr = self.cpu_addr,
|
||||
#i_cpu_wdata = self.cpu_wdata,
|
||||
#o_cpu_ready = self.cpu_ready,
|
||||
#i_cpu_write = self.cpu_write,
|
||||
#o_cpu_rdata = self.cpu_rdata,
|
||||
#i_cpu_lock = self.cpu_lock,
|
||||
#i_cpu_eclr = self.cpu_eclr,
|
||||
#o_cpu_errors = self.cpu_errors,
|
||||
i_cpu_valid = self.cpu_valid,
|
||||
i_cpu_addr = self.cpu_addr,
|
||||
i_cpu_wdata = self.cpu_wdata,
|
||||
o_cpu_ready = self.cpu_ready,
|
||||
i_cpu_write = self.cpu_write,
|
||||
o_cpu_rdata = self.cpu_rdata,
|
||||
i_cpu_lock = self.cpu_lock,
|
||||
i_cpu_eclr = self.cpu_eclr,
|
||||
o_cpu_errors = self.cpu_errors,
|
||||
o_mem_stdslot = self.mem_stdslot,
|
||||
o_mem_super = self.mem_super,
|
||||
o_mem_local = self.mem_local,
|
||||
|
||||
o_fpga_to_cpld_signal = platform.request("fpga_to_cpld_signal"),
|
||||
|
||||
i_nub_clk2xn = ClockSignal(cd_nubus90),
|
||||
io_nub_tm2n = platform.request("tm2_3v3_n"),
|
||||
)
|
||||
|
@ -98,10 +99,10 @@ class NuBus(Module):
|
|||
def add_sources(self, platform):
|
||||
platform.add_source("nubus.v", "verilog")
|
||||
platform.add_source("/home/dolbeau/XiBus/nubus.svh", "verilog")
|
||||
#platform.add_source("/home/dolbeau/XiBus/nubus_arbiter.v", "verilog")
|
||||
#platform.add_source("/home/dolbeau/XiBus/nubus_cpubus.v", "verilog")
|
||||
#platform.add_source("/home/dolbeau/XiBus/nubus_arbiter.v", "verilog") # in the CPLD
|
||||
platform.add_source("/home/dolbeau/XiBus/nubus_cpubus.v", "verilog")
|
||||
platform.add_source("/home/dolbeau/XiBus/nubus_driver.v", "verilog")
|
||||
#platform.add_source("/home/dolbeau/XiBus/nubus_errors.v", "verilog")
|
||||
#platform.add_source("/home/dolbeau/XiBus/nubus_errors.v", "verilog") # unused
|
||||
platform.add_source("/home/dolbeau/XiBus/nubus_membus.v", "verilog")
|
||||
#platform.add_source("/home/dolbeau/XiBus/nubus_master.v", "verilog")
|
||||
platform.add_source("/home/dolbeau/XiBus/nubus_master.v", "verilog")
|
||||
platform.add_source("/home/dolbeau/XiBus/nubus_slave.v", "verilog")
|
||||
|
|
|
@ -2,72 +2,103 @@
|
|||
* NuBus controller
|
||||
*
|
||||
* Autor: Valeriya Pudova (hww.github.io)
|
||||
* Adapted by Romain Dolbeau <romain@dolbeau.org> for the NuBusFPGA
|
||||
* Copyright (c) 2021-2022
|
||||
*/
|
||||
|
||||
/* This module is running on the FPGA */
|
||||
|
||||
module nubus
|
||||
#(
|
||||
// All slots area starts with addrss $FXXX XXXX
|
||||
// All slots area starts with address $FXXX XXXX
|
||||
parameter SLOTS_ADDRESS = 'hF,
|
||||
// All superslots starts at $9000 0000
|
||||
parameter SUPERSLOTS_ADDRESS = 'h9,
|
||||
// Watch dog timer bits. Master controller will terminate transfer
|
||||
// after (2 ^ WDT_W) clocks
|
||||
parameter WDT_W = 8,
|
||||
// Local space of card start and end addres. For example 0-5
|
||||
// Local space of card start and end address. For example 0-5
|
||||
// makes local space address $00000000-$50000000
|
||||
// UNUSED in NuBusFPGA
|
||||
parameter LOCAL_SPACE_EXPOSED_TO_NUBUS = 0,
|
||||
parameter LOCAL_SPACE_START = 0,
|
||||
parameter LOCAL_SPACE_END = 5,
|
||||
// Generate parity without ECC memory
|
||||
parameter NON_ECC_PARITY = 0
|
||||
parameter LOCAL_SPACE_END = 5
|
||||
)
|
||||
|
||||
(
|
||||
/* NuBus signals */
|
||||
|
||||
/* *** NuBus signals *** */
|
||||
/* those are connected to the FPGA */
|
||||
/* connected via the CPLD */
|
||||
input nub_clkn, // Clock (rising is driving edge, faling is sampling)
|
||||
input nub_resetn, // Reset
|
||||
input [ 3:0] nub_idn, // Slot Identificatjon
|
||||
|
||||
// inout nub_pfwn, // Power Fail Warning
|
||||
inout [31:0] nub_adn, // Address/Data
|
||||
input [ 3:0] nub_idn, // Slot Identification
|
||||
inout nub_tm0n, // Transfer Mode
|
||||
inout nub_tm1n, // Transfer Mode
|
||||
inout nub_startn, // Start
|
||||
inout nub_rqstn, // Request
|
||||
inout nub_ackn, // Acknowledge
|
||||
// inout [ 3:0] nub_arbn, // Arbitration
|
||||
output arb,
|
||||
input grant,
|
||||
output tmoen,
|
||||
output NUBUS_AD_DIR,
|
||||
|
||||
//inout nub_nmrqn, // Non-Master Request, handled in the Litex code
|
||||
|
||||
// connected via the CPLD but NuBus90 (unimplemented)
|
||||
input nub_clk2xn,
|
||||
inout nub_tm2n,
|
||||
|
||||
/* connected via the 74LVT245 */
|
||||
inout [31:0] nub_adn, // Address/Data
|
||||
|
||||
/* those are not used, and not even connected in the board */
|
||||
// inout nub_pfwn, // Power Fail Warning
|
||||
// inout nub_spn, // System Parity
|
||||
// inout nub_spvn, // System Parity Valid
|
||||
|
||||
/* Memory bus signals connected to a memory, accesible by nubus or processor */
|
||||
/* those ared used but handled in directly in the Litex code */
|
||||
// output nub_nmrqn, // Non-Master Request, handled in the Litex code
|
||||
|
||||
/* those are used but connected only to the CPLD */
|
||||
/* we deal with the CPLD via 'arbcy_n' and 'grant'
|
||||
// inout [ 3:0] nub_arbn, // Arbitration
|
||||
|
||||
/* *** CPLD <-> FPGA signals, not in NuBus */
|
||||
output arbcy_n, // request arbitration
|
||||
input grant, // arbitration won
|
||||
output tmoen, // output enable for tm0/1
|
||||
|
||||
/* *** CPLD <-> FPGA signals, spare, currently unused */
|
||||
output fpga_to_cpld_signal, // regular signal
|
||||
// inout fpga_to_cpld_signal_2, // regular signal
|
||||
// inout fpga_to_cpld_clk, // clk input on CPLD or regular signal
|
||||
|
||||
/* FPGA -> drivers */
|
||||
output NUBUS_AD_DIR, // direction for the LS245 (input/output for A/D lines)
|
||||
output nubus_master_dir, // are we in master mode (to drive the proper signals)
|
||||
|
||||
/* 'memory bus' signals; those are used to interface with the Wishbone to access the FPGA resources from NuBus */
|
||||
output mem_valid,
|
||||
output [31:0] mem_addr,
|
||||
output [31:0] mem_wdata,
|
||||
output [ 3:0] mem_write,
|
||||
input mem_ready,
|
||||
input [31:0] mem_rdata,
|
||||
input mem_error,
|
||||
input mem_tryagain,
|
||||
input mem_error, // ignored
|
||||
input mem_tryagain, // ignored
|
||||
|
||||
/* 'processor bus' signals; those are used to interface with the Wishbone to access NuBus resources from the FPGA */
|
||||
input cpu_valid,
|
||||
input [31:0] cpu_addr,
|
||||
input [31:0] cpu_wdata,
|
||||
input [ 3:0] cpu_write,
|
||||
output cpu_ready,
|
||||
output [31:0] cpu_rdata,
|
||||
input cpu_lock,
|
||||
input cpu_eclr, // ignored
|
||||
output [3:0] cpu_errors, // ignored
|
||||
|
||||
/* utilities signal from the NuBus stuff, currently unused */
|
||||
// Access to slot area
|
||||
output mem_stdslot,
|
||||
// Access to superslot area ($sXXXXXXX where <s> is card id)
|
||||
output mem_super,
|
||||
// Access to local memory on the card
|
||||
output mem_local,
|
||||
|
||||
// NuBus90 (unimplemented)
|
||||
input nub_clk2xn,
|
||||
inout nub_tm2n
|
||||
output mem_local
|
||||
);
|
||||
|
||||
`include "nubus.svh"
|
||||
|
@ -83,46 +114,66 @@ module nubus
|
|||
// Global signals
|
||||
// ==========================================================================
|
||||
|
||||
wire slv_master, slv_slave, slv_tm1n, slv_tm0n, slv_ackcyn, slv_myslotcy;
|
||||
wire unsigned [31:0] slv_addr;
|
||||
wire drv_tmoen, drv_mstdn;
|
||||
// ===== SLAVE =====
|
||||
//wire slv_master;
|
||||
wire slv_slave; // output nubus_slave module; input internal ; active during slave cycle
|
||||
wire slv_tm1n; // output nubus_slave module; input internal & nubus_membus
|
||||
wire slv_tm0n; // output nubus_slave module; input nubus_membus
|
||||
wire slv_ackcyn; // output nubus_slave module; input nubus_driver
|
||||
wire slv_myslotcy; // output nubus_slave module; input internal & nubus_driver
|
||||
wire unsigned [31:0] slv_addr;// output nubus_slave module; input nubus_membus
|
||||
|
||||
wire mst_timeout;
|
||||
// ===== CPU ====
|
||||
wire unsigned [31:0] cpu_ad; // output nubus_master; input MUX to A/D lines 'nub_ad' (nub_ad then as an OE and an iverter to reach nub_adn)
|
||||
wire cpu_tm1n; // R(h)/W(l); output nubus_cpu; input nubus_driver & internal
|
||||
wire cpu_tm0n; // byte size(l); idem
|
||||
wire cpu_masterd; // ignored
|
||||
|
||||
// ===== DRIVER =====
|
||||
wire drv_tmoen; // output enable for tm0n/tm1n (== tmoen) by nubus_driver
|
||||
wire drv_mstdn; // ??? only connected to driver as an output
|
||||
|
||||
// ===== MASTER ===
|
||||
wire mst_timeout; // timeout???; output nubus_master; input nubus_driver & nubus_slave
|
||||
wire mst_arbcyn; // req. arb; output nubus_master; input internal & to CPLD & nubus_driver
|
||||
assign arbcy_n = mst_arbcyn;
|
||||
wire mst_adrcyn; // during the address cycle for master; output nubus_master; input nubus_driver & nubus_cpubus
|
||||
wire mst_lockedn; // for locked accesses (?); output nubus_master; input nubus_driver
|
||||
wire mst_arbdn; // delay during arbitration; output nubus_master; input [NULL] ???
|
||||
wire mst_busyn; // busy during transfer; output nubus_master; input [NULL] ???
|
||||
wire mst_ownern; // master is bus owner; output nubus_master; input nubus_driver & internal
|
||||
wire mst_dtacyn; // during the data cycle for master; output nubus_master; input nubus_driver & internal
|
||||
|
||||
// ==========================================================================
|
||||
// Drive NuBus address-data line
|
||||
// ==========================================================================
|
||||
|
||||
// Select nubus data signals
|
||||
wire [31:0] nub_ad = mem_rdata;
|
||||
// Should we be putting the address (instead of data) on the bus [see also nub_adoe]
|
||||
// yes during address cycle, or if we're reading (not writing) data
|
||||
// actually during write the CPU puts data in cpu_ad so also when writing
|
||||
// nub_adoe takes care of the enablement
|
||||
wire cpu_adsel = ~mst_adrcyn | ~mst_dtacyn;// & ~cpu_tm1n;
|
||||
// Select nubus address or data signals
|
||||
wire [31:0] nub_ad = cpu_adsel ? cpu_ad : mem_rdata;
|
||||
|
||||
// When 1 - drive the NuBus AD lines
|
||||
wire nub_adoe = slv_slave & slv_tm1n
|
||||
/*SLAVE read of card*/
|
||||
// Tri-state control for the A/D line
|
||||
// nub_adoe is the output enable, when 0 A/D lines are high-impedance
|
||||
// Slave: only drive the A/D lines to return data on a read (slave cycle with tm1n high)
|
||||
// Master: drives during (a) address cycle
|
||||
// (b) data cycle when writing
|
||||
wire nub_adoe = slv_slave & slv_tm1n /* SLAVE read of card */
|
||||
| cpu_valid & ~mst_adrcyn /* MASTER address cycle*/
|
||||
| ~mst_ownern & ~mst_dtacyn & ~cpu_tm1n /* MASTER data cycle, when writing*/
|
||||
;
|
||||
|
||||
wire rqst_n, rqst_oe_n;
|
||||
|
||||
assign rqst_n = 'b1; // no master yet
|
||||
assign nub_rqstn = ~rqst_oe_n ? rqst_n : 'bZ;
|
||||
|
||||
|
||||
// Output to nubus the
|
||||
assign nub_adn = nub_adoe ? ~nub_ad : 'bZ;
|
||||
|
||||
assign mem_valid = slv_myslotcy;
|
||||
|
||||
/* for direction */
|
||||
assign NUBUS_AD_DIR = ~nub_adoe;
|
||||
//assign nubus_master_dir = grant | ~mst_adrcyn | ~mst_arbdn | ~mst_ownern | ~mst_dtacyn;
|
||||
assign nubus_master_dir = ~mst_ownern;
|
||||
|
||||
// ==========================================================================
|
||||
// Parity checking
|
||||
// ==========================================================================
|
||||
|
||||
//wire parity = ~^nub_adn;
|
||||
//wire nub_noparity = NON_ECC_PARITY & ~nub_adoe & ~nub_spvn & nub_spn == parity;
|
||||
|
||||
//assign nub_spn = NON_ECC_PARITY & nub_adoe ? parity : 'bZ;
|
||||
//assign nub_spvn = NON_ECC_PARITY & nub_adoe ? 0 : 'bZ;
|
||||
/* for slave access, enable the access during slv_myslotcy*/
|
||||
assign mem_valid = slv_myslotcy;
|
||||
|
||||
// ==========================================================================
|
||||
// Slave FSM
|
||||
|
@ -133,10 +184,10 @@ module nubus
|
|||
.SLOTS_ADDRESS (SLOTS_ADDRESS),
|
||||
.SUPERSLOTS_ADDRESS(SUPERSLOTS_ADDRESS),
|
||||
.SIMPLE_MAP(0),
|
||||
// UNUSED in NuBusFPGA
|
||||
.LOCAL_SPACE_EXPOSED_TO_NUBUS(LOCAL_SPACE_EXPOSED_TO_NUBUS),
|
||||
.LOCAL_SPACE_START(LOCAL_SPACE_START),
|
||||
.LOCAL_SPACE_END(LOCAL_SPACE_END)
|
||||
|
||||
)
|
||||
USlave
|
||||
(
|
||||
|
@ -149,7 +200,7 @@ module nubus
|
|||
.nub_tm1n(nub_tm1n), // Transition mode 1 (Read/Write)
|
||||
.nub_tm0n(nub_tm0n),
|
||||
.mem_ready(mem_ready),
|
||||
.mst_timeout(0),
|
||||
.mst_timeout(mst_timeout),
|
||||
|
||||
.slv_slave_o(slv_slave), // Slave mode
|
||||
.slv_tm1n_o(slv_tm1n), // Latched transition mode 1 (Read/Write)
|
||||
|
@ -161,6 +212,35 @@ module nubus
|
|||
.slv_local_o(mem_local), // Local area
|
||||
.slv_myslotcy_o(slv_myslotcy) // Any slot
|
||||
);
|
||||
|
||||
// ==========================================================================
|
||||
// Master FSM
|
||||
// ==========================================================================
|
||||
|
||||
nubus_master
|
||||
#(
|
||||
.WDT_W(WDT_W)
|
||||
)
|
||||
UMaster
|
||||
(
|
||||
.nub_clkn(nub_clkn), // Clock
|
||||
.nub_resetn(nub_resetn), // Reset
|
||||
.nub_rqstn(nub_rqstn), // Bus request
|
||||
.nub_startn(nub_startn), // Start transfer
|
||||
.nub_ackn(nub_ackn), // End of transfer
|
||||
.arb_grant(grant), // Grant access
|
||||
.cpu_lock(cpu_lock), // Address line
|
||||
.cpu_masterd(cpu_valid), // Master mode (delayed) // FIXME: ignoring cpu_masterd which is always 0 (see below)
|
||||
|
||||
.mst_lockedn_o(mst_lockedn), // Locked or not tranfer
|
||||
.mst_arbdn_o(mst_arbdn),
|
||||
.mst_busyn_o(mst_busyn),
|
||||
.mst_ownern_o(mst_ownern), // Address or data transfer
|
||||
.mst_dtacyn_o(mst_dtacyn), // Data strobe
|
||||
.mst_adrcyn_o(mst_adrcyn), // Address strobe
|
||||
.mst_arbcyn_o(mst_arbcyn), // Arbiter enabled
|
||||
.mst_timeout_o(mst_timeout)
|
||||
);
|
||||
|
||||
// ==========================================================================
|
||||
// Driver Nubus
|
||||
|
@ -170,26 +250,49 @@ module nubus
|
|||
|
||||
nubus_driver UNDriver
|
||||
(
|
||||
.slv_ackcyn(slv_ackcyn), // Achnowlege
|
||||
.mst_arbcyn(1), // Arbiter enabled
|
||||
.mst_adrcyn(1), // Address strobe
|
||||
.mst_dtacyn(1), // Data strobe
|
||||
.mst_ownern(1), // Master is owner of the bus
|
||||
.mst_lockedn(1), // Locked or not transfer
|
||||
.mst_tm1n(1), // Address ines
|
||||
.mst_tm0n(1), // Address ines
|
||||
.mst_timeout(0),
|
||||
.slv_ackcyn(slv_ackcyn), // Acknowlege
|
||||
.mst_arbcyn(mst_arbcyn), // Arbiter enabled
|
||||
.mst_adrcyn(mst_adrcyn), // Address strobe
|
||||
.mst_dtacyn(mst_dtacyn), // Data strobe
|
||||
.mst_ownern(mst_ownern), // Master is owner of the bus
|
||||
.mst_lockedn(mst_lockedn), // Locked or not transfer
|
||||
.mst_tm1n(cpu_tm1n), // Address lines
|
||||
.mst_tm0n(cpu_tm0n), // Address lines
|
||||
.mst_timeout(mst_timeout),
|
||||
.mis_errorn(TMN_COMPLETE),
|
||||
.nub_tm0n_o(nub_tm0n), // Transfer mode
|
||||
.nub_tm1n_o(nub_tm1n), // Transfer mode
|
||||
.nub_ackn_o(nub_ackn), // Achnowlege
|
||||
.nub_startn_o(nub_startn), // Transfer start
|
||||
.nub_rqstn_o(nub_rqstn), // Bus request
|
||||
.nub_rqstoen_o(rqst_oe_n), // Bus request enable
|
||||
.nub_rqstoen_o(fpga_to_cpld_signal), // Bus request enable
|
||||
.drv_tmoen_o(drv_tmoen), // Transfer mode enable
|
||||
.drv_mstdn_o(drv_mstdn) // Guess: Slave sends /ACK. Master responds with /MSTDN, which allows slave to clear /ACK and listen for next transaction.
|
||||
);
|
||||
|
||||
// ==========================================================================
|
||||
// CPU Interface
|
||||
// ==========================================================================
|
||||
|
||||
assign cpu_rdata = ~nub_adn;
|
||||
assign cpu_ready = ~nub_ackn & nub_startn;
|
||||
|
||||
nubus_cpubus UCPUBus
|
||||
(
|
||||
.nub_clkn(nub_clkn),
|
||||
.nub_resetn(nub_resetn),
|
||||
.mst_adrcyn(mst_adrcyn),
|
||||
.cpu_valid(cpu_valid),
|
||||
.cpu_write(cpu_write),
|
||||
.cpu_addr(cpu_addr),
|
||||
.cpu_wdata(cpu_wdata),
|
||||
.cpu_ad_o(cpu_ad),
|
||||
.cpu_tm1n_o(cpu_tm1n),
|
||||
.cpu_tm0n_o(cpu_tm0n),
|
||||
.cpu_error_o(cpu_errors),
|
||||
.cpu_masterd_o(cpu_masterd) // FIXME, set to 0 in Xibus nubus_cpubus
|
||||
);
|
||||
|
||||
// ==========================================================================
|
||||
// Memory Interface
|
||||
// ==========================================================================
|
||||
|
|
|
@ -6,16 +6,18 @@
|
|||
* generation of lower ARB<3:0> bits.
|
||||
* The GRANT signal must be timed externally to determine proper
|
||||
* NuBus constraints.
|
||||
* This version uses a new technique to minimize skews .
|
||||
* This version uses a new technique to minimize skews.
|
||||
*
|
||||
* Modified from the XiBus version to support external drivers in the NuBusFPGA
|
||||
*/
|
||||
|
||||
module nubus_arbiter
|
||||
(
|
||||
input [3:0] idn, // ID of this card
|
||||
input [3:0] arbn, // NuBus arbiter's lines (input)
|
||||
output [3:0] arbon, // NuBus arbiter's lines (control)
|
||||
input arbcyn, // enable arbitter
|
||||
output grant // Grant access
|
||||
input [3:0] idn, // ID of this card
|
||||
input [3:0] arbn, // NuBus arbiter's lines (input)
|
||||
output [3:0] arbon, // NuBus arbiter's lines (control)
|
||||
input arbcyn, // enable arbitter
|
||||
output grant // Grant access
|
||||
);
|
||||
|
||||
wire arb2oen, arb1oen, arb0oen;
|
||||
|
|
|
@ -55,7 +55,7 @@ NET "reset_n_3v3" LOC = "S:PIN48";
|
|||
NET "nubus_master_dir" LOC = "S:PIN49";
|
||||
NET "fpga_to_cpld_signal_2" LOC = "S:PIN50";
|
||||
NET "tmoen" LOC = "S:PIN51";
|
||||
NET "arb" LOC = "S:PIN52";
|
||||
NET "arbcy_n" LOC = "S:PIN52";
|
||||
// PIN53: JTAG_TDO
|
||||
// PIN24: GND
|
||||
// PIN55: VCCIO
|
||||
|
|
|
@ -13,7 +13,7 @@ module nubus_cpld
|
|||
|
||||
// Spares
|
||||
input fpga_to_cpld_clk, // unused (extra line from FPGA to CPLD, pin is a clk input)
|
||||
inout fpga_to_cpld_signal, // unused (extra line from FPGA to CPLD)
|
||||
input fpga_to_cpld_signal, // unused (extra line from FPGA to CPLD)
|
||||
inout fpga_to_cpld_signal_2, // unused (extra line from FPGA to CPLD)
|
||||
|
||||
// NuBus (output to FPGA)
|
||||
|
@ -23,7 +23,7 @@ module nubus_cpld
|
|||
output clk2x_n_3v3, // nubus90 clk to FPGA
|
||||
|
||||
// NuBus Arbiter
|
||||
input arb, // enable arbitter
|
||||
input arbcy_n, // enable arbitter
|
||||
input [3:0] arb_n_5v, // NuBus arbiter's lines
|
||||
output [3:0] arb_o_n, // NuBus arbiter's control lines
|
||||
output grant, // Grant access
|
||||
|
@ -56,12 +56,12 @@ module nubus_cpld
|
|||
|
||||
// Master Request (OC)
|
||||
input rqst_n_5v, // rqst from NuBus; needs monitoring before driving
|
||||
inout rqst_n_3v3, // rqst from/to FPGA; needs monitoring before driving?; needed? or is arb enough?
|
||||
inout rqst_n_3v3, // rqst from/to FPGA
|
||||
output rqst_o_n // rqst to NuBus
|
||||
);
|
||||
|
||||
// placeholder to make pretend we use the signals
|
||||
assign fpga_to_cpld_signal_2 = fpga_to_cpld_signal ^ fpga_to_cpld_clk;
|
||||
assign fpga_to_cpld_signal_2 = fpga_to_cpld_clk;
|
||||
// placeholders
|
||||
assign clk2x_n_3v3 = clk2x_n_5v;
|
||||
assign tm2_n_3v3 = tm2_n_5v;
|
||||
|
@ -80,28 +80,28 @@ module nubus_cpld
|
|||
assign start_n_3v3 = nubus_oe ? 'bZ : (~nubus_master_dir ? start_n_5v : 'bZ); // master in
|
||||
|
||||
// rqst_o_n is always driven (the 74lvt125 wired as open collector will convert 1 to Z) and is active low
|
||||
assign rqst_o_n = nubus_oe ? 1 : ( nubus_master_dir ? rqst_n_3v3 : 1); // master out
|
||||
assign rqst_n_3v3 = nubus_oe ? 'bZ : (~nubus_master_dir ? rqst_n_5v : 'bZ); // master in
|
||||
assign rqst_o_n = nubus_oe ? 1 : (~fpga_to_cpld_signal ? rqst_n_3v3 : 1); // master out
|
||||
assign rqst_n_3v3 = nubus_oe ? 'bZ : ( fpga_to_cpld_signal ? rqst_n_5v : 'bZ); // master in
|
||||
|
||||
//assign ack_o_5v = nubus_oe ? 'bZ : ((nubus_master_dir ^ ~tmoen) ? ack_n_3v3 : 'bZ); // slave out/in
|
||||
assign ack_o_n = nubus_oe ? 1 : ((nubus_master_dir ^ ~tmoen) ? ack_n_3v3 : 1); // slave out/in
|
||||
assign ack_oe_n = nubus_oe ? 1 : ((nubus_master_dir ^ ~tmoen) ? 0 : 1); // slave out/in
|
||||
assign ack_n_3v3 = nubus_oe ? 'bZ : ((nubus_master_dir ^ tmoen) ? ack_n_5v : 'bZ); // slave out/in
|
||||
assign ack_o_n = nubus_oe ? 1 : (( ~tmoen) ? ack_n_3v3 : 1); // slave out/in
|
||||
assign ack_oe_n = nubus_oe ? 1 : (( ~tmoen) ? 0 : 1); // slave out/in
|
||||
assign ack_n_3v3 = nubus_oe ? 'bZ : (( tmoen) ? ack_n_5v : 'bZ); // slave out/in
|
||||
|
||||
//assign tm0_n_5v = nubus_oe ? 'bZ : ((nubus_master_dir ^ ~tmoen) ? tm0_n_3v3 : 'bZ); // slave out/in
|
||||
//assign tm1_n_5v = nubus_oe ? 'bZ : ((nubus_master_dir ^ ~tmoen) ? tm1_n_3v3 : 'bZ); // slave out/in
|
||||
assign tm0_o_n = nubus_oe ? 1 : ((nubus_master_dir ^ ~tmoen) ? tm0_n_3v3 : 1); // slave out/in
|
||||
assign tm1_o_n = nubus_oe ? 1 : ((nubus_master_dir ^ ~tmoen) ? tm1_n_3v3 : 1); // slave out/in
|
||||
assign tmx_oe_n = nubus_oe ? 1 : ((nubus_master_dir ^ ~tmoen) ? 0 : 1); // slave out/in
|
||||
assign tm0_n_3v3 = nubus_oe ? 'bZ : ((nubus_master_dir ^ tmoen) ? tm0_n_5v : 'bZ); // slave in/out
|
||||
assign tm1_n_3v3 = nubus_oe ? 'bZ : ((nubus_master_dir ^ tmoen) ? tm1_n_5v : 'bZ); // slave in/out
|
||||
assign tm0_o_n = nubus_oe ? 1 : (( ~tmoen) ? tm0_n_3v3 : 1); // slave out/in
|
||||
assign tm1_o_n = nubus_oe ? 1 : (( ~tmoen) ? tm1_n_3v3 : 1); // slave out/in
|
||||
assign tmx_oe_n = nubus_oe ? 1 : (( ~tmoen) ? 0 : 1); // slave out/in
|
||||
assign tm0_n_3v3 = nubus_oe ? 'bZ : (( tmoen) ? tm0_n_5v : 'bZ); // slave in/out
|
||||
assign tm1_n_3v3 = nubus_oe ? 'bZ : (( tmoen) ? tm1_n_5v : 'bZ); // slave in/out
|
||||
|
||||
nubus_arbiter UArbiter
|
||||
(
|
||||
.idn(id_n_5v),
|
||||
.arbn(arb_n_5v),
|
||||
.arbon(arb_o_n),
|
||||
.arbcyn(arb),
|
||||
.arbcyn(arbcy_n),
|
||||
.grant(grant)
|
||||
);
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
from migen import *
|
||||
from migen.genlib.fifo import *
|
||||
|
||||
import litex
|
||||
from litex.soc.interconnect import wishbone
|
||||
|
||||
from migen.genlib.cdc import BusSynchronizer
|
||||
|
||||
class Wishbone2NuBus(Module):
|
||||
def __init__(self, nubus, wb):
|
||||
|
||||
# cpu
|
||||
# input cpu_valid,
|
||||
# input [31:0] cpu_addr,
|
||||
# input [31:0] cpu_wdata,
|
||||
# input [ 3:0] cpu_write,
|
||||
# output cpu_ready,
|
||||
# output [31:0] cpu_rdata,
|
||||
#input cpu_lock,
|
||||
#input cpu_eclr,
|
||||
#output [3:0] cpu_errors,
|
||||
|
||||
self.comb += nubus.cpu_valid.eq(wb.cyc & wb.stb)
|
||||
self.comb += nubus.cpu_addr.eq(Cat(Signal(2, reset = 0), wb.adr))
|
||||
self.comb += nubus.cpu_wdata.eq(wb.dat_w)
|
||||
self.comb += If(wb.we == 1,
|
||||
nubus.cpu_write.eq(wb.sel)).Else(
|
||||
nubus.cpu_write.eq(0))
|
||||
self.comb += wb.ack.eq(nubus.cpu_ready)
|
||||
self.comb += wb.dat_r.eq(nubus.cpu_rdata)
|
||||
self.comb += nubus.cpu_lock.eq(0) # FIXME: TODO: ???
|
||||
self.comb += nubus.cpu_eclr.eq(0) # FIXME: TODO: ???
|
|
@ -0,0 +1,130 @@
|
|||
set_input_delay -clock nubus_clk -min 2.404 [get_ports {rqst_3v3_n}]
|
||||
set_input_delay -clock nubus_clk -max 52.456 [get_ports {rqst_3v3_n}]
|
||||
set_output_delay -clock nubus_clk -min -6.155 [get_ports {rqst_3v3_n}]
|
||||
set_output_delay -clock nubus_clk -max 53.627 [get_ports {rqst_3v3_n}]
|
||||
set_input_delay -clock nubus_clk -min 2.457 [get_ports {start_3v3_n}]
|
||||
set_input_delay -clock nubus_clk -max 52.526 [get_ports {start_3v3_n}]
|
||||
set_output_delay -clock nubus_clk -min -6.102 [get_ports {start_3v3_n}]
|
||||
set_output_delay -clock nubus_clk -max 53.697 [get_ports {start_3v3_n}]
|
||||
set_input_delay -clock nubus_clk -min 2.525 [get_ports {ack_3v3_n}]
|
||||
set_input_delay -clock nubus_clk -max 52.617 [get_ports {ack_3v3_n}]
|
||||
set_output_delay -clock nubus_clk -min -6.034 [get_ports {ack_3v3_n}]
|
||||
set_output_delay -clock nubus_clk -max 53.788 [get_ports {ack_3v3_n}]
|
||||
set_input_delay -clock nubus_clk -min 2.285 [get_ports {ad_3v3_n[31]}]
|
||||
set_input_delay -clock nubus_clk -max 52.296 [get_ports {ad_3v3_n[31]}]
|
||||
set_output_delay -clock nubus_clk -min -6.274 [get_ports {ad_3v3_n[31]}]
|
||||
set_output_delay -clock nubus_clk -max 53.468 [get_ports {ad_3v3_n[31]}]
|
||||
set_input_delay -clock nubus_clk -min 2.274 [get_ports {ad_3v3_n[30]}]
|
||||
set_input_delay -clock nubus_clk -max 52.282 [get_ports {ad_3v3_n[30]}]
|
||||
set_output_delay -clock nubus_clk -min -6.285 [get_ports {ad_3v3_n[30]}]
|
||||
set_output_delay -clock nubus_clk -max 53.453 [get_ports {ad_3v3_n[30]}]
|
||||
set_input_delay -clock nubus_clk -min 2.261 [get_ports {ad_3v3_n[29]}]
|
||||
set_input_delay -clock nubus_clk -max 52.265 [get_ports {ad_3v3_n[29]}]
|
||||
set_output_delay -clock nubus_clk -min -6.298 [get_ports {ad_3v3_n[29]}]
|
||||
set_output_delay -clock nubus_clk -max 53.436 [get_ports {ad_3v3_n[29]}]
|
||||
set_input_delay -clock nubus_clk -min 2.259 [get_ports {ad_3v3_n[28]}]
|
||||
set_input_delay -clock nubus_clk -max 52.262 [get_ports {ad_3v3_n[28]}]
|
||||
set_output_delay -clock nubus_clk -min -6.300 [get_ports {ad_3v3_n[28]}]
|
||||
set_output_delay -clock nubus_clk -max 53.433 [get_ports {ad_3v3_n[28]}]
|
||||
set_input_delay -clock nubus_clk -min 2.257 [get_ports {ad_3v3_n[27]}]
|
||||
set_input_delay -clock nubus_clk -max 52.260 [get_ports {ad_3v3_n[27]}]
|
||||
set_output_delay -clock nubus_clk -min -6.302 [get_ports {ad_3v3_n[27]}]
|
||||
set_output_delay -clock nubus_clk -max 53.431 [get_ports {ad_3v3_n[27]}]
|
||||
set_input_delay -clock nubus_clk -min 2.239 [get_ports {ad_3v3_n[26]}]
|
||||
set_input_delay -clock nubus_clk -max 52.236 [get_ports {ad_3v3_n[26]}]
|
||||
set_output_delay -clock nubus_clk -min -6.320 [get_ports {ad_3v3_n[26]}]
|
||||
set_output_delay -clock nubus_clk -max 53.407 [get_ports {ad_3v3_n[26]}]
|
||||
set_input_delay -clock nubus_clk -min 2.244 [get_ports {ad_3v3_n[25]}]
|
||||
set_input_delay -clock nubus_clk -max 52.242 [get_ports {ad_3v3_n[25]}]
|
||||
set_output_delay -clock nubus_clk -min -6.315 [get_ports {ad_3v3_n[25]}]
|
||||
set_output_delay -clock nubus_clk -max 53.414 [get_ports {ad_3v3_n[25]}]
|
||||
set_input_delay -clock nubus_clk -min 2.246 [get_ports {ad_3v3_n[23]}]
|
||||
set_input_delay -clock nubus_clk -max 52.244 [get_ports {ad_3v3_n[23]}]
|
||||
set_output_delay -clock nubus_clk -min -6.313 [get_ports {ad_3v3_n[23]}]
|
||||
set_output_delay -clock nubus_clk -max 53.416 [get_ports {ad_3v3_n[23]}]
|
||||
set_input_delay -clock nubus_clk -min 2.291 [get_ports {ad_3v3_n[24]}]
|
||||
set_input_delay -clock nubus_clk -max 52.305 [get_ports {ad_3v3_n[24]}]
|
||||
set_output_delay -clock nubus_clk -min -6.268 [get_ports {ad_3v3_n[24]}]
|
||||
set_output_delay -clock nubus_clk -max 53.476 [get_ports {ad_3v3_n[24]}]
|
||||
set_input_delay -clock nubus_clk -min 2.239 [get_ports {ad_3v3_n[21]}]
|
||||
set_input_delay -clock nubus_clk -max 52.235 [get_ports {ad_3v3_n[21]}]
|
||||
set_output_delay -clock nubus_clk -min -6.320 [get_ports {ad_3v3_n[21]}]
|
||||
set_output_delay -clock nubus_clk -max 53.406 [get_ports {ad_3v3_n[21]}]
|
||||
set_input_delay -clock nubus_clk -min 2.218 [get_ports {ad_3v3_n[22]}]
|
||||
set_input_delay -clock nubus_clk -max 52.207 [get_ports {ad_3v3_n[22]}]
|
||||
set_output_delay -clock nubus_clk -min -6.341 [get_ports {ad_3v3_n[22]}]
|
||||
set_output_delay -clock nubus_clk -max 53.378 [get_ports {ad_3v3_n[22]}]
|
||||
set_input_delay -clock nubus_clk -min 2.211 [get_ports {ad_3v3_n[18]}]
|
||||
set_input_delay -clock nubus_clk -max 52.198 [get_ports {ad_3v3_n[18]}]
|
||||
set_output_delay -clock nubus_clk -min -6.348 [get_ports {ad_3v3_n[18]}]
|
||||
set_output_delay -clock nubus_clk -max 53.370 [get_ports {ad_3v3_n[18]}]
|
||||
set_input_delay -clock nubus_clk -min 2.202 [get_ports {ad_3v3_n[20]}]
|
||||
set_input_delay -clock nubus_clk -max 52.185 [get_ports {ad_3v3_n[20]}]
|
||||
set_output_delay -clock nubus_clk -min -6.357 [get_ports {ad_3v3_n[20]}]
|
||||
set_output_delay -clock nubus_clk -max 53.357 [get_ports {ad_3v3_n[20]}]
|
||||
set_input_delay -clock nubus_clk -min 2.251 [get_ports {ad_3v3_n[16]}]
|
||||
set_input_delay -clock nubus_clk -max 52.252 [get_ports {ad_3v3_n[16]}]
|
||||
set_output_delay -clock nubus_clk -min -6.308 [get_ports {ad_3v3_n[16]}]
|
||||
set_output_delay -clock nubus_clk -max 53.423 [get_ports {ad_3v3_n[16]}]
|
||||
set_input_delay -clock nubus_clk -min 2.205 [get_ports {ad_3v3_n[19]}]
|
||||
set_input_delay -clock nubus_clk -max 52.190 [get_ports {ad_3v3_n[19]}]
|
||||
set_output_delay -clock nubus_clk -min -6.354 [get_ports {ad_3v3_n[19]}]
|
||||
set_output_delay -clock nubus_clk -max 53.361 [get_ports {ad_3v3_n[19]}]
|
||||
set_input_delay -clock nubus_clk -min 2.147 [get_ports {ad_3v3_n[14]}]
|
||||
set_input_delay -clock nubus_clk -max 52.113 [get_ports {ad_3v3_n[14]}]
|
||||
set_output_delay -clock nubus_clk -min -6.412 [get_ports {ad_3v3_n[14]}]
|
||||
set_output_delay -clock nubus_clk -max 53.284 [get_ports {ad_3v3_n[14]}]
|
||||
set_input_delay -clock nubus_clk -min 2.178 [get_ports {ad_3v3_n[17]}]
|
||||
set_input_delay -clock nubus_clk -max 52.154 [get_ports {ad_3v3_n[17]}]
|
||||
set_output_delay -clock nubus_clk -min -6.381 [get_ports {ad_3v3_n[17]}]
|
||||
set_output_delay -clock nubus_clk -max 53.326 [get_ports {ad_3v3_n[17]}]
|
||||
set_input_delay -clock nubus_clk -min 2.148 [get_ports {ad_3v3_n[15]}]
|
||||
set_input_delay -clock nubus_clk -max 52.113 [get_ports {ad_3v3_n[15]}]
|
||||
set_output_delay -clock nubus_clk -min -6.411 [get_ports {ad_3v3_n[15]}]
|
||||
set_output_delay -clock nubus_clk -max 53.285 [get_ports {ad_3v3_n[15]}]
|
||||
set_input_delay -clock nubus_clk -min 2.145 [get_ports {ad_3v3_n[12]}]
|
||||
set_input_delay -clock nubus_clk -max 52.110 [get_ports {ad_3v3_n[12]}]
|
||||
set_output_delay -clock nubus_clk -min -6.414 [get_ports {ad_3v3_n[12]}]
|
||||
set_output_delay -clock nubus_clk -max 53.281 [get_ports {ad_3v3_n[12]}]
|
||||
set_input_delay -clock nubus_clk -min 2.134 [get_ports {ad_3v3_n[13]}]
|
||||
set_input_delay -clock nubus_clk -max 52.095 [get_ports {ad_3v3_n[13]}]
|
||||
set_output_delay -clock nubus_clk -min -6.425 [get_ports {ad_3v3_n[13]}]
|
||||
set_output_delay -clock nubus_clk -max 53.267 [get_ports {ad_3v3_n[13]}]
|
||||
set_input_delay -clock nubus_clk -min 2.139 [get_ports {ad_3v3_n[10]}]
|
||||
set_input_delay -clock nubus_clk -max 52.103 [get_ports {ad_3v3_n[10]}]
|
||||
set_output_delay -clock nubus_clk -min -6.420 [get_ports {ad_3v3_n[10]}]
|
||||
set_output_delay -clock nubus_clk -max 53.274 [get_ports {ad_3v3_n[10]}]
|
||||
set_input_delay -clock nubus_clk -min 2.120 [get_ports {ad_3v3_n[11]}]
|
||||
set_input_delay -clock nubus_clk -max 52.077 [get_ports {ad_3v3_n[11]}]
|
||||
set_output_delay -clock nubus_clk -min -6.439 [get_ports {ad_3v3_n[11]}]
|
||||
set_output_delay -clock nubus_clk -max 53.248 [get_ports {ad_3v3_n[11]}]
|
||||
set_input_delay -clock nubus_clk -min 2.163 [get_ports {ad_3v3_n[8]}]
|
||||
set_input_delay -clock nubus_clk -max 52.134 [get_ports {ad_3v3_n[8]}]
|
||||
set_output_delay -clock nubus_clk -min -6.396 [get_ports {ad_3v3_n[8]}]
|
||||
set_output_delay -clock nubus_clk -max 53.306 [get_ports {ad_3v3_n[8]}]
|
||||
set_input_delay -clock nubus_clk -min 2.146 [get_ports {ad_3v3_n[6]}]
|
||||
set_input_delay -clock nubus_clk -max 52.111 [get_ports {ad_3v3_n[6]}]
|
||||
set_input_delay -clock nubus_clk -min 2.128 [get_ports {ad_3v3_n[9]}]
|
||||
set_input_delay -clock nubus_clk -max 52.087 [get_ports {ad_3v3_n[9]}]
|
||||
set_input_delay -clock nubus_clk -min 2.166 [get_ports {ad_3v3_n[4]}]
|
||||
set_input_delay -clock nubus_clk -max 52.138 [get_ports {ad_3v3_n[4]}]
|
||||
set_input_delay -clock nubus_clk -min 2.142 [get_ports {ad_3v3_n[7]}]
|
||||
set_input_delay -clock nubus_clk -max 52.106 [get_ports {ad_3v3_n[7]}]
|
||||
set_input_delay -clock nubus_clk -min 2.189 [get_ports {ad_3v3_n[5]}]
|
||||
set_input_delay -clock nubus_clk -max 52.169 [get_ports {ad_3v3_n[5]}]
|
||||
set_output_delay -clock nubus_clk -min -6.370 [get_ports {ad_3v3_n[5]}]
|
||||
set_output_delay -clock nubus_clk -max 53.340 [get_ports {ad_3v3_n[5]}]
|
||||
set_input_delay -clock nubus_clk -min 2.614 [get_ports {tm2_3v3_n}]
|
||||
set_input_delay -clock nubus_clk -max 52.736 [get_ports {tm2_3v3_n}]
|
||||
set_input_delay -clock nubus_clk -min 2.168 [get_ports {ad_3v3_n[3]}]
|
||||
set_input_delay -clock nubus_clk -max 52.141 [get_ports {ad_3v3_n[3]}]
|
||||
set_input_delay -clock nubus_clk -min 2.136 [get_ports {ad_3v3_n[2]}]
|
||||
set_input_delay -clock nubus_clk -max 52.097 [get_ports {ad_3v3_n[2]}]
|
||||
set_input_delay -clock nubus_clk -min 2.250 [get_ports {ad_3v3_n[0]}]
|
||||
set_input_delay -clock nubus_clk -max 52.250 [get_ports {ad_3v3_n[0]}]
|
||||
set_input_delay -clock nubus_clk -min 2.264 [get_ports {ad_3v3_n[1]}]
|
||||
set_input_delay -clock nubus_clk -max 52.269 [get_ports {ad_3v3_n[1]}]
|
||||
set_input_delay -clock nubus_clk -min 2.508 [get_ports {tm1_3v3_n}]
|
||||
set_input_delay -clock nubus_clk -max 52.594 [get_ports {tm1_3v3_n}]
|
||||
set_input_delay -clock nubus_clk -min 2.498 [get_ports {tm0_3v3_n}]
|
||||
set_input_delay -clock nubus_clk -max 52.581 [get_ports {tm0_3v3_n}]
|
|
@ -0,0 +1,55 @@
|
|||
from migen import *
|
||||
from migen.genlib.fifo import *
|
||||
|
||||
import litex
|
||||
from litex.soc.interconnect import wishbone
|
||||
|
||||
class PingMaster(Module):
|
||||
def __init__(self):
|
||||
self.bus_slv = bus_slv = wishbone.Interface()
|
||||
self.bus_mst = bus_mst = wishbone.Interface()
|
||||
|
||||
valu_reg = Signal(32)
|
||||
addr_reg = Signal(32)
|
||||
writ_del = Signal(6)
|
||||
|
||||
self.sync += If(writ_del != 0,
|
||||
writ_del.eq(writ_del - 1))
|
||||
|
||||
self.submodules.wishbone_fsm = wishbone_fsm = FSM(reset_state = "Reset")
|
||||
wishbone_fsm.act("Reset",
|
||||
NextValue(bus_slv.ack, 0),
|
||||
NextState("Idle"))
|
||||
wishbone_fsm.act("Idle",
|
||||
If(bus_slv.cyc & bus_slv.stb & bus_slv.we & ~bus_slv.ack, #write
|
||||
# FIXME: should check for prefix?
|
||||
Case(bus_slv.adr[0:1], {
|
||||
0x0: [ NextValue(valu_reg, bus_slv.dat_w[0:32]), ],
|
||||
0x1: [ NextValue(addr_reg, bus_slv.dat_w[0:32]),
|
||||
NextValue(writ_del, 63), ],
|
||||
}),
|
||||
NextValue(bus_slv.ack, 1),
|
||||
).Elif(bus_slv.cyc & bus_slv.stb & ~bus_slv.we & ~bus_slv.ack, #read
|
||||
Case(bus_slv.adr[0:1], {
|
||||
0x0: [ NextValue(bus_slv.dat_r, valu_reg), ],
|
||||
0x1: [ NextValue(bus_slv.dat_r, addr_reg), ],
|
||||
}),
|
||||
NextValue(bus_slv.ack, 1),
|
||||
).Else(
|
||||
NextValue(bus_slv.ack, 0),
|
||||
),
|
||||
If(writ_del == 1,
|
||||
NextState("Write"),),
|
||||
)
|
||||
wishbone_fsm.act("Write",
|
||||
bus_mst.cyc.eq(1),
|
||||
bus_mst.stb.eq(1),
|
||||
bus_mst.we.eq(1),
|
||||
bus_mst.dat_w.eq(valu_reg),
|
||||
bus_mst.adr.eq(addr_reg[2:32]),
|
||||
bus_mst.sel.eq(0xf),
|
||||
If(bus_mst.ack,
|
||||
NextState("Idle")),
|
||||
)
|
||||
|
||||
|
|
@ -7,7 +7,6 @@ from litex.soc.interconnect import wishbone
|
|||
from migen.genlib.cdc import BusSynchronizer
|
||||
|
||||
class NuBus2Wishbone(Module):
|
||||
"""Wishbone Clock Domain Crossing [Master]"""
|
||||
def __init__(self, nubus, wb):
|
||||
|
||||
# memory
|
||||
|
@ -20,15 +19,30 @@ class NuBus2Wishbone(Module):
|
|||
#nubus.mem_error
|
||||
#nubus.mem_tryagain
|
||||
|
||||
#nubus_mem_addr_revb = Signal(32)
|
||||
#self.comb += nubus_mem_addr_revb.eq(Cat(nubus.mem_addr[24:32], nubus.mem_addr[16:24], nubus.mem_addr[8:16], nubus.mem_addr[0:8]))
|
||||
|
||||
self.comb += wb.cyc.eq(nubus.mem_valid)
|
||||
self.comb += wb.stb.eq(nubus.mem_valid)
|
||||
self.comb += If(nubus.mem_write == 0,
|
||||
wb.sel.eq(0xF)).Else(
|
||||
wb.sel.eq(nubus.mem_write))
|
||||
self.comb += wb.we.eq(nubus.mem_write != 0)
|
||||
self.comb += wb.adr.eq(Cat(nubus.mem_addr[2:24], Signal(8, reset = 0))) # 24 bits, a.k.a 22 bits of words
|
||||
self.comb += wb.dat_w.eq(nubus.mem_wdata)
|
||||
self.comb += nubus.mem_rdata.eq(wb.dat_r)
|
||||
|
||||
self.comb += [
|
||||
If(~nubus.mem_addr[23], # first 8 MiB of slot space: remap to last 8 Mib of SDRAM
|
||||
wb.adr.eq(Cat(nubus.mem_addr[2:23], Signal(1, reset=1), Signal(8, reset = 0x8f))), # 0x8f8...
|
||||
).Else( # second 8 MiB: direct access
|
||||
wb.adr.eq(Cat(nubus.mem_addr[2:24], Signal(8, reset = 0)))), # 24 bits, a.k.a 22 bits of words
|
||||
]
|
||||
|
||||
self.comb += [
|
||||
wb.dat_w.eq(nubus.mem_wdata),
|
||||
nubus.mem_rdata.eq(wb.dat_r),
|
||||
#wb.dat_w.eq(Cat(nubus.mem_wdata[24:32], nubus.mem_wdata[16:24], nubus.mem_wdata[8:16], nubus.mem_wdata[0:8])),
|
||||
#nubus.mem_rdata.eq(Cat(wb.dat_r[24:32], wb.dat_r[16:24], wb.dat_r[8:16], wb.dat_r[0:8])),
|
||||
]
|
||||
|
||||
self.comb += nubus.mem_ready.eq(wb.ack)
|
||||
self.comb += nubus.mem_error.eq(0)
|
||||
self.comb += nubus.mem_tryagain.eq(0)
|
||||
self.comb += nubus.mem_error.eq(0) # FIXME: TODO: ???
|
||||
self.comb += nubus.mem_tryagain.eq(0) # FIXME: TODO: ???
|
||||
|
|
|
@ -26,12 +26,15 @@ from litedram.frontend.dma import *
|
|||
from migen.genlib.cdc import BusSynchronizer
|
||||
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||
|
||||
from litex.soc.cores.video import VideoS7HDMIPHY
|
||||
from litex.soc.cores.video import VideoVGAPHY
|
||||
from litex.soc.cores.video import video_timings
|
||||
import goblin_fb
|
||||
|
||||
# Wishbone stuff
|
||||
from sbus_wb import WishboneDomainCrossingMaster
|
||||
from nubus_mem_wb import NuBus2Wishbone
|
||||
from nubus_cpu_wb import Wishbone2NuBus
|
||||
|
||||
# CRG ----------------------------------------------------------------------------------------------
|
||||
class _CRG_MINI_SIM(Module):
|
||||
|
@ -78,10 +81,10 @@ class _CRG_MINI_SIM(Module):
|
|||
num_adv = 0
|
||||
num_clk = 0
|
||||
|
||||
platform.add_platform_command("create_clock -name sysclk -period 20.8333 [get_nets clk48]")
|
||||
self.sys_bufg = Signal()
|
||||
self.specials += Instance("BUFG", i_I=clk48, o_O=self.sys_bufg)
|
||||
self.comb += self.cd_native.clk.eq(self.sys_bufg)
|
||||
#platform.add_platform_command("create_clock -name sysclk -period 20.8333 [get_nets clk48]")
|
||||
#self.sys_bufg = Signal()
|
||||
#self.specials += Instance("BUFG", i_I=clk48, o_O=self.sys_bufg)
|
||||
#self.comb += self.cd_native.clk.eq(self.sys_bufg)
|
||||
|
||||
|
||||
class _CRG(Module):
|
||||
|
@ -179,8 +182,8 @@ class _CRG(Module):
|
|||
platform.add_platform_command("create_generated_clock -name vga_clk [get_pins {{{{MMCME2_ADV_{}/CLKOUT{}}}}}]".format(num_adv, num_clk))
|
||||
num_clk = num_clk + 1
|
||||
else:
|
||||
video_pll.create_clkout(self.cd_hdmi, pix_clk, margin = 0.0005)
|
||||
video_pll.create_clkout(self.cd_hdmi5x, 5*pix_clk, margin = 0.0005)
|
||||
video_pll.create_clkout(self.cd_hdmi, pix_clk, margin = 0.005)
|
||||
video_pll.create_clkout(self.cd_hdmi5x, 5*pix_clk, margin = 0.005)
|
||||
platform.add_platform_command("create_generated_clock -name hdmi_clk [get_pins {{{{MMCME2_ADV_{}/CLKOUT{}}}}}]".format(num_adv, num_clk))
|
||||
num_clk = num_clk + 1
|
||||
platform.add_platform_command("create_generated_clock -name hdmi5x_clk [get_pins {{{{MMCME2_ADV_{}/CLKOUT{}}}}}]".format(num_adv, num_clk))
|
||||
|
@ -232,29 +235,35 @@ class NuBusFPGA(SoCCore):
|
|||
# * $A through $E for the Macintosh Quadra 900; $9 through $B for the Macintosh IIcx;
|
||||
# * $C through $E for the Macintosh IIci; $D and $E for the Macintosh Quadra 700; and
|
||||
# * $9 for the Macintosh IIsi).
|
||||
# So at best we get 16 MiB in 32-bits moden unless using "super slot space"
|
||||
# the Q650 is $C through $E like the IIci, $E is the one with the PDS.
|
||||
# So at best we get 16 MiB in 32-bits mode, unless using "super slot space"
|
||||
# in 24 bits it's only one megabyte, $s0 0000 through $sF FFFF
|
||||
# they are translated: '$s0 0000-$sF FFFF' to '$Fs00 0000-$Fs0F FFFF' (for s in range $9 through $E)
|
||||
# let's assume we have 32-bits mode, this can be requested in the DeclROM apparently
|
||||
self.wb_mem_map = wb_mem_map = {
|
||||
"goblin_mem": 0x00000000, # up to 8 MiB of FB memory
|
||||
#"END OF FIRST MB" : 0x000FFFFF,
|
||||
#"END OF 8 MB": 0x007FFFFF,
|
||||
"goblin_bt" : 0x00900000, # BT for goblin
|
||||
"csr" : 0x00a00000, # CSR
|
||||
"pingmaster": 0x00b00000,
|
||||
"rom": 0x00FF8000, # ROM at the end (32 KiB of it ATM)
|
||||
"END OF FIRST MB" : 0x000FFFFF,
|
||||
"END OF SLOT SPACE": 0x00FFFFFF,
|
||||
#"END OF SLOT SPACE": 0x00FFFFFF,
|
||||
"main_ram": 0x80000000, # not directly reachable from NuBus
|
||||
"video_framebuffer": 0x80000000 + 0x10000000 - goblin_fb_size, # Updated later
|
||||
"fixme_master": 0xF0000000,
|
||||
}
|
||||
self.mem_map.update(wb_mem_map)
|
||||
self.submodules.crg = _CRG(platform=platform, sys_clk_freq=sys_clk_freq, goblin=goblin, pix_clk=litex.soc.cores.video.video_timings[goblin_res]["pix_clk"])
|
||||
self.submodules.crg = _CRG(platform=platform, sys_clk_freq=sys_clk_freq, goblin=goblin, hdmi=hdmi, pix_clk=litex.soc.cores.video.video_timings[goblin_res]["pix_clk"])
|
||||
|
||||
## add our custom timings after the clocks have been defined
|
||||
xdc_timings_filename = None;
|
||||
#if (version == "V1.0"):
|
||||
# xdc_timings_filename = "/home/dolbeau/nubus-to-ztex-gateware/nubus-to-ztex-timings.xdc"
|
||||
if (version == "V1.0"):
|
||||
xdc_timings_filename = "/home/dolbeau/nubus-to-ztex-gateware/nubus_fpga_V1_0_timings.xdc"
|
||||
|
||||
if (xdc_timings_filename != None):
|
||||
xdc_timings_file = open(xdc_timings_filename)
|
||||
|
||||
xdc_timings_lines = xdc_timings_file.readlines()
|
||||
for line in xdc_timings_lines:
|
||||
if (line[0:3] == "set"):
|
||||
|
@ -263,7 +272,7 @@ class NuBusFPGA(SoCCore):
|
|||
platform.add_platform_command(fix_line)
|
||||
|
||||
rom_file = "rom_{}.bin".format(version.replace(".", "_"))
|
||||
rom_data = soc_core.get_mem_data(rom_file, "big")
|
||||
rom_data = soc_core.get_mem_data(rom_file, "little") # "big"
|
||||
# rom = Array(rom_data)
|
||||
#print("\n****************************************\n")
|
||||
#for i in range(len(rom)):
|
||||
|
@ -271,26 +280,34 @@ class NuBusFPGA(SoCCore):
|
|||
#print("\n****************************************\n")
|
||||
self.add_ram("rom", origin=self.mem_map["rom"], size=2**15, contents=rom_data, mode="r") ## 32 KiB, must match mmap
|
||||
|
||||
avail_sdram = 0
|
||||
self.submodules.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"),
|
||||
memtype = "DDR3",
|
||||
nphases = 4,
|
||||
sys_clk_freq = sys_clk_freq)
|
||||
self.add_sdram("sdram",
|
||||
phy = self.ddrphy,
|
||||
module = MT41J128M16(sys_clk_freq, "1:4"),
|
||||
l2_cache_size = 0,
|
||||
)
|
||||
avail_sdram = self.bus.regions["main_ram"].size
|
||||
from sdram_init import DDR3FBInit
|
||||
self.submodules.sdram_init = DDR3FBInit(sys_clk_freq=sys_clk_freq, bitslip=1, delay=25)
|
||||
self.bus.add_master(name="DDR3Init", master=self.sdram_init.bus)
|
||||
#avail_sdram = 256 * 1024 * 1024
|
||||
#from wb_test import WA2D
|
||||
#self.submodules.wa2d = WA2D(self.platform)
|
||||
#self.bus.add_slave("WA2D", self.wa2d.bus, SoCRegion(origin=0x00C00000, size=0x00400000, cached=False))
|
||||
|
||||
self.submodules.leds = LedChaser(
|
||||
pads = platform.request_all("user_led"),
|
||||
sys_clk_freq = sys_clk_freq)
|
||||
self.add_csr("leds")
|
||||
notsimul = 1
|
||||
if (notsimul):
|
||||
avail_sdram = 0
|
||||
self.submodules.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"),
|
||||
memtype = "DDR3",
|
||||
nphases = 4,
|
||||
sys_clk_freq = sys_clk_freq)
|
||||
self.add_sdram("sdram",
|
||||
phy = self.ddrphy,
|
||||
module = MT41J128M16(sys_clk_freq, "1:4"),
|
||||
l2_cache_size = 0,
|
||||
)
|
||||
avail_sdram = self.bus.regions["main_ram"].size
|
||||
from sdram_init import DDR3FBInit
|
||||
self.submodules.sdram_init = DDR3FBInit(sys_clk_freq=sys_clk_freq, bitslip=1, delay=25)
|
||||
self.bus.add_master(name="DDR3Init", master=self.sdram_init.bus)
|
||||
else:
|
||||
avail_sdram = 256 * 1024 * 1024
|
||||
self.add_ram("ram", origin=self.mem_map["goblin_mem"], size=2**16, mode="rw")
|
||||
|
||||
#self.submodules.leds = ClockDomainsRenamer("nubus")(LedChaser(
|
||||
# pads = platform.request_all("user_led"),
|
||||
# sys_clk_freq = 10e6))
|
||||
#self.add_csr("leds")
|
||||
|
||||
base_fb = self.wb_mem_map["main_ram"] + avail_sdram - 1048576 # placeholder
|
||||
if (goblin):
|
||||
|
@ -298,6 +315,7 @@ class NuBusFPGA(SoCCore):
|
|||
avail_sdram = avail_sdram - goblin_fb_size
|
||||
base_fb = self.wb_mem_map["main_ram"] + avail_sdram
|
||||
self.wb_mem_map["video_framebuffer"] = base_fb
|
||||
print(f"FrameBuffer base_fb @ {base_fb:x}")
|
||||
else:
|
||||
print("***** ERROR ***** Can't have a FrameBuffer without main ram\n")
|
||||
assert(False)
|
||||
|
@ -307,13 +325,16 @@ class NuBusFPGA(SoCCore):
|
|||
# requires us to reset the Macintosh afterward so the FPGA board
|
||||
# is properly identified
|
||||
# This is in the 'native' ClockDomain that is never reset
|
||||
# not needed, FPGA initializes fast enough, works on cold boots
|
||||
#hold_reset_ctr = Signal(30, reset=960000000)
|
||||
hold_reset_ctr = Signal(5, reset=31)
|
||||
self.sync.native += If(hold_reset_ctr>0, hold_reset_ctr.eq(hold_reset_ctr - 1))
|
||||
hold_reset = Signal(reset=1)
|
||||
hold_reset = Signal()
|
||||
self.comb += hold_reset.eq(~(hold_reset_ctr == 0))
|
||||
pad_nubus_oe = platform.request("nubus_oe")
|
||||
self.comb += pad_nubus_oe.eq(hold_reset)
|
||||
#pad_user_led_0 = platform.request("user_led", 0)
|
||||
#self.comb += pad_user_led_0.eq(~hold_reset)
|
||||
|
||||
# Interface NuBus to wishbone
|
||||
# we need to cross clock domains
|
||||
|
@ -325,14 +346,30 @@ class NuBusFPGA(SoCCore):
|
|||
self.submodules.nubus = nubus.NuBus(platform=platform, cd_nubus="nubus")
|
||||
self.submodules.nubus2wishbone = ClockDomainsRenamer("nubus")(NuBus2Wishbone(nubus=self.nubus,wb=self.wishbone_master_nubus))
|
||||
|
||||
wishbone_slave_nubus = wishbone.Interface(data_width=self.bus.data_width)
|
||||
self.submodules.wishbone2nubus = ClockDomainsRenamer("nubus")(Wishbone2NuBus(nubus=self.nubus,wb=wishbone_slave_nubus))
|
||||
self.submodules.wishbone_slave_sys = WishboneDomainCrossingMaster(platform=self.platform, slave=wishbone_slave_nubus, cd_master="sys", cd_slave="nubus")
|
||||
self.bus.add_slave("DMA", self.wishbone_slave_sys, SoCRegion(origin=self.mem_map.get("fixme_master", None), size=0x0fffffff, cached=False))
|
||||
|
||||
|
||||
if (goblin):
|
||||
if (not hdmi):
|
||||
self.submodules.videophy = VideoVGAPHY(platform.request("vga"), clock_domain="vga")
|
||||
self.submodules.goblin = goblin_fb.goblin(soc=self, phy=self.videophy, timings=goblin_res, clock_domain="vga") # clock_domain for the VGA side, goblin is running in cd_sys
|
||||
self.submodules.goblin = goblin_fb.goblin(soc=self, phy=self.videophy, timings=goblin_res, clock_domain="vga", irq_line=self.platform.request("nmrq_3v3_n"), endian="little", truecolor=False) # clock_domain for the VGA side, goblin is running in cd_sys
|
||||
else:
|
||||
self.submodules.videophy = VideoS7HDMIPHY(platform.request("hdmi"), clock_domain="hdmi")
|
||||
self.submodules.goblin = goblin_fb.goblin(soc=self, phy=self.videophy, timings=goblin_res, clock_domain="hdmi") # clock_domain for the VGA side, goblin is running in cd_sys
|
||||
self.submodules.goblin = goblin_fb.goblin(soc=self, phy=self.videophy, timings=goblin_res, clock_domain="hdmi", irq_line=self.platform.request("nmrq_3v3_n"), endian="little", truecolor=False) # clock_domain for the HDMI side, goblin is running in cd_sys
|
||||
self.bus.add_slave("goblin_bt", self.goblin.bus, SoCRegion(origin=self.mem_map.get("goblin_bt", None), size=0x1000, cached=False))
|
||||
pad_user_led_0 = platform.request("user_led", 0)
|
||||
pad_user_led_1 = platform.request("user_led", 1)
|
||||
self.comb += pad_user_led_0.eq(self.goblin.video_framebuffer.underflow)
|
||||
self.comb += pad_user_led_1.eq(self.goblin.video_framebuffer.fb_dma.enable)
|
||||
|
||||
# for testing
|
||||
#from nubus_master_tst import PingMaster
|
||||
#self.submodules.pingmaster = PingMaster()
|
||||
#self.bus.add_slave("pingmaster_slv", self.pingmaster.bus_slv, SoCRegion(origin=self.mem_map.get("pingmaster", None), size=0x010, cached=False))
|
||||
#self.bus.add_master(name="pingmaster_mst", master=self.pingmaster.bus_mst)
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
FILE=$1
|
||||
|
||||
sed -e 's/ad_n\([0-9]*\)/ad_3v3_n[\1]/' \
|
||||
-e 's/clk_n/clk_3v3_n/' \
|
||||
-e 's/rqst_n/rqst_3v3_n/' \
|
||||
-e 's/start_n/start_3v3_n/' \
|
||||
-e 's/ack_n/ack_3v3_n/' \
|
||||
-e 's/clk_n/clk_3v3_n/' \
|
||||
-e 's/tm_n\([0-9]*\)/tm\1_3v3_n/' \
|
||||
-e 's/clk_3v3_n/nubus_clk/g' \
|
||||
$FILE | grep -v 'nubus_clk.*nubus_clk' | grep '^set' | tee $2
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,139 @@
|
|||
#!/usr/bin/env python3
|
||||
from migen import *
|
||||
|
||||
from wb_master import *
|
||||
from wb_master import _WRITE_CMD, _WAIT_CMD, _DONE_CMD
|
||||
|
||||
|
||||
dfii_control_sel = 0x01
|
||||
dfii_control_cke = 0x02
|
||||
dfii_control_odt = 0x04
|
||||
dfii_control_reset_n = 0x08
|
||||
|
||||
dfii_command_cs = 0x01
|
||||
dfii_command_we = 0x02
|
||||
dfii_command_cas = 0x04
|
||||
dfii_command_ras = 0x08
|
||||
dfii_command_wrdata = 0x10
|
||||
dfii_command_rddata = 0x20
|
||||
|
||||
# /!\ keep up to date with csr /!\
|
||||
sdram_dfii_base = 0x00a01000
|
||||
sdram_dfii_control = sdram_dfii_base + 0x000
|
||||
sdram_dfii_pi0_command = sdram_dfii_base + 0x004
|
||||
sdram_dfii_pi0_command_issue = sdram_dfii_base + 0x008
|
||||
sdram_dfii_pi0_address = sdram_dfii_base + 0x00c
|
||||
sdram_dfii_pi0_baddress = sdram_dfii_base + 0x010
|
||||
|
||||
# /!\ keep up to date with csr /!\
|
||||
ddrphy_base = 0x00a00000
|
||||
ddrphy_rst = ddrphy_base + 0x000
|
||||
ddrphy_dly_sel = ddrphy_base + 0x010
|
||||
ddrphy_rdly_dq_rst = ddrphy_base + 0x014
|
||||
ddrphy_rdly_dq_inc = ddrphy_base + 0x018
|
||||
ddrphy_rdly_dq_bitslip_rst = ddrphy_base + 0x01c
|
||||
ddrphy_rdly_dq_bitslip = ddrphy_base + 0x020
|
||||
ddrphy_wdly_dq_bitslip_rst = ddrphy_base + 0x024
|
||||
ddrphy_wdly_dq_bitslip = ddrphy_base + 0x028
|
||||
ddrphy_rdphase = ddrphy_base + 0x02c
|
||||
ddrphy_wdphase = ddrphy_base + 0x030
|
||||
|
||||
|
||||
def period_to_cycles(sys_clk_freq, period):
|
||||
return int(period*sys_clk_freq)
|
||||
|
||||
def ddr3_init_instructions(sys_clk_freq):
|
||||
return [
|
||||
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.001),
|
||||
# phase
|
||||
_WRITE_CMD, ddrphy_rdphase, 2,
|
||||
_WRITE_CMD, ddrphy_wdphase, 3,
|
||||
|
||||
# software control
|
||||
_WRITE_CMD, sdram_dfii_control, dfii_control_reset_n | dfii_control_odt | dfii_control_cke,
|
||||
|
||||
# reset
|
||||
_WRITE_CMD, ddrphy_rst, 1,
|
||||
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.001),
|
||||
_WRITE_CMD, ddrphy_rst, 0,
|
||||
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.001),
|
||||
|
||||
# release reset
|
||||
_WRITE_CMD, sdram_dfii_pi0_address, 0x0,
|
||||
_WRITE_CMD, sdram_dfii_pi0_baddress, 0,
|
||||
_WRITE_CMD, sdram_dfii_control, dfii_control_odt|dfii_control_reset_n,
|
||||
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.005),
|
||||
|
||||
# bring cke high
|
||||
_WRITE_CMD, sdram_dfii_pi0_address, 0x0,
|
||||
_WRITE_CMD, sdram_dfii_pi0_baddress, 0,
|
||||
_WRITE_CMD, sdram_dfii_control, dfii_control_cke|dfii_control_odt|dfii_control_reset_n,
|
||||
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.001),
|
||||
|
||||
# load mode register 2, CWL = 5
|
||||
_WRITE_CMD, sdram_dfii_pi0_address, 0x200,
|
||||
_WRITE_CMD, sdram_dfii_pi0_baddress, 2,
|
||||
_WRITE_CMD, sdram_dfii_pi0_command, dfii_command_ras|dfii_command_cas|dfii_command_we|dfii_command_cs,
|
||||
_WRITE_CMD, sdram_dfii_pi0_command_issue, 1,
|
||||
|
||||
# load mode register 3
|
||||
_WRITE_CMD, sdram_dfii_pi0_address, 0x0,
|
||||
_WRITE_CMD, sdram_dfii_pi0_baddress, 3,
|
||||
_WRITE_CMD, sdram_dfii_pi0_command, dfii_command_ras|dfii_command_cas|dfii_command_we|dfii_command_cs,
|
||||
_WRITE_CMD, sdram_dfii_pi0_command_issue, 1,
|
||||
|
||||
# load mode register 1
|
||||
_WRITE_CMD, sdram_dfii_pi0_address, 0x6,
|
||||
_WRITE_CMD, sdram_dfii_pi0_baddress, 1,
|
||||
_WRITE_CMD, sdram_dfii_pi0_command, dfii_command_ras|dfii_command_cas|dfii_command_we|dfii_command_cs,
|
||||
_WRITE_CMD, sdram_dfii_pi0_command_issue, 1,
|
||||
|
||||
# load mode register 0, CL=6, BL=8
|
||||
_WRITE_CMD, sdram_dfii_pi0_address, 0x920,
|
||||
_WRITE_CMD, sdram_dfii_pi0_baddress, 0,
|
||||
_WRITE_CMD, sdram_dfii_pi0_command, dfii_command_ras|dfii_command_cas|dfii_command_we|dfii_command_cs,
|
||||
_WRITE_CMD, sdram_dfii_pi0_command_issue, 1,
|
||||
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.0002),
|
||||
|
||||
# zq calibration
|
||||
_WRITE_CMD, sdram_dfii_pi0_address, 0x400,
|
||||
_WRITE_CMD, sdram_dfii_pi0_baddress, 0,
|
||||
_WRITE_CMD, sdram_dfii_pi0_command, dfii_command_we|dfii_command_cs,
|
||||
_WRITE_CMD, sdram_dfii_pi0_command_issue, 1,
|
||||
_WAIT_CMD | period_to_cycles(sys_clk_freq, 0.0002),
|
||||
|
||||
# hardware control
|
||||
_WRITE_CMD, sdram_dfii_control, dfii_control_sel,
|
||||
]
|
||||
|
||||
|
||||
def ddr3_config_instructions(bitslip, delay):
|
||||
r = []
|
||||
for module in range(2):
|
||||
r += [_WRITE_CMD, ddrphy_dly_sel, 1<<module ]
|
||||
r += [_WRITE_CMD, ddrphy_wdly_dq_bitslip_rst, 1<<module ]
|
||||
r += [_WRITE_CMD, ddrphy_dly_sel, 0 ]
|
||||
for module in range(2):
|
||||
r += [_WRITE_CMD, ddrphy_dly_sel, 1<<module ]
|
||||
r += [_WRITE_CMD, ddrphy_rdly_dq_bitslip_rst, 1]
|
||||
for i in range(bitslip):
|
||||
r += [_WRITE_CMD, ddrphy_rdly_dq_bitslip, 1]
|
||||
r += [_WRITE_CMD, ddrphy_rdly_dq_rst, 1]
|
||||
for i in range(delay):
|
||||
r += [_WRITE_CMD, ddrphy_rdly_dq_inc, 1]
|
||||
r += [_WRITE_CMD, ddrphy_dly_sel, 0 ]
|
||||
return r
|
||||
|
||||
class DDR3Init(WishboneMaster):
|
||||
def __init__(self, sys_clk_freq, bitslip, delay):
|
||||
WishboneMaster.__init__(self,
|
||||
ddr3_init_instructions(sys_clk_freq) +
|
||||
ddr3_config_instructions(bitslip, delay) +
|
||||
[_DONE_CMD])
|
||||
|
||||
class DDR3FBInit(WishboneMaster):
|
||||
def __init__(self, sys_clk_freq, bitslip, delay):
|
||||
WishboneMaster.__init__(self,
|
||||
ddr3_init_instructions(sys_clk_freq) +
|
||||
ddr3_config_instructions(bitslip, delay) +
|
||||
[_DONE_CMD])
|
|
@ -4,12 +4,13 @@ module nubus_slave_tb ();
|
|||
|
||||
`include "nubus_tb.svh"
|
||||
|
||||
parameter TEST_CARD_ID = 'h0;
|
||||
parameter TEST_ADDR = 'hF0000000;
|
||||
parameter TEST_CARD_ID = 'hc;
|
||||
parameter TEST_ADDR = 'hFc000000;
|
||||
parameter TEST_DATA = 'h87654321;
|
||||
parameter [1:0] MEMORY_WAIT_CLOCKS = 1;
|
||||
parameter DEBUG_NUBUS_START = 0;
|
||||
parameter ROM_ADDR = 'hF0FFF000;
|
||||
parameter ROM_ADDR = 'hFcFFF000;
|
||||
parameter PING_ADDR = 'hFcB00000;
|
||||
|
||||
// Clock (rising is driving edge, faling is sampling)
|
||||
tri1 bd_clk48;
|
||||
|
@ -48,16 +49,18 @@ module nubus_slave_tb ();
|
|||
tri1 [1:0] leds;
|
||||
|
||||
tri unused0, tmoen, unused1, unused2;
|
||||
tri arb, grant;
|
||||
tri arbcy_n;
|
||||
tri grant;
|
||||
tri nubus_oe, nubus_master_dir, nubus_ad_dir;
|
||||
tri reset_n_3v3, clk_n_3v3, tm0_n_3v3, tm1_n_3v3, start_n_3v3, ack_n_3v3, rqst_n_3v3;
|
||||
tri1 [3:0] id_n_3v3;
|
||||
tri [3:0] id_n_3v3;
|
||||
tri [31:0] ad_n_3v3;
|
||||
tri [3:0] arb_o_n;
|
||||
tri tm0_o_n, tm1_o_n, tmx_oe_n;
|
||||
tri start_o_n, start_oe_n;
|
||||
tri ack_o_n, ack_oe_n;
|
||||
tri rqst_o_n;
|
||||
tri rqst_o_n;
|
||||
tri fpga_to_cpld_signal;
|
||||
|
||||
|
||||
tri clk2x_n_3v3;
|
||||
|
@ -66,9 +69,7 @@ module nubus_slave_tb ();
|
|||
|
||||
|
||||
assign nub_idn = ~ TEST_CARD_ID;
|
||||
|
||||
assign nubus_master_dir = 0;
|
||||
assign nub_arbn = 'b1111;
|
||||
//assign nub_arbn = 'b1111;
|
||||
|
||||
nubus_cpld UCPLD (
|
||||
.nubus_oe(nubus_oe),
|
||||
|
@ -81,7 +82,7 @@ module nubus_slave_tb ();
|
|||
.clk2x_n_5v(nub_clk2xn),
|
||||
|
||||
.fpga_to_cpld_clk(unused0),
|
||||
.fpga_to_cpld_signal(unused1),
|
||||
.fpga_to_cpld_signal(fpga_to_cpld_signal),
|
||||
.fpga_to_cpld_signal_2(unused2),
|
||||
|
||||
.id_n_3v3(id_n_3v3),
|
||||
|
@ -89,7 +90,7 @@ module nubus_slave_tb ();
|
|||
.clk_n_3v3(clk_n_3v3),
|
||||
.clk2x_n_3v3(clk2x_n_3v3),
|
||||
|
||||
.arb(arb),
|
||||
.arbcy_n(arbcy_n),
|
||||
.arb_n_5v(nub_arbn),
|
||||
.arb_o_n(arb_o_n),
|
||||
.grant(grant),
|
||||
|
@ -141,6 +142,8 @@ module nubus_slave_tb ();
|
|||
.nubus_ad_dir(nubus_ad_dir));
|
||||
|
||||
tri1 nmrq_3v3_n;
|
||||
assign nmrq_3v3_n = 1;
|
||||
|
||||
|
||||
sn74lvt145_quarter driver_u1a(.oe_n(nmrq_3v3_n),
|
||||
.in(0),
|
||||
|
@ -196,14 +199,15 @@ module nubus_slave_tb ();
|
|||
.rqst_3v3_n(rqst_n_3v3),
|
||||
.ack_3v3_n(ack_n_3v3),
|
||||
// .nubus_arb_n(nub_arbn),
|
||||
.arb(arb),
|
||||
.arbcy_n(arbcy_n),
|
||||
.grant(grant),
|
||||
.tmoen(tmoen),
|
||||
.nubus_ad_dir(nubus_ad_dir),
|
||||
.nmrq_3v3_n(nmrq_3v3_n),
|
||||
.nubus_master_dir(nubus_master_dir),
|
||||
.nubus_oe(nubus_oe),
|
||||
.clk2x_3v3_n(clk2x_n_3v3),
|
||||
.tm2_3v3_n(tm2_n_3v3)
|
||||
.tm2_3v3_n(tm2_n_3v3),
|
||||
.fpga_to_cpld_signal(fpga_to_cpld_signal)
|
||||
);
|
||||
|
||||
|
||||
|
@ -220,19 +224,22 @@ module nubus_slave_tb ();
|
|||
reg [31:0] tst_wdatan;
|
||||
reg [31:0] tst_rdatan;
|
||||
|
||||
// Drive NuBus signals
|
||||
reg mastermode_start;
|
||||
reg mastermode_tmack;
|
||||
|
||||
assign nub_clkn = tst_clkn;
|
||||
assign nub_clk2xn = tst_clk2xn;
|
||||
assign bd_clk48 = tst_clk48;
|
||||
assign nub_resetn = tst_resetn;
|
||||
assign nub_startn = tst_startn;
|
||||
assign nub_tm0n = tst_startn ? 'bZ : tst_tmn[0];
|
||||
assign nub_tm1n = tst_startn ? 'bZ : tst_tmn[1];
|
||||
assign nub_ackn = tst_startn ? 'bZ : tst_ackn;
|
||||
// Drive NuBus signals
|
||||
assign nub_startn = mastermode_start ? 'bZ: tst_startn;
|
||||
assign nub_tm0n = (tst_startn & ~mastermode_tmack) ? 'bZ : tst_tmn[0];
|
||||
assign nub_tm1n = (tst_startn & ~mastermode_tmack) ? 'bZ : tst_tmn[1];
|
||||
assign nub_ackn = (tst_startn & ~mastermode_tmack) ? 'bZ : tst_ackn;
|
||||
|
||||
// Drive NuBus address/data lines
|
||||
wire [31:0] tst_adn = tst_startn ? tst_wdatan : tst_addrn;
|
||||
wire tst_nuboen = tst_startn & tst_tmn[1];
|
||||
wire tst_nuboen = (tst_startn & tst_tmn[1]) | mastermode_start;
|
||||
assign nub_adn = tst_nuboen ? 'bZ : tst_adn;
|
||||
|
||||
// Inverted verions of registers
|
||||
|
@ -243,6 +250,10 @@ module nubus_slave_tb ();
|
|||
$display ("Start virtual master (vm) writes and reads to/from NuBus slave memory module");
|
||||
$dumpfile("nubus_slave_tb.vcd");
|
||||
$dumpvars;
|
||||
#1;
|
||||
|
||||
mastermode_start <= 0;
|
||||
mastermode_tmack <= 0;
|
||||
|
||||
tst_clkn <= 1;
|
||||
tst_resetn <= 0;
|
||||
|
@ -311,6 +322,40 @@ module nubus_slave_tb ();
|
|||
|
||||
#1000;
|
||||
|
||||
// check PingMaster
|
||||
$display ("PING ---------------------------");
|
||||
write_word(TMADN_WR_WORD, PING_ADDR+0, 'hC0FFEE00);
|
||||
read_word (TMADN_RD_WORD, PING_ADDR+0);
|
||||
write_word(TMADN_WR_WORD, PING_ADDR+4, 'hF0F0F0F0);
|
||||
|
||||
mastermode_start <= 1;
|
||||
mastermode_tmack <= 0;
|
||||
tst_ackn <= 1;
|
||||
|
||||
@ (negedge nub_startn);
|
||||
#1
|
||||
$display ("GOT START ---------------------------");
|
||||
$display ("%g (received ) address: $%h", $time, ~nub_adn);
|
||||
@ (negedge nub_clkn);
|
||||
#1
|
||||
@ (negedge nub_clkn);
|
||||
#1
|
||||
@ (negedge nub_clkn);
|
||||
#1
|
||||
$display ("%g (received ) data: $%h", $time, ~nub_adn);
|
||||
@ (posedge nub_clkn);
|
||||
mastermode_tmack <= 1;
|
||||
tst_ackn <= 0;
|
||||
tst_tmn <= TMN_COMPLETE;
|
||||
|
||||
@ (posedge nub_clkn);
|
||||
mastermode_start <= 0;
|
||||
mastermode_tmack <= 0;
|
||||
|
||||
|
||||
#2000;
|
||||
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ _nubus_nubus_v1_0 = [
|
|||
"D12 D13 D14 C14 B16 B17 D15 C15 "
|
||||
"B18 A18 C16 C17 E15 E16 F14 F13 "
|
||||
"D17 D18 E17 E18 F15 F18 F16 G18 "), IOStandard("lvttl")),
|
||||
# ("nubus_arb_n", 0, Pins(""), IOStandard("lvttl")), # CPLD only, we have 'arb'/'grant' instead
|
||||
# ("nubus_arb_n", 0, Pins(""), IOStandard("lvttl")), # CPLD only, we have 'arbcy_n'/'grant' instead
|
||||
("id_3v3_n", 0, Pins("U7 V6 V7 U8"), IOStandard("lvttl")),
|
||||
("tm0_3v3_n", 0, Pins("K15"), IOStandard("lvttl")),
|
||||
("tm1_3v3_n", 0, Pins("J17"), IOStandard("lvttl")),
|
||||
|
@ -121,7 +121,7 @@ _nubus_nubus_v1_0 = [
|
|||
("nubus_ad_dir", 0, Pins("G16"), IOStandard("lvttl")),
|
||||
("nubus_master_dir", 0, Pins("H17"), IOStandard("lvttl")),
|
||||
("grant", 0, Pins("H15"), IOStandard("lvttl")),
|
||||
("arb", 0, Pins("J13"), IOStandard("lvttl")),
|
||||
("arbcy_n", 0, Pins("J13"), IOStandard("lvttl")), # arb in the schematics
|
||||
("fpga_to_cpld_clk", 0, Pins("H14"), IOStandard("lvttl")),
|
||||
("tmoen", 0, Pins("U6"), IOStandard("lvttl")),
|
||||
("fpga_to_cpld_signal",0, Pins("J14"), IOStandard("lvttl")),
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,158 @@
|
|||
THICKNESS_MAX=2.44;
|
||||
THICKNESS=2.4;
|
||||
|
||||
ORIGINAL_THICKNESS=25.4/32;
|
||||
|
||||
NUBUS_HEIGHT_BELOW_OUTER_LIP=92; // NuBus p57, max is 97.25
|
||||
NUBUS_HEIGHT_ABOVE_OUTER_LIP=6; // NuBus p57
|
||||
|
||||
NUBUS_BETWEEN_NOTCHES=87.25; // DCDMF3 p625 & p635, bottom of low to top of high?
|
||||
NUBUS_HIGH_NOTCH_TO_TOP=10.35;// DCDMF3 p635, top of high to bottom of inner lip ?
|
||||
|
||||
NUBUS_BASE_WIDTH=18.57;
|
||||
NUBUS_EXTRA_WIDTH=2.93;
|
||||
NUBUS_FULL_WIDTH=NUBUS_BASE_WIDTH+NUBUS_EXTRA_WIDTH;
|
||||
NUBUS_TOP_WIDTH=21.82;
|
||||
NUBUS_OVERHANG_WIDTH=NUBUS_TOP_WIDTH-NUBUS_BASE_WIDTH;
|
||||
NUBUS_EXTRA_FROM_TOP=20.5;
|
||||
NUBUS_ANGLE_SECTION_LACK_OF_WIDTH=2.57;
|
||||
NUBUS_ANGLE_SECTION_WIDTH_REDUCTION=NUBUS_EXTRA_WIDTH+NUBUS_ANGLE_SECTION_LACK_OF_WIDTH;
|
||||
|
||||
NUBUS_HEIGHT_NARROW_BOTTOM_TO_TOP=94.6;
|
||||
NUBUS_FULL_HEIGHT=(NUBUS_BETWEEN_NOTCHES+NUBUS_HIGH_NOTCH_TO_TOP);
|
||||
NUBUS_NARROW_BOTTOM_HEIGHT=NUBUS_FULL_HEIGHT-NUBUS_HEIGHT_NARROW_BOTTOM_TO_TOP;
|
||||
|
||||
NUBUS_EXTRA_NARROW_BOTTOM=1.5;
|
||||
|
||||
NUBUS_OVERHANG_MIN_HEIGHT=8.4;
|
||||
NUBUS_OVERHANG_MAX_HEIGHT=12.18;
|
||||
NUBUS_OVERHANG_RADIUS=3.2;
|
||||
NUBUS_TOP_BIT_WIDTH=9.57-2.57;
|
||||
|
||||
FRONT_NOTCH_FROM_TOP=85.9;
|
||||
FRONT_NOTCH_STRAIGHT_WIDTH=2;
|
||||
FRONT_NOTCH_STRAIGHT_HEIGHT=6;
|
||||
FRONT_NOTCH_ANGLE_HEIGHT=(NUBUS_BETWEEN_NOTCHES+NUBUS_HIGH_NOTCH_TO_TOP)-(FRONT_NOTCH_FROM_TOP+FRONT_NOTCH_STRAIGHT_HEIGHT);
|
||||
FRONT_NOTCH_ANGLE_WIDTH=FRONT_NOTCH_ANGLE_HEIGHT*sin(23);
|
||||
|
||||
points=[[0,0],
|
||||
[NUBUS_BASE_WIDTH-7.82-FRONT_NOTCH_STRAIGHT_WIDTH/2-FRONT_NOTCH_ANGLE_WIDTH,0],
|
||||
[NUBUS_BASE_WIDTH-7.82-FRONT_NOTCH_STRAIGHT_WIDTH/2,FRONT_NOTCH_ANGLE_HEIGHT],
|
||||
[NUBUS_BASE_WIDTH-7.82-FRONT_NOTCH_STRAIGHT_WIDTH/2,FRONT_NOTCH_ANGLE_HEIGHT+FRONT_NOTCH_STRAIGHT_HEIGHT],
|
||||
[NUBUS_BASE_WIDTH-7.82+FRONT_NOTCH_STRAIGHT_WIDTH/2,FRONT_NOTCH_ANGLE_HEIGHT+FRONT_NOTCH_STRAIGHT_HEIGHT],
|
||||
[NUBUS_BASE_WIDTH-7.82+FRONT_NOTCH_STRAIGHT_WIDTH/2,FRONT_NOTCH_ANGLE_HEIGHT],
|
||||
[NUBUS_BASE_WIDTH-7.82+FRONT_NOTCH_STRAIGHT_WIDTH/2+FRONT_NOTCH_ANGLE_WIDTH,0],
|
||||
[NUBUS_BASE_WIDTH-NUBUS_EXTRA_NARROW_BOTTOM,0],
|
||||
|
||||
[NUBUS_BASE_WIDTH-NUBUS_EXTRA_NARROW_BOTTOM,NUBUS_NARROW_BOTTOM_HEIGHT],
|
||||
[NUBUS_FULL_WIDTH,NUBUS_NARROW_BOTTOM_HEIGHT],
|
||||
[NUBUS_FULL_WIDTH,NUBUS_FULL_HEIGHT-NUBUS_EXTRA_FROM_TOP],
|
||||
[NUBUS_FULL_WIDTH-NUBUS_ANGLE_SECTION_WIDTH_REDUCTION,(NUBUS_FULL_HEIGHT-NUBUS_EXTRA_FROM_TOP)+(NUBUS_ANGLE_SECTION_WIDTH_REDUCTION*2)],
|
||||
[NUBUS_FULL_WIDTH-NUBUS_ANGLE_SECTION_WIDTH_REDUCTION,NUBUS_FULL_HEIGHT+ORIGINAL_THICKNESS],
|
||||
[NUBUS_FULL_WIDTH-NUBUS_ANGLE_SECTION_WIDTH_REDUCTION-NUBUS_TOP_BIT_WIDTH,NUBUS_FULL_HEIGHT+ORIGINAL_THICKNESS],
|
||||
[NUBUS_FULL_WIDTH-NUBUS_ANGLE_SECTION_WIDTH_REDUCTION-NUBUS_TOP_BIT_WIDTH,NUBUS_FULL_HEIGHT+ORIGINAL_THICKNESS-6], //6: measurement
|
||||
[NUBUS_FULL_WIDTH-NUBUS_ANGLE_SECTION_WIDTH_REDUCTION-NUBUS_TOP_BIT_WIDTH-2,NUBUS_FULL_HEIGHT+ORIGINAL_THICKNESS-6], //2&6: measurement
|
||||
[NUBUS_FULL_WIDTH-NUBUS_ANGLE_SECTION_WIDTH_REDUCTION-NUBUS_TOP_BIT_WIDTH-2,NUBUS_FULL_HEIGHT+ORIGINAL_THICKNESS-NUBUS_HIGH_NOTCH_TO_TOP+5], // 5 is the diustance between top notch and top screw hole
|
||||
[-NUBUS_OVERHANG_WIDTH,NUBUS_FULL_HEIGHT+ORIGINAL_THICKNESS-NUBUS_HIGH_NOTCH_TO_TOP+5],
|
||||
[-NUBUS_OVERHANG_WIDTH,NUBUS_FULL_HEIGHT-NUBUS_OVERHANG_MAX_HEIGHT+NUBUS_OVERHANG_RADIUS],
|
||||
[0,NUBUS_FULL_HEIGHT-NUBUS_OVERHANG_MAX_HEIGHT]
|
||||
];
|
||||
|
||||
module backplate() {
|
||||
linear_extrude(height = ORIGINAL_THICKNESS, center = true) { polygon(points); };
|
||||
}
|
||||
|
||||
// PCB, don't print
|
||||
PCB_THICKNESS=1.6;
|
||||
PCB_OFFSET=(NUBUS_FULL_WIDTH-2.93)-PCB_THICKNESS/2;
|
||||
module pcb() {
|
||||
color("green") translate([PCB_OFFSET,0,-50]) linear_extrude(height = 100, center = true) { polygon ([[-PCB_THICKNESS,-5.08],[0,-5.08],[0,91.52],[-PCB_THICKNESS,91.52]]); };
|
||||
}
|
||||
|
||||
// NuBusFPGA
|
||||
BOTTOM_HOLE_Y=8-1.08;
|
||||
TOP_HOLE_Y=87.52;
|
||||
FIRST_HOLE_X=-6.44;
|
||||
SECOND_HOLE_X=-16.44;
|
||||
|
||||
module holders() {
|
||||
difference() {
|
||||
union() {
|
||||
color("red") translate([0,0,-11]) linear_extrude(height = 22, center = true) { polygon([
|
||||
[PCB_OFFSET-PCB_THICKNESS,BOTTOM_HOLE_Y-4],
|
||||
[PCB_OFFSET-PCB_THICKNESS,BOTTOM_HOLE_Y+4],
|
||||
[PCB_OFFSET-PCB_THICKNESS-2,BOTTOM_HOLE_Y+4],
|
||||
[PCB_OFFSET-PCB_THICKNESS-2,BOTTOM_HOLE_Y-4],
|
||||
]); };
|
||||
color("red") translate([0,0,-11]) linear_extrude(height = 22, center = true) { polygon([
|
||||
[PCB_OFFSET-PCB_THICKNESS,TOP_HOLE_Y-4],
|
||||
[PCB_OFFSET-PCB_THICKNESS,TOP_HOLE_Y+4],
|
||||
[PCB_OFFSET-PCB_THICKNESS-2,TOP_HOLE_Y+4],
|
||||
[PCB_OFFSET-PCB_THICKNESS-2,TOP_HOLE_Y-4],
|
||||
]); };
|
||||
}
|
||||
union() {
|
||||
color("blue") translate([0,BOTTOM_HOLE_Y,FIRST_HOLE_X]) rotate([0,90,0]) cylinder(r1=1.6,r2=1.6,h=20);
|
||||
color("blue") translate([0,BOTTOM_HOLE_Y,SECOND_HOLE_X]) rotate([0,90,0]) cylinder(r1=1.6,r2=1.6,h=20);
|
||||
color("blue") translate([0,TOP_HOLE_Y,FIRST_HOLE_X]) rotate([0,90,0]) cylinder(r1=1.6,r2=1.6,h=20);
|
||||
color("blue") translate([0,TOP_HOLE_Y,SECOND_HOLE_X]) rotate([0,90,0]) cylinder(r1=1.6,r2=1.6,h=20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//cube ([16.5+4, 12, 9.5+4 /* 14.8 max */], center = true);
|
||||
USB_HOLDER_HEIGHT=5;
|
||||
USB_HOLDER_WIDTH=10;
|
||||
USB_HOLDER_DEPTH=5;
|
||||
module usb_pos() {
|
||||
translate([-1-USB_HOLDER_HEIGHT/2+PCB_OFFSET-PCB_THICKNESS,100-(74.67+(83.47-74.67)/2),-USB_HOLDER_DEPTH/2]) cube([2+USB_HOLDER_HEIGHT,2+USB_HOLDER_WIDTH,USB_HOLDER_DEPTH], center = true);
|
||||
}
|
||||
module usb_neg() {
|
||||
translate([-0.499-USB_HOLDER_HEIGHT/2+PCB_OFFSET-PCB_THICKNESS,100-(74.67+(83.47-74.67)/2),-USB_HOLDER_DEPTH/2]) cube([1.001+USB_HOLDER_HEIGHT,USB_HOLDER_WIDTH,USB_HOLDER_DEPTH*4], center = true);
|
||||
}
|
||||
|
||||
VGA_HOLDER_HEIGHT=14.8;
|
||||
VGA_HOLDER_WIDTH=31.8;
|
||||
VGA_HOLDER_DEPTH=2;
|
||||
module vga_pos() {
|
||||
translate([-VGA_HOLDER_HEIGHT/2+PCB_OFFSET-PCB_THICKNESS,100-(18.21+(49.05-18.21)/2),-VGA_HOLDER_DEPTH/2+VGA_HOLDER_DEPTH]) cube ([VGA_HOLDER_HEIGHT, 6+VGA_HOLDER_WIDTH, VGA_HOLDER_DEPTH], center = true);
|
||||
}
|
||||
module vga_neg() {
|
||||
translate([-VGA_HOLDER_HEIGHT/2+PCB_OFFSET-PCB_THICKNESS,100-(18.21+(49.05-18.21)/2),-VGA_HOLDER_DEPTH/2]) cube ([10, 18, 10+0.001], center = true);
|
||||
|
||||
|
||||
translate([-VGA_HOLDER_HEIGHT/2+PCB_OFFSET-PCB_THICKNESS,100-(18.21+(49.05-18.21)/2)-12.5,-VGA_HOLDER_DEPTH/2]) color("black") rotate([0,0,90]) cylinder (h = 10, r1 = 1.6, r2 = 1.6, center = true);
|
||||
translate([-VGA_HOLDER_HEIGHT/2+PCB_OFFSET-PCB_THICKNESS,100-(18.21+(49.05-18.21)/2)+12.5,-VGA_HOLDER_DEPTH/2]) color("black") rotate([0,0,90]) cylinder (h = 10, r1 = 1.6, r2 = 1.6, center = true);
|
||||
}
|
||||
|
||||
HDMI_HOLDER_HEIGHT=8;
|
||||
HDMI_HOLDER_WIDTH=18;
|
||||
HDMI_HOLDER_DEPTH=2;
|
||||
module hdmi_pos() {
|
||||
translate([-1-HDMI_HOLDER_HEIGHT/2+PCB_OFFSET-PCB_THICKNESS,100-(53.3+(71.3-53.3)/2),-HDMI_HOLDER_DEPTH/2]) cube ([2+HDMI_HOLDER_HEIGHT, 2+HDMI_HOLDER_WIDTH, HDMI_HOLDER_DEPTH], center = true);
|
||||
}
|
||||
module hdmi_neg() {
|
||||
translate([-0.499-HDMI_HOLDER_HEIGHT/2+PCB_OFFSET-PCB_THICKNESS,100-(53.3+(71.3-53.3)/2),-HDMI_HOLDER_DEPTH/2]) cube ([1.001+HDMI_HOLDER_HEIGHT, HDMI_HOLDER_WIDTH, 5+0.001], center = true);
|
||||
}
|
||||
|
||||
//pcb();
|
||||
|
||||
module complete() {
|
||||
difference() {
|
||||
union() {
|
||||
backplate();
|
||||
holders();
|
||||
usb_pos();
|
||||
vga_pos();
|
||||
hdmi_pos();
|
||||
}
|
||||
union() {
|
||||
usb_neg();
|
||||
vga_neg();
|
||||
hdmi_neg();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
complete();
|
|
@ -0,0 +1,9 @@
|
|||
Hello,
|
||||
|
||||
About the DFA status:
|
||||
|
||||
(1) Molex 87831-1420 does not include a 'peg' and so does not need the hole for it if I understand the datasheet correctly; I think this is the issue raised? See <https://www.molex.com/pdm_docs/sd/878311420_sd.pdf> page 10 for the mention of a lack of 'peg', the 'peg' is pointed out in the picture on page 1.
|
||||
|
||||
(2) The measure in the schematics seem to be for the connector-side pins (the VGA plug), not for the solder-side pins. Datasgheet <https://cdn.amphenol-icc.com/media/wysiwyg/files/drawing/l77hde15sd1ch4fvga.pdf> has a 'recommended PCB layout' that shows the pins at 2.54mm interval.
|
||||
|
||||
(3) Yes, some files were left out, my bad, new upload
|
|
@ -1,12 +1,12 @@
|
|||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.0.2+dfsg1-1~bpo9+1*
|
||||
G04 #@! TF.CreationDate,2022-02-05T15:09:40+01:00*
|
||||
G04 #@! TF.CreationDate,2022-02-11T12:22:13+01:00*
|
||||
G04 #@! TF.ProjectId,nubus-to-ztex,6e756275-732d-4746-9f2d-7a7465782e6b,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Copper,L4,Bot*
|
||||
G04 #@! TF.FilePolarity,Positive*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Sat Feb 5 15:09:40 2022*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Fri Feb 11 12:22:13 2022*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.0.2+dfsg1-1~bpo9+1*
|
||||
G04 #@! TF.CreationDate,2022-02-05T15:09:40+01:00*
|
||||
G04 #@! TF.CreationDate,2022-02-11T12:22:13+01:00*
|
||||
G04 #@! TF.ProjectId,nubus-to-ztex,6e756275-732d-4746-9f2d-7a7465782e6b,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Profile,NP*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Sat Feb 5 15:09:40 2022*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Fri Feb 11 12:22:13 2022*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.0.2+dfsg1-1~bpo9+1*
|
||||
G04 #@! TF.CreationDate,2022-02-05T15:09:40+01:00*
|
||||
G04 #@! TF.CreationDate,2022-02-11T12:22:13+01:00*
|
||||
G04 #@! TF.ProjectId,nubus-to-ztex,6e756275-732d-4746-9f2d-7a7465782e6b,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Copper,L1,Top*
|
||||
G04 #@! TF.FilePolarity,Positive*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Sat Feb 5 15:09:40 2022*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Fri Feb 11 12:22:13 2022*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.0.2+dfsg1-1~bpo9+1*
|
||||
G04 #@! TF.CreationDate,2022-02-05T15:09:40+01:00*
|
||||
G04 #@! TF.CreationDate,2022-02-11T12:22:13+01:00*
|
||||
G04 #@! TF.ProjectId,nubus-to-ztex,6e756275-732d-4746-9f2d-7a7465782e6b,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Soldermask,Top*
|
||||
G04 #@! TF.FilePolarity,Negative*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Sat Feb 5 15:09:40 2022*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Fri Feb 11 12:22:13 2022*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.0.2+dfsg1-1~bpo9+1*
|
||||
G04 #@! TF.CreationDate,2022-02-05T15:09:40+01:00*
|
||||
G04 #@! TF.CreationDate,2022-02-11T12:22:13+01:00*
|
||||
G04 #@! TF.ProjectId,nubus-to-ztex,6e756275-732d-4746-9f2d-7a7465782e6b,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Paste,Top*
|
||||
G04 #@! TF.FilePolarity,Positive*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Sat Feb 5 15:09:40 2022*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Fri Feb 11 12:22:13 2022*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.0.2+dfsg1-1~bpo9+1*
|
||||
G04 #@! TF.CreationDate,2022-02-05T15:09:40+01:00*
|
||||
G04 #@! TF.CreationDate,2022-02-11T12:22:13+01:00*
|
||||
G04 #@! TF.ProjectId,nubus-to-ztex,6e756275-732d-4746-9f2d-7a7465782e6b,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Legend,Top*
|
||||
G04 #@! TF.FilePolarity,Positive*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Sat Feb 5 15:09:40 2022*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Fri Feb 11 12:22:13 2022*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.0.2+dfsg1-1~bpo9+1*
|
||||
G04 #@! TF.CreationDate,2022-02-05T15:09:40+01:00*
|
||||
G04 #@! TF.CreationDate,2022-02-11T12:22:13+01:00*
|
||||
G04 #@! TF.ProjectId,nubus-to-ztex,6e756275-732d-4746-9f2d-7a7465782e6b,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Copper,L2,Inr*
|
||||
G04 #@! TF.FilePolarity,Positive*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Sat Feb 5 15:09:40 2022*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Fri Feb 11 12:22:13 2022*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.0.2+dfsg1-1~bpo9+1*
|
||||
G04 #@! TF.CreationDate,2022-02-05T15:09:40+01:00*
|
||||
G04 #@! TF.CreationDate,2022-02-11T12:22:13+01:00*
|
||||
G04 #@! TF.ProjectId,nubus-to-ztex,6e756275-732d-4746-9f2d-7a7465782e6b,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Copper,L3,Inr*
|
||||
G04 #@! TF.FilePolarity,Positive*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Sat Feb 5 15:09:40 2022*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2+dfsg1-1~bpo9+1) date Fri Feb 11 12:22:13 2022*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
%!PS-Adobe-3.0
|
||||
%%Creator: PCBNEW
|
||||
%%CreationDate: Sat Feb 5 15:09:37 2022
|
||||
%%CreationDate: Fri Feb 11 12:24:04 2022
|
||||
%%Title: /home/dolbeau/MAC/NuBusFPGA/nubus-to-ztex/nubus-to-ztex-NPTH-drl_map.ps
|
||||
%%Pages: 1
|
||||
%%PageOrder: Ascend
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
M48
|
||||
;DRILL file {KiCad 5.0.2+dfsg1-1~bpo9+1} date Sat Feb 5 15:09:36 2022
|
||||
;DRILL file {KiCad 5.0.2+dfsg1-1~bpo9+1} date Fri Feb 11 12:24:04 2022
|
||||
;FORMAT={-:-/ absolute / inch / decimal}
|
||||
FMAT,2
|
||||
INCH,TZ
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
%!PS-Adobe-3.0
|
||||
%%Creator: PCBNEW
|
||||
%%CreationDate: Sat Feb 5 15:09:37 2022
|
||||
%%CreationDate: Fri Feb 11 12:24:04 2022
|
||||
%%Title: /home/dolbeau/MAC/NuBusFPGA/nubus-to-ztex/nubus-to-ztex-PTH-drl_map.ps
|
||||
%%Pages: 1
|
||||
%%PageOrder: Ascend
|
||||
|
@ -1397,104 +1397,6 @@ newpath
|
|||
90545.1 46713.9 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 54058.1 moveto
|
||||
26171.5 54245.7 lineto
|
||||
25983.9 54433.2 lineto
|
||||
25796.4 54245.7 lineto
|
||||
25983.9 54058.1 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 53224.5 moveto
|
||||
26171.5 53412.1 lineto
|
||||
25983.9 53599.7 lineto
|
||||
25796.4 53412.1 lineto
|
||||
25983.9 53224.5 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 52390.9 moveto
|
||||
26171.5 52578.5 lineto
|
||||
25983.9 52766.1 lineto
|
||||
25796.4 52578.5 lineto
|
||||
25983.9 52390.9 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 51557.3 moveto
|
||||
26171.5 51744.9 lineto
|
||||
25983.9 51932.5 lineto
|
||||
25796.4 51744.9 lineto
|
||||
25983.9 51557.3 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 50723.7 moveto
|
||||
26171.5 50911.3 lineto
|
||||
25983.9 51098.9 lineto
|
||||
25796.4 50911.3 lineto
|
||||
25983.9 50723.7 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 49890.2 moveto
|
||||
26171.5 50077.7 lineto
|
||||
25983.9 50265.3 lineto
|
||||
25796.4 50077.7 lineto
|
||||
25983.9 49890.2 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 49056.6 moveto
|
||||
26171.5 49244.1 lineto
|
||||
25983.9 49431.7 lineto
|
||||
25796.4 49244.1 lineto
|
||||
25983.9 49056.6 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 54058.1 moveto
|
||||
27005.1 54245.7 lineto
|
||||
26817.5 54433.2 lineto
|
||||
26630 54245.7 lineto
|
||||
26817.5 54058.1 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 53224.5 moveto
|
||||
27005.1 53412.1 lineto
|
||||
26817.5 53599.7 lineto
|
||||
26630 53412.1 lineto
|
||||
26817.5 53224.5 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 52390.9 moveto
|
||||
27005.1 52578.5 lineto
|
||||
26817.5 52766.1 lineto
|
||||
26630 52578.5 lineto
|
||||
26817.5 52390.9 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 51557.3 moveto
|
||||
27005.1 51744.9 lineto
|
||||
26817.5 51932.5 lineto
|
||||
26630 51744.9 lineto
|
||||
26817.5 51557.3 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 50723.7 moveto
|
||||
27005.1 50911.3 lineto
|
||||
26817.5 51098.9 lineto
|
||||
26630 50911.3 lineto
|
||||
26817.5 50723.7 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 49890.2 moveto
|
||||
27005.1 50077.7 lineto
|
||||
26817.5 50265.3 lineto
|
||||
26630 50077.7 lineto
|
||||
26817.5 49890.2 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 49056.6 moveto
|
||||
27005.1 49244.1 lineto
|
||||
26817.5 49431.7 lineto
|
||||
26630 49244.1 lineto
|
||||
26817.5 49056.6 lineto
|
||||
poly0
|
||||
newpath
|
||||
68343.1 69187.9 moveto
|
||||
68530.7 69375.5 lineto
|
||||
68343.1 69563 lineto
|
||||
|
@ -1593,6 +1495,104 @@ newpath
|
|||
73344.7 68354.3 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 54058.1 moveto
|
||||
26171.5 54245.7 lineto
|
||||
25983.9 54433.2 lineto
|
||||
25796.4 54245.7 lineto
|
||||
25983.9 54058.1 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 53224.5 moveto
|
||||
26171.5 53412.1 lineto
|
||||
25983.9 53599.7 lineto
|
||||
25796.4 53412.1 lineto
|
||||
25983.9 53224.5 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 52390.9 moveto
|
||||
26171.5 52578.5 lineto
|
||||
25983.9 52766.1 lineto
|
||||
25796.4 52578.5 lineto
|
||||
25983.9 52390.9 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 51557.3 moveto
|
||||
26171.5 51744.9 lineto
|
||||
25983.9 51932.5 lineto
|
||||
25796.4 51744.9 lineto
|
||||
25983.9 51557.3 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 50723.7 moveto
|
||||
26171.5 50911.3 lineto
|
||||
25983.9 51098.9 lineto
|
||||
25796.4 50911.3 lineto
|
||||
25983.9 50723.7 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 49890.2 moveto
|
||||
26171.5 50077.7 lineto
|
||||
25983.9 50265.3 lineto
|
||||
25796.4 50077.7 lineto
|
||||
25983.9 49890.2 lineto
|
||||
poly0
|
||||
newpath
|
||||
25983.9 49056.6 moveto
|
||||
26171.5 49244.1 lineto
|
||||
25983.9 49431.7 lineto
|
||||
25796.4 49244.1 lineto
|
||||
25983.9 49056.6 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 54058.1 moveto
|
||||
27005.1 54245.7 lineto
|
||||
26817.5 54433.2 lineto
|
||||
26630 54245.7 lineto
|
||||
26817.5 54058.1 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 53224.5 moveto
|
||||
27005.1 53412.1 lineto
|
||||
26817.5 53599.7 lineto
|
||||
26630 53412.1 lineto
|
||||
26817.5 53224.5 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 52390.9 moveto
|
||||
27005.1 52578.5 lineto
|
||||
26817.5 52766.1 lineto
|
||||
26630 52578.5 lineto
|
||||
26817.5 52390.9 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 51557.3 moveto
|
||||
27005.1 51744.9 lineto
|
||||
26817.5 51932.5 lineto
|
||||
26630 51744.9 lineto
|
||||
26817.5 51557.3 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 50723.7 moveto
|
||||
27005.1 50911.3 lineto
|
||||
26817.5 51098.9 lineto
|
||||
26630 50911.3 lineto
|
||||
26817.5 50723.7 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 49890.2 moveto
|
||||
27005.1 50077.7 lineto
|
||||
26817.5 50265.3 lineto
|
||||
26630 50077.7 lineto
|
||||
26817.5 49890.2 lineto
|
||||
poly0
|
||||
newpath
|
||||
26817.5 49056.6 moveto
|
||||
27005.1 49244.1 lineto
|
||||
26817.5 49431.7 lineto
|
||||
26630 49244.1 lineto
|
||||
26817.5 49056.6 lineto
|
||||
poly0
|
||||
newpath
|
||||
28551.4 41483.3 moveto
|
||||
28968.2 41066.5 lineto
|
||||
stroke
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
M48
|
||||
;DRILL file {KiCad 5.0.2+dfsg1-1~bpo9+1} date Sat Feb 5 15:09:36 2022
|
||||
;DRILL file {KiCad 5.0.2+dfsg1-1~bpo9+1} date Fri Feb 11 12:24:04 2022
|
||||
;FORMAT={-:-/ absolute / inch / decimal}
|
||||
FMAT,2
|
||||
INCH,TZ
|
||||
|
@ -175,20 +175,6 @@ T4
|
|||
X10.5983Y-3.0146
|
||||
X10.5983Y-3.2114
|
||||
T5
|
||||
X4.5118Y-2.5118
|
||||
X4.5118Y-2.5906
|
||||
X4.5118Y-2.6693
|
||||
X4.5118Y-2.748
|
||||
X4.5118Y-2.8268
|
||||
X4.5118Y-2.9055
|
||||
X4.5118Y-2.9843
|
||||
X4.5906Y-2.5118
|
||||
X4.5906Y-2.5906
|
||||
X4.5906Y-2.6693
|
||||
X4.5906Y-2.748
|
||||
X4.5906Y-2.8268
|
||||
X4.5906Y-2.9055
|
||||
X4.5906Y-2.9843
|
||||
X8.513Y-1.0827
|
||||
X8.513Y-1.1614
|
||||
X8.5917Y-1.0827
|
||||
|
@ -203,6 +189,20 @@ X8.9067Y-1.0827
|
|||
X8.9067Y-1.1614
|
||||
X8.9854Y-1.0827
|
||||
X8.9854Y-1.1614
|
||||
X4.5118Y-2.5118
|
||||
X4.5118Y-2.5906
|
||||
X4.5118Y-2.6693
|
||||
X4.5118Y-2.748
|
||||
X4.5118Y-2.8268
|
||||
X4.5118Y-2.9055
|
||||
X4.5118Y-2.9843
|
||||
X4.5906Y-2.5118
|
||||
X4.5906Y-2.5906
|
||||
X4.5906Y-2.6693
|
||||
X4.5906Y-2.748
|
||||
X4.5906Y-2.8268
|
||||
X4.5906Y-2.9055
|
||||
X4.5906Y-2.9843
|
||||
T6
|
||||
X4.774Y-3.737
|
||||
X4.774Y-3.837
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
### Module positions - created on Sat Feb 5 15:09:58 2022 ###
|
||||
### Module positions - created on Fri Feb 11 12:23:56 2022 ###
|
||||
### Printed by Pcbnew version kicad 5.0.2+dfsg1-1~bpo9+1
|
||||
## Unit = mm, Angle = deg.
|
||||
## Side : bottom
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Drill report for /home/dolbeau/MAC/NuBusFPGA/nubus-to-ztex/nubus-to-ztex.kicad_pcb
|
||||
Created on Sat Feb 5 15:09:39 2022
|
||||
Created on Fri Feb 11 12:24:06 2022
|
||||
|
||||
Copper Layer Stackup:
|
||||
=============================================================
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
### Module positions - created on Sat Feb 5 15:09:58 2022 ###
|
||||
### Module positions - created on Fri Feb 11 12:23:56 2022 ###
|
||||
### Printed by Pcbnew version kicad 5.0.2+dfsg1-1~bpo9+1
|
||||
## Unit = mm, Angle = deg.
|
||||
## Side : top
|
||||
|
|
|
@ -15,9 +15,13 @@
|
|||
(1 In1.Cu signal)
|
||||
(2 In2.Cu signal)
|
||||
(31 B.Cu signal)
|
||||
(32 B.Adhes user)
|
||||
(33 F.Adhes user)
|
||||
(34 B.Paste user)
|
||||
(35 F.Paste user)
|
||||
(36 B.SilkS user)
|
||||
(37 F.SilkS user)
|
||||
(38 B.Mask user)
|
||||
(39 F.Mask user)
|
||||
(40 Dwgs.User user)
|
||||
(41 Cmts.User user)
|
||||
|
@ -27,6 +31,7 @@
|
|||
(45 Margin user)
|
||||
(46 B.CrtYd user)
|
||||
(47 F.CrtYd user)
|
||||
(48 B.Fab user)
|
||||
(49 F.Fab user)
|
||||
)
|
||||
|
||||
|
@ -59,7 +64,7 @@
|
|||
(aux_axis_origin 0 0)
|
||||
(visible_elements FFFFFF7F)
|
||||
(pcbplotparams
|
||||
(layerselection 0x010a8_ffffffff)
|
||||
(layerselection 0x010fc_ffffffff)
|
||||
(usegerberextensions false)
|
||||
(usegerberattributes false)
|
||||
(usegerberadvancedattributes false)
|
||||
|
@ -21104,7 +21109,7 @@
|
|||
(segment (start 185.3125 71.8875) (end 184.7 72.5) (width 0.1524) (layer F.Cu) (net 230))
|
||||
(segment (start 156.4375 22) (end 158.7125 22) (width 0.1524) (layer F.Cu) (net 231))
|
||||
|
||||
(zone (net 1) (net_name GND) (layer In1.Cu) (tstamp 620A815F) (hatch edge 0.508)
|
||||
(zone (net 1) (net_name GND) (layer In1.Cu) (tstamp 620AA96B) (hatch edge 0.508)
|
||||
(connect_pads (clearance 0.508))
|
||||
(min_thickness 0.254)
|
||||
(fill yes (arc_segments 16) (thermal_gap 0.508) (thermal_bridge_width 0.508))
|
||||
|
@ -22116,7 +22121,7 @@
|
|||
)
|
||||
)
|
||||
)
|
||||
(zone (net 3) (net_name +3V3) (layer In2.Cu) (tstamp 620A815C) (hatch edge 0.508)
|
||||
(zone (net 3) (net_name +3V3) (layer In2.Cu) (tstamp 620AA968) (hatch edge 0.508)
|
||||
(connect_pads (clearance 0.508))
|
||||
(min_thickness 0.254)
|
||||
(fill yes (arc_segments 16) (thermal_gap 0.508) (thermal_bridge_width 0.508))
|
||||
|
@ -22756,7 +22761,7 @@
|
|||
)
|
||||
)
|
||||
)
|
||||
(zone (net 1) (net_name GND) (layer F.Cu) (tstamp 620A8159) (hatch edge 0.508)
|
||||
(zone (net 1) (net_name GND) (layer F.Cu) (tstamp 620AA965) (hatch edge 0.508)
|
||||
(connect_pads (clearance 0.508))
|
||||
(min_thickness 0.254)
|
||||
(fill yes (arc_segments 16) (thermal_gap 0.508) (thermal_bridge_width 0.508))
|
||||
|
@ -24812,7 +24817,7 @@
|
|||
)
|
||||
)
|
||||
)
|
||||
(zone (net 1) (net_name GND) (layer B.Cu) (tstamp 620A8156) (hatch edge 0.508)
|
||||
(zone (net 1) (net_name GND) (layer B.Cu) (tstamp 620AA962) (hatch edge 0.508)
|
||||
(connect_pads (clearance 0.508))
|
||||
(min_thickness 0.254)
|
||||
(fill yes (arc_segments 16) (thermal_gap 0.508) (thermal_bridge_width 0.508))
|
||||
|
|
|
@ -15,9 +15,13 @@
|
|||
(1 In1.Cu signal)
|
||||
(2 In2.Cu signal)
|
||||
(31 B.Cu signal)
|
||||
(32 B.Adhes user)
|
||||
(33 F.Adhes user)
|
||||
(34 B.Paste user)
|
||||
(35 F.Paste user)
|
||||
(36 B.SilkS user)
|
||||
(37 F.SilkS user)
|
||||
(38 B.Mask user)
|
||||
(39 F.Mask user)
|
||||
(40 Dwgs.User user)
|
||||
(41 Cmts.User user)
|
||||
|
@ -27,6 +31,7 @@
|
|||
(45 Margin user)
|
||||
(46 B.CrtYd user)
|
||||
(47 F.CrtYd user)
|
||||
(48 B.Fab user)
|
||||
(49 F.Fab user)
|
||||
)
|
||||
|
||||
|
@ -59,7 +64,7 @@
|
|||
(aux_axis_origin 0 0)
|
||||
(visible_elements FFFFFF7F)
|
||||
(pcbplotparams
|
||||
(layerselection 0x010a8_ffffffff)
|
||||
(layerselection 0x010fc_ffffffff)
|
||||
(usegerberextensions false)
|
||||
(usegerberattributes false)
|
||||
(usegerberadvancedattributes false)
|
||||
|
@ -21104,7 +21109,7 @@
|
|||
(segment (start 185.3125 71.8875) (end 184.7 72.5) (width 0.1524) (layer F.Cu) (net 230))
|
||||
(segment (start 156.4375 22) (end 158.7125 22) (width 0.1524) (layer F.Cu) (net 231))
|
||||
|
||||
(zone (net 1) (net_name GND) (layer In1.Cu) (tstamp 620A6580) (hatch edge 0.508)
|
||||
(zone (net 1) (net_name GND) (layer In1.Cu) (tstamp 620AA96B) (hatch edge 0.508)
|
||||
(connect_pads (clearance 0.508))
|
||||
(min_thickness 0.254)
|
||||
(fill yes (arc_segments 16) (thermal_gap 0.508) (thermal_bridge_width 0.508))
|
||||
|
@ -22116,7 +22121,7 @@
|
|||
)
|
||||
)
|
||||
)
|
||||
(zone (net 3) (net_name +3V3) (layer In2.Cu) (tstamp 620A657D) (hatch edge 0.508)
|
||||
(zone (net 3) (net_name +3V3) (layer In2.Cu) (tstamp 620AA968) (hatch edge 0.508)
|
||||
(connect_pads (clearance 0.508))
|
||||
(min_thickness 0.254)
|
||||
(fill yes (arc_segments 16) (thermal_gap 0.508) (thermal_bridge_width 0.508))
|
||||
|
@ -22756,7 +22761,7 @@
|
|||
)
|
||||
)
|
||||
)
|
||||
(zone (net 1) (net_name GND) (layer F.Cu) (tstamp 61FD3B36) (hatch edge 0.508)
|
||||
(zone (net 1) (net_name GND) (layer F.Cu) (tstamp 620AA965) (hatch edge 0.508)
|
||||
(connect_pads (clearance 0.508))
|
||||
(min_thickness 0.254)
|
||||
(fill yes (arc_segments 16) (thermal_gap 0.508) (thermal_bridge_width 0.508))
|
||||
|
@ -24812,7 +24817,7 @@
|
|||
)
|
||||
)
|
||||
)
|
||||
(zone (net 1) (net_name GND) (layer B.Cu) (tstamp 61FD3B37) (hatch edge 0.508)
|
||||
(zone (net 1) (net_name GND) (layer B.Cu) (tstamp 620AA962) (hatch edge 0.508)
|
||||
(connect_pads (clearance 0.508))
|
||||
(min_thickness 0.254)
|
||||
(fill yes (arc_segments 16) (thermal_gap 0.508) (thermal_bridge_width 0.508))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## Footprint report - date Sat Feb 5 15:10:10 2022
|
||||
## Footprint report - date Fri Feb 11 12:24:13 2022
|
||||
## Created by Pcbnew version kicad 5.0.2+dfsg1-1~bpo9+1
|
||||
## Unit = mm, Angle = deg.
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<export version="D">
|
||||
<design>
|
||||
<source>/home/dolbeau/MAC/NuBusFPGA/nubus-to-ztex/nubus-to-ztex.sch</source>
|
||||
<date>Sat Feb 5 15:10:52 2022</date>
|
||||
<date>Fri Feb 11 12:24:26 2022</date>
|
||||
<tool>Eeschema 5.0.2+dfsg1-1~bpo9+1</tool>
|
||||
<sheet number="1" name="/" tstamps="/">
|
||||
<title_block>
|
||||
|
|
Binary file not shown.
|
@ -1,8 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
GERBER_FILES="nubus-to-ztex-B.Cu.gbr nubus-to-ztex-Edge.Cuts.gbr nubus-to-ztex-F.Cu.gbr nubus-to-ztex-F.Mask.gbr nubus-to-ztex-F.Paste.gbr nubus-to-ztex-F.SilkS.gbr nubus-to-ztex-In1.Cu.gbr nubus-to-ztex-In2.Cu.gbr"
|
||||
|
||||
# nubus-to-ztex-B.Mask.gbr nubus-to-ztex-B.Paste.gbr nubus-to-ztex-B.SilkS.gbr
|
||||
GERBER_FILES="nubus-to-ztex-B.Cu.gbr nubus-to-ztex-B.Mask.gbr nubus-to-ztex-B.Paste.gbr nubus-to-ztex-B.SilkS.gbr nubus-to-ztex-Edge.Cuts.gbr nubus-to-ztex-F.Cu.gbr nubus-to-ztex-F.Mask.gbr nubus-to-ztex-F.Paste.gbr nubus-to-ztex-F.SilkS.gbr nubus-to-ztex-In1.Cu.gbr nubus-to-ztex-In2.Cu.gbr"
|
||||
|
||||
POS_FILES="nubus-to-ztex-top.pos"
|
||||
# nubus-to-ztex-bottom.pos
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue