ct_lsu_pfu_pmb_entry
module ct_lsu_pfu_pmb_entry( amr_wa_cancel, cp0_lsu_icg_en, cp0_lsu_l2_st_pref_en, cp0_yy_clk_en, cpurst_b, ld_da_ldfifo_pc, ld_da_pfu_act_dp_vld, ld_da_pfu_evict_cnt_vld, ld_da_pfu_pf_inst_vld, lsu_special_clk, pad_yy_icg_scan_en, pfu_pmb_entry_create_dp_vld_x, pfu_pmb_entry_create_gateclk_en_x, pfu_pmb_entry_create_vld_x, pfu_pmb_entry_evict_x, pfu_pmb_entry_hit_pc_x, pfu_pmb_entry_pc_v, pfu_pmb_entry_ready_grnt_x, pfu_pmb_entry_ready_x, pfu_pmb_entry_type_ld_x, pfu_pmb_entry_vld_x, pfu_pop_all_part_vld, pipe_create_pc, pmb_timeout_cnt_val, st_da_pc, st_da_pfu_evict_cnt_vld, st_da_pfu_pf_inst_vld );
-
输入端口:
- 控制信号: 包括
amr_wa_cancel 、cp0_lsu_icg_en 、cp0_lsu_l2_st_pref_en 、cp0_yy_clk_en 、cpurst_b 和pad_yy_icg_scan_en 。它们可能用于各种控制功能,如时钟门控、复位和扫描测试。 - 加载和存储数据: 如
ld_da_ldfifo_pc 、ld_da_pfu_act_dp_vld 、ld_da_pfu_evict_cnt_vld 、ld_da_pfu_pf_inst_vld 、st_da_pc 、st_da_pfu_evict_cnt_vld 和st_da_pfu_pf_inst_vld 等输入可能与加载和存储操作的数据和控制路径相关,包括预取指令和逐出计数。 - 预取和PMB管理: 如
pfu_pop_all_part_vld 、pipe_create_pc 和pmb_timeout_cnt_val 等输入表明该模块参与处理预取请求和管理PMB条目,包括它们的创建、逐出和超时条件。
- 控制信号: 包括
-
输出端口:
- PMB条目控制: 诸如
pfu_pmb_entry_create_dp_vld_x 、pfu_pmb_entry_create_gateclk_en_x 、pfu_pmb_entry_create_vld_x 、pfu_pmb_entry_evict_x 、pfu_pmb_entry_hit_pc_x 、pfu_pmb_entry_pc_v 、pfu_pmb_entry_ready_grnt_x 、pfu_pmb_entry_ready_x 、pfu_pmb_entry_type_ld_x 和pfu_pmb_entry_vld_x 等输出负责管理PMB条目。这包括条目的创建、验证、逐出和就绪,以及确定条目是否为加载类型的预取。
- PMB条目控制: 诸如
-
特殊时钟:
lsu_special_clk : 这可能是LSU或PFU的专用时钟,表明该单元具有特殊的时序要求。
-
功能:
- 该模块似乎管理着预取请求在PMB中的生命周期。这包括确定何时创建新条目,何时条目有效或就绪,以及何时逐出条目。
- 它还似乎处理特殊条件,如预取请求取消、PMB条目命中,以及管理特定于加载操作的条目。
- 各种时钟相关控制的存在表明,该模块旨在考虑到功耗效率,可能使用时钟门控等技术。
parameter TIMEOUT_BW = 8; parameter PC_LEN = 15; //========================================================== // Instance of Gated Cell //========================================================== assign pfu_pmb_entry_clk_en = pfu_pmb_entry_vld || pfu_pmb_entry_create_gateclk_en; // &Instance("gated_clk_cell", "x_lsu_pfu_pmb_entry_gated_clk"); @39 gated_clk_cell x_lsu_pfu_pmb_entry_gated_clk ( .clk_in (lsu_special_clk ), .clk_out (pfu_pmb_entry_clk ), .external_en (1'b0 ), .global_en (cp0_yy_clk_en ), .local_en (pfu_pmb_entry_clk_en), .module_en (cp0_lsu_icg_en ), .pad_yy_icg_scan_en (pad_yy_icg_scan_en ) ); // &Connect(.clk_in (lsu_special_clk ), @40 // .external_en (1'b0 ), @41 // .global_en (cp0_yy_clk_en ), @42 // .module_en (cp0_lsu_icg_en ), @43 // .local_en (pfu_pmb_entry_clk_en), @44 // .clk_out (pfu_pmb_entry_clk )); @45 assign pfu_pmb_entry_create_clk_en = pfu_pmb_entry_create_gateclk_en; // &Instance("gated_clk_cell", "x_lsu_pfu_pmb_entry_create_gated_clk"); @48 gated_clk_cell x_lsu_pfu_pmb_entry_create_gated_clk ( .clk_in (lsu_special_clk ), .clk_out (pfu_pmb_entry_create_clk ), .external_en (1'b0 ), .global_en (cp0_yy_clk_en ), .local_en (pfu_pmb_entry_create_clk_en), .module_en (cp0_lsu_icg_en ), .pad_yy_icg_scan_en (pad_yy_icg_scan_en ) );
-
参数定义(Parameter Definition):
TIMEOUT_BW 和PC_LEN 是定义的参数,分别表示超时带宽和程序计数器长度。
-
时钟使能逻辑(Clock Enable Logic):
pfu_pmb_entry_clk_en :这是一个用于控制PMB条目时钟门控的使能信号。当pfu_pmb_entry_vld (PMB条目有效)或pfu_pmb_entry_create_gateclk_en (创建PMB条目的时钟门控使能)其中任一为真时,该信号被置为真。pfu_pmb_entry_create_clk_en :这是一个专门用于控制创建PMB条目的时钟门控的使能信号。
-
时钟门控单元实例化(Gated Clock Cell Instantiation):
- 时钟门控单元
gated_clk_cell 被实例化两次,分别用于PMB条目的一般时钟(x_lsu_pfu_pmb_entry_gated_clk )和创建时钟(x_lsu_pfu_pmb_entry_create_gated_clk )。 - 对于每个实例,输入时钟(
lsu_special_clk )、全局使能(cp0_yy_clk_en )、模块使能(cp0_lsu_icg_en )和扫描使能(pad_yy_icg_scan_en )都被连接。 - 每个时钟门控单元还有一个本地使能信号(
local_en ),分别为pfu_pmb_entry_clk_en 和pfu_pmb_entry_create_clk_en ,用于控制对应的时钟输出(clk_out )。
- 时钟门控单元
-
功能和重要性:
- 这些时钟门控逻辑有助于降低整个预取单元的功耗,通过仅在需要时使能时钟。
- 这种时钟门控策略特别适用于性能敏感且功耗受限的设计,如高性能处理器的LSU部分。
//========================================================== // Register //========================================================== //+-----------+ //| entry_vld | //+-----------+ always @(posedge pfu_pmb_entry_clk or negedge cpurst_b) begin if (!cpurst_b) pfu_pmb_entry_vld <= 1'b0; else if(pfu_pmb_entry_pop_vld) pfu_pmb_entry_vld <= 1'b0; else if(pfu_pmb_entry_create_vld) pfu_pmb_entry_vld <= 1'b1; end //+----+ //| pc | //+----+ always @(posedge pfu_pmb_entry_create_clk or negedge cpurst_b) begin if (!cpurst_b) pfu_pmb_entry_pc[PC_LEN-1:0] <= {PC_LEN{1'b0}}; else if(pfu_pmb_entry_create_dp_vld) pfu_pmb_entry_pc[PC_LEN-1:0] <= pipe_create_pc[PC_LEN-1:0]; end //+----+------+ //| pref_type | //+----+------+ always @(posedge pfu_pmb_entry_create_clk or negedge cpurst_b) begin if (!cpurst_b) pfu_pmb_entry_type_ld <= 1'b0; else if(pfu_pmb_entry_create_dp_vld) pfu_pmb_entry_type_ld <= ld_da_pfu_act_dp_vld; end //+-----+ //| cnt | //+-----+ always @(posedge pfu_pmb_entry_all_pf_inst_clk or negedge cpurst_b) begin if (!cpurst_b) pfu_pmb_entry_cnt <= 1'b0; else if(pfu_pmb_entry_create_dp_vld) pfu_pmb_entry_cnt <= 1'b0; else if(!pfu_pmb_entry_cnt && pfu_pmb_entry_hit_pc) pfu_pmb_entry_cnt <= ~pfu_pmb_entry_cnt; end //+-------------+ //| timeout_cnt | //+-------------+ always @(posedge pfu_pmb_entry_all_pf_inst_clk or negedge cpurst_b) begin if (!cpurst_b) pfu_pmb_entry_timeout_cnt[TIMEOUT_BW-1:0] <= {TIMEOUT_BW{1'b0}}; else if(pfu_pmb_entry_create_dp_vld || pfu_pmb_entry_hit_pc) pfu_pmb_entry_timeout_cnt[TIMEOUT_BW-1:0] <= {TIMEOUT_BW{1'b0}}; else if(pipe_evict_cnt_vld && !pfu_pmb_entry_timeout_cnt_full) pfu_pmb_entry_timeout_cnt[TIMEOUT_BW-1:0] <= pfu_pmb_entry_timeout_cnt[TIMEOUT_BW-1:0] + {{TIMEOUT_BW-1{1'b0}},1'b1}; end //+-------+ //| ready | //+-------+ always @(posedge pfu_pmb_entry_clk or negedge cpurst_b) begin if (!cpurst_b) pfu_pmb_entry_ready <= 1'b0; else if(pfu_pmb_entry_create_dp_vld || pfu_pmb_entry_pop_vld) pfu_pmb_entry_ready <= 1'b0; else if(pfu_pmb_entry_cnt && pfu_pmb_entry_hit_pc) pfu_pmb_entry_ready <= 1'b1; end //+-------+ //| evict | //+-------+ always @(posedge pfu_pmb_entry_clk or negedge cpurst_b) begin if (!cpurst_b) pfu_pmb_entry_evict <= 1'b0; else if(pfu_pmb_entry_create_dp_vld || pfu_pmb_entry_pop_vld || pfu_sdb_entry_evict_clr) pfu_pmb_entry_evict <= 1'b0; else if(pfu_sdb_entry_evict_set) pfu_pmb_entry_evict <= 1'b1; end
预取单元(PFU)的预取缺失缓冲区(PMB)条目的寄存器定义和逻辑。包含多个始终块(always blocks),用于在不同条件下更新各种寄存器。让
-
entry_vld(条目有效)寄存器:
- 这个寄存器表示PMB条目是否有效。它在
pfu_pmb_entry_clk 的正边沿或cpurst_b 的负边沿上更新。 - 如果系统重置(
cpurst_b 为0),则将其清零。 - 如果条目被弹出(
pfu_pmb_entry_pop_vld 为真),则将其清零。 - 如果创建了新条目(
pfu_pmb_entry_create_vld 为真),则将其置为1。
- 这个寄存器表示PMB条目是否有效。它在
-
pc(程序计数器)寄存器:
- 这个寄存器存储与PMB条目相关的程序计数器值。它在
pfu_pmb_entry_create_clk 的正边沿或cpurst_b 的负边沿上更新。 - 系统重置时,该寄存器被清零。
- 如果有新的数据有效(
pfu_pmb_entry_create_dp_vld 为真),则更新为pipe_create_pc 的值。
- 这个寄存器存储与PMB条目相关的程序计数器值。它在
-
pref_type(预取类型)寄存器:
- 这个寄存器表明PMB条目的类型是否为加载(load)。它在
pfu_pmb_entry_create_clk 的正边沿或cpurst_b 的负边沿上更新。 - 系统重置时,该寄存器被清零。
- 如果有新的数据有效,根据
ld_da_pfu_act_dp_vld 的值进行更新。
- 这个寄存器表明PMB条目的类型是否为加载(load)。它在
-
cnt(计数)寄存器:
- 这个寄存器用于跟踪某些事件的发生次数。它在
pfu_pmb_entry_all_pf_inst_clk 的正边沿或cpurst_b 的负边沿上更新。 - 在重置或新数据有效时清零。
- 如果
pfu_pmb_entry_hit_pc 为真且cnt 为假,则取反cnt 的值。
- 这个寄存器用于跟踪某些事件的发生次数。它在
-
timeout_cnt(超时计数)寄存器:
- 用于跟踪PMB条目的超时状态。它在
pfu_pmb_entry_all_pf_inst_clk 的正边沿或cpurst_b 的负边沿上更新。 - 在重置、新数据有效或命中时清零。
- 如果
pipe_evict_cnt_vld 为真且pfu_pmb_entry_timeout_cnt_full 为假,则增加计数器。
- 用于跟踪PMB条目的超时状态。它在
-
ready(就绪)寄存器:
- 表示PMB条目是否准备好进行某些操作。它在
pfu_pmb_entry_clk 的正边沿或cpurst_b 的负边沿上更新。 - 在重置、新数据有效或条目被弹出时清零。
- 如果
cnt 和pfu_pmb_entry_hit_pc 都为真,则将其置为1。
- 表示PMB条目是否准备好进行某些操作。它在
-
evict(逐出)寄存器:
- 表示PMB条目是否应该被逐出。它在
pfu_pmb_entry_clk 的正边沿或cpurst_b 的负边沿上更新。 - 在重置、新数据有效、条目被弹出或逐出清除时清零。
- 如果设置逐出标志,则将其置为1。
- 表示PMB条目是否应该被逐出。它在
//========================================================== // pipe info select //========================================================== assign pipe_cmp_inst_vld = pfu_pmb_entry_type_ld ? ld_da_pfu_pf_inst_vld : st_da_pfu_pf_inst_vld; assign pipe_cmp_pc[PC_LEN-1:0] = pfu_pmb_entry_type_ld ? ld_da_ldfifo_pc[PC_LEN-1:0] : st_da_pc[PC_LEN-1:0]; assign pipe_evict_cnt_vld = ld_da_pfu_evict_cnt_vld || st_da_pfu_evict_cnt_vld; //========================================================== // Caucalate hit pc signal //========================================================== assign entry_hit_pc = pfu_pmb_entry_vld && (pipe_cmp_pc[PC_LEN-1:0] == pfu_pmb_entry_pc[PC_LEN-1:0]); //for maintance assign pfu_pmb_entry_hit_pc = entry_hit_pc && pipe_cmp_inst_vld; //for new inst create assign pfu_pmb_entry_hit_pc_for_new = entry_hit_pc && !(pfu_pmb_entry_type_ld ^ ld_da_pfu_act_dp_vld); //========================================================== // Set/clr evict //========================================================== assign pfu_pmb_entry_timeout_cnt_full = (pfu_pmb_entry_timeout_cnt[TIMEOUT_BW-1:0] == pmb_timeout_cnt_val[TIMEOUT_BW-1:0]); //if assign pfu_sdb_entry_evict_set = pfu_pmb_entry_vld && !pfu_pmb_entry_ready && pipe_cmp_inst_vld && pfu_pmb_entry_timeout_cnt_full && !pfu_pmb_entry_hit_pc; assign pfu_sdb_entry_evict_clr = pfu_pmb_entry_hit_pc; //========================================================== // Generate pop signal //========================================================== //st pref pop assign pfu_pop_st_all = pfu_pmb_entry_vld && !pfu_pmb_entry_type_ld && (!cp0_lsu_l2_st_pref_en || amr_wa_cancel); //for timing //when create_vld != create_dp,and the entry is at evict state //pop entry preventing data path from being changed incorrectly assign pfu_pmb_entry_evict_pop = pfu_pmb_entry_vld && pfu_pmb_entry_evict && pfu_pmb_entry_create_dp_vld && !pfu_pmb_entry_create_vld; assign pfu_pmb_entry_pop_vld = pfu_pmb_entry_ready_grnt || pfu_pmb_entry_evict_pop || pfu_pop_st_all || pfu_pop_all_part_vld;
预取缺失缓冲区(PMB)条目的逻辑,主要用于处理与预取相关的不同信号。
-
管线信息选择(Pipe Info Select):
pipe_cmp_inst_vld (管线比较指令有效):根据pfu_pmb_entry_type_ld (PMB条目类型)来选择是加载指令有效还是存储指令有效。pipe_cmp_pc (管线比较程序计数器):同样根据PMB条目类型选择相应的程序计数器值,用于加载或存储。
-
计算命中程序计数器信号(Calculate Hit PC Signal):
entry_hit_pc :如果PMB条目有效且管线比较的程序计数器与PMB条目的程序计数器相等,则此信号为真。pfu_pmb_entry_hit_pc :在entry_hit_pc 的基础上,还需要管线比较指令有效。pfu_pmb_entry_hit_pc_for_new :用于新指令创建时的命中检测。
-
设置/清除逐出(Set/Clear Evict):
pfu_pmb_entry_timeout_cnt_full :当PMB条目的超时计数器满时,此信号为真。pfu_sdb_entry_evict_set :如果PMB条目有效、未准备好、管线指令有效、超时计数器满,且未命中程序计数器,则设置逐出。pfu_sdb_entry_evict_clr :如果命中程序计数器,则清除逐出。
-
生成弹出信号(Generate Pop Signal):
pfu_pop_st_all :用于存储预取弹出。pfu_pmb_entry_evict_pop :当存在时序问题时(如创建有效不等于创建数据路径有效,且条目处于逐出状态),弹出条目以防止数据路径被错误改变。pfu_pmb_entry_pop_vld :结合多个条件生成最终的PMB条目弹出有效信号。
//========================================================== // Generate interface //========================================================== //------------------input----------------------------------- //-----------create signal-------------- assign pfu_pmb_entry_create_vld = pfu_pmb_entry_create_vld_x; assign pfu_pmb_entry_create_dp_vld = pfu_pmb_entry_create_dp_vld_x; assign pfu_pmb_entry_create_gateclk_en = pfu_pmb_entry_create_gateclk_en_x; //---------grnt/done signal------------- assign pfu_pmb_entry_ready_grnt = pfu_pmb_entry_ready_grnt_x; //------------------output---------------------------------- //-----------entry signal--------------- assign pfu_pmb_entry_vld_x = pfu_pmb_entry_vld; assign pfu_pmb_entry_pc_v[PC_LEN-1:0] = pfu_pmb_entry_pc[PC_LEN-1:0]; assign pfu_pmb_entry_ready_x = pfu_pmb_entry_ready; assign pfu_pmb_entry_evict_x = pfu_pmb_entry_evict; assign pfu_pmb_entry_type_ld_x = pfu_pmb_entry_type_ld; //-----------hit signal----------------- assign pfu_pmb_entry_hit_pc_x = pfu_pmb_entry_hit_pc_for_new;
预取缺失缓冲区(PMB)条目管理模块的接口生成部分。它主要负责将模块内部信号与外部或其他模块间的信号进行连接。代码分为两个主要部分:输入(input)和输出(output)。
-
输入信号(Input Signals):
pfu_pmb_entry_create_vld :表示创建PMB条目的有效性信号。pfu_pmb_entry_create_dp_vld :表示创建PMB条目的数据路径有效性信号。pfu_pmb_entry_create_gateclk_en :表示创建PMB条目时的时钟门控使能信号。
-
输出信号(Output Signals):
pfu_pmb_entry_vld_x :向外部表示PMB条目的有效性。pfu_pmb_entry_pc_v :向外部提供PMB条目关联的程序计数器值。pfu_pmb_entry_ready_x :向外部表示PMB条目是否准备就绪。pfu_pmb_entry_evict_x :向外部表示PMB条目是否应被逐出。pfu_pmb_entry_type_ld_x :向外部表示PMB条目的类型(是否为加载类型)。pfu_pmb_entry_hit_pc_x :向外部表示新指令是否命中PMB条目的程序计数器。
-
功能和重要性:
- 这部分代码是模块与外部环境交互的桥梁,确保内部状态和逻辑可以被外部模块正确读取和控制。
- 通过这些接口,可以灵活地将
ct_lsu_pfu_pmb_entry 模块集成到更大的系统中,如C910的整个预取单元或更广泛的处理器架构。 - 输入信号主要用于从外部接收控制和数据,而输出信号则用于向外部报告内部状态和决策。