Skip to content

Commit

Permalink
Merge pull request #6 from efabless/uvm
Browse files Browse the repository at this point in the history
Add tests for PSRAM
  • Loading branch information
M0stafaRady authored Oct 16, 2024
2 parents afc59c6 + 212a84a commit ee90cfc
Show file tree
Hide file tree
Showing 22 changed files with 1,561 additions and 8 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/uvm_ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Run UVM tests

on:
push: # This now triggers on pushes to any branch
pull_request: # This now triggers on pull requests to any branch

jobs:
Extract-Buses:
runs-on: ubuntu-latest
outputs:
IPs: ${{ steps.set-IPs-matrix.outputs.IPs }}
buses: ${{ steps.extract_buses.outputs.buses }}
steps:
- name: Extract Supported Buses
id: extract_buses
uses: efabless/EF_UVM/.github/actions/get-bus@main
- name: Check Output
run: echo ${{ steps.extract_buses.outputs.buses }}
Run-IP-Tests:
uses: efabless/EF_UVM/.github/workflows/run_IP.yaml@main
needs: [Extract-Buses]
with:
test-names: "all_tests"
name: ${{ github.event.repository.name }}
buses: ${{ needs.Extract-Buses.outputs.buses }}
is-ip: true
16 changes: 8 additions & 8 deletions EF_PSRAM_CTRL_V2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ registers:
fifo: no
offset: 0x0080_0100
bit_access: no
init: "3"
init: "'h3"
write_port: ""
description: RD Command Register
- name: wr_cmd
Expand All @@ -72,7 +72,7 @@ registers:
fifo: no
offset: 0x0080_0200
bit_access: no
init: "2"
init: "'h2"
write_port: ""
description: WR Command Register
- name: eqpi_cmd
Expand All @@ -81,7 +81,7 @@ registers:
fifo: no
offset: 0x0080_0400
bit_access: no
init: "35"
init: "'h35"
write_port: ""
description: Enter QPI Command Register
- name: xqpi_cmd
Expand All @@ -90,7 +90,7 @@ registers:
fifo: no
offset: 0x0080_0800
bit_access: no
init: "FE"
init: "'hFE"
write_port: ""
description: Exit QPI Command Register
- name: wait_states
Expand All @@ -99,7 +99,7 @@ registers:
fifo: no
offset: 0x0080_1000
bit_access: no
init: "0"
init: "'h0"
write_port: ""
description: Wait States Register
- name: mode
Expand All @@ -108,7 +108,7 @@ registers:
fifo: no
offset: 0x0080_2000
bit_access: no
init: "0"
init: "'h0"
write_port: ""
description: I/O Mode Register, {qpi, qspi}
- name: enter_qpi
Expand All @@ -117,7 +117,7 @@ registers:
fifo: no
offset: 0x0080_4000
bit_access: no
init: "0"
init: "'h0"
write_port: ""
description: Initiate Enter QPI (EQPI) Mode process Register
- name: exit_qpi
Expand All @@ -126,7 +126,7 @@ registers:
fifo: no
offset: 0x0080_8000
bit_access: no
init: "0"
init: "'h0"
write_port: ""
description: Initiate Exit QPI (XQPI) Mode process Register
clock: HCLK
Expand Down
3 changes: 3 additions & 0 deletions ip/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*
!dependencies.json
!.gitignore
7 changes: 7 additions & 0 deletions ip/dependencies.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"IP": [
{
"IP_Utilities": "v1.0.0"
}
]
}
13 changes: 13 additions & 0 deletions verify/uvm-python/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
*.yalm
*.html
*.pyc
*/__pycache__/
*.code-workspace
*.log
*.vcd
/sim/
/coverageReports/
*.xml
*.gtkw
/EF_UVM/
IP_Utilities/
612 changes: 612 additions & 0 deletions verify/uvm-python/23LC1024.v

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions verify/uvm-python/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
PLUSARGS += "+UVM_VERBOSITY=UVM_MEDUIM"
TOPLEVEL := top
MODULE ?= top_module
AHB_FILES ?= $(PWD)/../../hdl/rtl/bus_wrapper/EF_PSRAM_CTRL_V2_ahbl.v
APB_FILES ?= # TODO: Add add APB wrapper file path
WB_FILES ?= # TODO: Add add WB wrapper file path
HDL_FILES ?= $(PWD)/../../hdl/rtl/EF_PSRAM_CTRL_V2.v
VIP_FILES ?= $(PWD)/23LC1024.v
VERILOG_SOURCES ?= $(PWD)/top.v $(AHB_FILES) $(HDL_FILES) $(VIP_FILES)
RTL_MACROS += "" # Add macros needed
BUS_TYPE ?= AHB
RTL_MACROS += -DBUS_TYPE_AHB
DESIGN_NAME = EF_PSRAM_CTRL_V2_ahbl
export CLK_MAKEFILE = HCLK
export RST_MAKEFILE = HRESETn
## netlist Gen
GL_MACROS += -DGL -DFUNCTIONAL $(RTL_MACROS) -DUNIT_DELAY=\#1
PRE_SYS_FILES = $(AHB_FILES) $(APB_FILES) $(WB_FILES) $(HDL_FILES)
PDK_DIR = $(HOME)/.volare/volare/sky130/versions/bdc9412b3e468c102d01b7cf6337be06ec6e9c9a/sky130A/
PDK_FILES = $(PDK_DIR)/libs.ref/sky130_fd_sc_hd/verilog/primitives.v $(PDK_DIR)/libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v # get this from openlane logs in the future
IPM_DIR = $(HOME)/.ipm
POST_SYS_FILES = $(PWD)/top.v $(VIP_FILES) $(PWD)/../../hdl/gl/synthesis/nl/$(DESIGN_NAME).nl.v

