diff --git a/verilog/sd2snes/address.v b/verilog/sd2snes/address.v index ae203a0..ea359a2 100644 --- a/verilog/sd2snes/address.v +++ b/verilog/sd2snes/address.v @@ -19,6 +19,7 @@ ////////////////////////////////////////////////////////////////////////////////// module address( input CLK, + input [7:0] featurebits, // peripheral enable/disable input [2:0] MAPPER, // MCU detected mapper input [23:0] SNES_ADDR, // requested address from SNES input SNES_CS, // "CART" pin from SNES (active low) @@ -43,6 +44,13 @@ module address( output dspx_a0 ); +parameter [2:0] + FEAT_DSPX = 0, + FEAT_ST0010 = 1, + FEAT_SRTC = 2, + FEAT_MSU1 = 3 +; + wire [1:0] SRAM_BANK; wire [23:0] SRAM_ADDR_FULL; @@ -53,8 +61,6 @@ wire [23:0] SRAM_ADDR_FULL; 001 LoROM 010 ExHiROM (48-64Mbit) 011 BS-X - 100 DSPx (HiROM - 00-0f:6000-7fff) - 101 DSPx (LoROM - 30-3f:8000-ffff) 110 brainfuck interleaved 96MBit Star Ocean =) 111 menu (ROM in upper SRAM) */ @@ -62,48 +68,35 @@ wire [23:0] SRAM_ADDR_FULL; /* HiROM: SRAM @ Bank 0x30-0x3f, 0xb0-0xbf Offset 6000-7fff */ -assign IS_ROM = ( (MAPPER == 3'b000) ? ((!SNES_ADDR[22] & SNES_ADDR[15]) - |(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'b011) ? ((!SNES_ADDR[22] & SNES_ADDR[15]) - |(SNES_ADDR[22])) - : (MAPPER == 3'b100) ? ((!SNES_ADDR[22] & SNES_ADDR[15]) - |(SNES_ADDR[22])) - : (MAPPER == 3'b101) ? ((!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_ROM = ((!SNES_ADDR[22] & SNES_ADDR[15]) + |(SNES_ADDR[22])); -assign IS_SAVERAM = ((MAPPER == 3'b000 - || MAPPER == 3'b010 - || MAPPER == 3'b100 - || MAPPER == 3'b110 - || MAPPER == 3'b111) - ? (!SNES_ADDR[22] - & &SNES_ADDR[21:20] - & &SNES_ADDR[14:13] - & !SNES_ADDR[15] - ) +assign IS_SAVERAM = SAVERAM_MASK[0] + &(featurebits[FEAT_ST0010] + ?(SNES_ADDR[22:19] == 4'b1101 + && SNES_ADDR[15:12] == 4'b0000) + :((MAPPER == 3'b000 + || MAPPER == 3'b010 + || MAPPER == 3'b110 + || MAPPER == 3'b111) + ? (!SNES_ADDR[22] + & &SNES_ADDR[21:20] + & &SNES_ADDR[14:13] + & !SNES_ADDR[15] + ) /* LoROM: SRAM @ Bank 0x70-0x7d, 0xf0-0xfd Offset 0000-7fff TODO: 0000-ffff for small ROMs? */ - :(MAPPER == 3'b001 - || MAPPER == 3'b101) - ? (&SNES_ADDR[22:20] - & (SNES_ADDR[19:16] < 4'b1110) - & !SNES_ADDR[15] - ) + :(MAPPER == 3'b001) + ? (&SNES_ADDR[22:20] + & (SNES_ADDR[19:16] < 4'b1110) + & !SNES_ADDR[15] + ) /* BS-X: SRAM @ Bank 0x10-0x17 Offset 5000-5fff */ - :(MAPPER == 3'b011) - ? ((SNES_ADDR[23:19] == 5'b00010) - & (SNES_ADDR[15:12] == 4'b0101) - ) - : 1'b0); + :(MAPPER == 3'b011) + ? ((SNES_ADDR[23:19] == 5'b00010) + & (SNES_ADDR[15:12] == 4'b0101) + ) + : 1'b0)); assign IS_WRITABLE = IS_SAVERAM @@ -129,13 +122,13 @@ assign IS_WRITABLE = IS_SAVERAM */ assign SRAM_ADDR_FULL = (MODE) ? MCU_ADDR - :((MAPPER[1:0] == 2'b00) + :((MAPPER == 3'b000) ?(IS_SAVERAM ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK) : ({1'b0, SNES_ADDR[22:0]} & ROM_MASK)) - :(MAPPER[1:0] == 2'b01) + :(MAPPER == 3'b001) ?(IS_SAVERAM ? 24'hE00000 + (SNES_ADDR[14:0] & SAVERAM_MASK) : ({2'b00, SNES_ADDR[22:16], SNES_ADDR[14:0]} @@ -199,28 +192,41 @@ assign ROM_SEL = 1'b0; // (MODE) ? CS_ARRAY[SRAM_BANK] : IS_SAVERAM ? 4'b1000 : assign ROM_ADDR0 = SRAM_ADDR_FULL[0]; -assign msu_enable = (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfff8) == 16'h2000)); +assign msu_enable_w = featurebits[FEAT_MSU1] & (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfff8) == 16'h2000)); +reg [7:0] msu_enable_r; +initial msu_enable_r = 8'b00000000; +always @(posedge CLK) msu_enable_r <= {msu_enable_r[6:0], msu_enable_w}; +assign msu_enable = &msu_enable_r[5:2]; + assign use_bsx = (MAPPER == 3'b011); -assign srtc_enable = (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfffe) == 16'h2800)); +assign srtc_enable = featurebits[FEAT_SRTC] & (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfffe) == 16'h2800)); // DSP1 LoROM: DR=30-3f:8000-bfff; SR=30-3f:c000-ffff // or DR=60-6f:0000-3fff; SR=60-6f:4000-7fff // DSP1 HiROM: DR=00-0f:6000-6fff; SR=00-0f:7000-7fff wire dspx_enable_w = - (MAPPER == 3'b101) - ?(ROM_MASK[20] - ?(SNES_ADDR[22] & SNES_ADDR[21] & ~SNES_ADDR[20] & ~SNES_ADDR[15]) - :(~SNES_ADDR[22] & SNES_ADDR[21] & SNES_ADDR[20] & SNES_ADDR[15]) - ) - :(MAPPER == 3'b100) - ?(~SNES_ADDR[22] & ~SNES_ADDR[21] & ~SNES_ADDR[20] & ~SNES_ADDR[15] - & &SNES_ADDR[14:13]) + featurebits[FEAT_DSPX] + ?((MAPPER == 3'b001) + ?(ROM_MASK[20] + ?(SNES_ADDR[22] & SNES_ADDR[21] & ~SNES_ADDR[20] & ~SNES_ADDR[15]) + :(~SNES_ADDR[22] & SNES_ADDR[21] & SNES_ADDR[20] & SNES_ADDR[15]) + ) + :(MAPPER == 3'b000) + ?(~SNES_ADDR[22] & ~SNES_ADDR[21] & ~SNES_ADDR[20] & ~SNES_ADDR[15] + & &SNES_ADDR[14:13]) + :1'b0) + :featurebits[FEAT_ST0010] + ?(SNES_ADDR[22] & SNES_ADDR[21] & ~SNES_ADDR[20] & &(~SNES_ADDR[19:16]) & ~SNES_ADDR[15]) :1'b0; -assign dspx_a0 = (MAPPER == 3'b101) ? SNES_ADDR[14] - :(MAPPER == 3'b100) ? SNES_ADDR[12] - :1'b1; +assign dspx_a0 = featurebits[FEAT_DSPX] + ?((MAPPER == 3'b001) ? SNES_ADDR[14] + :(MAPPER == 3'b000) ? SNES_ADDR[12] + :1'b1) + :featurebits[FEAT_ST0010] + ?SNES_ADDR[0] + :1'b1; reg [7:0] dspx_enable_r; initial dspx_enable_r = 8'b00000000; diff --git a/verilog/sd2snes/ipcore_dir/upd77c25_datrom.v b/verilog/sd2snes/ipcore_dir/upd77c25_datrom.v index 6a23d1f..f18c77e 100644 --- a/verilog/sd2snes/ipcore_dir/upd77c25_datrom.v +++ b/verilog/sd2snes/ipcore_dir/upd77c25_datrom.v @@ -49,23 +49,23 @@ module upd77c25_datrom( input clka; input [0 : 0] wea; -input [9 : 0] addra; +input [10 : 0] addra; input [15 : 0] dina; input clkb; -input [9 : 0] addrb; +input [10 : 0] addrb; output [15 : 0] doutb; // synthesis translate_off BLK_MEM_GEN_V6_1 #( - .C_ADDRA_WIDTH(10), - .C_ADDRB_WIDTH(10), + .C_ADDRA_WIDTH(11), + .C_ADDRB_WIDTH(11), .C_ALGORITHM(1), .C_AXI_ID_WIDTH(4), .C_AXI_SLAVE_TYPE(0), .C_AXI_TYPE(1), .C_BYTE_SIZE(9), - .C_COMMON_CLK(0), + .C_COMMON_CLK(1), .C_DEFAULT_DATA("0"), .C_DISABLE_WARN_BHV_COLL(0), .C_DISABLE_WARN_BHV_RANGE(0), @@ -92,8 +92,8 @@ output [15 : 0] doutb; .C_MEM_TYPE(1), .C_MUX_PIPELINE_STAGES(0), .C_PRIM_TYPE(1), - .C_READ_DEPTH_A(1024), - .C_READ_DEPTH_B(1024), + .C_READ_DEPTH_A(1536), + .C_READ_DEPTH_B(1536), .C_READ_WIDTH_A(16), .C_READ_WIDTH_B(16), .C_RST_PRIORITY_A("CE"), @@ -109,8 +109,8 @@ output [15 : 0] doutb; .C_USE_SOFTECC(0), .C_WEA_WIDTH(1), .C_WEB_WIDTH(1), - .C_WRITE_DEPTH_A(1024), - .C_WRITE_DEPTH_B(1024), + .C_WRITE_DEPTH_A(1536), + .C_WRITE_DEPTH_B(1536), .C_WRITE_MODE_A("WRITE_FIRST"), .C_WRITE_MODE_B("WRITE_FIRST"), .C_WRITE_WIDTH_A(16), diff --git a/verilog/sd2snes/ipcore_dir/upd77c25_datrom.xco b/verilog/sd2snes/ipcore_dir/upd77c25_datrom.xco index 93455b2..1aff1dd 100644 --- a/verilog/sd2snes/ipcore_dir/upd77c25_datrom.xco +++ b/verilog/sd2snes/ipcore_dir/upd77c25_datrom.xco @@ -1,7 +1,7 @@ ############################################################## # # Xilinx Core Generator version 13.1 -# Date: Sun Jun 12 01:42:55 2011 +# Date: Sat Jun 18 13:58:09 2011 # ############################################################## # @@ -37,7 +37,7 @@ SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.1 # BEGIN Parameters CSET additional_inputs_for_power_estimation=false CSET algorithm=Minimum_Area -CSET assume_synchronous_clk=false +CSET assume_synchronous_clk=true CSET axi_id_width=4 CSET axi_slave_type=Memory_Slave CSET axi_type=AXI4_Full @@ -90,7 +90,7 @@ CSET use_regcea_pin=false CSET use_regceb_pin=false CSET use_rsta_pin=false CSET use_rstb_pin=false -CSET write_depth_a=1024 +CSET write_depth_a=1536 CSET write_width_a=16 CSET write_width_b=16 # END Parameters @@ -98,4 +98,4 @@ CSET write_width_b=16 MISC pkg_timestamp=2011-02-03T22:20:43.000Z # END Extra information GENERATE -# CRC: 9692711f +# CRC: 7b2b203b diff --git a/verilog/sd2snes/ipcore_dir/upd77c25_datrom.xise b/verilog/sd2snes/ipcore_dir/upd77c25_datrom.xise index b5cb66e..42d3a55 100644 --- a/verilog/sd2snes/ipcore_dir/upd77c25_datrom.xise +++ b/verilog/sd2snes/ipcore_dir/upd77c25_datrom.xise @@ -20,46 +20,351 @@ - - - - - + + + + + - - - - - + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + diff --git a/verilog/sd2snes/main.v b/verilog/sd2snes/main.v index 8e7dd79..230eab6 100644 --- a/verilog/sd2snes/main.v +++ b/verilog/sd2snes/main.v @@ -128,9 +128,10 @@ wire [10:0] dspx_pgm_addr; wire dspx_pgm_we; wire [15:0] dspx_dat_data; -wire [9:0] dspx_dat_addr; +wire [10:0] dspx_dat_addr; wire dspx_dat_we; +wire [7:0] featurebits; //wire SD_DMA_EN; //SPI_DMA_CTRL; sd_dma snes_sd_dma( @@ -320,7 +321,8 @@ mcu_cmd snes_mcu_cmd( .dspx_dat_data_out(dspx_dat_data), .dspx_dat_addr_out(dspx_dat_addr), .dspx_dat_we_out(dspx_dat_we), - .dspx_reset_out(dspx_reset) + .dspx_reset_out(dspx_reset), + .featurebits_out(featurebits) ); // dcm1: dfs 4x @@ -370,6 +372,7 @@ wire ROM_SEL; address snes_addr( .CLK(CLK2), .MAPPER(MAPPER), + .featurebits(featurebits), .SNES_ADDR(SNES_ADDR), // requested address from SNES .SNES_CS(SNES_CS), // "CART" pin from SNES (active low) .ROM_ADDR(ROM_ADDR), // Address to request from SRAM (active low) @@ -622,7 +625,7 @@ assign ROM_BLE = !ROM_WE ? !ROM_ADDR0 : 1'b0; //assign SNES_DATABUS_OE = (!IS_SAVERAM & SNES_CS) | (SNES_READ & SNES_WRITE); assign SNES_DATABUS_OE = dspx_enable ? 1'b0 : - msu_enable ? (SNES_READ & SNES_WRITE) : + msu_enable ? 1'b0 : bsx_data_ovr ? (SNES_READ & SNES_WRITE) : srtc_enable ? (SNES_READ & SNES_WRITE) : ((IS_ROM & SNES_CS) diff --git a/verilog/sd2snes/mcu_cmd.v b/verilog/sd2snes/mcu_cmd.v index d000b78..fd1a003 100644 --- a/verilog/sd2snes/mcu_cmd.v +++ b/verilog/sd2snes/mcu_cmd.v @@ -89,18 +89,21 @@ module mcu_cmd( output reg dspx_pgm_we_out, output reg [15:0] dspx_dat_data_out, - output reg [9:0] dspx_dat_addr_out, + output reg [10:0] dspx_dat_addr_out, output reg dspx_dat_we_out, output reg dspx_reset_out, + // feature enable + output reg [7:0] featurebits_out, + // SNES sync/clk input snes_sysclk ); initial begin dspx_pgm_addr_out = 11'b00000000000; - dspx_dat_addr_out = 9'b000000000; + dspx_dat_addr_out = 10'b0000000000; dspx_reset_out = 1'b1; end @@ -367,7 +370,7 @@ always @(posedge clk) begin case (spi_byte_cnt) 32'h2: begin dspx_pgm_addr_out <= 11'b00000000000; - dspx_dat_addr_out <= 9'b000000000; + dspx_dat_addr_out <= 10'b0000000000; end endcase end @@ -396,6 +399,8 @@ always @(posedge clk) begin dspx_reset_out <= 1'b1; 8'hec: // release DSPx reset dspx_reset_out <= 1'b0; + 8'hed: + featurebits_out <= param_data[7:0]; endcase end diff --git a/verilog/sd2snes/msu.v b/verilog/sd2snes/msu.v index 23ec17e..ebef6d8 100644 --- a/verilog/sd2snes/msu.v +++ b/verilog/sd2snes/msu.v @@ -41,6 +41,15 @@ module msu( input msu_address_ext_write ); +reg [2:0] reg_addr_r [3:0]; +always @(posedge clkin) begin + reg_addr_r[3] <= reg_addr_r[2]; + reg_addr_r[2] <= reg_addr_r[1]; + reg_addr_r[1] <= reg_addr_r[0]; + reg_addr_r[0] <= reg_addr; +end + + reg [1:0] status_reset_we_r; always @(posedge clkin) status_reset_we_r = {status_reset_we_r[0], status_reset_we}; wire status_reset_en = (status_reset_we_r == 2'b01); @@ -56,14 +65,18 @@ always @(posedge clkin) msu_address_ext_write_sreg <= {msu_address_ext_write_sreg[0], msu_address_ext_write}; wire msu_address_ext_write_rising = (msu_address_ext_write_sreg[1:0] == 2'b01); +reg [7:0] reg_enable_sreg; +initial reg_enable_sreg = 8'b11111111; +always @(posedge clkin) reg_enable_sreg <= {reg_enable_sreg[6:0], enable}; + reg [5:0] reg_oe_sreg; always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[4:0], reg_oe}; -wire reg_oe_falling = (reg_oe_sreg[3:0] == 4'b1000); -wire reg_oe_rising = (reg_oe_sreg[3:0] == 4'b0001); +//wire reg_oe_falling = (reg_oe_sreg[3:0] == 4'b1000); +wire reg_oe_rising = reg_enable_sreg[4] && (reg_oe_sreg[1:0] == 2'b01); -reg [1:0] reg_we_sreg; -always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[0], reg_we}; -wire reg_we_rising = (reg_we_sreg[1:0] == 2'b01); +reg [5:0] reg_we_sreg; +always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[4:0], reg_we}; +wire reg_we_rising = reg_enable_sreg[4] && (reg_we_sreg[1:0] == 2'b01); reg [31:0] addr_out_r; assign addr_out = addr_out_r; @@ -115,9 +128,9 @@ assign reg_data_out = data_out_r; always @(posedge clkin) data_in_r <= reg_data_in; always @(posedge clkin) begin - case(reg_addr) + case(reg_addr_r[3]) 3'h0: data_out_r <= {data_busy_r, audio_busy_r, audio_status_r, 4'b0001}; - 3'h1: data_out_r <= msu_data_r; + 3'h1: data_out_r <= msu_data; 3'h2: data_out_r <= 8'h53; 3'h3: data_out_r <= 8'h2d; 3'h4: data_out_r <= 8'h4d; @@ -128,8 +141,8 @@ always @(posedge clkin) begin end always @(posedge clkin) begin - if(reg_we_rising && enable) begin - case(reg_addr) + if(reg_we_rising) begin + case(reg_addr_r[3]) 3'h0: addr_out_r[7:0] <= reg_data_in; 3'h1: addr_out_r[15:8] <= reg_data_in; 3'h2: addr_out_r[23:16] <= reg_data_in; @@ -177,9 +190,8 @@ end always @(posedge clkin) begin if(msu_address_ext_write_rising) msu_address_r <= msu_address_ext; - else if(enable && reg_addr == 3'h1 && reg_oe_falling) begin + else if(reg_addr_r[3] == 3'h1 && reg_oe_rising) begin msu_address_r <= msu_address_r + 1; - msu_data_r <= msu_data; end end diff --git a/verilog/sd2snes/sd2snes.xise b/verilog/sd2snes/sd2snes.xise index 254f513..5a39501 100644 --- a/verilog/sd2snes/sd2snes.xise +++ b/verilog/sd2snes/sd2snes.xise @@ -381,8 +381,8 @@ - - + + diff --git a/verilog/sd2snes/upd77c25.v b/verilog/sd2snes/upd77c25.v index 8322b9c..d0361c5 100644 --- a/verilog/sd2snes/upd77c25.v +++ b/verilog/sd2snes/upd77c25.v @@ -32,7 +32,7 @@ module upd77c25( input DAT_WR, input [15:0] DAT_DI, - input [9:0] DAT_WR_ADDR, + input [10:0] DAT_WR_ADDR, // debug output [15:0] DR, @@ -76,7 +76,7 @@ reg [7:0] insn_state; // execute state reg [3:0] regs_dph; reg [3:0] regs_dpl; -reg [9:0] regs_rp; +reg [10:0] regs_rp; wire [15:0] ram_dina; reg [15:0] ram_dina_r; @@ -118,7 +118,7 @@ upd77c25_datrom datrom ( .addra(DAT_WR_ADDR), // input [9 : 0] addra .dina(DAT_DI), // input [15 : 0] dina .clkb(CLK), // input clkb - .addrb(regs_rp), // input [9 : 0] addrb + .addrb(regs_rp), // input [10 : 0] addrb .doutb(dat_doutb) // output [15 : 0] doutb ); @@ -185,7 +185,7 @@ initial begin regs_sp = 4'b0000; pc = 11'b0; regs_sr = 16'b0; - regs_rp = 16'h03ff; + regs_rp = 16'h0000; regs_dph = 4'b0; regs_dpl = 4'b0; regs_k = 16'b0; @@ -598,7 +598,7 @@ always @(posedge CLK) begin regs_sr[9] <= 0; regs_sr[8] <= 0; regs_sr[7] <= 0; - regs_rp <= 16'h03ff; + regs_rp <= 16'h0000; regs_dph <= 4'b0; regs_dpl <= 4'b0; regs_k <= 16'b0;