Forum Discussion

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

Nintendo DS Passthrough

Hiya, I'm trying to build a simple Nintendo DS card passthrough (also known as a "PassMe") -- basically use the FPGA as a man in the middle between the DS and DS card communication.

I've written some Verilog code which simply reroutes the signals from DS CARD0 to DS CARD1, and back.

The first 8 clock cycles is the command which is sent to a Nintendo DS card, after which the direction is switched and the card responds with data.

The rom select (RCS) signal will go low when a new transfer is started.


module main(
	CLOCK_50,
	DSCARD0_RCS,
	DSCARD0_ECS,
	DSCARD0_RES,
	DSCARD0_CLK,
	DSCARD0_DAT,
	DSCARD1_RCS,
	DSCARD1_ECS,
	DSCARD1_RES,
	DSCARD1_CLK,
	DSCARD1_DAT	
);
	input			CLOCK_50;
	input			DSCARD0_RCS;
	input			DSCARD0_ECS;
	input			DSCARD0_RES;
	input			DSCARD0_CLK;
	inout		DSCARD0_DAT;
	output			DSCARD1_RCS;
	output			DSCARD1_ECS;
	output			DSCARD1_RES;
	output			DSCARD1_CLK;
	inout		DSCARD1_DAT;
	
	assign			DSCARD1_RCS = DSCARD0_RCS;
	assign			DSCARD1_ECS = DSCARD0_ECS;
	assign			DSCARD1_RES = DSCARD0_RES;
	assign			DSCARD1_CLK = DSCARD0_CLK;
	
	reg				IsCommand;
	reg			CommandCounter;
		
	
	assign			DSCARD0_DAT = DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand? DSCARD1_DAT : 1'bz;
	assign			DSCARD1_DAT = DSCARD0_RES & ~DSCARD0_RCS & IsCommand? DSCARD0_DAT : 1'bz;
	
	assign			DSCARD0_DAT = DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand? DSCARD1_DAT : 1'bz;
	assign			DSCARD1_DAT = DSCARD0_RES & ~DSCARD0_RCS & IsCommand? DSCARD0_DAT : 1'bz;
	
	assign			DSCARD0_DAT = DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand? DSCARD1_DAT : 1'bz;
	assign			DSCARD1_DAT = DSCARD0_RES & ~DSCARD0_RCS & IsCommand? DSCARD0_DAT : 1'bz;
//	assign			DSCARD0_DAT = DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand? DSCARD1_DAT : 1'bz;
//	assign			DSCARD1_DAT = DSCARD0_RES & ~DSCARD0_RCS & IsCommand? DSCARD0_DAT : 1'bz;
//	assign			DSCARD0_DAT = DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand? DSCARD1_DAT : 1'bz;
//	assign			DSCARD1_DAT = DSCARD0_RES & ~DSCARD0_RCS & IsCommand? DSCARD0_DAT : 1'bz;
//	assign			DSCARD0_DAT = DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand? DSCARD1_DAT : 1'bz;
//	assign			DSCARD1_DAT = DSCARD0_RES & ~DSCARD0_RCS & IsCommand? DSCARD0_DAT : 1'bz;
	
	always @(posedge DSCARD0_CLK or posedge DSCARD0_RCS)
	begin
		if (DSCARD0_RCS)
		begin
			CommandCounter <= 8'h0;
			IsCommand <= 1'b1;
		end
		else if (CommandCounter == 8'h7)
			IsCommand <= 1'b0;
		else
			CommandCounter <= CommandCounter + 8'h1;
	end
endmodule

I have a problem which makes card communication unstable when adding more assign DSCARD0/1_DAT[x] = ...; lines.

Right now I'm connecting DAT[3] through DAT[7] directly to a real DS card, and DAT[0] through DAT[2] are connected to the FPGA, which are indirectly connected to the real DS card.

With only DAT[0], DAT[1] and DAT[2] rerouted through the FPGA, the DS will still accept the card, and communication is stable

Uncommenting the lines for DAT[3], DAT[4] and DAT[5] and connecting these signals indirectly to the DS card makes the communication more and more unstable. And I can't figure out why.

Could someone shed some light on why this is?

Thanks in advance.

3 Replies

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

    i'm not a Verilog guy but it doesn't look like you register card logic which could cause problems like this. how fast does the DS data run?

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

    you specify

    inout [7:0] DSCARD0_DAT;

    as an 8 bit bidir signal

    you correctly used assignments for that, but only for 6 bit [5:0] and no assignment for bit 6 and 7

    so you can combine these lines as

    assign DSCARD0_DAT[7:0] = (DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand ) ? DSCARD1_DAT[7:0] : 8'bzzzzzzzz;

    assign DSCARD1_DAT[7:0] = (DSCARD0_RES & ~DSCARD0_RCS & IsCommand ) ? DSCARD0_DAT[7:0] : 8'bzzzzzzzz;

    your problem no starts here where you try to switch the direction from card0 to card1 and vice versa with a registered signal. this is some kind of an asynchron dataloop, hard to dig down the problem.

    i have no information about how hard the timing must be in this application but if possible try to write a fully synchronus design and pipe some of the signals that the or clock synchron to each other.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    i'm not a Verilog guy but it doesn't look like you register card logic which could cause problems like this. how fast does the DS data run?

    --- Quote End ---

    What do you mean with I don't register card logic?

    The DS clock runs at approx 6.7 MHz.

    --- Quote Start ---

    you specify

    inout [7:0] DSCARD0_DAT;

    as an 8 bit bidir signal

    you correctly used assignments for that, but only for 6 bit [5:0] and no assignment for bit 6 and 7

    so you can combine these lines as

    assign DSCARD0_DAT[7:0] = (DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand ) ? DSCARD1_DAT[7:0] : 8'bzzzzzzzz;

    assign DSCARD1_DAT[7:0] = (DSCARD0_RES & ~DSCARD0_RCS & IsCommand ) ? DSCARD0_DAT[7:0] : 8'bzzzzzzzz;

    your problem no starts here where you try to switch the direction from card0 to card1 and vice versa with a registered signal. this is some kind of an asynchron dataloop, hard to dig down the problem.

    i have no information about how hard the timing must be in this application but if possible try to write a fully synchronus design and pipe some of the signals that the or clock synchron to each other.

    --- Quote End ---

    Yeah the reason for the seperate DSCARDx_DAT[] lines is that I was testing the signals one-by-one, while leaving 6 and 7 directly connected between CARD0 and CARD1.

    What do you mean the problem is with the registered signal? Could you explain this some more?

    How would a fully synchronous design look like?

    Thanks in advance