# ifeq ($(BUS_TYPE),APB)
# RTL_MACROS += -DBUS_TYPE_APB
# else ifeq ($(BUS_TYPE),AHB)
# RTL_MACROS += -DBUS_TYPE_AHB
# else ifeq ($(BUS_TYPE),WISHBONE)
# RTL_MACROS += -DBUS_TYPE_WISHBONE
# endif
# RTL_MACROS ?= "-DSKIP_WAVE_DUMP"
YAML_FILE = $(PWD)/../../EF_PSRAM_CTRL_V2.yaml # TODO: update yaml file path
MAKEFLAGS += --no-print-directory

# List of tests
TESTS := psram_spi_test psram_sqi_test psram_sdi_test

# Variable for tag - set this as required
SIM_TAG ?= default_tag

# Define SIM_PATH variable
SIM_PATH := $(PWD)/sim/$(SIM_TAG)

# Check and clone EF_UVM repository at the beginning of the Makefile execution

clone_ef_uvm := $(shell if [ ! -d "EF_UVM" ]; then \
echo "Cloning the EF_UVM repository..."; \
git clone https://github.com/efabless/EF_UVM.git; \
fi;)


include EF_UVM/Makefile.test
30 changes: 30 additions & 0 deletions verify/uvm-python/psram_agent/psram_driver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from uvm.macros import uvm_component_utils, uvm_fatal, uvm_info, uvm_warning
from uvm.base.uvm_config_db import UVMConfigDb
from uvm.base.uvm_object_globals import UVM_HIGH, UVM_LOW, UVM_MEDIUM
from cocotb.triggers import Timer, ClockCycles, FallingEdge, Event, RisingEdge, First
import cocotb
import random
from EF_UVM.ip_env.ip_agent.ip_driver import ip_driver


class psram_driver(ip_driver):
def __init__(self, name="psram_driver", parent=None):
super().__init__(name, parent)
self.tag = name

async def run_phase(self, phase):
uvm_info(self.tag, "run_phase started", UVM_LOW)
return
while True:
tr = []
await self.seq_item_port.get_next_item(tr)
tr = tr[0]
# TODO: Add your code here for driving the IP
uvm_fatal(
self.tag, "please remove this line and write your code for driving here"
)
# use self.vif.<signal name> for driving interface signals
self.seq_item_port.item_done()


uvm_component_utils(psram_driver)
32 changes: 32 additions & 0 deletions verify/uvm-python/psram_agent/psram_monitor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from uvm.macros import uvm_component_utils, uvm_fatal, uvm_info, uvm_error, uvm_warning
from uvm.comps.uvm_monitor import UVMMonitor
from uvm.tlm1.uvm_analysis_port import UVMAnalysisPort
from uvm.base.uvm_config_db import UVMConfigDb
from cocotb.triggers import (
Timer,
ClockCycles,
FallingEdge,
Event,
RisingEdge,
Combine,
First,
)
from uvm.base.uvm_object_globals import UVM_HIGH, UVM_LOW, UVM_MEDIUM
import cocotb
import math
from EF_UVM.ip_env.ip_agent.ip_monitor import ip_monitor


