FPGA: merge recent changes into sd2sneslite

This commit is contained in:
Maximilian Rehkopf 2011-10-08 17:05:22 +02:00
parent 9a58016f26
commit b05c89cdbf
7 changed files with 475 additions and 603 deletions

View File

@ -18,93 +18,46 @@
// //
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
module address( module address(
input CLK, input CLK,
input [2:0] MAPPER, // MCU detected mapper input [23:0] SNES_ADDR, // requested address from SNES
input [23:0] SNES_ADDR, // requested address from SNES input SNES_CS, // "CART" pin from SNES (active low)
input SNES_CS, // "CART" pin from SNES (active low) output [23:0] ROM_ADDR, // Address to request from SRAM0
output [22:0] ROM_ADDR, // Address to request from SRAM0 output ROM_SEL, // enable SRAM0 (active low)
output ROM_SEL, // enable SRAM0 (active low) output IS_SAVERAM, // address/CS mapped as SRAM?
input MCU_OVR, // enable MCU master mode (active low) output IS_ROM, // address mapped as ROM?
input MODE, // MCU(1) or SNES(0) ("bus phase") input [23:0] MCU_ADDR, // allow address to be set externally
output IS_SAVERAM, // address/CS mapped as SRAM? input ADDR_WRITE,
output IS_ROM, // address mapped as ROM? input [23:0] SAVERAM_MASK,
input [23:0] MCU_ADDR, // allow address to be set externally input [23:0] ROM_MASK
input ADDR_WRITE, );
output ROM_ADDR0,
input [23:0] SAVERAM_MASK,
input [23:0] ROM_MASK,
input use_msu,
output msu_enable
);
wire [1:0] SRAM_BANK; wire [23:0] SRAM_SNES_ADDR;
wire [23:0] SRAM_ADDR_FULL; /* static mapper:
menu (ROM in upper SRAM)
/* currently supported mappers:
Index Mapper
000 HiROM
001 LoROM
010 ExHiROM (48-64Mbit)
110 brainfuck interleaved 96MBit Star Ocean =)
111 menu (ROM in upper SRAM)
*/ */
/* HiROM: SRAM @ Bank 0x30-0x3f, 0xb0-0xbf /* HiROM: SRAM @ Bank 0x30-0x3f, 0xb0-0xbf
Offset 6000-7fff */ Offset 6000-7fff */
assign IS_ROM = ( (MAPPER == 3'b000) ? ((!SNES_ADDR[22] & SNES_ADDR[15]) assign IS_ROM = ((!SNES_ADDR[22] & SNES_ADDR[15])
|(SNES_ADDR[22])) |(SNES_ADDR[22]));
: (MAPPER == 3'b001) ? ((!SNES_ADDR[22] & SNES_ADDR[15])
|(SNES_ADDR[22]))
: (MAPPER == 3'b010) ? ((!SNES_ADDR[22] & SNES_ADDR[15])
|(SNES_ADDR[22]))
: (MAPPER == 3'b110) ? ((!SNES_ADDR[22] & SNES_ADDR[15])
|(SNES_ADDR[22]))
: (MAPPER == 3'b111) ? ((!SNES_ADDR[22] & SNES_ADDR[15])
|(SNES_ADDR[22]))
: 1'b0);
assign IS_SAVERAM = ((MAPPER == 3'b000 || MAPPER == 3'b010 || MAPPER == 3'b110 || MAPPER == 3'b111) ? (!SNES_ADDR[22] assign IS_SAVERAM = (!SNES_ADDR[22]
& SNES_ADDR[21:20] & &SNES_ADDR[21:20]
& &SNES_ADDR[14:13] & &SNES_ADDR[14:13]
& !SNES_ADDR[15] & !SNES_ADDR[15]
& SNES_CS );
)
/* LoROM: SRAM @ Bank 0x70-0x7d, 0xf0-0xfd
Offset 0000-7fff TODO: 0000-ffff for
small ROMs */
:(MAPPER == 3'b001) ? (&SNES_ADDR[22:20]
& (SNES_ADDR[19:16] < 4'b1110)
& !SNES_ADDR[15]
& !SNES_CS)
: 1'b0);
assign SRAM_ADDR_FULL = (MODE) ? MCU_ADDR assign SRAM_SNES_ADDR = (IS_SAVERAM
: ((MAPPER == 3'b000) ? ? 24'hFF0000 + ((SNES_ADDR[14:0] - 15'h6000)
(IS_SAVERAM ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK) & SAVERAM_MASK)
: ({1'b0, SNES_ADDR[22:0]} & ROM_MASK)) : (({1'b0, SNES_ADDR[22:0]} & ROM_MASK)
:(MAPPER == 3'b001) ? + 24'hE00000)
(IS_SAVERAM ? 24'hE00000 + (SNES_ADDR[14:0] & SAVERAM_MASK) );
: ({2'b00, SNES_ADDR[22:16], SNES_ADDR[14:0]} & ROM_MASK))
:(MAPPER == 3'b010) ? assign ROM_ADDR = SRAM_SNES_ADDR;
(IS_SAVERAM ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK)
: ({1'b0, !SNES_ADDR[23], SNES_ADDR[21:0]} & ROM_MASK))
:(MAPPER == 3'b110) ?
(IS_SAVERAM ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK)
: (SNES_ADDR[15] ? ({1'b0, SNES_ADDR[23:16], SNES_ADDR[14:0]})
: ({2'b10, SNES_ADDR[23], SNES_ADDR[21:16], SNES_ADDR[14:0]})))
:(MAPPER == 3'b111) ?
(IS_SAVERAM ? 24'hFF0000 + ((SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK)
: (({1'b0, SNES_ADDR[22:0]} & ROM_MASK) + 24'hE00000))
: 24'b0);
assign ROM_ADDR = SRAM_ADDR_FULL[23:1]; assign ROM_SEL = 1'b0;
assign ROM_SEL = 1'b0; // (MODE) ? CS_ARRAY[SRAM_BANK] : IS_SAVERAM ? 4'b1000 : CS_ARRAY[SRAM_BANK];
assign ROM_ADDR0 = SRAM_ADDR_FULL[0];
//488888
assign msu_enable = (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfff8) == 16'h2000));
endmodule endmodule

View File

@ -36,8 +36,7 @@ module data(
input MCU_OVR, input MCU_OVR,
input ROM_ADDR0, input ROM_ADDR0,
output [7:0] MSU_DATA_IN, output [7:0] MSU_DATA_IN,
input [7:0] MSU_DATA_OUT, input [7:0] MSU_DATA_OUT
input msu_enable
); );
reg [7:0] SNES_IN_MEM; reg [7:0] SNES_IN_MEM;
@ -49,7 +48,7 @@ wire [7:0] FROM_ROM_BYTE;
assign MSU_DATA_IN = SNES_DATA; assign MSU_DATA_IN = SNES_DATA;
assign SNES_DATA = SNES_READ ? 8'bZ : (!MCU_OVR ? 8'h00 : (msu_enable ? MSU_DATA_OUT : SNES_OUT_MEM)); assign SNES_DATA = SNES_READ ? 8'bZ : (!MCU_OVR ? 8'h00 : SNES_OUT_MEM);
assign FROM_ROM_BYTE = (ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8]); assign FROM_ROM_BYTE = (ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8]);

View File

@ -37,7 +37,7 @@ module my_dcm (
.CLKFX_DIVIDE(1), // Can be any integer from 1 to 32 .CLKFX_DIVIDE(1), // Can be any integer from 1 to 32
.CLKFX_MULTIPLY(4), // Can be any integer from 2 to 32 .CLKFX_MULTIPLY(4), // Can be any integer from 2 to 32
.CLKIN_DIVIDE_BY_2("FALSE"), // TRUE/FALSE to enable CLKIN divide by two feature .CLKIN_DIVIDE_BY_2("FALSE"), // TRUE/FALSE to enable CLKIN divide by two feature
.CLKIN_PERIOD(44.289), // Specify period of input clock .CLKIN_PERIOD(41.667), // Specify period of input clock
.CLKOUT_PHASE_SHIFT("NONE"), // Specify phase shift of NONE, FIXED or VARIABLE .CLKOUT_PHASE_SHIFT("NONE"), // Specify phase shift of NONE, FIXED or VARIABLE
.CLK_FEEDBACK("NONE"), // Specify clock feedback of NONE, 1X or 2X .CLK_FEEDBACK("NONE"), // Specify clock feedback of NONE, 1X or 2X
.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), // SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), // SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or

View File

@ -1,5 +1,20 @@
NET "CLKIN" TNM_NET = "CLKIN"; NET "CLKIN" TNM_NET = "CLKIN";
TIMESPEC TS_CLKIN = PERIOD "CLKIN" 22.579 MHz HIGH 50 %; TIMESPEC TS_CLKIN = PERIOD "CLKIN" 24 MHz HIGH 50 %;
//TIMESPEC TS_CLKIN = PERIOD "CLKIN" 21.5 MHz HIGH 50 %;
NET "p113_out" IOSTANDARD = LVCMOS33;
NET "p113_out" LOC = P113;
NET "SPI_SCK" LOC = P71;
NET "SPI_SCK" CLOCK_DEDICATED_ROUTE = FALSE;
NET "SPI_SCK" TNM_NET = "SPI_SCK";
TIMESPEC TS_SPI_SCK = PERIOD "SPI_SCK" 48MHz HIGH 50 %;
NET "SPI_SCK" IOSTANDARD = LVCMOS33;
NET "SPI_SCK" DRIVE = 8;
NET "SPI_SCK" PULLUP;
NET "SNES_CS" IOSTANDARD = LVCMOS33; NET "SNES_CS" IOSTANDARD = LVCMOS33;
NET "SNES_READ" IOSTANDARD = LVCMOS33; NET "SNES_READ" IOSTANDARD = LVCMOS33;
NET "SNES_WRITE" IOSTANDARD = LVCMOS33; NET "SNES_WRITE" IOSTANDARD = LVCMOS33;
@ -61,6 +76,10 @@ NET "MCU_OVR" LOC = P92;
NET "MCU_OVR" IOSTANDARD = LVCMOS33; NET "MCU_OVR" IOSTANDARD = LVCMOS33;
NET "MCU_OVR" DRIVE = 8; NET "MCU_OVR" DRIVE = 8;
NET "MCU_RDY" LOC = P83;
NET "MCU_RDY" IOSTANDARD = LVCMOS33;
NET "MCU_RDY" DRIVE = 8;
NET "ROM_ADDR[0]" LOC = P166; NET "ROM_ADDR[0]" LOC = P166;
@ -236,10 +255,6 @@ NET "ROM_BLE" LOC = P156;
NET "ROM_BLE" IOSTANDARD = LVCMOS33; NET "ROM_BLE" IOSTANDARD = LVCMOS33;
NET "ROM_BLE" DRIVE = 8; NET "ROM_BLE" DRIVE = 8;
NET "IRQ_DIR" LOC = P113;
NET "IRQ_DIR" IOSTANDARD = LVCMOS33;
NET "IRQ_DIR" DRIVE = 8;
NET "ROM_DATA[0]" LOC = P176; NET "ROM_DATA[0]" LOC = P176;
@ -415,10 +430,12 @@ NET "SNES_ADDR[9]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR[9]" DRIVE = 8; NET "SNES_ADDR[9]" DRIVE = 8;
NET "SNES_CPU_CLK" LOC = P94; NET "SNES_CPU_CLK" LOC = P95;
NET "SNES_CS" LOC = P116; NET "SNES_CS" LOC = P116;
NET "SNES_DATABUS_DIR" LOC = P111; NET "SNES_DATABUS_DIR" LOC = P111;
NET "SNES_DATABUS_OE" LOC = P109; NET "SNES_DATABUS_OE" LOC = P109;
NET "SNES_DATABUS_DIR" DRIVE = 8;
NET "SNES_DATABUS_OE" DRIVE = 8;
NET "SNES_DATA[0]" IOSTANDARD = LVCMOS33; NET "SNES_DATA[0]" IOSTANDARD = LVCMOS33;
@ -442,7 +459,7 @@ NET "SNES_DATA[7]" DRIVE = 8;
NET "SNES_IRQ" LOC = P114; NET "SNES_IRQ" LOC = P114;
NET "SNES_READ" LOC = P115; NET "SNES_READ" LOC = P115;
NET "SNES_REFRESH" LOC = P155; NET "SNES_REFRESH" LOC = P155;
NET "SNES_WRITE" LOC = P95; NET "SNES_WRITE" LOC = P94;
NET "SPI_MISO" LOC = P72; NET "SPI_MISO" LOC = P72;
@ -458,14 +475,6 @@ NET "SPI_MOSI" IOSTANDARD = LVCMOS33;
NET "SPI_MOSI" DRIVE = 8; NET "SPI_MOSI" DRIVE = 8;
NET "SPI_SCK" LOC = P71;
NET "SPI_SCK" IOSTANDARD = LVCMOS33;
NET "SPI_SCK" DRIVE = 8;
NET "SPI_SCK" PULLUP;
NET "SPI_SS" LOC = P68; NET "SPI_SS" LOC = P68;
@ -512,4 +521,4 @@ NET "SD_DAT[2]" IOSTANDARD = LVCMOS33;
NET "SD_DAT[3]" IOSTANDARD = LVCMOS33; NET "SD_DAT[3]" IOSTANDARD = LVCMOS33;
NET "SNES_SYSCLK" LOC = P180; NET "SNES_SYSCLK" LOC = P180;
NET "SNES_SYSCLK" IOSTANDARD = LVCMOS33; NET "SNES_SYSCLK" IOSTANDARD = LVCMOS33;

View File

@ -19,58 +19,67 @@
// //
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
module main( module main(
/* input clock */ /* input clock */
input CLKIN, input CLKIN,
/* SNES signals */
input [23:0] SNES_ADDR,
input SNES_READ,
input SNES_WRITE,
input SNES_CS,
inout [7:0] SNES_DATA,
input SNES_CPU_CLK,
input SNES_REFRESH,
inout SNES_IRQ,
output SNES_DATABUS_OE,
output SNES_DATABUS_DIR,
output IRQ_DIR,
input SNES_SYSCLK,
/* SRAM signals */ /* SNES signals */
inout [15:0] ROM_DATA, input [23:0] SNES_ADDR,
output [22:0] ROM_ADDR, input SNES_READ,
output ROM_CE, input SNES_WRITE,
output ROM_OE, input SNES_CS,
output ROM_WE, inout [7:0] SNES_DATA,
output ROM_BHE, input SNES_CPU_CLK,
output ROM_BLE, input SNES_REFRESH,
output SNES_IRQ,
output SNES_DATABUS_OE,
output SNES_DATABUS_DIR,
input SNES_SYSCLK,
/* SRAM signals */
/* Bus 1: PSRAM, 128Mbit, 16bit, 70ns */
inout [15:0] ROM_DATA,
output [22:0] ROM_ADDR,
output ROM_CE,
output ROM_OE,
output ROM_WE,
output ROM_BHE,
output ROM_BLE,
/* Bus 2: SRAM, 4Mbit, 8bit, 45ns */
inout [7:0] RAM_DATA,
output [18:0] RAM_ADDR,
output RAM_CE,
output RAM_OE,
output RAM_WE,
/* MCU signals */
input SPI_MOSI,
inout SPI_MISO,
input SPI_SS,
inout SPI_SCK,
input MCU_OVR,
output MCU_RDY,
output DAC_MCLK,
output DAC_LRCK,
output DAC_SDOUT,
/* SD signals */
input [3:0] SD_DAT,
inout SD_CMD,
inout SD_CLK,
/* debug */
output p113_out
);
/* MCU signals */
input SPI_MOSI,
inout SPI_MISO,
input SPI_SS,
inout SPI_SCK,
input MCU_OVR,
output DAC_MCLK,
output DAC_LRCK,
output DAC_SDOUT,
/* SD signals */
input [3:0] SD_DAT,
inout SD_CMD,
inout SD_CLK
/* debug */
//output DCM_IN_STOPPED,
//output DCM_FX_STOPPED
//input DCM_RST
);
assign DAC_MCLK = 1'b0; assign DAC_MCLK = 1'b0;
assign DAC_LRCK = 1'b0; assign DAC_LRCK = 1'b0;
assign DAC_SDOUT = 1'b0; assign DAC_SDOUT = 1'b0;
assign SD_CMD = 1'bZ;
assign SD_CLK = 1'bZ;
wire [7:0] spi_cmd_data; wire [7:0] spi_cmd_data;
wire [7:0] spi_param_data; wire [7:0] spi_param_data;
wire [7:0] spi_input_data; wire [7:0] spi_input_data;
@ -79,441 +88,318 @@ wire [2:0] spi_bit_cnt;
wire [23:0] MCU_ADDR; wire [23:0] MCU_ADDR;
wire [7:0] mcu_data_in; wire [7:0] mcu_data_in;
wire [7:0] mcu_data_out; wire [7:0] mcu_data_out;
wire [7:0] MCU_IN_DATA;
wire [7:0] MCU_OUT_DATA;
wire [3:0] MAPPER; wire [3:0] MAPPER;
wire [23:0] SAVERAM_MASK; wire [23:0] SAVERAM_MASK;
wire [23:0] ROM_MASK; wire [23:0] ROM_MASK;
wire [7:0] SD_DMA_SRAM_DATA;
wire [1:0] SD_DMA_TGT;
wire [10:0] SD_DMA_PARTIAL_START;
wire [10:0] SD_DMA_PARTIAL_END;
wire [10:0] dac_addr; wire [23:0] MAPPED_SNES_ADDR;
//wire [7:0] dac_volume; wire ROM_ADDR0;
wire [7:0] msu_volumerq_out;
wire [6:0] msu_status_out;
wire [31:0] msu_addressrq_out;
wire [15:0] msu_trackrq_out;
wire [13:0] msu_write_addr;
wire [13:0] msu_ptr_addr;
wire [7:0] MSU_SNES_DATA_IN;
wire [7:0] MSU_SNES_DATA_OUT;
wire [5:0] msu_status_reset_bits;
wire [5:0] msu_status_set_bits;
spi snes_spi(
spi snes_spi(.clk(CLK2), .clk(CLK2),
.MOSI(SPI_MOSI), .MOSI(SPI_MOSI),
.MISO(SPI_MISO), .MISO(SPI_MISO),
.SSEL(SPI_SS), .SSEL(SPI_SS),
.SCK(SPI_SCK), .SCK(SPI_SCK),
.cmd_ready(spi_cmd_ready), .cmd_ready(spi_cmd_ready),
.param_ready(spi_param_ready), .param_ready(spi_param_ready),
.cmd_data(spi_cmd_data), .cmd_data(spi_cmd_data),
.param_data(spi_param_data), .param_data(spi_param_data),
.endmessage(spi_endmessage), .endmessage(spi_endmessage),
.startmessage(spi_startmessage), .startmessage(spi_startmessage),
.input_data(spi_input_data), .input_data(spi_input_data),
.byte_cnt(spi_byte_cnt), .byte_cnt(spi_byte_cnt),
.bit_cnt(spi_bit_cnt) .bit_cnt(spi_bit_cnt)
); );
reg [7:0] MCU_DINr;
wire [7:0] MCU_DOUT;
mcu_cmd snes_mcu_cmd( mcu_cmd snes_mcu_cmd(
.clk(CLK2), .clk(CLK2),
.cmd_ready(spi_cmd_ready), .cmd_ready(spi_cmd_ready),
.param_ready(spi_param_ready), .param_ready(spi_param_ready),
.cmd_data(spi_cmd_data), .cmd_data(spi_cmd_data),
.param_data(spi_param_data), .param_data(spi_param_data),
.mcu_mapper(MAPPER), .mcu_sram_size(SRAM_SIZE),
.mcu_sram_size(SRAM_SIZE), .mcu_write(MCU_WRITE),
.mcu_read(MCU_READ), .mcu_data_in(MCU_DINr),
.mcu_write(MCU_WRITE), .mcu_data_out(MCU_DOUT),
.mcu_data_in(MCU_OUT_DATA), .spi_byte_cnt(spi_byte_cnt),
.mcu_data_out(MCU_IN_DATA), .spi_bit_cnt(spi_bit_cnt),
.spi_byte_cnt(spi_byte_cnt), .spi_data_out(spi_input_data),
.spi_bit_cnt(spi_bit_cnt), .addr_out(MCU_ADDR),
.spi_data_out(spi_input_data), .endmessage(spi_endmessage),
.addr_out(MCU_ADDR), .startmessage(spi_startmessage),
.endmessage(spi_endmessage), .saveram_mask_out(SAVERAM_MASK),
.startmessage(spi_startmessage), .rom_mask_out(ROM_MASK),
.saveram_mask_out(SAVERAM_MASK), .mcu_rrq(MCU_RRQ),
.rom_mask_out(ROM_MASK) .mcu_wrq(MCU_WRQ),
.mcu_rq_rdy(MCU_RDY)
); );
// dcm1: dfs 4x // dcm1: dfs 4x
my_dcm snes_dcm(.CLKIN(CLKIN), my_dcm snes_dcm(
.CLKFX(CLK2), .CLKIN(CLKIN),
.LOCKED(DCM_LOCKED), .CLKFX(CLK2),
.RST(DCM_RST), .LOCKED(DCM_LOCKED),
.STATUS(DCM_STATUS) .RST(DCM_RST),
); .STATUS(DCM_STATUS)
);
assign DCM_RST=0; assign DCM_RST=0;
/* reg [5:0] SNES_READr;
dcm_srl16 snes_dcm_resetter(.CLK(CLKIN), reg [5:0] SNES_WRITEr;
.Q(DCM_RST) reg [12:0] SNES_CPU_CLKr;
);
*/
//wire DCM_FX_STOPPED = DCM_STATUS[2];
//always @(posedge CLKIN) begin
// if(DCM_FX_STOPPED)
// DCM_RSTr <= 1'b1;
// else
// DCM_RSTr <= 1'b0;
//end
/*reg DO_DCM_RESET, DCM_RESETTING;
reg DCM_RSTr;
assign DCM_RST = DCM_RSTr;
reg [2:0] DCM_RESET_CNT;
initial DO_DCM_RESET = 1'b0;
initial DCM_RESETTING = 1'b0;
always @(posedge CLKIN) begin
if(!DCM_LOCKED && !DCM_RESETTING) begin
DCM_RSTr <= 1'b1;
DO_DCM_RESET <= 1'b1;
DCM_RESET_CNT <= 3'b0;
end else if (DO_DCM_RESET) begin
DCM_RSTr <= 1'b0;
DCM_RESET_CNT <= DCM_RESET_CNT + 1;
end
end
always @(posedge CLKIN) begin
if (DO_DCM_RESET)
DCM_RESETTING <= 1'b1;
else if (DCM_RESET_CNT == 3'b110)
DCM_RESETTING <= 1'b0;
end
*/
wire SNES_RW;
reg [1:0] SNES_READr;
reg [1:0] SNES_WRITEr;
reg [1:0] SNES_CSr;
reg [5:0] SNES_CPU_CLKr;
reg [5:0] SNES_RWr; reg [5:0] SNES_RWr;
reg [23:0] SNES_ADDRr; reg [23:0] SNES_ADDRr;
reg [23:0] SNES_ADDR_PREVr;
reg [3:0] SNES_ADDRCHGr;
wire SNES_READs = (SNES_READr == 2'b11); wire SNES_RW = (SNES_READ & SNES_WRITE);
wire SNES_WRITEs = (SNES_WRITEr == 2'b11);
wire SNES_CSs = (SNES_CSr == 2'b11);
wire SNES_CPU_CLKs = SNES_CPU_CLK; // (SNES_CPU_CLKr == 2'b11);
wire SNES_RW_start = (SNES_RWr == 6'b111110); // falling edge marks beginning of cycle wire SNES_RW_start = (SNES_RWr == 6'b111110); // falling edge marks beginning of cycle
wire SNES_cycle_start = (SNES_CPU_CLKr == 6'b000001); wire SNES_RD_start = (SNES_READr == 6'b111110);
wire SNES_ADDRCHG = (SNES_ADDRr != SNES_ADDR_PREVr); wire SNES_WR_start = (SNES_WRITEr == 6'b111110);
wire SNES_addr_start = (SNES_ADDRCHGr[0] == 1'b1); wire SNES_cycle_start = (SNES_CPU_CLKr[5:0] == 6'b000001);
wire SNES_cycle_end = (SNES_CPU_CLKr[5:0] == 6'b111110);
assign SNES_RW = (SNES_READ & SNES_WRITE);
always @(posedge CLK2) begin always @(posedge CLK2) begin
SNES_READr <= {SNES_READr[0], SNES_READ}; SNES_READr <= {SNES_READr[4:0], SNES_READ};
SNES_WRITEr <= {SNES_WRITEr[0], SNES_WRITE}; SNES_WRITEr <= {SNES_WRITEr[4:0], SNES_WRITE};
SNES_CSr <= {SNES_CSr[0], SNES_CS}; SNES_CPU_CLKr <= {SNES_CPU_CLKr[11:0], SNES_CPU_CLK};
SNES_CPU_CLKr <= {SNES_CPU_CLKr[4:0], SNES_CPU_CLK}; SNES_RWr <= {SNES_RWr[4:0], SNES_RW};
SNES_RWr <= {SNES_RWr[4:0], SNES_RW};
end end
reg ADDR_WRITE;
//reg [23:0] SNES_ADDRr;
//wire [23:0] SNES_ADDRw = SNES_ADDR;
wire ROM_SEL; wire ROM_SEL;
address snes_addr( address snes_addr(
.CLK(CLK2), .CLK(CLK2),
.MAPPER(MAPPER), .SNES_ADDR(SNES_ADDR), // requested address from SNES
.SNES_ADDR(SNES_ADDR), // requested address from SNES .SNES_CS(SNES_CS), // "CART" pin from SNES (active low)
.SNES_CS(SNES_CS), // "CART" pin from SNES (active low) .ROM_ADDR(MAPPED_SNES_ADDR), // Address to request from SRAM (active low)
.ROM_ADDR(ROM_ADDR), // Address to request from SRAM (active low) .ROM_SEL(ROM_SEL), // which SRAM unit to access
.ROM_SEL(ROM_SEL), // which SRAM unit to access .IS_SAVERAM(IS_SAVERAM),
.MCU_OVR(MCU_OVR), // enable MCU mode (active low) .IS_ROM(IS_ROM),
.MODE(MODE), // MCU(1) or SNES(0) ("bus phase") .MCU_ADDR(MCU_ADDR),
.IS_SAVERAM(IS_SAVERAM), .SAVERAM_MASK(SAVERAM_MASK),
.IS_ROM(IS_ROM), .ROM_MASK(ROM_MASK)
.MCU_ADDR(MCU_ADDR), );
.ROM_ADDR0(ROM_ADDR0),
.SAVERAM_MASK(SAVERAM_MASK),
.ROM_MASK(ROM_MASK)
);
wire SNES_READ_CYCLEw; wire SNES_READ_CYCLEw;
wire SNES_WRITE_CYCLEw; wire SNES_WRITE_CYCLEw;
wire MCU_READ_CYCLEw; wire MCU_READ_CYCLEw;
wire MCU_WRITE_CYCLEw; wire MCU_WRITE_CYCLEw;
data snes_data(.CLK(CLK2),
.SNES_READ(SNES_READ),
.SNES_WRITE(SNES_WRITE),
.MCU_READ(MCU_READ),
.MCU_WRITE(MCU_WRITE),
.SNES_DATA(SNES_DATA),
.ROM_DATA(ROM_DATA),
.MODE(MODE),
.SNES_DATA_TO_MEM(SNES_DATA_TO_MEM),
.MCU_DATA_TO_MEM(MCU_DATA_TO_MEM),
.ROM_DATA_TO_SNES_MEM(ROM_DATA_TO_SNES_MEM),
.ROM_DATA_TO_MCU_MEM(ROM_DATA_TO_MCU_MEM),
.MCU_OVR(MCU_OVR),
.MCU_IN_DATA(MCU_IN_DATA),
.MCU_OUT_DATA(MCU_OUT_DATA),
.ROM_ADDR0(ROM_ADDR0),
.MSU_DATA_IN(MSU_SNES_DATA_IN),
.MSU_DATA_OUT(MSU_SNES_DATA_OUT),
.msu_enable(msu_enable)
);
parameter MODE_SNES = 1'b0; parameter MODE_SNES = 1'b0;
parameter MODE_MCU = 1'b1; parameter MODE_MCU = 1'b1;
parameter STATE_0 = 14'b00000000000001; parameter ST_IDLE = 18'b000000000000000001;
parameter STATE_1 = 14'b00000000000010; parameter ST_SNES_RD_ADDR = 18'b000000000000000010;
parameter STATE_2 = 14'b00000000000100; parameter ST_SNES_RD_WAIT = 18'b000000000000000100;
parameter STATE_3 = 14'b00000000001000; parameter ST_SNES_RD_END = 18'b000000000000001000;
parameter STATE_4 = 14'b00000000010000; parameter ST_SNES_WR_ADDR = 18'b000000000000010000;
parameter STATE_5 = 14'b00000000100000; parameter ST_SNES_WR_WAIT1= 18'b000000000000100000;
parameter STATE_6 = 14'b00000001000000; parameter ST_SNES_WR_DATA = 18'b000000000001000000;
parameter STATE_7 = 14'b00000010000000; parameter ST_SNES_WR_WAIT2= 18'b000000000010000000;
parameter STATE_8 = 14'b00000100000000; parameter ST_SNES_WR_END = 18'b000000000100000000;
parameter STATE_9 = 14'b00001000000000; parameter ST_MCU_RD_ADDR = 18'b000000001000000000;
parameter STATE_10 = 14'b00010000000000; parameter ST_MCU_RD_WAIT = 18'b000000010000000000;
parameter STATE_11 = 14'b00100000000000; parameter ST_MCU_RD_WAIT2 = 18'b000000100000000000;
parameter STATE_12 = 14'b01000000000000; parameter ST_MCU_RD_END = 18'b000001000000000000;
parameter STATE_IDLE = 14'b10000000000000; parameter ST_MCU_WR_ADDR = 18'b000010000000000000;
parameter ST_MCU_WR_WAIT = 18'b000100000000000000;
parameter ST_MCU_WR_WAIT2 = 18'b001000000000000000;
parameter ST_MCU_WR_END = 18'b010000000000000000;
reg [13:0] STATE; parameter ROM_RD_WAIT = 4'h4;
reg [3:0] STATEIDX; parameter ROM_RD_WAIT_MCU = 4'h5;
parameter ROM_WR_WAIT1 = 4'h2;
parameter ROM_WR_WAIT2 = 4'h3;
parameter ROM_WR_WAIT_MCU = 4'h6;
reg [17:0] STATE;
initial STATE = ST_IDLE;
reg [1:0] CYCLE_RESET; reg [1:0] CYCLE_RESET;
reg ROM_WE_MASK; reg ROM_WE_MASK;
reg ROM_OE_MASK; reg ROM_OE_MASK;
reg [13:0] ROM_WE_ARRAY [3:0]; reg [7:0] SNES_DINr;
reg [13:0] ROM_OE_ARRAY [3:0]; reg [7:0] ROM_DOUTr;
reg [13:0] SNES_DATA_TO_MEM_ARRAY[1:0]; assign SNES_DATA = (!SNES_READ) ? SNES_DINr : 8'bZ;
reg [13:0] MCU_DATA_TO_MEM_ARRAY[1:0];
reg [13:0] ROM_DATA_TO_SNES_MEM_ARRAY[1:0];
reg [13:0] ROM_DATA_TO_MCU_MEM_ARRAY[1:0];
reg [13:0] MODE_ARRAY;
reg SNES_READ_CYCLE;
reg SNES_WRITE_CYCLE;
reg MCU_READ_CYCLE;
reg MCU_WRITE_CYCLE;
reg MCU_SPI_WRITEONCE;
reg MCU_SPI_READONCE;
reg MCU_SPI_WRITE;
reg MCU_SPI_READ;
reg MCU_SPI_ADDR_INCREMENT;
reg [7:0] MCU_DATA_IN;
reg [3:0] MAPPER_BUF;
reg SNES_DATABUS_OE_BUF;
reg SNES_DATABUS_DIR_BUF;
assign MODE = !MCU_OVR ? MODE_MCU : MODE_ARRAY[STATEIDX];
initial begin
CYCLE_RESET = 2'b0;
STATE = STATE_IDLE;
STATEIDX = 13;
ROM_WE_MASK = 1'b1;
ROM_OE_MASK = 1'b1;
SNES_READ_CYCLE = 1'b1;
SNES_WRITE_CYCLE = 1'b1;
MCU_READ_CYCLE = 1'b1;
MCU_WRITE_CYCLE = 1'b1;
MODE_ARRAY = 14'b0_000000_1111111;
ROM_WE_ARRAY[2'b00] = 14'b1_000000_0000000;
ROM_WE_ARRAY[2'b01] = 14'b1_000000_1111111;
ROM_WE_ARRAY[2'b10] = 14'b1_111111_0000000;
ROM_WE_ARRAY[2'b11] = 14'b1_111111_1111111;
ROM_OE_ARRAY[2'b00] = 14'b1_111111_1111111;
ROM_OE_ARRAY[2'b01] = 14'b1_111111_0000000;
ROM_OE_ARRAY[2'b10] = 14'b0_000000_1111111;
ROM_OE_ARRAY[2'b11] = 14'b0_000000_0000000;
SNES_DATA_TO_MEM_ARRAY[1'b0] = 14'b0_000100_0000000; // SNES write
/* 13'b0001000000000 */
SNES_DATA_TO_MEM_ARRAY[1'b1] = 14'b0_000000_0000000; // SNES read
MCU_DATA_TO_MEM_ARRAY[1'b0] = 14'b1_111111_1111111; // MCU write
// MCU_DATA_TO_MEM_ARRAY[1'b0] = 13'b0000000001000; // MCU write
MCU_DATA_TO_MEM_ARRAY[1'b1] = 14'b0_000000_0000000; // MCU read
ROM_DATA_TO_SNES_MEM_ARRAY[1'b0] = 14'b0_000000_0000000; // SNES write
ROM_DATA_TO_SNES_MEM_ARRAY[1'b1] = 14'b0_000010_0000000; // SNES read
/* 13'b0000100000000; */
ROM_DATA_TO_MCU_MEM_ARRAY[1'b0] = 14'b0_000000_0000000; // MCU write
ROM_DATA_TO_MCU_MEM_ARRAY[1'b1] = 14'b0_000000_0000001; // MCU read
// SRAM_DATA_TO_MCU_MEM_ARRAY[1'b1] = 13'b0000000000001; // MCU read
end
// falling edge of SNES /RD or /WR marks the beginning of a new cycle
// SNES READ or WRITE always starts @posedge CLK !!
// CPU cycle can be 6, 8 or 12 CLKIN cycles so we must satisfy
// the minimum of 6 SNES cycles to get everything done.
// we have 24 internal cycles to work with. (CLKIN * 4)
reg [3:0] ST_MEM_DELAYr;
reg MCU_RD_PENDr;
reg MCU_WR_PENDr;
reg [23:0] ROM_ADDRr;
reg NEED_SNES_ADDRr;
always @(posedge CLK2) begin always @(posedge CLK2) begin
CYCLE_RESET <= {CYCLE_RESET[0], SNES_cycle_start}; if(SNES_cycle_end) NEED_SNES_ADDRr <= 1'b1;
else if(STATE & (ST_SNES_RD_END | ST_SNES_WR_END)) NEED_SNES_ADDRr <= 1'b0;
end end
wire ASSERT_SNES_ADDR = SNES_CPU_CLK & NEED_SNES_ADDRr;
assign ROM_ADDR = (ASSERT_SNES_ADDR) ? MAPPED_SNES_ADDR[23:1] : ROM_ADDRr[23:1];
assign ROM_ADDR0 = (ASSERT_SNES_ADDR) ? MAPPED_SNES_ADDR[0] : ROM_ADDRr[0];
reg ROM_WEr;
initial ROM_WEr = 1'b1;
reg RQ_MCU_RDYr;
initial RQ_MCU_RDYr = 1'b1;
assign MCU_RDY = RQ_MCU_RDYr;
always @(posedge CLK2) begin always @(posedge CLK2) begin
MCU_READ_CYCLE <= MCU_READ; if(MCU_RRQ) begin
MCU_WRITE_CYCLE <= MCU_WRITE; MCU_RD_PENDr <= 1'b1;
if (SNES_cycle_start) begin RQ_MCU_RDYr <= 1'b0;
SNES_READ_CYCLE <= SNES_READ; end else if(MCU_WRQ) begin
SNES_WRITE_CYCLE <= SNES_WRITE; MCU_WR_PENDr <= 1'b1;
STATE <= STATE_0; RQ_MCU_RDYr <= 1'b0;
STATEIDX <= 12; end else if(STATE & (ST_MCU_RD_END | ST_MCU_WR_END)) begin
end else begin MCU_RD_PENDr <= 1'b0;
case (STATE) MCU_WR_PENDr <= 1'b0;
STATE_0: begin RQ_MCU_RDYr <= 1'b1;
STATE <= STATE_1; STATEIDX <= 11; end
end
STATE_1: begin
STATE <= STATE_2; STATEIDX <= 10;
end
STATE_2: begin
STATE <= STATE_3; STATEIDX <= 9;
end
STATE_3: begin
STATE <= STATE_4; STATEIDX <= 8;
end
STATE_4: begin
STATE <= STATE_5; STATEIDX <= 7;
end
STATE_5: begin
STATE <= STATE_6; STATEIDX <= 6;
end
STATE_6: begin
STATE <= STATE_7; STATEIDX <= 5;
end
STATE_7: begin
STATE <= STATE_8; STATEIDX <= 4;
end
STATE_8: begin
STATE <= STATE_9; STATEIDX <= 3;
end
STATE_9: begin
STATE <= STATE_10; STATEIDX <= 2;
end
STATE_10: begin
STATE <= STATE_11; STATEIDX <= 1;
end
STATE_11: begin
STATE <= STATE_12; STATEIDX <= 0;
end
STATE_12: begin
STATE <= STATE_IDLE; STATEIDX <= 13;
end
STATE_IDLE: begin
STATE <= STATE_IDLE; STATEIDX <= 13;
end
default: begin
STATE <= STATE_IDLE; STATEIDX <= 13;
end
endcase
end
end end
/*
reg snes_wr_cycle;
always @(posedge CLK2) begin always @(posedge CLK2) begin
if(SNES_cycle_start) begin
STATE <= ST_SNES_RD_ADDR;
end else if(SNES_WR_start) begin
STATE <= ST_SNES_WR_ADDR;
end else begin
case(STATE)
ST_IDLE: begin
ROM_ADDRr <= MAPPED_SNES_ADDR;
if(MCU_RD_PENDr) STATE <= ST_MCU_RD_ADDR;
else if(MCU_WR_PENDr) STATE <= ST_MCU_WR_ADDR;
else STATE <= ST_IDLE;
end
ST_SNES_RD_ADDR: begin
STATE <= ST_SNES_RD_WAIT;
ST_MEM_DELAYr <= ROM_RD_WAIT;
end
ST_SNES_RD_WAIT: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_RD_END;
else STATE <= ST_SNES_RD_WAIT;
if(ROM_ADDR0) SNES_DINr <= ROM_DATA[7:0];
else SNES_DINr <= ROM_DATA[15:8];
end
ST_SNES_RD_END: begin
STATE <= ST_IDLE;
if(ROM_ADDR0) SNES_DINr <= ROM_DATA[7:0];
else SNES_DINr <= ROM_DATA[15:8];
end
ST_SNES_WR_ADDR: begin
ROM_WEr <= (!IS_SAVERAM);
snes_wr_cycle <= 1'b1;
STATE <= ST_SNES_WR_WAIT1;
ST_MEM_DELAYr <= ROM_WR_WAIT1;
end
ST_SNES_WR_WAIT1: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_WR_DATA;
else STATE <= ST_SNES_WR_WAIT1;
end
ST_SNES_WR_DATA: begin
ROM_DOUTr <= SNES_DATA;
ST_MEM_DELAYr <= ROM_WR_WAIT2;
STATE <= ST_SNES_WR_WAIT2;
end
ST_SNES_WR_WAIT2: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_WR_END;
else STATE <= ST_SNES_WR_WAIT2;
end
ST_SNES_WR_END: begin
STATE <= ST_IDLE;
ROM_WEr <= 1'b1;
snes_wr_cycle <= 1'b0;
end
ST_MCU_RD_ADDR: begin
ROM_ADDRr <= MCU_ADDR;
STATE <= ST_MCU_RD_WAIT;
ST_MEM_DELAYr <= ROM_RD_WAIT_MCU;
end
ST_MCU_RD_WAIT: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
if(ST_MEM_DELAYr == 4'h0) begin
STATE <= ST_MCU_RD_WAIT2;
ST_MEM_DELAYr <= 4'h2;
end
else STATE <= ST_MCU_RD_WAIT;
if(ROM_ADDR0) MCU_DINr <= ROM_DATA[7:0];
else MCU_DINr <= ROM_DATA[15:8];
end
ST_MCU_RD_WAIT2: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
if(ST_MEM_DELAYr == 4'h0) begin
STATE <= ST_MCU_RD_END;
end else STATE <= ST_MCU_RD_WAIT2;
end
ST_MCU_RD_END: begin
STATE <= ST_IDLE;
end
ST_MCU_WR_ADDR: begin
ROM_ADDRr <= MCU_ADDR;
STATE <= ST_MCU_WR_WAIT;
ST_MEM_DELAYr <= ROM_WR_WAIT_MCU;
ROM_DOUTr <= MCU_DOUT;
ROM_WEr <= 1'b0;
end
ST_MCU_WR_WAIT: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
if(ST_MEM_DELAYr == 4'h0) begin
ROM_WEr <= 1'b1;
STATE <= ST_MCU_WR_WAIT2;
ST_MEM_DELAYr <= 4'h2;
end
else STATE <= ST_MCU_WR_WAIT;
end
ST_MCU_WR_WAIT2: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
if(ST_MEM_DELAYr == 4'h0) begin
STATE <= ST_MCU_WR_END;
end else STATE <= ST_MCU_WR_WAIT2;
end
ST_MCU_WR_END: begin
STATE <= ST_IDLE;
end
case (STATE) endcase
STATE_9: begin end
STATEIDX <= 9;
end
STATE_0: begin
STATEIDX <= 8;
end
STATE_1: begin
STATEIDX <= 7;
end
STATE_2: begin
STATEIDX <= 6;
end
STATE_3: begin
STATEIDX <= 5;
end
STATE_4: begin
STATEIDX <= 4;
end
STATE_5: begin
STATEIDX <= 3;
end
STATE_6: begin
STATEIDX <= 2;
end
STATE_7: begin
STATEIDX <= 1;
end
STATE_8: begin
STATEIDX <= 0;
end
default:
STATEIDX <= 9;
endcase
end end
*/
// When in MCU mode, enable SRAM_WE according to MCU programming
// else enable SRAM_WE according to state&cycle
assign ROM_WE = !MCU_OVR ? MCU_WRITE
: ((!IS_SAVERAM & !MODE) | ROM_WE_ARRAY[{SNES_WRITE_CYCLE, MCU_WRITE_CYCLE}][STATEIDX]);
// When in MCU mode, enable SRAM_OE whenever not writing assign ROM_DATA[7:0] = ROM_ADDR0
// else enable SRAM_OE according to state&cycle ?(!ROM_WE ? ROM_DOUTr : 8'bZ)
assign ROM_OE = !MCU_OVR ? MCU_READ :8'bZ;
: ROM_OE_ARRAY[{SNES_WRITE_CYCLE, MCU_WRITE_CYCLE}][STATEIDX];
assign ROM_CE = 1'b0; // !MCU_OVR ? (MCU_READ & MCU_WRITE) : ROM_SEL; assign ROM_DATA[15:8] = ROM_ADDR0 ? 8'bZ
:(!ROM_WE ? ROM_DOUTr : 8'bZ);
assign ROM_WE = ROM_WEr | (ASSERT_SNES_ADDR & ~snes_wr_cycle);
assign ROM_OE = 1'b0;
assign ROM_CE = 1'b0;
assign ROM_BHE = !ROM_WE ? ROM_ADDR0 : 1'b0; assign ROM_BHE = !ROM_WE ? ROM_ADDR0 : 1'b0;
assign ROM_BLE = !ROM_WE ? !ROM_ADDR0 : 1'b0; assign ROM_BLE = !ROM_WE ? !ROM_ADDR0 : 1'b0;
//assign SRAM_BHE = SRAM_ADDR0; assign SNES_DATABUS_OE = ((IS_ROM & SNES_CS)
//assign SRAM_BLE = ~SRAM_ADDR0; |(!IS_ROM & !IS_SAVERAM)
|(SNES_READ & SNES_WRITE)
);
// dumb version
//assign SRAM_OE = !MCU_ENA ? MCU_READ : SNES_READs;
//assign SRAM_WE = !MCU_ENA ? MCU_WRITE : 1'b1;
//assign SNES_DATABUS_OE = (!IS_SAVERAM & SNES_CS) | (SNES_READ & SNES_WRITE);
assign SNES_DATABUS_OE = msu_enable ? 1'b0 : ((IS_ROM & SNES_CS) | (!IS_ROM & !IS_SAVERAM) | (SNES_READ & SNES_WRITE));
assign SNES_DATABUS_DIR = !SNES_READ ? 1'b1 : 1'b0; assign SNES_DATABUS_DIR = !SNES_READ ? 1'b1 : 1'b0;
assign SNES_DATA_TO_MEM = SNES_DATA_TO_MEM_ARRAY[SNES_WRITE_CYCLE][STATEIDX]; assign SNES_IRQ = 1'b0;
assign MCU_DATA_TO_MEM = MCU_DATA_TO_MEM_ARRAY[MCU_WRITE_CYCLE][STATEIDX];
assign ROM_DATA_TO_SNES_MEM = ROM_DATA_TO_SNES_MEM_ARRAY[SNES_WRITE_CYCLE][STATEIDX]; assign p113_out = 1'b0;
assign ROM_DATA_TO_MCU_MEM = ROM_DATA_TO_MCU_MEM_ARRAY[MCU_WRITE_CYCLE][STATEIDX];
assign SNES_READ_CYCLEw = SNES_READ_CYCLE;
assign SNES_WRITE_CYCLEw = SNES_WRITE_CYCLE;
assign IRQ_DIR = 1'b0;
assign SNES_IRQ = 1'bZ;
endmodule endmodule

View File

@ -9,44 +9,44 @@
<!-- along with the project source files, is sufficient to open and --> <!-- along with the project source files, is sufficient to open and -->
<!-- implement in ISE Project Navigator. --> <!-- implement in ISE Project Navigator. -->
<!-- --> <!-- -->
<!-- Copyright (c) 1995-2010 Xilinx, Inc. All rights reserved. --> <!-- Copyright (c) 1995-2011 Xilinx, Inc. All rights reserved. -->
</header> </header>
<version xil_pn:ise_version="12.3" xil_pn:schema_version="2"/> <version xil_pn:ise_version="13.2" xil_pn:schema_version="2"/>
<files> <files>
<file xil_pn:name="address.v" xil_pn:type="FILE_VERILOG"> <file xil_pn:name="address.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation"/> <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
<association xil_pn:name="Implementation"/> <association xil_pn:name="Implementation" xil_pn:seqID="4"/>
</file> </file>
<file xil_pn:name="spi.v" xil_pn:type="FILE_VERILOG"> <file xil_pn:name="spi.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation"/> <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/>
<association xil_pn:name="Implementation"/> <association xil_pn:name="Implementation" xil_pn:seqID="1"/>
</file> </file>
<file xil_pn:name="main.v" xil_pn:type="FILE_VERILOG"> <file xil_pn:name="main.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation"/> <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="3"/>
<association xil_pn:name="Implementation"/> <association xil_pn:name="Implementation" xil_pn:seqID="5"/>
</file> </file>
<file xil_pn:name="dcm.v" xil_pn:type="FILE_VERILOG"> <file xil_pn:name="dcm.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation"/> <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="4"/>
<association xil_pn:name="Implementation"/> <association xil_pn:name="Implementation" xil_pn:seqID="3"/>
</file> </file>
<file xil_pn:name="data.v" xil_pn:type="FILE_VERILOG"> <file xil_pn:name="data.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation"/> <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="5"/>
<association xil_pn:name="Implementation"/> <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
</file>
<file xil_pn:name="avr_cmd.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation"/>
<association xil_pn:name="Implementation"/>
</file> </file>
<file xil_pn:name="main.ucf" xil_pn:type="FILE_UCF"> <file xil_pn:name="main.ucf" xil_pn:type="FILE_UCF">
<association xil_pn:name="Implementation"/> <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
</file>
<file xil_pn:name="mcu_cmd.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="58"/>
<association xil_pn:name="Implementation" xil_pn:seqID="2"/>
</file> </file>
</files> </files>
<properties> <properties>
<property xil_pn:name="Add I/O Buffers" xil_pn:value="true" xil_pn:valueState="default"/> <property xil_pn:name="Add I/O Buffers" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Logic Optimization Across Hierarchy" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Allow Logic Optimization Across Hierarchy" xil_pn:value="true" xil_pn:valueState="non-default"/>
<property xil_pn:name="Allow SelectMAP Pins to Persist" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Allow SelectMAP Pins to Persist" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Unexpanded Blocks" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Allow Unexpanded Blocks" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Unmatched LOC Constraints" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Allow Unmatched LOC Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
@ -99,7 +99,7 @@
<property xil_pn:name="Do Not Escape Signal and Instance Names in Netlist" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Do Not Escape Signal and Instance Names in Netlist" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Done (Output Events)" xil_pn:value="Default (4)" xil_pn:valueState="default"/> <property xil_pn:name="Done (Output Events)" xil_pn:value="Default (4)" xil_pn:valueState="default"/>
<property xil_pn:name="Drive Done Pin High" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Drive Done Pin High" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable BitStream Compression" xil_pn:value="true" xil_pn:valueState="non-default"/> <property xil_pn:name="Enable BitStream Compression" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Cyclic Redundancy Checking (CRC)" xil_pn:value="true" xil_pn:valueState="default"/> <property xil_pn:name="Enable Cyclic Redundancy Checking (CRC)" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Debugging of Serial Mode BitStream" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Enable Debugging of Serial Mode BitStream" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Hardware Co-Simulation" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Enable Hardware Co-Simulation" xil_pn:value="false" xil_pn:valueState="default"/>
@ -157,12 +157,14 @@
<property xil_pn:name="JTAG Pin TDI" xil_pn:value="Pull Up" xil_pn:valueState="default"/> <property xil_pn:name="JTAG Pin TDI" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TDO" xil_pn:value="Pull Up" xil_pn:valueState="default"/> <property xil_pn:name="JTAG Pin TDO" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TMS" xil_pn:value="Pull Up" xil_pn:valueState="default"/> <property xil_pn:name="JTAG Pin TMS" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Keep Hierarchy" xil_pn:value="No" xil_pn:valueState="default"/> <property xil_pn:name="Keep Hierarchy" xil_pn:value="Yes" xil_pn:valueState="non-default"/>
<property xil_pn:name="Language" xil_pn:value="VHDL" xil_pn:valueState="default"/> <property xil_pn:name="Language" xil_pn:value="VHDL" xil_pn:valueState="default"/>
<property xil_pn:name="Last Applied Goal" xil_pn:value="Balanced" xil_pn:valueState="default"/> <property xil_pn:name="Last Applied Goal" xil_pn:value="Balanced" xil_pn:valueState="default"/>
<property xil_pn:name="Last Applied Strategy" xil_pn:value="Xilinx Default (unlocked)" xil_pn:valueState="default"/> <property xil_pn:name="Last Applied Strategy" xil_pn:value="Xilinx Default (unlocked)" xil_pn:valueState="default"/>
<property xil_pn:name="Last Unlock Status" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Last Unlock Status" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Launch SDK after Export" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Library for Verilog Sources" xil_pn:value="" xil_pn:valueState="default"/> <property xil_pn:name="Library for Verilog Sources" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Load glbl" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Logical Shifter Extraction" xil_pn:value="true" xil_pn:valueState="default"/> <property xil_pn:name="Logical Shifter Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Manual Implementation Compile Order" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Manual Implementation Compile Order" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Map Effort Level" xil_pn:value="High" xil_pn:valueState="default"/> <property xil_pn:name="Map Effort Level" xil_pn:value="High" xil_pn:valueState="default"/>
@ -180,8 +182,8 @@
<property xil_pn:name="Number of Clock Buffers" xil_pn:value="8" xil_pn:valueState="default"/> <property xil_pn:name="Number of Clock Buffers" xil_pn:value="8" xil_pn:valueState="default"/>
<property xil_pn:name="Number of Paths in Error/Verbose Report" xil_pn:value="3" xil_pn:valueState="default"/> <property xil_pn:name="Number of Paths in Error/Verbose Report" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Number of Paths in Error/Verbose Report Post Trace" xil_pn:value="3" xil_pn:valueState="default"/> <property xil_pn:name="Number of Paths in Error/Verbose Report Post Trace" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Optimization Effort" xil_pn:value="Normal" xil_pn:valueState="default"/> <property xil_pn:name="Optimization Effort" xil_pn:value="High" xil_pn:valueState="non-default"/>
<property xil_pn:name="Optimization Goal" xil_pn:value="Speed" xil_pn:valueState="default"/> <property xil_pn:name="Optimization Goal" xil_pn:value="Area" xil_pn:valueState="non-default"/>
<property xil_pn:name="Optimization Strategy (Cover Mode)" xil_pn:value="Area" xil_pn:valueState="default"/> <property xil_pn:name="Optimization Strategy (Cover Mode)" xil_pn:value="Area" xil_pn:valueState="default"/>
<property xil_pn:name="Optimize Instantiated Primitives" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Optimize Instantiated Primitives" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Other Bitgen Command Line Options" xil_pn:value="" xil_pn:valueState="default"/> <property xil_pn:name="Other Bitgen Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
@ -205,7 +207,7 @@
<property xil_pn:name="Overwrite Compiled Libraries" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Overwrite Compiled Libraries" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Pack I/O Registers into IOBs" xil_pn:value="Auto" xil_pn:valueState="default"/> <property xil_pn:name="Pack I/O Registers into IOBs" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Pack I/O Registers/Latches into IOBs" xil_pn:value="Off" xil_pn:valueState="default"/> <property xil_pn:name="Pack I/O Registers/Latches into IOBs" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="Package" xil_pn:value="pq208" xil_pn:valueState="default"/> <property xil_pn:name="Package" xil_pn:value="pq208" xil_pn:valueState="non-default"/>
<property xil_pn:name="Perform Advanced Analysis" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Perform Advanced Analysis" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Perform Advanced Analysis Post Trace" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Perform Advanced Analysis Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Perform Timing-Driven Packing and Placement" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Perform Timing-Driven Packing and Placement" xil_pn:value="false" xil_pn:valueState="default"/>
@ -221,9 +223,8 @@
<property xil_pn:name="Power Reduction Par" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Power Reduction Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Preferred Language" xil_pn:value="Verilog" xil_pn:valueState="default"/> <property xil_pn:name="Preferred Language" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="Priority Encoder Extraction" xil_pn:value="Yes" xil_pn:valueState="default"/> <property xil_pn:name="Priority Encoder Extraction" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Produce Advanced Verbose Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Produce Verbose Report" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Produce Verbose Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Project Description" xil_pn:value="lite (bootstrap) configware for embedding into MCU firmware. For showing status messages even with no configware loaded from SD card" xil_pn:valueState="non-default"/> <property xil_pn:name="Project Description" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Property Specification in Project File" xil_pn:value="Store all values" xil_pn:valueState="default"/> <property xil_pn:name="Property Specification in Project File" xil_pn:value="Store all values" xil_pn:valueState="default"/>
<property xil_pn:name="RAM Extraction" xil_pn:value="true" xil_pn:valueState="default"/> <property xil_pn:name="RAM Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="RAM Style" xil_pn:value="Auto" xil_pn:valueState="default"/> <property xil_pn:name="RAM Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
@ -291,6 +292,7 @@
<property xil_pn:name="Trim Unconnected Signals" xil_pn:value="true" xil_pn:valueState="default"/> <property xil_pn:name="Trim Unconnected Signals" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Tristate On Configuration Pulse Width" xil_pn:value="0" xil_pn:valueState="default"/> <property xil_pn:name="Tristate On Configuration Pulse Width" xil_pn:value="0" xil_pn:valueState="default"/>
<property xil_pn:name="Unused IOB Pins" xil_pn:value="Pull Down" xil_pn:valueState="default"/> <property xil_pn:name="Unused IOB Pins" xil_pn:value="Pull Down" xil_pn:valueState="default"/>
<property xil_pn:name="Use 64-bit PlanAhead on 64-bit Systems" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Use Clock Enable" xil_pn:value="Yes" xil_pn:valueState="default"/> <property xil_pn:name="Use Clock Enable" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Use Custom Project File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Post-Map" xil_pn:value="false" xil_pn:valueState="default"/> <property xil_pn:name="Use Custom Project File Post-Map" xil_pn:value="false" xil_pn:valueState="default"/>

View File

@ -19,25 +19,23 @@
// //
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
module spi(input clk, module spi(
input SCK, input clk,
input MOSI, input SCK,
inout MISO, input MOSI,
input SSEL, inout MISO,
output cmd_ready, input SSEL,
output param_ready, output cmd_ready,
output [7:0] cmd_data, output param_ready,
output [7:0] param_data, output [7:0] cmd_data,
output endmessage, output [7:0] param_data,
output startmessage, output endmessage,
input [7:0] input_data, output startmessage,
output [31:0] byte_cnt, input [7:0] input_data,
output [2:0] bit_cnt output [31:0] byte_cnt,
output [2:0] bit_cnt
);
// SD "DMA" extension
/*input sd_dma_sck,
input sd_dma_ovr*/);
reg [7:0] cmd_data_r; reg [7:0] cmd_data_r;
reg [7:0] param_data_r; reg [7:0] param_data_r;
@ -68,46 +66,71 @@ reg byte_received; // high when a byte has been received
reg [7:0] byte_data_received; reg [7:0] byte_data_received;
assign bit_cnt = bitcnt; assign bit_cnt = bitcnt;
/*
always @(posedge clk) always @(posedge clk)
begin begin
if(~SSEL_active) begin if(~SSEL_active) begin
bitcnt <= 3'b000; bitcnt <= 3'b000;
end end
else if(SCK_risingedge) begin else if(SCK_risingedge) begin
bitcnt <= bitcnt + 3'b001; bitcnt <= bitcnt + 3'b001;
// shift received data into the register // shift received data into the register
byte_data_received <= {byte_data_received[6:0], MOSI_data}; byte_data_received <= {byte_data_received[6:0], MOSI_data};
end end
end
*/
always @(posedge SCK) begin
if(SSEL) bitcnt <= 3'b000;
else begin
bitcnt <= bitcnt + 3'b001;
byte_data_received <= {byte_data_received[6:0], MOSI};
end
if(~SSEL && bitcnt==3'b111) byte_received <= 1'b1;
else byte_received <= 1'b0;
end end
always @(posedge clk) byte_received <= SSEL_active && SCK_risingedge && (bitcnt==3'b111); //always @(posedge clk)
// byte_received <= SSEL_active && SCK_risingedge && (bitcnt==3'b111);
reg [1:0] byte_received_r;
always @(posedge clk) byte_received_r <= {byte_received_r[0], byte_received};
wire byte_received_sync = (byte_received_r == 2'b01);
always @(posedge clk) begin always @(posedge clk) begin
if(~SSEL_active) if(~SSEL_active)
byte_cnt_r <= 16'h0000; byte_cnt_r <= 16'h0000;
else if(byte_received) begin else if(byte_received_sync) begin
byte_cnt_r <= byte_cnt_r + 16'h0001; byte_cnt_r <= byte_cnt_r + 16'h0001;
end end
end end
reg [7:0] byte_data_sent; reg [7:0] byte_data_sent;
always @(posedge clk) begin /*always @(posedge clk) begin
if(SSEL_active) begin if(SSEL_active) begin
if(SSEL_startmessage) if(SSEL_startmessage)
byte_data_sent <= 8'h5A; // dummy byte byte_data_sent <= 8'h5A; // dummy byte
else else
if(SCK_fallingedge) begin if(SCK_fallingedge) begin
if(bitcnt==3'b000) if(bitcnt==3'b000)
byte_data_sent <= input_data; // after that, we send whatever we get byte_data_sent <= input_data; // after that, we send whatever we get
else else
byte_data_sent <= {byte_data_sent[6:0], 1'b0}; byte_data_sent <= {byte_data_sent[6:0], 1'b0};
end end
end end
end
*/
always @(negedge SCK) begin
if(~SSEL) begin
if(bitcnt==3'b000)
byte_data_sent <= input_data;
else
byte_data_sent <= {byte_data_sent[6:0], 1'b0};
end
end end
assign MISO = SSEL_active ? byte_data_sent[7] : 1'bZ; // send MSB first assign MISO = ~SSEL ? input_data[7-bitcnt] /*byte_data_sent[7]*/ : 1'bZ; // send MSB first
reg cmd_ready_r; reg cmd_ready_r;
reg param_ready_r; reg param_ready_r;
@ -119,23 +142,23 @@ assign cmd_data = cmd_data_r;
assign param_data = param_data_r; assign param_data = param_data_r;
assign byte_cnt = byte_cnt_r; assign byte_cnt = byte_cnt_r;
always @(posedge clk) cmd_ready_r2 = byte_received && byte_cnt_r == 32'h0; always @(posedge clk) cmd_ready_r2 = byte_received_sync && byte_cnt_r == 32'h0;
always @(posedge clk) param_ready_r2 = byte_received && byte_cnt_r > 32'h0; always @(posedge clk) param_ready_r2 = byte_received_sync && byte_cnt_r > 32'h0;
// fill registers // fill registers
always @(posedge clk) begin always @(posedge clk) begin
if (SSEL_startmessage) if (SSEL_startmessage)
cmd_data_r <= 8'h00; cmd_data_r <= 8'h00;
else if(cmd_ready_r2) else if(cmd_ready_r2)
cmd_data_r <= byte_data_received; cmd_data_r <= byte_data_received;
else if(param_ready_r2) else if(param_ready_r2)
param_data_r <= byte_data_received; param_data_r <= byte_data_received;
end end
// delay ready signals by one clock (why did I do this again...) // delay ready signals by one clock (why did I do this again...)
always @(posedge clk) begin always @(posedge clk) begin
cmd_ready_r <= cmd_ready_r2; cmd_ready_r <= cmd_ready_r2;
param_ready_r <= param_ready_r2; param_ready_r <= param_ready_r2;
end end
endmodule endmodule