mirror of
https://github.com/rdolbeau/NuBusFPGA.git
synced 2024-06-01 11:42:13 +00:00
update to first tested version
This commit is contained in:
parent
de1aaf8161
commit
62b2c48b32
BIN
Pictures/NuBusFPGA.jpg
Normal file
BIN
Pictures/NuBusFPGA.jpg
Normal file
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.
|
||||
|
|
BIN
nubus-to-ztex-gateware/ConsoleTest/.AppleDouble/.Parent
Normal file
BIN
nubus-to-ztex-gateware/ConsoleTest/.AppleDouble/.Parent
Normal file
Binary file not shown.
BIN
nubus-to-ztex-gateware/ConsoleTest/.AppleDouble/ConsoleTest
Normal file
BIN
nubus-to-ztex-gateware/ConsoleTest/.AppleDouble/ConsoleTest
Normal file
Binary file not shown.
BIN
nubus-to-ztex-gateware/ConsoleTest/.AppleDouble/HelloWorld.c
Normal file
BIN
nubus-to-ztex-gateware/ConsoleTest/.AppleDouble/HelloWorld.c
Normal file
Binary file not shown.
BIN
nubus-to-ztex-gateware/ConsoleTest/ConsoleTest
Normal file
BIN
nubus-to-ztex-gateware/ConsoleTest/ConsoleTest
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1
nubus-to-ztex-gateware/ConsoleTest/HelloWorld.c
Normal file
1
nubus-to-ztex-gateware/ConsoleTest/HelloWorld.c
Normal file
|
@ -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
|
||||
|
|
100
nubus-to-ztex-gateware/DeclROM/NuBusFPGAPrimaryInit_Primary.c
Normal file
100
nubus-to-ztex-gateware/DeclROM/NuBusFPGAPrimaryInit_Primary.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
38
nubus-to-ztex-gateware/DeclROM/NuBusFPGASecondaryInit.s
Normal file
38
nubus-to-ztex-gateware/DeclROM/NuBusFPGASecondaryInit.s
Normal file
|
@ -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 */
|
||||
|
BIN
nubus-to-ztex-gateware/DeclROM/goblinfb.zip
Normal file
BIN
nubus-to-ztex-gateware/DeclROM/goblinfb.zip
Normal file
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 */
|
||||
|
|
1
nubus-to-ztex-gateware/DepVideoEqu.a
Executable file
1
nubus-to-ztex-gateware/DepVideoEqu.a
Executable file
|
@ -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
nubus-to-ztex-gateware/NuBusFPGADrvr.a
Normal file
0
nubus-to-ztex-gateware/NuBusFPGADrvr.a
Normal file
1
nubus-to-ztex-gateware/NuBusFPGAPrimaryInit.a
Normal file
1
nubus-to-ztex-gateware/NuBusFPGAPrimaryInit.a
Normal file
|
@ -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
|
0
nubus-to-ztex-gateware/NuBusFPGASecondaryInit.a
Normal file
0
nubus-to-ztex-gateware/NuBusFPGASecondaryInit.a
Normal file
|
@ -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)
|
||||
);
|
||||
|
||||
|
|
32
nubus-to-ztex-gateware/nubus_cpu_wb.py
Normal file
32
nubus-to-ztex-gateware/nubus_cpu_wb.py
Normal file
|
@ -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: ???
|
130
nubus-to-ztex-gateware/nubus_fpga_V1_0_timings.xdc
Normal file
130
nubus-to-ztex-gateware/nubus_fpga_V1_0_timings.xdc
Normal file
|
@ -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}]
|
55
nubus-to-ztex-gateware/nubus_master_tst.py
Normal file
55
nubus-to-ztex-gateware/nubus_master_tst.py
Normal file
|
@ -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():
|
||||
|
|
15
nubus-to-ztex-gateware/post_process_timings.sh
Executable file
15
nubus-to-ztex-gateware/post_process_timings.sh
Executable file
|
@ -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
|
||||
|
||||
|
1
nubus-to-ztex-gateware/rom.a
Normal file
1
nubus-to-ztex-gateware/rom.a
Normal file
File diff suppressed because one or more lines are too long
139
nubus-to-ztex-gateware/sdram_init.py
Normal file
139
nubus-to-ztex-gateware/sdram_init.py
Normal file
|
@ -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")),
|
||||
|
|
BIN
nubus-to-ztex/1727034_seeed_dfareporta172464820220211.xlsx
Normal file
BIN
nubus-to-ztex/1727034_seeed_dfareporta172464820220211.xlsx
Normal file
Binary file not shown.
BIN
nubus-to-ztex/691037.pdf
Normal file
BIN
nubus-to-ztex/691037.pdf
Normal file
Binary file not shown.
158
nubus-to-ztex/N2Z_backplate.scad
Normal file
158
nubus-to-ztex/N2Z_backplate.scad
Normal file
|
@ -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();
|
9
nubus-to-ztex/dfa_reply.txt
Normal file
9
nubus-to-ztex/dfa_reply.txt
Normal file
|
@ -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
Block a user