data out: out
+percolate up: DDR2_CAS_B 1
+percolate up: DDR2_CKE 2
+percolate up: DDR2_RAS_B 1
+percolate up: DDR2_WE_B 1
+percolate up: DDR2_ODT 2
+percolate up: DDR2_CS0_B 2
+percolate up: DDR2_CLK_N 2
+percolate up: DDR2_CLK_P 2
+percolate up: DDR2_A 14
+percolate up: DDR2_BA 3
+percolate inout: DDR2_DQ 64
+percolate up: DDR2_DM 8
+percolate inout: DDR2_DQS_N 8
+percolate inout: DDR2_DQS_P 8
+
+percolate inout: I2C_DDR2_SCL 1
+percolate inout: I2C_DDR2_SDA 1
+
+percolate down: CLKBUF_Q1_N 1
+percolate down: CLKBUF_Q1_P 1
+
== TeX ==============================================================
== Fleeterpreter ====================================================
== FPGA ==============================================================
- reg ddr2_addr_r;
- reg ddr2_isread;
- reg ddr2_write_data_push;
- reg ddr2_read_data_pop;
- reg [`DATAWIDTH:0] out_d;
-
- assign ddr2_addr_r_ = ddr2_addr_r;
- assign ddr2_isread_ = ddr2_isread;
- assign ddr2_addr_ = !ddr2_isread ? inAddrWrite_d[31:0] : inAddrRead_d[31:0];
- assign ddr2_write_data_push_ = ddr2_write_data_push;
- assign ddr2_read_data_pop_ = ddr2_read_data_pop;
- assign ddr2_write_data_ = { inDataWrite_d[31:5], inDataWrite_d[4], inDataWrite_d[35:0] };
-// assign ddr2_write_data_ = inDataWrite_d[(`DATAWIDTH-1):0];
- assign out_d_ = out_d;
+// Nearly all of this was copied from Greg Gibeling's work; copyright shown below:
+
+// Everything here was copied from
+// GateLib/Firmware/DRAM/Hardware/DDR2SDRAM/Test/FPGA_TOP_ML505_DDR2SDRAMTest.v
+
+//==============================================================================
+// Section: License
+//==============================================================================
+// Copyright (c) 2005-2008, Regents of the University of California
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// - Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// - Neither the name of the University of California, Berkeley nor the
+// names of its contributors may be used to endorse or promote
+// products derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//==============================================================================
+
+parameter
+ ClockFreq = 200000000,
+ BAWidth = 2,
+ RAWidth = 13,
+ CAWidth = 10,
+ DWidth = 128, // 128b SDR internal transfers
+ UWidth = 8, // This will almost ALWAYS be 8
+ BurstLen = 2, // 256b total burst, 2 words DWidth words at SDR, or 4 external words at DDR
+ EnableMask = 1,
+ EnableECC = 0,
+ Board = 0;
+
+localparam
+ UCount = DWidth / UWidth,
+ // 128b/8 = 16b per mask means per-byte masking
+ MWidth = (EnableECC || (EnableMask == 0)) ? 0 : UCount,
+ // Unused lower address bits, the -1 is to get a proper log2
+ UAWidth = `log2(UCount-1),
+ TAWidth = CAWidth + RAWidth + BAWidth,
+ // Note that the components are in order according to where in the
+ // address they appear, the -1 is to account for DDR
+ AWidth = TAWidth + UAWidth - 1,
+ ECheck = EnableECC ? 2 : 0,
+ ECorrect = EnableECC ? 1 : 0,
+ CWidth = 3,
+ EHWidth = `max(`log2(ECheck), 1),
+ ERWidth = `max(`log2(ECheck), 1);
+
+wire Reset;
+assign Reset = !rst;
+
+reg [AWidth-1:0] CommandAddress;
+reg [CWidth-1:0] Command;
+wire CommandReady;
+reg CommandValid;
+
+wire [DWidth-1:0] DataIn;
+wire [MWidth-1:0] DataInMask;
+reg DataInValid;
+wire DataInReady;
+
+wire [DWidth-1:0] DataOut;
+wire [EHWidth-1:0] DataOutErrorChecked;
+wire [ERWidth-1:0] DataOutErrorCorrected;
+wire DataOutValid;
+reg DataOutReady;
+
+wire Clock_IBUFG;
+wire Clock, ClockD2, ClockP90;
+wire Clock_DCM, ClockD2_DCM, ClockP90_DCM;
+wire Locked;
+
+reg [`WORDWIDTH:0] out_d;
+assign out_d_ = out_d;
+
+assign DDR2_BA[2] = 1'b0;
+assign DDR2_CS0_B[1] = 1'b1;
+assign DDR2_ODT[1] = 1'b0;
+assign DDR2_CKE[1] = 1'b0;
+
+IBUFGDS ClockIBufG(.I(CLKBUF_Q1_P), .IB(CLKBUF_Q1_N), .O(Clock_IBUFG));
+DCM_BASE
+ #(
+ .CLKIN_PERIOD(5.0),
+ .CLKDV_DIVIDE(2.0),
+ .DLL_FREQUENCY_MODE("HIGH"),
+ .DUTY_CYCLE_CORRECTION("TRUE"),
+ .FACTORY_JF(16'hF0F0)
+ )
+ DCMBase(
+ .CLK0(Clock_DCM),
+ .CLK180( ),
+ .CLK270( ),
+ .CLK2X( ),
+ .CLK2X180( ),
+ .CLK90(ClockP90_DCM),
+ .CLKDV(ClockD2_DCM),
+ .CLKFX( ),
+ .CLKFX180( ),
+ .LOCKED(Locked),
+ .CLKFB(Clock),
+ .CLKIN(Clock_IBUFG),
+ .RST(Reset));
+ // synthesis attribute CLKIN_PERIOD of DCMBase is "5.0"
+ // synthesis attribute CLKDV_DIVIDE of DCMBase is "2.0"
+ // synthesis attribute DLL_FREQUENCY_MODE of DCMBase is "HIGH"
+ // synthesis attribute DUTY_CYCLE_CORRECTION of DCMBase is "TRUE"
+ // synthesis attribute FACTORY_JF of DCMBase is "16'hF0F0"
+ BUFG ClockBufG(.I(Clock_DCM), .O(Clock));
+ BUFG ClockP90BufG(.I(ClockP90_DCM), .O(ClockP90));
+ BUFG ClockD2BufG(.I(ClockD2_DCM), .O(ClockD2));
+
+DDR2SDRAM DDR2SDRAM(
+ .Clock(Clock),
+ .ClockD2(ClockD2),
+ .ClockP90(ClockP90),
+ .Reset(Reset),
+ .Locked(Locked),
+ .ClockF200(Clock),
+ .Initialized( ),
+ .PoweredUp( ),
+
+ .CommandClock(clk),
+ .DataInClock(clk),
+ .DataOutClock(clk),
+ .CommandReset(Reset),
+ .DataInReset(Reset),
+ .DataOutReset(Reset),
+
+ .CommandAddress(CommandAddress),
+ .Command(Command),
+ .CommandValid(CommandValid),
+ .CommandReady(CommandReady),
+ .DataIn(DataIn),
+ .DataInMask(DataInMask),
+ .DataInValid(DataInValid),
+ .DataInReady(DataInReady),
+ .DataOut(DataOut),
+ .DataOutErrorChecked(DataOutErrorChecked),
+ .DataOutErrorCorrected(DataOutErrorCorrected),
+ .DataOutValid(DataOutValid),
+ .DataOutReady(DataOutReady),
+ .DDR2_DQ(DDR2_DQ),
+ .DDR2_A(DDR2_A),
+ .DDR2_BA(DDR2_BA[1:0]),
+ .DDR2_RAS_B(DDR2_RAS_B),
+ .DDR2_CAS_B(DDR2_CAS_B),
+ .DDR2_WE_B(DDR2_WE_B),
+ .DDR2_CS0_B(DDR2_CS0_B[0]),
+ .DDR2_ODT(DDR2_ODT[0]),
+ .DDR2_CKE(DDR2_CKE[0]),
+ .DDR2_DM(DDR2_DM),
+ .DDR2_DQS_P(DDR2_DQS_P),
+ .DDR2_DQS_N(DDR2_DQS_N),
+ .DDR2_CLK_P(DDR2_CLK_P),
+ .DDR2_CLK_N(DDR2_CLK_N));
+ defparam DDR2SDRAM.UWidth = UWidth;
+ defparam DDR2SDRAM.BAWidth = BAWidth;
+ defparam DDR2SDRAM.RAWidth = RAWidth;
+ defparam DDR2SDRAM.CAWidth = CAWidth;
+ defparam DDR2SDRAM.DWidth = DWidth;
+ defparam DDR2SDRAM.BurstLen = BurstLen;
+ defparam DDR2SDRAM.EnableMask = EnableMask;
+ defparam DDR2SDRAM.EnableECC = EnableECC;
+ defparam DDR2SDRAM.Board = Board;
+ defparam DDR2SDRAM.MultiClock = 1;
+
+ assign DataIn = inDataWrite_d;
+ assign DataInMask = 16'b1111111111111111;
always @(posedge clk) begin
- if (!rst) begin
+ if (rst) begin
`reset
- ddr2_isread <= 0;
- ddr2_addr_r <= 0;
- ddr2_read_data_pop <= 0;
-
+ CommandValid <= 0;
+ DataOutReady <= 0;
end else begin
- `flush
-
- if (!inAddrRead_r_ && inAddrRead_a) inAddrRead_a <= 0;
- if (!inDataWrite_r_ && inDataWrite_a) inDataWrite_a <= 0;
- if (!inAddrWrite_r_ && inAddrWrite_a) inAddrWrite_a <= 0;
- if ( out_r && out_a) out_r <= 0;
-
- if (ddr2_addr_r && !ddr2_addr_a) begin
- // busy
- end else if (ddr2_addr_r && ddr2_addr_a && !ddr2_isread) begin
- ddr2_addr_r <= 0;
- inAddrWrite_a <= 1;
- inDataWrite_a <= 1;
- out_d <= { 1'b1, 37'b0 };
- out_r <= 1;
- end else if (ddr2_addr_r && ddr2_addr_a && ddr2_isread) begin
- ddr2_addr_r <= 0;
- inAddrRead_a <= 1;
- out_d <= { 1'b0, ddr2_read_data[36:0] };
- out_r <= 1;
- end else if (!out_r && !out_a && inAddrWrite_r && !inAddrWrite_a && inDataWrite_r && !inDataWrite_a && !ddr2_addr_r && !ddr2_addr_a) begin
- ddr2_addr_r <= 1;
- ddr2_isread <= 0;
- end else if (!out_r && !out_a && inAddrRead_r && !inAddrRead_a && !ddr2_addr_r && !ddr2_addr_a) begin
- ddr2_addr_r <= 1;
- ddr2_isread <= 1;
+ `cleanup
+
+ CommandValid <= 0;
+ DataInValid <= 0;
+
+ if (`out_empty) begin
+ DataOutReady <= 1;
+ end
+
+ if (DataOutReady && DataOutValid && `out_empty) begin
+ out_d <= { 1'b0, DataOut[`WORDWIDTH-1:0] };
+ `fill_out
+ DataOutReady <= 0;
+
+ end else if (DataOutReady && CommandReady && DataInReady && `out_empty) begin
+ if (`inAddrWrite_full && `inDataWrite_full) begin
+ `drain_inDataWrite
+ `drain_inAddrWrite
+ CommandAddress <= inAddrWrite_d;
+ Command <= 3'b000;
+ CommandValid <= 1;
+ DataInValid <= 1;
+ out_d <= { 1'b1, 37'b0 };
+ `fill_out
+ DataOutReady <= 0;
+ end else if (`inAddrRead_full) begin
+ `drain_inAddrRead
+ CommandAddress <= inAddrRead_d;
+ CommandValid <= 1;
+ Command <= 3'b001;
+ DataInValid <= 0;
+ DataOutReady <= 1;
+ end
end
end
end
+== Test ==============================================================
-== Test ========================================================
#skip
+#expect 0
+
+#ship debug : Debug
+#ship ddr : DDR2
+
+debug.in:
+ recv, deliver;
+
+ddr.out:
+ collect;
+ set flags a=!c,b=b;
+ send to debug.in;
+ collect;
+ set flags a=!c,b=b;
+ send to debug.in;
+ddr.inAddrWrite:
+ set word=0;
+ deliver;
+ deliver;
+ddr.inDataWrite:
+ set word=1;
+ deliver;
+ deliver;
+
+
+
== Constants ========================================================