Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
9 years ago

Trouble interfacing FLASH pins to GPIO (retro game related)

Hey all,

Just got an Altera DE1 dev board using the Cyclone II, and I'm working on a simple test that is literally just connecting the FLASH chip to the GPIO_0 bus. I'm not performing any logic, but the FLASH does have code I wrote to it using the DE Control panel, and I've verified my code is correct.

This is a test to send a small test ROM file from the DE1 to the GPIO ports which are connected to a Super Nintendo cartridge. I've done similar tests with Xilinx CPLD before (data lines ran direct to system, but address and control lines ran to CPLD), but this is my first foray into sending all pins through a FPGA.

My problem is that the game will not boot! I've double and triple checked my wiring, and that's good. Each pin on the SNES just connects to one of the corresponding GPIO pins, which is routed to the FLASH pins through the FPGA. I've never run data lines through a PLD before, so I don't know if there is something special that they need in contrast to a regular address line? Or is there something glaringly obvious that I'm missing?

I've attached my code in hopes someone can help me out.

Also, I've already added FL_CE_N into my pin assignments as I noticed that it was missing originally.

library ieee;use ieee.std_logic_1164.all;
entity mapper is
	port( 
	FL_ADDR  : out std_logic_vector(21 downto 0) ;
	FL_DQ    : out std_logic_vector(7 downto 0) ;
	FL_CE_N  : out std_logic;
	FL_OE_N  : out std_logic;
	FL_RST_N : out std_logic;
	FL_WE_N  : out std_logic;
	GPIO_0   : inout std_logic_vector(35 downto 0) 
	
	);
	
end mapper;
architecture arch of mapper is
begin
	--CONTROL LINES
	FL_CE_N <= '0';
	FL_OE_N <= '0';
	FL_RST_N <= '1';
	FL_WE_N <= '1';
	--DATA LINES
	FL_DQ(7 downto 0) <= GPIO_0(21 downto 14);
	-- ADDRESS LINES
	FL_ADDR(17) <= GPIO_0(2);
	FL_ADDR(16) <= GPIO_0(24);
	FL_ADDR(15) <= GPIO_0(4);
	FL_ADDR(14) <= GPIO_0(29);
	FL_ADDR(13) <= GPIO_0(28);
	FL_ADDR(12) <= GPIO_0(5);
	FL_ADDR(11) <= GPIO_0(25);
	FL_ADDR(10) <= GPIO_0(23);
	FL_ADDR(9) <= GPIO_0(26);
	FL_ADDR(8) <= GPIO_0(27);
	FL_ADDR(7) <= GPIO_0(6);
	FL_ADDR(6) <= GPIO_0(7);
	FL_ADDR(5) <= GPIO_0(8);
	FL_ADDR(4) <= GPIO_0(9);
	FL_ADDR(3) <= GPIO_0(10);
	FL_ADDR(2) <= GPIO_0(11);
	FL_ADDR(1) <= GPIO_0(12);
	FL_ADDR(0) <= GPIO_0(13);
	
end arch;

Any ideas and help here would be greatly appreciated, thanks!

