diff options
| author | Fuwn <[email protected]> | 2026-02-24 20:46:14 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-24 20:46:14 -0800 |
| commit | 57bb24b96645ad0f60c6e6968a6b2ac48754e2dc (patch) | |
| tree | 9f7da4da999b87ea9541e5ad83b9cbe87f674ce7 | |
| parent | feat(homework_2): Add initial files (diff) | |
| download | cst456-57bb24b96645ad0f60c6e6968a6b2ac48754e2dc.tar.xz cst456-57bb24b96645ad0f60c6e6968a6b2ac48754e2dc.zip | |
feat(homework_2): Add implementation
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | homework_2/SIM/run_coverage.bat | 7 | ||||
| -rw-r--r-- | homework_2/SIM/run_sim_cli.bat | 5 | ||||
| -rw-r--r-- | homework_2/SIM/run_sim_gui.bat | 6 | ||||
| -rw-r--r-- | homework_2/SRC/base_test.sv | 130 | ||||
| -rw-r--r-- | homework_2/SRC/driver.sv | 70 | ||||
| -rw-r--r-- | homework_2/SRC/duv.sv | 151 | ||||
| -rw-r--r-- | homework_2/SRC/gen_item_seq.sv | 58 | ||||
| -rw-r--r-- | homework_2/SRC/interface.sv | 31 | ||||
| -rw-r--r-- | homework_2/SRC/item.sv | 35 | ||||
| -rw-r--r-- | homework_2/SRC/monitor.sv | 81 | ||||
| -rw-r--r-- | homework_2/SRC/scoreboard.sv | 114 | ||||
| -rw-r--r-- | homework_2/SRC/tb.sv | 71 |
13 files changed, 400 insertions, 360 deletions
@@ -7,3 +7,4 @@ xsim.dir .Xil *.zip xsim.covdb +cRun* diff --git a/homework_2/SIM/run_coverage.bat b/homework_2/SIM/run_coverage.bat new file mode 100644 index 0000000..6448877 --- /dev/null +++ b/homework_2/SIM/run_coverage.bat @@ -0,0 +1,7 @@ +@echo off +call C:\Xilinx\Vivado\2022.1\bin\xvlog -nolog --sv ../SRC/duv.sv ../SRC/tb.sv -L UVM +if %ERRORLEVEL% EQU 0 call C:\Xilinx\Vivado\2022.1\bin\xelab -nolog -debug typical -top tb -snapshot duv_tb_snapshot -L UVM -cc_type sbct -cc_db DB1 -cc_dir ./cRun1 +if %ERRORLEVEL% EQU 0 call C:\Xilinx\Vivado\2022.1\bin\xsim duv_tb_snapshot -R +if %ERRORLEVEL% EQU 0 call C:\Xilinx\Vivado\2022.1\bin\xcrg -cc_db DB1 -cc_dir ./cRun1 -cc_report ./cReport1 +if %ERRORLEVEL% EQU 0 start ./cReport1/dashboard.html +pause diff --git a/homework_2/SIM/run_sim_cli.bat b/homework_2/SIM/run_sim_cli.bat new file mode 100644 index 0000000..aad09bd --- /dev/null +++ b/homework_2/SIM/run_sim_cli.bat @@ -0,0 +1,5 @@ +@echo off +call C:\Xilinx\Vivado\2022.1\bin\xvlog -nolog --sv ../SRC/duv.sv ../SRC/tb.sv -L UVM +if %ERRORLEVEL% EQU 0 call C:\Xilinx\Vivado\2022.1\bin\xelab -nolog -debug typical -top tb -snapshot duv_tb_snapshot -L UVM +if %ERRORLEVEL% EQU 0 call C:\Xilinx\Vivado\2022.1\bin\xsim duv_tb_snapshot -R +pause diff --git a/homework_2/SIM/run_sim_gui.bat b/homework_2/SIM/run_sim_gui.bat new file mode 100644 index 0000000..100bf58 --- /dev/null +++ b/homework_2/SIM/run_sim_gui.bat @@ -0,0 +1,6 @@ +@echo off +call C:\Xilinx\Vivado\2022.1\bin\xvlog -nolog --sv ../SRC/duv.sv ../SRC/tb.sv -L UVM +if %ERRORLEVEL% EQU 0 call C:\Xilinx\Vivado\2022.1\bin\xelab -nolog -debug typical -top tb -snapshot duv_tb_snapshot -L UVM +if %ERRORLEVEL% EQU 0 call C:\Xilinx\Vivado\2022.1\bin\xsim duv_tb_snapshot --tclbatch xsim_cfg.tcl +if %ERRORLEVEL% EQU 0 call C:\Xilinx\Vivado\2022.1\bin\xsim --gui duv_tb_snapshot.wdb +pause diff --git a/homework_2/SRC/base_test.sv b/homework_2/SRC/base_test.sv index ea675bc..b6b81ef 100644 --- a/homework_2/SRC/base_test.sv +++ b/homework_2/SRC/base_test.sv @@ -1,63 +1,67 @@ -// Test class instantiates the environment and starts it.
-class base_test extends uvm_test;
- `uvm_component_utils(base_test)
- function new(string name = "base_test", uvm_component parent=null);
- super.new(name, parent);
- endfunction
-
- env e0;
- bit[`LENGTH-1:0] pattern = 4'b1011;
- gen_item_seq seq;
- virtual des_if vif;
-
- virtual function void build_phase(uvm_phase phase);
- super.build_phase(phase);
-
- // Create the environment
- e0 = env::type_id::create("e0", this);
-
- // Get virtual IF handle from top level and pass it to everything
- // in env level
- if (!uvm_config_db#(virtual des_if)::get(this, "", "des_vif", vif))
- `uvm_fatal("TEST", "Did not get vif")
- uvm_config_db#(virtual des_if)::set(this, "e0.a0.*", "des_vif", vif);
-
- // Setup pattern queue and place into config db
- uvm_config_db#(bit[`LENGTH-1:0])::set(this, "*", "ref_pattern", pattern);
-
- // Create sequence and randomize it
- seq = gen_item_seq::type_id::create("seq");
- seq.randomize();
- endfunction
-
- virtual task run_phase(uvm_phase phase);
- phase.raise_objection(this);
- apply_reset();
- seq.start(e0.a0.s0);
- #200;
- phase.drop_objection(this);
- endtask
-
- virtual task apply_reset();
- vif.rstn <= 0;
- vif.in <= 0;
- repeat(5) @ (posedge vif.clk);
- vif.rstn <= 1;
- repeat(10) @ (posedge vif.clk);
- endtask
-endclass
-
-class test_1011 extends base_test;
- `uvm_component_utils(test_1011)
- function new(string name="test_1011", uvm_component parent=null);
- super.new(name, parent);
- endfunction
-
- virtual function void build_phase(uvm_phase phase);
- pattern = 4'b1011;
- super.build_phase(phase);
- seq.randomize() with { num inside {[300:500]}; };
- endfunction
-endclass
-
-// The int
\ No newline at end of file +// Test class instantiates the environment and starts it. +class base_test extends uvm_test; + `uvm_component_utils(base_test) + function new(string name = "base_test", uvm_component parent = null); + super.new(name, parent); + endfunction + + env e0; + gen_item_seq seq; + virtual des_if vif; + + virtual function void build_phase(uvm_phase phase); + super.build_phase(phase); + + // Create the environment + e0 = env::type_id::create("e0", this); + + // Get virtual IF handle from top level and pass it to everything + // in env level + if (!uvm_config_db#(virtual des_if)::get(this, "", "des_vif", vif)) + `uvm_fatal("TEST", "Did not get vif") + + uvm_config_db#(virtual des_if)::set(this, "e0.a0.*", "des_vif", vif); + + // Create sequence and randomize it + seq = gen_item_seq::type_id::create("seq"); + + if (!seq.randomize()) `uvm_fatal("TEST", "Failed to randomize sequence") + endfunction + + virtual task run_phase(uvm_phase phase); + phase.raise_objection(this); + apply_reset(); + seq.start(e0.a0.s0); + + #200; + + `uvm_info("TEST_DONE", "Sequence detector test completed", UVM_LOW) + + phase.drop_objection(this); + endtask + + virtual task apply_reset(); + vif.reset <= 1'b1; + vif.inp <= 0; + + repeat (5) @(posedge vif.clk); + + vif.reset <= 0; + + repeat (10) @(posedge vif.clk); + endtask +endclass + +class test_both_patterns extends base_test; + `uvm_component_utils(test_both_patterns) + function new(string name = "test_both_patterns", uvm_component parent = null); + super.new(name, parent); + endfunction + + virtual function void build_phase(uvm_phase phase); + super.build_phase(phase); + + if (!seq.randomize() with {num inside {[520 : 620]};}) + `uvm_fatal("TEST", "Failed to randomize sequence length") + endfunction +endclass diff --git a/homework_2/SRC/driver.sv b/homework_2/SRC/driver.sv index 37d0583..03d17b8 100644 --- a/homework_2/SRC/driver.sv +++ b/homework_2/SRC/driver.sv @@ -1,33 +1,37 @@ -// The driver is responsible for driving transactions to the DUT
-// All it does is to get a transaction from the mailbox if it is
-// available and drive it out into the DUT interface.
-class driver extends uvm_driver #(Item);
- `uvm_component_utils(driver)
- function new(string name = "driver", uvm_component parent=null);
- super.new(name, parent);
- endfunction
-
- virtual des_if vif;
-
- virtual function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- if (!uvm_config_db#(virtual des_if)::get(this, "", "des_vif", vif))
- `uvm_fatal("DRV", "Could not get vif")
- endfunction
-
- virtual task run_phase(uvm_phase phase);
- super.run_phase(phase);
- forever begin
- Item m_item;
- `uvm_info("DRV", $sformatf("Wait for item from sequencer"), UVM_HIGH)
- seq_item_port.get_next_item(m_item);
- drive_item(m_item);
- seq_item_port.item_done();
- end
- endtask
-
- virtual task drive_item(Item m_item);
- @(vif.cb);
- vif.cb.in <= m_item.in;
- endtask
-endclass
\ No newline at end of file +// The driver is responsible for driving transactions to the DUT +// All it does is to get a transaction from the mailbox if it is +// available and drive it out into the DUT interface. +class driver extends uvm_driver #(Item); + `uvm_component_utils(driver) + function new(string name = "driver", uvm_component parent = null); + super.new(name, parent); + endfunction + + virtual des_if vif; + + virtual function void build_phase(uvm_phase phase); + super.build_phase(phase); + + if (!uvm_config_db#(virtual des_if)::get(this, "", "des_vif", vif)) + `uvm_fatal("DRV", "Could not get vif") + endfunction + + virtual task run_phase(uvm_phase phase); + super.run_phase(phase); + forever begin + Item m_item; + + `uvm_info("DRV", $sformatf("Wait for item from sequencer"), UVM_HIGH) + + seq_item_port.get_next_item(m_item); + drive_item(m_item); + seq_item_port.item_done(); + end + endtask + + virtual task drive_item(Item m_item); + @(vif.cb); + + vif.cb.inp <= m_item.inp; + endtask +endclass diff --git a/homework_2/SRC/duv.sv b/homework_2/SRC/duv.sv index e7e0c0f..62e5b99 100644 --- a/homework_2/SRC/duv.sv +++ b/homework_2/SRC/duv.sv @@ -1,86 +1,65 @@ -module duv ( input clk,
- input rstn,
- input in,
- output out );
-
- parameter IDLE = 0,
- S1 = 1,
- S10 = 2,
- S101 = 3,
- S1011 = 4;
-
- reg [2:0] cur_state, next_state;
-
- assign out = cur_state == S1011 ? 1 : 0;
-
- always @ (posedge clk) begin
- if (!rstn)
- cur_state <= IDLE;
- else
- cur_state <= next_state;
- end
-
- always @ (cur_state or in) begin
- case (cur_state)
- IDLE : begin
- if (in) next_state = S1;
- else next_state = IDLE;
- end
-
- S1: begin
-`ifdef BUG_FIX_1
- // Designer assumed that if next input is 1,
- // state should start from IDLE. But he forgot
- // that it should stay in same state since it
- // already matched part of the pattern which
- // is the starting "1"
- if (in) next_state = S1;
-`else
- if (in) next_state = IDLE;
-`endif
- else next_state = S10;
- end
-
- S10 : begin
- if (in) next_state = S101;
- else next_state = IDLE;
- end
-
- S101 : begin
- if (in) next_state = S1011;
-`ifdef BUG_FIX_2
- // Designer assumed that if next input is 0,
- // then pattern fails to match and should
- // restart. But he forgot that S101 followed
- // by 0 actually matches part of the pattern
- // which is "10" and only "11" is remaining
- // So it should actually go back to S10
- else next_state = S10;
-`else
- else next_state = IDLE;
-`endif
- end
-
- S1011: begin
-`ifdef BUG_FIX_3
- // Designer assumed next state should always
- // be IDLE since the pattern has matched. But
- // he forgot that if next input is 1, it is
- // already the start of another sequence and
- // instead should go to S1.
- if (in) next_state = S1;
- `ifdef BUG_FIX_4
- // Designer forgot again that if next input is 0
- // then pattern still matches "10" and should
- // go to S10 instead of IDLE.
- else next_state = S10;
- `else
- else next_state = IDLE;
- `endif
-`else
- next_state = IDLE;
-`endif
- end
- endcase
- end
-endmodule
\ No newline at end of file +module duv ( + input logic clk, + input logic reset, + input logic inp, + output logic outp +); + localparam S0 = 3'b000, S1 = 3'b001, S11 = 3'b010, S10 = 3'b011, S110 = 3'b100, S101 = 3'b101; + + logic [2:0] state; + logic [2:0] next_state; + + // State register with asynchronous active-high reset + always_ff @(posedge clk or posedge reset) begin + if (reset) state <= S0; + else state <= next_state; + end + + // Mealy next-state and output logic for 1011 and 1100 + always_comb begin + next_state = state; + outp = 1'b0; + + case (state) + S0: begin + if (inp) next_state = S1; + else next_state = S0; + end + + S1: begin + if (inp) next_state = S11; + else next_state = S10; + end + + S11: begin + if (inp) next_state = S11; + else next_state = S110; + end + + S10: begin + if (inp) next_state = S101; + else next_state = S0; + end + + S110: begin + if (inp) begin + next_state = S101; + end else begin + next_state = S0; + outp = 1'b1; // Detected 1100 + end + end + + S101: begin + if (inp) begin + next_state = S11; + outp = 1'b1; // Detected 1011 + end else begin + next_state = S10; + end + end + + default: next_state = S0; + endcase + end +endmodule diff --git a/homework_2/SRC/gen_item_seq.sv b/homework_2/SRC/gen_item_seq.sv index c42cf3a..ce3c3f5 100644 --- a/homework_2/SRC/gen_item_seq.sv +++ b/homework_2/SRC/gen_item_seq.sv @@ -1,22 +1,36 @@ -// The generator class is replaced by a sequence
-class gen_item_seq extends uvm_sequence;
- `uvm_object_utils(gen_item_seq)
- function new(string name="gen_item_seq");
- super.new(name);
- endfunction
-
- rand int num; // Config total number of items to be sent
-
- constraint c1 { soft num inside {[10:50]}; }
-
- virtual task body();
- for (int i = 0; i < num; i ++) begin
- Item m_item = Item::type_id::create("m_item");
- start_item(m_item);
- m_item.randomize();
- `uvm_info("SEQ", $sformatf("Generate new item: %s", m_item.convert2str()), UVM_HIGH)
- finish_item(m_item);
- end
- `uvm_info("SEQ", $sformatf("Done generation of %0d items", num), UVM_LOW)
- endtask
-endclass
\ No newline at end of file +// The generator class is replaced by a sequence +class gen_item_seq extends uvm_sequence; + `uvm_object_utils(gen_item_seq) + function new(string name = "gen_item_seq"); + super.new(name); + endfunction + + rand int num; // Config total number of items to be sent + + constraint c1 {soft num inside {[300 : 500]};} + + virtual task body(); + bit seed_bits [$] = '{1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0}; + int total_num; + + total_num = (num < seed_bits.size()) ? seed_bits.size() : num; + + for (int i = 0; i < total_num; i++) begin + Item m_item = Item::type_id::create($sformatf("m_item_%0d", i)); + + start_item(m_item); + + if (i < seed_bits.size()) begin + m_item.inp = seed_bits[i]; + end else begin + if (!m_item.randomize()) `uvm_fatal("SEQ", "Randomization failure for sequence item") + end + + `uvm_info("SEQ", $sformatf("Generate new item: %s", m_item.convert2str()), UVM_HIGH) + + finish_item(m_item); + end + + `uvm_info("SEQ", $sformatf("Done generation of %0d items", total_num), UVM_LOW) + endtask +endclass diff --git a/homework_2/SRC/interface.sv b/homework_2/SRC/interface.sv index a9906c8..47ed74a 100644 --- a/homework_2/SRC/interface.sv +++ b/homework_2/SRC/interface.sv @@ -1,15 +1,16 @@ -// using a virtual interface handle
-interface des_if (input bit clk);
- logic rstn;
- logic in;
- logic out;
-
- clocking cb @(posedge clk);
- default input #1step output #3ns;
- input out;
- output in;
- endclocking
-
-endinterface
-
-// Top level test
\ No newline at end of file +// using a virtual interface handle +interface des_if ( + input bit clk +); + logic reset; + logic inp; + logic outp; + + clocking cb @(posedge clk); + default input #1step output #3ns; + input outp; + output inp; + endclocking +endinterface + +// Top level test diff --git a/homework_2/SRC/item.sv b/homework_2/SRC/item.sv index 5decdca..655d0b5 100644 --- a/homework_2/SRC/item.sv +++ b/homework_2/SRC/item.sv @@ -1,15 +1,20 @@ -class Item extends uvm_sequence_item;
- `uvm_object_utils(Item)
- rand bit in;
- bit out;
-
- virtual function string convert2str();
- return $sformatf("in=%0d, out=%0d", in, out);
- endfunction
-
- function new(string name = "Item");
- super.new(name);
- endfunction
-
- constraint c1 { in dist {0:/20, 1:/80}; }
-endclass
\ No newline at end of file +class Item extends uvm_sequence_item; + `uvm_object_utils(Item) + rand bit inp; + bit outp; + + virtual function string convert2str(); + return $sformatf("inp=%0d, outp=%0d", inp, outp); + endfunction + + function new(string name = "Item"); + super.new(name); + endfunction + + constraint c1 { + inp dist { + 0 :/ 50, + 1 :/ 50 + }; + } +endclass diff --git a/homework_2/SRC/monitor.sv b/homework_2/SRC/monitor.sv index cb848ec..d4b3e01 100644 --- a/homework_2/SRC/monitor.sv +++ b/homework_2/SRC/monitor.sv @@ -1,37 +1,44 @@ -// The monitor has a virtual interface handle with which
-// it can monitor the events happening on the interface.
-// It sees new transactions and then captures information
-// into a packet and sends it to the scoreboard
-// using another mailbox.
-class monitor extends uvm_monitor;
- `uvm_component_utils(monitor)
- function new(string name="monitor", uvm_component parent=null);
- super.new(name, parent);
- endfunction
-
- uvm_analysis_port #(Item) mon_analysis_port;
- virtual des_if vif;
-
- virtual function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- if (!uvm_config_db#(virtual des_if)::get(this, "", "des_vif", vif))
- `uvm_fatal("MON", "Could not get vif")
- mon_analysis_port = new ("mon_analysis_port", this);
- endfunction
-
- virtual task run_phase(uvm_phase phase);
- super.run_phase(phase);
- // This task monitors the interface for a complete
- // transaction and writes into analysis port when complete
- forever begin
- @ (vif.cb);
- if (vif.rstn) begin
- Item item = Item::type_id::create("item");
- item.in = vif.in;
- item.out = vif.cb.out;
- mon_analysis_port.write(item);
- `uvm_info("MON", $sformatf("Saw item %s", item.convert2str()), UVM_HIGH)
- end
- end
- endtask
-endclass
+// The monitor has a virtual interface handle with which +// it can monitor the events happening on the interface. +// It sees new transactions and then captures information +// into a packet and sends it to the scoreboard +// using another mailbox. +class monitor extends uvm_monitor; + `uvm_component_utils(monitor) + function new(string name = "monitor", uvm_component parent = null); + super.new(name, parent); + endfunction + + uvm_analysis_port #(Item) mon_analysis_port; + + virtual des_if vif; + + virtual function void build_phase(uvm_phase phase); + super.build_phase(phase); + + if (!uvm_config_db#(virtual des_if)::get(this, "", "des_vif", vif)) + `uvm_fatal("MON", "Could not get vif") + + mon_analysis_port = new("mon_analysis_port", this); + endfunction + + virtual task run_phase(uvm_phase phase); + super.run_phase(phase); + + // This task monitors the interface for a complete + // transaction and writes into analysis port when complete + forever begin + @(vif.cb); + if (!vif.reset) begin + Item item = Item::type_id::create("item"); + + item.inp = vif.inp; + item.outp = vif.cb.outp; + + mon_analysis_port.write(item); + + `uvm_info("MON", $sformatf("Saw item %s", item.convert2str()), UVM_HIGH) + end + end + endtask +endclass diff --git a/homework_2/SRC/scoreboard.sv b/homework_2/SRC/scoreboard.sv index c442f57..a55c812 100644 --- a/homework_2/SRC/scoreboard.sv +++ b/homework_2/SRC/scoreboard.sv @@ -1,53 +1,61 @@ -// the design routes packets based on an address range, the
-// scoreboard checks that the packet's address is within valid
-// range.
-class scoreboard extends uvm_scoreboard;
- `uvm_component_utils(scoreboard)
- function new(string name="scoreboard", uvm_component parent=null);
- super.new(name, parent);
- endfunction
-`define LENGTH 4
- bit[`LENGTH-1:0] ref_pattern;
- bit[`LENGTH-1:0] act_pattern;
- bit exp_out;
-
- uvm_analysis_imp #(Item, scoreboard) m_analysis_imp;
-
- virtual function void build_phase(uvm_phase phase);
- super.build_phase(phase);
-
- m_analysis_imp = new("m_analysis_imp", this);
- if (!uvm_config_db#(bit[`LENGTH-1:0])::get(this, "*", "ref_pattern", ref_pattern))
- `uvm_fatal("SCBD", "Did not get ref_pattern !")
- endfunction
-
- virtual function write(Item item);
- act_pattern = act_pattern << 1 | item.in;
-
- `uvm_info("SCBD", $sformatf("in=%0d out=%0d ref=0b%0b act=0b%0b",
- item.in, item.out, ref_pattern, act_pattern), UVM_LOW)
-
- // Always check that expected out value is the actual observed value
- // Since it takes 1 clock for out to be updated after pattern match,
- // do the check first and then update exp_out value
- if (item.out != exp_out) begin
- `uvm_error("SCBD", $sformatf("ERROR ! out=%0d exp=%0d",
- item.out, exp_out))
- end else begin
- `uvm_info("SCBD", $sformatf("PASS ! out=%0d exp=%0d",
- item.out, exp_out), UVM_HIGH)
- end
-
- // If current index has reached the full pattern, then set exp_out to be 1
- // which will be checked in the next clock. If pattern is not complete, keep
- // exp_out to zero
- if (!(ref_pattern ^ act_pattern)) begin
- `uvm_info("SCBD", $sformatf("Pattern found to match, next out should be 1"), UVM_LOW)
- exp_out = 1;
- end else begin
- exp_out = 0;
- end
-
- endfunction
-endclass
-
\ No newline at end of file +// the design checks two valid sequence patterns and compares +// expected output to monitored output in each cycle. +class scoreboard extends uvm_scoreboard; + `uvm_component_utils(scoreboard) + function new(string name = "scoreboard", uvm_component parent = null); + super.new(name, parent); + endfunction + + `define LENGTH 4 + bit [`LENGTH-1:0] act_pattern; + bit exp_out; + bit seen_1011; + bit seen_1100; + + uvm_analysis_imp #(Item, scoreboard) m_analysis_imp; + + virtual function void build_phase(uvm_phase phase); + super.build_phase(phase); + + m_analysis_imp = new("m_analysis_imp", this); + act_pattern = '0; + exp_out = 0; + seen_1011 = 0; + seen_1100 = 0; + endfunction + + virtual function write(Item item); + act_pattern = act_pattern << 1 | item.inp; + exp_out = ((act_pattern == 4'b1011) || (act_pattern == 4'b1100)); + + `uvm_info("SCBD", $sformatf("inp=%0d outp=%0d act=0b%0b", item.inp, item.outp, act_pattern), + UVM_LOW) + + if (act_pattern == 4'b1011) begin + seen_1011 = 1; + + `uvm_info("SCBD", $sformatf("Pattern found to match"), UVM_LOW) + end + + if (act_pattern == 4'b1100) begin + seen_1100 = 1; + + `uvm_info("SCBD", $sformatf("Pattern found to match"), UVM_LOW) + end + + if (item.outp != exp_out) begin + `uvm_error("SCBD", $sformatf("ERROR ! out=%0d exp=%0d", item.outp, exp_out)) + end else if (exp_out) begin + `uvm_info("SCBD", $sformatf("PASS ! out=%0d exp=%0d", item.outp, exp_out), UVM_LOW) + end + endfunction + + virtual function void report_phase(uvm_phase phase); + super.report_phase(phase); + + if (!seen_1011 || !seen_1100) + `uvm_error( + "SCBD", $sformatf( + "Both patterns were not observed (seen_1011=%0d seen_1100=%0d)", seen_1011, seen_1100)) + endfunction +endclass diff --git a/homework_2/SRC/tb.sv b/homework_2/SRC/tb.sv index fd98597..40ecafc 100644 --- a/homework_2/SRC/tb.sv +++ b/homework_2/SRC/tb.sv @@ -1,36 +1,35 @@ -`include "uvm_macros.svh"
-import uvm_pkg::*;
-
-`include "interface.sv"
-`include "item.sv"
-`include "gen_item_seq.sv"
-`include "monitor.sv"
-`include "scoreboard.sv"
-`include "driver.sv"
-`include "agent.sv"
-`include "env.sv"
-`include "base_test.sv"
-
-
-
-`define LENGTH 4
-
-module tb;
- reg clk;
-
- always #10 clk =~ clk;
- des_if _if (clk);
-
- duv u0 ( .clk(clk),
- .rstn(_if.rstn),
- .in(_if.in),
- .out(_if.out));
-
-
- initial begin
- clk <= 0;
- uvm_config_db#(virtual des_if)::set(null, "uvm_test_top", "des_vif", _if);
- run_test("test_1011");
- end
- endmodule
-
+`include "uvm_macros.svh" +import uvm_pkg::*; + +`include "interface.sv" +`include "item.sv" +`include "gen_item_seq.sv" +`include "monitor.sv" +`include "scoreboard.sv" +`include "driver.sv" +`include "agent.sv" +`include "env.sv" +`include "base_test.sv" + +module tb; + reg clk; + + always #10 clk = ~clk; + + des_if _if (clk); + + duv u0 ( + .clk (clk), + .reset(_if.reset), + .inp (_if.inp), + .outp (_if.outp) + ); + + initial begin + clk <= 0; + + uvm_config_db#(virtual des_if)::set(null, "uvm_test_top", "des_vif", _if); + + run_test("test_both_patterns"); + end +endmodule |