텐서 곱셈 모듈의 UVM 테스트벤치를 작성하라고 해 보았음
그런 다음에 클로드3 소넷이랑 붙던데 답변이 끝도없이 길게 나왔음
말 안 해도 자체적으로 Step by step 적용하네
몇개 좀 이상한 부분이 있긴 한데 HDL은 자료가 워낙에 적어서 뭐 그러려니한듯
--------
Creating a UVM testbench for a synthesizable Verilog module that performs tensor multiplication requires several steps. Here, I'll guide you through the process of setting up a basic UVM testbench structure that you can use to stimulate and verify a tensor multiplication module.
### Step-by-Step Guide to Create a UVM Testbench
#### 1. **Define the Testbench Architecture**
First, define the overall structure of your UVM testbench. The typical components include:
- **DUT (Device Under Test):** The Verilog module performing tensor multiplication.
- **Testbench:** Contains instances of UVM components like agents, monitors, and scoreboards.
- **Agent:** Manages the interface with the DUT, including a sequencer, driver, and monitor.
- **Environment:** Encloses all the agents and provides configuration.
- **Test:** Defines and runs sequences of transactions.
#### 2. **Identify the Interface**
Suppose your tensor multiplication module has the following interface:
```verilog
module tensor_mult #(
parameter DATA_WIDTH = 8,
parameter A_DIM1 = 4, A_DIM2 = 3, B_DIM2 = 2
)(
input logic clk,
input logic rst,
input logic [A_DIM1*A_DIM2*DATA_WIDTH-1:0] A,
input logic [A_DIM2*B_DIM2*DATA_WIDTH-1:0] B,
output logic [A_DIM1*B_DIM2*DATA_WIDTH-1:0] C,
output logic valid
);
```
#### 3. **Create the Interface**
Create a UVM interface to communicate with the DUT. For instance:
```systemverilog
interface tensor_mult_if(
input logic clk
);
logic rst;
logic [A_DIM1*A_DIM2*DATA_WIDTH-1:0] A;
logic [A_DIM2*B_DIM2*DATA_WIDTH-1:0] B;
logic [A_DIM1*B_DIM2*DATA_WIDTH-1:0] C;
logic valid;
modport DUT(
input rst, A, B,
output C, valid
);
endinterface
```
#### 4. **Build the UVM Components**
##### a. **Sequence Item**
This represents a single operation of tensor multiplication.
```systemverilog
class tensor_mult_item extends uvm_sequence_item;
`uvm__utils(tensor_mult_item)
rand bit [A_DIM1*A_DIM2*DATA_WIDTH-1:0] A;
rand bit [A_DIM2*B_DIM2*DATA_WIDTH-1:0] B;
bit [A_DIM1*B_DIM2*DATA_WIDTH-1:0] C;
function new(string name = "tensor_mult_item");
super.new(name);
endfunction
endclass
```
##### b. **Driver**
Drives the inputs of the DUT based on the sequence item.
```systemverilog
class tensor_mult_driver extends uvm_driver #(tensor_mult_item);
`uvm_component_utils(tensor_mult_driver)
tensor_mult_if vif;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
if (!uvm_config_db #(virtual tensor_mult_if)::get(this, "", "vif", vif))
`uvm_fatal("NOVIF", "virtual interface must be set for: " .name)
endfunction
virtual task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req);
vif.A <= req.A;
vif.B <= req.B;
wait (vif.valid === 1'b1);
req.C = vif.C;
seq_item_port.item_done();
end
endtask
endclass
```
##### c. **Monitor**
Observes outputs from the DUT and reports them.
```systemverilog
class tensor_mult_monitor extends uvm_monitor;
`uvm_component_utils(tensor_mult_monitor)
tensor_mult_if vif;
uvm_analysis_port #(tensor_mult_item) item_collected_port;
function new(string name, uvm_component parent);
super.new(name, parent);
item_collected_port = new("item_collected_port", this);
endfunction
virtual function void build_phase(uvm_phase phase);
if (!uvm_config_db #(virtual tensor_mult_if)::get(this, "", "vif", vif))
`uvm_fatal("NOVIF", "virtual interface must be set for: " .name)
endfunction
virtual task run_phase(uvm_phase phase);
tensor_mult_item item;
forever begin
wait (vif.valid === 1'b1);
item = tensor_mult_item::type_id::create("item");
item.C = vif.C;
item_collected_port.write(item);
end
endtask
endclass
```
##### d. **Agent**
Combines the driver and monitor.
```systemverilog
class tensor_mult_agent extends uvm_agent;
`uvm_component_utils(tensor_mult_agent)
tensor_mult_driver driver;
tensor_mult_monitor monitor;
virtual tensor_mult_if vif;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
if (!uvm_config_db #(virtual tensor_mult_if)::get(this, "", "vif", vif))
`uvm_fatal("NOVIF", "virtual interface must be set for: " .name)
driver = tensor_mult_driver::type_id::create("driver", this);
monitor = tensor_mult_monitor::type_id::create("monitor", this);
endfunction
virtual function void connect_phase(uvm_phase phase);
driver.seq_item_port.connect(get_sequencer().seq_item_export);
driver.vif = vif;
monitor.vif = vif;
endfunction
endclass
```
##### e. **Environment**
Encapsulates the agent.
```systemverilog
class tensor_mult_env extends uvm_env;
`uvm_component_utils(tensor_mult_env)
tensor_mult_agent agent;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
agent = tensor_mult_agent::type_id::create("agent", this);
if (!uvm_config_db #(virtual tensor_mult_if)::get(this, "", "vif", agent.vif))
`uvm_fatal("NOVIF", "virtual interface must be set for the agent")
endfunction
endclass
```
##### f. **Test**
Defines the test scenario.
```systemverilog
class tensor_mult_test extends uvm_test;
`uvm_component_utils(tensor_mult_test)
tensor_mult_env env;
virtual tensor_mult_if vif;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = tensor_mult_env::type_id::create("env", this);
if (!uvm_config_db #(virtual tensor_mult_if)::get(this, "", "vif", vif))
`uvm_fatal("NOVIF", "virtual interface must be set for the environment")
endfunction
virtual task run_phase(uvm_phase phase);
super.run_phase(phase);
tensor_mult_item item;
uvm_config_db #(virtual tensor_mult_if)::set(this, "env.agent", "vif", vif);
phase.raise_ion(this);
// Example sequence
item = tensor_mult_item::type_id::create("item");
item.A = {8'd1, 8'd2, 8'd3, 8'd4, 8'd5, 8'd6, 8'd7, 8'd8, 8'd9, 8'd10, 8'd11, 8'd12};
item.B = {8'd1, 8'd2, 8'd3, 8'd4, 8'd5, 8'd6};
uvm_do_with(item, {});
wait (vif.valid === 1'b1);
phase.drop_ion(this);
endtask
endclass
```
#### 5. **Top Module**
Connects the DUT with the testbench using the interface.
```systemverilog
module tb_top;
logic clk = 0;
always #5 clk = ~clk;
tensor_mult_if vif(clk);
tensor_mult #(
.DATA_WIDTH(8),
.A_DIM1(4), .A_DIM2(3), .B_DIM2(2)
) DUT (
.clk(clk),
.rst(vif.rst),
.A(vif.A),
.B(vif.B),
.C(vif.C),
.valid(vif.valid)
);
initial begin
uvm_config_db #(virtual tensor_mult_if)::set(null, "uvm_test_top.env.agent", "vif", vif);
run_test("tensor_mult_test");
end
endmodule
```
This testbench is a basic framework to stimulate and verify a tensor multiplication module in SystemVerilog using UVM. You can expand this by adding more complex sequences, coverage, and scoreboards to fully verify the module's functionality.
기존모델들 베릴로그 디따못하던데 얜좀 낫나
그러게 좀 더 시켜보고 싶음
Also붙은걸로해라 그냥 good이아니라 also붙은걸말하는거임
ALSO붙은게 제일성능좋은거임 ALSO가 가장최근에나온 제일성능좋은모델임
지금 하는데 자꾸 딴모델만 나오고 안나온다
계속뉴 라운드돌리면 나옴 also붙은걸로 다시올려보셈