added self-refresh to vivado IP GUI, tested self-refresh on hardware with microblaze

This commit is contained in:
AngeloJacobo 2024-11-24 17:40:21 +08:00
parent e08612658b
commit 05589c3f83
6 changed files with 151 additions and 41 deletions

View File

@ -49,6 +49,7 @@ module ddr3_top_axi #(
parameter[1:0] ECC_ENABLE = 0, // set to 1 or 2 to add ECC (1 = Side-band ECC per burst, 2 = Side-band ECC per 8 bursts , 3 = Inline ECC )
parameter[1:0] DIC = 2'b00, //Output Driver Impedance Control (2'b00 = RZQ/6, 2'b01 = RZQ/7, RZQ = 240ohms) (only change when you know what you are doing)
parameter[2:0] RTT_NOM = 3'b011, //RTT Nominal (3'b000 = disabled, 3'b001 = RZQ/4, 3'b010 = RZQ/2 , 3'b011 = RZQ/6, RZQ = 240ohms) (only change when you know what you are doing)
parameter[1:0] SELF_REFRESH = 2'b00, // 0 = use i_user_self_refresh input, 1 = Self-refresh mode is enabled after 64 controller clock cycles of no requests, 2 = 128 cycles, 3 = 256 cycles
parameter // The next parameters act more like a localparam (since user does not have to set this manually) but was added here to simplify port declaration
DQ_BITS = 8, //device width (fixed to 8, if DDR3 is x16 then BYTE_LANES will be 2 while )
serdes_ratio = 4, // this controller is fixed as a 4:1 memory controller (CONTROLLER_CLK_PERIOD/DDR3_CLK_PERIOD = 4)
@ -130,11 +131,14 @@ module ddr3_top_axi #(
output wire o_calib_complete,
//
// Debug outputs
output wire[31:0] o_debug1
output wire[31:0] o_debug1,
// output wire[31:0] o_debug2,
// output wire[31:0] o_debug3,
// output wire[(DQ_BITS*BYTE_LANES)/8-1:0] o_ddr3_debug_read_dqs_p,
// output wire[(DQ_BITS*BYTE_LANES)/8-1:0] o_ddr3_debug_read_dqs_n
//
// User enabled self-refresh
input wire i_user_self_refresh
);
wire wb_cyc;
@ -165,7 +169,8 @@ ddr3_top #(
.SKIP_INTERNAL_TEST(SKIP_INTERNAL_TEST), // skip built-in self test (would require >2 seconds of internal test right after calibration)
.ECC_ENABLE(ECC_ENABLE), // set to 1 or 2 to add ECC (1 = Side-band ECC per burst, 2 = Side-band ECC per 8 bursts , 3 = Inline ECC )
.DIC(DIC), // Output Driver Impedance Control (2'b00 = RZQ/6, 2'b01 = RZQ/7, RZQ = 240ohms) (only change when you know what you are doing)
.RTT_NOM(RTT_NOM) //RTT Nominal (3'b000 = disabled, 3'b001 = RZQ/4, 3'b010 = RZQ/2 , 3'b011 = RZQ/6, RZQ = 240ohms) (only change when you know what you are doing)
.RTT_NOM(RTT_NOM), //RTT Nominal (3'b000 = disabled, 3'b001 = RZQ/4, 3'b010 = RZQ/2 , 3'b011 = RZQ/6, RZQ = 240ohms) (only change when you know what you are doing)
.SELF_REFRESH(SELF_REFRESH) // Self-refresh options (0 = use i_user_self_refresh input, 1 = Self-refresh mode is enabled after 64 controller clock cycles of no requests, 2 = 128 cycles, 3 = 256 cycles)
) ddr3_top_inst
(
//clock and reset
@ -222,11 +227,13 @@ ddr3_top #(
.o_calib_complete(o_calib_complete),
//
// Debug outputs
.o_debug1(o_debug1)
.o_debug1(o_debug1),
// .o_debug2(o_debug2),
// .o_debug3(o_debug3),
// .o_ddr3_debug_read_dqs_p(o_ddr3_debug_read_dqs_p),
// .o_ddr3_debug_read_dqs_n(o_ddr3_debug_read_dqs_n)
//
.i_user_self_refresh(i_user_self_refresh)
////////////////////////////////////
);

View File

