SPI offloading -> 5x loading speed (needs code cleanup)
This commit is contained in:
parent
b37fc1b846
commit
63febb92c6
@ -80,6 +80,8 @@ DRESULT disk_getinfo(BYTE drv, BYTE page, void *buffer);
|
||||
|
||||
void disk_init(void);
|
||||
|
||||
uint8_t SD_SPI_OFFLOAD;
|
||||
|
||||
/* Will be set to DISK_ERROR if any access on the card fails */
|
||||
enum diskstates { DISK_CHANGED = 0, DISK_REMOVED, DISK_OK, DISK_ERROR };
|
||||
|
||||
|
||||
8
src/ff.c
8
src/ff.c
@ -60,6 +60,7 @@
|
||||
#include "ff.h" /* FatFs declarations */
|
||||
#include "diskio.h" /* Include file for user provided disk functions */
|
||||
#include "uart.h"
|
||||
#include "fpga.h"
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@ -1603,8 +1604,12 @@ FRESULT f_read (
|
||||
cc = btr / SS(fs); /* When left bytes >= SS(fs), */
|
||||
if (cc) { /* Read maximum contiguous sectors directly */
|
||||
if (cc > fp->csect) cc = fp->csect;
|
||||
if(SPI_OFFLOAD) {
|
||||
SD_SPI_OFFLOAD = 1;
|
||||
}
|
||||
if (disk_read(fs->drive, rbuff, sect, (BYTE)cc) != RES_OK)
|
||||
goto fr_error;
|
||||
SD_SPI_OFFLOAD = 0;
|
||||
fp->csect -= (BYTE)(cc - 1);
|
||||
fp->curr_sect += cc - 1;
|
||||
rcnt = cc * SS(fs);
|
||||
@ -1619,10 +1624,13 @@ FRESULT f_read (
|
||||
}
|
||||
}
|
||||
|
||||
SPI_OFFLOAD = 0;
|
||||
return FR_OK;
|
||||
|
||||
fr_error: /* Abort this file due to an unrecoverable error */
|
||||
fp->flag |= FA__ERROR;
|
||||
SPI_OFFLOAD = 0;
|
||||
SD_SPI_OFFLOAD = 0;
|
||||
return FR_RW_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@ -55,6 +55,10 @@ void fpga_init() {
|
||||
DDRD |= _BV(PD3) | _BV(PD4); // PD3, PD4 are outputs
|
||||
|
||||
DDRA = ~_BV(PA3); // PA3 is input <- DONE
|
||||
|
||||
DDRB |= _BV(PB2); // DMA_CTRL preinit
|
||||
PORTB |= _BV(PB2);
|
||||
SPI_OFFLOAD=0;
|
||||
set_cclk(0); // initial clk=0
|
||||
}
|
||||
|
||||
@ -64,7 +68,7 @@ int fpga_get_done(void) {
|
||||
|
||||
void fpga_postinit() {
|
||||
DDRA |= _BV(PA0) | _BV(PA1) | _BV(PA2) | _BV(PA4) | _BV(PA5) | _BV(PA6); // MAPPER+NEXTADDR output
|
||||
DDRB |= _BV(PB2) | _BV(PB1) | _BV(PB0); // turn PB2 into output, enable AVR_BANK
|
||||
DDRB |= _BV(PB1) | _BV(PB0); // turn PB2 into output, enable AVR_BANK
|
||||
DDRD |= _BV(PD7); // turn PD7 into output
|
||||
}
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ void set_avr_addr_en(uint8_t val);
|
||||
void set_avr_mapper(uint8_t val);
|
||||
void set_avr_bank(uint8_t val);
|
||||
|
||||
uint8_t SPI_OFFLOAD;
|
||||
|
||||
#define FPGA_TEST_TOKEN (0xa5)
|
||||
|
||||
|
||||
51
src/main.c
51
src/main.c
@ -48,6 +48,7 @@
|
||||
#include "spi.h"
|
||||
#include "avrcompat.h"
|
||||
#include "filetypes.h"
|
||||
#include "sdcard.h"
|
||||
|
||||
void writetest(void) {
|
||||
// HERE BE LIONS, GET IN THE CAR
|
||||
@ -116,12 +117,6 @@ void poison_memory(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void avr_goto_addr(const uint32_t val) {
|
||||
AVR_ADDR_RESET();
|
||||
for(uint32_t i=0; i<val; i++) {
|
||||
AVR_NEXTADDR();
|
||||
}
|
||||
}
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1)
|
||||
int main(void) __attribute__((OS_main));
|
||||
#endif
|
||||
@ -189,7 +184,41 @@ restart:
|
||||
uint16_t mem_dir_id = sram_readshort(SRAM_DIRID);
|
||||
uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
|
||||
|
||||
|
||||
while(0) {
|
||||
SD_SPI_OFFLOAD=1;
|
||||
sd_read(0, file_buf, 32L, 1);
|
||||
// sram_writeblock((void*)file_buf, 0, 0x200);
|
||||
sram_hexdump(0,0x10);
|
||||
uart_putc('+');
|
||||
}
|
||||
/* here be strange monsters */
|
||||
while(0){
|
||||
// uint16_t hurdur1 = 0, hurdur2 = 0;
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
PORTB |= _BV(PB2);
|
||||
DDRB |= _BV(PB2);
|
||||
PORTB &= ~_BV(PB2);
|
||||
DDRB &= ~_BV(PB7); // tristate SCK
|
||||
PORTB |= _BV(PB2);
|
||||
DDRB &= ~_BV(PB2);
|
||||
while(!(PINB & _BV(PB2))) {
|
||||
}
|
||||
DDRB |= _BV(PB7);
|
||||
_delay_ms(1);
|
||||
// dprintf("hurdur1=%d hurdur2=%d\n", hurdur1, hurdur2);
|
||||
}
|
||||
if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id)) {
|
||||
uint16_t curr_dir_id = scan_dir(fs_path, 0, 0); // generate files footprint
|
||||
dprintf("curr dir id = %x\n", curr_dir_id);
|
||||
@ -207,7 +236,7 @@ restart:
|
||||
save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR);
|
||||
save_sram((uint8_t*)"/sd2snes/sd2snes.dir", direndaddr-(SRAM_DIR_ADDR), SRAM_DIR_ADDR);
|
||||
dprintf("done\n");
|
||||
sram_hexdump(SRAM_DB_ADDR, 0x400);
|
||||
// sram_hexdump(SRAM_DB_ADDR, 0x400);
|
||||
} else {
|
||||
dprintf("saved dir id = %x\n", saved_dir_id);
|
||||
dprintf("different card, consistent db, loading db...\n");
|
||||
@ -229,10 +258,14 @@ restart:
|
||||
|
||||
led_pwm();
|
||||
|
||||
// sram_hexdump(0, 0x200);
|
||||
uart_putc('(');
|
||||
load_rom((uint8_t*)"/sd2snes/menu.bin");
|
||||
set_rom_mask(0x3fffff); // force mirroring off
|
||||
uart_putc(')');
|
||||
uart_putcrlf();
|
||||
// sram_hexdump(0, 0x200);
|
||||
// save_sram((uint8_t*)"/sd2snes/dump", 65536, 0);
|
||||
|
||||
sram_writebyte(0, SRAM_CMD_ADDR);
|
||||
|
||||
@ -256,6 +289,7 @@ restart:
|
||||
set_avr_ena(0);
|
||||
dprintf("Selected name: %s\n", file_lfn);
|
||||
load_rom(file_lfn);
|
||||
// save_sram((uint8_t*)"/sd2snes/test.smc", romprops.romsize_bytes, 0);
|
||||
if(romprops.ramsize_bytes) {
|
||||
strcpy(strrchr((char*)file_lfn, (int)'.'), ".srm");
|
||||
dprintf("SRM file: %s\n", file_lfn);
|
||||
@ -281,7 +315,6 @@ restart:
|
||||
uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0;
|
||||
uint16_t reset_count=0;
|
||||
while(fpga_test() == FPGA_TEST_TOKEN) {
|
||||
dprintf("%02X\n", fpga_test());
|
||||
snes_reset_now=get_snes_reset();
|
||||
if(snes_reset_now) {
|
||||
if(!snes_reset_prev) {
|
||||
|
||||
15
src/memory.c
15
src/memory.c
@ -124,7 +124,7 @@ void sram_writeblock(void* buf, uint32_t addr, uint16_t size) {
|
||||
}
|
||||
|
||||
uint32_t load_rom(uint8_t* filename) {
|
||||
uint8_t dummy;
|
||||
// uint8_t dummy;
|
||||
set_avr_bank(0);
|
||||
UINT bytes_read;
|
||||
DWORD filesize;
|
||||
@ -132,18 +132,25 @@ uint32_t load_rom(uint8_t* filename) {
|
||||
file_open(filename, FA_READ);
|
||||
filesize = file_handle.fsize;
|
||||
smc_id(&romprops);
|
||||
dprintf("no nervous breakdown beyond this point! or else!\n");
|
||||
if(file_res) {
|
||||
uart_putc('?');
|
||||
uart_putc(0x30+file_res);
|
||||
return 0;
|
||||
}
|
||||
f_lseek(&file_handle, romprops.offset);
|
||||
spi_none();
|
||||
for(;;) {
|
||||
SPI_OFFLOAD=1;
|
||||
spi_none();
|
||||
bytes_read = file_read();
|
||||
spi_none();
|
||||
if (file_res || !bytes_read) break;
|
||||
spi_fpga();
|
||||
if(!(count++ % 8)) {
|
||||
// toggle_busy_led();
|
||||
bounce_busy_led();
|
||||
uart_putc('.');
|
||||
}
|
||||
/* spi_fpga();
|
||||
spiTransferByte(0x91); // write w/ increment
|
||||
if(!(count++ % 8)) {
|
||||
// toggle_busy_led();
|
||||
@ -156,7 +163,7 @@ uint32_t load_rom(uint8_t* filename) {
|
||||
loop_until_bit_is_set(SPSR, SPIF);
|
||||
dummy = SPDR;
|
||||
}
|
||||
spiTransferByte(0x00); // dummy tx for increment+write pulse
|
||||
spiTransferByte(0x00); // dummy tx for increment+write pulse */
|
||||
}
|
||||
file_close();
|
||||
spi_none();
|
||||
|
||||
48
src/sdcard.c
48
src/sdcard.c
@ -60,6 +60,7 @@
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <util/crc16.h>
|
||||
#include <util/delay.h>
|
||||
#include "config.h"
|
||||
#include "avrcompat.h"
|
||||
#include "crc7.h"
|
||||
@ -308,6 +309,8 @@ static void sdInit(const uint8_t card) {
|
||||
uint8_t i;
|
||||
uint16_t counter;
|
||||
|
||||
SD_SPI_OFFLOAD = 0;
|
||||
|
||||
counter = 0xffff;
|
||||
do {
|
||||
// Prepare for ACMD, send CMD55: APP_CMD
|
||||
@ -557,24 +560,46 @@ DRESULT sd_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) {
|
||||
|
||||
// Get data
|
||||
crc = 0;
|
||||
// Initiate data exchange over SPI
|
||||
SPDR = 0xff;
|
||||
|
||||
for (i=0; i<512; i++) {
|
||||
// Wait until data has been received
|
||||
loop_until_bit_is_set(SPSR, SPIF);
|
||||
tmp = SPDR;
|
||||
// Transmit the next byte while we store the current one
|
||||
if(SD_SPI_OFFLOAD) {
|
||||
// uart_putc('O');
|
||||
PORTB |= _BV(PB2);
|
||||
DDRB |= _BV(PB2);
|
||||
PORTB &= ~_BV(PB2);
|
||||
PORTB |= _BV(PB2);
|
||||
PORTB &= ~_BV(PB7);
|
||||
DDRB &= ~_BV(PB7); // tristate SCK
|
||||
// SPCR=0;
|
||||
DDRB &= ~_BV(PB2);
|
||||
_delay_us(1);
|
||||
loop_until_bit_is_set(PINB, PB2);
|
||||
DDRB |= _BV(PB2);
|
||||
// SPCR=0b01010000;
|
||||
SD_SPI_OFFLOAD = 0;
|
||||
deselectCard(drv);
|
||||
DDRB |= _BV(PB7);
|
||||
return RES_OK;
|
||||
SPDR = 0xff;
|
||||
|
||||
*(buffer++) = tmp;
|
||||
} else {
|
||||
// Initiate data exchange over SPI
|
||||
SPDR = 0xff;
|
||||
|
||||
for (i=0; i<512; i++) {
|
||||
// Wait until data has been received
|
||||
loop_until_bit_is_set(SPSR, SPIF);
|
||||
tmp = SPDR;
|
||||
// Transmit the next byte while we store the current one
|
||||
SPDR = 0xff;
|
||||
|
||||
*(buffer++) = tmp;
|
||||
#ifdef CONFIG_SD_DATACRC
|
||||
crc = _crc_xmodem_update(crc, tmp);
|
||||
crc = _crc_xmodem_update(crc, tmp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// Wait until the first CRC byte is received
|
||||
loop_until_bit_is_set(SPSR, SPIF);
|
||||
|
||||
|
||||
// Check CRC
|
||||
recvcrc = (SPDR << 8) + spiTransferByte(0xff);
|
||||
#ifdef CONFIG_SD_DATACRC
|
||||
@ -586,7 +611,6 @@ DRESULT sd_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
deselectCard(drv);
|
||||
|
||||
@ -38,7 +38,13 @@ module avr_cmd(
|
||||
input endmessage,
|
||||
input startmessage,
|
||||
output [23:0] saveram_mask_out,
|
||||
output [23:0] rom_mask_out
|
||||
output [23:0] rom_mask_out,
|
||||
|
||||
// SPI "DMA" extension
|
||||
input spi_dma_ovr,
|
||||
input spi_dma_nextaddr,
|
||||
input [7:0] spi_dma_sram_data,
|
||||
input spi_dma_sram_we
|
||||
);
|
||||
|
||||
reg [3:0] MAPPER_BUF;
|
||||
@ -50,6 +56,8 @@ reg [7:0] AVR_DATA_OUT_BUF;
|
||||
reg [7:0] AVR_DATA_IN_BUF;
|
||||
reg [1:0] avr_nextaddr_buf;
|
||||
wire avr_nextaddr;
|
||||
wire spi_dma_nextaddr_trig;
|
||||
reg [2:0] spi_dma_nextaddr_r;
|
||||
|
||||
reg [1:0] SRAM_MASK_IDX;
|
||||
reg [23:0] SAVERAM_MASK;
|
||||
@ -59,17 +67,15 @@ assign spi_data_out = AVR_DATA_IN_BUF;
|
||||
|
||||
initial begin
|
||||
ADDR_OUT_BUF = 0;
|
||||
spi_dma_nextaddr_r = 0;
|
||||
end
|
||||
|
||||
// command interpretation
|
||||
always @(posedge clk) begin
|
||||
if (cmd_ready) begin
|
||||
case (cmd_data[7:4])
|
||||
4'h3:
|
||||
MAPPER_BUF <= cmd_data[3:0];
|
||||
// 4'h8:
|
||||
// AVR_DATA_IN_BUF <= avr_data_in;
|
||||
// 4'hF:
|
||||
// TODO AVR_DATA_IN_BUF <= 8'hA5;
|
||||
endcase
|
||||
end else if (param_ready) begin
|
||||
case (cmd_data[7:4])
|
||||
@ -102,16 +108,15 @@ always @(posedge clk) begin
|
||||
32'h4:
|
||||
SAVERAM_MASK[7:0] <= param_data;
|
||||
endcase
|
||||
// 4'h8:
|
||||
// AVR_DATA_IN_BUF <= avr_data_in;
|
||||
4'h9:
|
||||
AVR_DATA_OUT_BUF <= param_data;
|
||||
endcase
|
||||
end
|
||||
if (avr_nextaddr & (cmd_data[7:5] == 3'h4) && (cmd_data[0]) && (spi_byte_cnt > (32'h1+cmd_data[4])))
|
||||
if (spi_dma_nextaddr_trig | (avr_nextaddr & (cmd_data[7:5] == 3'h4) && (cmd_data[0]) && (spi_byte_cnt > (32'h1+cmd_data[4]))))
|
||||
ADDR_OUT_BUF <= ADDR_OUT_BUF + 1;
|
||||
end
|
||||
|
||||
// value fetch during last SPI bit
|
||||
always @(posedge clk) begin
|
||||
if (spi_bit_cnt == 3'h7)
|
||||
if (cmd_data[7:4] == 4'hF)
|
||||
@ -120,6 +125,7 @@ always @(posedge clk) begin
|
||||
AVR_DATA_IN_BUF <= avr_data_in;
|
||||
end
|
||||
|
||||
// nextaddr pulse generation
|
||||
always @(posedge clk) begin
|
||||
if (spi_bit_cnt == 3'h0)
|
||||
avr_nextaddr_buf <= {avr_nextaddr_buf[0], 1'b1};
|
||||
@ -127,23 +133,33 @@ always @(posedge clk) begin
|
||||
avr_nextaddr_buf <= {avr_nextaddr_buf[0], 1'b0};
|
||||
end
|
||||
|
||||
assign spi_dma_nextaddr_trig = (spi_dma_nextaddr_r[2:1] == 2'b01);
|
||||
always @(posedge clk) begin
|
||||
spi_dma_nextaddr_r <= {spi_dma_nextaddr_r[1:0], spi_dma_nextaddr};
|
||||
end
|
||||
|
||||
// r/w pulse
|
||||
always @(posedge clk) begin
|
||||
if ((spi_bit_cnt == 3'h1) & (cmd_data[7:4] == 4'h9) & (spi_byte_cnt > 32'h1))
|
||||
AVR_WRITE_BUF <= 1'b0;
|
||||
else
|
||||
AVR_WRITE_BUF <= 1'b1;
|
||||
|
||||
// Read pulse is two spi cycles to ensure that the value
|
||||
// is ready in the 2nd cycle in AVR master mode
|
||||
if ((spi_bit_cnt == 3'h6 || spi_bit_cnt == 3'h7) & (cmd_data[7:4] == 4'h8) & (spi_byte_cnt > 32'h0))
|
||||
AVR_READ_BUF <= 1'b0;
|
||||
else
|
||||
AVR_READ_BUF <= 1'b1;
|
||||
end
|
||||
|
||||
// trigger for nextaddr
|
||||
assign avr_nextaddr = avr_nextaddr_buf == 2'b01;
|
||||
|
||||
assign avr_read = AVR_READ_BUF;
|
||||
assign avr_write = AVR_WRITE_BUF;
|
||||
assign avr_write = spi_dma_ovr ? spi_dma_sram_we : AVR_WRITE_BUF;
|
||||
assign addr_out = ADDR_OUT_BUF;
|
||||
assign avr_data_out = AVR_DATA_OUT_BUF;
|
||||
assign avr_data_out = spi_dma_ovr ? spi_dma_sram_data : AVR_DATA_OUT_BUF;
|
||||
assign avr_mapper = MAPPER_BUF;
|
||||
assign avr_sram_size = SRAM_SIZE_BUF;
|
||||
assign rom_mask_out = ROM_MASK;
|
||||
|
||||
@ -40,7 +40,6 @@ NET "SNES_CPU_CLK" IOSTANDARD = LVCMOS33;
|
||||
NET "SNES_REFRESH" IOSTANDARD = LVCMOS33;
|
||||
NET "SPI_MISO" IOSTANDARD = LVCMOS33;
|
||||
NET "SPI_MOSI" IOSTANDARD = LVCMOS33;
|
||||
NET "SPI_SCK" IOSTANDARD = LVCMOS33;
|
||||
NET "AVR_ENA" LOC = P58;
|
||||
NET "CLKIN" LOC = P125;
|
||||
NET "IRQ_DIR" LOC = P40;
|
||||
@ -187,5 +186,7 @@ NET "SRAM_DATA[8]" IOSTANDARD = LVCMOS33;
|
||||
NET "SRAM_DATA[9]" IOSTANDARD = LVCMOS33;
|
||||
NET "SRAM_OE" IOSTANDARD = LVCMOS33;
|
||||
NET "SRAM_WE" IOSTANDARD = LVCMOS33;
|
||||
TEMPERATURE = 60 C;
|
||||
VOLTAGE = 1.25 V;
|
||||
NET "SPI_DMA_CTRL" LOC = P41;
|
||||
NET "SPI_DMA_CTRL" IOSTANDARD = LVCMOS33;
|
||||
NET "SPI_SCK" IOSTANDARD = LVCMOS33;
|
||||
NET "SPI_SCK" PULLDOWN;
|
||||
|
||||
@ -46,10 +46,11 @@ module main(
|
||||
|
||||
/* AVR signals */
|
||||
input SPI_MOSI,
|
||||
output SPI_MISO,
|
||||
inout SPI_MISO,
|
||||
input SPI_SS,
|
||||
input SPI_SCK,
|
||||
input AVR_ENA
|
||||
inout SPI_SCK,
|
||||
input AVR_ENA,
|
||||
inout SPI_DMA_CTRL
|
||||
|
||||
/* debug */
|
||||
//output DCM_IN_STOPPED,
|
||||
@ -69,13 +70,15 @@ wire [7:0] AVR_OUT_DATA;
|
||||
wire [3:0] MAPPER;
|
||||
wire [23:0] SAVERAM_MASK;
|
||||
wire [23:0] ROM_MASK;
|
||||
wire [23:0] spi_dma_addr;
|
||||
wire [7:0] spi_dma_sram_data;
|
||||
wire spi_dma_trig = SPI_DMA_CTRL;
|
||||
|
||||
spi snes_spi(.clk(CLK2),
|
||||
.MOSI(SPI_MOSI),
|
||||
.MISO(SPI_MISO),
|
||||
.SSEL(SPI_SS),
|
||||
.SCK(SPI_SCK),
|
||||
.LED(SPI_LSB),
|
||||
.cmd_ready(spi_cmd_ready),
|
||||
.param_ready(spi_param_ready),
|
||||
.cmd_data(spi_cmd_data),
|
||||
@ -84,7 +87,10 @@ spi snes_spi(.clk(CLK2),
|
||||
.startmessage(spi_startmessage),
|
||||
.input_data(spi_input_data),
|
||||
.byte_cnt(spi_byte_cnt),
|
||||
.bit_cnt(spi_bit_cnt)
|
||||
.bit_cnt(spi_bit_cnt),
|
||||
|
||||
.spi_dma_sck(spi_dma_sck),
|
||||
.spi_dma_ovr(spi_dma_ovr)
|
||||
);
|
||||
|
||||
avr_cmd snes_avr_cmd(
|
||||
@ -106,10 +112,27 @@ avr_cmd snes_avr_cmd(
|
||||
.endmessage(spi_endmessage),
|
||||
.startmessage(spi_startmessage),
|
||||
.saveram_mask_out(SAVERAM_MASK),
|
||||
.rom_mask_out(ROM_MASK)
|
||||
.rom_mask_out(ROM_MASK),
|
||||
|
||||
.spi_dma_ovr(spi_dma_ovr),
|
||||
.spi_dma_nextaddr(spi_dma_nextaddr),
|
||||
.spi_dma_sram_data(spi_dma_sram_data),
|
||||
.spi_dma_sram_we(spi_dma_sram_we)
|
||||
);
|
||||
|
||||
//wire [7:0] DCM_STATUS;
|
||||
spi_dma snes_spi_dma(
|
||||
.clk(CLK2),
|
||||
.spi_dma_ovr(spi_dma_ovr), // to spi, avr_cmd
|
||||
.spi_dma_miso(SPI_MISO), // to spi
|
||||
.spi_dma_sck(spi_dma_sck), // to spi
|
||||
.spi_dma_trig(spi_dma_trig), // from avr
|
||||
.spi_dma_nextaddr(spi_dma_nextaddr), // to avr_cmd?
|
||||
.spi_dma_sram_data(spi_dma_sram_data), // to avr_cmd?
|
||||
.spi_dma_sram_we(spi_dma_sram_we), // to avr_cmd?
|
||||
.spi_dma_done(spi_dma_done) // to avr
|
||||
);
|
||||
|
||||
assign SPI_DMA_CTRL = spi_dma_ovr ? 1'b0 : 1'bZ;
|
||||
|
||||
// dcm1: dfs 4x
|
||||
my_dcm snes_dcm(.CLKIN(CLKIN),
|
||||
|
||||
@ -46,7 +46,6 @@ module main_tf2;
|
||||
wire SRAM_WE;
|
||||
wire SPI_MISO;
|
||||
wire MODE;
|
||||
wire SPI_LSB;
|
||||
wire SRAM_BHE;
|
||||
wire SRAM_BLE;
|
||||
|
||||
|
||||
@ -69,6 +69,22 @@
|
||||
<association xil_pn:name="BehavioralSimulation"/>
|
||||
<association xil_pn:name="Implementation"/>
|
||||
</file>
|
||||
<file xil_pn:name="spi_dma.v" xil_pn:type="FILE_VERILOG">
|
||||
<association xil_pn:name="Implementation"/>
|
||||
<association xil_pn:name="BehavioralSimulation"/>
|
||||
</file>
|
||||
<file xil_pn:name="tf_spi_dma.v" xil_pn:type="FILE_VERILOG">
|
||||
<association xil_pn:name="BehavioralSimulation"/>
|
||||
<association xil_pn:name="PostTranslateSimulation"/>
|
||||
<association xil_pn:name="PostMapSimulation"/>
|
||||
<association xil_pn:name="PostRouteSimulation"/>
|
||||
</file>
|
||||
<file xil_pn:name="tf_main_3.v" xil_pn:type="FILE_VERILOG">
|
||||
<association xil_pn:name="BehavioralSimulation"/>
|
||||
<association xil_pn:name="PostTranslateSimulation"/>
|
||||
<association xil_pn:name="PostMapSimulation"/>
|
||||
<association xil_pn:name="PostRouteSimulation"/>
|
||||
</file>
|
||||
</files>
|
||||
|
||||
<properties>
|
||||
@ -92,9 +108,9 @@
|
||||
<property xil_pn:name="Optimization Effort" xil_pn:value="High"/>
|
||||
<property xil_pn:name="Optimization Strategy (Cover Mode)" xil_pn:value="Balanced"/>
|
||||
<property xil_pn:name="Optimize Instantiated Primitives" xil_pn:value="true"/>
|
||||
<property xil_pn:name="PROP_BehavioralSimTop" xil_pn:value="Module|main_tf2"/>
|
||||
<property xil_pn:name="PROP_BehavioralSimTop" xil_pn:value="Module|tf_main_3"/>
|
||||
<property xil_pn:name="PROP_DesignName" xil_pn:value="sd2snes"/>
|
||||
<property xil_pn:name="PROP_PostParSimTop" xil_pn:value="Module|main_tf2"/>
|
||||
<property xil_pn:name="PROP_PostParSimTop" xil_pn:value="Module|tf_main_3"/>
|
||||
<property xil_pn:name="Package" xil_pn:value="tq144"/>
|
||||
<property xil_pn:name="Place & Route Effort Level (Overall)" xil_pn:value="High"/>
|
||||
<property xil_pn:name="Placer Effort Level (Overrides Overall Level)" xil_pn:value="High"/>
|
||||
@ -104,8 +120,8 @@
|
||||
<property xil_pn:name="Register Duplication" xil_pn:value="On"/>
|
||||
<property xil_pn:name="Release Write Enable (Output Events)" xil_pn:value="5"/>
|
||||
<property xil_pn:name="Router Effort Level (Overrides Overall Level)" xil_pn:value="High"/>
|
||||
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="Module|main_tf2"/>
|
||||
<property xil_pn:name="Selected Simulation Root Source Node Post-Route" xil_pn:value="Module|main_tf2"/>
|
||||
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="Module|tf_main_3"/>
|
||||
<property xil_pn:name="Selected Simulation Root Source Node Post-Route" xil_pn:value="Module|tf_main_3"/>
|
||||
<property xil_pn:name="Selected Simulation Source Node" xil_pn:value="uut"/>
|
||||
<property xil_pn:name="Simulator" xil_pn:value="ISim (VHDL/Verilog)"/>
|
||||
<property xil_pn:name="Speed Grade" xil_pn:value="-4"/>
|
||||
|
||||
@ -20,11 +20,10 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
module spi(input clk,
|
||||
input SCK,
|
||||
inout SCK,
|
||||
input MOSI,
|
||||
output MISO,
|
||||
inout MISO,
|
||||
input SSEL,
|
||||
output LED,
|
||||
output cmd_ready,
|
||||
output param_ready,
|
||||
output [7:0] cmd_data,
|
||||
@ -33,15 +32,41 @@ module spi(input clk,
|
||||
output startmessage,
|
||||
input [7:0] input_data,
|
||||
output [31:0] byte_cnt,
|
||||
output [2:0] bit_cnt);
|
||||
output [2:0] bit_cnt,
|
||||
|
||||
// spi "DMA" extension
|
||||
input spi_dma_sck,
|
||||
input spi_dma_ovr);
|
||||
|
||||
reg [7:0] cmd_data_r;
|
||||
reg [7:0] param_data_r;
|
||||
|
||||
// sync SCK to the FPGA clock using a 3-bits shift register
|
||||
// SCK is an OUTPUT in "DMA" mode
|
||||
reg [2:0] spi_dma_ovr_r;
|
||||
reg [9:0] spi_dma_leadout_cnt;
|
||||
reg spi_dma_leadout;
|
||||
initial begin
|
||||
spi_dma_ovr_r = 3'b000;
|
||||
spi_dma_leadout_cnt <= 10'b0000000000;
|
||||
end
|
||||
always @(posedge clk) spi_dma_ovr_r <= {spi_dma_ovr_r[1:0], spi_dma_ovr};
|
||||
wire spi_dma_ovr_falling = (spi_dma_ovr_r[1:0] == 2'b10);
|
||||
always @(posedge clk) begin
|
||||
if (spi_dma_ovr_falling) begin
|
||||
spi_dma_leadout <= 1;
|
||||
spi_dma_leadout_cnt <= 0;
|
||||
end else begin
|
||||
if(spi_dma_leadout_cnt == 100)
|
||||
spi_dma_leadout <= 0;
|
||||
if(spi_dma_leadout)
|
||||
spi_dma_leadout_cnt <= spi_dma_leadout_cnt + 1;
|
||||
end
|
||||
end
|
||||
assign SCK = spi_dma_ovr ? spi_dma_sck : spi_dma_leadout ? 1'b0 : 1'bZ;
|
||||
reg [2:0] SCKr; always @(posedge clk) SCKr <= {SCKr[1:0], SCK};
|
||||
wire SCK_risingedge = (SCKr[2:1]==2'b01); // now we can detect SCK rising edges
|
||||
wire SCK_fallingedge = (SCKr[2:1]==2'b10); // and falling edges
|
||||
wire SCK_risingedge = spi_dma_ovr ? 0 : (SCKr[2:1]==2'b01); // now we can detect SCK rising edges
|
||||
wire SCK_fallingedge = spi_dma_ovr ? 0 : (SCKr[2:1]==2'b10); // and falling edges
|
||||
|
||||
// same thing for SSEL
|
||||
reg [2:0] SSELr; always @(posedge clk) SSELr <= {SSELr[1:0], SSEL};
|
||||
@ -55,7 +80,7 @@ assign startmessage = SSEL_startmessage;
|
||||
reg [1:0] MOSIr; always @(posedge clk) MOSIr <= {MOSIr[0], MOSI};
|
||||
wire MOSI_data = MOSIr[1];
|
||||
|
||||
// we handle SPI in 8-bits format, so we need a 3 bits counter to count the bits as they come in
|
||||
// bit count for one SPI byte + byte count for the message
|
||||
reg [2:0] bitcnt;
|
||||
reg [31:0] byte_cnt_r;
|
||||
|
||||
@ -66,44 +91,32 @@ assign bit_cnt = bitcnt;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(~SSEL_active) begin
|
||||
bitcnt <= 3'b000;
|
||||
end else
|
||||
if(SCK_risingedge)
|
||||
begin
|
||||
bitcnt <= bitcnt + 3'b001;
|
||||
|
||||
// implement a shift-left register (since we receive the data MSB first)
|
||||
byte_data_received <= {byte_data_received[6:0], MOSI_data};
|
||||
end
|
||||
if(~SSEL_active) begin
|
||||
bitcnt <= 3'b000;
|
||||
end
|
||||
else if(SCK_risingedge) begin
|
||||
bitcnt <= bitcnt + 3'b001;
|
||||
// shift received data into the register
|
||||
byte_data_received <= {byte_data_received[6:0], MOSI_data};
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) byte_received <= SSEL_active && SCK_risingedge && (bitcnt==3'b111);
|
||||
|
||||
// we use the LSB of the data received to control an LED
|
||||
reg LEDr;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(~SSEL_active)
|
||||
byte_cnt_r <= 16'h0000;
|
||||
byte_cnt_r <= 16'h0000;
|
||||
else if(byte_received) begin
|
||||
LEDr <= byte_data_received[0];
|
||||
byte_cnt_r <= byte_cnt_r + 16'h0001;
|
||||
end
|
||||
end
|
||||
assign LED = LEDr;
|
||||
|
||||
reg [7:0] byte_data_sent;
|
||||
|
||||
reg [7:0] cnt;
|
||||
always @(posedge clk) begin
|
||||
if(SSEL_startmessage) cnt<=cnt+8'h1; // count the messages
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(SSEL_active) begin
|
||||
if(SSEL_startmessage)
|
||||
byte_data_sent <= cnt; // first byte sent in a message is the message count
|
||||
byte_data_sent <= 8'h5A; // dummy byte
|
||||
else
|
||||
if(SCK_fallingedge) begin
|
||||
if(bitcnt==3'b000)
|
||||
@ -114,7 +127,8 @@ always @(posedge clk) begin
|
||||
end
|
||||
end
|
||||
|
||||
assign MISO = SSEL_active ? byte_data_sent[7] : 1'bZ; // send MSB first
|
||||
// Slave out is an INPUT in "DMA" mode
|
||||
assign MISO = spi_dma_ovr ? 1'bZ : SSEL_active ? byte_data_sent[7] : 1'bZ; // send MSB first
|
||||
|
||||
reg cmd_ready_r;
|
||||
reg param_ready_r;
|
||||
@ -128,6 +142,8 @@ assign byte_cnt = byte_cnt_r;
|
||||
|
||||
always @(posedge clk) cmd_ready_r2 = byte_received && byte_cnt_r == 32'h0;
|
||||
always @(posedge clk) param_ready_r2 = byte_received && byte_cnt_r > 32'h0;
|
||||
|
||||
// fill registers
|
||||
always @(posedge clk) begin
|
||||
if (SSEL_startmessage)
|
||||
cmd_data_r <= 8'h00;
|
||||
@ -135,8 +151,9 @@ always @(posedge clk) begin
|
||||
cmd_data_r <= byte_data_received;
|
||||
else if(param_ready_r2)
|
||||
param_data_r <= byte_data_received;
|
||||
|
||||
end
|
||||
|
||||
// delay ready signals by one clock (why did I do this again...)
|
||||
always @(posedge clk) begin
|
||||
cmd_ready_r <= cmd_ready_r2;
|
||||
param_ready_r <= param_ready_r2;
|
||||
|
||||
143
verilog/sd2snes/spi_dma.v
Normal file
143
verilog/sd2snes/spi_dma.v
Normal file
@ -0,0 +1,143 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 22:18:56 12/20/2009
|
||||
// Design Name:
|
||||
// Module Name: spi_dma
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
module spi_dma(
|
||||
input clk,
|
||||
output spi_dma_ovr,
|
||||
input spi_dma_miso,
|
||||
output spi_dma_sck,
|
||||
input spi_dma_trig,
|
||||
output spi_dma_nextaddr,
|
||||
output [7:0] spi_dma_sram_data,
|
||||
output spi_dma_sram_we,
|
||||
output spi_dma_done
|
||||
);
|
||||
|
||||
reg spi_dma_sram_we_r;
|
||||
reg spi_dma_done_r;
|
||||
reg spi_dma_ovr_r;
|
||||
reg spi_dma_nextaddr_r;
|
||||
reg [7:0] spi_dma_sram_data_r;
|
||||
|
||||
reg [3:0] spi_dma_bitcnt; // extra bits
|
||||
reg [9:0] spi_dma_bytecnt;
|
||||
reg [3:0] spi_dma_clkcnt;
|
||||
reg [3:0] spi_dma_sck_int_r;
|
||||
reg [5:0] spi_dma_trig_r;
|
||||
reg [1:0] spi_dma_miso_r;
|
||||
reg spi_dma_sck_out_r;
|
||||
reg spi_dma_sck_out_r2;
|
||||
|
||||
initial begin
|
||||
spi_dma_clkcnt <= 4'b0000;
|
||||
spi_dma_bitcnt <= 4'b1110;
|
||||
spi_dma_bytecnt <= 10'b0000000000;
|
||||
spi_dma_nextaddr_r <= 1'b0;
|
||||
spi_dma_sram_we_r <= 1'b1;
|
||||
spi_dma_done_r <= 1'b1;
|
||||
spi_dma_sck_int_r <= 4'b0000;
|
||||
spi_dma_trig_r <= 6'b000000;
|
||||
spi_dma_ovr_r <= 1'b0;
|
||||
spi_dma_sck_out_r <= 1'b0;
|
||||
spi_dma_sck_out_r2 <= 1'b0;
|
||||
end
|
||||
|
||||
// synthesize clock
|
||||
wire spi_dma_sck_int = spi_dma_clkcnt[1];
|
||||
assign spi_dma_sck = spi_dma_sck_out_r & spi_dma_sck_out_r2;
|
||||
always @(posedge clk) begin
|
||||
spi_dma_clkcnt <= spi_dma_clkcnt + 1;
|
||||
spi_dma_sck_int_r <= {spi_dma_sck_int_r[2:0], spi_dma_sck_int};
|
||||
spi_dma_trig_r <= {spi_dma_trig_r[4:0], spi_dma_trig};
|
||||
spi_dma_miso_r <= {spi_dma_miso_r[0], spi_dma_miso};
|
||||
end
|
||||
|
||||
wire spi_dma_trig_rising = (spi_dma_trig_r[5:1] == 5'b00011);
|
||||
wire spi_dma_trig_falling = (spi_dma_trig_r[5:1] == 5'b11100);
|
||||
wire spi_dma_sck_rising = (spi_dma_sck_int_r[1:0] == 2'b01);
|
||||
wire spi_dma_sck_falling = (spi_dma_sck_int_r[1:0] == 2'b10);
|
||||
wire spi_dma_sck_rising2 = (spi_dma_sck_int_r[1:0] == 2'b01);
|
||||
wire spi_dma_sck_falling2 = (spi_dma_sck_int_r[1:0] == 2'b10);
|
||||
|
||||
assign spi_dma_nextaddr = spi_dma_nextaddr_r;
|
||||
assign spi_dma_sram_data = spi_dma_sram_data_r;
|
||||
assign spi_dma_sram_we = spi_dma_sram_we_r;
|
||||
assign spi_dma_done = spi_dma_done_r;
|
||||
assign spi_dma_ovr = spi_dma_ovr_r;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (spi_dma_trig_falling & !spi_dma_ovr_r) begin
|
||||
spi_dma_done_r <= 0;
|
||||
spi_dma_ovr_r <= 1;
|
||||
end else if (spi_dma_bitcnt == 0 && spi_dma_bytecnt == 512) begin
|
||||
spi_dma_done_r <= 1;
|
||||
spi_dma_ovr_r <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(spi_dma_sck_falling)
|
||||
spi_dma_sck_out_r2 <= 0;
|
||||
else if(spi_dma_sck_rising)
|
||||
spi_dma_sck_out_r2 <= 1;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (spi_dma_sck_rising & spi_dma_ovr_r & spi_dma_bitcnt < 8)
|
||||
spi_dma_sram_data_r <= {spi_dma_sram_data_r[6:0], spi_dma_miso};
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(spi_dma_sck_rising & spi_dma_ovr_r) begin
|
||||
if (spi_dma_bitcnt < 8) begin
|
||||
spi_dma_sck_out_r <= 1;
|
||||
spi_dma_bitcnt <= spi_dma_bitcnt + 1;
|
||||
end else if (spi_dma_bitcnt == 8) begin
|
||||
spi_dma_sck_out_r <= 0;
|
||||
spi_dma_bitcnt <= spi_dma_bitcnt + 1;
|
||||
spi_dma_sram_we_r <= 0;
|
||||
end else if (spi_dma_bitcnt == 9) begin
|
||||
spi_dma_sck_out_r <= 0;
|
||||
spi_dma_sram_we_r <= 1;
|
||||
spi_dma_bytecnt <= spi_dma_bytecnt + 1;
|
||||
spi_dma_bitcnt <= 10;
|
||||
end else if (spi_dma_bitcnt == 10) begin
|
||||
spi_dma_nextaddr_r <= 1;
|
||||
spi_dma_bitcnt <= spi_dma_bitcnt + 1;
|
||||
end else if (spi_dma_bitcnt == 11) begin
|
||||
spi_dma_nextaddr_r <= 0;
|
||||
spi_dma_bitcnt <= spi_dma_bitcnt + 1;
|
||||
end else if (spi_dma_bitcnt == 12) begin
|
||||
spi_dma_bitcnt <= 0;
|
||||
end else if (spi_dma_bitcnt == 4'b1101) begin
|
||||
spi_dma_sck_out_r <= 0;
|
||||
spi_dma_bitcnt <= 4'b1110;
|
||||
end else if (spi_dma_bitcnt == 4'b1110) begin
|
||||
spi_dma_bitcnt <= spi_dma_bitcnt + 1;
|
||||
end else if (spi_dma_bitcnt == 4'b1111) begin
|
||||
spi_dma_bitcnt <= 0;
|
||||
end
|
||||
end else if (spi_dma_sck_rising & !spi_dma_ovr_r) begin
|
||||
spi_dma_bitcnt <= 4'b1101;
|
||||
spi_dma_bytecnt <= 10'b0000000000;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
132
verilog/sd2snes/tf_main_3.v
Normal file
132
verilog/sd2snes/tf_main_3.v
Normal file
@ -0,0 +1,132 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 04:03:25 12/21/2009
|
||||
// Design Name: main
|
||||
// Module Name: /home/ikari/prj/sd2snes/verilog/sd2snes/tf_main_3.v
|
||||
// Project Name: sd2snes
|
||||
// Target Device:
|
||||
// Tool versions:
|
||||
// Description:
|
||||
//
|
||||
// Verilog Test Fixture created by ISE for module: main
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module tf_main_3;
|
||||
|
||||
// Inputs
|
||||
reg CLKIN;
|
||||
reg [23:0] SNES_ADDR;
|
||||
reg SNES_READ;
|
||||
reg SNES_WRITE;
|
||||
reg SNES_CS;
|
||||
reg SNES_CPU_CLK;
|
||||
reg SNES_REFRESH;
|
||||
reg SPI_MOSI;
|
||||
reg SPI_SS;
|
||||
reg AVR_ENA;
|
||||
|
||||
// Outputs
|
||||
wire SNES_DATABUS_OE;
|
||||
wire SNES_DATABUS_DIR;
|
||||
wire IRQ_DIR;
|
||||
wire [19:0] SRAM_ADDR;
|
||||
wire [3:0] SRAM_CE2;
|
||||
wire SRAM_OE;
|
||||
wire SRAM_WE;
|
||||
wire SRAM_BHE;
|
||||
wire SRAM_BLE;
|
||||
|
||||
// Bidirs
|
||||
wire [7:0] SNES_DATA;
|
||||
wire SNES_IRQ;
|
||||
wire [15:0] SRAM_DATA;
|
||||
wire SPI_MISO;
|
||||
wire SPI_SCK;
|
||||
wire SPI_DMA_CTRL;
|
||||
|
||||
reg SPI_DMA_CTRLdir;
|
||||
reg SPI_DMA_CTRLr;
|
||||
|
||||
reg SPI_MISOdir;
|
||||
reg SPI_MISOr;
|
||||
// Instantiate the Unit Under Test (UUT)
|
||||
main uut (
|
||||
.CLKIN(CLKIN),
|
||||
.SNES_ADDR(SNES_ADDR),
|
||||
.SNES_READ(SNES_READ),
|
||||
.SNES_WRITE(SNES_WRITE),
|
||||
.SNES_CS(SNES_CS),
|
||||
.SNES_DATA(SNES_DATA),
|
||||
.SNES_CPU_CLK(SNES_CPU_CLK),
|
||||
.SNES_REFRESH(SNES_REFRESH),
|
||||
.SNES_IRQ(SNES_IRQ),
|
||||
.SNES_DATABUS_OE(SNES_DATABUS_OE),
|
||||
.SNES_DATABUS_DIR(SNES_DATABUS_DIR),
|
||||
.IRQ_DIR(IRQ_DIR),
|
||||
.SRAM_DATA(SRAM_DATA),
|
||||
.SRAM_ADDR(SRAM_ADDR),
|
||||
.SRAM_CE2(SRAM_CE2),
|
||||
.SRAM_OE(SRAM_OE),
|
||||
.SRAM_WE(SRAM_WE),
|
||||
.SRAM_BHE(SRAM_BHE),
|
||||
.SRAM_BLE(SRAM_BLE),
|
||||
.SPI_MOSI(SPI_MOSI),
|
||||
.SPI_MISO(SPI_MISO),
|
||||
.SPI_SS(SPI_SS),
|
||||
.SPI_SCK(SPI_SCK),
|
||||
.AVR_ENA(AVR_ENA),
|
||||
.SPI_DMA_CTRL(SPI_DMA_CTRL)
|
||||
);
|
||||
|
||||
initial begin
|
||||
// Initialize Inputs
|
||||
CLKIN = 0;
|
||||
SNES_ADDR = 0;
|
||||
SNES_READ = 0;
|
||||
SNES_WRITE = 0;
|
||||
SNES_CS = 0;
|
||||
SNES_CPU_CLK = 0;
|
||||
SNES_REFRESH = 0;
|
||||
SPI_MOSI = 0;
|
||||
SPI_SS = 0;
|
||||
AVR_ENA = 0;
|
||||
SPI_DMA_CTRLr = 1;
|
||||
SPI_DMA_CTRLdir = 0;
|
||||
SPI_MISOr = 0;
|
||||
SPI_MISOdir = 0;
|
||||
// Wait 100 ns for global reset to finish
|
||||
#100;
|
||||
#600; // dcm?
|
||||
// Add stimulus here
|
||||
SPI_DMA_CTRLr = 1;
|
||||
SPI_DMA_CTRLdir = 1;
|
||||
#100 SPI_DMA_CTRLr = 0;
|
||||
#100 SPI_DMA_CTRLr = 1'bZ;
|
||||
SPI_DMA_CTRLdir = 0;
|
||||
SPI_MISOdir = 1;
|
||||
#260 SPI_MISOr = 1;
|
||||
#80 SPI_MISOr = 0;
|
||||
#80 SPI_MISOr = 0;
|
||||
#80 SPI_MISOr = 1;
|
||||
#80 SPI_MISOr = 0;
|
||||
#80 SPI_MISOr = 1;
|
||||
#80 SPI_MISOr = 0;
|
||||
#80 SPI_MISOr = 1;
|
||||
end
|
||||
|
||||
assign SPI_DMA_CTRL = SPI_DMA_CTRLdir ? SPI_DMA_CTRLr : 1'bZ;
|
||||
assign SPI_MISO = SPI_MISOdir ? SPI_MISOr : 1'bZ;
|
||||
always #35 CLKIN = ~CLKIN;
|
||||
endmodule
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user