5.9 Register Sequences (레지스터 시퀀스)
UVM에서 Register Sequence는 레지스터의 값을 읽거나 쓰기 위한 시퀀스입니다. 레지스터 접근 작업을 관리하며, 이를 통해 레지스터 값을 쉽게 제어할 수 있습니다.
1. Register Sequence와 Virtual Sequence 제어
Virtual Sequence는 여러 하위 시퀀서를 한꺼번에 제어하는 시퀀스입니다. 레지스터 시퀀스는 이러한 Virtual Sequence에 포함될 수 있으며, 하위 시퀀서를 통해 레지스터 읽기/쓰기 작업을 관리할 수 있습니다. 이를 위해, p_sequencer를 사용하여 가상 시퀀서에서 하위 시퀀서를 참조하고, 이를 통해 레지스터 시퀀스를 실행합니다.
Register Sequence에서 Virtual Sequencer로 제어하는 예시:
class my_virtual_sequence extends uvm_sequence#(uvm_sequence_item);
`uvm_object_utils(my_virtual_sequence)
my_virtual_sequencer p_sequencer;
function new(string name = "my_virtual_sequence");
super.new(name);
endfunction
virtual task body();
uvm_reg_data_t data1, data2;
// 첫 번째 레지스터 시퀀서에서 레지스터 값을 읽고 씀
p_sequencer.reg_sequencer1.write(status, 32'hDEAD_BEEF, .parent(this));
p_sequencer.reg_sequencer1.read(status, data1, .parent(this));
`uvm_info("VSEQ", $sformatf("Data read from sequencer 1: %h", data1), UVM_LOW);
// 두 번째 레지스터 시퀀서에서 레지스터 값을 읽고 씀
p_sequencer.reg_sequencer2.write(status, 32'hABCD_1234, .parent(this));
p_sequencer.reg_sequencer2.read(status, data2, .parent(this));
`uvm_info("VSEQ", $sformatf("Data read from sequencer 2: %h", data2), UVM_LOW);
endtask
endclass
이 코드는 가상 시퀀서 p_sequencer를 통해 하위 시퀀서 seqr1에서 레지스터 값을 읽고 쓰는 방법을 보여줍니다. 이를 통해 레지스터 접근을 보다 효율적으로 관리할 수 있습니다.
5.10 Predicting Values in the Register Model (uvm_predictor 구현)
**uvm_predictor**는 레지스터의 값을 예측하고 하드웨어와 동기화하는 역할을 하는 중요한 클래스입니다. 레지스터 모델 내에서 값이 변경될 때마다 예상 값과 실제 값이 일치하는지 확인하는 데 사용됩니다.
uvm_predictor 구현
uvm_predictor는 UVM에서 제공하는 기본 클래스이며, 이를 확장하여 특정 설계에 맞는 예측 기능을 구현할 수 있습니다.
기본 uvm_predictor 구현 예시:
class my_predictor extends uvm_predictor;
`uvm_component_utils(my_predictor)
uvm_reg_map reg_map; // 레지스터 맵 참조
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
// 레지스터 맵 설정 (필요 시 환경에서 전달받음)
if (!uvm_config_db#(uvm_reg_map)::get(this, "", "reg_map", reg_map)) begin
`uvm_fatal("PREDICTOR", "No reg_map set for predictor");
end
endfunction
// 모니터로부터 전달받은 시퀀스 아이템을 처리
virtual function void predict(uvm_sequence_item seq_item);
uvm_reg_adapter adapter;
uvm_reg_bus_op rw;
// 시퀀스 아이템이 레지스터 관련 트랜잭션인지 확인
if (!$cast(adapter, reg_map.get_adapter())) begin
`uvm_fatal("PREDICTOR", "No adapter set for the reg_map");
end
// 시퀀스 아이템을 버스 트랜잭션으로 변환
rw = adapter.seq2bus(seq_item);
if (rw.kind == UVM_WRITE) begin
// 쓰기 작업: 하드웨어와 동기화
reg_map.update(seq_item);
`uvm_info("PREDICTOR", $sformatf("Predicted write value: %h", rw.data), UVM_LOW);
end
else if (rw.kind == UVM_READ) begin
// 읽기 작업: 예상된 값을 확인
`uvm_info("PREDICTOR", $sformatf("Predicted read value: %h", rw.data), UVM_LOW);
end
endfunction
endclass
이 코드는 기본적으로 쓰기 작업을 예측하며, 실제 레지스터에 값이 쓰였는지 확인합니다. 읽기 작업에 대한 예측도 추가할 수 있으며, 이를 통해 소프트웨어 모델과 하드웨어 상태 간의 동기화를 유지할 수 있습니다.
uvm_predictor의 기능
- 레지스터 값을 읽거나 쓰는 작업을 예측하고, 예상 값과 실제 하드웨어의 값을 비교합니다.
- 주로 레지스터 값 동기화 및 하드웨어와의 상태 유지에 사용됩니다.
5.11 Default Register Sequences (기본 레지스터 시퀀스)
UVM에서는 기본적으로 제공되는 여러 Default Register Sequences가 있습니다. 이러한 기본 시퀀스는 레지스터의 기본적인 읽기/쓰기 동작을 수행하며, 이를 통해 복잡한 레지스터 검증을 효율적으로 관리할 수 있습니다.
1. uvm_reg_hw_reset_seq
이 시퀀스는 하드웨어의 레지스터 리셋 값을 읽는 기본 시퀀스입니다. 레지스터 모델의 초기화 및 리셋 작업을 자동으로 처리하며, 이를 통해 하드웨어 리셋 값이 예상대로 설정되었는지 확인합니다.
class uvm_reg_hw_reset_seq extends uvm_reg_sequence;
`uvm_object_utils(uvm_reg_hw_reset_seq)
virtual task body();
uvm_reg_data_t data;
// 각 레지스터의 리셋 값 읽기
foreach (regs[i]) begin
regs[i].read(data, .parent(this), UVM_FRONTDOOR);
`uvm_info("RESET_SEQ", $sformatf("Reset value: %h", data), UVM_LOW)
end
endtask
endclass
2. uvm_reg_bit_bash_seq
Bit Bash 시퀀스는 각 레지스터의 비트가 정상적으로 동작하는지 검증하는 기본 시퀀스입니다. 이 시퀀스는 레지스터의 모든 비트를 0으로 설정했다가 다시 1로 변경하며, 이를 통해 각 비트가 제대로 반응하는지 확인합니다.
class uvm_reg_bit_bash_seq extends uvm_reg_sequence;
`uvm_object_utils(uvm_reg_bit_bash_seq)
virtual task body();
uvm_reg_data_t data;
foreach (regs[i]) begin
// 레지스터 비트를 0으로 설정
regs[i].write(0, .parent(this));
regs[i].read(data, .parent(this));
`uvm_info("BIT_BASH_SEQ", $sformatf("Bit 0 value: %h", data), UVM_LOW)
// 레지스터 비트를 1로 설정
regs[i].write(32'hFFFF_FFFF, .parent(this));
regs[i].read(data, .parent(this));
`uvm_info("BIT_BASH_SEQ", $sformatf("Bit 1 value: %h", data), UVM_LOW)
end
endtask
endclass
이 코드는 Bit Bash 시퀀스의 기본 동작을 보여줍니다. 레지스터의 각 비트를 테스트하여 읽기/쓰기가 제대로 동작하는지 확인할 수 있습니다.
3. uvm_reg_access_seq
uvm_reg_access_seq는 모든 레지스터에 대한 읽기/쓰기 테스트를 수행하는 시퀀스입니다. 이를 통해 전체 레지스터 맵에 대한 검증을 빠르고 효율적으로 수행할 수 있습니다.
class uvm_reg_access_seq extends uvm_reg_sequence;
`uvm_object_utils(uvm_reg_access_seq)
virtual task body();
uvm_reg_data_t data;
// 각 레지스터에 대한 읽기/쓰기 수행
foreach (regs[i]) begin
regs[i].write(32'hDEAD_BEEF, .parent(this));
regs[i].read(data, .parent(this));
`uvm_info("ACCESS_SEQ", $sformatf("Accessed data: %h", data), UVM_LOW)
end
endtask
endclass
이 시퀀스는 레지스터에 값을 쓰고 읽는 작업을 자동으로 처리하며, 레지스터 맵 전체의 검증을 손쉽게 수행할 수 있습니다.
결론
5.9에서 5.11까지는 UVM에서 레지스터 시퀀스와 Virtual Sequence를 어떻게 제어하는지, uvm_predictor를 사용해 레지스터 값을 예측하는 방법, 그리고 기본적으로 제공되는 Default Register Sequences에 대해 설명했습니다. 특히, 기본 제공되는 시퀀스들은 프로젝트에서 자주 사용되며, 레지스터 맵의 초기화, 비트 검증, 그리고 전체 접근 테스트를 통해 검증을 효율적으로 관리할 수 있습니다.
'지식 공유 > UVM' 카테고리의 다른 글
[UVM 1.1d] 6-3. Advanced UVM Topics (UVM CLI) (0) | 2024.11.19 |
---|---|
[UVM 1.1d] 6-2. Advanced UVM Topics (SEQ_LIB, Layering) (0) | 2024.11.13 |
[UVM 1.1d] 6-1. Advanced UVM Topics (Factory, Callback) (0) | 2024.11.12 |
[UVM 1.1d] 5-3. Register Model (Register Abstraction Layer) (0) | 2024.10.20 |
[UVM 1.1d] 5-2. Register Model (Register Abstraction Layer) (0) | 2024.10.15 |
[UVM 1.1d] 5-1. Register Model (Register Abstraction Layer) (0) | 2024.10.15 |
댓글