diff --git a/tb/agents/fu_if/fu_if_agent.svh b/tb/agents/fu_if/fu_if_agent.svh index 7d0cc8352..4db74c580 100644 --- a/tb/agents/fu_if/fu_if_agent.svh +++ b/tb/agents/fu_if/fu_if_agent.svh @@ -11,6 +11,9 @@ class fu_if_agent extends uvm_component; //------------------------------------------ // Component Members //------------------------------------------ + uvm_analysis_port #(fu_if_seq_item) ap; + fu_if_driver m_driver; + fu_if_sequencer m_sequencer; //------------------------------------------ // Methods //------------------------------------------ @@ -19,17 +22,22 @@ class fu_if_agent extends uvm_component; extern function void build_phase(uvm_phase phase); extern function void connect_phase(uvm_phase phase); endclass : fu_if_agent + function fu_if_agent::new(string name = "fu_if_agent", uvm_component parent = null); super.new(name, parent); endfunction : new + function void fu_if_agent::build_phase(uvm_phase phase); if (!uvm_config_db #(fu_if_agent_config)::get(this, "", "fu_if_agent_config", m_cfg) ) `uvm_fatal("CONFIG_LOAD", "Cannot get() configuration apb_agent_config from uvm_config_db. Have you set() it?") - if (m_cfg.is_master) - `uvm_info("CONFIG_LOAD", "Created master memory interface", UVM_LOW) - else - `uvm_info("CONFIG_LOAD", "Created slave memory interface", UVM_LOW) + + m_driver = fu_if_driver::type_id::create("m_driver", this); + m_sequencer = spi_sequencer::type_id::create("m_sequencer", this); + endfunction : build_phase + function void fu_if_agent::connect_phase(uvm_phase phase); - super.connect_phase(phase); + + m_driver.seq_item_port.connect(m_sequencer.seq_item_export); + m_driver.m_cfg = m_cfg; endfunction: connect_phase \ No newline at end of file diff --git a/tb/agents/fu_if/fu_if_driver.svh b/tb/agents/fu_if/fu_if_driver.svh index e69de29bb..38a35f01d 100644 --- a/tb/agents/fu_if/fu_if_driver.svh +++ b/tb/agents/fu_if/fu_if_driver.svh @@ -0,0 +1,55 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 12/21/2016 +// Description: Driver of the memory interface + +class fu_if_driver extends uvm_driver #(sequence_item); + + // UVM Factory Registration Macro + `uvm_component_utils(fu_if_driver) + + // Virtual Interface + virtual fu_if fu; + + //--------------------- + // Data Members + //--------------------- + fu_if_agent_config m_cfg; + + // Standard UVM Methods: + extern function new(string name = "fu_if_driver", uvm_component parent = null); + extern task run_phase(uvm_phase phase); + extern function void build_phase(uvm_phase phase); + + +endclass : fu_if_driver + +function fu_if_driver::new(string name = "fu_if_driver", uvm_component parent = null); + super.new(name, parent); +endfunction + +task fu_if_driver::run_phase(uvm_phase phase); + sequence_item cmd; + + forever begin : cmd_loop + shortint unsigned result; + seq_item_port.get_next_item(cmd); + + // using clocking blocks this is possible + @(fu.mck) + fu.mclk.operandA <= cmd.operandA; + fu.mclk.operandB <= cmd.operandB; + fu.mclk.operandC <= cmd.operandC; + fu.mclk.operator <= cmd.operator; + + cmd.result <= fu.mclk.result; + cmd.compare_result <= fu.mclk.compare_result; + + seq_item_port.item_done(); + + end : cmd_loop +endtask : run_phase + +function void fu_if_driver::build_phase(uvm_phase phase); + if (!uvm_config_db #(fu_if_agent_config)::get(this, "", "fu_if_agent_config", m_cfg) ) + `uvm_fatal("CONFIG_LOAD", "Cannot get() configuration fu_if_agent_config from uvm_config_db. Have you set() it?") +endfunction: build_phase \ No newline at end of file diff --git a/tb/env/alu_env.svh b/tb/env/alu_env.svh index 3a526a7fd..f9f9a9aad 100644 --- a/tb/env/alu_env.svh +++ b/tb/env/alu_env.svh @@ -11,7 +11,7 @@ class alu_env extends uvm_env; // Data Members //------------------------------------------ fu_if_agent m_fu_if_agent; - + fu_if_sequencer m_fu_if_sequencer; alu_env_config m_cfg; //------------------------------------------ @@ -40,11 +40,12 @@ function void alu_env::build_phase(uvm_phase phase); m_cfg.m_fu_if); m_fu_if_agent = fu_if_agent::type_id::create("m_fu_if_agent", this); - + // Get sequencer + m_fu_if_sequencer = fu_if_sequencer::type_id::create("m_fu_if_sequencer", this); endfunction:build_phase function void alu_env::connect_phase(uvm_phase phase); - + m_fu_if_sequencer = m_fu_if_agent.m_sequencer; endfunction: connect_phase diff --git a/tb/sequences/fibonacci_sequence.svh b/tb/sequences/fibonacci_sequence.svh new file mode 100644 index 000000000..3461a8040 --- /dev/null +++ b/tb/sequences/fibonacci_sequence.svh @@ -0,0 +1,33 @@ +class fibonacci_sequence extends uvm_sequence #(sequence_item); + `uvm_object_utils(fibonacci_sequence); + + function new(string name = "fibonacci"); + super.new(name); + endfunction : new + + + task body(); + byte unsigned n_minus_2=0; + byte unsigned n_minus_1=1; + sequence_item command; + + command = fu_if_seq_item::type_id::create("command"); + + `uvm_info("FIBONACCI", " Fib(01) = 00", UVM_MEDIUM); + `uvm_info("FIBONACCI", " Fib(02) = 01", UVM_MEDIUM); + for(int ff = 3; ff<=14; ff++) begin + start_item(command); + command.operandA = n_minus_2; + command.operandB = n_minus_1; + command.op = 7'b00; + + finish_item(command); + + n_minus_2 = n_minus_1; + n_minus_1 = command.result; + + `uvm_info("FIBONACCI", $sformatf("Fib(%02d) = %02d", ff, n_minus_1), + UVM_MEDIUM); + end + endtask : body +endclass : fibonacci_sequence \ No newline at end of file diff --git a/tb/test/alu_test.svh b/tb/test/alu_test.svh index ea11945b6..b9313c5c3 100644 --- a/tb/test/alu_test.svh +++ b/tb/test/alu_test.svh @@ -28,6 +28,8 @@ endfunction task alu_test::run_phase(uvm_phase phase); phase.raise_objection(this, "alu_test"); + fibonacci_sequence fibonacci_seq = fibonacci_sequence::type_id::create("fibonacci_sequence"); + fibonacci_seq.start(m_env.m_fu_if_sequencer); // Testlogic goes here #100ns; phase.drop_objection(this, "alu_test");