From dfb7efbbc504299b2833109706c16a028aca881d Mon Sep 17 00:00:00 2001 From: M0stafaRady Date: Thu, 17 Oct 2024 13:08:19 +0300 Subject: [PATCH 1/3] fix how RTL wrapper handle the HSIZE --- hdl/rtl/bus_wrapper/EF_PSRAM_CTRL_V2_ahbl.v | 78 +++++++++++++++++++-- 1 file changed, 74 insertions(+), 4 deletions(-) diff --git a/hdl/rtl/bus_wrapper/EF_PSRAM_CTRL_V2_ahbl.v b/hdl/rtl/bus_wrapper/EF_PSRAM_CTRL_V2_ahbl.v index f62b7e5..d9af696 100644 --- a/hdl/rtl/bus_wrapper/EF_PSRAM_CTRL_V2_ahbl.v +++ b/hdl/rtl/bus_wrapper/EF_PSRAM_CTRL_V2_ahbl.v @@ -44,7 +44,7 @@ module EF_PSRAM_CTRL_V2_ahbl #(parameter REGISTER_HWDATA = 1) input wire HWRITE, input wire HREADY, output reg HREADYOUT, - output wire [31:0] HRDATA, + output reg [31:0] HRDATA, // External Interface to Quad I/O output wire sck, @@ -85,6 +85,77 @@ module EF_PSRAM_CTRL_V2_ahbl #(parameter REGISTER_HWDATA = 1) // Hand-shaking Signals wire start; wire done; + reg [31:0] data_i; + reg [31:0] data_i_sized; + wire [31:0] data_o; + + // handle hsize + wire is_byte = (last_HSIZE == 3'b000); + wire is_half = (last_HSIZE == 3'b001); + wire is_word = (last_HSIZE == 3'b010); + + wire byte_0 = is_byte & (last_HADDR[1:0] == 2'b00); + wire byte_1 = is_byte & (last_HADDR[1:0] == 2'b01); + wire byte_2 = is_byte & (last_HADDR[1:0] == 2'b10); + wire byte_3 = is_byte & (last_HADDR[1:0] == 2'b11); + + wire half_0 = is_half & ~last_HADDR[1]; + wire half_2 = is_half & last_HADDR[1]; + + always @(*) begin + if (is_word) begin + data_i_sized = data_i; // Assign the full word + end + else if (is_half) begin + if (half_0) begin + data_i_sized = data_i[15:0]; // Assign lower half-word + end + else begin + data_i_sized = data_i[31:16]; // Assign upper half-word + end + end + else begin + if (byte_0) begin + data_i_sized = data_i[7:0]; // Assign first byte + end + else if (byte_1) begin + data_i_sized = data_i[15:8]; // Assign second byte + end + else if (byte_2) begin + data_i_sized = data_i[23:16]; // Assign third byte + end + else begin + data_i_sized = data_i[31:24]; // Assign fourth byte + end + end + end + + always @(*) begin + if (is_word) begin + HRDATA = data_o; // Assign the full word + end + else if (is_half) begin + if (half_0) begin + HRDATA = data_o[15:0]; // Assign lower half-word + end + else begin + HRDATA = {data_o[15:0], 16'b0}; // Assign upper half-word + end + end else begin + if (byte_0) begin + HRDATA = data_o[7:0]; // Assign first byte + end + else if (byte_1) begin + HRDATA = {data_o[7:0], 8'b0}; // Assign second byte + end + else if (byte_2) begin + HRDATA = {data_o[7:0], 16'b0}; // Assign third byte + end + else begin + HRDATA = {data_o[7:0], 24'b0}; // Assign fourth byte + end + end + end always@ (posedge HCLK or negedge HRESETn) begin if (!HRESETn) begin @@ -200,7 +271,6 @@ module EF_PSRAM_CTRL_V2_ahbl #(parameter REGISTER_HWDATA = 1) //generate // if(REGISTER_HWDATA) begin - reg [31:0] data_i; always @(posedge HCLK or negedge HRESETn) begin if(!HRESETn) @@ -228,8 +298,8 @@ module EF_PSRAM_CTRL_V2_ahbl #(parameter REGISTER_HWDATA = 1) .clk(HCLK), .rst_n(HRESETn), .addr(mctrl_addr), - .data_i(data_i), - .data_o(HRDATA), + .data_i(data_i_sized), + .data_o(data_o), .size(size), .start(start), .done(done), From fcc9f135bbdd3e71a6d3d1715ec3bf233347055d Mon Sep 17 00:00:00 2001 From: M0stafaRady Date: Thu, 17 Oct 2024 13:08:42 +0300 Subject: [PATCH 2/3] update and add new test for hsize --- verify/uvm-python/Makefile | 2 +- .../psram_ref_model/psram_ref_model.py | 24 +++++++--- .../psram_seq_lib/psram_hsize_seq.py | 46 +++++++++++++++++++ verify/uvm-python/test_lib.py | 23 +++++++++- 4 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 verify/uvm-python/psram_seq_lib/psram_hsize_seq.py diff --git a/verify/uvm-python/Makefile b/verify/uvm-python/Makefile index 0944ad3..c360ab8 100644 --- a/verify/uvm-python/Makefile +++ b/verify/uvm-python/Makefile @@ -33,7 +33,7 @@ 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 +TESTS := psram_spi_test psram_sqi_test psram_sdi_test psram_hsize_test # Variable for tag - set this as required SIM_TAG ?= default_tag diff --git a/verify/uvm-python/psram_ref_model/psram_ref_model.py b/verify/uvm-python/psram_ref_model/psram_ref_model.py index 5caa8c0..c586a7c 100644 --- a/verify/uvm-python/psram_ref_model/psram_ref_model.py +++ b/verify/uvm-python/psram_ref_model/psram_ref_model.py @@ -57,16 +57,26 @@ def write_bus(self, tr): # TODO: write logic needed when write transaction is received # For example, to write the same value to the same resgiter uncomment the following lines if tr.addr & 0xFFF00000 == 0x00700000: # access to the external memory - addr = tr.addr & 0xFFFFF + addr_wr = tr.addr & 0xFFFFF if tr.size == bus_item.WORD_ACCESS: - self.external_mem.write_word(addr, tr.data) + self.external_mem.write_word(addr_wr, tr.data) elif tr.size == bus_item.HALF_WORD_ACCESS: - self.external_mem.write_halfword(addr, tr.data) + if addr_wr % 4 == 0: + self.external_mem.write_halfword(addr_wr, tr.data & 0xFFFF) + else: + self.external_mem.write_halfword(addr_wr, tr.data >> 16) elif tr.size == bus_item.BYTE_ACCESS: - self.external_mem.write_byte(addr, tr.data) - else: - self.regs.write_reg_value(tr.addr, tr.data) - self.bus_bus_export.write(tr) # this is output to the scoreboard + if addr_wr % 4 == 0: + self.external_mem.write_byte(addr_wr, tr.data & 0xFF) + elif addr_wr % 4 == 1: + self.external_mem.write_byte(addr_wr, (tr.data >> 8) & 0xFF) + elif addr_wr % 4 == 2: + self.external_mem.write_byte(addr_wr, (tr.data >> 16) & 0xFF) + else: + self.external_mem.write_byte(addr_wr, (tr.data >> 24) & 0xFF) + else: + self.regs.write_reg_value(tr.addr, tr.data) + self.bus_bus_export.write(tr) # this is output to the scoreboard # check if the write register is icr , set the icr changed event elif tr.kind == bus_item.READ: diff --git a/verify/uvm-python/psram_seq_lib/psram_hsize_seq.py b/verify/uvm-python/psram_seq_lib/psram_hsize_seq.py new file mode 100644 index 0000000..729fdd0 --- /dev/null +++ b/verify/uvm-python/psram_seq_lib/psram_hsize_seq.py @@ -0,0 +1,46 @@ +from uvm.seq import UVMSequence +from uvm.macros.uvm_object_defines import uvm_object_utils +from uvm.macros.uvm_message_defines import uvm_fatal +from uvm.base.uvm_config_db import UVMConfigDb +from EF_UVM.bus_env.bus_seq_lib.bus_seq_base import bus_seq_base +from cocotb.triggers import Timer +from uvm.macros.uvm_sequence_defines import uvm_do_with, uvm_do +import random +from EF_UVM.bus_env.bus_item import bus_item +from psram_seq_lib.psram_base_seq import psram_base_seq +import random + + +class psram_hsize_seq(psram_base_seq): + # use this sequence write or read from register by the bus interface + # this sequence should be connected to the bus sequencer in the testbench + # you should create as many sequences as you need not only this one + def __init__(self, name="psram_bus_seq"): + super().__init__(name) + + async def body(self): + await super().body() + # test write byte and half word + for i in range(50): + # write bytes or half words + address = random.randint(0, 0x1FFFF // 4) * 4 + size = random.choice([bus_item.BYTE_ACCESS, bus_item.HALF_WORD_ACCESS]) + address_steps = [0, 1, 2, 3] if size == bus_item.BYTE_ACCESS else [0, 2] + random.shuffle(address_steps) + for i in address_steps: + await self.write_to_mem(address=address + i, size=size) + # read word + await self.read_from_mem(address=address, size=bus_item.WORD_ACCESS) + # test read byte and half word + for i in range(50): + # write word + address = random.randint(0, 0x1FFFF // 4) * 4 + await self.write_to_mem(address=address, size=bus_item.WORD_ACCESS) + # read bytes or half words + size = random.choice([bus_item.BYTE_ACCESS, bus_item.HALF_WORD_ACCESS]) + address_steps = [0, 1, 2, 3] if size == bus_item.BYTE_ACCESS else [0, 2] + random.shuffle(address_steps) + for i in address_steps: + await self.read_from_mem(address=address + i, size=size) + +uvm_object_utils(psram_hsize_seq) diff --git a/verify/uvm-python/test_lib.py b/verify/uvm-python/test_lib.py index 0d749e1..c0e235a 100644 --- a/verify/uvm-python/test_lib.py +++ b/verify/uvm-python/test_lib.py @@ -40,6 +40,7 @@ from psram_seq_lib.psram_spi_seq import psram_spi_seq from psram_seq_lib.psram_sqi_seq import psram_sqi_seq from psram_seq_lib.psram_sdi_seq import psram_sdi_seq +from psram_seq_lib.psram_hsize_seq import psram_hsize_seq @cocotb.test() async def module_top(dut): @@ -190,6 +191,26 @@ async def shutdown_phase(self, phase): await super().shutdown_phase(phase) self.check_mode(1) # SDI +class psram_hsize_test(psram_base_test): + def __init__(self, name="psram__first_test", parent=None): + super().__init__(name, parent=parent) + self.tag = name + + async def main_phase(self, phase): + uvm_info(self.tag, f"Starting test {self.__class__.__name__}", UVM_LOW) + phase.raise_objection(self, f"{self.__class__.__name__} OBJECTED") + # TODO: conntect sequence with sequencer here + # for example if you need to run the 2 sequence sequentially + bus_seq = psram_hsize_seq("psram_hsize_seq") + # ip_seq = psram_ip_seq("psram_ip_seq") + await bus_seq.start(self.bus_sqr) + # await ip_seq.start(self.ip_sqr) + phase.drop_objection(self, f"{self.__class__.__name__} drop objection") + + async def shutdown_phase(self, phase): + await super().shutdown_phase(phase) + self.check_mode(0) # SPI + -uvm_component_utils(psram_sdi_test) +uvm_component_utils(psram_hsize_test) From 46b0373fbfe4b5701a1e5c13116c5bd92129d6b2 Mon Sep 17 00:00:00 2001 From: M0stafaRady Date: Thu, 17 Oct 2024 15:53:00 +0300 Subject: [PATCH 3/3] changes needed after change how the ahb monitor read write command --- .../uvm-python/psram_ref_model/psram_ref_model.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/verify/uvm-python/psram_ref_model/psram_ref_model.py b/verify/uvm-python/psram_ref_model/psram_ref_model.py index c586a7c..ba637ca 100644 --- a/verify/uvm-python/psram_ref_model/psram_ref_model.py +++ b/verify/uvm-python/psram_ref_model/psram_ref_model.py @@ -61,19 +61,9 @@ def write_bus(self, tr): if tr.size == bus_item.WORD_ACCESS: self.external_mem.write_word(addr_wr, tr.data) elif tr.size == bus_item.HALF_WORD_ACCESS: - if addr_wr % 4 == 0: - self.external_mem.write_halfword(addr_wr, tr.data & 0xFFFF) - else: - self.external_mem.write_halfword(addr_wr, tr.data >> 16) + self.external_mem.write_halfword(addr_wr, tr.data & 0xFFFF) elif tr.size == bus_item.BYTE_ACCESS: - if addr_wr % 4 == 0: - self.external_mem.write_byte(addr_wr, tr.data & 0xFF) - elif addr_wr % 4 == 1: - self.external_mem.write_byte(addr_wr, (tr.data >> 8) & 0xFF) - elif addr_wr % 4 == 2: - self.external_mem.write_byte(addr_wr, (tr.data >> 16) & 0xFF) - else: - self.external_mem.write_byte(addr_wr, (tr.data >> 24) & 0xFF) + self.external_mem.write_byte(addr_wr, tr.data & 0xFF) else: self.regs.write_reg_value(tr.addr, tr.data) self.bus_bus_export.write(tr) # this is output to the scoreboard