class psram_monitor(ip_monitor):
def __init__(self, name="psram_monitor", parent=None):
super().__init__(name, parent)

async def run_phase(self, phase):
# TODO: Add logic to monitor the IP
# use self.vif.<signal name> for monitoring interface signals
# self.monitor_port.write(tr) # this is the port to send the transaction after sampling it
# NOTES: how to create transaction
pass


uvm_component_utils(psram_monitor)
14 changes: 14 additions & 0 deletions verify/uvm-python/psram_bus_item.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from EF_UVM.bus_env.bus_item import bus_item
from uvm.macros import (
uvm_object_utils_begin,
uvm_object_utils_end,
uvm_field_int,
uvm_object_utils,
)

class psram_bus_item(bus_item):
def __init__(self, name="psram_bus_item"):
super().__init__(name)
self.rand("addr", range(0, 0xFFFFFFF))

uvm_object_utils(psram_bus_item)
29 changes: 29 additions & 0 deletions verify/uvm-python/psram_coverage/psram_coverage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from uvm.base.uvm_component import UVMComponent
from uvm.macros import uvm_component_utils
from uvm.tlm1.uvm_analysis_port import UVMAnalysisImp
from uvm.macros import uvm_component_utils, uvm_fatal, uvm_info
from uvm.base.uvm_object_globals import UVM_HIGH, UVM_LOW
from uvm.base.uvm_config_db import UVMConfigDb
from uvm.macros.uvm_tlm_defines import uvm_analysis_imp_decl
from EF_UVM.ip_env.ip_coverage.ip_coverage import ip_coverage


class psram_coverage(ip_coverage):
"""
component that initialize the coverage groups and control when to sample the data.
"""

def __init__(self, name="psram_coverage", parent=None):
super().__init__(name, parent)

def build_phase(self, phase):
super().build_phase(phase)
# TODO: initialize the class for coverage groups here

def write(self, tr):
# called when new transaction from ip monitor is received
# TODO: Add sampling logic here
pass


uvm_component_utils(psram_coverage)
9 changes: 9 additions & 0 deletions verify/uvm-python/psram_interface/psram_if.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from uvm.base.sv import sv_if


class psram_if(sv_if):
def __init__(self, dut):
# TODO: Add signal need to be seen by the ip monitor and driver in the following format
# bus_map = {<signal name seen in testbench>: <signal name seen in dut>}
bus_map = {"mode": "IOMode"}
super().__init__(dut, "", bus_map)
31 changes: 31 additions & 0 deletions verify/uvm-python/psram_item/psram_item.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from uvm.seq.uvm_sequence_item import UVMSequenceItem
from uvm.macros import (
uvm_object_utils_begin,
uvm_object_utils_end,
uvm_field_int,
uvm_object_utils,
uvm_error,
uvm_info,
)
from uvm.base.uvm_object_globals import UVM_ALL_ON, UVM_NOPACK, UVM_HIGH, UVM_MEDIUM
from uvm.base.sv import sv
from EF_UVM.ip_env.ip_item import ip_item


class psram_item(ip_item):
def __init__(self, name="psram_item"):
super().__init__(name)
# TODO: Add the variables that defined the item and thier randomization status

def convert2string(self):
# TODO: return the string representation of the item
return ""

def do_compare(self, tr):
# method used by scoreboard to compare the items
# TODO: Add logic to compare the item with another passed item
# in the simple case this function should return (self.varaible1 == tr.variable2 and self.varaible2 == tr.variable2 and .. )
return False


uvm_object_utils(psram_item)
23 changes: 23 additions & 0 deletions verify/uvm-python/psram_logger/psram_logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from EF_UVM.ip_env.ip_logger.ip_logger import ip_logger
import cocotb
from uvm.macros import uvm_component_utils, uvm_fatal


class psram_logger(ip_logger):
def __init__(self, name="psram_logger", parent=None):
super().__init__(name, parent)
return
uvm_fatal("psram_logger", "please write self.header in list format")
# self.header = ['Time (ns)', "Direction", "value"]
self.col_widths = [10] * len(self.header)

def logger_formatter(self, transaction):
sim_time = f"{cocotb.utils.get_sim_time(units='ns')} ns"
# this called when new transaction is called from ip monitor
# TODO: should return the list of strings by the information in the header with the same order
return [
sim_time,
]


uvm_component_utils(psram_logger)
Loading

0 comments on commit ee90cfc

Please sign in to comment.