@ -489,7 +489,8 @@ module ddr3_controller #(
initial begin
o_phy_bitslip = 0;
end
reg cmd_odt_q = 0, cmd_odt, cmd_ck_en, cmd_reset_n;
reg cmd_odt_q = 0, cmd_odt, cmd_reset_n;
(* mark_debug = "true" *) reg cmd_ck_en;
reg o_wb_stall_q = 1, o_wb_stall_d, o_wb_stall_calib = 1;
reg precharge_slot_busy;
reg activate_slot_busy;

View File

@ -371,5 +371,29 @@ ddr3_top #(
.o_ddr3_debug_read_dqs_p(/*o_ddr3_debug_read_dqs_p*/),
.o_ddr3_debug_read_dqs_n(/*o_ddr3_debug_read_dqs_n*/)
);
// display value of parameters for easy debugging
initial begin
$display("\nDDR3 TOP PARAMETERS:\n-----------------------------");
$display("CONTROLLER_CLK_PERIOD = %0d", CONTROLLER_CLK_PERIOD);
$display("DDR3_CLK_PERIOD = %0d", DDR3_CLK_PERIOD);
$display("ROW_BITS = %0d", ROW_BITS);
$display("COL_BITS = %0d", COL_BITS);
$display("BA_BITS = %0d", BA_BITS);
$display("BYTE_LANES = %0d", BYTE_LANES);
$display("AUX_WIDTH = %0d", AUX_WIDTH);
$display("WB2_ADDR_BITS = %0d", WB2_ADDR_BITS);
$display("WB2_DATA_BITS = %0d", WB2_DATA_BITS);
$display("MICRON_SIM = %0d", MICRON_SIM);
$display("ODELAY_SUPPORTED = %0d", ODELAY_SUPPORTED);
$display("SECOND_WISHBONE = %0d", SECOND_WISHBONE);
$display("WB_ERROR = %0d", WB_ERROR);
$display("SKIP_INTERNAL_TEST = %0d", SKIP_INTERNAL_TEST);
$display("ECC_ENABLE = %0d", ECC_ENABLE);
$display("DIC = %0d", DIC);
$display("RTT_NOM = %0d", RTT_NOM);
$display("SELF_REFRESH = %0d", SELF_REFRESH);
$display("End of DDR3 TOP PARAMETERS\n-----------------------------");
end
endmodule

View File