17 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    You have to create a SIGNAL assignment for an additional signal in the design.

    SIGNAL FL_ADDR_TEMP (21 DOWNTO 0);

    Then let's say you want to access address location 0x24ffff (22 bit wide address though your code isn't using any of the upper bits for some reason):

    FL_ADDR <= x"24ffff";

    FL_ADDR_TEMP <= FL_ADDR;

    Then the code you have would be:

    GPIO_0(2) <= FL_ADDR_TEMP(17);

    GPIO_0(24) <= FL_ADDR_TEMP(16);

    GPIO_0(4) <= FL_ADDR_TEMP(15);

    GPIO_0(29) <= FL_ADDR_TEMP(14);

    GPIO_0(28) <= FL_ADDR_TEMP(13);

    GPIO_0(5) <= FL_ADDR_TEMP(12);

    GPIO_0(25) <= FL_ADDR_TEMP(11);

    GPIO_0(23) <= FL_ADDR_TEMP(10);

    GPIO_0(26) <= FL_ADDR_TEMP(9);

    GPIO_0(27) <= FL_ADDR_TEMP(8);

    GPIO_0(6) <= FL_ADDR_TEMP(7);

    GPIO_0(7) <= FL_ADDR_TEMP(6);

    GPIO_0(8) <= FL_ADDR_TEMP(5);

    GPIO_0(9) <= FL_ADDR_TEMP(4);

    GPIO_0(10) <= FL_ADDR_TEMP(3);

    GPIO_0(11) <= FL_ADDR_TEMP(2);

    GPIO_0(12) <= FL_ADDR_TEMP(1);

    GPIO_0(13) <= FL_ADDR_TEMP(0);

    --- Quote End ---

    Ok, so I have re-written my code to hopefully make things more clear. I have changed the data bus behavior to work as "read-only" from the Flash chip, so that should make things simpler to implement. However, this still isn't working:

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    entity mapper_test is
    	port( 
    	FL_ADDR  	: out   std_logic_vector(21 downto 0);
    	FL_DQ    	: in    std_logic_vector(7 downto 0);
    	FL_CE_N  	: out   std_logic;
    	FL_OE_N  	: out   std_logic;
    	FL_RST_N 	: out   std_logic;  
    	FL_WE_N  	: out   std_logic; 
    --	LEDR     	: out   std_logic_vector(9 downto 0);    
    --	LEDG     	: out   std_logic_vector(7 downto 0); 
    --	SW       	: in    std_logic_vector(2 downto 0);
    	
    	SNES_ADDR   : in 	  std_logic_vector(21 downto 0);  -- SNES ADDRESS BUS
    	SNES_DATA	: out   std_logic_vector(7 downto 0); 	 -- SNES DATA BUS
    	SNES_ROMSEL : in    std_logic; 							 -- /ROMSEL (CART PIN 49)
    	SNES_RST		: in    std_logic; 							 -- CART RESET
    	SNES_VCC    : in    std_logic; 							 -- CART VCC
    	SNES_RD		: in    std_logic 							 -- SNES /RD
    	
    	);
    	
    end mapper_test;
    architecture arch of mapper_test is
    begin
    	--FLASH CONTROL PINS
    	FL_CE_N <= SNES_ROMSEL; 									 -- INPUT SNES /ROMSEL TO OUTPUT FLASH /CE
    	FL_OE_N <= SNES_RD;  									    -- INPUT SNES /RD TO OUTPUT FLASH /OE
    	FL_RST_N <= '1'; 												 -- KEEP FLASH /RST HIGH
    	FL_WE_N  <= '1'; 												 -- KEEP FLASH /WE HIGH
    	
    	--FLASH DATA PINS
    	
    	SNES_DATA(7 downto 0) <= FL_DQ(7 downto 0); 			 -- INPUT FLASH DATA BUS (7:0) TO OUTPUT SNES DATA BUS (7:0) FOR READ MODE
    	
    	--ADDRESS PINS
    	FL_ADDR(14 downto 0) <= SNES_ADDR(14 downto 0);		 -- INPUT SNES ADDRESS (14:0) TO OUTPUT FLASH ADDRESS (14:0) 
    	FL_ADDR(20 downto 15) <= SNES_ADDR(21 downto 16); 	 -- LOROM CONFIG ---> INPUT SNES ADDRESS (21:16) TO OUTPUT FLASH ADDRESS (20:15)
    	FL_ADDR(21) <= '0';											 -- KEEP FLASH(21) LOW FOR 2MBYTE ONLY
    	
    	
    	end arch;

    Any ideas of what else it could be? I figure it still has to be with the data bus, but I don't know how else to write it.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You have to create a SIGNAL assignment for an additional signal in the design.

    SIGNAL FL_ADDR_TEMP (21 DOWNTO 0);

    Then let's say you want to access address location 0x24ffff (22 bit wide address though your code isn't using any of the upper bits for some reason):

    FL_ADDR <= x"24ffff";

    FL_ADDR_TEMP <= FL_ADDR;

    Then the code you have would be:

    GPIO_0(2) <= FL_ADDR_TEMP(17);

    GPIO_0(24) <= FL_ADDR_TEMP(16);

    GPIO_0(4) <= FL_ADDR_TEMP(15);

    GPIO_0(29) <= FL_ADDR_TEMP(14);

    GPIO_0(28) <= FL_ADDR_TEMP(13);

    GPIO_0(5) <= FL_ADDR_TEMP(12);

    GPIO_0(25) <= FL_ADDR_TEMP(11);

    GPIO_0(23) <= FL_ADDR_TEMP(10);

    GPIO_0(26) <= FL_ADDR_TEMP(9);

    GPIO_0(27) <= FL_ADDR_TEMP(8);

    GPIO_0(6) <= FL_ADDR_TEMP(7);

    GPIO_0(7) <= FL_ADDR_TEMP(6);

    GPIO_0(8) <= FL_ADDR_TEMP(5);

    GPIO_0(9) <= FL_ADDR_TEMP(4);

    GPIO_0(10) <= FL_ADDR_TEMP(3);

    GPIO_0(11) <= FL_ADDR_TEMP(2);

    GPIO_0(12) <= FL_ADDR_TEMP(1);

    GPIO_0(13) <= FL_ADDR_TEMP(0);
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I'm still not sure what you're trying to do. Are you retrieving data from the flash and wanting to send it out the GPIO? If that's the case, then no, FL_ADDR should still be an output because you're trying to access an address location on the flash. FL_DQ should be an input, as you have it in the new code, to read in data from the selected flash address.

    But now you're sending an address and data out the GPIO. Is this your intention? If so, then the only issue with the new code is the direction of FL_ADDR. But you also need additional logic to specify what FL_ADDR should be to access a location in the flash.

    --- Quote End ---

    I'm trying to read data off of the chip (in this case a test game), send it through the FPGA and into the GPIO pins, which then runs into a cartridge so that the SNES console can read it. Sorry if that wasn't clear to begin with.

    If I make FL_ADDR an output, how to get that to work with the GPIO if i also have that as an output? VHDL just gives me an error that way.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I'm still not sure what you're trying to do. Are you retrieving data from the flash and wanting to send it out the GPIO? If that's the case, then no, FL_ADDR should still be an output because you're trying to access an address location on the flash. FL_DQ should be an input, as you have it in the new code, to read in data from the selected flash address.

    But now you're sending an address and data out the GPIO. Is this your intention? If so, then the only issue with the new code is the direction of FL_ADDR. But you also need additional logic to specify what FL_ADDR should be to access a location in the flash.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I don't quite understand what you're trying to do here. You're doing read-only on the flash (FL_WE_N <= 1) and you're sending data from GPIO_0 to FL_DQ, which won't do anything because you're doing read-only.

    Also, why is GPIO_0 bidirectional?

    If you're trying to send something out of GPIO_0, GPIO_0 must be on the left hand side of an assignment somewhere.

    --- Quote End ---

    That's a bit of what I was confused about. It had looked like in the datasheet for this dev board that GPIO 1 and 2 were both bidirectional, so I figured I needed to implement them as such?

    So if i'm understanding you properly, seeing as the FLASH is in read-only mode, it's pins (maybe aside from the control pins) should be set as INPUT in my port list, all driving the GPIO?

    So:

    library ieee;
    use ieee.std_logic_1164.all;
    entity mapper is
    	port( 
    	FL_ADDR  : in std_logic_vector(21 downto 0) ;
    	FL_DQ    : in std_logic_vector(7 downto 0) ;
    	FL_CE_N  : out std_logic;
    	FL_OE_N  : out std_logic;
    	FL_RST_N : out std_logic;
    	FL_WE_N  : out std_logic;
    	GPIO_0   : out std_logic_vector(35 downto 0) 
    	
    	);
    	
    end mapper;
    architecture arch of mapper is
    begin
    	--CONTROL LINES
    	FL_CE_N <= '0';
    	FL_OE_N <= '0';
    	FL_RST_N <= '1';
    	FL_WE_N <= '1';
    	--DATA LINES
    	GPIO_0(21 downto 14) <= FL_DQ(7 downto 0) ;
    	-- ADDRESS LINES
    	GPIO_0(2) <= FL_ADDR(17);
    	GPIO_0(24) <= FL_ADDR(16);
    	GPIO_0(4) <= FL_ADDR(15);
    	GPIO_0(29) <= FL_ADDR(14);
    	GPIO_0(28) <= FL_ADDR(13);
    	GPIO_0(5) <= FL_ADDR(12);
    	GPIO_0(25) <= FL_ADDR(11);
    	GPIO_0(23) <= FL_ADDR(10);
    	GPIO_0(26) <= FL_ADDR(9);
    	GPIO_0(27) <= FL_ADDR(8);
    	GPIO_0(6) <= FL_ADDR(7);
    	GPIO_0(7) <= FL_ADDR(6);
    	GPIO_0(8) <= FL_ADDR(5);
    	GPIO_0(9) <= FL_ADDR(4);
    	GPIO_0(10) <= FL_ADDR(3);
    	GPIO_0(11) <= FL_ADDR(2);
    	GPIO_0(12) <= FL_ADDR(1);
    	GPIO_0(13) <= FL_ADDR(0);
    	
    end arch;
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I don't quite understand what you're trying to do here. You're doing read-only on the flash (FL_WE_N <= 1) and you're sending data from GPIO_0 to FL_DQ, which won't do anything because you're doing read-only.

    Also, why is GPIO_0 bidirectional?

    If you're trying to send something out of GPIO_0, GPIO_0 must be on the left hand side of an assignment somewhere.