714 lines
18 KiB
Systemverilog
714 lines
18 KiB
Systemverilog
// (C) 2001-2019 Intel Corporation. All rights reserved.
|
|
// Your use of Intel Corporation's design tools, logic functions and other
|
|
// software and tools, and its AMPP partner logic functions, and any output
|
|
// files from any of the foregoing (including device programming or simulation
|
|
// files), and any associated documentation or information are expressly subject
|
|
// to the terms and conditions of the Intel Program License Subscription
|
|
// Agreement, Intel FPGA IP License Agreement, or other applicable
|
|
// license agreement, including, without limitation, that your use is for the
|
|
// sole purpose of programming logic devices manufactured by Intel and sold by
|
|
// Intel or its authorized distributors. Please refer to the applicable
|
|
// agreement for further details.
|
|
|
|
|
|
|
|
|
|
`timescale 1 ps / 1 ps
|
|
|
|
module rw_manager_generic (
|
|
avl_clk,
|
|
avl_reset_n,
|
|
avl_address,
|
|
avl_write,
|
|
avl_writedata,
|
|
avl_read,
|
|
avl_readdata,
|
|
avl_waitrequest,
|
|
|
|
afi_clk,
|
|
afi_reset_n,
|
|
afi_wdata,
|
|
afi_dm,
|
|
afi_odt,
|
|
afi_rdata,
|
|
afi_rdata_valid,
|
|
afi_wrank,
|
|
afi_rrank,
|
|
|
|
ac_masked_bus,
|
|
ac_bus,
|
|
csr_clk,
|
|
csr_ena,
|
|
csr_dout_phy,
|
|
csr_dout
|
|
|
|
);
|
|
|
|
parameter AVL_DATA_WIDTH = "";
|
|
parameter AVL_ADDRESS_WIDTH = "";
|
|
|
|
parameter MEM_DQ_WIDTH = "";
|
|
parameter MEM_DM_WIDTH = "";
|
|
parameter MEM_ODT_WIDTH = "";
|
|
parameter MEM_NUMBER_OF_RANKS = "";
|
|
parameter MASK_WIDTH = "";
|
|
parameter AC_ODT_BIT = "";
|
|
parameter AC_BUS_WIDTH = "";
|
|
parameter AC_MASKED_BUS_WIDTH = "";
|
|
parameter AFI_RATIO = "";
|
|
|
|
parameter MEM_READ_DQS_WIDTH = "";
|
|
parameter MEM_WRITE_DQS_WIDTH = "";
|
|
|
|
parameter DEBUG_READ_DI_WIDTH = "";
|
|
parameter DEBUG_WRITE_TO_READ_RATIO_2_EXPONENT = "";
|
|
parameter DEBUG_WRITE_TO_READ_RATIO = "";
|
|
parameter MAX_DI_BUFFER_WORDS_LOG_2 = "";
|
|
|
|
parameter RATE = "";
|
|
parameter HCX_COMPAT_MODE = 0;
|
|
parameter DEVICE_FAMILY = "";
|
|
parameter AC_ROM_INIT_FILE_NAME = "";
|
|
parameter INST_ROM_INIT_FILE_NAME = "";
|
|
|
|
parameter USE_ALL_AFI_PHASES_FOR_COMMAND_ISSUE = 0;
|
|
|
|
parameter AP_MODE_EN = 2'b00;
|
|
|
|
parameter AVL_CLK_PS = 1000;
|
|
parameter AFI_CLK_PS = 1000;
|
|
|
|
parameter ENABLE_NON_DES_CAL = 0;
|
|
parameter TREFI = 36000;
|
|
parameter REFRESH_INTERVAL = 30000;
|
|
parameter TRFC = 370;
|
|
parameter REFRESH_RANKS_SIMUL = 1;
|
|
|
|
input avl_clk;
|
|
input avl_reset_n;
|
|
input [AVL_ADDRESS_WIDTH-1:0] avl_address;
|
|
input avl_write;
|
|
input [AVL_DATA_WIDTH-1:0] avl_writedata;
|
|
input avl_read;
|
|
output [AVL_DATA_WIDTH-1:0] avl_readdata;
|
|
output avl_waitrequest;
|
|
|
|
input afi_clk;
|
|
input afi_reset_n;
|
|
|
|
output [AC_MASKED_BUS_WIDTH - 1:0] ac_masked_bus;
|
|
output [AC_BUS_WIDTH - 1:0] ac_bus;
|
|
output [MEM_DQ_WIDTH * 2 * AFI_RATIO - 1:0] afi_wdata;
|
|
output [MEM_DM_WIDTH * 2 * AFI_RATIO - 1:0] afi_dm;
|
|
output [MEM_ODT_WIDTH * AFI_RATIO - 1:0] afi_odt;
|
|
output [MEM_WRITE_DQS_WIDTH * MEM_NUMBER_OF_RANKS * AFI_RATIO - 1:0] afi_wrank;
|
|
output [MEM_READ_DQS_WIDTH * MEM_NUMBER_OF_RANKS * AFI_RATIO - 1:0] afi_rrank;
|
|
|
|
input [MEM_DQ_WIDTH * 2 * AFI_RATIO - 1:0] afi_rdata;
|
|
input afi_rdata_valid;
|
|
|
|
input csr_clk;
|
|
input csr_ena;
|
|
input csr_dout_phy;
|
|
output csr_dout;
|
|
|
|
|
|
|
|
reg [AVL_DATA_WIDTH-1:0] avl_readdata;
|
|
reg avl_waitrequest;
|
|
|
|
wire avl_wr;
|
|
reg cmd_done_avl;
|
|
|
|
wire [AC_BUS_WIDTH - 1:0] ac_bus;
|
|
wire [AC_MASKED_BUS_WIDTH - 1:0] ac_masked_bus;
|
|
|
|
reg [AVL_DATA_WIDTH-1:0] avl_readdata_raw;
|
|
|
|
wire avl_rd;
|
|
wire cmd_read;
|
|
wire cmd_write;
|
|
reg avl_rd_r;
|
|
reg avl_wr_r;
|
|
|
|
|
|
typedef enum int unsigned {
|
|
STATE_RW_IDLE,
|
|
STATE_RW_EXEC,
|
|
STATE_RW_DONE,
|
|
STATE_RW_REFRESH,
|
|
STATE_RW_RESTORE
|
|
} STATE_RW_T;
|
|
|
|
STATE_RW_T state;
|
|
|
|
|
|
assign avl_rd = avl_read;
|
|
|
|
|
|
wire [7:0] jump_ptr_0_export;
|
|
wire [7:0] jump_ptr_1_export;
|
|
wire [7:0] jump_cntr_0_export;
|
|
wire [7:0] jump_cntr_1_export;
|
|
wire [7:0] cs_mask_export;
|
|
|
|
reg [7:0] jump_ptr_0_reg;
|
|
reg [7:0] jump_ptr_1_reg;
|
|
reg [7:0] jump_cntr_0_reg;
|
|
reg [7:0] jump_cntr_1_reg;
|
|
reg [7:0] cs_mask_reg;
|
|
|
|
reg req_avl_bus;
|
|
reg have_avl_bus;
|
|
wire all_refresh_done;
|
|
wire restore_done;
|
|
reg refresh_enabled;
|
|
reg refresh_took_too_long;
|
|
|
|
generate
|
|
if (ENABLE_NON_DES_CAL==1)
|
|
begin
|
|
wire decode_enable_refresh;
|
|
assign decode_enable_refresh = (avl_address [11:8] == 4'b1100);
|
|
|
|
always @(posedge avl_clk or negedge avl_reset_n)
|
|
begin
|
|
if (~avl_reset_n)
|
|
refresh_enabled <= 1'b0;
|
|
else if (avl_write & decode_enable_refresh)
|
|
begin
|
|
if (avl_writedata == {AVL_DATA_WIDTH{1'b0}})
|
|
refresh_enabled <= 1'b0;
|
|
else
|
|
refresh_enabled <= 1'b1;
|
|
end
|
|
end
|
|
|
|
|
|
assign avl_wr = avl_write & ~decode_enable_refresh;
|
|
assign avl_readdata = (decode_enable_refresh)? {'0, refresh_took_too_long}: avl_readdata_raw;
|
|
|
|
end
|
|
else
|
|
begin
|
|
assign req_avl_bus = 1'b0;
|
|
assign avl_wr = avl_write;
|
|
assign avl_readdata = avl_readdata_raw;
|
|
end
|
|
endgenerate
|
|
|
|
|
|
|
|
|
|
always_ff @(posedge avl_clk) begin
|
|
if (~avl_reset_n) begin
|
|
state <= STATE_RW_IDLE;
|
|
|
|
cs_mask_reg <= '0;
|
|
jump_ptr_0_reg <= '0;
|
|
jump_ptr_1_reg <= '0;
|
|
jump_cntr_0_reg <= '0;
|
|
jump_cntr_1_reg <= '0;
|
|
|
|
end else begin
|
|
case (state)
|
|
STATE_RW_IDLE:
|
|
begin
|
|
if (req_avl_bus) begin
|
|
state <= STATE_RW_REFRESH;
|
|
|
|
cs_mask_reg <= cs_mask_export;
|
|
jump_ptr_0_reg <= jump_ptr_0_export;
|
|
jump_ptr_1_reg <= jump_ptr_1_export;
|
|
jump_cntr_0_reg <= jump_cntr_0_export;
|
|
jump_cntr_1_reg <= jump_cntr_1_export;
|
|
|
|
|
|
|
|
end else
|
|
begin
|
|
if (avl_rd) begin
|
|
state <= STATE_RW_EXEC;
|
|
end
|
|
if (avl_wr) begin
|
|
state <= STATE_RW_EXEC;
|
|
end
|
|
end
|
|
end
|
|
STATE_RW_EXEC:
|
|
if (cmd_done_avl) begin
|
|
state <= STATE_RW_DONE;
|
|
end
|
|
STATE_RW_DONE:
|
|
begin
|
|
state <= STATE_RW_IDLE;
|
|
end
|
|
STATE_RW_REFRESH:
|
|
begin
|
|
if (all_refresh_done) begin
|
|
state <= STATE_RW_RESTORE;
|
|
end
|
|
end
|
|
STATE_RW_RESTORE:
|
|
begin
|
|
if (restore_done) begin
|
|
state <= STATE_RW_DONE;
|
|
end
|
|
end
|
|
|
|
endcase
|
|
end
|
|
end
|
|
|
|
|
|
reg [AVL_DATA_WIDTH - 1:0] avl_writedata_avl;
|
|
reg [AVL_ADDRESS_WIDTH - 1:0] avl_address_avl;
|
|
wire [AVL_DATA_WIDTH - 1:0] avl_readdata_afi;
|
|
wire cmd_done_afi;
|
|
|
|
reg [AVL_DATA_WIDTH - 1:0] avl_writedata_avl_refresh;
|
|
reg [AVL_ADDRESS_WIDTH - 1:0] avl_address_avl_refresh;
|
|
wire [AVL_DATA_WIDTH - 1:0] avl_writedata_avl_muxed;
|
|
wire [AVL_ADDRESS_WIDTH - 1:0] avl_address_avl_muxed;
|
|
|
|
wire cmd_read_muxed;
|
|
wire cmd_write_muxed;
|
|
|
|
|
|
|
|
generate
|
|
if (ENABLE_NON_DES_CAL==0)
|
|
begin
|
|
assign avl_writedata_avl_muxed = avl_writedata_avl;
|
|
assign avl_address_avl_muxed = avl_address_avl;
|
|
assign cmd_read_muxed = cmd_read;
|
|
assign cmd_write_muxed = cmd_write;
|
|
end
|
|
endgenerate
|
|
|
|
reg [AVL_DATA_WIDTH - 1:0] avl_readdata_g_avl;
|
|
|
|
always @(posedge avl_clk or negedge avl_reset_n)
|
|
begin
|
|
if (~avl_reset_n)
|
|
begin
|
|
avl_writedata_avl <= {AVL_DATA_WIDTH{1'b0}};
|
|
avl_address_avl <= {AVL_ADDRESS_WIDTH{1'b0}};
|
|
avl_readdata_g_avl <= {AVL_DATA_WIDTH{1'b0}};
|
|
cmd_done_avl <= 1'b0;
|
|
avl_rd_r <= 1'b0;
|
|
avl_wr_r <= 1'b0;
|
|
end
|
|
else begin
|
|
avl_writedata_avl <= avl_writedata;
|
|
avl_address_avl <= avl_address;
|
|
avl_readdata_g_avl <= avl_readdata_afi;
|
|
cmd_done_avl <= cmd_done_afi;
|
|
avl_rd_r <= avl_rd;
|
|
avl_wr_r <= avl_wr;
|
|
end
|
|
end
|
|
|
|
rw_manager_core rw_mgr_core_inst (
|
|
.avl_reset_n(avl_reset_n),
|
|
.avl_clk(avl_clk),
|
|
.afi_clk(afi_clk),
|
|
.avl_address(avl_address_avl_muxed),
|
|
.avl_readdata(avl_readdata_afi),
|
|
.avl_writedata(avl_writedata_avl_muxed),
|
|
.afi_reset_n(afi_reset_n),
|
|
.afi_wdata(afi_wdata),
|
|
.afi_dm(afi_dm),
|
|
.afi_odt(afi_odt),
|
|
.afi_rdata(afi_rdata),
|
|
.afi_rdata_valid(afi_rdata_valid),
|
|
.afi_wrank(afi_wrank),
|
|
.afi_rrank(afi_rrank),
|
|
.ac_bus(ac_bus),
|
|
.ac_masked_bus(ac_masked_bus),
|
|
.cmd_read(cmd_read_muxed),
|
|
.cmd_write(cmd_write_muxed),
|
|
.cmd_done(cmd_done_afi),
|
|
.csr_clk(csr_clk),
|
|
.csr_ena(csr_ena),
|
|
.csr_dout_phy(csr_dout_phy),
|
|
.csr_dout(csr_dout),
|
|
|
|
.cs_mask_export(cs_mask_export),
|
|
.jump_ptr_0_export(jump_ptr_0_export),
|
|
.jump_ptr_1_export(jump_ptr_1_export),
|
|
.jump_cntr_0_export(jump_cntr_0_export),
|
|
.jump_cntr_1_export(jump_cntr_1_export)
|
|
|
|
);
|
|
defparam rw_mgr_core_inst.AVL_DATA_WIDTH = AVL_DATA_WIDTH;
|
|
defparam rw_mgr_core_inst.AVL_ADDRESS_WIDTH = AVL_ADDRESS_WIDTH;
|
|
defparam rw_mgr_core_inst.MEM_DQ_WIDTH = MEM_DQ_WIDTH;
|
|
defparam rw_mgr_core_inst.MEM_DM_WIDTH = MEM_DM_WIDTH;
|
|
defparam rw_mgr_core_inst.MEM_ODT_WIDTH = MEM_ODT_WIDTH;
|
|
defparam rw_mgr_core_inst.MEM_NUMBER_OF_RANKS = MEM_NUMBER_OF_RANKS;
|
|
defparam rw_mgr_core_inst.MASK_WIDTH = MASK_WIDTH;
|
|
defparam rw_mgr_core_inst.AC_ODT_BIT = AC_ODT_BIT;
|
|
defparam rw_mgr_core_inst.AC_BUS_WIDTH = AC_BUS_WIDTH;
|
|
defparam rw_mgr_core_inst.AC_MASKED_BUS_WIDTH = AC_MASKED_BUS_WIDTH;
|
|
defparam rw_mgr_core_inst.AFI_RATIO = AFI_RATIO;
|
|
defparam rw_mgr_core_inst.MEM_READ_DQS_WIDTH = MEM_READ_DQS_WIDTH;
|
|
defparam rw_mgr_core_inst.MEM_WRITE_DQS_WIDTH = MEM_WRITE_DQS_WIDTH;
|
|
defparam rw_mgr_core_inst.DEBUG_READ_DI_WIDTH = DEBUG_READ_DI_WIDTH;
|
|
defparam rw_mgr_core_inst.DEBUG_WRITE_TO_READ_RATIO_2_EXPONENT = DEBUG_WRITE_TO_READ_RATIO_2_EXPONENT;
|
|
defparam rw_mgr_core_inst.DEBUG_WRITE_TO_READ_RATIO = DEBUG_WRITE_TO_READ_RATIO;
|
|
defparam rw_mgr_core_inst.RATE = RATE;
|
|
defparam rw_mgr_core_inst.HCX_COMPAT_MODE = HCX_COMPAT_MODE;
|
|
defparam rw_mgr_core_inst.DEVICE_FAMILY = DEVICE_FAMILY;
|
|
defparam rw_mgr_core_inst.AC_ROM_INIT_FILE_NAME = AC_ROM_INIT_FILE_NAME;
|
|
defparam rw_mgr_core_inst.INST_ROM_INIT_FILE_NAME = INST_ROM_INIT_FILE_NAME;
|
|
defparam rw_mgr_core_inst.MAX_DI_BUFFER_WORDS_LOG_2 = MAX_DI_BUFFER_WORDS_LOG_2;
|
|
defparam rw_mgr_core_inst.USE_ALL_AFI_PHASES_FOR_COMMAND_ISSUE = USE_ALL_AFI_PHASES_FOR_COMMAND_ISSUE;
|
|
defparam rw_mgr_core_inst.AP_MODE_EN = AP_MODE_EN;
|
|
|
|
assign cmd_read = avl_rd_r & ~cmd_done_avl & (state == STATE_RW_EXEC);
|
|
assign cmd_write = avl_wr_r & ~cmd_done_avl & (state == STATE_RW_EXEC);
|
|
|
|
|
|
always_comb
|
|
begin
|
|
if (((avl_wr || avl_rd) && (~cmd_done_avl || state != STATE_RW_EXEC)) || ~avl_reset_n || state == STATE_RW_REFRESH)
|
|
avl_waitrequest = 1;
|
|
else
|
|
avl_waitrequest = 0;
|
|
|
|
if (avl_rd)
|
|
avl_readdata_raw = avl_readdata_g_avl;
|
|
else
|
|
avl_readdata_raw = '0;
|
|
end
|
|
|
|
assert property (@(posedge avl_reset_n) AC_MASKED_BUS_WIDTH == MASK_WIDTH*AFI_RATIO)
|
|
$display("%t, [GENERIC ASSERT] AC_MASKED_BUS_WIDTH PARAMETER is correct", $time);
|
|
else
|
|
$error("%t, [GENERIC ASSERT] AC_MASKED_BUS_WIDTH PARAMETER is incorrect, AC_MASKED_BUS_WIDTH = %d, MASK_WIDTH*AFI_RATIO = %d", $time, AC_MASKED_BUS_WIDTH, MASK_WIDTH*AFI_RATIO);
|
|
|
|
assert property (@(posedge avl_clk) !avl_reset_n |-> !cmd_read);
|
|
assert property (@(posedge avl_clk) !avl_reset_n |-> avl_waitrequest);
|
|
|
|
|
|
generate
|
|
if (ENABLE_NON_DES_CAL==1)
|
|
begin
|
|
|
|
|
|
localparam MAX_REFI_COUNT= (REFRESH_INTERVAL*1000)/AVL_CLK_PS;
|
|
localparam REALLY_MAX_REFI_COUNT = (TREFI*1000)/AVL_CLK_PS;
|
|
localparam MAX_TRFC = (TRFC*1000)/AFI_CLK_PS;
|
|
localparam WAIT_TIME = 400000/AVL_CLK_PS;
|
|
reg [16:0] refi_counter;
|
|
|
|
reg [2:0] rank_counter;
|
|
wire refresh_done;
|
|
|
|
wire time_for_refresh;
|
|
assign time_for_refresh = (ENABLE_NON_DES_CAL==1) & (refi_counter == MAX_REFI_COUNT[16:0]);
|
|
|
|
typedef enum int unsigned {
|
|
STATE_RF_IDLE,
|
|
STATE_RF_SET_MASK,
|
|
STATE_RF_PRECHARGE,
|
|
STATE_RF_REFRESH_0,
|
|
STATE_RF_REFRESH_1,
|
|
STATE_RF_REFRESH_2,
|
|
STATE_RF_REFRESH_3,
|
|
STATE_RF_REFRESH_4,
|
|
|
|
STATE_RF_WAIT,
|
|
|
|
STATE_RF_ACTIVATE_0,
|
|
STATE_RF_ACTIVATE_1,
|
|
STATE_RF_ACTIVATE_2,
|
|
STATE_RF_ACTIVATE_3,
|
|
STATE_RF_ACTIVATE_4,
|
|
|
|
STATE_RF_RESTORE_0,
|
|
STATE_RF_RESTORE_1,
|
|
STATE_RF_RESTORE_2,
|
|
STATE_RF_RESTORE_3,
|
|
STATE_RF_RESTORE_4
|
|
|
|
|
|
} STATE_RF_T;
|
|
|
|
STATE_RF_T rf_state;
|
|
|
|
STATE_RF_T next_rf_state;
|
|
|
|
wire start_refresh;
|
|
wire issue_refresh_cmd;
|
|
wire go_next_refresh;
|
|
|
|
wire wait_done;
|
|
reg refresh_cmd;
|
|
reg refresh_wait;
|
|
|
|
|
|
|
|
assign issue_refresh_cmd = refresh_cmd;
|
|
assign go_next_refresh = (cmd_done_avl == 1'b0) && (refresh_wait == 1'b1);
|
|
|
|
always @(posedge avl_clk or negedge avl_reset_n)
|
|
begin
|
|
if (~avl_reset_n)
|
|
begin
|
|
rf_state <= STATE_RF_IDLE;
|
|
refi_counter <= '0;
|
|
refresh_cmd <= 1'b0;
|
|
refresh_wait <= 1'b0;
|
|
refresh_took_too_long <= 1'b0;
|
|
|
|
end
|
|
else
|
|
begin
|
|
|
|
if (refresh_enabled)
|
|
refi_counter <= (rf_state == STATE_RF_REFRESH_0 || rf_state == STATE_RF_REFRESH_4)? '0 : refi_counter + 1;
|
|
|
|
if (refi_counter > REALLY_MAX_REFI_COUNT [16:0])
|
|
refresh_took_too_long <= 1'b1;
|
|
|
|
if ( ((rf_state == STATE_RF_WAIT) & wait_done) |
|
|
((rf_state == STATE_RF_IDLE) & (start_refresh | state == STATE_RW_RESTORE)) |
|
|
(~refresh_wait & cmd_done_avl & (rf_state != STATE_RF_WAIT && rf_state != STATE_RF_IDLE )) )
|
|
begin
|
|
rf_state <= next_rf_state;
|
|
refresh_cmd <= 1'b0;
|
|
refresh_wait <= 1'b1;
|
|
end
|
|
else if (rf_state != STATE_RF_WAIT & rf_state != STATE_RF_IDLE)
|
|
begin
|
|
if (~cmd_done_avl)
|
|
refresh_wait <= 1'b0;
|
|
|
|
if (~refresh_wait)
|
|
refresh_cmd <= 1'b1;
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
reg [16:0] wait_cntr;
|
|
|
|
always @(posedge avl_clk or negedge avl_reset_n)
|
|
begin
|
|
if (~avl_reset_n)
|
|
wait_cntr <= '0;
|
|
else
|
|
begin
|
|
if (rf_state == STATE_RF_WAIT)
|
|
wait_cntr <= wait_cntr + 1;
|
|
else
|
|
wait_cntr <= 0;
|
|
end
|
|
end
|
|
|
|
assign wait_done = (wait_cntr == WAIT_TIME);
|
|
|
|
|
|
wire [AVL_DATA_WIDTH-1:0] rank_mask;
|
|
assign rank_mask = (REFRESH_RANKS_SIMUL == 1)? '0 : {'0, ~(7'h01 << rank_counter)};
|
|
|
|
always_comb
|
|
begin
|
|
case (rf_state)
|
|
STATE_RF_IDLE:
|
|
begin
|
|
avl_address_avl_refresh = '0;
|
|
avl_writedata_avl_refresh = '0;
|
|
next_rf_state = (state == STATE_RW_REFRESH & start_refresh)? STATE_RF_SET_MASK : (state == STATE_RW_RESTORE)? STATE_RF_RESTORE_0 : STATE_RF_IDLE;
|
|
end
|
|
STATE_RF_SET_MASK:
|
|
begin
|
|
avl_address_avl_refresh = {20'h00000 ,4'b0101, 8'h00};
|
|
avl_writedata_avl_refresh = rank_mask;
|
|
next_rf_state = STATE_RF_PRECHARGE;
|
|
end
|
|
STATE_RF_PRECHARGE:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0000;
|
|
avl_writedata_avl_refresh = 32'h12;
|
|
next_rf_state = STATE_RF_REFRESH_0;
|
|
end
|
|
STATE_RF_REFRESH_0:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0300;
|
|
avl_writedata_avl_refresh = 32'h14;
|
|
next_rf_state = STATE_RF_REFRESH_1;
|
|
end
|
|
STATE_RF_REFRESH_1:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0301;
|
|
avl_writedata_avl_refresh = 32'h0015;
|
|
next_rf_state = STATE_RF_REFRESH_2;
|
|
end
|
|
STATE_RF_REFRESH_2:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0200;
|
|
avl_writedata_avl_refresh = 32'h0007;
|
|
next_rf_state = STATE_RF_REFRESH_3;
|
|
end
|
|
STATE_RF_REFRESH_3:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0201;
|
|
avl_writedata_avl_refresh = MAX_TRFC;
|
|
next_rf_state = STATE_RF_REFRESH_4;
|
|
end
|
|
STATE_RF_REFRESH_4:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0000;
|
|
avl_writedata_avl_refresh = 32'h14;
|
|
next_rf_state = STATE_RF_WAIT;
|
|
end
|
|
STATE_RF_WAIT:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0000;
|
|
avl_writedata_avl_refresh = 32'd0;
|
|
next_rf_state = STATE_RF_ACTIVATE_0;
|
|
end
|
|
STATE_RF_ACTIVATE_0:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0200;
|
|
avl_writedata_avl_refresh = 32'h00;
|
|
next_rf_state = STATE_RF_ACTIVATE_1;
|
|
end
|
|
STATE_RF_ACTIVATE_1:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0201;
|
|
avl_writedata_avl_refresh = 32'h0F;
|
|
next_rf_state = STATE_RF_ACTIVATE_2;
|
|
end
|
|
STATE_RF_ACTIVATE_2:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0300;
|
|
avl_writedata_avl_refresh = 32'h0E;
|
|
next_rf_state = STATE_RF_ACTIVATE_3;
|
|
end
|
|
STATE_RF_ACTIVATE_3:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0301;
|
|
avl_writedata_avl_refresh = 32'h10;
|
|
next_rf_state = STATE_RF_ACTIVATE_4;
|
|
end
|
|
STATE_RF_ACTIVATE_4:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0000;
|
|
avl_writedata_avl_refresh = 32'h0D;
|
|
next_rf_state = STATE_RF_IDLE;
|
|
end
|
|
STATE_RF_RESTORE_0:
|
|
begin
|
|
avl_address_avl_refresh = {20'h00000 ,4'b0101, 8'h00};
|
|
avl_writedata_avl_refresh = cs_mask_reg;
|
|
next_rf_state = STATE_RF_RESTORE_1;
|
|
end
|
|
STATE_RF_RESTORE_1:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0200;
|
|
avl_writedata_avl_refresh = jump_cntr_0_reg;
|
|
next_rf_state = STATE_RF_RESTORE_2;
|
|
end
|
|
STATE_RF_RESTORE_2:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0201;
|
|
avl_writedata_avl_refresh = jump_cntr_1_reg;
|
|
next_rf_state = STATE_RF_RESTORE_3;
|
|
end
|
|
STATE_RF_RESTORE_3:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0300;
|
|
avl_writedata_avl_refresh = jump_ptr_0_reg;
|
|
next_rf_state = STATE_RF_RESTORE_4;
|
|
end
|
|
STATE_RF_RESTORE_4:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0301;
|
|
avl_writedata_avl_refresh = jump_ptr_1_reg;
|
|
next_rf_state = STATE_RF_IDLE;
|
|
end
|
|
default:
|
|
begin
|
|
avl_address_avl_refresh = 32'h0000;
|
|
avl_writedata_avl_refresh = 32'd0;
|
|
next_rf_state = STATE_RF_IDLE;
|
|
|
|
end
|
|
endcase
|
|
end
|
|
|
|
assign refresh_done = (rf_state == STATE_RF_ACTIVATE_3);
|
|
assign restore_done = (rf_state == STATE_RF_RESTORE_4) & cmd_done_avl & ~refresh_wait;
|
|
|
|
|
|
always @(posedge avl_clk or negedge avl_reset_n)
|
|
begin
|
|
if (~avl_reset_n)
|
|
rank_counter <= '0;
|
|
else
|
|
begin
|
|
if (all_refresh_done | (REFRESH_RANKS_SIMUL == 1))
|
|
rank_counter <= '0;
|
|
else if (refresh_done & go_next_refresh)
|
|
rank_counter <= rank_counter + 1;
|
|
end
|
|
end
|
|
|
|
|
|
assign all_refresh_done = ((rank_counter == MEM_NUMBER_OF_RANKS[2:0]) | (REFRESH_RANKS_SIMUL == 1)) & refresh_done;
|
|
|
|
|
|
|
|
reg [7:0] idle_wait;
|
|
localparam IDLE_WAIT_CNT= 32;
|
|
assign start_refresh = (idle_wait == IDLE_WAIT_CNT[7:0]) & have_avl_bus;
|
|
|
|
|
|
assign avl_writedata_avl_muxed = (have_avl_bus)? avl_writedata_avl_refresh : avl_writedata_avl;
|
|
assign avl_address_avl_muxed = (have_avl_bus)? avl_address_avl_refresh : avl_address_avl;
|
|
assign cmd_read_muxed = (have_avl_bus)? 1'b0 : cmd_read;
|
|
assign cmd_write_muxed = (have_avl_bus)? issue_refresh_cmd : cmd_write;
|
|
|
|
|
|
always @(posedge avl_clk or negedge avl_reset_n)
|
|
begin
|
|
if (~avl_reset_n)
|
|
begin
|
|
idle_wait <= '0;
|
|
req_avl_bus <= 1'b0;
|
|
have_avl_bus <= 1'b0;
|
|
end
|
|
else
|
|
begin
|
|
if (time_for_refresh)
|
|
req_avl_bus <= 1'b1;
|
|
else if (have_avl_bus)
|
|
req_avl_bus <= 1'b0;
|
|
|
|
if (req_avl_bus & state == STATE_RW_REFRESH)
|
|
have_avl_bus <= 1'b1;
|
|
else if (restore_done )
|
|
have_avl_bus <= 1'b0;
|
|
|
|
if (have_avl_bus & rf_state == STATE_RF_IDLE)
|
|
idle_wait <= idle_wait +1;
|
|
else
|
|
idle_wait <= '0;
|
|
|
|
end
|
|
end
|
|
end
|
|
endgenerate
|
|
|
|
endmodule
|