@ -311,28 +311,6 @@
</spirit:portMap>
</spirit:portMaps>
</spirit:busInterface>
<spirit:busInterface>
<spirit:name>i_rst_n</spirit:name>
<spirit:busType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset" spirit:version="1.0"/>
<spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset_rtl" spirit:version="1.0"/>
<spirit:slave/>
<spirit:portMaps>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>RST</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>i_rst_n</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
</spirit:portMaps>
<spirit:parameters>
<spirit:parameter>
<spirit:name>POLARITY</spirit:name>
<spirit:value spirit:id="BUSIFPARAM_VALUE.I_RST_N.POLARITY" spirit:choiceRef="choice_list_9d8b0d81">ACTIVE_LOW</spirit:value>
</spirit:parameter>
</spirit:parameters>
</spirit:busInterface>
<spirit:busInterface>
<spirit:name>i_controller_clk</spirit:name>
<spirit:busType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="clock" spirit:version="1.0"/>
@ -387,6 +365,28 @@
</spirit:portMap>
</spirit:portMaps>
</spirit:busInterface>
<spirit:busInterface>
<spirit:name>i_rst_n</spirit:name>
<spirit:busType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset" spirit:version="1.0"/>
<spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset_rtl" spirit:version="1.0"/>
<spirit:slave/>
<spirit:portMaps>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>RST</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>i_rst_n</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
</spirit:portMaps>
<spirit:parameters>
<spirit:parameter>
<spirit:name>POLARITY</spirit:name>
<spirit:value spirit:id="BUSIFPARAM_VALUE.I_RST_N.POLARITY" spirit:choiceRef="choice_list_9d8b0d81">ACTIVE_LOW</spirit:value>
</spirit:parameter>
</spirit:parameters>
</spirit:busInterface>
<spirit:busInterface>
<spirit:name>ddr3</spirit:name>
<spirit:displayName>ddr3</spirit:displayName>
@ -561,7 +561,7 @@
<spirit:parameters>
<spirit:parameter>
<spirit:name>viewChecksum</spirit:name>
<spirit:value>e9f63973</spirit:value>
<spirit:value>1dea7b87</spirit:value>
</spirit:parameter>
</spirit:parameters>
</spirit:view>
@ -577,7 +577,7 @@
<spirit:parameters>
<spirit:parameter>
<spirit:name>viewChecksum</spirit:name>
<spirit:value>e9f63973</spirit:value>
<spirit:value>1dea7b87</spirit:value>
</spirit:parameter>
</spirit:parameters>
</spirit:view>
@ -591,7 +591,7 @@
<spirit:parameters>
<spirit:parameter>
<spirit:name>viewChecksum</spirit:name>
<spirit:value>30e22270</spirit:value>
<spirit:value>ce7b9cf6</spirit:value>
</spirit:parameter>
</spirit:parameters>
</spirit:view>
@ -1578,6 +1578,29 @@
</spirit:wireTypeDefs>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>i_user_self_refresh</spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:wireTypeDefs>
<spirit:wireTypeDef>
<spirit:typeName>wire</spirit:typeName>
<spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef>
<spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef>
</spirit:wireTypeDef>
</spirit:wireTypeDefs>
<spirit:driver>
<spirit:defaultValue spirit:format="long">0</spirit:defaultValue>
</spirit:driver>
</spirit:wire>
<spirit:vendorExtensions>
<xilinx:portInfo>
<xilinx:enablement>
<xilinx:isEnabled xilinx:resolve="dependent" xilinx:id="PORT_ENABLEMENT.i_user_self_refresh" xilinx:dependency="$SELF_REFRESH = 0">true</xilinx:isEnabled>
</xilinx:enablement>
</xilinx:portInfo>
</spirit:vendorExtensions>
</spirit:port>
</spirit:ports>
<spirit:modelParameters>
<spirit:modelParameter xsi:type="spirit:nameValueTypeType" spirit:dataType="integer">
@ -1655,6 +1678,11 @@
<spirit:displayName>Ecc Enable</spirit:displayName>
<spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.ECC_ENABLE">0</spirit:value>
</spirit:modelParameter>
<spirit:modelParameter spirit:dataType="integer">
<spirit:name>SELF_REFRESH</spirit:name>
<spirit:displayName>Self-Refresh</spirit:displayName>
<spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.SELF_REFRESH">0</spirit:value>
</spirit:modelParameter>
<spirit:modelParameter spirit:dataType="integer">
<spirit:name>DIC</spirit:name>
<spirit:displayName>Dic</spirit:displayName>
@ -1723,6 +1751,20 @@
<spirit:enumeration>ACTIVE_HIGH</spirit:enumeration>
<spirit:enumeration>ACTIVE_LOW</spirit:enumeration>
</spirit:choice>
<spirit:choice>
<spirit:name>choice_pairs_933dc0fc</spirit:name>
<spirit:enumeration spirit:text="0 (ECC DIsabled)">0</spirit:enumeration>
<spirit:enumeration spirit:text="1 (Side-band ECC per burst)">1</spirit:enumeration>
<spirit:enumeration spirit:text="2 (Side-band ECC per 8 bursts)">2</spirit:enumeration>
<spirit:enumeration spirit:text="3 (Inline ECC)">3</spirit:enumeration>
</spirit:choice>
<spirit:choice>
<spirit:name>choice_pairs_96a879b9</spirit:name>
<spirit:enumeration spirit:text="0 (Enable self-refresh based on i_user_self_refresh)">0</spirit:enumeration>
<spirit:enumeration spirit:text="1 (Enable self-refresh after 64 clock cycles of inactivity)">1</spirit:enumeration>
<spirit:enumeration spirit:text="2 (Enable self-refresh after 128 clock cycles of inactivity)">2</spirit:enumeration>
<spirit:enumeration spirit:text="3 (Enable self-refresh after 256 clock cycles of inactivity)">3</spirit:enumeration>
</spirit:choice>
</spirit:choices>
<spirit:fileSets>
<spirit:fileSet>
@ -1778,7 +1820,7 @@
<spirit:file>
<spirit:name>../rtl/axi/ddr3_top_axi.v</spirit:name>
<spirit:fileType>verilogSource</spirit:fileType>
<spirit:userFileType>CHECKSUM_4123fcc3</spirit:userFileType>
<spirit:userFileType>CHECKSUM_f4e2d855</spirit:userFileType>
</spirit:file>
</spirit:fileSet>
<spirit:fileSet>
@ -1841,7 +1883,7 @@
<spirit:file>
<spirit:name>xgui/uberddr3_axi_v1_0.tcl</spirit:name>
<spirit:fileType>tclSource</spirit:fileType>
<spirit:userFileType>CHECKSUM_30e22270</spirit:userFileType>
<spirit:userFileType>CHECKSUM_ce7b9cf6</spirit:userFileType>
<spirit:userFileType>XGUI_VERSION_2</spirit:userFileType>
</spirit:file>
</spirit:fileSet>
@ -1935,7 +1977,7 @@
<spirit:parameter>
<spirit:name>ECC_ENABLE</spirit:name>
<spirit:displayName>ECC Enable</spirit:displayName>
<spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.ECC_ENABLE" spirit:minimum="0" spirit:maximum="3" spirit:rangeType="long">0</spirit:value>
<spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.ECC_ENABLE" spirit:choiceRef="choice_pairs_933dc0fc">0</spirit:value>
</spirit:parameter>
<spirit:parameter>
<spirit:name>DIC</spirit:name>
@ -2057,6 +2099,11 @@
<spirit:name>Component_Name</spirit:name>
<spirit:value spirit:resolve="user" spirit:id="PARAM_VALUE.Component_Name" spirit:order="1">uberddr3_axi_v1_0</spirit:value>
</spirit:parameter>
<spirit:parameter>
<spirit:name>SELF_REFRESH</spirit:name>
<spirit:displayName>Self-Refresh</spirit:displayName>
<spirit:value spirit:resolve="user" spirit:id="PARAM_VALUE.SELF_REFRESH" spirit:choiceRef="choice_pairs_96a879b9">0</spirit:value>
</spirit:parameter>
</spirit:parameters>
<spirit:vendorExtensions>
<xilinx:coreExtensions>
@ -2090,20 +2137,20 @@
<xilinx:displayName>uberddr3_axi_v1_0</xilinx:displayName>
<xilinx:definitionSource>package_project</xilinx:definitionSource>
<xilinx:vendorURL>https://github.com/AngeloJacobo/UberDDR3</xilinx:vendorURL>
<xilinx:coreRevision>9</xilinx:coreRevision>
<xilinx:coreCreationDateTime>2024-10-19T05:33:11Z</xilinx:coreCreationDateTime>
<xilinx:coreRevision>11</xilinx:coreRevision>
<xilinx:coreCreationDateTime>2024-11-24T08:00:34Z</xilinx:coreCreationDateTime>
<xilinx:tags>
<xilinx:tag xilinx:name="nopcore"/>
</xilinx:tags>
</xilinx:coreExtensions>
<xilinx:packagingInfo>
<xilinx:xilinxVersion>2022.1</xilinx:xilinxVersion>
<xilinx:checksum xilinx:scope="busInterfaces" xilinx:value="a8e6cc4e"/>
<xilinx:checksum xilinx:scope="busInterfaces" xilinx:value="6c0c2bc0"/>
<xilinx:checksum xilinx:scope="memoryMaps" xilinx:value="cd65c31e"/>
<xilinx:checksum xilinx:scope="fileGroups" xilinx:value="68e3a14b"/>
<xilinx:checksum xilinx:scope="ports" xilinx:value="a969876f"/>
<xilinx:checksum xilinx:scope="fileGroups" xilinx:value="ba5aba03"/>
<xilinx:checksum xilinx:scope="ports" xilinx:value="abd96048"/>
<xilinx:checksum xilinx:scope="hdlParameters" xilinx:value="86f21185"/>
<xilinx:checksum xilinx:scope="parameters" xilinx:value="17670e8c"/>
<xilinx:checksum xilinx:scope="parameters" xilinx:value="5574e240"/>
</xilinx:packagingInfo>
</spirit:vendorExtensions>
</spirit:component>

