问题
在实际项目中,我们可能根据design的形状以及绕线资源,需要在设计中插入多个EDT来实现减少绕线,那么基于ssn 架构,我们怎么实现多个EDT的插入呢
解决方法
第一步: 首先需要create 你需要的EDT IP
read_config_data -in $dftspec -from_string {
EDT {
ijtag_host_interface : Sib(edt);
Controller (EXT_EDT) {
longest_chain_range : 170, 300;
scan_chain_count : 20;
input_channel_count : 1;
output_channel_count : 1;
separate_control_data_channels : off;
Compactor {
pipeline_logic_levels_in_compactor : 2;
}
ShiftPowerOptions {
present : on;
min_switching_threshold_percentage: 5 ;
}
Connections {
ssh_chain_group: group_1;
mode_enables: ext_edt_mode;
EdtChannelsIn(1:1) {
PipelineStage {
leaf_instance_name: dfx_ext_edt_channels_in_pipe;
}
}
EdtChannelsOut(1:1) {
PipelineStage {
leaf_instance_name: dfx_ext_edt_channels_out_pipe;
}
}
}
}
Controller (INT_EDT_1) {
longest_chain_range : 300, 500;
scan_chain_count : 900;
input_channel_count : 5;
output_channel_count : 5;
separate_control_data_channels : on;
Compactor {
pipeline_logic_levels_in_compactor : 2;
}
ShiftPowerOptions {
present : on;
min_switching_threshold_percentage: 5 ;
}
Connections {
ssh_chain_group: group_2;
mode_enables: int_edt_mode;
EdtChannelsIn(5:1) {
PipelineStage {
leaf_instance_name: dfx_int_edt_channels_in_pipe_right;
}
}
EdtChannelsOut(5:1) {
PipelineStage {
leaf_instance_name: dfx_int_edt_channels_out_pipe_right;
}
}
}
}
Controller (INT_EDT_2) {
longest_chain_range : 300, 500;
scan_chain_count : 4000;
input_channel_count : 42;
output_channel_count : 42;
separate_control_data_channels : on;
Compactor {
pipeline_logic_levels_in_compactor : 2;
}
ShiftPowerOptions {
present : on;
min_switching_threshold_percentage: 5 ;
}
Connections {
ssh_chain_group: group_1;
mode_enables: int_edt_mode;
EdtChannelsIn(27:1) {
PipelineStage {
leaf_instance_name: dfx_int_edt_channels_in_pipe_left;
}
}
EdtChannelsOut(27:1) {
PipelineStage {
leaf_instance_name: dfx_int_edt_channels_out_pipe_left;
}
}
}
}
}
}
代码中定义的EDT_name 和chain group 都需要在chain group中指定。这样就会先生成多个EDT IP在design 中, 需要注意的是,两个INT EDT 需要使用同一个enable 信号。
然后再scan chain insert的时候,我们就可以通过chain group setting和 scan mode setting,分别将需要的chain 连接到对应的EDT 上,然后后端就可以将不同的EDT 摆放再对应的位置, 来缩短走线,节省绕线资源。
register_attribute -name name1 -obj_type scan_element -value_type boolean
set_attribute_value [get_scan_elements -types segment [get_name_list [get_pins scan_out -hierarchical -of_instances [get_instances *instance1 -h]]]] -name name1
create_scan_chain_family group_1 -chain_length unlimited -include_elements [get_scan_elements -types segment [get_name_list [get_pins scan_out -hierarchical -of_instances [get_instances *instance1 -h]]]] -si_connections tessent_edt_INT_EDT_1_inst/edt_scan_in[0] -so_connections tessent_edt_INT_EDT_1_inst/edt_scan_out[0]
register_attribute -name name2 -obj_type scan_element -value_type boolean
set_attribute_value [get_scan_elements -below_instances [get_name_list [get_instance "*instance2* && *instance3*" -h]] -filter {name!~"*instance4*"}] -name name2
create_scan_chain_family group_2 -include_elements [get_scan_elements -below_instances [get_name_list [get_instance "*instance2* && *instance3*" -h]] -filter {name!~"*instance4*"}] -si_connections tessent_edt_INT_EDT_1_inst/edt_scan_in[10:1] -so_connections tessent_edt_INT_EDT_1_inst/edt_scan_out[10:1] -chain_length 412
register_attribute -name name3 -obj_type scan_element -value_type boolean
set_attribute_value [get_scan_elements -types segment [get_name_list [get_pins o_scan*out -of_instances [get_instances instance6]]]] -name name3
create_scan_chain_family group_3 -chain_length unlimited -include_elements [get_scan_elements -types segment [get_name_list [get_pins o_scan*out -of_instances [get_instances instacne4]]]] -si_connections tessent_edt_INT_EDT_1_inst/edt_scan_in[700:11] -so_connections tessent_edt_INT_EDT_1_inst/edt_scan_out[700:11]
register_attribute -name name4 -obj_type scan_element -value_type boolean
set_attribute_value [get_scan_elements -filter "!name1 && !name2 && !name3"] -name name4
create_scan_chain_family group_4 -chain_length unlimited -include_elements [get_scan_elements -filter "!name1 && !name2 && !name3"]
register_attribute -name occ -obj_type scan_element -value_type boolean
set_attribute_value [get_scan_elements -below_instances [get_name_list [get_instance *tessent_occ* -h -filter {name=~"*clk*"}]]] -name occ
create_scan_chain_family OCC_CHAIN -chain_length unlimited -chain_count 2 -include_elements [get_scan_elements -below_instances [get_name_list [get_instance *tessent_occ* -h -filter {name=~"*clk*"}]]]
chain family 创建好了, 需要指定scan mode
add_scan_mode int_mode_1 -type internal -enable_dft_signal int_stuck_pvt_mode -include_chain_families {name1 name4} -si_pipelining off -single_clock_edge_chains on -single_wrapper_type_chains on -single_clock_domain_chains off -si_lockup_cell_type flop -single_class_chains on -unused_chain_connection_handling insert_pipelining_flop -si_connections {tessent_edt_INT_EDT_2_inst/edt_scan_in[4000:0] tessent_edt_INT_EDT_1_inst/edt_scan_in[0]} -so_connections { tessent_edt_INT_EDT_2_inst/edt_scan_out[4000:0] tessent_edt_INT_EDT_1_inst/edt_scan_in[0]}
add_scan_mode ext_mode -type external -enable_dft_signal ext_mode -edt_instances [get_name_list [get_instance -of_icl_instances [get_name [get_icl_instances -filter "name=~*isp_vivo_sys_*EXT_EDT_inst* && tessent_instrument_type==mentor::edt"]]]] -include_chain_families {OCC} -include_elements [get_scan_elements -filter "class == wrapper"] -si_pipelining off -single_clock_edge_chains on -single_wrapper_type_chains on -single_clock_domain_chains off -si_lockup_cell_type flop -single_class_chains on
这些不同的mode 可以将之前定义的chain 包含进去,自由搭配。
而这些mode 信号,需要在前期就要考虑好,声明这些mode 信号
register_static_dft_signal_names int_mode_1 -usage scan_mode -scan_mode_type internal
add_dft_signal int_mode_1 ext_mode
看前面代码展示,在做chain group的时候,其实是需要知道chain 是如何分配的,以及需要分配的短chain 数量,这样才能指定EDT的scan in 和scan out的bit 数, 所以这种方法是需要迭代,先去获取需要单独串chain的instance里面短chain的数量,这样才能给它指定挂载的EDT和scan in的bit数。同事除了加多个EDT 需要这样做,chain group的设置也是减少短chain 乱串的一个有效手段, 可以解后端的绕线问题,同时,项目前期就应该和后端同事沟通,将那些摆放很近,绕线空间很小的instance 单独串chain,这样就可以避免后面的迭代。