Merge pull request #17 from AngeloJacobo/self_refresh_feature
Add self refresh feature (passing simulation, formal, and hardware test)
This commit is contained in:
commit
29ce61bcac
|
|
@ -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)
|
||||
////////////////////////////////////
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -135,9 +135,11 @@ module ddr3_controller #(
|
|||
// Done Calibration pin
|
||||
output wire o_calib_complete,
|
||||
// Debug port
|
||||
output wire [31:0] o_debug1
|
||||
output wire [31:0] o_debug1,
|
||||
// output wire [31:0] o_debug2,
|
||||
// output wire [31:0] o_debug3
|
||||
// User enabled self-refresh
|
||||
input wire i_user_self_refresh
|
||||
);
|
||||
|
||||
|
||||
|
|
@ -150,8 +152,10 @@ module ddr3_controller #(
|
|||
CMD_WR = 4'b0100, // Write (A10-AP: 0 = no Auto-Precharge) (A12-BC#: 1 = Burst Length 8)
|
||||
CMD_RD = 4'b0101, //Read (A10-AP: 0 = no Auto-Precharge) (A12-BC#: 1 = Burst Length 8)
|
||||
CMD_NOP = 4'b0111, // No Operation
|
||||
CMD_ZQC = 4'b0110; // ZQ Calibration (A10-AP: 0 = ZQ Calibration Short, 1 = ZQ Calibration Long)
|
||||
|
||||
CMD_ZQC = 4'b0110, // ZQ Calibration (A10-AP: 0 = ZQ Calibration Short, 1 = ZQ Calibration Long)
|
||||
CMD_SREF_EN = 4'b0001,
|
||||
CMD_SREF_XT = 4'b0111;
|
||||
|
||||
localparam RST_DONE = 27, // Command bit that determines if reset seqeunce had aready finished. non-persistent (only needs to be toggled once),
|
||||
REF_IDLE = 27, // No refresh is about to start and no ongoing refresh. (same bit as RST_DONE)
|
||||
USE_TIMER = 26, // Command bit that determines if timer will be used (if delay is zero, USE_TIMER must be LOW)
|
||||
|
|
@ -248,7 +252,11 @@ module ddr3_controller #(
|
|||
localparam DELAY_MAX_VALUE = ps_to_cycles(INITIAL_CKE_LOW); //Largest possible delay needed by the reset and refresh sequence
|
||||
localparam DELAY_COUNTER_WIDTH= $clog2(DELAY_MAX_VALUE); //Bitwidth needed by the maximum possible delay, this will be the delay counter width
|
||||
localparam CALIBRATION_DELAY = 2; // must be >= 2
|
||||
|
||||
localparam tXSDLL = nCK_to_cycles(512); // cycles (controller) Exit Self Refresh to commands requiring a locked DLL
|
||||
localparam tXSDLL_tRFC = tXSDLL - ps_to_cycles(tRFC); // cycles (controller) Time before refresh after exit from self-refresh
|
||||
localparam tCKE = max(3, ps_to_nCK(7500) ); // nCK CKE minimum pulse width
|
||||
localparam tCKESR = nCK_to_cycles(tCKE + 1)+ 5; // cycles (controller) Minimum time that the DDR3 SDRAM must remain in Self-Refresh mode is tCKESR
|
||||
localparam tCPDED = 1; // cycle (tCPDED is at most 2nCK but we make it to 1cycle or 4nCK) Command pass disable delay , required cycles of NOP after CKE low
|
||||
/*********************************************************************************************************************************************/
|
||||
|
||||
|
||||
|
|
@ -481,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;
|
||||
|
|
@ -586,7 +595,8 @@ module ddr3_controller #(
|
|||
wire db_err_o;
|
||||
wire[wb_data_bits - 1:0] o_wb_data_q_decoded;
|
||||
/* verilator lint_on UNDRIVEN */
|
||||
|
||||
reg user_self_refresh_q; // registered i_user_self_refresh
|
||||
|
||||
// initial block for all regs
|
||||
initial begin
|
||||
o_wb_stall = 1;
|
||||
|
|
@ -660,7 +670,7 @@ module ddr3_controller #(
|
|||
else
|
||||
read_rom_instruction = {5'b01000 , CMD_NOP , ps_to_cycles(POWER_ON_RESET_HIGH)};
|
||||
//0. RESET# needs to be maintained low for minimum 200us with power-up initialization. CKE is pulled
|
||||
//“Low” anytime before RESET# being de-asserted (min. time 10 ns). .
|
||||
//“Low<EFBFBD>? anytime before RESET# being de-asserted (min. time 10 ns). .
|
||||
|
||||
5'd1:
|
||||
if (MICRON_SIM)
|
||||
|
|
@ -727,7 +737,7 @@ module ddr3_controller #(
|
|||
5'd18: read_rom_instruction = {5'b01011, CMD_NOP, tMOD[DELAY_SLOT_WIDTH-1:0]};
|
||||
//18. Delay of tMOD between MRS command to a non-MRS command excluding NOP and DES
|
||||
|
||||
// Perform first refresh and any subsequent refresh (so instruction 12 to 15 will be re-used for the refresh sequence)
|
||||
// Perform first refresh and any subsequent refresh (so instruction 19 to 22 will be re-used for the refresh sequence)
|
||||
5'd19: read_rom_instruction = {5'b01111, CMD_PRE, ps_to_cycles(tRP)};
|
||||
//19. All banks must be precharged (A10-AP = high) and idle for a minimum of the precharge time tRP(min) before the Refresh Command can be applied.
|
||||
|
||||
|
|
@ -740,7 +750,22 @@ module ddr3_controller #(
|
|||
|
||||
5'd22: read_rom_instruction = {5'b01011, CMD_NOP, PRE_REFRESH_DELAY[DELAY_SLOT_WIDTH-1:0]};
|
||||
// 22. Extra delay needed before starting the refresh sequence.
|
||||
// (this already sets the wishbone stall high to make sure no user request is on-going when refresh seqeunce starts)
|
||||
// (this already sets the wishbone stall high to make sure no user request is on-going when refresh seqeunce starts)
|
||||
|
||||
5'd23: read_rom_instruction = {5'b01111, CMD_PRE, ps_to_cycles(tRP)};
|
||||
// 23. All banks must be precharged (A10-AP = high) and idle for a minimum of the precharge time tRP(min) before the Self-Refresh Command can be applied.
|
||||
|
||||
5'd24: read_rom_instruction = {5'b01001, CMD_NOP, tCPDED[DELAY_SLOT_WIDTH-1:0]};
|
||||
// 24. CKE must go low to enter self-refresh, tCPDED cycles of NOP are required before CMD_SREF_EN
|
||||
|
||||
5'd25: read_rom_instruction = {5'b01001, CMD_SREF_EN, tCKESR[DELAY_SLOT_WIDTH-1:0]};
|
||||
// 25. Self-refresh entry
|
||||
// JEDEC Standard No. 79-3E Page 79: The minimum time that the DDR3 SDRAM must remain in Self-Refresh mode is tCKESR
|
||||
|
||||
5'd26: read_rom_instruction = {5'b01011, CMD_SREF_XT, tXSDLL_tRFC[DELAY_SLOT_WIDTH-1:0]};
|
||||
// 26. From 25 (Self-refresh entry), wait until user-self_refresh is disabled then wait for tXSDLL - tRFC before going to 20 (Refresh)
|
||||
// JEDEC Standard No. 79-3E Page 79: Before a command that requires a locked DLL can be applied, a delay of at least tXSDLL must be satisfied.
|
||||
// JEDEC Standard No. 79-3E Page 80: Upon exit from Self-Refresh, the DDR3 SDRAM requires a minimum of one extra refresh command before it is put back into Self-Refresh Mode.
|
||||
|
||||
default: read_rom_instruction = {5'b00011, CMD_NOP, {(DELAY_SLOT_WIDTH){1'b0}}};
|
||||
endcase
|
||||
|
|
@ -778,21 +803,45 @@ module ddr3_controller #(
|
|||
//delay_counter is 1 (for r/w calibration and prestall delay)
|
||||
//address will only move forward for these kinds of delay only
|
||||
//when skip_reset_seq_delay is toggled
|
||||
else if(instruction[USE_TIMER] /*&& delay_counter != {(DELAY_COUNTER_WIDTH){1'b1}}*/ && !pause_counter) delay_counter <= delay_counter - 1;
|
||||
else if(instruction[USE_TIMER] /*&& delay_counter != {(DELAY_COUNTER_WIDTH){1'b1}}*/ && !pause_counter && delay_counter != 0) delay_counter <= delay_counter - 1;
|
||||
|
||||
//delay_counter of 1 means we will need to update the delay_counter next clock cycle (delay_counter of zero) so we need to retrieve
|
||||
//now the next instruction. The same thing needs to be done when current instruction does not need the timer delay.
|
||||
if(delay_counter == 1 || !instruction[USE_TIMER]/* || skip_reset_seq_delay*/) begin
|
||||
delay_counter_is_zero <= 1;
|
||||
instruction <= read_rom_instruction(instruction_address);
|
||||
instruction_address <= (instruction_address == 5'd22)? 5'd19:instruction_address+1; //wrap back of address to repeat refresh sequence
|
||||
if(instruction_address == 5'd22) begin // if user_self_refresh is disabled, wrap back to 19 (Precharge All before Refresh)
|
||||
instruction_address <= 5'd19;
|
||||
end
|
||||
else if(instruction_address == 5'd26) begin // self-refresh exit always wraps back to 20 (Refresh)
|
||||
instruction_address <= 5'd20;
|
||||
end
|
||||
else begin
|
||||
instruction_address <= instruction_address + 5'd1; // just increment address
|
||||
end
|
||||
end
|
||||
//we are now on the middle of a delay
|
||||
else delay_counter_is_zero <=0;
|
||||
else begin
|
||||
delay_counter_is_zero <=0;
|
||||
end
|
||||
|
||||
if(instruction_address == 5'd22 && user_self_refresh_q) begin // if user_self_refresh is enabled, go straight to 23
|
||||
instruction_address <= 23; // go to Precharge All for Self-refresh
|
||||
delay_counter_is_zero <= 1;
|
||||
delay_counter <= 0;
|
||||
instruction <= read_rom_instruction(instruction_address);
|
||||
end
|
||||
|
||||
|
||||
//instruction[RST_DONE] is non-persistent thus we need to register it once it goes high
|
||||
reset_done <= instruction[RST_DONE]? 1'b1:reset_done;
|
||||
end
|
||||
end
|
||||
|
||||
// register user-enabled self-refresh
|
||||
always @(posedge i_controller_clk) begin
|
||||
user_self_refresh_q <= i_user_self_refresh && (user_self_refresh_q || (instruction_address != 5'd26)) && final_calibration_done; //will not go high again if already at instruction_address 26 (self-refresh exit), only go high when calibration is done
|
||||
end
|
||||
/*********************************************************************************************************************************************/
|
||||
|
||||
|
||||
|
|
@ -879,7 +928,7 @@ module ddr3_controller #(
|
|||
bank_active_row_q[index] <= bank_active_row_d[index];
|
||||
end
|
||||
|
||||
if(instruction_address == 20) begin ///current instruction at precharge
|
||||
if(instruction_address == 20 || instruction_address == 24) begin ///current instruction at precharge
|
||||
cmd_odt_q <= 1'b0;
|
||||
//all banks will be in idle after refresh
|
||||
for( index=0; index < (1<<BA_BITS); index=index+1) begin
|
||||
|
|
@ -2567,6 +2616,12 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
DONE_CALIBRATE: begin
|
||||
calib_stb <= 0;
|
||||
state_calibrate <= DONE_CALIBRATE;
|
||||
if(instruction_address == 5'd26) begin // Self-refresh Exit
|
||||
pause_counter <= user_self_refresh_q; // wait until user-self-refresh is disabled before continuing 25 (Self-refresh Exit)
|
||||
end
|
||||
else begin
|
||||
pause_counter <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endcase
|
||||
|
|
@ -2581,7 +2636,7 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
if(odelay_data_cntvaluein[lane] == 15) begin
|
||||
odelay_cntvalue_halfway <= 1;
|
||||
end
|
||||
if(instruction_address == 19) begin //pre-stall delay to finish all remaining requests
|
||||
if(instruction_address == 19 || instruction_address == 23) begin //pre-stall delay before precharge all to finish all remaining requests
|
||||
pause_counter <= 1; // pause instruction address until pre-stall delay before refresh sequence finishes
|
||||
//skip to instruction address 20 (precharge all before refresh) when no pending requests anymore
|
||||
//toggle it for 1 clk cycle only
|
||||
|
|
@ -3463,9 +3518,24 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
end
|
||||
//move the pipeline forward when counter is about to go zero and we are not yet at end of reset sequence
|
||||
else if((delay_counter == 1 || !instruction[USE_TIMER])) begin
|
||||
f_addr <= (f_addr == 22)? 19:f_addr + 1;
|
||||
if(f_addr == 22 && user_self_refresh_q) begin // if self refresh, move forward
|
||||
f_addr <= 23;
|
||||
end
|
||||
else if(f_addr == 22 & !user_self_refresh_q) begin // if not self refresh, move backward
|
||||
f_addr <= 19;
|
||||
end
|
||||
else if (f_addr == 26) begin // 26 (self-refresh exit) always wraps back to 20 (refresh)
|
||||
f_addr <= 20;
|
||||
end
|
||||
else begin // else, just increment
|
||||
f_addr <= f_addr + 1;
|
||||
end
|
||||
f_read <= f_addr;
|
||||
end
|
||||
else if(f_addr == 22 && user_self_refresh_q) begin // if self refresh, move forward immediately (no need to wait for delay zero)
|
||||
f_addr <= 23;
|
||||
f_read <= f_addr;
|
||||
end
|
||||
end
|
||||
|
||||
// assert f_addr and f_read as shadows of next and current instruction address
|
||||
|
|
@ -3490,11 +3560,11 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
end
|
||||
else if(f_past_valid) begin
|
||||
//if counter is zero previously and current instruction needs timer delay, then this cycle should now have the new updated counter value
|
||||
if( $past(delay_counter_is_zero) && $past(f_read_inst[USE_TIMER]) ) begin
|
||||
if( $past(delay_counter_is_zero) && $past(f_read_inst[USE_TIMER]) && !$past(user_self_refresh_q) ) begin
|
||||
assert(delay_counter == f_read_inst[DELAY_COUNTER_WIDTH - 1:0]);
|
||||
end
|
||||
//delay_counter_is_zero can be high when counter is zero and current instruction needs delay
|
||||
if($past(f_read_inst[USE_TIMER]) && !$past(pause_counter) ) begin
|
||||
if($past(f_read_inst[USE_TIMER]) && !$past(pause_counter) && !$past(user_self_refresh_q)) begin
|
||||
assert( delay_counter_is_zero == (delay_counter == 0) );
|
||||
end
|
||||
//delay_counter_is_zero will go high this cycle when we received a don't-use-timer instruction
|
||||
|
|
@ -3511,12 +3581,12 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
|
||||
//if delay is not yet zero and timer delay is enabled, then delay_counter should decrement
|
||||
if(!$past(delay_counter_is_zero) && $past(f_read_inst[USE_TIMER]) && !$past(pause_counter) ) begin
|
||||
assert(delay_counter == $past(delay_counter) - 1);
|
||||
assert((delay_counter == $past(delay_counter) - 1) || (delay_counter == 0 && $past(user_self_refresh_q)));
|
||||
assert(delay_counter < $past(delay_counter) ); //just to make sure delay_counter will never overflow back to all 1's
|
||||
end
|
||||
|
||||
//sanity checking for the comment "delay_counter will be zero AT NEXT CLOCK CYCLE when counter is now one"
|
||||
if($past(delay_counter) == 1) begin
|
||||
if($past(delay_counter) == 1 && !$past(pause_counter)) begin
|
||||
assert(delay_counter == 0 && delay_counter_is_zero);
|
||||
end
|
||||
//assert the relationship between the stages FOR RESET SEQUENCE
|
||||
|
|
@ -3537,15 +3607,18 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
//assert the relationship between the stages FOR REFRESH SEQUENCE
|
||||
else begin
|
||||
if(f_read == 22) begin
|
||||
assert(f_addr == 19); //if current instruction is 22, then next instruction must be at 19 (instruction address wraps from 15 to 12)
|
||||
assert( (f_addr == 19) || (f_addr == 23 ) ); //if current instruction is 22, then next instruction must be at 19 or 23 (instruction address wraps from 22 to 19 if not self refresh, else 22 to 23)
|
||||
end
|
||||
else if(f_addr == 19) begin
|
||||
assert(f_read == 22); //if next instruction is at 12, then current instruction must be at 15 (instruction address wraps from 15 to 12)
|
||||
else if(f_addr == 19 || f_addr == 23) begin
|
||||
assert(f_read == 22); //if next instruction is at 19 or 23, then current instruction must be at 22 (instruction address wraps from 22 to 19)
|
||||
end
|
||||
else if(f_read == 26) begin
|
||||
assert(f_addr == 20); // if current instruction is 26 (exit self-refresh) then go to 20 (refresh)
|
||||
end
|
||||
else begin
|
||||
assert(f_read + 1 == f_addr); //if there is no need to wrap around, then instruction address must increment
|
||||
end
|
||||
assert((f_read >= 19 && f_read <= 22) ); //refresh sequence is only on instruction address 19,20,21,22
|
||||
assert((f_read >= 19 && f_read <= 26) ); //refresh sequence is only on instruction address 19,20,21,22
|
||||
end
|
||||
|
||||
// reset_done must retain high when it was already asserted once
|
||||
|
|
@ -3562,7 +3635,7 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
if(reset_done && f_read_inst[REF_IDLE]) begin
|
||||
assert(f_read == 21);
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -3575,9 +3648,18 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
assert( a[DELAY_COUNTER_WIDTH - 1:0] > 0);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// assertion on FSM calibration
|
||||
always @* begin
|
||||
if(instruction_address == 19 || instruction_address == 23) begin //pre-stall delay before precharge all to finish all remaining requests
|
||||
if(pause_counter == 1) begin // if there are still pending requests (pause_counter high) then delay_counter should still be at PRE_REFRESH_DELAY
|
||||
assert(delay_counter == PRE_REFRESH_DELAY);
|
||||
end
|
||||
end
|
||||
if(instruction_address >= 24 && instruction_address < 26) begin
|
||||
assert(!pause_counter); // no pause counter from precharge to sel-refresh entry
|
||||
end
|
||||
|
||||
if(instruction_address < 13) begin
|
||||
assert(state_calibrate == IDLE);
|
||||
end
|
||||
|
|
@ -3595,6 +3677,7 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
|
||||
if(pause_counter) begin
|
||||
assert(delay_counter != 0);
|
||||
// will fix this soon
|
||||
end
|
||||
|
||||
if(state_calibrate > ISSUE_WRITE_1 && state_calibrate <= ANALYZE_DATA) begin
|
||||
|
|
@ -3890,10 +3973,10 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
end
|
||||
|
||||
if(reset_done) begin
|
||||
assert(cmd_d[PRECHARGE_SLOT][CMD_CKE] && cmd_d[PRECHARGE_SLOT][CMD_RESET_N]); //cke and rst_n should stay high when reset sequence is already done
|
||||
assert(cmd_d[ACTIVATE_SLOT][CMD_CKE] && cmd_d[ACTIVATE_SLOT][CMD_RESET_N]); //cke and rst_n should stay high when reset sequence is already done
|
||||
assert(cmd_d[READ_SLOT][CMD_CKE] && cmd_d[READ_SLOT][CMD_RESET_N]); //cke and rst_n should stay high when reset sequence is already done
|
||||
assert(cmd_d[WRITE_SLOT][CMD_CKE] && cmd_d[WRITE_SLOT][CMD_RESET_N]); //cke and rst_n should stay high when reset sequence is already done
|
||||
assert(cmd_d[PRECHARGE_SLOT][CMD_RESET_N]); //cke and rst_n should stay high when reset sequence is already done
|
||||
assert(cmd_d[ACTIVATE_SLOT][CMD_RESET_N]); //cke and rst_n should stay high when reset sequence is already done
|
||||
assert(cmd_d[READ_SLOT][CMD_RESET_N]); //cke and rst_n should stay high when reset sequence is already done
|
||||
assert(cmd_d[WRITE_SLOT][CMD_RESET_N]); //cke and rst_n should stay high when reset sequence is already done
|
||||
end
|
||||
end
|
||||
if(state_calibrate == DONE_CALIBRATE) begin
|
||||
|
|
@ -3908,7 +3991,7 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
if(!f_empty) begin
|
||||
assert(state_calibrate == DONE_CALIBRATE);
|
||||
end
|
||||
if(train_delay == 0 && state_calibrate == FINISH_READ) begin//remove
|
||||
if(train_delay == 0 && state_calibrate == FINISH_READ) begin//fix this soon
|
||||
assume(f_sum_of_pending_acks == 0);
|
||||
end
|
||||
end
|
||||
|
|
@ -4053,6 +4136,12 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
end
|
||||
always @* begin
|
||||
assert(f_bank_status == bank_status_q);
|
||||
if(instruction_address >= 25) begin // after precharge until end of refresh, all banks are idle
|
||||
assert(bank_status_q == 0);
|
||||
end
|
||||
if(instruction_address == 23 && pause_counter) begin // if at PRE_REFRESH_DELAY and not yet done, then delay_counter should still be at original value
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
(*keep*) reg[31:0] bank;
|
||||
|
|
@ -4090,9 +4179,17 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
f_bank_status_2 = f_bank_status_2 | (1<<bank); //bank will be turned active
|
||||
f_bank_active_row[bank] <= cmd_d[ACTIVATE_SLOT][CMD_ADDRESS_START:0]; //save row to be activated
|
||||
end
|
||||
|
||||
if(instruction_address == 20 || instruction_address == 24) begin ///current instruction at precharge
|
||||
//all banks will be in idle after refresh
|
||||
for( index=0; index < (1<<BA_BITS); index=index+1) begin
|
||||
f_bank_status_2[index] <= 0;
|
||||
end
|
||||
end
|
||||
f_bank_status <= f_bank_status_2;
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
assign f_write_slot = WRITE_SLOT;
|
||||
|
|
@ -4143,7 +4240,7 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
end
|
||||
|
||||
always @* begin
|
||||
if(instruction_address != 22 && instruction_address != 19) begin
|
||||
if(instruction_address != 22 && instruction_address != 19 && instruction_address != 23) begin
|
||||
assert(!stage1_pending && !stage2_pending); //must be pending except in tREFI and in prestall delay
|
||||
end
|
||||
|
||||
|
|
@ -4344,7 +4441,7 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
end
|
||||
always @(posedge i_controller_clk) begin
|
||||
if(f_past_valid) begin
|
||||
if(instruction_address != 22 && instruction_address != 19 && $past(i_wb_cyc) && !past_sync_rst_controller) begin
|
||||
if(instruction_address != 22 && instruction_address != 19 && instruction_address != 23 && $past(i_wb_cyc) && !past_sync_rst_controller) begin
|
||||
assert(f_nreqs == $past(f_nreqs));
|
||||
end
|
||||
if(state_calibrate == DONE_CALIBRATE && $past(state_calibrate) != DONE_CALIBRATE && !past_sync_rst_controller) begin//just started DONE_CALBRATION
|
||||
|
|
@ -4518,12 +4615,12 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
// extra assertions to make sure engine starts properly
|
||||
always @* begin
|
||||
//if(!past_sync_rst_controller) begin
|
||||
assert(instruction_address <= 22);
|
||||
assert(instruction_address <= 26);
|
||||
assert(state_calibrate <= DONE_CALIBRATE);
|
||||
|
||||
if(!o_wb_stall) begin
|
||||
assert(state_calibrate == DONE_CALIBRATE);
|
||||
assert(instruction_address == 22 || (instruction_address == 19 && delay_counter == 0));
|
||||
assert(instruction_address == 22 || (instruction_address == 19 && delay_counter == 0) || (instruction_address == 23));
|
||||
end
|
||||
|
||||
if(instruction_address == 19 && delay_counter != 0 && state_calibrate == DONE_CALIBRATE) begin
|
||||
|
|
@ -4534,7 +4631,7 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
|
||||
if(stage1_pending || stage2_pending) begin
|
||||
assert(state_calibrate > ISSUE_WRITE_1);
|
||||
assert(instruction_address == 22 || instruction_address == 19);
|
||||
assert(instruction_address == 22 || instruction_address == 19 || instruction_address == 23);
|
||||
end
|
||||
|
||||
if(instruction_address < 13) begin
|
||||
|
|
@ -4576,7 +4673,7 @@ ALTERNATE_WRITE_READ: if(!o_wb_stall_calib) begin
|
|||
assert(o_wb_stall_calib);
|
||||
end
|
||||
if(reset_done) begin
|
||||
assert(instruction_address >= 19 && instruction_address <= 22);
|
||||
assert(instruction_address >= 19 && instruction_address <= 26);
|
||||
end
|
||||
//delay_counter is zero at first clock of new instruction address, the actual delay_clock wil start at next clock cycle
|
||||
if(instruction_address == 19 && delay_counter != 0) begin
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ module ddr3_top #(
|
|||
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)
|
||||
|
|
@ -108,11 +109,14 @@ module ddr3_top #(
|
|||
// Done Calibration pin
|
||||
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
|
||||
);
|
||||
|
||||
// Instantiation Template (DEFAULT VALUE IS FOR ARTY S7)
|
||||
|
|
@ -207,6 +211,30 @@ ddr3_top #(
|
|||
wire write_leveling_calib;
|
||||
wire reset;
|
||||
|
||||
// logic for self-refresh
|
||||
reg[8:0] refresh_counter = 0;
|
||||
reg user_self_refresh;
|
||||
// refresh counter
|
||||
always @(posedge i_controller_clk) begin
|
||||
if(i_wb_stb && i_wb_cyc) begin // if there is Wishbone request, then reset counter
|
||||
refresh_counter <= 0;
|
||||
end
|
||||
else if(!o_wb_stall || user_self_refresh) begin // if no request (but not stalled) OR already on self-refresh, then increment counter
|
||||
refresh_counter <= refresh_counter + 1;
|
||||
end
|
||||
end
|
||||
// choose self-refresh options
|
||||
always @* begin
|
||||
case(SELF_REFRESH)
|
||||
2'b00: user_self_refresh = i_user_self_refresh; // use input i_user_self_refresh (high = enter self-refresh, low = exit self-refresh)
|
||||
2'b01: user_self_refresh = refresh_counter[6]; // Self-refresh mode is enabled after 64 controller clock cycles of no requests, then exit Self-refresh after another 64 controller clk cycles
|
||||
2'b10: user_self_refresh = refresh_counter[7]; // Self-refresh mode is enabled after 128 controller clock cycles of no requests, then exit Self-refresh after another 128 controller clk cycles
|
||||
2'b11: user_self_refresh = refresh_counter[8]; // Self-refresh mode is enabled after 256 controller clock cycles of no requests, then exit Self-refresh after another 256 controller clk cycles
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
|
||||
//module instantiations
|
||||
ddr3_controller #(
|
||||
.CONTROLLER_CLK_PERIOD(CONTROLLER_CLK_PERIOD), //ps, clock period of the controller interface
|
||||
|
|
@ -281,9 +309,11 @@ ddr3_top #(
|
|||
// Done Calibration pin
|
||||
.o_calib_complete(o_calib_complete),
|
||||
// Debug outputs
|
||||
.o_debug1(o_debug1)
|
||||
.o_debug1(o_debug1),
|
||||
// .o_debug2(o_debug2),
|
||||
// .o_debug3(o_debug3)
|
||||
// User enabled self-refresh
|
||||
.i_user_self_refresh(user_self_refresh)
|
||||
);
|
||||
|
||||
ddr3_phy #(
|
||||
|
|
@ -341,6 +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*/)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ module ddr3_dimm_micron_sim;
|
|||
localparam CONTROLLER_CLK_PERIOD = 10_000, //ps, period of clock input to this DDR3 controller module
|
||||
DDR3_CLK_PERIOD = 2500, //ps, period of clock input to DDR3 RAM device
|
||||
AUX_WIDTH = 16, // AUX lines
|
||||
ECC_ENABLE = 0; // ECC enable
|
||||
ECC_ENABLE = 0, // ECC enable
|
||||
SELF_REFRESH = 2'b11;
|
||||
|
||||
reg i_controller_clk, i_ddr3_clk, i_ref_clk, i_ddr3_clk_90;
|
||||
reg i_rst_n;
|
||||
|
|
@ -107,7 +108,8 @@ module ddr3_dimm_micron_sim;
|
|||
wire o_wb2_stall; //1 = busy, cannot accept requests
|
||||
wire o_wb2_ack; //1 = read/write request has completed
|
||||
wire[$bits(ddr3_top.o_wb2_data)-1:0] o_wb2_data; //read data
|
||||
|
||||
// User enabled self-refresh
|
||||
reg i_user_self_refresh;
|
||||
wire clk_locked;
|
||||
|
||||
`ifdef USE_CLOCK_WIZARD
|
||||
|
|
@ -163,7 +165,9 @@ ddr3_top #(
|
|||
.ODELAY_SUPPORTED(ODELAY_SUPPORTED), //set to 1 if ODELAYE2 is supported
|
||||
.SECOND_WISHBONE(0), //set to 1 if 2nd wishbone for debugging is needed
|
||||
.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 )
|
||||
.WB_ERROR(1) // set to 1 to support Wishbone error (asserts at ECC double bit error)
|
||||
.WB_ERROR(1), // set to 1 to support Wishbone error (asserts at ECC double bit error)
|
||||
.SKIP_INTERNAL_TEST(0), // skip built-in self test (would require >2 seconds of internal test right after calibration)
|
||||
.SELF_REFRESH(SELF_REFRESH) // 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
|
||||
(
|
||||
//clock and reset
|
||||
|
|
@ -211,9 +215,9 @@ ddr3_top #(
|
|||
.io_ddr3_dq(dq),
|
||||
.io_ddr3_dqs(dqs),
|
||||
.io_ddr3_dqs_n(dqs_n),
|
||||
.o_ddr3_dm(ddr3_dm)
|
||||
|
||||
////////////////////////////////////
|
||||
.o_ddr3_dm(ddr3_dm),
|
||||
// User enabled self-refresh
|
||||
.i_user_self_refresh(i_user_self_refresh)
|
||||
);
|
||||
|
||||
|
||||
|
|
@ -318,6 +322,7 @@ ddr3_top #(
|
|||
integer average_1, average_2, average_3, average_4;
|
||||
localparam MAX_READS = (2**COL_BITS)*(2**BA_BITS + 1)/8; //1 row = 2**(COL_BITS) addresses/8 burst = 128 words per row. Times 8 to pass all 8 banks
|
||||
initial begin
|
||||
i_user_self_refresh = 0;
|
||||
//toggle reset for 1 slow clk
|
||||
@(posedge i_controller_clk) begin
|
||||
i_rst_n <= 0;
|
||||
|
|
@ -342,7 +347,11 @@ ddr3_top #(
|
|||
i_rst_n <= 1;
|
||||
end
|
||||
wait(ddr3_top.ddr3_controller_inst.state_calibrate == ddr3_top.ddr3_controller_inst.DONE_CALIBRATE);
|
||||
|
||||
|
||||
// test self refresh after calibration
|
||||
// test self refresh
|
||||
self_refresh();
|
||||
|
||||
// test 1 phase 1: Write random word sequentially
|
||||
// write to row 1
|
||||
number_of_op <= 0;
|
||||
|
|
@ -380,8 +389,8 @@ ddr3_top #(
|
|||
if (!o_wb_stall) i_wb_stb <= 1'b0;
|
||||
end
|
||||
end
|
||||
#1000_000; //rest here
|
||||
|
||||
// test self refresh
|
||||
self_refresh();
|
||||
|
||||
//Read sequentially
|
||||
address <= start_address;
|
||||
|
|
@ -407,7 +416,8 @@ ddr3_top #(
|
|||
if (!o_wb_stall) i_wb_stb <= 1'b0;
|
||||
end
|
||||
end
|
||||
#1000_000; //rest here
|
||||
// test self refresh
|
||||
self_refresh();
|
||||
|
||||
average_1 = ($time-time_started)/(number_of_op*1000);
|
||||
$display("\n--------------------------------\nDONE TEST 1: FIRST ROW\nNumber of Operations: %0d\nTime Started: %0d ns\nTime Done: %0d ns\nAverage Rate: %0d ns/request\n--------------------------------\n\n",
|
||||
|
|
@ -454,7 +464,8 @@ ddr3_top #(
|
|||
if (!o_wb_stall) i_wb_stb <= 1'b0;
|
||||
end
|
||||
end
|
||||
#1000_000; //rest here
|
||||
// test self refresh
|
||||
self_refresh();
|
||||
|
||||
// Read sequentially
|
||||
address <= start_address;
|
||||
|
|
@ -480,7 +491,8 @@ ddr3_top #(
|
|||
if (!o_wb_stall) i_wb_stb <= 1'b0;
|
||||
end
|
||||
end
|
||||
#1000_000; //rest here
|
||||
// test self refresh
|
||||
self_refresh();
|
||||
|
||||
average_2 = ($time-time_started)/(number_of_op*1000);
|
||||
$display("\n--------------------------------\nDONE TEST 1: MIDDLE ROW\nNumber of Operations: %0d\nTime Started: %0d ns\nTime Done: %0d ns\nAverage Rate: %0d ns/request\n--------------------------------\n\n",
|
||||
|
|
@ -524,7 +536,8 @@ ddr3_top #(
|
|||
if (!o_wb_stall) i_wb_stb <= 1'b0;
|
||||
end
|
||||
end
|
||||
#1000_000; //rest here
|
||||
// test self refresh
|
||||
self_refresh();
|
||||
|
||||
// Read sequentially
|
||||
address <= start_address;
|
||||
|
|
@ -556,15 +569,14 @@ ddr3_top #(
|
|||
// i_wb_stb <= 0;
|
||||
// end
|
||||
// end
|
||||
#1000_000; //rest here
|
||||
// test self refresh
|
||||
self_refresh();
|
||||
|
||||
average_3 = ($time-time_started)/(number_of_op*1000);
|
||||
$display("\n--------------------------------\nDONE TEST 1: LAST ROW\nNumber of Operations: %0d\nTime Started: %0d ns\nTime Done: %0d ns\nAverage Rate: %0d ns/request\n--------------------------------\n\n",
|
||||
number_of_op,time_started/1000, $time/1000, ($time-time_started)/(number_of_op*1000));
|
||||
//#100_000;
|
||||
|
||||
|
||||
|
||||
// Test 2:Random Access
|
||||
// write randomly
|
||||
address <= random_start; //this will just be used as the seed to generate a random number
|
||||
|
|
@ -600,7 +612,9 @@ ddr3_top #(
|
|||
if (!o_wb_stall) i_wb_stb <= 1'b0;
|
||||
end
|
||||
end
|
||||
#1000_000; //rest here
|
||||
|
||||
// test self refresh
|
||||
self_refresh();
|
||||
|
||||
// Read sequentially
|
||||
// Read the random words written at the random addresses
|
||||
|
|
@ -637,8 +651,10 @@ ddr3_top #(
|
|||
average_4 = ($time-time_started)/(number_of_op*1000);
|
||||
$display("\n--------------------------------\nDONE TEST 2: RANDOM\nNumber of Operations: %0d\nTime Started: %0d ns\nTime Done: %0d ns\nAverage Rate: %0d ns/request\n--------------------------------\n\n",
|
||||
number_of_op,time_started/1000, $time/1000, ($time-time_started)/(number_of_op*1000));
|
||||
|
||||
#100_000;
|
||||
|
||||
// test self refresh
|
||||
self_refresh();
|
||||
|
||||
// Test 3: Read from wishbone 2 (PHY)
|
||||
// Wishbone 2
|
||||
i_wb2_cyc <= 0; //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
|
|
@ -697,7 +713,11 @@ ddr3_top #(
|
|||
end
|
||||
end
|
||||
|
||||
#1000_000;
|
||||
#1000_000; //rest here
|
||||
// test self refresh
|
||||
self_refresh();
|
||||
#1000_000; // rest
|
||||
|
||||
$display("\n\n------- SUMMARY -------\nNumber of Writes = %0d\nNumber of Reads = %0d\nNumber of Success = %0d\nNumber of Fails = %0d\nNumber of Injected Errors = %0d\n",
|
||||
number_of_writes, number_of_reads,number_of_successful, number_of_failed, number_of_injected_errors);
|
||||
$display("\n\nTEST CALIBRATION\n[-]: write_test_address_counter = %0d", ddr3_top.ddr3_controller_inst.write_test_address_counter);
|
||||
|
|
@ -707,6 +727,20 @@ ddr3_top #(
|
|||
$stop;
|
||||
end
|
||||
|
||||
task self_refresh;
|
||||
if(SELF_REFRESH == 2'b00) begin
|
||||
// test self refresh
|
||||
@(posedge i_controller_clk)
|
||||
i_user_self_refresh = 1;
|
||||
#40_000_000; //40_000 ns of self-refresh
|
||||
@(posedge i_controller_clk)
|
||||
i_user_self_refresh = 0;
|
||||
end
|
||||
else begin
|
||||
#10_000_000; // 10_000 ns of rest
|
||||
end
|
||||
endtask
|
||||
|
||||
//check read data
|
||||
initial begin
|
||||
start_read_address = 0; //start at first row
|
||||
|
|
@ -986,4 +1020,3 @@ ddr3_top #(
|
|||
*/
|
||||
endmodule
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,15 +11,15 @@
|
|||
</db_ref>
|
||||
</db_ref_list>
|
||||
<zoom_setting>
|
||||
<ZoomStartTime time="749.583 ns"></ZoomStartTime>
|
||||
<ZoomEndTime time="6,229.584 ns"></ZoomEndTime>
|
||||
<Cursor1Time time="1,130.000 ns"></Cursor1Time>
|
||||
<ZoomStartTime time="0.000000 us"></ZoomStartTime>
|
||||
<ZoomEndTime time="55.000001 us"></ZoomEndTime>
|
||||
<Cursor1Time time="33.460000 us"></Cursor1Time>
|
||||
</zoom_setting>
|
||||
<column_width_setting>
|
||||
<NameColumnWidth column_width="272"></NameColumnWidth>
|
||||
<ValueColumnWidth column_width="129"></ValueColumnWidth>
|
||||
<ValueColumnWidth column_width="125"></ValueColumnWidth>
|
||||
</column_width_setting>
|
||||
<WVObjectSize size="47" />
|
||||
<WVObjectSize size="52" />
|
||||
<wvobject fp_name="divider869" type="divider">
|
||||
<obj_property name="label">Clocks and Reset</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
|
|
@ -45,16 +45,37 @@
|
|||
<obj_property name="ObjectShortName">i_ref_clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="divider869" type="divider">
|
||||
<obj_property name="label">Calibration</obj_property>
|
||||
<obj_property name="label">Self-refresh</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/\sideband_ECC_per_8_bursts.ecc_dec_inst /sb_err">
|
||||
<obj_property name="ElementShortName">sb_err</obj_property>
|
||||
<obj_property name="ObjectShortName">sb_err</obj_property>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/i_user_self_refresh">
|
||||
<obj_property name="ElementShortName">i_user_self_refresh</obj_property>
|
||||
<obj_property name="ObjectShortName">i_user_self_refresh</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/\sideband_ECC_per_8_bursts.ecc_dec_inst /db_err">
|
||||
<obj_property name="ElementShortName">db_err</obj_property>
|
||||
<obj_property name="ObjectShortName">db_err</obj_property>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/user_self_refresh_q">
|
||||
<obj_property name="ElementShortName">user_self_refresh_q</obj_property>
|
||||
<obj_property name="ObjectShortName">user_self_refresh_q</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/o_ddr3_cke">
|
||||
<obj_property name="ElementShortName">o_ddr3_cke</obj_property>
|
||||
<obj_property name="ObjectShortName">o_ddr3_cke</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_dimm_micron_sim/ddr3_top/refresh_counter">
|
||||
<obj_property name="ElementShortName">refresh_counter[8:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">refresh_counter[8:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/o_wb_stall">
|
||||
<obj_property name="ElementShortName">o_wb_stall</obj_property>
|
||||
<obj_property name="ObjectShortName">o_wb_stall</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/i_wb_stb">
|
||||
<obj_property name="ElementShortName">i_wb_stb</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_stb</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="divider869" type="divider">
|
||||
<obj_property name="label">Calibration</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/initial_calibration_done">
|
||||
<obj_property name="ElementShortName">initial_calibration_done</obj_property>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
Loading…
Reference in New Issue