View File

@ -15,6 +15,7 @@ proc init_gui { IPINST } {
ipgui::add_param $IPINST -name "DIC" -parent ${Page_0}
ipgui::add_param $IPINST -name "DQ_BITS" -parent ${Page_0}
ipgui::add_param $IPINST -name "ECC_ENABLE" -parent ${Page_0}
ipgui::add_param $IPINST -name "SELF_REFRESH" -parent ${Page_0}
ipgui::add_param $IPINST -name "MICRON_SIM" -parent ${Page_0}
ipgui::add_param $IPINST -name "ODELAY_SUPPORTED" -parent ${Page_0}
ipgui::add_param $IPINST -name "ROW_BITS" -parent ${Page_0}
@ -142,6 +143,15 @@ proc validate_PARAM_VALUE.ECC_ENABLE { PARAM_VALUE.ECC_ENABLE } {
return true
}
proc update_PARAM_VALUE.SELF_REFRESH { PARAM_VALUE.SELF_REFRESH } {
# Procedure called to update SELF_REFRESH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.SELF_REFRESH { PARAM_VALUE.SELF_REFRESH } {
# Procedure called to validate SELF_REFRESH
return true
}
proc update_PARAM_VALUE.MICRON_SIM { PARAM_VALUE.MICRON_SIM } {
# Procedure called to update MICRON_SIM when any of the dependent parameters in the arguments change
}
@ -353,6 +363,11 @@ proc update_MODELPARAM_VALUE.ECC_ENABLE { MODELPARAM_VALUE.ECC_ENABLE PARAM_VALU
set_property value [get_property value ${PARAM_VALUE.ECC_ENABLE}] ${MODELPARAM_VALUE.ECC_ENABLE}
}
proc update_MODELPARAM_VALUE.SELF_REFRESH { MODELPARAM_VALUE.SELF_REFRESH PARAM_VALUE.SELF_REFRESH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.SELF_REFRESH}] ${MODELPARAM_VALUE.SELF_REFRESH}
}
proc update_MODELPARAM_VALUE.DIC { MODELPARAM_VALUE.DIC PARAM_VALUE.DIC } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.DIC}] ${MODELPARAM_VALUE.DIC}

