📄 hssdrc_access_manager.v
字号:
pre_act_enable_srl [p] <= cPreActEnableInitValue;
else begin
if (arb_act && (arb_ba == p))
pre_act_enable_srl [p] <= cPreActEnableActValue;
else
pre_act_enable_srl [p] <= (pre_act_enable_srl [p] << 1) | 1'b1;
end
if (reset)
pre_rw_enable_srl [p] <= cPreRwEnableInitValue;
else if (sclr)
pre_rw_enable_srl [p] <= cPreRwEnableInitValue;
else begin
if (arb_write && (arb_ba == p))
pre_rw_enable_srl [p] <= PreRwEnableWriteValue (arb_burst) & ((pre_act_enable_srl [p] << 1) | 1'b1);
else if (arb_read && (arb_ba == p))
pre_rw_enable_srl [p] <= PreRwEnableReadValue (arb_burst) & ((pre_act_enable_srl [p] << 1) | 1'b1);
else
pre_rw_enable_srl [p] <= (pre_rw_enable_srl [p] << 1) | 1'b1;
end
end
assign pre_enable [p] = pre_rw_enable_srl [p] [cPreRwEnableLength-1] ;
end
endgenerate
//--------------------------------------------------------------------------------------------------
// pre_all_enable has same logic as pre enable.
// pre_all_enable == &(pre_enable), but for increase performance it have own control registers
//--------------------------------------------------------------------------------------------------
pre_act_enable_srl_t pre_all_act_enable_srl ;
pre_rw_enable_srl_t pre_all_rw_enable_srl ;
wire pre_all_enable;
always_ff @(posedge clk or posedge reset) begin : pre_all_enable_shift_register
if (reset)
pre_all_act_enable_srl <= cPreActEnableInitValue;
else if (sclr)
pre_all_act_enable_srl <= cPreActEnableInitValue;
else begin
if (arb_act)
pre_all_act_enable_srl <= cPreActEnableActValue;
else
pre_all_act_enable_srl <= (pre_all_act_enable_srl << 1) | 1'b1;
end
if (reset)
pre_all_rw_enable_srl <= cPreRwEnableInitValue;
else if (sclr)
pre_all_rw_enable_srl <= cPreRwEnableInitValue;
else begin
if (arb_write)
pre_all_rw_enable_srl <= PreRwEnableWriteValue (arb_burst) & ((pre_all_act_enable_srl << 1) | 1'b1);
else if (arb_read)
pre_all_rw_enable_srl <= PreRwEnableReadValue (arb_burst) & ((pre_all_act_enable_srl << 1) | 1'b1);
else
pre_all_rw_enable_srl <= (pre_all_rw_enable_srl << 1) | 1'b1;
end
end
assign pre_all_enable = pre_all_rw_enable_srl [cPreRwEnableLength-1];
//--------------------------------------------------------------------------------------------------
// tread 4/5/6 : Trfc (refr -> act) & Trc (act -> act) & Trrd (act a -> act b)
// Trc don't need to be contolled, becouse Trc = Tras + Trcd
// Trfc & Trrd control via one register becouse refr -> any act has locked & sequental access.
// for Trc we can use 1 register, becouse act a -> act a is imposible sequence
//--------------------------------------------------------------------------------------------------
localparam int cActEnableLength = max (cTrfc_m1, cTrrd_m1);
typedef logic [cActEnableLength-1:0] act_enable_srl_t;
// to act load patterns
localparam act_enable_srl_t cActEnableInitValue = {cActEnableLength{1'b1}};
localparam act_enable_srl_t cActEnableRefrValue = PercentRelation(cTrfc_m1, cActEnableLength);
localparam act_enable_srl_t cActEnableActValue = PercentRelation(cTrrd_m1, cActEnableLength);
act_enable_srl_t act_enable_srl ;
wire [0:3] act_enable ;
always_ff @(posedge clk or posedge reset) begin : act_enable_shift_register
if (reset)
act_enable_srl <= cActEnableInitValue;
else if (sclr)
act_enable_srl <= cActEnableInitValue;
else begin
if (arb_refr)
act_enable_srl <= cActEnableRefrValue;
else if (arb_act)
act_enable_srl <= cActEnableActValue;
else
act_enable_srl <= (act_enable_srl << 1) | 1'b1;
end
end
assign act_enable = {4{act_enable_srl [cActEnableLength-1]}} ;
//--------------------------------------------------------------------------------------------------
// tread 8/9 : Burst (write -> write) & Burst + CL + BTA (read -> write).
// control via one register becouse write/read -> write is atomic sequental access.
//--------------------------------------------------------------------------------------------------
localparam int cWriteEnableLength = max (cSdramBL_m1, cSdramBL_m1 + pCL + pBTA);
typedef logic [cWriteEnableLength-1:0] write_enable_srl_t;
// to write load patterns
localparam write_enable_srl_t cWriteEnableInitValue = {cWriteEnableLength{1'b1}};
// Remember : burst already has -1 offset (!!!!)
function automatic write_enable_srl_t WriteEnableWriteValue (input sdram_burst_t burst);
WriteEnableWriteValue = PercentRelation(burst, cWriteEnableLength);
endfunction
function automatic write_enable_srl_t WriteEnableReadValue (input sdram_burst_t burst);
WriteEnableReadValue = PercentRelation(burst + pCL + pBTA, cWriteEnableLength);
endfunction
write_enable_srl_t write_enable_srl;
wire [0:3] write_enable ;
always_ff @(posedge clk or posedge reset) begin : write_enable_shift_register
if (reset)
write_enable_srl <= cWriteEnableInitValue;
else if (sclr)
write_enable_srl <= cWriteEnableInitValue;
else begin
if (arb_write)
write_enable_srl <= WriteEnableWriteValue (arb_burst);
else if (arb_read)
write_enable_srl <= WriteEnableReadValue (arb_burst);
else
write_enable_srl <= (write_enable_srl << 1) | 1'b1;
end
end
assign write_enable = {4{write_enable_srl [cWriteEnableLength-1]}};
//--------------------------------------------------------------------------------------------------
// tread 11/12 : Burst + BTA (write -> read) & Burst (read -> read).
// contorl via one register becouse write/read -> read is atomic sequental access
// BTA from write -> read is not need !!! becouse read have read latency !!!!
//--------------------------------------------------------------------------------------------------
localparam int cReadEnableLength = max(cSdramBL_m1, cSdramBL_m1);
typedef logic [cReadEnableLength-1:0] read_enable_srl_t;
// to read load patterns
localparam read_enable_srl_t cReadEnableInitValue = {cReadEnableLength{1'b1}};
// Remember : burst already has -1 offset (!!!!)
function automatic read_enable_srl_t ReadEnableWriteValue (input sdram_burst_t burst);
ReadEnableWriteValue = PercentRelation(burst, cReadEnableLength);
endfunction
function automatic read_enable_srl_t ReadEnableReadValue (input sdram_burst_t burst);
ReadEnableReadValue = PercentRelation(burst, cReadEnableLength);
endfunction
read_enable_srl_t read_enable_srl;
wire [0:3] read_enable ;
always_ff @(posedge clk or posedge reset) begin : read_enable_shift_register
if (reset)
read_enable_srl <= cReadEnableInitValue;
else if (sclr)
read_enable_srl <= cReadEnableInitValue;
else begin
if (arb_write)
read_enable_srl <= ReadEnableWriteValue (arb_burst);
else if (arb_read)
read_enable_srl <= ReadEnableReadValue (arb_burst);
else
read_enable_srl <= (read_enable_srl << 1) | 1'b1;
end
end
assign read_enable = {4{read_enable_srl [cReadEnableLength-1]}};
//--------------------------------------------------------------------------------------------------
// tread 13/14 : Trp (pre_all -> refr) & Trfc (refr -> refr).
// contol via one register becouse pre_all/refr has locked access & (pre_all -> refr) has sequental access
//--------------------------------------------------------------------------------------------------
localparam int cRefrEnableLength = max (cTrp_m1, cTrfc_m1);
typedef logic [cRefrEnableLength-1:0] refr_enable_srl_t;
// to refr load patterns
localparam refr_enable_srl_t cRefrEnableInitValue = {cRefrEnableLength{1'b1}};
localparam refr_enable_srl_t cRefrEnablePreAllValue = PercentRelation( cTrp_m1, cRefrEnableLength);
localparam refr_enable_srl_t cRefrEnableRefrValue = PercentRelation(cTrfc_m1, cRefrEnableLength);
refr_enable_srl_t refr_enable_srl;
wire refr_enable;
always_ff @(posedge clk or posedge reset) begin : refr_enable_shift_register
if (reset)
refr_enable_srl <= cRefrEnableInitValue;
else if (sclr)
refr_enable_srl <= cRefrEnableInitValue;
else begin
if (arb_pre_all)
refr_enable_srl <= cRefrEnablePreAllValue;
else if (arb_refr)
refr_enable_srl <= cRefrEnableRefrValue;
else
refr_enable_srl <= (refr_enable_srl << 1) | 1'b1;
end
end
assign refr_enable = refr_enable_srl [cRefrEnableLength-1];
//--------------------------------------------------------------------------------------------------
// output mapping
//--------------------------------------------------------------------------------------------------
assign am_pre_all_enable = pre_all_enable;
assign am_refr_enable = refr_enable;
assign am_act_enable = act_enable;
assign am_pre_enable = pre_enable;
assign am_write_enable = write_enable;
assign am_read_enable = read_enable;
//--------------------------------------------------------------------------------------------------
// function to generate 'b{{{data}1'b0}, {{length-data}{1'b1}}} shift register load pattern
//--------------------------------------------------------------------------------------------------
function automatic int unsigned PercentRelation (input int unsigned data, length);
int unsigned value;
int i;
int ones_num;
value = 0;
ones_num = length - data; // number of ones from lsb in constant vector
for ( i = 0; i < length; i++) begin
if (i < ones_num) value[i] = 1'b1;
else value[i] = 1'b0;
end
return value;
endfunction
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -