diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/apb_m_intf.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/apb_m_intf.yaml new file mode 100644 index 00000000..097ef17a --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/apb_m_intf.yaml @@ -0,0 +1,99 @@ +uvmf: + interfaces: + "apb": + clock: "pclk" + reset: "presetn" + veloce_ready: "True" + reset_assertion_level: 'False' + parameters: + - name: "APB_ADDR_WIDTH" + type: "int" + value: '32' + - name: "APB_DATA_WIDTH" + type: "int" + value: '32' + - name: "STRB_LEN" + type: "int" + value: "APB_ADDR_WIDTH/8" + ports: + - dir: "output" + name: "psel" + reset_value: '''b0' + width: '16' + - dir: "output" + name: "penable" + reset_value: '''b0' + width: '1' + - dir: "output" + name: "paddr" + reset_value: '''b0' + width: "APB_ADDR_WIDTH" + - dir: "output" + name: "pwdata" + reset_value: '''b0' + width: "APB_DATA_WIDTH" + - dir: "output" + name: "pwrite" + reset_value: '''b0' + width: '1' + - dir: "output" + name: "pstrb" + reset_value: '''b0' + width: 'STRB_LEN' + - dir: "output" + name: "pprot" + reset_value: '''b0' + width: '3' + - dir: "input" + name: "prdata" + reset_value: '''b0' + width: "APB_DATA_WIDTH" + - dir: "input" + name: "pready" + reset_value: '0' + width: '1' + - dir: "input" + name: "pslverr" + reset_value: '0' + width: '1' + transaction_vars: + - iscompare: 'False' + isrand: 'True' + name: "psel" + type: "bit" + - iscompare: 'True' + isrand: 'True' + name: "penable" + type: "bit" + - iscompare: 'True' + isrand: 'True' + name: "paddr" + type: "bit [APB_ADDR_WIDTH-1:0]" + - iscompare: 'True' + isrand: 'True' + name: "pwdata" + type: "bit [APB_DATA_WIDTH-1:0]" + - iscompare: 'True' + isrand: 'True' + name: "pwrite" + type: "bit" + - iscompare: 'True' + isrand: 'True' + name: "pstrb" + type: "bit [STRB_LEN:0]" + - iscompare: 'True' + isrand: 'True' + name: "pprot" + type: "bit [3:0]" + - iscompare: 'True' + isrand: 'False' + name: "prdata" + type: "APB_DATA_WIDTH" + - iscompare: 'True' + isrand: 'False' + name: "pready" + type: "bit" + - iscompare: 'True' + isrand: 'False' + name: "pslverr" + type: "bit" diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/axi_m_intf.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/axi_m_intf.yaml new file mode 100644 index 00000000..cf5b3c82 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/axi_m_intf.yaml @@ -0,0 +1,396 @@ +uvmf: + interfaces: + axi: + clock: axi_clk + reset: rst + reset_assertion_level: "False" + veloce_ready: "True" + parameters: + - name: "AW_WIDTH" + type: "int" + value: "32" + - name: "LEN" + type: "int" + value: "8" + - name: "DATA_WIDTH" + type: "int" + value: "32" + - name: "X" + type: "int" + value: "16" + ports: + # write address channel + - name: awvalid + dir: output + width: "1" + - name: awready + dir: input + width: "1" + - name: awaddr + dir: output + width: "AW_WIDTH" + - name: awsize + dir: output + width: "3" + - name: awburst + dir: output + width: "2" + - name: awcache + dir: output + width: "4" + - name: awprot + dir: output + width: "3" + - name: awid + dir: output + width: "X" + - name: awlen + dir: output + width: "LEN" + - name: awlock + dir: output + width: "1" + - name: awqos + dir: output + width: "4" + - name: awregion + dir: output + width: "4" + - name: awuser + dir: output + width: "X" + # write data channel + - name: wvalid + dir: output + width: "1" + - name: wready + dir: input + width: "1" + - name: wlast + dir: output + width: "1" + - name: wdata + dir: output + width: "DATA_WIDTH" + - name: wstrb + dir: output + width: "data_width/8" + - name: wid + dir: output + width: "X" + - name: wuser + dir: output + width: "X" + # write response channel + - name: bwvalid + dir: input + width: "1" + - name: bwready + dir: output + width: "1" + - name: bresp + dir: input + width: "2" + - name: bid + dir: input + width: "X" + - name: buser + dir: input + width: "X" + #read address channel + - name: arvalid + dir: output + width: "1" + - name: aready + dir: input + width: "1" + - name: araddr + dir: output + width: "AW_WIDTH" + - name: arsize + dir: output + width: "3" + - name: arburst + dir: output + width: "2" + - name: arcache + dir: output + width: "4" + - name: arprot + dir: output + width: "3" + - name: arid + dir: output + width: "X" + - name: arlen + dir: output + width: "LEN" + - name: arlock + dir: output + width: "1" + - name: arqos + dir: output + width: "4" + - name: aregion + dir: output + width: "4" + - name: aruser + dir: output + width: "X" + #read data channel + - name: rvalid + dir: input + width: "1" + - name: rready + dir: output + width: "1" + - name: rlast + dir: input + width: "1" + - name: rdata + dir: input + width: "DATA_WIDTH" + - name: rid + dir: input + width: "X" + - name: ruser + dir: input + width: "X" + - name: rresp + dir: input + width: "2" + transaction_vars: + #write address channel + - name: "awvalid" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "awready" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "awaddr" + type: "bit [AW_WIDTH-1:0]" + isrand: "True" + iscompare: "False" + + - name: "awsize" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "awburst" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "awcache" + type: "bit" + isrand: "true" + iscompare: "False" + + - name: "awprot" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "awid" + type: "bit [X-1:0]" + isrand: "True" + iscompare: "False" + + - name: "awlen" + type: "bit [LEN-1:0]" + isrand: "True" + iscompare: "False" + + - name: "awlock" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "awqos" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "awregion" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "awuser" + type: "bit [X-1:0]" + isrand: "true" + iscompare: "False" + + #write data channel + - name: "wvalid" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "wready" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "wlast" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "wdata" + type: "bit [DATA_WIDTH-1:0]" + isrand: "True" + iscompare: "False" + + - name: "wstrb" + type: "bit [DATA_WIDTH/8-1]" + isrand: "True" + iscompare: "False" + + - name: "wid" + type: "bit [X-1:0]" + isrand: "False" + iscompare: "False" + + - name: "wuser" + type: "bit [X-1:0]" + isrand: "True" + iscompare: "False" + + #write response channel + - name: "bwvalid" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "bwready" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "bresp" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "bid" + type: "bit [X-1:0]" + isrand: "False" + iscompare: "False" + + - name: "buser" + type: "bit [X-1:0]" + isrand: "True" + iscompare: "False" + + #ready address channel + - name: "arvalid" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "aready" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "araddr" + type: "bit [AW_WIDTH-1:0]" + isrand: "True" + iscompare: "False" + + - name: "arsize" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "arburst" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "arcache" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "arprot" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "arid" + type: "bit [X-1:0]" + isrand: "True" + iscompare: "False" + + - name: "arlen" + type: "bit [LEN-1:0]" + isrand: "True" + iscompare: "False" + + - name: "arlock" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "arqos" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "aregion" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "aruser" + type: "bit [X-1:0]" + isrand: "True" + iscompare: "False" + + #ready data channel + + - name: "rvalid" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "rready" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "rlast" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "rdata" + type: "bit [DATA_WIDTH-1:0]" + isrand: "True" + iscompare: "False" + + - name: "rid" + type: "bit [X-1:0]" + isrand: "True" + iscompare: "False" + + - name: "ruser" + type: "bit [X-1:0]" + isrand: "True" + iscompare: "False" + + - name: "rresp" + type: "bit" + isrand: "True" + iscompare: "False" + + + + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/axi_s_intf.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/axi_s_intf.yaml new file mode 100644 index 00000000..61431731 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/axi_s_intf.yaml @@ -0,0 +1,396 @@ +uvmf: + interfaces: + axi: + clock: axi_clk + reset: rst + reset_assertion_level: "False" + veloce_ready: "True" + parameters: + - name: "AW_WIDTH"" + type: "int" + value: "32" + - name: "LEN" + type: "int" + value: "8" + - name: "DATA_WIDTH" + type: "int" + value: "32" + - name: "X" + type: "int" + value: "16" + ports: + # write address channel + - name: awvalid + dir: input + width: "1" + - name: awready + dir: output + width: "1" + - name: awaddr + dir: input + width: "AW_WIDTH"" + - name: awsize + dir: input + width: "3" + - name: awburst + dir: input + width: "2" + - name: awcache + dir: input + width: "4" + - name: awprot + dir: input + width: "3" + - name: awid + dir: input + width: "X" + - name: awlen + dir: input + width: "LEN" + - name: awlock + dir: input + width: "1" + - name: awqos + dir: input + width: "4" + - name: awregion + dir: input + width: "4" + - name: awuser + dir: input + width: "X" + # write data channel + - name: wvalid + dir: input + width: "1" + - name: wready + dir: output + width: "1" + - name: wlast + dir: input + width: "1" + - name: wdata + dir: input + width: "DATA_WIDTH" + - name: wstrb + dir: input + width: "data_width/8" + - name: wid + dir: input + width: "X" + - name: wuser + dir: input + width: "X" + # write response channel + - name: bwvalid + dir: output + width: "1" + - name: bwready + dir: output + width: "1" + - name: bresp + dir: input + width: "2" + - name: bid + dir: output + width: "X" + - name: buser + dir: output + width: "X" + #read address channel + - name: arvalid + dir: input + width: "1" + - name: aready + dir: output + width: "1" + - name: araddr + dir: input + width: "AW_WIDTH"" + - name: arsize + dir: input + width: "3" + - name: arburst + dir: input + width: "2" + - name: arcache + dir: input + width: "4" + - name: arprot + dir: input + width: "3" + - name: arid + dir: input + width: "X" + - name: arlen + dir: input + width: "LEN" + - name: arlock + dir: input + width: "1" + - name: arqos + dir: input + width: "4" + - name: aregion + dir: input + width: "4" + - name: aruser + dir: input + width: "X" + #read data channel + - name: rvalid + dir: output + width: "1" + - name: rready + dir: input + width: "1" + - name: rlast + dir: output + width: "1" + - name: rdata + dir: output + width: "DATA_WIDTH" + - name: rid + dir: output + width: "X" + - name: ruser + dir: output + width: "X" + - name: rresp + dir: output + width: "2" + transaction_vars: + #write address channel + - name: "awvalid" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "awready" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "awaddr" + type: "bit [AW_WIDTH-1:0]" + isrand: "False" + iscompare: "False" + + - name: "awsize" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "awburst" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "awcache" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "awprot" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "awid" + type: "bit [X-1:0]" + isrand: "False" + iscompare: "False" + + - name: "awlen" + type: "bit [LEN-1:0]" + isrand: "False" + iscompare: "False" + + - name: "awlock" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "awqos" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "awregion" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "awuser" + type: "bit [X-1:0]" + isrand: "False" + iscompare: "False" + + #write data channel + - name: "wvalid" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "wready" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "wlast" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "wdata" + type: "bit [DATA_WIDTH-1:0]" + isrand: "False" + iscompare: "False" + + - name: "wstrb" + type: "bit [DATA_WIDTH/8-1]" + isrand: "False" + iscompare: "False" + + - name: "wid" + type: "bit [X-1:0]" + isrand: "False" + iscompare: "False" + + - name: "wuser" + type: "bit [X-1:0]" + isrand: "False" + iscompare: "False" + + #write response channel + - name: "bwvalid" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "bwready" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "bresp" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "bid" + type: "bit [X-1:0]" + isrand: "False" + iscompare: "False" + + - name: "buser" + type: "bit [X-1:0]" + isrand: "True" + iscompare: "False" + + #ready address channeli + - name: "arvalid" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "aready" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "araddr" + type: "bit [AW_WIDTH-1:0]" + isrand: "True" + iscompare: "False" + + - name: "arsize" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "arburst" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "arcache" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "arprot" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "arid" + type: "bit [X-1:0]" + isrand: "True" + iscompare: "False" + + - name: "arlen" + type: "bit [LEN-1:0]" + isrand: "True" + iscompare: "False" + + - name: "arlock" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "arqos" + type: "bit" + isrand: "True" + iscompare: "False" + + - name: "aregion" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "aruser" + type: "bit [X-1:0]" + isrand: "False" + iscompare: "False" + + #ready data channel + + - name: "rvalid" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "rready" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "rlast" + type: "bit" + isrand: "False" + iscompare: "False" + + - name: "rdata" + type: "bit [DATA_WIDTH-1:0]" + isrand: "True" + iscompare: "False" + + - name: "rid" + type: "bit [X-1:0]" + isrand: "True" + iscompare: "False" + + - name: "ruser" + type: "bit [X-1:0]" + isrand: "True" + iscompare: "False" + + - name: "rresp" + type: "bit" + isrand: "True" + iscompare: "False" + + + + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/block_1/block1_env.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/block_1/block1_env.yaml new file mode 100644 index 00000000..ffb0cf6d --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/block_1/block1_env.yaml @@ -0,0 +1,28 @@ +uvmf: + benches: + "block_1" : + ## Specify the top-level block + top_env: "block_1" + clock_half_period: "5ns" + reset_assertion_level: "True" + reset_duration: "200ns" + environments: + "block_1" : + agents : + - name: "apb_master" + type: "apb" + initiator_responder: "INITIATOR" + - name: "axi_master1" + type: "axi_m" + initiator_responder: "INITIATOR" + - name: "axi_master2" + type: "axi_m" + initiator_responder: "INITIATOR" + - name: "spi_slave" + type: "spi_s" + initiator_responder: "RESPONDER" + analysis_components : + - name: "block_1_pred" + type: "block_1_predictor" + - name: "block_1_sb" + type: "block_1_scoreboard" diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/block_1/block1_util.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/block_1/block1_util.yaml new file mode 100644 index 00000000..12eb277f --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/block_1/block1_util.yaml @@ -0,0 +1,41 @@ +uvmf: + util_components: + block_1_predictor: + analysis_exports: + - name: apb_ae + type: 'apb_transaction #(.APB_DATA_WIDTH(APB_DATA_WIDTH), .APB_ADDR_WIDTH(APB_ADDR_WIDTH))' + - name: axi_1_ae + type: 'axi_transaction #(.AW_WIDTH(AW_WIDTH), .LEN(LEN), .DATA_WIDTH(DATA_WIDTH), .X(X))' + - name: axi_2_ae + type: 'axi_transaction #(.AW_WIDTH(AW_WIDTH), .LEN(LEN), .DATA_WIDTH(DATA_WIDTH), .X(X))' + analysis_ports: + - name: pre_to_sco_ap + type: 'spi_s_transaction' + existing_library_component: 'True' + parameters: + - name: APB_DATA_WIDTH + type: int + value: '32' + - name: APB_ADDR_WIDTH + type: int + value: '32' + - name: AW_WIDTH + type: int + value: '32' + - name: DATA_WIDTH + type: int + value: '32' + - name: LEN + type: int + value: '32' + - name: X + type: int + value: '16' + type: predictor + block_1_scoreboard: + analysis_exports: + - name: spi_ae + type: 'spi_s_transaction' + - name: sco_from_pre_ae + type: 'spi_s_transaction' + type: scoreboard diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/block_2/block2_env.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/block_2/block2_env.yaml new file mode 100644 index 00000000..3934e4d9 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/block_2/block2_env.yaml @@ -0,0 +1,38 @@ +uvmf: + benches: + "block_2" : + top_env: "block_2" + clock_half_period: "5ns" + reset_assertion_level: "True" + reset_duration: "200ns" + active_passive: + - bfm_name: "spi_master" + value: "ACTIVE" + - bfm_name: "wb_slave" + value: "PASSIVE" + environments: + "block_2" : + agents : + - name: "spi_master" + type: "spi_m" + initiator_responder: "INITIATOR" + - name: "wb_slave" + type: "wb_s" + initiator_responder: "RESPONDER" + analysis_components : + - name: "block_2_pred" + type: "block_2_predictor" + - name: "block_2_sb" + type: "block_2_scoreboard" + tlm_connections: + - driver: "spi_master.monitored_ap" + receiver: "block_2_pred.spi_ae" + - driver: "wb_slave.monitored_ap" + receiver: "block_2_sb.wb_ae" + - driver: "block_2_pred.pred_to_sco_ap" + receiver: "block_2_sb.sco_from_pred_ae" + config_vars : + - name: "has_scoreboard" + type : "bit" + isrand : "False" + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/block_2/block2_util.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/block_2/block2_util.yaml new file mode 100644 index 00000000..ebf62361 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/block_2/block2_util.yaml @@ -0,0 +1,18 @@ +uvmf: + util_components: + block_2_predictor: + analysis_exports: + - name: spi_ae + type: 'spi_m_transaction' + analysis_ports: + - name: pre_to_sco_ap + type: 'wb_s_transaction' + existing_library_component: 'True' + type: predictor + block_2_scoreboard: + analysis_exports: + - name: wb_ae + type: 'wb_s_transaction' + - name: sco_from_pre_ae + type: 'wb_s_transaction' + type: scoreboard diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_m_intf.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/spi_m_intf.yaml new file mode 100644 index 00000000..3f2fe239 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_m_intf.yaml @@ -0,0 +1,36 @@ +uvmf: + interfaces: + "spi_m": + clock: "sck" + reset: "rst" + reset_assertion_level: "True" + ports: + - name: "sclk" + dir: "output" + width: "1" + reset_value: "'b0" + - name: "ss" + dir: "output" + width: "1" + reset_value: "'b0" + - name: "mosi" + dir: "output" + width: "bit [7:0]" + reset_value: "'b0" + - name: "miso" + dir: "input" + width: "bit [7:0]" + reset_value: "'b0" + transaction_vars: + - iscompare: "True" + isrand: "True" + name: "ssel" + type: "bit" + - iscompare: "True" + isrand: "True" + name: "mosi" + type: "bit [7:0]" + - iscompare: "True" + isrand: "False" + name: "miso" + type: "bit [7:0]" diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/.svproject b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/.svproject new file mode 100644 index 00000000..a60de9cf --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/.svproject @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/Makefile b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/Makefile new file mode 100644 index 00000000..6e92ac2c --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/Makefile @@ -0,0 +1,62 @@ +# spi interface packages source +# pragma uvmf custom additional begin +# pragma uvmf custom additional end + +spi_PKG = \ + +incdir+$(UVMF_VIP_LIBRARY_HOME)/interface_packages/spi_pkg \ + -F $(UVMF_VIP_LIBRARY_HOME)/interface_packages/spi_pkg/spi_filelist_hvl.f + +spi_PKG_HDL = \ + +incdir+$(UVMF_VIP_LIBRARY_HOME)/interface_packages/spi_pkg \ + -F $(UVMF_VIP_LIBRARY_HOME)/interface_packages/spi_pkg/spi_filelist_hdl.f + +spi_PKG_XRTL = \ + +incdir+$(UVMF_VIP_LIBRARY_HOME)/interface_packages/spi_pkg \ + -F $(UVMF_VIP_LIBRARY_HOME)/interface_packages/spi_pkg/spi_filelist_xrtl.f + +COMP_spi_PKG_TGT_0 = q_comp_spi_pkg +COMP_spi_PKG_TGT_1 = v_comp_spi_pkg +COMP_spi_PKG_TGT = $(COMP_spi_PKG_TGT_$(USE_VELOCE)) + +comp_spi_pkg: $(COMP_spi_PKG_TGT) + +q_comp_spi_pkg: + $(HDL_COMP_CMD) $(spi_PKG_HDL) + $(HVL_COMP_CMD) $(spi_PKG) + $(HDL_COMP_CMD) $(spi_PKG_XRTL) + +v_comp_spi_pkg: + $(HVL_COMP_CMD) $(spi_PKG_HDL) + $(HVL_COMP_CMD) $(spi_PKG) + $(VELANALYZE_HVL_CMD) $(spi_PKG_HDL) + $(VELANALYZE_HVL_CMD) $(spi_PKG) + $(HDL_COMP_CMD) $(spi_PKG_XRTL) + +ifeq ($(MTI_VCO_MODE),64) + GCC_COMP_ARCH = -m64 +else + GCC_COMP_ARCH = -m32 +endif + +C_FILE_COMPILE_LIST_spi_pkg = \ + +O_FILE_COMPILE_LIST_spi_pkg = $(notdir $(C_FILE_COMPILE_LIST_spi_pkg:.c=.o)) + +GCC_COMP_ARGS_spi_pkg += -I$(UVMF_VIP_LIBRARY_HOME)/interface_packages/spi_pkg/dpi \ + -fPIC + +GCC_LINK_ARGS_spi_pkg += \ + \ + -o .so + +comp_spi_pkg_c_files: + @echo "--------------------------------" + @echo "Compiling Interface C source" + @echo "--------------------------------" + gcc $(GCC_COMP_ARCH) $(GCC_COMP_ARGS_spi_pkg) $(C_FILE_COMPILE_LIST_spi_pkg) + @echo "--------------------------------" + @echo "Linking Interface C objects into a shared object" + @echo "--------------------------------" + gcc $(GCC_COMP_ARCH) $(GCC_LINK_ARGS_spi_pkg) $(O_FILE_COMPILE_LIST_spi_pkg) + @echo "--------------------------------" + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/compile.do b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/compile.do new file mode 100644 index 00000000..644f2b84 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/compile.do @@ -0,0 +1,14 @@ +# Tcl do file for compile of spi interface + +# pragma uvmf custom additional begin +# pragma uvmf custom additional end + + +vlog -sv -timescale 1ps/1ps -suppress 2223,2286 +incdir+$env(UVMF_VIP_LIBRARY_HOME)/interface_packages/spi_pkg \ + -F $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/spi_pkg/spi_filelist_hdl.f + +vlog -sv -timescale 1ps/1ps -suppress 2223,2286 +incdir+$env(UVMF_VIP_LIBRARY_HOME)/interface_packages/spi_pkg \ + -F $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/spi_pkg/spi_filelist_hvl.f + +vlog -sv -timescale 1ps/1ps -suppress 2223,2286 +incdir+$env(UVMF_VIP_LIBRARY_HOME)/interface_packages/spi_pkg \ + -F $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/spi_pkg/spi_filelist_xrtl.f \ No newline at end of file diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/doc/spi_if_wiring.pdf b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/doc/spi_if_wiring.pdf new file mode 100644 index 00000000..9ed883ab Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/doc/spi_if_wiring.pdf differ diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi.compile b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi.compile new file mode 100644 index 00000000..f10c71a6 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi.compile @@ -0,0 +1,3 @@ +needs: + - spi_hvl.compile + - spi_hdl.compile diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_bfm.vinfo b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_bfm.vinfo new file mode 100644 index 00000000..678dc7f5 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_bfm.vinfo @@ -0,0 +1,6 @@ +@use $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg_hdl.vinfo +@use spi_pkg_hdl.vinfo ++incdir+@vinfodir +src/spi_if.sv +src/spi_driver_bfm.sv +src/spi_monitor_bfm.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_common.compile b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_common.compile new file mode 100644 index 00000000..5b4df47e --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_common.compile @@ -0,0 +1,9 @@ +incdir: + - ${uvm_path}/src + - . + +needs: + - $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg_hdl.compile + +src: + - spi_pkg_hdl.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_filelist_hdl.f b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_filelist_hdl.f new file mode 100644 index 00000000..e8cb92ed --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_filelist_hdl.f @@ -0,0 +1 @@ +$UVMF_VIP_LIBRARY_HOME/interface_packages/spi_pkg/spi_pkg_hdl.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_filelist_hvl.f b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_filelist_hvl.f new file mode 100644 index 00000000..92f98f2b --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_filelist_hvl.f @@ -0,0 +1 @@ +$UVMF_VIP_LIBRARY_HOME/interface_packages/spi_pkg/spi_pkg.sv \ No newline at end of file diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_filelist_xrtl.f b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_filelist_xrtl.f new file mode 100644 index 00000000..0e06eef6 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_filelist_xrtl.f @@ -0,0 +1,4 @@ +$UVMF_VIP_LIBRARY_HOME/interface_packages/spi_pkg/spi_pkg_hdl.sv +$UVMF_VIP_LIBRARY_HOME/interface_packages/spi_pkg/src/spi_if.sv +$UVMF_VIP_LIBRARY_HOME/interface_packages/spi_pkg/src/spi_monitor_bfm.sv +$UVMF_VIP_LIBRARY_HOME/interface_packages/spi_pkg/src/spi_driver_bfm.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_hdl.compile b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_hdl.compile new file mode 100644 index 00000000..9a4f4399 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_hdl.compile @@ -0,0 +1,7 @@ +src: + - src/spi_if.sv + - src/spi_driver_bfm.sv + - src/spi_monitor_bfm.sv + +needs: + - spi_common.compile diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_hvl.compile b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_hvl.compile new file mode 100644 index 00000000..424e2970 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_hvl.compile @@ -0,0 +1,6 @@ +needs: + - $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg.compile + - spi_common.compile + +src: + - spi_pkg.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg.sv b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg.sv new file mode 100644 index 00000000..52f6bdba --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg.sv @@ -0,0 +1,81 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// PACKAGE: This file defines all of the files contained in the +// interface package that will run on the host simulator. +// +// CONTAINS: +// - +// - +// - + +// - +// - +// - + +// - +// - +// - + +// - +// - +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +package spi_pkg; + + import uvm_pkg::*; + import uvmf_base_pkg_hdl::*; + import uvmf_base_pkg::*; + import spi_pkg_hdl::*; + + `include "uvm_macros.svh" + + // pragma uvmf custom package_imports_additional begin + // pragma uvmf custom package_imports_additional end + + `include "src/spi_macros.svh" + + export spi_pkg_hdl::*; + + + + // Parameters defined as HVL parameters + + `include "src/spi_typedefs.svh" + `include "src/spi_transaction.svh" + + `include "src/spi_configuration.svh" + `include "src/spi_driver.svh" + `include "src/spi_monitor.svh" + + `include "src/spi_transaction_coverage.svh" + `include "src/spi_sequence_base.svh" + `include "src/spi_random_sequence.svh" + + `include "src/spi_responder_sequence.svh" + `include "src/spi2reg_adapter.svh" + + `include "src/spi_agent.svh" + + // pragma uvmf custom package_item_additional begin + `include "src/spi_mem_slave_transaction.svh" + `include "src/spi_mem_slave_transaction_coverage.svh" + `include "src/spi_mem_slave_transaction_viewer.svh" + + `include "src/spi_master_seq.svh" + `include "src/spi_mem_slave_seq.svh" + + + + + // pragma uvmf custom package_item_additional end + +endpackage + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg.vinfo b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg.vinfo new file mode 100644 index 00000000..045dc07e --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg.vinfo @@ -0,0 +1,4 @@ +@use $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg.vinfo +@use spi_pkg_hdl.vinfo ++incdir+@vinfodir +spi_pkg.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg_hdl.sv b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg_hdl.sv new file mode 100644 index 00000000..cc139714 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg_hdl.sv @@ -0,0 +1,35 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// PACKAGE: This file defines all of the files contained in the +// interface package that needs to be compiled and synthesized +// for running on Veloce. +// +// CONTAINS: +// - +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +package spi_pkg_hdl; + + import uvmf_base_pkg_hdl::*; + + // pragma uvmf custom package_imports_additional begin + // pragma uvmf custom package_imports_additional end + + // Parameters defined as HDL parameters + + `include "src/spi_typedefs_hdl.svh" + `include "src/spi_macros.svh" + + // pragma uvmf custom package_item_additional begin + // pragma uvmf custom package_item_additional end + +endpackage + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg_hdl.vinfo b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg_hdl.vinfo new file mode 100644 index 00000000..42093530 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg_hdl.vinfo @@ -0,0 +1,2 @@ +@use $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg_hdl.vinfo +spi_pkg_hdl.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg_sve.F b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg_sve.F new file mode 100644 index 00000000..d2339b7a --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/spi_pkg_sve.F @@ -0,0 +1,10 @@ +// UVM ++incdir+${UVM_HOME}/src +${UVM_HOME}/src/uvm_pkg.sv + +// Common UVMF files +-f ${UVMF_HOME}/common/common_sve.f + ++incdir+. +-f ${UVMF_VIP_LIBRARY_HOME}/interface_packages/spi_pkg/spi_filelist_hdl.f +-f ${UVMF_VIP_LIBRARY_HOME}/interface_packages/spi_pkg/spi_filelist_hvl.f diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi2reg_adapter.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi2reg_adapter.svh new file mode 100644 index 00000000..9779c223 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi2reg_adapter.svh @@ -0,0 +1,103 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This file contains the UVM register adapter for the spi interface. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class spi2reg_adapter extends uvm_reg_adapter; + + `uvm_object_utils( spi2reg_adapter ) + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + //-------------------------------------------------------------------- + // new + //-------------------------------------------------------------------- + function new (string name = "spi2reg_adapter" ); + super.new(name); + // pragma uvmf custom new begin + // UVMF_CHANGE_ME : Configure the adapter regarding byte enables and provides response. + + // Does the protocol the Agent is modeling support byte enables? + // 0 = NO + // 1 = YES + supports_byte_enable = 0; + + // Does the Agent's Driver provide separate response sequence items? + // i.e. Does the driver call seq_item_port.put() + // and do the sequences call get_response()? + // 0 = NO + // 1 = YES + provides_responses = 0; + + + + // pragma uvmf custom new end + + endfunction: new + + //-------------------------------------------------------------------- + // reg2bus + //-------------------------------------------------------------------- + virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw); + + spi_transaction trans_h = spi_transaction ::type_id::create("trans_h"); + + // pragma uvmf custom reg2bus begin + // UVMF_CHANGE_ME : Fill in the reg2bus adapter mapping registe fields to protocol fields. + + //Adapt the following for your sequence item type + // trans_h.op = (rw.kind == UVM_READ) ? WB_READ : WB_WRITE; + //Copy over address + // trans_h.addr = rw.addr; + //Copy over write data + // trans_h.data = rw.data; + + + + + // pragma uvmf custom reg2bus end + + // Return the adapted transaction + return trans_h; + + endfunction: reg2bus + + //-------------------------------------------------------------------- + // bus2reg + //-------------------------------------------------------------------- + virtual function void bus2reg(uvm_sequence_item bus_item, + ref uvm_reg_bus_op rw); + spi_transaction trans_h; + if (!$cast(trans_h, bus_item)) begin + `uvm_fatal("ADAPT","Provided bus_item is not of the correct type") + return; + end + // pragma uvmf custom bus2reg begin + // UVMF_CHANGE_ME : Fill in the bus2reg adapter mapping protocol fields to register fields. + //Adapt the following for your sequence item type + //Copy over instruction type + // rw.kind = (trans_h.op == WB_WRITE) ? UVM_WRITE : UVM_READ; + //Copy over address + // rw.addr = trans_h.addr; + //Copy over read data + // rw.data = trans_h.data; + //Check for errors on the bus and return UVM_NOT_OK if there is an error + // rw.status = UVM_IS_OK; + + + + // pragma uvmf custom bus2reg end + + endfunction: bus2reg + +endclass : spi2reg_adapter diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_agent.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_agent.svh new file mode 100644 index 00000000..a35be3d4 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_agent.svh @@ -0,0 +1,47 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Protocol specific agent class definition +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class spi_agent extends uvmf_parameterized_agent #( + .CONFIG_T(spi_configuration ), + .DRIVER_T(spi_driver ), + .MONITOR_T(spi_monitor ), + .COVERAGE_T(spi_transaction_coverage ), + .TRANS_T(spi_transaction ) + ); + + `uvm_component_utils( spi_agent ) + +// pragma uvmf custom class_item_additional begin +// pragma uvmf custom class_item_additional end + +// **************************************************************************** +// FUNCTION : new() +// This function is the standard SystemVerilog constructor. +// + function new( string name = "", uvm_component parent = null ); + super.new( name, parent ); + endfunction + +// **************************************************************************** + // FUNCTION: build_phase + virtual function void build_phase(uvm_phase phase); + super.build_phase(phase); + if (configuration.active_passive == ACTIVE) begin + // Place sequencer handle into configuration object + // so that it may be retrieved from configuration + // rather than using uvm_config_db + configuration.sequencer = this.sequencer; + end + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_configuration.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_configuration.svh new file mode 100644 index 00000000..a70693e6 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_configuration.svh @@ -0,0 +1,186 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class contains all variables and functions used +// to configure the spi agent and its bfm's. It gets the +// bfm's from the uvm_config_db for use by the agent. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class spi_configuration extends uvmf_parameterized_agent_configuration_base #( + .DRIVER_BFM_BIND_T(virtual spi_driver_bfm ), + .MONITOR_BFM_BIND_T( virtual spi_monitor_bfm )); + + `uvm_object_utils( spi_configuration ) + + + // Sequencer handle populated by agent + uvm_sequencer #(spi_transaction ) sequencer; + + //Constraints for the configuration variables: + + // pragma uvmf custom class_item_additional begin +// SPCR : Serial Peripheral Control Register + bit SPCR_SPIE = 0; // Serial Peripheral Interrupt Enable + bit SPCR_SPE = 0; // Serial Peripheral Enable + bit SPCR_RESERVED = 0; // Reserved field + bit SPCR_MSTR = 1; // Master Mode Select + rand bit SPCR_CPOL = 0; // Clock Polarity + rand bit SPCR_CPHA = 0; // Clock Phase + rand bit [1:0] SPCR_SPR = 0; // SPI Clock Rate Select + +// SPER : Serial Peripheral Extensions Register + bit [1:0] SPER_ICNT = 0; // Serial Peripheral Interrupt Count + bit [3:0] SPER_RESERVED = 0; // Reserved field + rand bit [1:0] SPER_ESPR = 0; // Extended SPI Clock Rate Select + + + + + // pragma uvmf custom class_item_additional end + + covergroup spi_configuration_cg; + // pragma uvmf custom covergroup begin + option.auto_bin_max=1024; + // pragma uvmf custom covergroup end + endgroup + + //******************************************************************* + //******************************************************************* + // Structure used to pass configuration variables to monitor and driver BFM's. + // Use to_struct function to pack variables into structure. + // Use from_struct function to unpack variables from structure. + // This structure is defined in spi_macros.svh + `spi_CONFIGURATION_STRUCT + spi_configuration_s spi_configuration_struct; + //******************************************************************* + // FUNCTION: to_struct() + // This function packs variables into a spi_configuration_s + // structure. The function returns the handle to the spi_configuration_struct. + // This function is defined in spi_macros.svh + `spi_CONFIGURATION_TO_STRUCT_FUNCTION + //******************************************************************* + // FUNCTION: from_struct() + // This function unpacks the struct provided as an argument into + // variables of this class. + // This function is defined in spi_macros.svh + `spi_CONFIGURATION_FROM_STRUCT_FUNCTION + + // **************************************************************************** + // FUNCTION : new() + // This function is the standard SystemVerilog constructor. + // + function new( string name = "" ); + super.new( name ); + // Construct the covergroup for this configuration class + spi_configuration_cg = new; + endfunction + + // **************************************************************************** + // FUNCTION: post_randomize() + // This function is automatically called after the randomize() function + // is executed. + // + function void post_randomize(); + super.post_randomize(); + spi_configuration_cg.sample(); + endfunction + + // **************************************************************************** + // FUNCTION: initialize + // This function causes the configuration to retrieve + // its virtual interface handle from the uvm_config_db. + // This function also makes itself available to its + // agent through the uvm_config_db. + // + // ARGUMENTS: + // uvmf_active_passive_t activity: + // This argument identifies the simulation level + // as either BLOCK, CHIP, SIMULATION, etc. + // + // AGENT_PATH: + // This argument identifies the path to this + // configurations agent. This configuration + // makes itself available to the agent specified + // by agent_path by placing itself into the + // uvm_config_db. + // + // INTERFACE_NAME: + // This argument identifies the string name of + // this configurations BFM's. This string + // name is used to retrieve the driver and + // monitor BFM from the uvm_config_db. + // + virtual function void initialize(uvmf_active_passive_t activity, + string agent_path, + string interface_name); + + super.initialize( activity, agent_path, interface_name); + // The covergroup is given the same name as the interface + spi_configuration_cg.set_inst_name(interface_name); + + // This configuration places itself into the uvm_config_db for the agent, identified by the agent_path variable, to retrieve. + uvm_config_db #( spi_configuration + )::set( null ,agent_path,UVMF_AGENT_CONFIG, this ); + + // This configuration also places itself in the config db using the same identifier used by the interface. This allows users to access + // configuration variables and the interface through the bfm api class rather than directly accessing the BFM. This is useful for + // accessingthe BFM when using Veloce + uvm_config_db #( spi_configuration + )::set( null ,UVMF_CONFIGURATIONS, interface_name, this ); + + spi_configuration_cg.set_inst_name($sformatf("spi_configuration_cg_%s",get_full_name())); + + // pragma uvmf custom initialize begin + // This controls whether or not the agent returns a transaction handle in the driver when calling + // item_done() back into the sequencer or not. If set to 1, a transaction is sent back which means + // the sequence on the other end must use the get_response() part of the driver/sequence API. If + // this doesn't occur, there will eventually be response_queue overflow errors during the test. + return_transaction_response = 1'b0; + + + + + // pragma uvmf custom initialize end + + endfunction + + // **************************************************************************** + // TASK: wait_for_reset + // *[Required]* Blocks until reset is released. The wait_for_reset operation is performed + // by a task in the monitor bfm. + virtual task wait_for_reset(); + monitor_bfm.wait_for_reset(); + endtask + + // **************************************************************************** + // TASK: wait_for_num_clocks + // *[Required]* Blocks until specified number of clocks have elapsed. The wait_for_num_clocks + // operation is performed by a task in the monitor bfm. + virtual task wait_for_num_clocks(int clocks); + monitor_bfm.wait_for_num_clocks(clocks); + endtask + + // **************************************************************************** + // FUNCTION : convert2string() + // This function is used to convert variables in this class into a string for log messaging. + // + virtual function string convert2string (); + // pragma uvmf custom convert2string begin + return $sformatf(""); + // pragma uvmf custom convert2string end + endfunction + + // **************************************************************************** + // FUNCTION: get_sequencer + function uvm_sequencer #(spi_transaction) get_sequencer(); + return sequencer; + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_driver.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_driver.svh new file mode 100644 index 00000000..50ebb98b --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_driver.svh @@ -0,0 +1,88 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class passes transactions between the sequencer +// and the BFM driver interface. It accesses the driver BFM +// through the bfm handle. This driver +// passes transactions to the driver BFM through the access +// task. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class spi_driver extends uvmf_driver_base #( + .CONFIG_T(spi_configuration ), + .BFM_BIND_T(virtual spi_driver_bfm ), + .REQ(spi_transaction ), + .RSP(spi_transaction )); + + `uvm_component_utils( spi_driver ) +//******************************************************************* +// Macros that define structs located in spi_macros.svh +//******************************************************************* +// Initiator macro used by spi_driver and spi_driver_bfm +// to communicate initiator driven data to spi_driver_bfm. +`spi_INITIATOR_STRUCT + spi_initiator_s spi_initiator_struct; +//******************************************************************* +// Responder macro used by spi_driver and spi_driver_bfm +// to communicate Responder driven data to spi_driver_bfm. +`spi_RESPONDER_STRUCT + spi_responder_s spi_responder_struct; + +// pragma uvmf custom class_item_additional begin +// pragma uvmf custom class_item_additional end + +// **************************************************************************** +// This function is the standard SystemVerilog constructor. +// + function new( string name = "", uvm_component parent=null ); + super.new( name, parent ); + endfunction + +// **************************************************************************** +// This function sends configuration object variables to the driver BFM +// using the configuration struct. +// + virtual function void configure(input CONFIG_T cfg); + bfm.configure( cfg.to_struct() ); + endfunction + +// **************************************************************************** +// This function places a handle to this class in the proxy variable in the +// driver BFM. This allows the driver BFM to call tasks and function within this class. +// + virtual function void set_bfm_proxy_handle(); + bfm.proxy = this; endfunction + +// **************************************************************************** +// This task is called by the run_phase in uvmf_driver_base. + virtual task access( inout REQ txn ); +// pragma uvmf custom access begin + if (configuration.initiator_responder==RESPONDER) begin + // Complete current transfer and wait for next transfer + bfm.set_miso_data(txn.to_responder_struct()); + bfm.get_mosi_data(spi_initiator_struct); + // Unpack information about initiated transfer received by this responder + txn.from_initiator_struct(spi_initiator_struct); + end else begin + // Initiate a transfer and get response + bfm.initiate_and_get_response( + txn.to_initiator_struct(), + spi_responder_struct + ); + // Unpack transfer response information received by this initiator + txn.from_responder_struct(spi_responder_struct); + end + + + +// pragma uvmf custom access end + endtask + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_driver_bfm.sv b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_driver_bfm.sv new file mode 100644 index 00000000..fdee6367 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_driver_bfm.sv @@ -0,0 +1,294 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This interface performs the spi signal driving. It is +// accessed by the uvm spi driver through a virtual interface +// handle in the spi configuration. It drives the singals passed +// in through the port connection named bus of type spi_if. +// +// Input signals from the spi_if are assigned to an internal input +// signal with a _i suffix. The _i signal should be used for sampling. +// +// The input signal connections are as follows: +// bus.signal -> signal_i +// +// This bfm drives signals with a _o suffix. These signals +// are driven onto signals within spi_if based on INITIATOR/RESPONDER and/or +// ARBITRATION/GRANT status. +// +// The output signal connections are as follows: +// signal_o -> bus.signal +// +// +// Interface functions and tasks used by UVM components: +// +// configure: +// This function gets configuration attributes from the +// UVM driver to set any required BFM configuration +// variables such as 'initiator_responder'. +// +// initiate_and_get_response: +// This task is used to perform signaling activity for initiating +// a protocol transfer. The task initiates the transfer, using +// input data from the initiator struct. Then the task captures +// response data, placing the data into the response struct. +// The response struct is returned to the driver class. +// +// respond_and_wait_for_next_transfer: +// This task is used to complete a current transfer as a responder +// and then wait for the initiator to start the next transfer. +// The task uses data in the responder struct to drive protocol +// signals to complete the transfer. The task then waits for +// the next transfer. Once the next transfer begins, data from +// the initiator is placed into the initiator struct and sent +// to the responder sequence for processing to determine +// what data to respond with. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +import uvmf_base_pkg_hdl::*; +import spi_pkg_hdl::*; +`include "src/spi_macros.svh" + +interface spi_driver_bfm + (spi_if bus); + // The following pragma and additional ones in-lined further below are for running this BFM on Veloce + // pragma attribute spi_driver_bfm partition_interface_xif + // Config value to determine if this is an initiator or a responder + uvmf_initiator_responder_t initiator_responder; + // Custom configuration variables. + // These are set using the configure function which is called during the UVM connect_phase + + tri sck_i; + tri rst_i; + + // Signal list (all signals are capable of being inputs and outputs for the sake + // of supporting both INITIATOR and RESPONDER mode operation. Expectation is that + // directionality in the config file was from the point-of-view of the INITIATOR + + // INITIATOR mode input signals + tri miso_i; + reg miso_o = 'bz; + + // INITIATOR mode output signals + tri mosi_i; + reg mosi_o = 'bz; + + // Bi-directional signals + + + assign sck_i = bus.sck; + assign rst_i = bus.rst; + + // These are signals marked as 'input' by the config file, but the signals will be + // driven by this BFM if put into RESPONDER mode (flipping all signal directions around) + assign miso_i = bus.miso; + assign bus.miso = (initiator_responder == RESPONDER) ? miso_o : 'bz; + + + // These are signals marked as 'output' by the config file, but the outputs will + // not be driven by this BFM unless placed in INITIATOR mode. + assign bus.mosi = (initiator_responder == INITIATOR) ? mosi_o : 'bz; + assign mosi_i = bus.mosi; + + // Proxy handle to UVM driver + spi_pkg::spi_driver proxy; + // pragma tbx oneway proxy.my_function_name_in_uvm_driver + + // **************************************************************************** + // **************************************************************************** + // Macros that define structs located in spi_macros.svh + // **************************************************************************** + // Struct for passing configuration data from spi_driver to this BFM + // **************************************************************************** + `spi_CONFIGURATION_STRUCT + // **************************************************************************** + // Structs for INITIATOR and RESPONDER data flow + //******************************************************************* + // Initiator macro used by spi_driver and spi_driver_bfm + // to communicate initiator driven data to spi_driver_bfm. + `spi_INITIATOR_STRUCT + spi_initiator_s spi_initiator_struct; + // Responder macro used by spi_driver and spi_driver_bfm + // to communicate Responder driven data to spi_driver_bfm. + `spi_RESPONDER_STRUCT + spi_responder_s spi_responder_struct; + + // **************************************************************************** + // Always block used to return signals to reset value upon assertion of reset + always @( posedge rst_i ) + begin + // RESPONDER mode output signals + miso_o <= 'b0; + // INITIATOR mode output signals + mosi_o <= 'b0; + // Bi-directional signals + + end + + // pragma uvmf custom interface_item_additional begin +// **************************************************************************** +/* bit spi_active; + + function void put_spi_dout(input spi_transaction_s spi_txn); // pragma tbx xtf + spi_driver_dout = spi_txn.spi_data; + spi_output <= spi_driver_dout[SPI_XFER_WIDTH-1]; + put_spi_dout_active = 1; + endfunction + + always begin + wait(spi_active); + @(posedge bus.sck); + for (int i=6;i>=0;i--) begin + miso_o <= miso_data[i]; @(posedge bus.sck); + end + spi_active = 0; + end + +// **************************************************************************** + task get_spi_din(input spi_transaction_s spi_txn, + output bit [SPI_XFER_WIDTH-1:0] spi_driver_din); // pragma tbx xtf + @(posedge bus.sck); + spi_driver_din[SPI_XFER_WIDTH-1]=spi_input; + for (int i=(SPI_XFER_WIDTH-2);i>=0;i--) begin + @(posedge bus.sck) spi_driver_din[i]=spi_input; + end + endtask +*/ + + + + // pragma uvmf custom interface_item_additional end + + //****************************************************************** + // The configure() function is used to pass agent configuration + // variables to the driver BFM. It is called by the driver within + // the agent at the beginning of the simulation. It may be called + // during the simulation if agent configuration variables are updated + // and the driver BFM needs to be aware of the new configuration + // variables. + // + + function void configure(spi_configuration_s spi_configuration_arg); // pragma tbx xtf + initiator_responder = spi_configuration_arg.initiator_responder; + // pragma uvmf custom configure begin + // pragma uvmf custom configure end + endfunction + +// pragma uvmf custom initiate_and_get_response begin +// **************************************************************************** +// UVMF_CHANGE_ME +// This task is used by an initator. The task first initiates a transfer then +// waits for the responder to complete the transfer. + task initiate_and_get_response( + // This argument passes transaction variables used by an initiator + // to perform the initial part of a protocol transfer. The values + // come from a sequence item created in a sequence. + input spi_initiator_s spi_initiator_struct, + // This argument is used to send data received from the responder + // back to the sequence item. The sequence item is returned to the sequence. + output spi_responder_s spi_responder_struct + );// pragma tbx xtf + // + // Members within the spi_initiator_struct: + // spi_dir_t dir ; + // bit [7:0] mosi_data ; + // bit [7:0] miso_data ; + // Members within the spi_responder_struct: + // spi_dir_t dir ; + // bit [7:0] mosi_data ; + // bit [7:0] miso_data ; + // + // Reference code; + // How to wait for signal value + // while (control_signal == 1'b1) @(posedge sck_i); + // + // How to assign a responder struct member, named xyz, from a signal. + // All available input signals listed. + // spi_responder_struct.xyz = mosi_i; // + // spi_responder_struct.xyz = miso_i; // + // How to assign a signal, named xyz, from an initiator struct member. + // All available input signals listed. + // Notice the _o. Those are storage variables that allow for procedural assignment. + // mosi_o <= spi_initiator_struct.xyz; // + // miso_o <= spi_initiator_struct.xyz; // + // Initiate a transfer using the data received. + @(posedge sck_i); + @(posedge sck_i); + // Wait for the responder to complete the transfer then place the responder data into + // spi_responder_struct. + @(posedge sck_i); + @(posedge sck_i); + endtask + + + +// pragma uvmf custom initiate_and_get_response end + +// pragma uvmf custom respond_and_wait_for_next_transfer begin +bit [7:0] miso_data; +bit miso_valid = 0; + + function void set_miso_data( + // This argument passes transaction variables used by a responder + // to complete a protocol transfer. The values come from a sequence item. + input spi_responder_s spi_responder_struct + );// pragma tbx xtf + miso_data = spi_responder_struct.miso_data; + miso_o <= miso_data[7]; + miso_valid =1; + endfunction + + always begin + wait(miso_valid); + @(posedge sck_i); + for (int i=6;i>=0;i--) begin + miso_o <= miso_data[i]; + @(posedge sck_i); + end + miso_valid = 0; + end +// **************************************************************************** +// The first_transfer variable is used to prevent completing a transfer in the +// first call to this task. For the first call to this task, there is not +// current transfer to complete. +bit first_transfer=1; + +// UVMF_CHANGE_ME +// This task is used by a responder. The task first completes the current +// transfer in progress then waits for the initiator to start the next transfer. + task get_mosi_data( + // This argument is used to send data received from the initiator + // back to the sequence item. The sequence determines how to respond. + output spi_initiator_s spi_initiator_struct + );// pragma tbx xtf + // Variables within the spi_initiator_struct: + // spi_dir_t dir ; + // bit [7:0] mosi_data ; + // bit [7:0] miso_data ; + // Variables within the spi_responder_struct: + // spi_dir_t dir ; + // bit [7:0] mosi_data ; + // bit [7:0] miso_data ; + + @(posedge sck_i); + spi_initiator_struct.mosi_data[7] = mosi_i; + for (int i=6;i>=0;i--) begin + @(posedge sck_i); + spi_initiator_struct.mosi_data[i] = mosi_i; + end + endtask + + + +// pragma uvmf custom respond_and_wait_for_next_transfer end + + +endinterface diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_if.sv b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_if.sv new file mode 100644 index 00000000..c47d99a5 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_if.sv @@ -0,0 +1,66 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This interface contains the spi interface signals. +// It is instantiated once per spi bus. Bus Functional Models, +// BFM's named spi_driver_bfm, are used to drive signals on the bus. +// BFM's named spi_monitor_bfm are used to monitor signals on the +// bus. This interface signal bundle is passed in the port list of +// the BFM in order to give the BFM access to the signals in this +// interface. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// This template can be used to connect a DUT to these signals +// +// .dut_signal_port(spi_bus.mosi), // Agent output +// .dut_signal_port(spi_bus.miso), // Agent input + +import uvmf_base_pkg_hdl::*; +import spi_pkg_hdl::*; + +interface spi_if + + ( + input tri sck, + input tri rst, + inout tri mosi, + inout tri miso + ); + +modport monitor_port + ( + input sck, + input rst, + input mosi, + input miso + ); + +modport initiator_port + ( + input sck, + input rst, + output mosi, + input miso + ); + +modport responder_port + ( + input sck, + input rst, + input mosi, + output miso + ); + + +// pragma uvmf custom interface_item_additional begin +// pragma uvmf custom interface_item_additional end + +endinterface + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_macros.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_macros.svh new file mode 100644 index 00000000..a78d1af5 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_macros.svh @@ -0,0 +1,139 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This file contains macros used with the spi package. +// These macros include packed struct definitions. These structs are +// used to pass data between classes, hvl, and BFM's, hdl. Use of +// structs are more efficient and simpler to modify. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + +// **************************************************************************** +// When changing the contents of this struct, be sure to update the to_struct +// and from_struct methods defined in the macros below that are used in +// the spi_configuration class. +// + `define spi_CONFIGURATION_STRUCT \ +typedef struct packed { \ + uvmf_active_passive_t active_passive; \ + uvmf_initiator_responder_t initiator_responder; \ + } spi_configuration_s; + + `define spi_CONFIGURATION_TO_STRUCT_FUNCTION \ + virtual function spi_configuration_s to_struct();\ + spi_configuration_struct = \ + {\ + this.active_passive,\ + this.initiator_responder\ + };\ + return ( spi_configuration_struct );\ + endfunction + + `define spi_CONFIGURATION_FROM_STRUCT_FUNCTION \ + virtual function void from_struct(spi_configuration_s spi_configuration_struct);\ + {\ + this.active_passive,\ + this.initiator_responder \ + } = spi_configuration_struct;\ + endfunction + +// **************************************************************************** +// When changing the contents of this struct, be sure to update the to_monitor_struct +// and from_monitor_struct methods of the spi_transaction class. +// + `define spi_MONITOR_STRUCT typedef struct packed { \ + spi_dir_t dir ; \ + bit [7:0] mosi_data ; \ + bit [7:0] miso_data ; \ + } spi_monitor_s; + + `define spi_TO_MONITOR_STRUCT_FUNCTION \ + virtual function spi_monitor_s to_monitor_struct();\ + spi_monitor_struct = \ + { \ + this.dir , \ + this.mosi_data , \ + this.miso_data \ + };\ + return ( spi_monitor_struct);\ + endfunction\ + + `define spi_FROM_MONITOR_STRUCT_FUNCTION \ + virtual function void from_monitor_struct(spi_monitor_s spi_monitor_struct);\ + {\ + this.dir , \ + this.mosi_data , \ + this.miso_data \ + } = spi_monitor_struct;\ + endfunction + +// **************************************************************************** +// When changing the contents of this struct, be sure to update the to_initiator_struct +// and from_initiator_struct methods of the spi_transaction class. +// Also update the comments in the driver BFM. +// + `define spi_INITIATOR_STRUCT typedef struct packed { \ + spi_dir_t dir ; \ + bit [7:0] mosi_data ; \ + bit [7:0] miso_data ; \ + } spi_initiator_s; + + `define spi_TO_INITIATOR_STRUCT_FUNCTION \ + virtual function spi_initiator_s to_initiator_struct();\ + spi_initiator_struct = \ + {\ + this.dir , \ + this.mosi_data , \ + this.miso_data \ + };\ + return ( spi_initiator_struct);\ + endfunction + + `define spi_FROM_INITIATOR_STRUCT_FUNCTION \ + virtual function void from_initiator_struct(spi_initiator_s spi_initiator_struct);\ + {\ + this.dir , \ + this.mosi_data , \ + this.miso_data \ + } = spi_initiator_struct;\ + endfunction + +// **************************************************************************** +// When changing the contents of this struct, be sure to update the to_responder_struct +// and from_responder_struct methods of the spi_transaction class. +// Also update the comments in the driver BFM. +// + `define spi_RESPONDER_STRUCT typedef struct packed { \ + spi_dir_t dir ; \ + bit [7:0] mosi_data ; \ + bit [7:0] miso_data ; \ + } spi_responder_s; + + `define spi_TO_RESPONDER_STRUCT_FUNCTION \ + virtual function spi_responder_s to_responder_struct();\ + spi_responder_struct = \ + {\ + this.dir , \ + this.mosi_data , \ + this.miso_data \ + };\ + return ( spi_responder_struct);\ + endfunction + + `define spi_FROM_RESPONDER_STRUCT_FUNCTION \ + virtual function void from_responder_struct(spi_responder_s spi_responder_struct);\ + {\ + this.dir , \ + this.mosi_data , \ + this.miso_data \ + } = spi_responder_struct;\ + endfunction +// pragma uvmf custom additional begin +// pragma uvmf custom additional end diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_master_seq.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_master_seq.svh new file mode 100644 index 00000000..63417102 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_master_seq.svh @@ -0,0 +1,63 @@ +//---------------------------------------------------------------------- +// Copyright 2013 Mentor Graphics Corporation +// All Rights Reserved Worldwide +// +// Licensed under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in +// writing, software distributed under the License is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See +// the License for the specific language governing +// permissions and limitations under the License. +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// Mentor Graphics Inc +//---------------------------------------------------------------------- +// Project : spi interface agent +// Unit : Sequence library +// File : spi_master_seq.svh +//---------------------------------------------------------------------- +// Creation Date : 05.12.2011 +//---------------------------------------------------------------------- +// Description: This file contains the sequence used for master +// operations on the spi bus. +// +//---------------------------------------------------------------------- +// +class spi_master_seq extends spi_sequence_base; + + `uvm_object_utils( spi_master_seq ) + + REQ mosi_transaction; + RSP miso_transaction; + + function new(string name = "" ); + super.new( name ); + mosi_transaction=spi_transaction::type_id::create("mosi_transaction"); + endfunction + + function void set_mosi(bit [7:0] data); + mosi_transaction.mosi_data = data; + endfunction + + function bit [7:0] get_miso(); + return miso_transaction.miso_data; + endfunction + + function string convert2string(); + return ({"MOSI:",mosi_transaction.convert2string(),"MISO:",miso_transaction.convert2string()}); + endfunction + + virtual task body(); + start_item(mosi_transaction); + finish_item(mosi_transaction); + //get_response(miso_transaction); + endtask + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_mem_slave_seq.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_mem_slave_seq.svh new file mode 100644 index 00000000..20d77526 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_mem_slave_seq.svh @@ -0,0 +1,69 @@ +//---------------------------------------------------------------------- +// Copyright 2013 Mentor Graphics Corporation +// All Rights Reserved Worldwide +// +// Licensed under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in +// writing, software distributed under the License is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See +// the License for the specific language governing +// permissions and limitations under the License. +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// Mentor Graphics Inc +//---------------------------------------------------------------------- +// Project : spi interface agent +// Unit : Sequence library +// File : spi_mem_slave_seq.svh +//---------------------------------------------------------------------- +// Creation Date : 05.12.2011 +//---------------------------------------------------------------------- +// Description: This sequence is used to model a memory slave on the +// spi bus. +// +//---------------------------------------------------------------------- +// +class spi_mem_slave_seq extends spi_sequence_base; + + `uvm_object_utils( spi_mem_slave_seq ) + + spi_mem_slave_transaction req_transaction; + // mem_slave_transaction rsp_transaction; + + bit [7:0] next_req; + bit [3:0] mem [7:0]; + + function new(string name = "" ); + super.new( name ); + endfunction + + virtual task body(); + forever begin + req_transaction=spi_mem_slave_transaction::type_id::create("req_transaction"); + req_transaction.dir = MISO; + req_transaction.status = next_req[7]; + req_transaction.addr = next_req[6:4]; + req_transaction.data = next_req[3:0]; + req_transaction.pack_fields(); + start_item(req_transaction); + finish_item(req_transaction); + // get_response(rsp_transaction); + if (req_transaction.mosi_data[7] == SPI_SLAVE_WRITE ) begin + mem[req_transaction.mosi_data[6:4]]=req_transaction.mosi_data[3:0]; + next_req = {1'b1, req_transaction.mosi_data[6:0]}; + `uvm_info("SEQ",{"WRITE:",req_transaction.convert2string()},UVM_HIGH) + end else begin // SPI_SLAVE_READ + next_req = {1'b1, req_transaction.mosi_data[6:4], mem[req_transaction.mosi_data[6:4]]}; + `uvm_info("SEQ",{"READ:",req_transaction.convert2string()},UVM_HIGH) + end + end + endtask + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_mem_slave_transaction.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_mem_slave_transaction.svh new file mode 100644 index 00000000..f81d641b --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_mem_slave_transaction.svh @@ -0,0 +1,110 @@ +//---------------------------------------------------------------------- +// Copyright 2013 Mentor Graphics Corporation +// All Rights Reserved Worldwide +// +// Licensed under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in +// writing, software distributed under the License is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See +// the License for the specific language governing +// permissions and limitations under the License. +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// Mentor Graphics Inc +//---------------------------------------------------------------------- +// Project : spi interface agent +// Unit : Transaction +// File : spi_transaction.svh +//---------------------------------------------------------------------- +// Creation Date : 05.12.2011 +//---------------------------------------------------------------------- +// Description: This class defines the variables required for an spi +// memory slave transaction. Class variables to be displayed in +// waveform transaction viewing are added to the transaction viewing +// stream in the add_to_wave function. +// +//---------------------------------------------------------------------- +// +class spi_mem_slave_transaction extends spi_transaction; + + `uvm_object_utils( spi_mem_slave_transaction ) + + spi_op_t op; + bit [2:0] addr; + bit [3:0] data; + bit status; + bit command; + + +// **************************************************************************** + function new( string name = "" ); + super.new( name ); + endfunction + +// **************************************************************************** + virtual function string convert2string(); + string msg; + $sformat(msg,"op:%s dir:%s command:%h status:%h addr:0x%h data:0x%h",op, dir, command,status,addr,data); + return { msg, super.convert2string()}; + endfunction + +//******************************************************************* + function void do_copy (uvm_object rhs); + spi_transaction RHS; + assert($cast(RHS,rhs)); + super.do_copy(rhs); + unpack_fields(); + endfunction : do_copy + +//******************************************************************* + virtual function void do_print(uvm_printer printer); + $display(convert2string()); + endfunction + +//******************************************************************* + virtual function bit do_compare (uvm_object rhs, uvm_comparer comparer); + spi_transaction RHS; + if (!$cast(RHS,rhs)) + return 0; + + pack_fields(); + return (super.do_compare(rhs, comparer)); + + endfunction : do_compare + +// **************************************************************************** + virtual function void unpack_fields(); + if (mosi_data[7]== 1) op = SPI_SLAVE_WRITE; + else op = SPI_SLAVE_READ; + command = mosi_data[7]; + addr = mosi_data[6:4]; + data = mosi_data[3:0]; + endfunction + +// **************************************************************************** + virtual function void pack_fields(); + //mosi_data = { command, addr, data}; + miso_data = { status, addr, data}; + endfunction + +// **************************************************************************** + virtual function void add_to_wave( int transaction_viewing_stream_h ); + transaction_view_h = $begin_transaction(transaction_viewing_stream_h,op.name(),start_time); + if ( op == SPI_SLAVE_WRITE ) $add_color( transaction_view_h, "cyan" ); + else if ( op == SPI_SLAVE_READ ) $add_color( transaction_view_h, "brown" ); + $add_attribute( transaction_view_h, dir, "dir" ); + $add_attribute( transaction_view_h, op, "op" ); + $add_attribute( transaction_view_h, addr, "addr" ); + $add_attribute( transaction_view_h, data, "data" ); + $end_transaction(transaction_view_h,end_time); + $free_transaction(transaction_view_h); + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_mem_slave_transaction_coverage.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_mem_slave_transaction_coverage.svh new file mode 100644 index 00000000..738e480c --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_mem_slave_transaction_coverage.svh @@ -0,0 +1,70 @@ +//---------------------------------------------------------------------- +// Copyright 2013 Mentor Graphics Corporation +// All Rights Reserved Worldwide +// +// Licensed under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in +// writing, software distributed under the License is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See +// the License for the specific language governing +// permissions and limitations under the License. +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// Mentor Graphics Inc +//---------------------------------------------------------------------- +// Project : spi interface agent +// Unit : Transaction coverage +// File : spi_transaction_coverage.svh +//---------------------------------------------------------------------- +// Creation Date : 05.12.2011 +//---------------------------------------------------------------------- +// Description: This class records spi memory slave transaction information using +// a covergroup named spi_mem_slave_transaction_cg. An instance of this +// coverage component is instantiated in the uvmf_parameterized_agent +// if the has_coverage flag is set. +// +//---------------------------------------------------------------------- +// +class spi_mem_slave_transaction_coverage extends uvm_subscriber#(spi_transaction); + + `uvm_component_utils( spi_mem_slave_transaction_coverage ) + + spi_op_t op; + bit [2:0] addr; + bit [3:0] data; + +// **************************************************************************** + covergroup spi_mem_slave_transaction_cg; + coverpoint op; + coverpoint addr; + coverpoint data; + addr_x_data: cross addr, data; + op_x_addr: cross op, addr; + endgroup + + function new(string name="", uvm_component parent=null); + super.new(name,parent); + spi_mem_slave_transaction_cg=new; + spi_mem_slave_transaction_cg.set_inst_name($sformatf("spi_mem_slave_transaction_cg_%s",get_full_name())); + endfunction + + virtual function void write (T t); + `uvm_info("COV","Received transaction",UVM_LOW); + if ( t.dir == MOSI ) begin + if ( t.mosi_data[7] == 1'b1 ) op = SPI_SLAVE_WRITE; + else op = SPI_SLAVE_READ; + addr = t.mosi_data[6:4]; + data = t.mosi_data[3:0]; + spi_mem_slave_transaction_cg.sample(); + end + + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_mem_slave_transaction_viewer.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_mem_slave_transaction_viewer.svh new file mode 100644 index 00000000..0efaeb8d --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_mem_slave_transaction_viewer.svh @@ -0,0 +1,63 @@ +//---------------------------------------------------------------------- +// Copyright 2013 Mentor Graphics Corporation +// All Rights Reserved Worldwide +// +// Licensed under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in +// writing, software distributed under the License is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See +// the License for the specific language governing +// permissions and limitations under the License. +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// Mentor Graphics Inc +//---------------------------------------------------------------------- +// Project : spi interface agent +// Unit : Transaction viewer +// File : spi_transaction_coverage.svh +//---------------------------------------------------------------------- +// Creation Date : 05.12.2011 +//---------------------------------------------------------------------- +// Description: This class creates a waveform transaction viewing stream +// for spi mem slave transactions from the spi agent +// +//---------------------------------------------------------------------- +// +class spi_mem_slave_transaction_viewer extends uvm_subscriber#(.T(spi_transaction)); + + `uvm_component_utils( spi_mem_slave_transaction_viewer ) + + spi_mem_slave_transaction spi_mem_transaction=new; + + spi_configuration configuration; + + // Handle used for transaction viewing + int transaction_viewing_stream; + + function new(string name="", uvm_component parent=null); + super.new(name,parent); + endfunction + + // FUNCTION: start_of_simulation_phase + virtual function void start_of_simulation_phase(uvm_phase phase); + if (configuration.enable_transaction_viewing) + transaction_viewing_stream = $create_transaction_stream({"..",get_full_name(),".","txn_stream"}); + endfunction + + virtual function void write (T t); + `uvm_info("VIEW","Received transaction",UVM_LOW); + if ( configuration.enable_transaction_viewing ) begin + spi_mem_transaction.do_copy(t); + spi_mem_transaction.unpack_fields(); + spi_mem_transaction.add_to_wave(transaction_viewing_stream); + end + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_monitor.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_monitor.svh new file mode 100644 index 00000000..d095e540 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_monitor.svh @@ -0,0 +1,81 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class receives spi transactions observed by the +// spi monitor BFM and broadcasts them through the analysis port +// on the agent. It accesses the monitor BFM through the monitor +// task. This UVM component captures transactions +// for viewing in the waveform viewer if the +// enable_transaction_viewing flag is set in the configuration. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class spi_monitor extends uvmf_monitor_base #( + .CONFIG_T(spi_configuration ), + .BFM_BIND_T(virtual spi_monitor_bfm ), + .TRANS_T(spi_transaction )); + + `uvm_component_utils( spi_monitor ) + +// Structure used to pass data from monitor BFM to monitor class in agent. +// Use to_monitor_struct function to pack transaction variables into structure. +// Use from_monitor_struct function to unpack transaction variables from structure. +`spi_MONITOR_STRUCT + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + +// **************************************************************************** +// This function is the standard SystemVerilog constructor. +// + function new( string name = "", uvm_component parent = null ); + super.new( name, parent ); + endfunction + +// **************************************************************************** +// This function sends configuration object variables to the monitor BFM +// using the configuration struct. +// + virtual function void configure(input CONFIG_T cfg); + bfm.configure( cfg.to_struct() ); + + endfunction + +// **************************************************************************** +// This function places a handle to this class in the proxy variable in the +// monitor BFM. This allows the monitor BFM to call the notify_transaction +// function within this class. +// + virtual function void set_bfm_proxy_handle(); + bfm.proxy = this; endfunction + +// *************************************************************************** + virtual task run_phase(uvm_phase phase); + // Start monitor BFM thread and don't call super.run() in order to + // override the default monitor proxy 'pull' behavior with the more + // emulation-friendly BFM 'push' approach using the notify_transaction + // function below + bfm.start_monitoring(); + endtask + +// ************************************************************************** + +// This function is called by the monitor BFM. It receives data observed by the +// monitor BFM. Data is passed using the spi_monitor_struct. + virtual function void notify_transaction(input spi_monitor_s spi_monitor_struct); + trans = new("trans"); + trans.start_time = time_stamp; + trans.end_time = $time; + time_stamp = trans.end_time; + + trans.from_monitor_struct(spi_monitor_struct); + analyze(trans); + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_monitor_bfm.sv b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_monitor_bfm.sv new file mode 100644 index 00000000..ddd9c48a --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_monitor_bfm.sv @@ -0,0 +1,163 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This interface performs the spi signal monitoring. +// It is accessed by the uvm spi monitor through a virtual +// interface handle in the spi configuration. It monitors the +// signals passed in through the port connection named bus of +// type spi_if. +// +// Input signals from the spi_if are assigned to an internal input +// signal with a _i suffix. The _i signal should be used for sampling. +// +// The input signal connections are as follows: +// bus.signal -> signal_i +// +// Interface functions and tasks used by UVM components: +// monitor(inout TRANS_T txn); +// This task receives the transaction, txn, from the +// UVM monitor and then populates variables in txn +// from values observed on bus activity. This task +// blocks until an operation on the spi bus is complete. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +import uvmf_base_pkg_hdl::*; +import spi_pkg_hdl::*; + +`include "src/spi_macros.svh" + +interface spi_monitor_bfm + ( spi_if bus ); + // The pragma below and additional ones in-lined further down are for running this BFM on Veloce + // pragma attribute spi_monitor_bfm partition_interface_xif + + // Structure used to pass transaction data from monitor BFM to monitor class in agent. +`spi_MONITOR_STRUCT + spi_monitor_s spi_monitor_struct; + + // Structure used to pass configuration data from monitor class to monitor BFM. + `spi_CONFIGURATION_STRUCT + + + // Config value to determine if this is an initiator or a responder + uvmf_initiator_responder_t initiator_responder; + // Custom configuration variables. + // These are set using the configure function which is called during the UVM connect_phase + + tri sck_i; + tri rst_i; + tri mosi_i; + tri miso_i; + assign sck_i = bus.sck; + assign rst_i = bus.rst; + assign mosi_i = bus.mosi; + assign miso_i = bus.miso; + + // Proxy handle to UVM monitor + spi_pkg::spi_monitor proxy; + // pragma tbx oneway proxy.notify_transaction + + // pragma uvmf custom interface_item_additional begin + // pragma uvmf custom interface_item_additional end + + //****************************************************************** + task wait_for_reset();// pragma tbx xtf + @(posedge sck_i) ; + do_wait_for_reset(); + endtask + + // **************************************************************************** + task do_wait_for_reset(); + wait ( rst_i == 0 ) ; + @(posedge sck_i) ; + endtask + + //****************************************************************** + + task wait_for_num_clocks(input int unsigned count); // pragma tbx xtf + @(posedge sck_i); + + repeat (count-1) @(posedge sck_i); + endtask + + //****************************************************************** + event go; + function void start_monitoring();// pragma tbx xtf + -> go; + endfunction + + // **************************************************************************** + initial begin + @go; + forever begin + @(posedge sck_i); + do_monitor( spi_monitor_struct ); + + + proxy.notify_transaction( spi_monitor_struct ); + + end + end + + //****************************************************************** + // The configure() function is used to pass agent configuration + // variables to the monitor BFM. It is called by the monitor within + // the agent at the beginning of the simulation. It may be called + // during the simulation if agent configuration variables are updated + // and the monitor BFM needs to be aware of the new configuration + // variables. + // + function void configure(spi_configuration_s spi_configuration_arg); // pragma tbx xtf + initiator_responder = spi_configuration_arg.initiator_responder; + // pragma uvmf custom configure begin + // pragma uvmf custom configure end + endfunction + + + // **************************************************************************** + + task do_monitor(output spi_monitor_s spi_monitor_struct); + // UVMF_CHANGE_ME : Implement protocol monitoring. The commented reference code + // below are examples of how to capture signal values and assign them to + // structure members. All available input signals are listed. The 'while' + // code example shows how to wait for a synchronous flow control signal. This + // task should return when a complete transfer has been observed. Once this task is + // exited with captured values, it is then called again to wait for and observe + // the next transfer. One clock cycle is consumed between calls to do_monitor. + // + // Available struct members: + // // spi_monitor_struct.dir + // // spi_monitor_struct.mosi_data + // // spi_monitor_struct.miso_data + // // + // Reference code; + // How to wait for signal value + // while (control_signal == 1'b1) @(posedge sck_i); + // + // How to assign a struct member, named xyz, from a signal. + // All available input signals listed. + // spi_monitor_struct.xyz = mosi_i; // + // spi_monitor_struct.xyz = miso_i; // + // pragma uvmf custom do_monitor begin + spi_monitor_struct.mosi_data[7] = mosi_i; + spi_monitor_struct.miso_data[7] = miso_i; + for (int i=6;i>=0;i--) begin + @(posedge sck_i); + spi_monitor_struct.mosi_data[i] = mosi_i; + spi_monitor_struct.miso_data[i] = miso_i; + end + + + + // pragma uvmf custom do_monitor end + endtask + + +endinterface diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_random_sequence.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_random_sequence.svh new file mode 100644 index 00000000..5e5fe665 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_random_sequence.svh @@ -0,0 +1,50 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This sequences randomizes the spi transaction and sends it +// to the UVM driver. +// +// This sequence constructs and randomizes a spi_transaction. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class spi_random_sequence + extends spi_sequence_base ; + + `uvm_object_utils( spi_random_sequence ) + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + //***************************************************************** + function new(string name = ""); + super.new(name); + endfunction: new + + // **************************************************************************** + // TASK : body() + // This task is automatically executed when this sequence is started using the + // start(sequencerHandle) task. + // + task body(); + begin + // Construct the transaction + req=spi_transaction::type_id::create("req"); + start_item(req); + // Randomize the transaction + if(!req.randomize()) `uvm_fatal("SEQ", "spi_random_sequence::body()-spi_transaction randomization failed") + // Send the transaction to the spi_driver_bfm via the sequencer and spi_driver. + finish_item(req); + `uvm_info("SEQ", {"Response:",req.convert2string()},UVM_MEDIUM) + end + + endtask + +endclass: spi_random_sequence diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_responder_sequence.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_responder_sequence.svh new file mode 100644 index 00000000..d5c3adc1 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_responder_sequence.svh @@ -0,0 +1,48 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class can be used to provide stimulus when an interface +// has been configured to run in a responder mode. It +// will never finish by default, always going back to the driver +// and driver BFM for the next transaction with which to respond. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class spi_responder_sequence + extends spi_sequence_base ; + + `uvm_object_utils( spi_responder_sequence ) + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + function new(string name = "spi_responder_sequence"); + super.new(name); + endfunction + + task body(); + req=spi_transaction::type_id::create("req"); + forever begin + start_item(req); + finish_item(req); + // pragma uvmf custom body begin + // UVMF_CHANGE_ME : Do something here with the resulting req item. The + // finish_item() call above will block until the req transaction is ready + // to be handled by the responder sequence. + // If this was an item that required a response, the expectation is + // that the response should be populated within this transaction now. + `uvm_info("SEQ",$sformatf("Processed txn: %s",req.convert2string()),UVM_HIGH) + + + + // pragma uvmf custom body end + end + endtask + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_sequence_base.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_sequence_base.svh new file mode 100644 index 00000000..802d2ea2 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_sequence_base.svh @@ -0,0 +1,95 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This file contains the class used as the base class for all sequences +// for this interface. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class spi_sequence_base extends uvmf_sequence_base #( + .REQ(spi_transaction ), + .RSP(spi_transaction )); + + `uvm_object_utils( spi_sequence_base ) + + // variables + typedef spi_transaction spi_transaction_req_t; + spi_transaction_req_t req; + typedef spi_transaction spi_transaction_rsp_t; + spi_transaction_rsp_t rsp; + + // Event for identifying when a response was received from the sequencer + event new_rsp; + + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + // **************************************************************************** + // TASK : get_responses() + // This task recursively gets sequence item responses from the sequencer. + // + virtual task get_responses(); + fork + begin + // Block until new rsp available + get_response(rsp); + // New rsp received. Indicate to sequence using event. + ->new_rsp; + // Display the received response transaction + `uvm_info("SEQ", {"New response transaction:",rsp.convert2string()}, UVM_MEDIUM) + end + join_none + endtask + + // **************************************************************************** + // TASK : pre_body() + // This task is called automatically when start is called with call_pre_post set to 1 (default). + // By calling get_responses() within pre_body() any derived sequences are automatically + // processing response transactions. + // + virtual task pre_body(); + // pragma uvmf custom pre_body begin + get_responses(); + // pragma uvmf custom pre_body end + endtask + + // **************************************************************************** + // TASK : body() + // This task is called automatically when start is called. This sequence sends + // a req sequence item to the sequencer identified as an argument in the call + // to start. + // + virtual task body(); + // pragma uvmf custom body begin + start_item(req); + finish_item(req); + + + + // pragma uvmf custom body end + endtask + + // **************************************************************************** + // FUNCTION : new() + // This function is the standard SystemVerilog constructor. + // + function new( string name =""); + super.new( name ); + // pragma uvmf custom new begin + req = spi_transaction_req_t::type_id::create("req"); + rsp = spi_transaction_rsp_t::type_id::create("rsp"); + + + + // pragma uvmf custom new end + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_transaction.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_transaction.svh new file mode 100644 index 00000000..5214fcd4 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_transaction.svh @@ -0,0 +1,190 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class defines the variables required for an spi +// transaction. Class variables to be displayed in waveform transaction +// viewing are added to the transaction viewing stream in the add_to_wave +// function. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class spi_transaction extends uvmf_transaction_base; + + `uvm_object_utils( spi_transaction ) + + spi_dir_t dir ; + bit [7:0] mosi_data ; + bit [7:0] miso_data ; + + //Constraints for the transaction variables: + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + //******************************************************************* + //******************************************************************* + // Macros that define structs and associated functions are + // located in spi_macros.svh + + //******************************************************************* + // Monitor macro used by spi_monitor and spi_monitor_bfm + // This struct is defined in spi_macros.svh + `spi_MONITOR_STRUCT + spi_monitor_s spi_monitor_struct; + //******************************************************************* + // FUNCTION: to_monitor_struct() + // This function packs transaction variables into a spi_monitor_s + // structure. The function returns the handle to the spi_monitor_struct. + // This function is defined in spi_macros.svh + `spi_TO_MONITOR_STRUCT_FUNCTION + //******************************************************************* + // FUNCTION: from_monitor_struct() + // This function unpacks the struct provided as an argument into transaction + // variables of this class. + // This function is defined in spi_macros.svh + `spi_FROM_MONITOR_STRUCT_FUNCTION + + //******************************************************************* + // Initiator macro used by spi_driver and spi_driver_bfm + // to communicate initiator driven data to spi_driver_bfm. + // This struct is defined in spi_macros.svh + `spi_INITIATOR_STRUCT + spi_initiator_s spi_initiator_struct; + //******************************************************************* + // FUNCTION: to_initiator_struct() + // This function packs transaction variables into a spi_initiator_s + // structure. The function returns the handle to the spi_initiator_struct. + // This function is defined in spi_macros.svh + `spi_TO_INITIATOR_STRUCT_FUNCTION + //******************************************************************* + // FUNCTION: from_initiator_struct() + // This function unpacks the struct provided as an argument into transaction + // variables of this class. + // This function is defined in spi_macros.svh + `spi_FROM_INITIATOR_STRUCT_FUNCTION + + //******************************************************************* + // Responder macro used by spi_driver and spi_driver_bfm + // to communicate Responder driven data to spi_driver_bfm. + // This struct is defined in spi_macros.svh + `spi_RESPONDER_STRUCT + spi_responder_s spi_responder_struct; + //******************************************************************* + // FUNCTION: to_responder_struct() + // This function packs transaction variables into a spi_responder_s + // structure. The function returns the handle to the spi_responder_struct. + // This function is defined in spi_macros.svh + `spi_TO_RESPONDER_STRUCT_FUNCTION + //******************************************************************* + // FUNCTION: from_responder_struct() + // This function unpacks the struct provided as an argument into transaction + // variables of this class. + // This function is defined in spi_macros.svh + `spi_FROM_RESPONDER_STRUCT_FUNCTION + // **************************************************************************** + // FUNCTION : new() + // This function is the standard SystemVerilog constructor. + // + function new( string name = "" ); + super.new( name ); + endfunction + + // **************************************************************************** + // FUNCTION: convert2string() + // This function converts all variables in this class to a single string for + // logfile reporting. + // + virtual function string convert2string(); + // pragma uvmf custom convert2string begin + // UVMF_CHANGE_ME : Customize format if desired. + return $sformatf("dir:0x%x mosi_data:0x%x miso_data:0x%x ",dir,mosi_data,miso_data); + + + + // pragma uvmf custom convert2string end + endfunction + + //******************************************************************* + // FUNCTION: do_print() + // This function is automatically called when the .print() function + // is called on this class. + // + virtual function void do_print(uvm_printer printer); + // pragma uvmf custom do_print begin + // UVMF_CHANGE_ME : Current contents of do_print allows for the use of UVM 1.1d, 1.2 or P1800.2. + // Update based on your own printing preference according to your preferred UVM version + $display(convert2string()); + + + + // pragma uvmf custom do_print end + endfunction + + //******************************************************************* + // FUNCTION: do_compare() + // This function is automatically called when the .compare() function + // is called on this class. + // + virtual function bit do_compare (uvm_object rhs, uvm_comparer comparer); + spi_transaction RHS; + if (!$cast(RHS,rhs)) return 0; + // UVMF_CHANGE_ME : Eliminate comparison of variables not to be used for compare + return (super.do_compare(rhs,comparer) + &&(this.mosi_data == RHS.mosi_data) + &&(this.miso_data == RHS.miso_data) + ); + endfunction + + //******************************************************************* + // FUNCTION: do_copy() + // This function is automatically called when the .copy() function + // is called on this class. + // + virtual function void do_copy (uvm_object rhs); + spi_transaction RHS; + assert($cast(RHS,rhs)); + super.do_copy(rhs); + this.dir = RHS.dir; + this.mosi_data = RHS.mosi_data; + this.miso_data = RHS.miso_data; + endfunction + + // **************************************************************************** + // FUNCTION: add_to_wave() + // This function is used to display variables in this class in the waveform + // viewer. The start_time and end_time variables must be set before this + // function is called. If the start_time and end_time variables are not set + // the transaction will be hidden at 0ns on the waveform display. + // + virtual function void add_to_wave(int transaction_viewing_stream_h); + `ifdef QUESTA + if (transaction_view_h == 0) begin + transaction_view_h = $begin_transaction(transaction_viewing_stream_h,"spi_transaction",start_time); + end + super.add_to_wave(transaction_view_h); + // pragma uvmf custom add_to_wave begin + // UVMF_CHANGE_ME : Color can be applied to transaction entries based on content, example below + // case() + // 1 : $add_color(transaction_view_h,"red"); + // default : $add_color(transaction_view_h,"grey"); + // endcase + // UVMF_CHANGE_ME : Eliminate transaction variables not wanted in transaction viewing in the waveform viewer + $add_attribute(transaction_view_h,dir,"dir"); + $add_attribute(transaction_view_h,mosi_data,"mosi_data"); + $add_attribute(transaction_view_h,miso_data,"miso_data"); + + + + // pragma uvmf custom add_to_wave end + $end_transaction(transaction_view_h,end_time); + $free_transaction(transaction_view_h); + `endif // QUESTA + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_transaction_coverage.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_transaction_coverage.svh new file mode 100644 index 00000000..818e8ed5 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_transaction_coverage.svh @@ -0,0 +1,70 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class records spi transaction information using +// a covergroup named spi_transaction_cg. An instance of this +// coverage component is instantiated in the uvmf_parameterized_agent +// if the has_coverage flag is set. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class spi_transaction_coverage extends uvm_subscriber #(.T(spi_transaction )); + + `uvm_component_utils( spi_transaction_coverage ) + + T coverage_trans; + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + // **************************************************************************** + covergroup spi_transaction_cg; + // pragma uvmf custom covergroup begin + // UVMF_CHANGE_ME : Add coverage bins, crosses, exclusions, etc. according to coverage needs. + option.auto_bin_max=1024; + option.per_instance=1; + dir: coverpoint coverage_trans.dir; + mosi_data: coverpoint coverage_trans.mosi_data; + miso_data: coverpoint coverage_trans.miso_data; + + + + // pragma uvmf custom covergroup end + endgroup + + // **************************************************************************** + // FUNCTION : new() + // This function is the standard SystemVerilog constructor. + // + function new(string name="", uvm_component parent=null); + super.new(name,parent); + spi_transaction_cg=new; + endfunction + + // **************************************************************************** + // FUNCTION : build_phase() + // This function is the standard UVM build_phase. + // + function void build_phase(uvm_phase phase); + spi_transaction_cg.set_inst_name($sformatf("spi_transaction_cg_%s",get_full_name())); + endfunction + + // **************************************************************************** + // FUNCTION: write (T t) + // This function is automatically executed when a transaction arrives on the + // analysis_export. It copies values from the variables in the transaction + // to local variables used to collect functional coverage. + // + virtual function void write (T t); + `uvm_info("COV","Received transaction",UVM_HIGH); + coverage_trans = t; + spi_transaction_cg.sample(); + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_typedefs.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_typedefs.svh new file mode 100644 index 00000000..b78302a6 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_typedefs.svh @@ -0,0 +1,20 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This file contains defines and typedefs to be compiled for use in +// the simulation running on the host server when using Veloce. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + + +// pragma uvmf custom additional begin +// pragma uvmf custom additional end + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_typedefs_hdl.svh b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_typedefs_hdl.svh new file mode 100644 index 00000000..e4863057 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/src/spi_typedefs_hdl.svh @@ -0,0 +1,23 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This file contains defines and typedefs to be compiled for use in +// the simulation running on the emulator when using Veloce. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + + +typedef enum {SPI_SLAVE_READ, SPI_SLAVE_WRITE} spi_op_t; +typedef enum {MOSI, MISO, TO_SPI, FROM_SPI} spi_dir_t; + +// pragma uvmf custom additional begin +// pragma uvmf custom additional end + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/yaml/spi_interface.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/yaml/spi_interface.yaml new file mode 100644 index 00000000..50d444a1 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_pkg/yaml/spi_interface.yaml @@ -0,0 +1,49 @@ +uvmf: + interfaces: + spi: + clock: sck + config_constraints: [] + config_vars: [] + existing_library_component: 'True' + gen_inbound_streaming_driver: 'False' + hdl_pkg_parameters: [] + hdl_typedefs: + - name: spi_op_t + type: enum {SPI_SLAVE_READ, SPI_SLAVE_WRITE} + - name: spi_dir_t + type: enum {MOSI, MISO, TO_SPI, FROM_SPI} + hvl_pkg_parameters: [] + hvl_typedefs: [] + parameters: [] + ports: + - dir: output + name: mosi + reset_value: '''b0' + width: '1' + - dir: input + name: miso + reset_value: '''b0' + width: '1' + reset: rst + reset_assertion_level: 'True' + response_info: + data: [] + operation: 1'b1 + transaction_constraints: [] + transaction_vars: + - iscompare: 'False' + isrand: 'False' + name: dir + type: spi_dir_t + unpacked_dimension: '' + - iscompare: 'True' + isrand: 'False' + name: mosi_data + type: bit [7:0] + unpacked_dimension: '' + - iscompare: 'True' + isrand: 'False' + name: miso_data + type: bit [7:0] + unpacked_dimension: '' + use_dpi_link: 'False' diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/spi_s_intf.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/spi_s_intf.yaml new file mode 100644 index 00000000..f69e1aaa --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/spi_s_intf.yaml @@ -0,0 +1,36 @@ +uvmf: + interfaces: + "spi_s": + clock: "sck" + reset: "rst" + reset_assertion_level: "True" + ports: + - name: "sclk" + dir: "input" + width: "1" + reset_value: "'b0" + - name: "ss" + dir: "input" + width: "1" + reset_value: "'b0" + - name: "mosi" + dir: "input" + width: "bit [7:0]" + reset_value: "'b0" + - name: "miso" + dir: "output" + width: "bit [7:0]" + reset_value: "'b0" + transaction_vars: + - iscompare: "True" + isrand: "False" + name: "ssel" + type: "bit" + - iscompare: "True" + isrand: "False" + name: "mosi" + type: "bit [7:0]" + - iscompare: "True" + isrand: "True" + name: "miso" + type: "bit [7:0]" diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/subsystem.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/subsystem.yaml new file mode 100644 index 00000000..cadba2b2 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/subsystem.yaml @@ -0,0 +1,26 @@ +uvmf: + environments: + "subsys": + subenvs: + - name: "BLOCK_1" + type: "block_1" + - name: "BLOCK_2" + type: "block_2" + analysis_components: + - name: "SUBSYS_PREDICTOR" + type: "subsys_predictor" + - name: "SUBSYS_SCOREBOARD" + type: "subsys_scoreboard" + tlm_connections: + - driver: "block_1.block_1_predictor.pre_to_sco_ap" + receiver: "subsys_predictor.subsys_ae" + - driver: "subsys_predictor.subsys_ap" + receiver: "subsys_scoreboard.subsys_sb_ap" + - driver: "block_2.block_2_predictor.pre_to_sco_ap" + receiver: "subsys_scoreboard.subsys_sb_ap" + + + + + + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/subsystem_utils.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/subsystem_utils.yaml new file mode 100644 index 00000000..cb279399 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/subsystem_utils.yaml @@ -0,0 +1,19 @@ +uvmf: + util_components: + "subsys_predictor": + - type: "predictor" + analysis_exports: + - name: "subsys_ae" + type: "block_1_pred" + analysis_ports: + - name: "subsys_ap" + type: "subsys_scoreboard" + "subsys_scoreboard": + - type: "scoreboard" + analysis_ports: + - name: "subsys_sb_ap" + type: "wb_master_transaction" + + + + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/vinay/block_c_util.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/vinay/block_c_util.yaml new file mode 100644 index 00000000..46afb7b2 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/vinay/block_c_util.yaml @@ -0,0 +1,18 @@ +uvmf: + util_components: + block_3_predictor: + analysis_exports: + - name: wb_ae + type: 'wb_m_transaction' + analysis_ports: + - name: pre_to_sco_ap + type: 'axi_s_transaction' + existing_library_component: 'True' + type: predictor + block_3_scoreboard: + analysis_exports: + - name: axi_ae + type: 'axi_s_transaction' + - name: sco_from_pre_ae + type: 'axi_s_transaction' + type: scoreboard diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_master.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/wb_master.yaml new file mode 100644 index 00000000..5336f27b --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_master.yaml @@ -0,0 +1,98 @@ +uvmf: + interfaces: + wb_m: + clock: "clock" + reset: "reset" + reset_assertion_level: 'True' + # gen_inbound_streaming_driver: 'False' + # hdl_typedefs: + # - name: wb_op_t + # type: enum {WB_RESET, WB_WRITE, WB_READ} + parameters: + -name: WB_ADDR_WIDTH + type: int + value: '32' + -name: WB_DATA_WIDTH + type: int + value: '16' + ports: + #- dir: output + #name: inta + #reset_value: '''b0' + #width: '1' + - dir: input + name: din + reset_value: '''b0' + width: WB_DATA_WIDTH + - dir: output + name: dout + reset_value: '''b0' + width: WB_DATA_WIDTH + - dir: input + name: "TGD_I" + - dir: output + name: "TGD_O" + - dir: output + name: ack + reset_value: 1'b0 + width: '1' + - dir: output + name: adr + reset_value: '''b0' + width: WB_ADDR_WIDTH + - dir: output + name: cyc + reset_value: '0' + width: '1' + - dir: input + name: err + reset_value: '''b0' + width: '1' + - dir: output + name: we + reset_value: '0' + width: '1' + - dir: output + name: stb + reset_value: '0' + width: '1' + - dir: output + name: sel + reset_value: '''b0' + width: WB_DATA_WIDTH/8 + #- dir: output + # name: rty + # reset_value: '''b0' + # width: '1' + #- dir: input + # name: q + # reset_value: '''b0' + # width: WB_DATA_WIDTH + #response_info: + # data: [] + # operation: 1'b1 + transaction_constraints: [] + transaction_vars: + # - iscompare: 'False' + #isrand: 'True' + #name: op + #type: wb_op_t + #unpacked_dimension: '' + - iscompare: 'True' + isrand: 'True' + name: data + type: bit [WB_DATA_WIDTH-1:0] + unpacked_dimension: '' + - iscompare: 'True' + isrand: 'True' + name: byte_select + type: bit [(WB_DATA_WIDTH/8)-1:0] + unpacked_dimension: '' + - iscompare: "True" + isrand: "True" + name: WrENB + type: "bit" + - iscompare: "True" + isrand: "True" + name: selslv + type: "bit" diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/.svproject b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/.svproject new file mode 100644 index 00000000..954f4b7f --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/.svproject @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/Makefile b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/Makefile new file mode 100644 index 00000000..fdfe9902 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/Makefile @@ -0,0 +1,62 @@ +# wb interface packages source +# pragma uvmf custom additional begin +# pragma uvmf custom additional end + +wb_PKG = \ + +incdir+$(UVMF_VIP_LIBRARY_HOME)/interface_packages/wb_pkg \ + -F $(UVMF_VIP_LIBRARY_HOME)/interface_packages/wb_pkg/wb_filelist_hvl.f + +wb_PKG_HDL = \ + +incdir+$(UVMF_VIP_LIBRARY_HOME)/interface_packages/wb_pkg \ + -F $(UVMF_VIP_LIBRARY_HOME)/interface_packages/wb_pkg/wb_filelist_hdl.f + +wb_PKG_XRTL = \ + +incdir+$(UVMF_VIP_LIBRARY_HOME)/interface_packages/wb_pkg \ + -F $(UVMF_VIP_LIBRARY_HOME)/interface_packages/wb_pkg/wb_filelist_xrtl.f + +COMP_wb_PKG_TGT_0 = q_comp_wb_pkg +COMP_wb_PKG_TGT_1 = v_comp_wb_pkg +COMP_wb_PKG_TGT = $(COMP_wb_PKG_TGT_$(USE_VELOCE)) + +comp_wb_pkg: $(COMP_wb_PKG_TGT) + +q_comp_wb_pkg: + $(HDL_COMP_CMD) $(wb_PKG_HDL) + $(HVL_COMP_CMD) $(wb_PKG) + $(HDL_COMP_CMD) $(wb_PKG_XRTL) + +v_comp_wb_pkg: + $(HVL_COMP_CMD) $(wb_PKG_HDL) + $(HVL_COMP_CMD) $(wb_PKG) + $(VELANALYZE_HVL_CMD) $(wb_PKG_HDL) + $(VELANALYZE_HVL_CMD) $(wb_PKG) + $(HDL_COMP_CMD) $(wb_PKG_XRTL) + +ifeq ($(MTI_VCO_MODE),64) + GCC_COMP_ARCH = -m64 +else + GCC_COMP_ARCH = -m32 +endif + +C_FILE_COMPILE_LIST_wb_pkg = \ + +O_FILE_COMPILE_LIST_wb_pkg = $(notdir $(C_FILE_COMPILE_LIST_wb_pkg:.c=.o)) + +GCC_COMP_ARGS_wb_pkg += -I$(UVMF_VIP_LIBRARY_HOME)/interface_packages/wb_pkg/dpi \ + -fPIC + +GCC_LINK_ARGS_wb_pkg += \ + \ + -o .so + +comp_wb_pkg_c_files: + @echo "--------------------------------" + @echo "Compiling Interface C source" + @echo "--------------------------------" + gcc $(GCC_COMP_ARCH) $(GCC_COMP_ARGS_wb_pkg) $(C_FILE_COMPILE_LIST_wb_pkg) + @echo "--------------------------------" + @echo "Linking Interface C objects into a shared object" + @echo "--------------------------------" + gcc $(GCC_COMP_ARCH) $(GCC_LINK_ARGS_wb_pkg) $(O_FILE_COMPILE_LIST_wb_pkg) + @echo "--------------------------------" + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/compile.do b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/compile.do new file mode 100644 index 00000000..de71b4b8 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/compile.do @@ -0,0 +1,14 @@ +# Tcl do file for compile of wb interface + +# pragma uvmf custom additional begin +# pragma uvmf custom additional end + + +vlog -sv -timescale 1ps/1ps -suppress 2223,2286 +incdir+$env(UVMF_VIP_LIBRARY_HOME)/interface_packages/wb_pkg \ + -F $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/wb_pkg/wb_filelist_hdl.f + +vlog -sv -timescale 1ps/1ps -suppress 2223,2286 +incdir+$env(UVMF_VIP_LIBRARY_HOME)/interface_packages/wb_pkg \ + -F $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/wb_pkg/wb_filelist_hvl.f + +vlog -sv -timescale 1ps/1ps -suppress 2223,2286 +incdir+$env(UVMF_VIP_LIBRARY_HOME)/interface_packages/wb_pkg \ + -F $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/wb_pkg/wb_filelist_xrtl.f \ No newline at end of file diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb2reg_adapter.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb2reg_adapter.svh new file mode 100644 index 00000000..96e8c702 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb2reg_adapter.svh @@ -0,0 +1,110 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This file contains the UVM register adapter for the wb interface. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class wb2reg_adapter #( + int WB_ADDR_WIDTH = 32, + int WB_DATA_WIDTH = 16 + ) extends uvm_reg_adapter; + + `uvm_object_param_utils( wb2reg_adapter #( + WB_ADDR_WIDTH, + WB_DATA_WIDTH + )) + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + //-------------------------------------------------------------------- + // new + //-------------------------------------------------------------------- + function new (string name = "wb2reg_adapter" ); + super.new(name); + // pragma uvmf custom new begin + // UVMF_CHANGE_ME : Configure the adapter regarding byte enables and provides response. + + // Does the protocol the Agent is modeling support byte enables? + // 0 = NO + // 1 = YES + supports_byte_enable = 0; + + // Does the Agent's Driver provide separate response sequence items? + // i.e. Does the driver call seq_item_port.put() + // and do the sequences call get_response()? + // 0 = NO + // 1 = YES + provides_responses = 0; + + + + + + // pragma uvmf custom new end + + endfunction: new + + //-------------------------------------------------------------------- + // reg2bus + //-------------------------------------------------------------------- + virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw); + + wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) trans_h = wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + )::type_id::create("trans_h"); + + // pragma uvmf custom reg2bus begin + //Adapt the following for your sequence item type + trans_h.op = (rw.kind == UVM_READ) ? WB_READ : WB_WRITE; + //Copy over address + trans_h.addr = rw.addr; + //Copy over write data + trans_h.data = rw.data; + // pragma uvmf custom reg2bus end + + // Return the adapted transaction + return trans_h; + + endfunction: reg2bus + + //-------------------------------------------------------------------- + // bus2reg + //-------------------------------------------------------------------- + virtual function void bus2reg(uvm_sequence_item bus_item, + ref uvm_reg_bus_op rw); + wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) trans_h; + if (!$cast(trans_h, bus_item)) begin + `uvm_fatal("ADAPT","Provided bus_item is not of the correct type") + return; + end + // pragma uvmf custom bus2reg begin + //Adapt the following for your sequence item type + //Copy over instruction type + rw.kind = (trans_h.op == WB_WRITE) ? UVM_WRITE : UVM_READ; + //Copy over address + rw.addr = trans_h.addr; + //Copy over read data + rw.data = trans_h.data; + //Check for errors on the bus and return UVM_NOT_OK if there is an error + rw.status = UVM_IS_OK; + // pragma uvmf custom bus2reg end + + endfunction: bus2reg + +endclass : wb2reg_adapter diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_agent.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_agent.svh new file mode 100644 index 00000000..a00d2368 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_agent.svh @@ -0,0 +1,68 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Protocol specific agent class definition +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class wb_agent #( + int WB_ADDR_WIDTH = 32, + int WB_DATA_WIDTH = 16 + ) extends uvmf_parameterized_agent #( + .CONFIG_T(wb_configuration #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + )), + .DRIVER_T(wb_driver #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + )), + .MONITOR_T(wb_monitor #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + )), + .COVERAGE_T(wb_transaction_coverage #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + )), + .TRANS_T(wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + )) + ); + + `uvm_component_param_utils( wb_agent #( + WB_ADDR_WIDTH, + WB_DATA_WIDTH + )) + +// pragma uvmf custom class_item_additional begin +// pragma uvmf custom class_item_additional end + +// **************************************************************************** +// FUNCTION : new() +// This function is the standard SystemVerilog constructor. +// + function new( string name = "", uvm_component parent = null ); + super.new( name, parent ); + endfunction + +// **************************************************************************** + // FUNCTION: build_phase + virtual function void build_phase(uvm_phase phase); + super.build_phase(phase); + if (configuration.active_passive == ACTIVE) begin + // Place sequencer handle into configuration object + // so that it may be retrieved from configuration + // rather than using uvm_config_db + configuration.sequencer = this.sequencer; + end + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_configuration.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_configuration.svh new file mode 100644 index 00000000..aa093b44 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_configuration.svh @@ -0,0 +1,195 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class contains all variables and functions used +// to configure the wb agent and its bfm's. It gets the +// bfm's from the uvm_config_db for use by the agent. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class wb_configuration #( + int WB_ADDR_WIDTH = 32, + int WB_DATA_WIDTH = 16 + ) extends uvmf_parameterized_agent_configuration_base #( + .DRIVER_BFM_BIND_T(virtual wb_driver_bfm #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + )), + .MONITOR_BFM_BIND_T( virtual wb_monitor_bfm #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ))); + + `uvm_object_param_utils( wb_configuration #( + WB_ADDR_WIDTH, + WB_DATA_WIDTH + )) + + + // Sequencer handle populated by agent + uvm_sequencer #(wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) ) sequencer; + + //Constraints for the configuration variables: + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + covergroup wb_configuration_cg; + // pragma uvmf custom covergroup begin + option.auto_bin_max=1024; + // pragma uvmf custom covergroup end + endgroup + + //******************************************************************* + //******************************************************************* + // Structure used to pass configuration variables to monitor and driver BFM's. + // Use to_struct function to pack variables into structure. + // Use from_struct function to unpack variables from structure. + // This structure is defined in wb_macros.svh + `wb_CONFIGURATION_STRUCT + wb_configuration_s wb_configuration_struct; + //******************************************************************* + // FUNCTION: to_struct() + // This function packs variables into a wb_configuration_s + // structure. The function returns the handle to the wb_configuration_struct. + // This function is defined in wb_macros.svh + `wb_CONFIGURATION_TO_STRUCT_FUNCTION + //******************************************************************* + // FUNCTION: from_struct() + // This function unpacks the struct provided as an argument into + // variables of this class. + // This function is defined in wb_macros.svh + `wb_CONFIGURATION_FROM_STRUCT_FUNCTION + + // **************************************************************************** + // FUNCTION : new() + // This function is the standard SystemVerilog constructor. + // + function new( string name = "" ); + super.new( name ); + // Construct the covergroup for this configuration class + wb_configuration_cg = new; + endfunction + + // **************************************************************************** + // FUNCTION: post_randomize() + // This function is automatically called after the randomize() function + // is executed. + // + function void post_randomize(); + super.post_randomize(); + wb_configuration_cg.sample(); + endfunction + + // **************************************************************************** + // FUNCTION: initialize + // This function causes the configuration to retrieve + // its virtual interface handle from the uvm_config_db. + // This function also makes itself available to its + // agent through the uvm_config_db. + // + // ARGUMENTS: + // uvmf_active_passive_t activity: + // This argument identifies the simulation level + // as either BLOCK, CHIP, SIMULATION, etc. + // + // AGENT_PATH: + // This argument identifies the path to this + // configurations agent. This configuration + // makes itself available to the agent specified + // by agent_path by placing itself into the + // uvm_config_db. + // + // INTERFACE_NAME: + // This argument identifies the string name of + // this configurations BFM's. This string + // name is used to retrieve the driver and + // monitor BFM from the uvm_config_db. + // + virtual function void initialize(uvmf_active_passive_t activity, + string agent_path, + string interface_name); + + super.initialize( activity, agent_path, interface_name); + // The covergroup is given the same name as the interface + wb_configuration_cg.set_inst_name(interface_name); + + // This configuration places itself into the uvm_config_db for the agent, identified by the agent_path variable, to retrieve. + uvm_config_db #( wb_configuration #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) + )::set( null ,agent_path,UVMF_AGENT_CONFIG, this ); + + // This configuration also places itself in the config db using the same identifier used by the interface. This allows users to access + // configuration variables and the interface through the bfm api class rather than directly accessing the BFM. This is useful for + // accessingthe BFM when using Veloce + uvm_config_db #( wb_configuration #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) + )::set( null ,UVMF_CONFIGURATIONS, interface_name, this ); + + wb_configuration_cg.set_inst_name($sformatf("wb_configuration_cg_%s",get_full_name())); + + // pragma uvmf custom initialize begin + // This controls whether or not the agent returns a transaction handle in the driver when calling + // item_done() back into the sequencer or not. If set to 1, a transaction is sent back which means + // the sequence on the other end must use the get_response() part of the driver/sequence API. If + // this doesn't occur, there will eventually be response_queue overflow errors during the test. + return_transaction_response = 1'b0; + + + + + + + // pragma uvmf custom initialize end + + endfunction + + // **************************************************************************** + // TASK: wait_for_reset + // *[Required]* Blocks until reset is released. The wait_for_reset operation is performed + // by a task in the monitor bfm. + virtual task wait_for_reset(); + monitor_bfm.wait_for_reset(); + endtask + + // **************************************************************************** + // TASK: wait_for_num_clocks + // *[Required]* Blocks until specified number of clocks have elapsed. The wait_for_num_clocks + // operation is performed by a task in the monitor bfm. + virtual task wait_for_num_clocks(int clocks); + monitor_bfm.wait_for_num_clocks(clocks); + endtask + + // **************************************************************************** + // FUNCTION : convert2string() + // This function is used to convert variables in this class into a string for log messaging. + // + virtual function string convert2string (); + // pragma uvmf custom convert2string begin + return $sformatf(""); + // pragma uvmf custom convert2string end + endfunction + + // **************************************************************************** + // FUNCTION: get_sequencer + function uvm_sequencer #(wb_transaction#( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + )) get_sequencer(); + return sequencer; + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_driver.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_driver.svh new file mode 100644 index 00000000..b98f1b50 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_driver.svh @@ -0,0 +1,108 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class passes transactions between the sequencer +// and the BFM driver interface. It accesses the driver BFM +// through the bfm handle. This driver +// passes transactions to the driver BFM through the access +// task. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class wb_driver #( + int WB_ADDR_WIDTH = 32, + int WB_DATA_WIDTH = 16 + ) extends uvmf_driver_base #( + .CONFIG_T(wb_configuration #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) ), + .BFM_BIND_T(virtual wb_driver_bfm #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) ), + .REQ(wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) ), + .RSP(wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) )); + + `uvm_component_param_utils( wb_driver #( + WB_ADDR_WIDTH, + WB_DATA_WIDTH + )) +//******************************************************************* +// Macros that define structs located in wb_macros.svh +//******************************************************************* +// Initiator macro used by wb_driver and wb_driver_bfm +// to communicate initiator driven data to wb_driver_bfm. +`wb_INITIATOR_STRUCT + wb_initiator_s wb_initiator_struct; +//******************************************************************* +// Responder macro used by wb_driver and wb_driver_bfm +// to communicate Responder driven data to wb_driver_bfm. +`wb_RESPONDER_STRUCT + wb_responder_s wb_responder_struct; + +// pragma uvmf custom class_item_additional begin +// pragma uvmf custom class_item_additional end + +// **************************************************************************** +// This function is the standard SystemVerilog constructor. +// + function new( string name = "", uvm_component parent=null ); + super.new( name, parent ); + endfunction + +// **************************************************************************** +// This function sends configuration object variables to the driver BFM +// using the configuration struct. +// + virtual function void configure(input CONFIG_T cfg); + bfm.configure( cfg.to_struct() ); + endfunction + +// **************************************************************************** +// This function places a handle to this class in the proxy variable in the +// driver BFM. This allows the driver BFM to call tasks and function within this class. +// + virtual function void set_bfm_proxy_handle(); + bfm.proxy = this; endfunction + +// **************************************************************************** +// This task is called by the run_phase in uvmf_driver_base. + virtual task access( inout REQ txn ); +// pragma uvmf custom access begin + if (configuration.initiator_responder==RESPONDER) begin + // Complete current transfer and wait for next transfer + bfm.respond_and_wait_for_next_transfer( + wb_initiator_struct, + txn.to_responder_struct() + ); + // Unpack information about initiated transfer received by this responder + txn.from_initiator_struct(wb_initiator_struct); + end else begin + // Initiate a transfer and get response + bfm.initiate_and_get_response( + txn.to_initiator_struct(), + wb_responder_struct + ); + // Unpack transfer response information received by this initiator + txn.from_responder_struct(wb_responder_struct); + end + + + +// pragma uvmf custom access end + endtask + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_driver_bfm.sv b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_driver_bfm.sv new file mode 100644 index 00000000..aab2aaa8 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_driver_bfm.sv @@ -0,0 +1,383 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This interface performs the wb signal driving. It is +// accessed by the uvm wb driver through a virtual interface +// handle in the wb configuration. It drives the singals passed +// in through the port connection named bus of type wb_if. +// +// Input signals from the wb_if are assigned to an internal input +// signal with a _i suffix. The _i signal should be used for sampling. +// +// The input signal connections are as follows: +// bus.signal -> signal_i +// +// This bfm drives signals with a _o suffix. These signals +// are driven onto signals within wb_if based on INITIATOR/RESPONDER and/or +// ARBITRATION/GRANT status. +// +// The output signal connections are as follows: +// signal_o -> bus.signal +// +// +// Interface functions and tasks used by UVM components: +// +// configure: +// This function gets configuration attributes from the +// UVM driver to set any required BFM configuration +// variables such as 'initiator_responder'. +// +// initiate_and_get_response: +// This task is used to perform signaling activity for initiating +// a protocol transfer. The task initiates the transfer, using +// input data from the initiator struct. Then the task captures +// response data, placing the data into the response struct. +// The response struct is returned to the driver class. +// +// respond_and_wait_for_next_transfer: +// This task is used to complete a current transfer as a responder +// and then wait for the initiator to start the next transfer. +// The task uses data in the responder struct to drive protocol +// signals to complete the transfer. The task then waits for +// the next transfer. Once the next transfer begins, data from +// the initiator is placed into the initiator struct and sent +// to the responder sequence for processing to determine +// what data to respond with. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +import uvmf_base_pkg_hdl::*; +import wb_pkg_hdl::*; +`include "src/wb_macros.svh" + +interface wb_driver_bfm #( + int WB_ADDR_WIDTH = 32, + int WB_DATA_WIDTH = 16 + ) + (wb_if bus); + // The following pragma and additional ones in-lined further below are for running this BFM on Veloce + // pragma attribute wb_driver_bfm partition_interface_xif + // Config value to determine if this is an initiator or a responder + uvmf_initiator_responder_t initiator_responder; + // Custom configuration variables. + // These are set using the configure function which is called during the UVM connect_phase + + tri clk_i; + tri rst_i; + + // Signal list (all signals are capable of being inputs and outputs for the sake + // of supporting both INITIATOR and RESPONDER mode operation. Expectation is that + // directionality in the config file was from the point-of-view of the INITIATOR + + // INITIATOR mode input signals + tri [WB_DATA_WIDTH-1:0] din_i; + reg [WB_DATA_WIDTH-1:0] din_o = 'bz; + tri [WB_DATA_WIDTH/8-1:0] sel_i; + reg [WB_DATA_WIDTH/8-1:0] sel_o = 'bz; + tri [WB_DATA_WIDTH-1:0] q_i; + reg [WB_DATA_WIDTH-1:0] q_o = 'bz; + tri ack_i; + reg ack_o = 1'b0; + + // INITIATOR mode output signals + tri inta_i; + reg inta_o = 'bz; + tri cyc_i; + reg cyc_o = 0; + tri stb_i; + reg stb_o = 0; + tri [WB_ADDR_WIDTH-1:0] adr_i; + reg [WB_ADDR_WIDTH-1:0] adr_o = 'bz; + tri we_i; + reg we_o = 0; + tri [WB_DATA_WIDTH-1:0] dout_i; + reg [WB_DATA_WIDTH-1:0] dout_o = 'bz; + tri err_i; + reg err_o = 'bz; + tri rty_i; + reg rty_o = 'bz; + + // Bi-directional signals + + + assign clk_i = bus.clk; + assign rst_i = bus.rst; + + // These are signals marked as 'input' by the config file, but the signals will be + // driven by this BFM if put into RESPONDER mode (flipping all signal directions around) + assign din_i = bus.din; + assign bus.din = (initiator_responder == RESPONDER) ? din_o : 'bz; + assign sel_i = bus.sel; + assign bus.sel = (initiator_responder == RESPONDER) ? sel_o : 'bz; + assign q_i = bus.q; + assign bus.q = (initiator_responder == RESPONDER) ? q_o : 'bz; + assign ack_i = bus.ack; + assign bus.ack = (initiator_responder == RESPONDER) ? ack_o : 'bz; + + + // These are signals marked as 'output' by the config file, but the outputs will + // not be driven by this BFM unless placed in INITIATOR mode. + assign bus.inta = (initiator_responder == INITIATOR) ? inta_o : 'bz; + assign inta_i = bus.inta; + assign bus.cyc = (initiator_responder == INITIATOR) ? cyc_o : 'bz; + assign cyc_i = bus.cyc; + assign bus.stb = (initiator_responder == INITIATOR) ? stb_o : 'bz; + assign stb_i = bus.stb; + assign bus.adr = (initiator_responder == INITIATOR) ? adr_o : 'bz; + assign adr_i = bus.adr; + assign bus.we = (initiator_responder == INITIATOR) ? we_o : 'bz; + assign we_i = bus.we; + assign bus.dout = (initiator_responder == INITIATOR) ? dout_o : 'bz; + assign dout_i = bus.dout; + assign bus.err = (initiator_responder == INITIATOR) ? err_o : 'bz; + assign err_i = bus.err; + assign bus.rty = (initiator_responder == INITIATOR) ? rty_o : 'bz; + assign rty_i = bus.rty; + + // Proxy handle to UVM driver + wb_pkg::wb_driver #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) proxy; + // pragma tbx oneway proxy.my_function_name_in_uvm_driver + + // **************************************************************************** + // **************************************************************************** + // Macros that define structs located in wb_macros.svh + // **************************************************************************** + // Struct for passing configuration data from wb_driver to this BFM + // **************************************************************************** + `wb_CONFIGURATION_STRUCT + // **************************************************************************** + // Structs for INITIATOR and RESPONDER data flow + //******************************************************************* + // Initiator macro used by wb_driver and wb_driver_bfm + // to communicate initiator driven data to wb_driver_bfm. + `wb_INITIATOR_STRUCT + wb_initiator_s wb_initiator_struct; + // Responder macro used by wb_driver and wb_driver_bfm + // to communicate Responder driven data to wb_driver_bfm. + `wb_RESPONDER_STRUCT + wb_responder_s wb_responder_struct; + + // **************************************************************************** + // Always block used to return signals to reset value upon assertion of reset + always @( negedge rst_i ) + begin + // RESPONDER mode output signals + din_o <= 'b0; + sel_o <= 'b0; + q_o <= 'b0; + ack_o <= 1'b0; + // INITIATOR mode output signals + inta_o <= 'b0; + cyc_o <= 0; + stb_o <= 0; + adr_o <= 'b0; + we_o <= 0; + dout_o <= 'b0; + err_o <= 'b0; + rty_o <= 'b0; + // Bi-directional signals + + end + + // pragma uvmf custom interface_item_additional begin + bit cyc_q, stb_q; + always @(posedge clk_i) begin + cyc_q <= cyc_i; + stb_q <= stb_i; + end + // Need to detect rising edge on cyc and stb in order to begin a new operation + wire cycle_ready = (!cyc_q & cyc_i) & (!stb_q & stb_i); + + + + + + // pragma uvmf custom interface_item_additional end + + //****************************************************************** + // The configure() function is used to pass agent configuration + // variables to the driver BFM. It is called by the driver within + // the agent at the beginning of the simulation. It may be called + // during the simulation if agent configuration variables are updated + // and the driver BFM needs to be aware of the new configuration + // variables. + // + + function void configure(wb_configuration_s wb_configuration_arg); // pragma tbx xtf + initiator_responder = wb_configuration_arg.initiator_responder; + // pragma uvmf custom configure begin + // pragma uvmf custom configure end + endfunction + +// pragma uvmf custom initiate_and_get_response begin +// **************************************************************************** +// UVMF_CHANGE_ME +// This task is used by an initator. The task first initiates a transfer then +// waits for the responder to complete the transfer. + task initiate_and_get_response( + // This argument passes transaction variables used by an initiator + // to perform the initial part of a protocol transfer. The values + // come from a sequence item created in a sequence. + input wb_initiator_s wb_initiator_struct, + // This argument is used to send data received from the responder + // back to the sequence item. The sequence item is returned to the sequence. + output wb_responder_s wb_responder_struct + );// pragma tbx xtf + // + // Members within the wb_initiator_struct: + // wb_op_t op ; + // bit [WB_DATA_WIDTH-1:0] data ; + // bit [WB_ADDR_WIDTH-1:0] addr ; + // bit [(WB_DATA_WIDTH/8)-1:0] byte_select ; + // Members within the wb_responder_struct: + // wb_op_t op ; + // bit [WB_DATA_WIDTH-1:0] data ; + // bit [WB_ADDR_WIDTH-1:0] addr ; + // bit [(WB_DATA_WIDTH/8)-1:0] byte_select ; + // + // Reference code; + // How to wait for signal value + // while (control_signal == 1'b1) @(posedge clk_i); + // + // How to assign a responder struct member, named xyz, from a signal. + // All available input signals listed. + // wb_responder_struct.xyz = inta_i; // + // wb_responder_struct.xyz = cyc_i; // + // wb_responder_struct.xyz = stb_i; // + // wb_responder_struct.xyz = adr_i; // [WB_ADDR_WIDTH-1:0] + // wb_responder_struct.xyz = we_i; // + // wb_responder_struct.xyz = dout_i; // [WB_DATA_WIDTH-1:0] + // wb_responder_struct.xyz = din_i; // [WB_DATA_WIDTH-1:0] + // wb_responder_struct.xyz = err_i; // + // wb_responder_struct.xyz = rty_i; // + // wb_responder_struct.xyz = sel_i; // [WB_DATA_WIDTH/8-1:0] + // wb_responder_struct.xyz = q_i; // [WB_DATA_WIDTH-1:0] + // wb_responder_struct.xyz = ack_i; // + // How to assign a signal, named xyz, from an initiator struct member. + // All available input signals listed. + // Notice the _o. Those are storage variables that allow for procedural assignment. + // inta_o <= wb_initiator_struct.xyz; // + // cyc_o <= wb_initiator_struct.xyz; // + // stb_o <= wb_initiator_struct.xyz; // + // adr_o <= wb_initiator_struct.xyz; // [WB_ADDR_WIDTH-1:0] + // we_o <= wb_initiator_struct.xyz; // + // dout_o <= wb_initiator_struct.xyz; // [WB_DATA_WIDTH-1:0] + // din_o <= wb_initiator_struct.xyz; // [WB_DATA_WIDTH-1:0] + // err_o <= wb_initiator_struct.xyz; // + // rty_o <= wb_initiator_struct.xyz; // + // sel_o <= wb_initiator_struct.xyz; // [WB_DATA_WIDTH/8-1:0] + // q_o <= wb_initiator_struct.xyz; // [WB_DATA_WIDTH-1:0] + // ack_o <= wb_initiator_struct.xyz; // + @(posedge clk_i); + case (wb_initiator_struct.op) + WB_WRITE : begin + adr_o <= wb_initiator_struct.addr; + dout_o <= wb_initiator_struct.data; + cyc_o <= 1'b1; + stb_o <= 1'b1; + we_o <= 1'b1; + sel_o <= wb_initiator_struct.byte_select; + while (!ack_i) @(posedge clk_i); + cyc_o <= 1'b0; + stb_o <= 1'b0; + adr_o <= 'bx; + dout_o <= 'bx; + we_o <= 1'b0; + sel_o <= 1'b0; + wb_responder_struct.data = wb_initiator_struct.data; + @(posedge clk_i); + @(posedge clk_i); + end + WB_READ : begin + adr_o <= wb_initiator_struct.addr; + dout_o <= 'bx; + cyc_o <= 1'b1; + stb_o <= 1'b1; + we_o <= 1'b0; + sel_o <= wb_initiator_struct.byte_select; + @(posedge clk_i); + while (!ack_i) @(posedge clk_i); + cyc_o <= 1'b0; + stb_o <= 1'b0; + adr_o <= 'bx; + dout_o <= 'bx; + we_o <= 1'b0; + sel_o <= 'b0; + wb_responder_struct.data = din_i; + end + endcase + + endtask + + + +// pragma uvmf custom initiate_and_get_response end + +// pragma uvmf custom respond_and_wait_for_next_transfer begin +// **************************************************************************** +// The first_transfer variable is used to prevent completing a transfer in the +// first call to this task. For the first call to this task, there is not +// current transfer to complete. +bit first_transfer=1; + +// UVMF_CHANGE_ME +// This task is used by a responder. The task first completes the current +// transfer in progress then waits for the initiator to start the next transfer. + task respond_and_wait_for_next_transfer( + // This argument is used to send data received from the initiator + // back to the sequence item. The sequence determines how to respond. + output wb_initiator_s wb_initiator_struct, + // This argument passes transaction variables used by a responder + // to complete a protocol transfer. The values come from a sequence item. + input wb_responder_s wb_responder_struct + );// pragma tbx xtf + // Variables within the wb_initiator_struct: + // wb_op_t op ; + // bit [WB_DATA_WIDTH-1:0] data ; + // bit [WB_ADDR_WIDTH-1:0] addr ; + // bit [(WB_DATA_WIDTH/8)-1:0] byte_select ; + // Variables within the wb_responder_struct: + // wb_op_t op ; + // bit [WB_DATA_WIDTH-1:0] data ; + // bit [WB_ADDR_WIDTH-1:0] addr ; + // bit [(WB_DATA_WIDTH/8)-1:0] byte_select ; + + @(posedge clk_i); + if (!first_transfer) begin + din_o <= wb_responder_struct.data; + ack_o <= 1'b1; + @(posedge clk_i); + din_o <= 'b0; + ack_o <= 1'b0; + end + // Wait for next transfer then gather info from intiator about the transfer. + // Place the data into the wb_initiator_struct. + while (cycle_ready!==1'b1) @(posedge clk_i); + wb_initiator_struct.addr = adr_i; + wb_initiator_struct.data = dout_i; + if (we_i) begin + wb_initiator_struct.op = WB_WRITE; + end else begin + wb_initiator_struct.op = WB_READ; + end + first_transfer = 0; + + + endtask + + + +// pragma uvmf custom respond_and_wait_for_next_transfer end + + +endinterface diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_if.sv b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_if.sv new file mode 100644 index 00000000..2291029a --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_if.sv @@ -0,0 +1,119 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This interface contains the wb interface signals. +// It is instantiated once per wb bus. Bus Functional Models, +// BFM's named wb_driver_bfm, are used to drive signals on the bus. +// BFM's named wb_monitor_bfm are used to monitor signals on the +// bus. This interface signal bundle is passed in the port list of +// the BFM in order to give the BFM access to the signals in this +// interface. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// This template can be used to connect a DUT to these signals +// +// .dut_signal_port(wb_bus.inta), // Agent output +// .dut_signal_port(wb_bus.cyc), // Agent output +// .dut_signal_port(wb_bus.stb), // Agent output +// .dut_signal_port(wb_bus.adr), // Agent output +// .dut_signal_port(wb_bus.we), // Agent output +// .dut_signal_port(wb_bus.dout), // Agent output +// .dut_signal_port(wb_bus.din), // Agent input +// .dut_signal_port(wb_bus.err), // Agent output +// .dut_signal_port(wb_bus.rty), // Agent output +// .dut_signal_port(wb_bus.sel), // Agent input +// .dut_signal_port(wb_bus.q), // Agent input +// .dut_signal_port(wb_bus.ack), // Agent input + +import uvmf_base_pkg_hdl::*; +import wb_pkg_hdl::*; + +interface wb_if #( + int WB_ADDR_WIDTH = 32, + int WB_DATA_WIDTH = 16 + ) + + ( + input tri clk, + input tri rst, + inout tri inta, + inout tri cyc, + inout tri stb, + inout tri [WB_ADDR_WIDTH-1:0] adr, + inout tri we, + inout tri [WB_DATA_WIDTH-1:0] dout, + inout tri [WB_DATA_WIDTH-1:0] din, + inout tri err, + inout tri rty, + inout tri [WB_DATA_WIDTH/8-1:0] sel, + inout tri [WB_DATA_WIDTH-1:0] q, + inout tri ack + ); + +modport monitor_port + ( + input clk, + input rst, + input inta, + input cyc, + input stb, + input adr, + input we, + input dout, + input din, + input err, + input rty, + input sel, + input q, + input ack + ); + +modport initiator_port + ( + input clk, + input rst, + output inta, + output cyc, + output stb, + output adr, + output we, + output dout, + input din, + output err, + output rty, + input sel, + input q, + input ack + ); + +modport responder_port + ( + input clk, + input rst, + input inta, + input cyc, + input stb, + input adr, + input we, + input dout, + output din, + input err, + input rty, + output sel, + output q, + output ack + ); + + +// pragma uvmf custom interface_item_additional begin +// pragma uvmf custom interface_item_additional end + +endinterface + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_macros.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_macros.svh new file mode 100644 index 00000000..66b40758 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_macros.svh @@ -0,0 +1,148 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This file contains macros used with the wb package. +// These macros include packed struct definitions. These structs are +// used to pass data between classes, hvl, and BFM's, hdl. Use of +// structs are more efficient and simpler to modify. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + +// **************************************************************************** +// When changing the contents of this struct, be sure to update the to_struct +// and from_struct methods defined in the macros below that are used in +// the wb_configuration class. +// + `define wb_CONFIGURATION_STRUCT \ +typedef struct packed { \ + uvmf_active_passive_t active_passive; \ + uvmf_initiator_responder_t initiator_responder; \ + } wb_configuration_s; + + `define wb_CONFIGURATION_TO_STRUCT_FUNCTION \ + virtual function wb_configuration_s to_struct();\ + wb_configuration_struct = \ + {\ + this.active_passive,\ + this.initiator_responder\ + };\ + return ( wb_configuration_struct );\ + endfunction + + `define wb_CONFIGURATION_FROM_STRUCT_FUNCTION \ + virtual function void from_struct(wb_configuration_s wb_configuration_struct);\ + {\ + this.active_passive,\ + this.initiator_responder \ + } = wb_configuration_struct;\ + endfunction + +// **************************************************************************** +// When changing the contents of this struct, be sure to update the to_monitor_struct +// and from_monitor_struct methods of the wb_transaction class. +// + `define wb_MONITOR_STRUCT typedef struct packed { \ + wb_op_t op ; \ + bit [WB_DATA_WIDTH-1:0] data ; \ + bit [WB_ADDR_WIDTH-1:0] addr ; \ + bit [(WB_DATA_WIDTH/8)-1:0] byte_select ; \ + } wb_monitor_s; + + `define wb_TO_MONITOR_STRUCT_FUNCTION \ + virtual function wb_monitor_s to_monitor_struct();\ + wb_monitor_struct = \ + { \ + this.op , \ + this.data , \ + this.addr , \ + this.byte_select \ + };\ + return ( wb_monitor_struct);\ + endfunction\ + + `define wb_FROM_MONITOR_STRUCT_FUNCTION \ + virtual function void from_monitor_struct(wb_monitor_s wb_monitor_struct);\ + {\ + this.op , \ + this.data , \ + this.addr , \ + this.byte_select \ + } = wb_monitor_struct;\ + endfunction + +// **************************************************************************** +// When changing the contents of this struct, be sure to update the to_initiator_struct +// and from_initiator_struct methods of the wb_transaction class. +// Also update the comments in the driver BFM. +// + `define wb_INITIATOR_STRUCT typedef struct packed { \ + wb_op_t op ; \ + bit [WB_DATA_WIDTH-1:0] data ; \ + bit [WB_ADDR_WIDTH-1:0] addr ; \ + bit [(WB_DATA_WIDTH/8)-1:0] byte_select ; \ + } wb_initiator_s; + + `define wb_TO_INITIATOR_STRUCT_FUNCTION \ + virtual function wb_initiator_s to_initiator_struct();\ + wb_initiator_struct = \ + {\ + this.op , \ + this.data , \ + this.addr , \ + this.byte_select \ + };\ + return ( wb_initiator_struct);\ + endfunction + + `define wb_FROM_INITIATOR_STRUCT_FUNCTION \ + virtual function void from_initiator_struct(wb_initiator_s wb_initiator_struct);\ + {\ + this.op , \ + this.data , \ + this.addr , \ + this.byte_select \ + } = wb_initiator_struct;\ + endfunction + +// **************************************************************************** +// When changing the contents of this struct, be sure to update the to_responder_struct +// and from_responder_struct methods of the wb_transaction class. +// Also update the comments in the driver BFM. +// + `define wb_RESPONDER_STRUCT typedef struct packed { \ + wb_op_t op ; \ + bit [WB_DATA_WIDTH-1:0] data ; \ + bit [WB_ADDR_WIDTH-1:0] addr ; \ + bit [(WB_DATA_WIDTH/8)-1:0] byte_select ; \ + } wb_responder_s; + + `define wb_TO_RESPONDER_STRUCT_FUNCTION \ + virtual function wb_responder_s to_responder_struct();\ + wb_responder_struct = \ + {\ + this.op , \ + this.data , \ + this.addr , \ + this.byte_select \ + };\ + return ( wb_responder_struct);\ + endfunction + + `define wb_FROM_RESPONDER_STRUCT_FUNCTION \ + virtual function void from_responder_struct(wb_responder_s wb_responder_struct);\ + {\ + this.op , \ + this.data , \ + this.addr , \ + this.byte_select \ + } = wb_responder_struct;\ + endfunction +// pragma uvmf custom additional begin +// pragma uvmf custom additional end diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_master_access_sequence.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_master_access_sequence.svh new file mode 100644 index 00000000..873e1711 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_master_access_sequence.svh @@ -0,0 +1,50 @@ +class wb_master_access_sequence #(int WB_ADDR_WIDTH = 32, int WB_DATA_WIDTH = 16 ) + extends wb_sequence_base #(.WB_ADDR_WIDTH(WB_ADDR_WIDTH),.WB_DATA_WIDTH(WB_DATA_WIDTH)); + + `uvm_object_param_utils(wb_master_access_sequence#(WB_ADDR_WIDTH, WB_DATA_WIDTH )) + + typedef wb_transaction #(.WB_ADDR_WIDTH(WB_ADDR_WIDTH),.WB_DATA_WIDTH(WB_DATA_WIDTH)) wb_trans_t; + + bit [WB_ADDR_WIDTH-1:0] req_addr; + bit [WB_DATA_WIDTH-1:0] req_data; + wb_op_t req_op; + + function new(string name = "wb_master_access_sequence"); + super.new(name); + endfunction + + task read(input bit [WB_ADDR_WIDTH-1:0] addr, output bit [WB_DATA_WIDTH-1:0] read_data, + input uvm_sequencer #(wb_trans_t) seqr, + // input uvm_sequencer #(wb_transaction #(.WB_ADDR_WIDTH(WB_ADDR_WIDTH),.WB_DATA_WIDTH(WB_DATA_WIDTH))) seqr, + input uvm_sequence_base parent = null); + this.req_addr = addr; + this.req_op = WB_READ; + this.start(seqr,parent); + read_data = req.data; + endtask + + task write(input bit [WB_ADDR_WIDTH-1:0] addr, input bit [WB_DATA_WIDTH-1:0] write_data, + input uvm_sequencer #(wb_trans_t) seqr, + // input uvm_sequencer #(wb_transaction #(.WB_ADDR_WIDTH(WB_ADDR_WIDTH),.WB_DATA_WIDTH(WB_DATA_WIDTH))) seqr, + input uvm_sequence_base parent = null); + this.req_addr = addr; + this.req_op = WB_WRITE; + this.req_data = write_data; + this.start(seqr,parent); + endtask + + task body(); + req = wb_trans_t::type_id::create("req"); + start_item(req); + if (!req.randomize() with { + op == req_op; + addr == req_addr; + data == req_data; + byte_select == {WB_DATA_WIDTH/8{1'b1}}; + }) + `uvm_fatal("SEQ","Randomization failed"); + finish_item(req); + `uvm_info("SEQ",{"Transaction finished: ",req.convert2string()},UVM_MEDIUM) + endtask + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_memory_slave_sequence.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_memory_slave_sequence.svh new file mode 100644 index 00000000..ac223a22 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_memory_slave_sequence.svh @@ -0,0 +1,50 @@ +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// Created by : jcraft +// Creation Date : 2016 Nov 03 +//---------------------------------------------------------------------- +// +//---------------------------------------------------------------------- +// Project : wb responder sequence +// Unit : Interface UVM Responder +// File : wb_responder_sequence.svh +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class can be used to provide stimulus when an interface +// has been configured to run in a responder mode. It +// will never finish by default, always going back to the driver +// and driver BFM for the next transaction with which to respond. +// +// **************************************************************************** +// **************************************************************************** +//---------------------------------------------------------------------- +// +class wb_memory_slave_sequence #( + int WB_ADDR_WIDTH = 32, int WB_DATA_WIDTH = 16 ) +extends wb_sequence_base #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), .WB_DATA_WIDTH(WB_DATA_WIDTH) ) ; + + `uvm_object_param_utils( wb_memory_slave_sequence #( WB_ADDR_WIDTH, WB_DATA_WIDTH )) + + bit [WB_DATA_WIDTH-1:0] mem[bit[WB_ADDR_WIDTH-1:0]]; + + function new(string name = "wb_memory_slave_sequence"); + super.new(name); + endfunction + + task body(); + req=wb_transaction #( .WB_ADDR_WIDTH(WB_ADDR_WIDTH), .WB_DATA_WIDTH(WB_DATA_WIDTH) ) ::type_id::create("req"); + forever begin + start_item(req); + finish_item(req); + if (req.op == WB_READ) begin + if (mem.exists(req.addr)) req.data = mem[req.addr]; + else req.data = ~req.addr; + end else begin + mem[req.addr] = req.data; + end + `uvm_info("SEQ",$sformatf("Processed txn: %s",req.convert2string()),UVM_HIGH) + end + endtask + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_monitor.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_monitor.svh new file mode 100644 index 00000000..78f9905b --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_monitor.svh @@ -0,0 +1,96 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class receives wb transactions observed by the +// wb monitor BFM and broadcasts them through the analysis port +// on the agent. It accesses the monitor BFM through the monitor +// task. This UVM component captures transactions +// for viewing in the waveform viewer if the +// enable_transaction_viewing flag is set in the configuration. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class wb_monitor #( + int WB_ADDR_WIDTH = 32, + int WB_DATA_WIDTH = 16 + ) extends uvmf_monitor_base #( + .CONFIG_T(wb_configuration #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + )), + .BFM_BIND_T(virtual wb_monitor_bfm #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + )), + .TRANS_T(wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ))); + + `uvm_component_param_utils( wb_monitor #( + WB_ADDR_WIDTH, + WB_DATA_WIDTH + )) + +// Structure used to pass data from monitor BFM to monitor class in agent. +// Use to_monitor_struct function to pack transaction variables into structure. +// Use from_monitor_struct function to unpack transaction variables from structure. +`wb_MONITOR_STRUCT + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + +// **************************************************************************** +// This function is the standard SystemVerilog constructor. +// + function new( string name = "", uvm_component parent = null ); + super.new( name, parent ); + endfunction + +// **************************************************************************** +// This function sends configuration object variables to the monitor BFM +// using the configuration struct. +// + virtual function void configure(input CONFIG_T cfg); + bfm.configure( cfg.to_struct() ); + + endfunction + +// **************************************************************************** +// This function places a handle to this class in the proxy variable in the +// monitor BFM. This allows the monitor BFM to call the notify_transaction +// function within this class. +// + virtual function void set_bfm_proxy_handle(); + bfm.proxy = this; endfunction + +// *************************************************************************** + virtual task run_phase(uvm_phase phase); + // Start monitor BFM thread and don't call super.run() in order to + // override the default monitor proxy 'pull' behavior with the more + // emulation-friendly BFM 'push' approach using the notify_transaction + // function below + bfm.start_monitoring(); + endtask + +// ************************************************************************** + +// This function is called by the monitor BFM. It receives data observed by the +// monitor BFM. Data is passed using the wb_monitor_struct. + virtual function void notify_transaction(input wb_monitor_s wb_monitor_struct); + trans = new("trans"); + trans.start_time = time_stamp; + trans.end_time = $time; + time_stamp = trans.end_time; + + trans.from_monitor_struct(wb_monitor_struct); + analyze(trans); + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_monitor_bfm.sv b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_monitor_bfm.sv new file mode 100644 index 00000000..2a327e34 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_monitor_bfm.sv @@ -0,0 +1,212 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This interface performs the wb signal monitoring. +// It is accessed by the uvm wb monitor through a virtual +// interface handle in the wb configuration. It monitors the +// signals passed in through the port connection named bus of +// type wb_if. +// +// Input signals from the wb_if are assigned to an internal input +// signal with a _i suffix. The _i signal should be used for sampling. +// +// The input signal connections are as follows: +// bus.signal -> signal_i +// +// Interface functions and tasks used by UVM components: +// monitor(inout TRANS_T txn); +// This task receives the transaction, txn, from the +// UVM monitor and then populates variables in txn +// from values observed on bus activity. This task +// blocks until an operation on the wb bus is complete. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +import uvmf_base_pkg_hdl::*; +import wb_pkg_hdl::*; + +`include "src/wb_macros.svh" + +interface wb_monitor_bfm #( + int WB_ADDR_WIDTH = 32, + int WB_DATA_WIDTH = 16 + ) + ( wb_if bus ); + // The pragma below and additional ones in-lined further down are for running this BFM on Veloce + // pragma attribute wb_monitor_bfm partition_interface_xif + + // Structure used to pass transaction data from monitor BFM to monitor class in agent. +`wb_MONITOR_STRUCT + wb_monitor_s wb_monitor_struct; + + // Structure used to pass configuration data from monitor class to monitor BFM. + `wb_CONFIGURATION_STRUCT + + + // Config value to determine if this is an initiator or a responder + uvmf_initiator_responder_t initiator_responder; + // Custom configuration variables. + // These are set using the configure function which is called during the UVM connect_phase + + tri clk_i; + tri rst_i; + tri inta_i; + tri cyc_i; + tri stb_i; + tri [WB_ADDR_WIDTH-1:0] adr_i; + tri we_i; + tri [WB_DATA_WIDTH-1:0] dout_i; + tri [WB_DATA_WIDTH-1:0] din_i; + tri err_i; + tri rty_i; + tri [WB_DATA_WIDTH/8-1:0] sel_i; + tri [WB_DATA_WIDTH-1:0] q_i; + tri ack_i; + assign clk_i = bus.clk; + assign rst_i = bus.rst; + assign inta_i = bus.inta; + assign cyc_i = bus.cyc; + assign stb_i = bus.stb; + assign adr_i = bus.adr; + assign we_i = bus.we; + assign dout_i = bus.dout; + assign din_i = bus.din; + assign err_i = bus.err; + assign rty_i = bus.rty; + assign sel_i = bus.sel; + assign q_i = bus.q; + assign ack_i = bus.ack; + + // Proxy handle to UVM monitor + wb_pkg::wb_monitor #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) proxy; + // pragma tbx oneway proxy.notify_transaction + + // pragma uvmf custom interface_item_additional begin + // pragma uvmf custom interface_item_additional end + + //****************************************************************** + task wait_for_reset();// pragma tbx xtf + @(posedge clk_i) ; + do_wait_for_reset(); + endtask + + // **************************************************************************** + task do_wait_for_reset(); + wait ( rst_i == 1 ) ; + @(posedge clk_i) ; + endtask + + //****************************************************************** + + task wait_for_num_clocks(input int unsigned count); // pragma tbx xtf + @(posedge clk_i); + + repeat (count-1) @(posedge clk_i); + endtask + + //****************************************************************** + event go; + function void start_monitoring();// pragma tbx xtf + -> go; + endfunction + + // **************************************************************************** + initial begin + @go; + forever begin + @(posedge clk_i); + do_monitor( wb_monitor_struct ); + + + proxy.notify_transaction( wb_monitor_struct ); + + end + end + + //****************************************************************** + // The configure() function is used to pass agent configuration + // variables to the monitor BFM. It is called by the monitor within + // the agent at the beginning of the simulation. It may be called + // during the simulation if agent configuration variables are updated + // and the monitor BFM needs to be aware of the new configuration + // variables. + // + function void configure(wb_configuration_s wb_configuration_arg); // pragma tbx xtf + initiator_responder = wb_configuration_arg.initiator_responder; + // pragma uvmf custom configure begin + // pragma uvmf custom configure end + endfunction + + + // **************************************************************************** + + task do_monitor(output wb_monitor_s wb_monitor_struct); + // UVMF_CHANGE_ME : Implement protocol monitoring. The commented reference code + // below are examples of how to capture signal values and assign them to + // structure members. All available input signals are listed. The 'while' + // code example shows how to wait for a synchronous flow control signal. This + // task should return when a complete transfer has been observed. Once this task is + // exited with captured values, it is then called again to wait for and observe + // the next transfer. One clock cycle is consumed between calls to do_monitor. + // + // Available struct members: + // // wb_monitor_struct.op + // // wb_monitor_struct.data + // // wb_monitor_struct.addr + // // wb_monitor_struct.byte_select + // // + // Reference code; + // How to wait for signal value + // while (control_signal == 1'b1) @(posedge clk_i); + // + // How to assign a struct member, named xyz, from a signal. + // All available input signals listed. + // wb_monitor_struct.xyz = inta_i; // + // wb_monitor_struct.xyz = cyc_i; // + // wb_monitor_struct.xyz = stb_i; // + // wb_monitor_struct.xyz = adr_i; // [WB_ADDR_WIDTH-1:0] + // wb_monitor_struct.xyz = we_i; // + // wb_monitor_struct.xyz = dout_i; // [WB_DATA_WIDTH-1:0] + // wb_monitor_struct.xyz = din_i; // [WB_DATA_WIDTH-1:0] + // wb_monitor_struct.xyz = err_i; // + // wb_monitor_struct.xyz = rty_i; // + // wb_monitor_struct.xyz = sel_i; // [WB_DATA_WIDTH/8-1:0] + // wb_monitor_struct.xyz = q_i; // [WB_DATA_WIDTH-1:0] + // wb_monitor_struct.xyz = ack_i; // + // pragma uvmf custom do_monitor begin + if ( !rst_i ) begin + wb_monitor_struct.op = WB_RESET; + do_wait_for_reset(); + end + else begin + while (!ack_i) @(posedge clk_i); + if (we_i) begin + wb_monitor_struct.op = WB_WRITE; + wb_monitor_struct.data = dout_i; + wb_monitor_struct.addr = adr_i; + end else begin + wb_monitor_struct.op = WB_READ; + wb_monitor_struct.data = din_i; + wb_monitor_struct.addr = adr_i; + end + end + if (wb_monitor_struct.op == WB_WRITE) repeat (2) @(posedge clk_i); + + + + + + // pragma uvmf custom do_monitor end + endtask + + +endinterface diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_random_sequence.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_random_sequence.svh new file mode 100644 index 00000000..5c80af6a --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_random_sequence.svh @@ -0,0 +1,62 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This sequences randomizes the wb transaction and sends it +// to the UVM driver. +// +// This sequence constructs and randomizes a wb_transaction. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class wb_random_sequence #( + int WB_ADDR_WIDTH = 32, + int WB_DATA_WIDTH = 16 + ) + extends wb_sequence_base #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ); + + `uvm_object_param_utils( wb_random_sequence #( + WB_ADDR_WIDTH, + WB_DATA_WIDTH + )) + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + //***************************************************************** + function new(string name = ""); + super.new(name); + endfunction: new + + // **************************************************************************** + // TASK : body() + // This task is automatically executed when this sequence is started using the + // start(sequencerHandle) task. + // + task body(); + begin + // Construct the transaction + req=wb_transaction#( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + )::type_id::create("req"); + start_item(req); + // Randomize the transaction + if(!req.randomize()) `uvm_fatal("SEQ", "wb_random_sequence::body()-wb_transaction randomization failed") + // Send the transaction to the wb_driver_bfm via the sequencer and wb_driver. + finish_item(req); + `uvm_info("SEQ", {"Response:",req.convert2string()},UVM_MEDIUM) + end + + endtask + +endclass: wb_random_sequence diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_reset_sequence.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_reset_sequence.svh new file mode 100644 index 00000000..fc99d856 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_reset_sequence.svh @@ -0,0 +1,64 @@ +//---------------------------------------------------------------------- +// Copyright 2013 Mentor Graphics Corporation +// All Rights Reserved Worldwide +// +// Licensed under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in +// writing, software distributed under the License is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See +// the License for the specific language governing +// permissions and limitations under the License. +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// Mentor Graphics Inc +//---------------------------------------------------------------------- +// Project : WB interface agent +// Unit : Sequence library +// File : wb_reset_sequence.svh +//---------------------------------------------------------------------- +// Creation Date : 05.12.2011 +//---------------------------------------------------------------------- +// Description: This file contains wb sequence used to generate a reset +// on the wb bus. +// +//---------------------------------------------------------------------- +// +class wb_reset_sequence #(int WB_ADDR_WIDTH = 32, int WB_DATA_WIDTH = 16 ) extends wb_sequence_base #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) ); + + // declaration macros + `uvm_object_param_utils( wb_reset_sequence #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) )) + + typedef wb_transaction#( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) ) wb_trans_t; + +//***************************************************************** + function new(string name = ""); + super.new(name); + endfunction: new + +//***************************************************************** + task body(); + + begin + assert($cast(req, create_item(wb_trans_t::get_type(), m_sequencer, "req"))); + start_item(req); + req.op = WB_RESET; + `uvm_info("SEQ",{"Sending transaction ",req.convert2string()}, UVM_MEDIUM); + finish_item(req); + end + + endtask: body + +endclass: wb_reset_sequence diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_responder_sequence.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_responder_sequence.svh new file mode 100644 index 00000000..c8257987 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_responder_sequence.svh @@ -0,0 +1,62 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class can be used to provide stimulus when an interface +// has been configured to run in a responder mode. It +// will never finish by default, always going back to the driver +// and driver BFM for the next transaction with which to respond. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class wb_responder_sequence #( + int WB_ADDR_WIDTH = 32, + int WB_DATA_WIDTH = 16 + ) + extends wb_sequence_base #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ); + + `uvm_object_param_utils( wb_responder_sequence #( + WB_ADDR_WIDTH, + WB_DATA_WIDTH + )) + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + function new(string name = "wb_responder_sequence"); + super.new(name); + endfunction + + task body(); + req=wb_transaction#( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + )::type_id::create("req"); + forever begin + start_item(req); + finish_item(req); + // pragma uvmf custom body begin + // UVMF_CHANGE_ME : Do something here with the resulting req item. The + // finish_item() call above will block until the req transaction is ready + // to be handled by the responder sequence. + // If this was an item that required a response, the expectation is + // that the response should be populated within this transaction now. + `uvm_info("SEQ",$sformatf("Processed txn: %s",req.convert2string()),UVM_HIGH) + + + + + + // pragma uvmf custom body end + end + endtask + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_sequence_base.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_sequence_base.svh new file mode 100644 index 00000000..7619ea8f --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_sequence_base.svh @@ -0,0 +1,117 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This file contains the class used as the base class for all sequences +// for this interface. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class wb_sequence_base #( + int WB_ADDR_WIDTH = 32, + int WB_DATA_WIDTH = 16 + ) extends uvmf_sequence_base #( + .REQ(wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + )), + .RSP(wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ))); + + `uvm_object_param_utils( wb_sequence_base #( + WB_ADDR_WIDTH, + WB_DATA_WIDTH + )) + + // variables + typedef wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) wb_transaction_req_t; + wb_transaction_req_t req; + typedef wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) wb_transaction_rsp_t; + wb_transaction_rsp_t rsp; + + // Event for identifying when a response was received from the sequencer + event new_rsp; + + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + // **************************************************************************** + // TASK : get_responses() + // This task recursively gets sequence item responses from the sequencer. + // + virtual task get_responses(); + fork + begin + // Block until new rsp available + get_response(rsp); + // New rsp received. Indicate to sequence using event. + ->new_rsp; + // Display the received response transaction + `uvm_info("SEQ", {"New response transaction:",rsp.convert2string()}, UVM_MEDIUM) + end + join_none + endtask + + // **************************************************************************** + // TASK : pre_body() + // This task is called automatically when start is called with call_pre_post set to 1 (default). + // By calling get_responses() within pre_body() any derived sequences are automatically + // processing response transactions. + // + virtual task pre_body(); + // pragma uvmf custom pre_body begin + get_responses(); + // pragma uvmf custom pre_body end + endtask + + // **************************************************************************** + // TASK : body() + // This task is called automatically when start is called. This sequence sends + // a req sequence item to the sequencer identified as an argument in the call + // to start. + // + virtual task body(); + // pragma uvmf custom body begin + start_item(req); + finish_item(req); + + + + + + // pragma uvmf custom body end + endtask + + // **************************************************************************** + // FUNCTION : new() + // This function is the standard SystemVerilog constructor. + // + function new( string name =""); + super.new( name ); + // pragma uvmf custom new begin + req = wb_transaction_req_t::type_id::create("req"); + rsp = wb_transaction_rsp_t::type_id::create("rsp"); + + + + + + // pragma uvmf custom new end + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_slave_access_sequence.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_slave_access_sequence.svh new file mode 100644 index 00000000..ca9ab7e4 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_slave_access_sequence.svh @@ -0,0 +1,52 @@ +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// Created by : jcraft +// Creation Date : 2016 Nov 03 +//---------------------------------------------------------------------- +// +//---------------------------------------------------------------------- +// Project : wb responder sequence +// Unit : Interface UVM Responder +// File : wb_responder_sequence.svh +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class can be used to provide stimulus when an interface +// has been configured to run in a responder mode. It +// will never finish by default, always going back to the driver +// and driver BFM for the next transaction with which to respond. +// +// **************************************************************************** +// **************************************************************************** +//---------------------------------------------------------------------- +// +class wb_slave_access_sequence #( + int WB_ADDR_WIDTH = 32, int WB_DATA_WIDTH = 16 ) +extends wb_sequence_base #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), .WB_DATA_WIDTH(WB_DATA_WIDTH) ) ; + + `uvm_object_param_utils( wb_slave_access_sequence #( WB_ADDR_WIDTH, WB_DATA_WIDTH )) + + function new(string name = "wb_memory_slave_sequence"); + super.new(name); + endfunction + + task body(); + req=wb_transaction #( .WB_ADDR_WIDTH(WB_ADDR_WIDTH), .WB_DATA_WIDTH(WB_DATA_WIDTH) ) ::type_id::create("req"); + // This loop will reuse the transaction object created above for as long as the simulation is + // running. The first call to start_item() and finish_item() is a "dummy" transaction. The + // finish_item() call will block in the driver BFM until a valid transaction is seen at which + // point this will unblock, allowing the sequence to act on the resulting information. In the event + // of a read, we return the inverted address seen. This response is passed back into the driver + // on the next pass into start_item()/finish_item() which will also block again waiting for the + // next transaction. + forever begin + start_item(req); + finish_item(req); + if (req.op == WB_READ) begin + req.data = ~req.addr; + end + `uvm_info("SEQ",$sformatf("Processed txn: %s",req.convert2string()),UVM_HIGH) + end + endtask + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_transaction.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_transaction.svh new file mode 100644 index 00000000..4f127a60 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_transaction.svh @@ -0,0 +1,212 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class defines the variables required for an wb +// transaction. Class variables to be displayed in waveform transaction +// viewing are added to the transaction viewing stream in the add_to_wave +// function. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class wb_transaction #( + int WB_ADDR_WIDTH = 32, + int WB_DATA_WIDTH = 16 + ) extends uvmf_transaction_base; + + `uvm_object_param_utils( wb_transaction #( + WB_ADDR_WIDTH, + WB_DATA_WIDTH + )) + + rand wb_op_t op ; + rand bit [WB_DATA_WIDTH-1:0] data ; + rand bit [WB_ADDR_WIDTH-1:0] addr ; + rand bit [(WB_DATA_WIDTH/8)-1:0] byte_select ; + + //Constraints for the transaction variables: + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + //******************************************************************* + //******************************************************************* + // Macros that define structs and associated functions are + // located in wb_macros.svh + + //******************************************************************* + // Monitor macro used by wb_monitor and wb_monitor_bfm + // This struct is defined in wb_macros.svh + `wb_MONITOR_STRUCT + wb_monitor_s wb_monitor_struct; + //******************************************************************* + // FUNCTION: to_monitor_struct() + // This function packs transaction variables into a wb_monitor_s + // structure. The function returns the handle to the wb_monitor_struct. + // This function is defined in wb_macros.svh + `wb_TO_MONITOR_STRUCT_FUNCTION + //******************************************************************* + // FUNCTION: from_monitor_struct() + // This function unpacks the struct provided as an argument into transaction + // variables of this class. + // This function is defined in wb_macros.svh + `wb_FROM_MONITOR_STRUCT_FUNCTION + + //******************************************************************* + // Initiator macro used by wb_driver and wb_driver_bfm + // to communicate initiator driven data to wb_driver_bfm. + // This struct is defined in wb_macros.svh + `wb_INITIATOR_STRUCT + wb_initiator_s wb_initiator_struct; + //******************************************************************* + // FUNCTION: to_initiator_struct() + // This function packs transaction variables into a wb_initiator_s + // structure. The function returns the handle to the wb_initiator_struct. + // This function is defined in wb_macros.svh + `wb_TO_INITIATOR_STRUCT_FUNCTION + //******************************************************************* + // FUNCTION: from_initiator_struct() + // This function unpacks the struct provided as an argument into transaction + // variables of this class. + // This function is defined in wb_macros.svh + `wb_FROM_INITIATOR_STRUCT_FUNCTION + + //******************************************************************* + // Responder macro used by wb_driver and wb_driver_bfm + // to communicate Responder driven data to wb_driver_bfm. + // This struct is defined in wb_macros.svh + `wb_RESPONDER_STRUCT + wb_responder_s wb_responder_struct; + //******************************************************************* + // FUNCTION: to_responder_struct() + // This function packs transaction variables into a wb_responder_s + // structure. The function returns the handle to the wb_responder_struct. + // This function is defined in wb_macros.svh + `wb_TO_RESPONDER_STRUCT_FUNCTION + //******************************************************************* + // FUNCTION: from_responder_struct() + // This function unpacks the struct provided as an argument into transaction + // variables of this class. + // This function is defined in wb_macros.svh + `wb_FROM_RESPONDER_STRUCT_FUNCTION + // **************************************************************************** + // FUNCTION : new() + // This function is the standard SystemVerilog constructor. + // + function new( string name = "" ); + super.new( name ); + endfunction + + // **************************************************************************** + // FUNCTION: convert2string() + // This function converts all variables in this class to a single string for + // logfile reporting. + // + virtual function string convert2string(); + // pragma uvmf custom convert2string begin + // UVMF_CHANGE_ME : Customize format if desired. + return $sformatf("op:0x%x data:0x%x addr:0x%x byte_select:0x%x ",op,data,addr,byte_select); + + + + + + // pragma uvmf custom convert2string end + endfunction + + //******************************************************************* + // FUNCTION: do_print() + // This function is automatically called when the .print() function + // is called on this class. + // + virtual function void do_print(uvm_printer printer); + // pragma uvmf custom do_print begin + // UVMF_CHANGE_ME : Current contents of do_print allows for the use of UVM 1.1d, 1.2 or P1800.2. + // Update based on your own printing preference according to your preferred UVM version + $display(convert2string()); + + + + + + // pragma uvmf custom do_print end + endfunction + + //******************************************************************* + // FUNCTION: do_compare() + // This function is automatically called when the .compare() function + // is called on this class. + // + virtual function bit do_compare (uvm_object rhs, uvm_comparer comparer); + wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) RHS; + if (!$cast(RHS,rhs)) return 0; + // UVMF_CHANGE_ME : Eliminate comparison of variables not to be used for compare + return (super.do_compare(rhs,comparer) + &&(this.data == RHS.data) + &&(this.addr == RHS.addr) + &&(this.byte_select == RHS.byte_select) + ); + endfunction + + //******************************************************************* + // FUNCTION: do_copy() + // This function is automatically called when the .copy() function + // is called on this class. + // + virtual function void do_copy (uvm_object rhs); + wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ) RHS; + assert($cast(RHS,rhs)); + super.do_copy(rhs); + this.op = RHS.op; + this.data = RHS.data; + this.addr = RHS.addr; + this.byte_select = RHS.byte_select; + endfunction + + // **************************************************************************** + // FUNCTION: add_to_wave() + // This function is used to display variables in this class in the waveform + // viewer. The start_time and end_time variables must be set before this + // function is called. If the start_time and end_time variables are not set + // the transaction will be hidden at 0ns on the waveform display. + // + virtual function void add_to_wave(int transaction_viewing_stream_h); + `ifdef QUESTA + if (transaction_view_h == 0) begin + transaction_view_h = $begin_transaction(transaction_viewing_stream_h,"wb_transaction",start_time); + end + super.add_to_wave(transaction_view_h); + // pragma uvmf custom add_to_wave begin + // UVMF_CHANGE_ME : Color can be applied to transaction entries based on content, example below + // case() + // 1 : $add_color(transaction_view_h,"red"); + // default : $add_color(transaction_view_h,"grey"); + // endcase + // UVMF_CHANGE_ME : Eliminate transaction variables not wanted in transaction viewing in the waveform viewer + $add_attribute(transaction_view_h,op,"op"); + $add_attribute(transaction_view_h,data,"data"); + $add_attribute(transaction_view_h,addr,"addr"); + $add_attribute(transaction_view_h,byte_select,"byte_select"); + + + + + + // pragma uvmf custom add_to_wave end + $end_transaction(transaction_view_h,end_time); + $free_transaction(transaction_view_h); + `endif // QUESTA + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_transaction_coverage.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_transaction_coverage.svh new file mode 100644 index 00000000..910f2250 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_transaction_coverage.svh @@ -0,0 +1,82 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class records wb transaction information using +// a covergroup named wb_transaction_cg. An instance of this +// coverage component is instantiated in the uvmf_parameterized_agent +// if the has_coverage flag is set. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class wb_transaction_coverage #( + int WB_ADDR_WIDTH = 32, + int WB_DATA_WIDTH = 16 + ) extends uvm_subscriber #(.T(wb_transaction #( + .WB_ADDR_WIDTH(WB_ADDR_WIDTH), + .WB_DATA_WIDTH(WB_DATA_WIDTH) + ))); + + `uvm_component_param_utils( wb_transaction_coverage #( + WB_ADDR_WIDTH, + WB_DATA_WIDTH + )) + + T coverage_trans; + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + // **************************************************************************** + covergroup wb_transaction_cg; + // pragma uvmf custom covergroup begin + // UVMF_CHANGE_ME : Add coverage bins, crosses, exclusions, etc. according to coverage needs. + option.auto_bin_max=1024; + option.per_instance=1; + op: coverpoint coverage_trans.op; + data: coverpoint coverage_trans.data; + addr: coverpoint coverage_trans.addr; + byte_select: coverpoint coverage_trans.byte_select; + + + + + + // pragma uvmf custom covergroup end + endgroup + + // **************************************************************************** + // FUNCTION : new() + // This function is the standard SystemVerilog constructor. + // + function new(string name="", uvm_component parent=null); + super.new(name,parent); + wb_transaction_cg=new; + endfunction + + // **************************************************************************** + // FUNCTION : build_phase() + // This function is the standard UVM build_phase. + // + function void build_phase(uvm_phase phase); + wb_transaction_cg.set_inst_name($sformatf("wb_transaction_cg_%s",get_full_name())); + endfunction + + // **************************************************************************** + // FUNCTION: write (T t) + // This function is automatically executed when a transaction arrives on the + // analysis_export. It copies values from the variables in the transaction + // to local variables used to collect functional coverage. + // + virtual function void write (T t); + `uvm_info("COV","Received transaction",UVM_HIGH); + coverage_trans = t; + wb_transaction_cg.sample(); + endfunction + +endclass diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_typedefs.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_typedefs.svh new file mode 100644 index 00000000..b78302a6 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_typedefs.svh @@ -0,0 +1,20 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This file contains defines and typedefs to be compiled for use in +// the simulation running on the host server when using Veloce. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + + +// pragma uvmf custom additional begin +// pragma uvmf custom additional end + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_typedefs_hdl.svh b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_typedefs_hdl.svh new file mode 100644 index 00000000..077b08e6 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/src/wb_typedefs_hdl.svh @@ -0,0 +1,22 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This file contains defines and typedefs to be compiled for use in +// the simulation running on the emulator when using Veloce. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + + +typedef enum {WB_RESET, WB_WRITE, WB_READ} wb_op_t; + +// pragma uvmf custom additional begin +// pragma uvmf custom additional end + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb.compile b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb.compile new file mode 100644 index 00000000..38c2764e --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb.compile @@ -0,0 +1,3 @@ +needs: + - wb_hvl.compile + - wb_hdl.compile diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_bfm.vinfo b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_bfm.vinfo new file mode 100644 index 00000000..15605674 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_bfm.vinfo @@ -0,0 +1,6 @@ +@use $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg_hdl.vinfo +@use wb_pkg_hdl.vinfo ++incdir+@vinfodir +src/wb_if.sv +src/wb_driver_bfm.sv +src/wb_monitor_bfm.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_common.compile b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_common.compile new file mode 100644 index 00000000..2879ffee --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_common.compile @@ -0,0 +1,9 @@ +incdir: + - ${uvm_path}/src + - . + +needs: + - $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg_hdl.compile + +src: + - wb_pkg_hdl.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_filelist_hdl.f b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_filelist_hdl.f new file mode 100644 index 00000000..ca9787c8 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_filelist_hdl.f @@ -0,0 +1 @@ +$UVMF_VIP_LIBRARY_HOME/interface_packages/wb_pkg/wb_pkg_hdl.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_filelist_hvl.f b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_filelist_hvl.f new file mode 100644 index 00000000..895e5a80 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_filelist_hvl.f @@ -0,0 +1 @@ +$UVMF_VIP_LIBRARY_HOME/interface_packages/wb_pkg/wb_pkg.sv \ No newline at end of file diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_filelist_xrtl.f b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_filelist_xrtl.f new file mode 100644 index 00000000..4d20beaa --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_filelist_xrtl.f @@ -0,0 +1,4 @@ +$UVMF_VIP_LIBRARY_HOME/interface_packages/wb_pkg/wb_pkg_hdl.sv +$UVMF_VIP_LIBRARY_HOME/interface_packages/wb_pkg/src/wb_if.sv +$UVMF_VIP_LIBRARY_HOME/interface_packages/wb_pkg/src/wb_monitor_bfm.sv +$UVMF_VIP_LIBRARY_HOME/interface_packages/wb_pkg/src/wb_driver_bfm.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_hdl.compile b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_hdl.compile new file mode 100644 index 00000000..b6ac46e9 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_hdl.compile @@ -0,0 +1,7 @@ +src: + - src/wb_if.sv + - src/wb_driver_bfm.sv + - src/wb_monitor_bfm.sv + +needs: + - wb_common.compile diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_hvl.compile b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_hvl.compile new file mode 100644 index 00000000..94b4d7db --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_hvl.compile @@ -0,0 +1,6 @@ +needs: + - $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg.compile + - wb_common.compile + +src: + - wb_pkg.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg.sv b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg.sv new file mode 100644 index 00000000..fc83bdaf --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg.sv @@ -0,0 +1,79 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// PACKAGE: This file defines all of the files contained in the +// interface package that will run on the host simulator. +// +// CONTAINS: +// - +// - +// - + +// - +// - +// - + +// - +// - +// - + +// - +// - +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +package wb_pkg; + + import uvm_pkg::*; + import uvmf_base_pkg_hdl::*; + import uvmf_base_pkg::*; + import wb_pkg_hdl::*; + + `include "uvm_macros.svh" + + // pragma uvmf custom package_imports_additional begin + // pragma uvmf custom package_imports_additional end + + `include "src/wb_macros.svh" + + export wb_pkg_hdl::*; + + + + // Parameters defined as HVL parameters + + `include "src/wb_typedefs.svh" + `include "src/wb_transaction.svh" + + `include "src/wb_configuration.svh" + `include "src/wb_driver.svh" + `include "src/wb_monitor.svh" + + `include "src/wb_transaction_coverage.svh" + `include "src/wb_sequence_base.svh" + `include "src/wb_random_sequence.svh" + + `include "src/wb_responder_sequence.svh" + `include "src/wb2reg_adapter.svh" + + `include "src/wb_agent.svh" + + // pragma uvmf custom package_item_additional begin + `include "src/wb_master_access_sequence.svh" + `include "src/wb_memory_slave_sequence.svh" + `include "src/wb_slave_access_sequence.svh" + + + + + + // pragma uvmf custom package_item_additional end + +endpackage + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg.vinfo b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg.vinfo new file mode 100644 index 00000000..bb2526ed --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg.vinfo @@ -0,0 +1,4 @@ +@use $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg.vinfo +@use wb_pkg_hdl.vinfo ++incdir+@vinfodir +wb_pkg.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg_hdl.sv b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg_hdl.sv new file mode 100644 index 00000000..5c5db632 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg_hdl.sv @@ -0,0 +1,35 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2019.4_1 +//---------------------------------------------------------------------- +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// PACKAGE: This file defines all of the files contained in the +// interface package that needs to be compiled and synthesized +// for running on Veloce. +// +// CONTAINS: +// - +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +package wb_pkg_hdl; + + import uvmf_base_pkg_hdl::*; + + // pragma uvmf custom package_imports_additional begin + // pragma uvmf custom package_imports_additional end + + // Parameters defined as HDL parameters + + `include "src/wb_typedefs_hdl.svh" + `include "src/wb_macros.svh" + + // pragma uvmf custom package_item_additional begin + // pragma uvmf custom package_item_additional end + +endpackage + diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg_hdl.vinfo b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg_hdl.vinfo new file mode 100644 index 00000000..56bf8ef4 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg_hdl.vinfo @@ -0,0 +1,2 @@ +@use $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg_hdl.vinfo +wb_pkg_hdl.sv diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg_sve.F b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg_sve.F new file mode 100644 index 00000000..fd084d09 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/wb_pkg_sve.F @@ -0,0 +1,10 @@ +// UVM ++incdir+${UVM_HOME}/src +${UVM_HOME}/src/uvm_pkg.sv + +// Common UVMF files +-f ${UVMF_HOME}/common/common_sve.f + ++incdir+. +-f ${UVMF_VIP_LIBRARY_HOME}/interface_packages/wb_pkg/wb_filelist_hdl.f +-f ${UVMF_VIP_LIBRARY_HOME}/interface_packages/wb_pkg/wb_filelist_hvl.f diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/yaml/wb_interface.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/yaml/wb_interface.yaml new file mode 100644 index 00000000..67a87085 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_pkg/yaml/wb_interface.yaml @@ -0,0 +1,97 @@ +uvmf: + interfaces: + wb: + clock: clk + config_constraints: [] + config_vars: [] + gen_inbound_streaming_driver: 'False' + hdl_pkg_parameters: [] + hdl_typedefs: + - name: wb_op_t + type: enum {WB_RESET, WB_WRITE, WB_READ} + hvl_pkg_parameters: [] + hvl_typedefs: [] + parameters: + - name: WB_ADDR_WIDTH + type: int + value: '32' + - name: WB_DATA_WIDTH + type: int + value: '16' + ports: + - dir: output + name: inta + reset_value: '''b0' + width: '1' + - dir: output + name: cyc + reset_value: '0' + width: '1' + - dir: output + name: stb + reset_value: '0' + width: '1' + - dir: output + name: adr + reset_value: '''b0' + width: WB_ADDR_WIDTH + - dir: output + name: we + reset_value: '0' + width: '1' + - dir: output + name: dout + reset_value: '''b0' + width: WB_DATA_WIDTH + - dir: input + name: din + reset_value: '''b0' + width: WB_DATA_WIDTH + - dir: output + name: err + reset_value: '''b0' + width: '1' + - dir: output + name: rty + reset_value: '''b0' + width: '1' + - dir: input + name: sel + reset_value: '''b0' + width: WB_DATA_WIDTH/8 + - dir: input + name: q + reset_value: '''b0' + width: WB_DATA_WIDTH + - dir: input + name: ack + reset_value: 1'b0 + width: '1' + reset: rst + reset_assertion_level: 'False' + response_info: + data: [] + operation: 1'b1 + transaction_constraints: [] + transaction_vars: + - iscompare: 'False' + isrand: 'True' + name: op + type: wb_op_t + unpacked_dimension: '' + - iscompare: 'True' + isrand: 'True' + name: data + type: bit [WB_DATA_WIDTH-1:0] + unpacked_dimension: '' + - iscompare: 'True' + isrand: 'True' + name: addr + type: bit [WB_ADDR_WIDTH-1:0] + unpacked_dimension: '' + - iscompare: 'True' + isrand: 'True' + name: byte_select + type: bit [(WB_DATA_WIDTH/8)-1:0] + unpacked_dimension: '' + use_dpi_link: 'False' diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/wb_slave.yaml b/UVM_Framework/UVMF_2022.3/challenge_3/wb_slave.yaml new file mode 100644 index 00000000..8bdef3e0 --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/wb_slave.yaml @@ -0,0 +1,90 @@ +uvmf: + interfaces: + wb_s: + clock: "clock" + reset: "reset" + reset_assertion_level: 'True' + # gen_inbound_streaming_driver: 'False' + # hdl_typedefs: + # - name: wb_op_t + # type: enum {WB_RESET, WB_WRITE, WB_READ} + parameters: + -name: WB_ADDR_WIDTH + type: int + value: '32' + -name: WB_DATA_WIDTH + type: int + value: '16' + ports: + #- dir: output + #name: inta + #reset_value: '''b0' + #width: '1' + - dir: input + name: din + reset_value: '''b0' + width: WB_DATA_WIDTH + - dir: output + name: dout + reset_value: '''b0' + width: WB_DATA_WIDTH + - dir: input + name: "TGD_I" + - dir: output + name: "TGD_O" + - dir: output + name: ack + reset_value: 1'b0 + width: '1' + - dir: input + name: adr + reset_value: '''b0' + width: WB_ADDR_WIDTH + - dir: input + name: cyc + reset_value: '0' + width: '1' + - dir: output + name: err + reset_value: '''b0' + width: '1' + - dir: input + name: we + reset_value: '0' + width: '1' + - dir: input + name: stb + reset_value: '0' + width: '1' + - dir: input + name: sel + reset_value: '''b0' + width: WB_DATA_WIDTH/8 + #- dir: output + # name: rty + # reset_value: '''b0' + # width: '1' + #- dir: input + # name: q + # reset_value: '''b0' + # width: WB_DATA_WIDTH + #response_info: + # data: [] + # operation: 1'b1 + transaction_constraints: [] + transaction_vars: + # - iscompare: 'False' + #isrand: 'True' + #name: op + #type: wb_op_t + #unpacked_dimension: '' + - iscompare: 'True' + isrand: 'True' + name: data + type: bit [WB_DATA_WIDTH-1:0] + unpacked_dimension: '' + #- iscompare: 'True' + # isrand: 'True' + # name: byte_select + # type: bit [(WB_DATA_WIDTH/8)-1:0] + # unpacked_dimension: '' diff --git a/UVM_Framework/UVMF_2022.3/challenge_3/yaml2uvmf.py b/UVM_Framework/UVMF_2022.3/challenge_3/yaml2uvmf.py new file mode 100755 index 00000000..286bec9b --- /dev/null +++ b/UVM_Framework/UVMF_2022.3/challenge_3/yaml2uvmf.py @@ -0,0 +1,1659 @@ +#! /usr/bin/env python + +############################################################################## +## Copyright 2017 Mentor Graphics +## All Rights Reserved Worldwide +## +## Licensed under the Apache License, Version 2.0 (the "License"); you may +## not use this file except in compliance with the License. You may obtain +## a copy of the License at +## +## http://www.apache.org/license/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in +## writing, software distributed under the License is +## distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +## CONDITIONS OF ANY KIND, either express or implied. See +## the License for the specific language governing +## permissions and limitations under the License. +## +############################################################################## +## +## Mentor Graphics Inc +## +############################################################################## +## +## Created by : Jon Craft & Bob Oden +## Creation date : May 25 2017 +## +############################################################################## +## +## This script utilizes the Python-based generator API to take data structures +## defined in YAML and convert them into UVMF code for interfaces, environments +## and benches. +## +## Run 'yaml2uvmf.py --help' for more information +## +############################################################################## + +import sys +import os +import time +import re +import inspect +import copy +import pprint +from optparse import OptionParser, SUPPRESS_HELP +from fnmatch import fnmatch +import shutil + +# Determine addition to sys.path automatically based on script location +# This means user does not have to explicitly set PYTHONPATH in order for this +# script to work properly. + +sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.realpath(__file__)))+"/templates/python"); +# Only need python2 packages if using python2 +if sys.version_info[0] < 3: + sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.realpath(__file__)))+"/templates/python/python2"); + +from uvmf_yaml import * +import uvmf_gen +from uvmf_gen import (UVMFCommandLineParser,PassThroughOptionParser,UserError,InterfaceClass,EnvironmentClass,BenchClass) +from voluptuous import Invalid, MultipleInvalid +from voluptuous.humanize import humanize_error +from uvmf_version import version + +try: + import yaml +except ImportError: + print("ERROR : yaml package not found. See templates.README for more information") + print("Python version info:\n{}".format(sys.version)) + sys.exit(1) + +def merge_summary(merge,verbose=False): + block_count = sum(len(l) for l in merge.found_blocks.values()) + new_block_count = sum(len(l) for l in merge.new_blocks.values()) + if verbose: + print("============================== Merge Details ==============================") + print(" Parsed {0} original files finding a total of {1} \"pragma uvmf custom\" blocks".format(len(merge.rd), block_count)) + if verbose and (len(merge.found_blocks)>0): + for f in merge.found_blocks: + print(" File: {0}".format(f)) + for l in merge.found_blocks[f]: + print(" \"{0}\"".format(l['name'])) + print(" Copied {0} new files from generated source".format(len(merge.copied_files))) + if verbose and (len(merge.copied_files)>0): + print(" Files found in new output but not in merged source. List of copied file destinations:") + for f in merge.copied_files: + print(" {0}".format(f)) + print(" Found {0} new \"pragma uvmf custom\" blocks in generated source".format(new_block_count)) + if verbose and (len(merge.new_blocks)>0): + print(" Blocks found in new output but not in merged source. List of new blocks and their associated source file locations:") + for f in merge.new_blocks: + print(" File: {0}".format(f)) + for l in merge.new_blocks[f]: + print(" \"{0}\"".format(l)) + if verbose: + print("===========================================================================") + +class ConfigFileReader: + """Reads in a .f file and builds up array of files to parse""" + def __init__(self,fname,relative_to_file=False): + self.fname = fname + self.files = [] + try: + self.fh = open(fname,'r') + except IOError: + raise UserError("Unable to open -f/-F file "+fname) + self.lines = self.fh.readlines() + for line in self.lines: + # Strip comments + line = re.sub(r"(.*?)#.*",r"\1",line.rstrip()).strip() + # Elaborate environment variables + line = os.path.expandvars(line) + if (line != ""): + if relative_to_file: + line = os.path.normpath(os.path.dirname(os.path.abspath(fname))+os.path.sep+line) + self.files.append(line) + self.fh.close() + +class DataClass: + def __init__(self,parser,debug=False): + self.data = {'interfaces':{},'environments':{},'benches':{},'util_components':{},'qvip_environments':{},'qvip_library':{},'global':{}} + self.parser = parser + self.debug = debug + self.validators = {} + self.used_ac_items = [] + + def parseFile(self,fname): + try: + fs = open(fname) + except IOError: + raise UserError("Unable to open config file "+fname) + d = yaml.safe_load(fs) + fs.close() + try: + if 'uvmf' not in d.keys(): + raise UserError("Contents of "+fname+" not valid UVMF info") + except: + raise UserError("Contents of "+fname+" not valid UVMF info") + for k in d['uvmf'].keys(): + if k not in self.data.keys(): + raise UserError("Top-level element \""+k+"\" in "+fname+" is not valid. Allowed entries:\n "+str(self.data.keys())) + for elem in self.data.keys(): + try: self.data[elem].update(d['uvmf'][elem]) + except KeyError: + pass + + ## Validate various data structures against the associated schema + def validate(self): + self.validators = { + 'interfaces':InterfaceValidator(), + 'util_components':ComponentValidator(), + 'qvip_environments':QVIPEnvValidator(), + 'environments':EnvironmentValidator(), + 'benches':BenchValidator(), + 'global':GlobalValidator(), +# 'qvip_library':QVIPLibValidator(), ## Don't validate QVIP library info, for debug purposes only + } + ## Check for any incorrect top-level keys + for t in self.validators.keys(): + for c in self.data[t].keys(): + if (t=='global'): + v = self.data[t] + else: + v = self.data[t][c] + try: + self.validators[t].schema(v) + except MultipleInvalid as e: + resp = humanize_error(v,e).split('\n') + raise UserError("While validating "+t+" YAML '"+c+"':\n"+pprint.pformat(resp,indent=2)) + + def calculateRelativeVipLocation(self,compClass): + ## Determine relative path to "loc" if CWD is bench's "sim" directory + simpath = compClass.bench_location+"/bench_name/sim" + ret = os.path.relpath(compClass.vip_location,simpath) + ## Even on Windows, these need to be forward slashes because they'll be normalized within Tcl. Replace any backslashes with forward ones + ## Can't use pathlib here due to Python2 back-compat, just do a global search/replace + return ret.replace('\\','/') + + def calculateRelativeVipToCwd(self,compClass): + ret = os.path.relpath(os.getcwd(),compClass.vip_location) + return ret.replace('\\','/') + + def calculateRelativeBenchToCwd(self,compClass): + ret = os.path.relpath(os.getcwd(),compClass.bench_location) + return ret.replace('\\','/') + + def calculateRelativeInterfaceToCwd(self,compClass): + ret = os.path.relpath(os.getcwd(),compClass.vip_location+os.path.sep+compClass.interface_location) + return ret.replace('\\','/') + + def calculateRelativeEnvironmentToCwd(self,compClass): + ret = os.path.relpath(os.getcwd(),compClass.vip_location+os.path.sep+compClass.environment_location) + return ret.replace('\\','/') + + def setupGlobalVars(self,compClass): + try: + compClass.header = self.data['global']['header'] + except KeyError: + compClass.header = None + pass + try: + compClass.flat_output = (self.data['global']['flat_output'] == "True") + except KeyError: + compClass.flat_output = False + pass + try: + compClass.vip_location = self.data['global']['vip_location'] + except KeyError: + pass + try: + compClass.interface_location = self.data['global']['interface_location'] + except KeyError: + pass + try: + compClass.environment_location = self.data['global']['environment_location'] + except KeyError: + pass + try: + compClass.bench_location = self.data['global']['bench_location'] + except KeyError: + pass + compClass.relative_vip_from_sim = self.calculateRelativeVipLocation(compClass) + compClass.relative_vip_from_cwd = self.calculateRelativeVipToCwd(compClass) + compClass.relative_bench_from_cwd = self.calculateRelativeBenchToCwd(compClass) + compClass.relative_interface_from_cwd = self.calculateRelativeInterfaceToCwd(compClass) + compClass.relative_environment_from_cwd = self.calculateRelativeEnvironmentToCwd(compClass) + return compClass + + ## Generate everything from the data structures + def buildElements(self,genarray,verify=True,build_existing=False,archive_yaml=True): + count = 0 + self.interfaceDict = {} + try: + arrlen = len(genarray) + except TypeError: + arrlen = 0 + pass + for interface_name in self.data['interfaces']: + if ((arrlen>0) and (interface_name in genarray)) or (arrlen==0): + self.interfaceDict[interface_name] = self.generateInterface(interface_name,build_existing,archive_yaml) + count = count + 1 + self.environmentDict = {} + for environment_name in self.data['environments']: + if ((arrlen>0) and (environment_name in genarray)) or (arrlen==0): + self.environmentDict[environment_name] = self.generateEnvironment(environment_name,build_existing,archive_yaml) + count = count + 1 + self.benchDict = {} + for bench_name in self.data['benches']: + if ((arrlen>0) and (bench_name in genarray)) or (arrlen==0): + self.benchDict[bench_name] = self.generateBench(bench_name,build_existing,archive_yaml) + count = count + 1 + ## Check to see if any utility components were defined but never instantiated, flag that as a warning + for util_comp in self.data['util_components']: + if util_comp not in self.used_ac_items: + print(" WARNING : Utility component \""+util_comp+"\" was defined but never used. It will not be generated.") + ## Verify that something was produced (possible that YAML input was empty or genarray had no matches) + if count==0 and verify: + raise UserError("No output was produced!") + + + def recursion_print(self,recurse_list): + r = "" + for i,s in enumerate(recurse_list): + r = r + s + if i != len(recurse_list)-1: + r = r + " -> " + return r + + ## This method recursively searches all environments from the specified level down for QVIP subenvs, compiling + ## a list of underlying QVIP agents, their subenvironment parent names, their import list and active/passive info + def getQVIPAgents(self,topEnv,recurse_list=[]): + struct = self.data['environments'] + # Check for recursion, error out if detected + if topEnv in recurse_list: + raise UserError("Sub-environment recursion detected within environment \""+topEnv+"\". Tree: \""+self.recursion_print(recurse_list+[topEnv])+"\"") + try: + env = struct[topEnv] + except KeyError: + raise UserError("Unable to find environment \""+topEnv+"\" in defined environments (available list is "+str(struct.keys())) + agent_list = [] + import_list = [] + ## First look for any local QVIP subenvironments and extract those agent names + try: + qvip_subenv_list = env['qvip_subenvs'] + except KeyError: + qvip_subenv_list = [] + pass + for s in qvip_subenv_list: + try: + d = self.data['qvip_environments'][s['type']] + except KeyError: + raise UserError("Definition for QVIP subenvironment \""+s['name']+"\" of type \""+s['type']+"\" is not found") + local_agents = d['agents'] + for a in local_agents: + try: + active_passive = a['active_passive'] + except KeyError: + active_passive = None + agent_list = agent_list + [{ 'name': a['name'], 'parent': s['type'], 'active_passive': active_passive }] + try: + import_list = import_list + a['imports'] + except KeyError: pass + ## Next drill down and call getQVIPAgents on any non-QVIP subenvironments + try: + subenv_list = env['subenvs'] + except KeyError: + subenv_list = [] + pass + for s in subenv_list: + qstruct = self.getQVIPAgents(s['type'],recurse_list+[topEnv]) + agent_list = agent_list + qstruct['alist']; + import_list = import_list + qstruct['ilist']; + ## Finally, uniquify the import list + ilist = import_list + import_list = [] + for i in ilist: + if i not in import_list: + import_list = import_list + [ i ] + return {'alist':agent_list, 'ilist':import_list} + + ## This method will return a list of environments at the provided environment level or recursively. + def getEnvironments(self,topEnv,recursive=True): + struct = self.data['environments'] + try: + env = struct[topEnv] + except KeyError: + raise UserError("Unable to find environment \""+topEnv+"\" in defined environments (available list is "+str(struct.keys())) + envs = [] + try: + envs = env['subenvs'] + except KeyError: pass + if not recursive: + return envs + for subenv in envs: + envs = envs + self.getEnvironments(subenv['type'],recursive=True) + return envs + + ## This method takes a dotted component hierarchy string and returns + ## the same but with underscores. For use in cases where a unique identifier + ## is required. Removes final entry in component hierarchy too. + def getUniqueID(self,val): + l = val.split(".") + return "uvm_test_top."+'.'.join(l[:-1])+"." + + ## This method returns an ordered list of information on ALL BFMs from a given top-level environment, down. + ## The list entries all have the following structure: + ## - BFM Name ('bfm_name') + ## - BFM Type ('bfm_type') + ## - BFM Parent Type ('parent_type') + ## - Environment Path ('env_path') + ## - VIP Library Env Variable Name ('lib_env_var_name') (only valid for non-QVIP) + ## - QVIP/Non-QVIP flag ('is_qvip') + ## - Initiator/Responder info ('initiator_responder') + ## - VeloceReady flag ('veloce_ready') + def getAllAgents(self,env_type,env_inst,isQVIP,envPath): + alist = [] + if (isQVIP==1): + # This environment we've been given is a QVIP environment which is stored + # in a different structure + struct = self.data['qvip_environments'] + try: + env = struct[env_type] + except KeyError: + raise UserError("Unable to find QVIP environment \""+env_type+"\" in defined QVIP environments (available list is "+str(struct.keys())+")") + for a in env['agents']: + ## All we have is the name of each BFM. + alist = alist + [{ 'bfm_name': a['name'], + 'bfm_type': 'unknown', + 'parent_type': env_type, + 'env_path': envPath+"."+a['name'], + 'lib_env_var_name':'unknown', + 'is_qvip': 1 , + 'initiator_responder':'UNKNOWN', + 'veloce_ready':False }] + ## No nesting with QVIP environments so safe to just return here + return alist + else: + struct = self.data['environments'] + try: + env = struct[env_type] + except KeyError: + raise UserError("Unable to find environment \""+env_type+"\" in defined environments (available list is "+str(struct.keys())) + ## We're looking at a non-QVIP environment. This can have underlying QVIP and/or non-QVIP sub-environments as well as local agents. + ## Look for underlying QVIP subenvs first, then non-QVIP sub-envs, then local agents. + try: + qvip_subenvs = env['qvip_subenvs'] + for e in qvip_subenvs: + alist = alist + self.getAllAgents(e['type'],e['name'],1,envPath+"."+e['name']) + except KeyError: pass + try: + subenvs = env['subenvs'] + for e in subenvs: + alist = alist + self.getAllAgents(e['type'],e['name'],0,envPath+"."+e['name']) + except KeyError: pass + try: + agents = env['agents'] + for a in agents: + try: + env_var_name = self.data['interfaces'][a['type']]['vip_lib_env_variable'] + except KeyError: + env_var_name = 'UVMF_VIP_LIBRARY_HOME' + pass + try: + init_resp = a['initiator_responder'] + except KeyError: + init_resp = 'INITIATOR' + pass + try: + veloce_ready = (self.data['interfaces'][a['type']]['veloce_ready']=="True") + except KeyError: + veloce_ready = True + pass + infact_ready = ('infact_ready' in self.data['interfaces'][a['type']].keys() and self.data['interfaces'][a['type']]['infact_ready']) + + alist = alist + [{ 'bfm_name': a['name'], + 'bfm_type': a['type'], + 'parent_type': env_type, + 'env_path': envPath+"."+a['name'], + 'lib_env_var_name':env_var_name, + 'is_qvip': 0, + 'initiator_responder':init_resp , + 'veloce_ready':veloce_ready, + 'infact_ready':infact_ready }] + except KeyError: pass + return alist + + ## This method returns an ordered list of information on ALL BFMs from a given top-level environment, down. + ## The list entries all have the following structure: + ## - BFM Name ('bfm_name') + ## - BFM Type ('bfm_type') + ## - BFM Parent Type ('parent_type') + ## - Environment Path ('env_path') + ## - VIP Library Env Variable Name ('lib_env_var_name') (only valid for non-QVIP) + ## - QVIP/Non-QVIP flag ('is_qvip') + ## - Initiator/Responder info ('initiator_responder') + ## - VeloceReady flag ('veloce_ready') + def getAllScoreboards(self,env_type,env_inst,envPath): + sblist = [] + struct = self.data['environments'] + try: + env = struct[env_type] + except KeyError: + raise UserError("Unable to find environment \""+env_type+"\" in defined environments (available list is "+str(struct.keys())) + try: + subenvs = env['subenvs'] + for e in subenvs: + sblist = sblist + self.getAllScoreboards(e['type'],e['name'],envPath+"."+e['name']) + except KeyError: pass + try: + sbs = env['scoreboards'] + for sb in sbs: + sblist = sblist + [envPath+"."+sb['name']] + except KeyError: pass + return sblist + + ## This method can be employed to return either a list of (non-QVIP) agents at the provided environment + ## level or recursively, searching through all sub-environments and down. + def getAgents(self,topEnv,recursive=True,givePath=False,parentPath=[]): + struct = self.data['environments'] + try: + env = struct[topEnv] + except KeyError: + raise UserError("Unable to find environment \""+topEnv+"\" in defined environments (available list is "+str(struct.keys())) + agents = [] + try: + agents = env['agents'] + except: + agents = [] + pass + if not givePath: + structure = agents + else: + structure = [] + for agent in agents: + try: + vip_lib_env_variable = self.data['interfaces'][agent['type']]['vip_lib_env_variable'] + except KeyError: + vip_lib_env_variable = "UVMF_VIP_LIBRARY_HOME" + structure = structure + [{ 'envpath' : parentPath, 'agent' : agent, 'vip_lib_env_variable' : vip_lib_env_variable }] + if not recursive: + return structure + try: + subEnvs = env['subenvs'] + for subEnv in subEnvs: + structure = structure + self.getAgents(subEnv['type'],recursive=True,givePath=givePath,parentPath=parentPath+[subEnv['name']]) + except KeyError: pass + return structure + + def dataExtract(self,keys,dictionary): + ## Pull the specified keys out of the given structure. If the key + ## does not exist return None for the given value + ret = [] + for key in keys: + try: + ret = ret + [dictionary[key]] + except KeyError: + ret = ret + [None] + pass + return ret + + def generateEnvironment(self,name,build_existing=False,archive_yaml=True): + env = EnvironmentClass(name) + struct = self.data['environments'][name] + qvip_agents_dot = [] + qvip_agents_und = [] + valid_ap_list = [] + valid_ae_list = [] + valid_qsubenv_list = [] + env_has_extdef_items = False + env = self.setupGlobalVars(env) + ## Extract any environment-level parameters and add them + try: + for param in struct['parameters']: + pname,ptype,pval = self.dataExtract(['name','type','value'],param) + env.addParamDef(pname,ptype,pval) + except KeyError: pass + try: + for param in struct['hvl_pkg_parameters']: + pname,ptype,pval = self.dataExtract(['name','type','value'],param) + env.addHvlPkgParamDef(pname,ptype,pval) + except KeyError: pass + ## Extract any configuration variable settings and add them + try: + for cv_val in struct['config_variable_values']: + cvvname,cvvval = self.dataExtract(['name','value'],cv_val) + env.addConfigVariableValue(cvvname,cvvval) + except KeyError: pass + ## Drill down into any QVIP subenvironments for import information, that'll be needed here + qstruct = self.getQVIPAgents(name) + ilist = qstruct['ilist'] + for i in ilist: + env.addImport(i) + ## Call out any locally defined imports + try: + for imp in struct['imports']: + env.addImport(imp['name']) + except KeyError: pass + ## If imp-decl macros are needed, add them + try: + for impdecl in struct ['imp_decls']: + env.addImpDecl(impdecl['name']) + except KeyError: pass + try: + for nonUvmfComps in struct ['non_uvmf_components']: + cname,ctype = self.dataExtract(['name', 'type'],nonUvmfComps) + try: + cextdef = ( nonUvmfComps['extdef'] == 'True' ) + env_has_extdef_items = True + except KeyError: + pass + try: + cparams_array = nonUvmfComps['parameters'] + except KeyError: + cparams_array = {} + pass + cparams = {} + for item in cparams_array: + n,v = self.dataExtract(['name','value'],item) + cparams[n] = v + env.addNonUvmfComponent(cname,ctype,cparams) + except KeyError: pass + try: + for qvipMemAgents in struct ['qvip_memory_agents']: + qmaname,qmatype,qmaqenv = self.dataExtract(['name', 'type','qvip_environment'],qvipMemAgents) + try: + qmaparams_array = qvipMemAgents['parameters'] + except KeyError: + qmaparams_array = {} + pass + qmaparams = {} + for item in qmaparams_array: + n,v = self.dataExtract(['name','value'],item) + qmaparams[n] = v + env.addQvipMemoryAgent(qmaname,qmatype,qmaqenv,qmaparams) + except KeyError: pass + ## The order of the following loops is important. The order in which local agents, sub-environments and QVIP + ## sub-environments are added must match the order in which they will be added at the bench level, otherwise + ## things will be configured out-of-order. + ## The order is as follows: + ## QVIP subenvs + ## Custom sub-environments + ## Locally defined custom interfaces + ## Look for defined QVIP sub-environments and add those + try: + for subenv in struct['qvip_subenvs']: + n,t = self.dataExtract(['name','type'],subenv) + try: + qvipStruct = self.data['qvip_environments'][t] + except KeyError: + raise UserError("QVIP environment \""+t+"\" in environment \""+name+"\" is not defined") + alist = [] + for a in qvipStruct['agents']: + alist = alist + [a['name']] + qvip_agents_dot = qvip_agents_dot + [n+"."+a['name']] + qvip_agents_und = qvip_agents_und + [n+"_"+a['name']] + valid_qsubenv_list = valid_qsubenv_list + [n] + env.addQvipSubEnv(name=n,envPkg=t,agentList=alist) + except KeyError: pass + ## Look for defined sub-environments and add them + try: + for subenv in struct['subenvs']: + ename,etype = self.dataExtract(['name','type'],subenv) + try: + subextdef = ( subenv['extdef'] == 'True' ) + env_has_extdef_items = True + except KeyError: + pass + try: + eparams_array = subenv['parameters'] + except KeyError: + eparams_array = {} + pass + eparams = {} + num = 0 + for item in eparams_array: + n,v = self.dataExtract(['name','value'],item) + eparams[n] = v + num += 1 + ## Determine how many agents are defined in the subenvironment as that is a required argument going into + ## this API call. This is a recursive count of agents. + agents = self.getAgents(etype,recursive=True) + ## Also find any underlying QVIP agents underneath this subenvironment (nested underneath underlying QVIP subenvs) + qvip_agents_struct = self.getQVIPAgents(etype); + qvip_agents = qvip_agents_struct['alist'] + if agents==None: + raise UserError("Sub-environment type \""+etype+"\" used in environment \""+name+"\" is not found") + self.check_parameters('environment',name,'subenv',ename,etype,eparams_array,self.data['environments'][etype]) + ## Check if subenv has a register model defined unless asked explicitly to avoid it + try: + v = subenv['use_register_model']=='True' + except KeyError: + v = True + pass + if v: + try: + rm = self.data['environments'][etype]['register_model'] + except KeyError: + rm = None + pass + else: + rm = None + if not rm: + rm_pkg = None + rm_block_class = None + else: + try: + rm_pkg = rm['reg_model_package'] + except KeyError: + rm_pkg = etype+"_reg_pkg" + pass + try: + rm_block_class = rm['reg_block_class'] + except KeyError: + rm_block_class = etype+"_reg_model" + pass + env.addSubEnv(ename,etype,len(agents)+len(qvip_agents),eparams,rm_pkg,rm_block_class) + env_def = self.data['environments'][etype] + try: + env_ap_list = env_def['analysis_ports'] + for env_ap in env_ap_list: + valid_ap_list = valid_ap_list + [ename+"."+env_ap['name']] + except KeyError: pass + try: + env_ae_list = env_def['analysis_exports'] + for env_ae in env_ae_list: + valid_ae_list = valid_ae_list + [ename+"."+env_ae['name']] + except KeyError: pass + except KeyError: pass + ## Locally defined agent instantiations + try: + for agent in self.getAgents(name,recursive=False): + aname,atype = self.dataExtract(['name','type'],agent) + try: + aextdef = ( agent['extdef'] == 'True' ) + env_has_extdef_items = True + except KeyError: + pass + try: + aparams_list = agent['parameters'] + except KeyError: + aparams_list = [] + pass + aparams = {} + for item in aparams_list: + n,v = self.dataExtract(['name','value'],item) + aparams[n] = v; + try: + intf = self.data['interfaces'][atype] + except KeyError: + raise UserError("Agent type \""+atype+"\" in environment \""+name+"\" is not recognized") + try: + initResp = agent['initiator_responder'] + except KeyError: + initResp = 'INITIATOR' + pass + self.check_parameters('environment',name,'agent',agent['name'],atype,aparams_list,self.data['interfaces'][atype]) + env.addAgent(agent['name'],atype,intf['clock'],intf['reset'],aparams,initResp) + valid_ap_list = valid_ap_list + [agent['name']+".monitored_ap"] + except KeyError: pass + defined_ac_items = [] + try: + ac_items = struct['analysis_components'] + except KeyError: + ac_items = [] + pass + for ac_item in ac_items: + ac_type,ac_name = self.dataExtract(['type','name'],ac_item) + try: + ac_params = ac_item['parameters'] + except KeyError: + ac_params = [] + pass + ## Don't go through the trouble of poking at the definition of the analysis component if it was already + ## used before. Just instantiate it + try: + extdef = (ac_item['extdef'] == 'True') + env_has_extdef_items = True + except KeyError: + extdef = False + pass + if (ac_type not in defined_ac_items) and (not extdef): + try: + definition = self.data['util_components'][ac_type] + except KeyError: + raise UserError("No definition found for component \""+ac_name+"\" of type \""+ac_type) + ac_type_type = definition['type'] + exports = {} + try: + for item in definition['analysis_exports']: + exports[item['name']] = item['type'] + except KeyError: pass + ports = {} + try: + for item in definition['analysis_ports']: + ports[item['name']] = item['type'] + except KeyError: pass + qvip_exports = {} + try: + for item in definition['qvip_analysis_exports']: + qvip_exports[item['name']] = item['type'] + except KeyError: pass + try: + parameters = definition['parameters'] + except KeyError: + parameters = [] + pass + try: + ac_mtlb_ready = definition['mtlb_ready']==True + except KeyError: + ac_mtlb_ready = False + env.defineAnalysisComponent(ac_type_type,ac_type,exports,ports,qvip_exports,parameters,mtlbReady=ac_mtlb_ready) + defined_ac_items = defined_ac_items + [ac_type] + if ac_type not in self.used_ac_items: + self.used_ac_items = self.used_ac_items + [ac_type] + if not extdef: + self.check_parameters('environment',name,ac_type_type,ac_name,ac_type,ac_params,self.data['util_components'][ac_type]) + env.addAnalysisComponent(ac_name,ac_type,ac_params,extdef) + try: ports + except NameError: ports = None + if ports is not None: + for ap in ports: + valid_ap_list = valid_ap_list + [ac_name+"."+ap] + try: exports + except NameError: exports = None + if exports is not None: + for ae in exports: + valid_ae_list = valid_ae_list + [ac_name+"."+ae] + try: qvip_exports + except NameError: qvip_exports = None + if qvip_exports is not None: + for qae in qvip_exports: + valid_ae_list = valid_ae_list + [ac_name+"."+qae] + try: + sb_items = struct['scoreboards'] + except KeyError: + sb_items = [] + pass + for sb_item in sb_items: + sb_name,sb_type,trans_type = self.dataExtract(['name','sb_type','trans_type'],sb_item) + try: + sb_params_list = sb_item['parameters'] + except KeyError: + sb_params_list = [] + pass + sb_params = {} + for item in sb_params_list: + n,v = self.dataExtract(['name','value'],item) + sb_params[n] = v + env.addUvmfScoreboard(sb_name,sb_type,trans_type,sb_params) + valid_ae_list = valid_ae_list + [sb_name+".expected_analysis_export"] + valid_ae_list = valid_ae_list + [sb_name+".actual_analysis_export"] + try: + for item in struct['analysis_ports']: + n,t,c = self.dataExtract(['name','trans_type','connected_to'],item) + if c not in valid_ap_list: + mess = "TLM connected_to entry \""+c+"\" listed in analysis_ports for environment \""+name+"\" not a valid TLM driver name. \nValid names:" + for ap in valid_ap_list: + mess = mess+"\n "+ap + if env_has_extdef_items: + mess = mess+"\nPort may be on externally defined component - Skipping check on this connnection." + print(mess) + else: + raise UserError(mess) + env.addAnalysisPort(n,t,c) + except KeyError: pass + try: + for item in struct['analysis_exports']: + n,t,c = self.dataExtract(['name','trans_type','connected_to'],item) + if c not in valid_ae_list: + mess = "TLM connected_to entry \""+c+"\" listed in analysis_exports for environment \""+name+"\" not a valid TLM receiver name. \nValid names:" + for ae in valid_ae_list: + mess = mess+"\n "+ae + if env_has_extdef_items: + mess = mess+"\nPort may be on externally defined component - Skipping check on this connnection." + print(mess) + else: + raise UserError(mess) + env.addAnalysisExport(n,t,c) + except KeyError: pass + try: + for item in struct['qvip_connections']: + d,r,k,v = self.dataExtract(['driver','receiver','ap_key','validate'],item) + rlist = r.split(".") + ## Allow the driver (QVIP) to contain regular "." hierarchy for clarity. Convert any found + ## to underscores in order to adhere to the API + dm = re.sub(r'\.','_',d) + if not v: + v = 'True' + if v == 'True': + if dm not in qvip_agents_und: + mess = "QVIP TLM Driver name entry \""+d+"\" listed in qvip_connections for environment \""+name+"\" not a valid QVIP agent name. \nValid names:" + for b in qvip_agents_dot: + mess = mess+"\n "+b + mess = mess+"\nNote: Underscores are valid substitutions within YAML for dot delimeters in this list of valid names.\n" + if env_has_extdef_items: + mess = mess+"\nPort may be on externally defined component - Skipping check on this connnection." + print(mess) + else: + raise UserError(mess) + if r not in valid_ae_list: + mess = "QVIP TLM Receiver name entry \""+r+"\" listed in qvip_connections for environment \""+name+"\" not a valid QVIP TLM receiver name. \nValid names:" + for ae in valid_ae_list: + mess = mess+"\n "+ae + if env_has_extdef_items: + mess = mess+"\nPort may be on externally defined component - Skipping check on this connnection." + print(mess) + else: + raise UserError(mess) + env.addQvipConnection(dm,k,'.'.join(rlist[:-1]),rlist[-1],v) + except KeyError: pass + try: + for conn in struct['tlm_connections']: + d,r,v = self.dataExtract(['driver','receiver', 'validate'],conn) + dlist = d.split(".") + rlist = r.split(".") + ## The driver and receiver entries provided need to be split to work with the API in uvmf_gen + if not v: + v = 'True' + if v == 'True': + if d not in valid_ap_list: + mess = "TLM Driver name entry \""+d+"\" listed in tlm_connections for environment \""+name+"\" not a valid TLM driver name. \nValid names:" + for ap in valid_ap_list: + mess = mess+"\n "+ap + if dlist[0] not in valid_qsubenv_list: + if env_has_extdef_items: + mess = mess+"\nPort may be on externally defined component - Skipping check on this connnection." + print(mess) + else: + raise UserError(mess) + if r not in valid_ae_list: + mess = "TLM Receiver name entry \""+r+"\" listed in tlm_connections for environment \""+name+"\" not a valid TLM receiver name. \nValid names:" + for ae in valid_ae_list: + mess = mess+"\n "+ae + if env_has_extdef_items: + mess = mess+"\nPort may be on externally defined component - Skipping check on this connnection." + print(mess) + else: + raise UserError(mess) + env.addConnection('.'.join(dlist[:-1]),dlist[-1],'.'.join(rlist[:-1]),rlist[-1],v) + except KeyError: pass + try: + for cfg_item in struct['config_vars']: + n,t,c = self.dataExtract(['name','type','comment'],cfg_item) + if not c: + c = "" + try: + crand = (cfg_item['isrand']=="True") + except KeyError: + crand = False + pass + cval = '' + try: + cval = cfg_item['value'] + except KeyError: pass + try: + cvud = cfg_item['unpacked_dimension'] + except KeyError: + cvud = "" + pass + env.addConfigVar(n,t,crand,cval,c,cvud) + except KeyError: pass + try: + for item in struct['config_constraints']: + n,v,c = self.dataExtract(['name','value','comment'],item) + if not c: + c = "" + env.addConfigVarConstraint(n,v,c) + except KeyError: pass + try: + regInfo = struct['register_model'] + except KeyError: + regInfo = None + pass + if regInfo != None: + try: + reg_model_pkg = regInfo['reg_model_package'] + except KeyError: + reg_model_pkg = name+"_reg_pkg" + pass + try: + reg_blk_class = regInfo['reg_block_class'] + except KeyError: + reg_blk_class = name+"_reg_model" + pass + try: + maps = regInfo['maps'] + except KeyError: + maps = None + pass + if maps==None: + use_adapter = False + use_explicit_prediction = False + sequencer = None + trans = None + adapter = None + mapName = None + qvip_agent = False + else: + try: + use_adapter = regInfo['use_adapter'] == "True" + except KeyError: + use_adapter = True + try: + use_explicit_prediction = regInfo['use_explicit_prediction'] == "True" + except KeyError: + use_explicit_prediction = True + maps = regInfo['maps'] + ## Currently only support a single map - this will change in the future, hopefully + if len(maps) != 1: + raise UserError("Register model in environment \""+name+"\" can only have one map defined") + ## Extract information regarding the interface we should be attaching to. + ## First, confirm that the name of the agent is a valid instance. This will return a list + ## of structures, each with an 'name' key and 'type' key. The interface we're attaching to + ## must match up with the 'name' key in this list somewhere + try: + qvip_agent = maps[0]['qvip_agent'] + except KeyError: + qvip_agent = "False" + pass + if qvip_agent == "False": + agent_list = self.getAgents(name,recursive=True) + agent_type = "" + for a in agent_list: + if a['name'] == maps[0]['interface']: + ## Testing for a defined type might be thought to be needed here but if it wasn't a + ## valid agent type the above check would never pass + agent_type = a['type'] + try: + agent_params = self.parameterSyntax(a['parameters']) + except KeyError: + agent_params = "" + pass + break + if agent_type == "": + raise UserError("For register map \""+maps[0]['name']+"\" in environment \""+name+"\" no interface \""+maps[0]['interface']+"\" was found") + sequencer = maps[0]['interface'] + trans = agent_type+"_transaction"+agent_params + adapter = agent_type+"2reg_adapter"+agent_params + mapName = maps[0]['name'] + else: + sequencer = maps[0]['interface'] + trans = "uvm_sequence_item" + adapter = "uvm_reg_adapter" + mapName = maps[0]['name'] + env.addRegisterModel( + sequencer=sequencer, + transactionType=trans, + adapterType=adapter, + busMap=mapName, + useAdapter=use_adapter, + useExplicitPrediction=use_explicit_prediction, + qvipAgent=qvip_agent, + regModelPkg=reg_model_pkg, + regBlockClass=reg_blk_class) + try: + dpi_def = struct['dpi_define'] + ca = "" + la = "" + try: + ca = dpi_def['comp_args'] + except KeyError: pass + try: + la = dpi_def['link_args'] + except KeyError: pass + env.setDPISOName(value=dpi_def['name'],compArgs=ca,linkArgs=la) + for f in dpi_def['files']: + env.addDPIFile(f) + try: + for imp in dpi_def['imports']: + sv_args = [] + try: + sv_args = imp['sv_args'] + except KeyError: pass + env.addDPIImport(imp['c_return_type'],imp['sv_return_type'],imp['name'],imp['c_args'],sv_args) + except KeyError: pass + try: + for exp in dpi_def['exports']: + intf.addDPIExport(exp) + except KeyError: pass + except KeyError: pass + try: + typedefs = struct['typedefs'] + for t in typedefs: + n,v = self.dataExtract(['name','type'],t) + env.addTypedef(n,v) + except KeyError: pass + ## UVMC Stuff + try: + env.addUVMCflags(struct['uvmc_flags']) + except KeyError: pass + try: + env.addUVMClinkArgs(struct['uvmc_link_args']) + except KeyError: pass + try: + cpp_files = struct['uvmc_files'] + for f in cpp_files: + env.addUVMCfile(f) + except KeyError: pass + try: + env.mtlbReady = (struct['mtlb_ready']=="True") + except KeyError: + pass + existing_component = False + try: + if not build_existing: + existing_component = (struct['existing_library_component']=="True") + except KeyError: + pass + if (existing_component == True): + print(" Skipping generation of predefined component "+str(name)) + else: + env.create(parser=self.parser,archive_yaml=archive_yaml) + return env + + def parameterSyntax(self,parameterList): + ## Take the parameter list provided and return the SV syntax for a parameterized type + ## This is expected to be of "parameterUseSchema" with 'name' and a 'value' keys + l = [] + for p in parameterList: + s = "."+p['name']+"("+p['value']+")" + l = l + [ s ] + fs = "#("+','.join(l)+")" + return fs + + def generateBench(self,name,build_existing=False,archive_yaml=True): + ## Isolate the YAML structure for this bench + struct = self.data['benches'][name] + ## Get the name of the top-level environment + top_env = struct['top_env'] + ## Confirm top-level environment is defined + if top_env not in self.data['environments']: + raise UserError("Bench \"{}\" top-env of type \"{}\" is not defined".format(name,top_env)) + ## Top-level environment parameters + try: + env_params_list = struct['top_env_params'] + except KeyError: + env_params_list = [] + pass + ## Build up simpler name/value pair dict of env params + env_params = {} + for p in env_params_list: + env_params[p['name']] = p['value'] + ## Check that parameterization is valid for the top-env + self.check_parameters('bench',name,'environment',top_env,'top_env',env_params_list,self.data['environments'][top_env]) + ## With this information we can create the bench class object + ben = BenchClass(name,top_env,env_params) + ben = self.setupGlobalVars(ben) + ## Look for clock and reset control settings (all optional) + try: + ben.clockHalfPeriod = struct['clock_half_period'] + except KeyError: pass + try: + ben.clockPhaseOffset = struct['clock_phase_offset'] + except KeyError: pass + try: + ben.resetAssertionLevel = (struct['reset_assertion_level']=='True') + except KeyError: pass + try: + ben.useDpiLink = (struct['use_dpi_link']=='True') + except KeyError: pass + try: + ben.resetDuration = struct['reset_duration'] + except KeyError: pass + try: + ben.activePassiveDefault = struct['active_passive_default'] + except KeyError: + ben.activePassiveDefault = 'ACTIVE' + pass + ## Check for inFact ready flag + ben.inFactEnabled = ('infact_enabled' in struct.keys() and struct['infact_enabled']=='True') + + ## Use co-emulation clk/rst generator + try: + ben.useCoEmuClkRstGen = (struct['use_coemu_clk_rst_gen']=='True') + except KeyError: pass + ## Set the veloceReady flag for the bench + try: + ben.veloceReady = (struct['veloce_ready'] == "True") + except KeyError: + ben.veloceReady = True + pass + ## Pull out bench-level parameter definitions, if any + try: + for param in struct['parameters']: + pname,ptype,pval = self.dataExtract(['name','type','value'],param) + ben.addParamDef(pname,ptype,pval) + except KeyError: pass + ## Drill down into any QVIP subenvironments for import information, that'll be needed here + qstruct = self.getQVIPAgents(top_env) + ilist = qstruct['ilist'] + for i in ilist: + ben.addImport(i) + ## Imports + try: + for imp in struct['imports']: + ben.addImport(imp['name']) + except KeyError: pass + ## Pull out active/passive list and produce more easily parsed dict keyed by the BFM names + try: + ap_list = struct['active_passive'] + except KeyError: + ap_list = [] + pass + ap_dict = {} + for i in ap_list: + ap_dict[i['bfm_name']] = i['value'] + ## Do the same for interface parameters + try: + ifp_list = struct['interface_params'] + except KeyError: + ifp_list = [] + ifp_dict = {} + for entry in ifp_list: + bfm_name = entry['bfm_name'] + param_list = entry['value'] + ifp_dict[bfm_name] = {} + for p in param_list: + ifp_dict[bfm_name][p['name']] = p['value'] + ## Determine if top_env has a register model associated with it + try: + e = self.data['environments'][top_env] + except KeyError: + raise UserError("Top-level env \""+top_env+"\" is not defined") + try: + rm = e['register_model'] + ben.topEnvHasRegisterModel = True + try: + rm_pkg = rm['reg_model_package'] + ben.regModelPkg = e['register_model']['reg_model_package'] + except KeyError: + ben.regModelPkg = top_env+"_reg_pkg" + pass + try: + ben.regBlockClass = e['register_model']['reg_block_class'] + except KeyError: + ben.regBlockClass = top_env+"_reg_model" + pass + except KeyError: + ben.topEnvHasRegisterModel = False + pass + ## Find BFMs and add those - order is important, must match how we instantiated the components + ## within the environment. Traverse the environment topology in the order in which sub-envs were + ## called out in the YAML. Use getAllAgents to intelligently traverse the topology and build up a list + ## of BFMs (may be a mix of QVIP and non-QVIP BFMs). Each entry in the resulting list will be a structure + ## with the following information: + ## - BFM Name + ## - BFM Type + ## - Environment Path + ## - QVIP/Non-QVIP flag + ## - Active/Passive flag + ## - Initiator/Responder flag + ## - Veloce Ready flag (for checking) + alist = self.getAllAgents(top_env,'environment',0,'environment') + ## Check for Veloce compatibility. If the bench has been flagged for veloce_ready then none of the underlying + ## non-QVIP agents can be flagged differently. QVIP is a different story, for now. + if ben.veloceReady: + for a in alist: + if a['is_qvip']==0: # Don't bother checking QVIP agents + if not a['veloce_ready']: + ## Fatal out if bench veloce_ready is TRUE but any agents underneath are FALSE + raise UserError("Bench \""+name+"\" is flagged veloce_ready True but underlying agent \""+a['env_path']+"\" of type \""+a['bfm_type']+"\" is flagged veloce_ready False") + valid_bfm_names = [] + ## Now that we have an ordered list of BFMs we can call the appropriate API call for each + for a in alist: + if a['env_path'].count('.')==1: + bfm_name = a['bfm_name'] + debugpath = 'environment' + else: + debugpath = re.sub(r'(.*)\.\w+',r'\1',a['env_path']) + bfm_name = re.sub(r'^environment\.','',a['env_path']) + bfm_name = re.sub(r'\.',r'_',bfm_name) + valid_bfm_names = valid_bfm_names + [bfm_name] + try: + active_passive = ap_dict[bfm_name] + except KeyError: + active_passive = ben.activePassiveDefault + if a['is_qvip']==1: + ## Add each QVIP BFM instantiation. Function API is slightly different for QVIP vs. non-QVIP + ben.addQvipBfm(name=a['bfm_name'],ifPkg=a['parent_type'],activity=active_passive,unique_id=self.getUniqueID(a['env_path'])) + else: + ## Name of each BFM is simplified if they live under the top-level env + ## Determine this by inspecting the env_path entry for each item and counting + ## the number of dots (.). If only one, means this BFM lives at the top-most + ## level. + try: + agentDef = self.data['interfaces'][a['bfm_type']] + except: + raise UserError("Definition for interface type \""+a['bfm_type']+"\" for instance \""+a['env_path']+"\" is not found") + try: + aParams = ifp_dict[bfm_name] + except KeyError: + aParams = {} + pass + infact_ready = ('infact_ready' in a.keys() and a['infact_ready']) + try: + port_list = agentDef['ports'] + except KeyError: + port_list = [] + ben.addBfm(name=bfm_name,ifPkg=a['bfm_type'],clk=agentDef['clock'],rst=agentDef['reset'],activity=active_passive,parametersDict=aParams,sub_env_path=debugpath,agentInstName=a['bfm_name'],vipLibEnvVariable=a['lib_env_var_name'],initResp=a['initiator_responder'],inFactReady=infact_ready,portList=port_list) + ## Check that all keys in the ifp_dict and ap_dict match something in the valid_bfm_names list that + ## was based on the actual UVM component hierarchy elements. If not, it probably means we have a typo somewhere in the bench YAML + for k in ifp_dict.keys(): + if k not in valid_bfm_names: + mess = "BFM name entry \""+k+"\" listed in interface_params structure for bench \""+name+"\" but not a valid BFM name. Valid BFM names:" + for b in valid_bfm_names: + mess = mess+"\n "+b + raise UserError(mess) + for k in ap_dict.keys(): + if k not in valid_bfm_names: + mess = "BFM name entry \""+k+"\" listed in active_passive structure for bench \""+name+"\" but not a valid BFM name. Valid BFM names:" + for b in valid_bfm_names: + mess = mess+"\n "+b + raise UserError(mess) + ## Now drill down again but this time find any DPI packages - these could be defined at any + ## interface or environment, so getAgents isn't good enough. Also need to call getEnvironments + dpi_packages = [] + vinfo_interface_dpi_dependencies = [] + vinfo_environment_dpi_dependencies = [] + for agent in self.getAgents(top_env,recursive=True): + try: + dpi_pkg = self.data['interfaces'][agent['type']]['dpi_define']['name'] + if dpi_pkg not in dpi_packages: + dpi_packages.append(dpi_pkg) + #vinfo_interface_dpi_dependencies.append(self.data['interfaces'][agent['type']]['dpi_define']['name']) + vinfo_interface_dpi_dependencies.append(agent['type']) + except KeyError: pass + envs = self.getEnvironments(top_env,recursive=True) + ## Also add the top-environment to the array when searching for DPI + for env in envs+[{'type':top_env}]: + try: + dpi_pkg = self.data['environments'][env['type']]['dpi_define']['name'] + if dpi_pkg not in dpi_packages: + dpi_packages.append(dpi_pkg) + #vinfo_environment_dpi_dependencies.append(self.data['environments'][env['type']]['dpi_define']['name']) + vinfo_environment_dpi_dependencies.append(env['type']) + except KeyError: pass + for d in dpi_packages: + ben.addDPILibName(d) + for d in vinfo_interface_dpi_dependencies: + ben.addVinfoDependency("comp_"+d+"_pkg_c_files") + for d in vinfo_environment_dpi_dependencies: + ben.addVinfoDependency("comp_"+d+"_env_pkg_c_files") + sblist = self.getAllScoreboards(top_env,'environment','environment') + try: sblist + except NameError: sblist = None + if sblist is not None: + for sb in sblist: + ben.addScoreboard(sb) + try: + for t in struct['additional_tops']: + ben.addTopLevel(t) + except KeyError: pass + try: + ben.mtlbReady = (struct['mtlb_ready']=="True") + except KeyError: + pass + try: + ben.useBCR = (struct['use_bcr']=="True") + except KeyError: + ben.useBCR = False + existing_component = False + try: + if not build_existing: + existing_component = (struct['existing_library_component']=="True") + except KeyError: + pass + if (existing_component == True): + print(" Skipping generation of predefined component "+str(name)) + else: + ben.create(parser=self.parser,archive_yaml=archive_yaml) + return ben + + def generateInterface(self,name,build_existing=False,archive_yaml=True): + intf = InterfaceClass(name) + struct = self.data['interfaces'][name] + intf.clock = struct['clock'] + intf.reset = struct['reset'] + intf = self.setupGlobalVars(intf) + try: + intf.resetAssertionLevel = (struct['reset_assertion_level'] == 'True') + except KeyError: pass + try: + intf.useDpiLink = (struct['use_dpi_link']=='True') + except KeyError: pass + try: + intf.genInBoundStreamingDriver = (struct['gen_inbound_streaming_driver']=='True') + except KeyError: pass + try: + intf.vipLibEnvVariable = struct['vip_lib_env_variable'] + except KeyError: pass + try: + for imp in struct['imports']: + intf.addImport(imp['name']) + except KeyError: pass + try: + for item in struct['parameters']: + n,t,v = self.dataExtract(['name','type','value'],item) + intf.addParamDef(n,t,v) + except KeyError: pass + try: + for item in struct['hdl_pkg_parameters']: + n,t,v = self.dataExtract(['name','type','value'],item) + intf.addHdlPkgParamDef(n,t,v) + except KeyError: pass + try: + for item in struct['hvl_pkg_parameters']: + n,t,v = self.dataExtract(['name','type','value'],item) + intf.addHvlPkgParamDef(n,t,v) + except KeyError: pass + try: + for item in struct['hdl_typedefs']: + n,t = self.dataExtract(['name','type'],item) + intf.addHdlTypedef(n,t) + except KeyError: pass + try: + for item in struct['hvl_typedefs']: + n,t = self.dataExtract(['name','type'],item) + intf.addHvlTypedef(n,t) + except KeyError: pass + try: + for port in struct['ports']: + n,w,d = self.dataExtract(['name','width','dir'],port) + if not re.search(r"^(input|output|inout)$",d): + raise UserError("Direction \""+d+"\" invalid for port \""+n+"\" in interface \""+name+"\"") + try: + r = (port['reset_value']) + except KeyError: + r = "'bz" + intf.addPort(n,w,d,r) + except KeyError: pass + try: + for trans in struct['transaction_vars']: + n,t,c = self.dataExtract(['name','type','comment'],trans) + if not c: + c = "" + try: + trand = (trans['isrand']=="True") + except KeyError: + trand = False + pass + try: + tcomp = (trans['iscompare']=="True") + except KeyError: + tcomp = True + pass + try: + ud = trans['unpacked_dimension'] + except KeyError: + ud = "" + pass + intf.addTransVar(n,t,isrand=trand,iscompare=tcomp,unpackedDim=ud,comment=c) + except KeyError: pass + try: + for cfg in struct['config_vars']: + n,t,c = self.dataExtract(['name','type','comment'],cfg) + if not c: + c = "" + try: + crand = (cfg['isrand']=="True") + except KeyError: + crand = False + pass + cval = '' + try: + cval = cfg['value'] + except KeyError: pass + try: + cvud = cfg['unpacked_dimension'] + except KeyError: + cvud = "" + pass + intf.addConfigVar(n,t,crand,cval,c,cvud) + except KeyError: pass + try: + for item in struct['transaction_constraints']: + n,v,c = self.dataExtract(['name','value','comment'],item) + if not c: + c = "" + intf.addTransVarConstraint(n,v,c) + except KeyError: pass + try: + for item in struct['config_constraints']: + n,v,c = self.dataExtract(['name','value','comment'],item) + if not c: + c = "" + intf.addConfigVarConstraint(n,v,c) + except KeyError: pass + try: + response_info = struct['response_info'] + resp_op = response_info['operation'] + intf.specifyResponseOperation(resp_op) + resp_data = response_info['data'] + intf.specifyResponseData(resp_data) + print("Warning: response_info YAML structure deprecated. Slave agent response data now determined by arguments to respond_and_wait_for_next_transfer task within generated driver_bfm.") + except KeyError: pass + try: + dpi_def = struct['dpi_define'] + ca = "" + la = "" + try: + ca = dpi_def['comp_args'] + except KeyError: pass + try: + la = dpi_def['link_args'] + except KeyError: pass + intf.setDPISOName(value=dpi_def['name'],compArgs=ca,linkArgs=la) + for f in dpi_def['files']: + intf.addDPIFile(f) + try: + for imp in dpi_def['imports']: + sv_args = [] + try: + sv_args = imp['sv_args'] + except KeyError: pass + intf.addDPIImport(imp['c_return_type'],imp['sv_return_type'],imp['name'],imp['c_args'],sv_args) + except KeyError: pass + try: + for exp in dpi_def['exports']: + intf.addDPIExport(exp) + except KeyError: pass + except KeyError: pass + intf.inFactReady = ('infact_ready' in struct.keys() and struct['infact_ready']) + try: + intf.mtlbReady = (struct['mtlb_ready']=="True") + except KeyError: + pass + try: + intf.veloceReady = (struct['veloce_ready'] == "True") + except KeyError: + intf.veloceReady = True + pass + try: + intf.enableFunctionalCoverage = (struct['enable_functional_coverage'] == "True") + except KeyError: pass + if intf.veloceReady == True: + try: + for trans in struct['transaction_vars']: + try: + if trans['unpacked_dimension'] != "": + raise UserError("Interface \""+name+"\" flagged to be Veloce ready but transaction variable \""+trans['name']+"\" has specified an unpacked dimension") + except KeyError: pass + except KeyError: + ## If this happens it means there are no transaction variables, which is also illegal + raise UserError("Interface \"{0}\" flagged to be Veloce ready but no transaction variables have been defined. Must define at least one".format(name)) + pass + try: + for cfg in struct['config_vars']: + try: + if cfg['unpacked_dimension'] != "": + raise UserError("Interface \""+name+"\" flagged to be Veloce ready but configuration variable \""+cfg['name']+"\" has specified an unpacked dimension") + except KeyError: pass + except KeyError: pass + ## If this happens it means there are no transaction variables, which is also illegal +# raise UserError("Interface \"{0}\" flagged to be Veloce ready but no transaction variables have been defined. Must define at least one".format(name)) +# pass + ## Also possible that there was a transaction variables array defined but its empty. Also illegal + if len(struct['transaction_vars'])==0: + raise UserError("Interface \"{0}\" flagged to be Veloce ready but no transaction variables have been defined. Must define at least one".format(name)) + existing_component = False + try: + if not build_existing: + existing_component = (struct['existing_library_component']=="True") + except KeyError: + pass + if existing_component == True: + print(" Skipping generation of predefined component "+str(name)) + else: + intf.create(parser=self.parser,archive_yaml=archive_yaml) + return intf + + def check_parameters(self,parentType,parentName,instanceType,instanceName,definitionName,instanceParams,instanceDefinition): + ## Compare the parameters in a given instance to make sure that the names match up with + ## something in the list of parameters given in the definition. Can be used for any component. Pass + ## in the list of parameters for both. If problem found, display debug information + ## including the name of the parent component, the name and type of the instance and the + ## parameter in question. + ## Don't bother checking anything if the instiation was not provided any parameters. + if len(instanceParams) == 0: + return + try: + definitionParams = instanceDefinition['parameters'] + except KeyError: + raise UserError("When instantiating "+instanceType+" \""+instanceName+"\" of type \""+definitionName+"\" inside "+parentType+" \""+parentName+"\", parameters were provided but definition had no parameters") + ipn = [] + dpn = [] + for p in definitionParams: + dpn = dpn + [p['name']] + for p in instanceParams: + if p['name'] not in dpn: + raise UserError("Unable to find parameter \""+p['name']+"\" in definition of "+instanceType+" \""+definitionName+"\" as instance \""+instanceName+"\" in "+parentType+" \""+parentName+"\"") + +def run(): + ## When invoked, this script can read a series of provided YAML-based configuration files and parse them, building + ## up a database of information on the contained components. Each component will have an associated uvmf_gen class + ## created around it based on the contents. + + ## User can specify that a particular element(s) be created with the -g/--generate switch but the default is to produce + ## everything (i.e. call ".create()" against all defined elements). Any item passed in via --generate + ## that matches the name of a defined element will be generated (if environments/benches/interfaces are named the + ## same the script will match all of them) + search_paths = ['.'] + __version__ = version + uvmf_parser = UVMFCommandLineParser(version=__version__,usage="yaml2uvmf.py [options] [yaml_file1 [yaml_fileN]]") + uvmf_parser.parser.add_option("-f","--file",dest="configfile",action="append",help="Specify a file list of YAML configs. Relative paths relative to the invocation directory") + uvmf_parser.parser.add_option("-F","--relfile",dest="rel_configfile",action="append",help="Specify a file list of YAML configs. Relative paths relative to the file list itself") + uvmf_parser.parser.add_option("-g","--generate",dest="gen_name",action="append",help="Specify which elements to generate (default is everything") + uvmf_parser.parser.add_option("--pdb",dest="enable_pdb",action="store_true",help=SUPPRESS_HELP,default=False) + uvmf_parser.parser.add_option("-m","--merge_source",dest="merge_source",action="store",help="Enable auto-merge flow, pulling from the specified source directory") + uvmf_parser.parser.add_option("-s","--merge_skip_missing_blocks",dest="merge_skip_missing",action="store_true",help="Continue merge if unable to locate a custom block that was defined in old source, producing a report at the end. Default behavior is to raise an error",default=False) + uvmf_parser.parser.add_option("--merge_export_yaml",dest="merge_export_yaml",action="store",help=SUPPRESS_HELP,default=None) + uvmf_parser.parser.add_option("--merge_import_yaml",dest="merge_import_yaml",action="store",help=SUPPRESS_HELP,default=None) + uvmf_parser.parser.add_option("--merge_import_yaml_output",dest="merge_import_yaml_output",action="store",help=SUPPRESS_HELP,default="uvmf_template_merged") + uvmf_parser.parser.add_option("--merge_no_backup",dest="merge_no_backup",action="store_true",help="Do not back up original merge source",default=False) + uvmf_parser.parser.add_option("--merge_debug",dest="merge_debug",action="store_true",help="Provide intermediate unmerged output directory for debug purposes. Debug directory can be specified by --dest_dir switch.",default=False) + uvmf_parser.parser.add_option("--merge_verbose",dest="merge_verbose",action="store_true",help="Output more verbose messages during the merge operation for debug purposes.",default=False) + uvmf_parser.parser.add_option("--build_existing_components",dest="build_existing_components",action="store_true",help="Ignore \"existing_library_component\" flags and attempt to build anyway.",default=False) + uvmf_parser.parser.add_option("--no_archive_yaml",dest="no_archive_yaml",action="store_true",default=False,help="Disable YAML archive creation") + (options,args) = uvmf_parser.parser.parse_args() + if options.enable_pdb or options.debug: + print("Python version info:\n"+sys.version) + if options.enable_pdb == True: + import pdb + pdb.set_trace() + elif options.debug == False: + sys.tracebacklimit = 0 + if (len(args) == 0) and (options.configfile == None) and (options.rel_configfile == None) and (options.merge_source == None): + raise UserError("No configurations or config file specified as input. Must provide one or both") + if (options.merge_source != None) and (options.merge_import_yaml != None): + raise UserError("--merge_source and --merge_import_yaml options are mutually exclusive") + dataObj = DataClass(uvmf_parser) + configfiles = [] + if options.configfile != None: + for cf in options.configfile: + cfr = ConfigFileReader(cf) + configfiles = configfiles + cfr.files + if options.rel_configfile != None: + for cf in options.rel_configfile: + cfr = ConfigFileReader(cf,relative_to_file=True) + configfiles = configfiles + cfr.files + try: + configfiles = configfiles + args + except TypeError: + pass + if len(configfiles) == 0: + if not ((options.merge_source != None) and (options.merge_export_yaml)): + raise UserError("No configuration YAML specified to parse, must provide at least one") + if options.merge_source != None: + if os.path.abspath(os.path.normpath(options.dest_dir)) == os.path.abspath(os.path.normpath(options.merge_source)): + raise UserError("Cannot merge changes into source directory \"{0}\" without specifying an alternate output directory with --dest_dir switch".format(os.path.abspath(os.path.normpath(options.dest_dir)))) + for cfg in configfiles: + dataObj.parseFile(cfg) + dataObj.validate() + dataObj.buildElements(options.gen_name,verify=options.merge_export_yaml==None,build_existing=options.build_existing_components,archive_yaml=(not options.no_archive_yaml)) + if options.merge_source or options.merge_import_yaml: + if not options.merge_import_yaml: + if not (options.merge_no_backup or options.merge_export_yaml): + ## Create a backup of the original source. + backup_copy = backup(options.merge_source) + if not options.quiet: + print("Backed up original source to {0}".format(backup_copy)) + if not options.quiet: + print("Parsing customizations from {0} ...".format(options.merge_source)) + # Parse old source for pragma blocks. Resulting object will contain data structure of this activity + parse = Parse(quiet=options.quiet,cleanup=options.merge_import_yaml,root=os.path.abspath(os.path.normpath(options.merge_source))) + # Need to first produce a list of directories in the new output. Only validate files in the merge source + # that are in the equivalent directories (to do otherwise would be a waste of time) + parse.collect_directories(new_root_dir=options.dest_dir,old_root_dir=options.merge_source) + # Traverse through the merged source directory structure. This will only collect data on + # directories that were just re-generated, nothing outside of that area. + parse.traverse_dir(options.merge_source) + old_root = parse.root + if options.merge_export_yaml: + if not options.quiet: + print(" Exporting merge data to {0}".format(options.merge_export_yaml)) + parse.dump(options.merge_export_yaml) + sys.exit(0) + else: + if not options.quiet: + print("Merging custom code in {0} with new output ...".format(options.merge_source)) + else: + if not options.quiet: + print("Pulling in customizations from imported YAML file {0}".format(options.merge_import_yaml)) + old_root = os.path.abspath(os.path.normpath(options.merge_import_yaml_output)) + merge = Merge(outdir=old_root,skip_missing_blocks=options.merge_skip_missing,new_root=os.path.abspath(os.path.normpath(options.dest_dir)),old_root=old_root,quiet=options.quiet) + if options.merge_import_yaml: + merge.load_yaml(options.merge_import_yaml) + # If we're importing the data, copy newly generated source over to desired final location. This will be what we treat as the "original" output directory + from shutil import copytree + try: + copytree(options.dest_dir,options.merge_import_yaml_output) + except: + pass + else: + merge.load_data(parse.data) + merge.traverse_dir(options.dest_dir) + if (not options.merge_debug): + # Remove the intermediate directory unless asked otherwise + if not options.quiet: + print("Deleting intermediate directory {0} after merging data...".format(options.dest_dir)) + try: + shutil.rmtree(options.dest_dir) + except: + raise UserError("Unable to remove intermediate output directory {0}. Permissions issue?".format(options.dest_dir)) + if not options.quiet: + print("Merge complete!") + if options.merge_verbose: + merge_summary(merge,verbose=True) + merge_summary(merge) + if len(merge.missing_blocks)>0: + print("WARNING: Found \"pragma uvmf custom\" blocks in original source that could not be mapped to new output. These require hand-edits:") + for f in merge.missing_blocks: + print (" File: {0}".format(f)) + for l in merge.missing_blocks[f]: + print(" \"{0}\"".format(l)) + print(" Use backup or revision control source to recover the original content of these blocks") + +if __name__ == '__main__': + run() diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/__init__.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/__init__.pyc new file mode 100644 index 00000000..661c107e Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/__init__.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/_compat.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/_compat.pyc new file mode 100644 index 00000000..98452d83 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/_compat.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/bccache.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/bccache.pyc new file mode 100644 index 00000000..6ce5a98e Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/bccache.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/compiler.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/compiler.pyc new file mode 100644 index 00000000..41c7b400 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/compiler.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/defaults.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/defaults.pyc new file mode 100644 index 00000000..764c29ff Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/defaults.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/environment.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/environment.pyc new file mode 100644 index 00000000..f124e501 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/environment.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/exceptions.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/exceptions.pyc new file mode 100644 index 00000000..a3228670 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/exceptions.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/filters.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/filters.pyc new file mode 100644 index 00000000..76711901 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/filters.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/lexer.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/lexer.pyc new file mode 100644 index 00000000..7ee27ed1 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/lexer.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/loaders.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/loaders.pyc new file mode 100644 index 00000000..4d8b6e37 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/loaders.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/nodes.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/nodes.pyc new file mode 100644 index 00000000..0e7a30c0 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/nodes.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/optimizer.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/optimizer.pyc new file mode 100644 index 00000000..3e2f4c1b Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/optimizer.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/parser.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/parser.pyc new file mode 100644 index 00000000..274438ad Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/parser.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/runtime.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/runtime.pyc new file mode 100644 index 00000000..a9ba562b Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/runtime.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/tests.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/tests.pyc new file mode 100644 index 00000000..2ebda02e Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/tests.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/utils.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/utils.pyc new file mode 100644 index 00000000..5e10413c Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/utils.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/visitor.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/visitor.pyc new file mode 100644 index 00000000..7b1b3a00 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/jinja2/visitor.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/markupsafe/__init__.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/markupsafe/__init__.pyc new file mode 100644 index 00000000..f8cdb20a Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/markupsafe/__init__.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/markupsafe/_native.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/markupsafe/_native.pyc new file mode 100644 index 00000000..0f37fe76 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/markupsafe/_native.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/__init__.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/__init__.pyc new file mode 100644 index 00000000..7e0d161a Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/__init__.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/composer.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/composer.pyc new file mode 100644 index 00000000..08785b0a Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/composer.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/constructor.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/constructor.pyc new file mode 100644 index 00000000..444deec6 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/constructor.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/cyaml.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/cyaml.pyc new file mode 100644 index 00000000..05da88f8 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/cyaml.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/dumper.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/dumper.pyc new file mode 100644 index 00000000..5abbfe9a Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/dumper.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/emitter.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/emitter.pyc new file mode 100644 index 00000000..7e83198e Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/emitter.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/error.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/error.pyc new file mode 100644 index 00000000..55f24895 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/error.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/events.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/events.pyc new file mode 100644 index 00000000..07c55264 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/events.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/loader.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/loader.pyc new file mode 100644 index 00000000..e5dc225e Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/loader.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/nodes.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/nodes.pyc new file mode 100644 index 00000000..0de468ea Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/nodes.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/parser.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/parser.pyc new file mode 100644 index 00000000..0b4727ff Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/parser.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/reader.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/reader.pyc new file mode 100644 index 00000000..6e049176 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/reader.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/representer.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/representer.pyc new file mode 100644 index 00000000..f6777b13 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/representer.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/resolver.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/resolver.pyc new file mode 100644 index 00000000..39d33c2b Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/resolver.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/scanner.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/scanner.pyc new file mode 100644 index 00000000..5e2c28e9 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/scanner.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/serializer.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/serializer.pyc new file mode 100644 index 00000000..b1c68b95 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/serializer.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/tokens.pyc b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/tokens.pyc new file mode 100644 index 00000000..7580781b Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/python2/yaml/tokens.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/template_files/interface_templates/interface_driver_bfm.TMPL b/UVM_Framework/UVMF_2022.3/templates/python/template_files/interface_templates/interface_driver_bfm.TMPL index 2883d5e7..225c66dd 100644 --- a/UVM_Framework/UVMF_2022.3/templates/python/template_files/interface_templates/interface_driver_bfm.TMPL +++ b/UVM_Framework/UVMF_2022.3/templates/python/template_files/interface_templates/interface_driver_bfm.TMPL @@ -96,8 +96,8 @@ end {{config.type}} {{config.name}} {{config.unpackedDim}}; {% endfor %} - tri {{clock}}_i; - tri {{reset}}_i; + logic {{clock}}_i; + logic {{reset}}_i; // Signal list (all signals are capable of being inputs and outputs for the sake // of supporting both INITIATOR and RESPONDER mode operation. Expectation is that diff --git a/UVM_Framework/UVMF_2022.3/templates/python/template_files/interface_templates/interface_if.TMPL b/UVM_Framework/UVMF_2022.3/templates/python/template_files/interface_templates/interface_if.TMPL index 95cfb328..3d302e65 100644 --- a/UVM_Framework/UVMF_2022.3/templates/python/template_files/interface_templates/interface_if.TMPL +++ b/UVM_Framework/UVMF_2022.3/templates/python/template_files/interface_templates/interface_if.TMPL @@ -28,11 +28,11 @@ import {{name}}_pkg_hdl::*; interface {{name}}_if {{macro.paramDeclare(paramDefs)|indent(2)}} ( - input tri {{clock}}, - input tri {{reset}}{% if sigs|length > 0 %},{% endif %} + input logic {{clock}}, + input logic {{reset}}{% if sigs|length > 0 %},{% endif %} {% for sig in sigs %} - inout tri {{sig.vector}} {{sig.name}}{{macro.commalist(loop)}} + {{sig.dir}} logic {{sig.vector}} {{sig.name}}{{macro.commalist(loop)}} {%- endfor %} ); diff --git a/UVM_Framework/UVMF_2022.3/templates/python/template_files/interface_templates/interface_monitor_bfm.TMPL b/UVM_Framework/UVMF_2022.3/templates/python/template_files/interface_templates/interface_monitor_bfm.TMPL index c346a492..b9d7f416 100644 --- a/UVM_Framework/UVMF_2022.3/templates/python/template_files/interface_templates/interface_monitor_bfm.TMPL +++ b/UVM_Framework/UVMF_2022.3/templates/python/template_files/interface_templates/interface_monitor_bfm.TMPL @@ -87,8 +87,8 @@ end {{config.type}} {{config.name}} {{config.unpackedDim}}; {% endfor %} - tri {{clock}}_i; - tri {{reset}}_i; + logic {{clock}}_i; + logic {{reset}}_i; {% for sig in sigs %} tri {{sig.vector}} {{sig.name}}_i; {% endfor %} diff --git a/UVM_Framework/UVMF_2022.3/templates/python/uvmf_gen.pyc b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_gen.pyc new file mode 100644 index 00000000..0dd7336a Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_gen.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/uvmf_version.pyc b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_version.pyc new file mode 100644 index 00000000..8e7f6640 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_version.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/__init__.pyc b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/__init__.pyc new file mode 100644 index 00000000..4405ceb4 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/__init__.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/backup.pyc b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/backup.pyc new file mode 100644 index 00000000..0f2a2219 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/backup.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/dumper.pyc b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/dumper.pyc new file mode 100644 index 00000000..a3a268a6 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/dumper.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/regen.pyc b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/regen.pyc new file mode 100644 index 00000000..2993ab67 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/regen.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/validator.pyc b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/validator.pyc new file mode 100644 index 00000000..bd11319a Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/uvmf_yaml/validator.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/__init__.pyc b/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/__init__.pyc new file mode 100644 index 00000000..05f76205 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/__init__.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/error.pyc b/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/error.pyc new file mode 100644 index 00000000..2d9e680a Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/error.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/humanize.pyc b/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/humanize.pyc new file mode 100644 index 00000000..0ff54492 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/humanize.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/schema_builder.pyc b/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/schema_builder.pyc new file mode 100644 index 00000000..633208f0 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/schema_builder.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/util.pyc b/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/util.pyc new file mode 100644 index 00000000..44920aea Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/util.pyc differ diff --git a/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/validators.pyc b/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/validators.pyc new file mode 100644 index 00000000..a3470f06 Binary files /dev/null and b/UVM_Framework/UVMF_2022.3/templates/python/voluptuous/validators.pyc differ