View File

@ -19,8 +19,10 @@ proc init_gui { IPINST } {
set_property tooltip {Width of bank address} ${BA_BITS}
set BYTE_LANES [ipgui::add_param $IPINST -name "BYTE_LANES" -parent ${Page_0}]
set_property tooltip {Number of byte lanes of DDR3 RAM in the FPGA board (e.g. x16 DDR3 will have 2 byte lanes)} ${BYTE_LANES}
set ECC_ENABLE [ipgui::add_param $IPINST -name "ECC_ENABLE" -parent ${Page_0}]
set_property tooltip {0 = DIsabled, 1 = Side-band ECC per burst, 2 = Side-band ECC per 8 bursts , 3 = Inline ECC} ${ECC_ENABLE}
set ECC_ENABLE [ipgui::add_param $IPINST -name "ECC_ENABLE" -parent ${Page_0} -widget comboBox]
set_property tooltip {Type of ECC (0,1,2,3)} ${ECC_ENABLE}
set SELF_REFRESH [ipgui::add_param $IPINST -name "SELF_REFRESH" -parent ${Page_0} -widget comboBox]
set_property tooltip {Enable option for self-refresh} ${SELF_REFRESH}
set SKIP_INTERNAL_TEST [ipgui::add_param $IPINST -name "SKIP_INTERNAL_TEST" -parent ${Page_0}]
set_property tooltip {Check to skip built-in self-test (check this if UberDDR3 will be connected to Microblaze)} ${SKIP_INTERNAL_TEST}
set ODELAY_SUPPORTED [ipgui::add_param $IPINST -name "ODELAY_SUPPORTED" -parent ${Page_0}]
@ -284,6 +286,15 @@ proc validate_PARAM_VALUE.SECOND_WISHBONE { PARAM_VALUE.SECOND_WISHBONE } {
return true
}
proc update_PARAM_VALUE.SELF_REFRESH { PARAM_VALUE.SELF_REFRESH } {
# Procedure called to update SELF_REFRESH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.SELF_REFRESH { PARAM_VALUE.SELF_REFRESH } {
# Procedure called to validate SELF_REFRESH
return true
}
proc update_PARAM_VALUE.SKIP_INTERNAL_TEST { PARAM_VALUE.SKIP_INTERNAL_TEST } {
# Procedure called to update SKIP_INTERNAL_TEST when any of the dependent parameters in the arguments change
}
@ -405,6 +416,11 @@ proc update_MODELPARAM_VALUE.ECC_ENABLE { MODELPARAM_VALUE.ECC_ENABLE PARAM_VALU
set_property value [get_property value ${PARAM_VALUE.ECC_ENABLE}] ${MODELPARAM_VALUE.ECC_ENABLE}
}
proc update_MODELPARAM_VALUE.SELF_REFRESH { MODELPARAM_VALUE.SELF_REFRESH PARAM_VALUE.SELF_REFRESH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.SELF_REFRESH}] ${MODELPARAM_VALUE.SELF_REFRESH}
}
proc update_MODELPARAM_VALUE.DIC { MODELPARAM_VALUE.DIC PARAM_VALUE.DIC } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.DIC}] ${MODELPARAM_VALUE.DIC}