From d834ceb9e1be2e0e31b3b93dbee51b828d3750b9 Mon Sep 17 00:00:00 2001 From: dwn1c21 <dwn1c21@soton.ac.uk> Date: Thu, 6 Feb 2025 11:44:08 +0000 Subject: [PATCH] QSPI over apb working in FPGA, some issues over AHB but not sure if this is in RTL or configuration steps --- README.md | 2 +- fpga/pynq_z2/PYNQ-Z2 v1.0.xdc | 17 +- .../logical/qspi_controller.sv | 29 ++- verif/VIP/qspi_flash.v | 0 verif/cocotb/SST26VF064B.py | 238 ++++++++++++++++++ verif/cocotb/ahb_qspi_tests.py | 232 +---------------- 6 files changed, 267 insertions(+), 251 deletions(-) delete mode 100644 verif/VIP/qspi_flash.v create mode 100644 verif/cocotb/SST26VF064B.py diff --git a/README.md b/README.md index 1d4d7b0..59b4906 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Read bandwidth with 4 KB cache for 512x 32 bit reads, and system clock of 200 MH - Add programmable op codes for AHB interface - Improve writing method over APB? (see below) - Add interrupts for QSPI finish -- Add programmable address length +- Add programmable address length (currently this is set to the maximum of the CG092 flash cache. If we want to increase this then we need a new cache) ## Writing over APB Currently the method for writing over APB to the flash is to write up to 4x 32 bit words to the APB registers and then tell the QSPI controller to write. However as there is a long latency after writing over QSPI for the flash to finish, this is not optimal. diff --git a/fpga/pynq_z2/PYNQ-Z2 v1.0.xdc b/fpga/pynq_z2/PYNQ-Z2 v1.0.xdc index 05bee3d..e853b06 100644 --- a/fpga/pynq_z2/PYNQ-Z2 v1.0.xdc +++ b/fpga/pynq_z2/PYNQ-Z2 v1.0.xdc @@ -193,18 +193,13 @@ set_property -dict {PACKAGE_PIN W19 IOSTANDARD LVCMOS33} [get_ports {QSPI_IO_0[3 #set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { crypto_sda }]; #IO_25_35 Sch=crypto_sda +create_generated_clock -name QSPI_SCLK -source [get_pins {ahb_qspi_i/processing_system7_0/inst/PS7_i/FCLKCLK[0]}] -divide_by 2 [get_pins ahb_qspi_i/AXI_QSPI_0/inst/ahb_qspi_fpga_wrapper_0/inst/u_top_ahb_qspi/u_qspi_controller/u_qspi_clock_div/QSPI_SCLK_i] +create_generated_clock -name QSPI_CLK_o -source [get_pins ahb_qspi_i/AXI_QSPI_0/inst/ahb_qspi_fpga_wrapper_0/inst/u_top_ahb_qspi/u_qspi_controller/u_qspi_clock_div/QSPI_SCLK_i] -divide_by 1 [get_ports QSPI_SCLK_0] -set_input_delay -clock [get_clocks clk_fpga_0] -min -add_delay 2.000 [get_ports {QSPI_IO_0[*]}] -set_input_delay -clock [get_clocks clk_fpga_0] -max -add_delay 5.000 [get_ports {QSPI_IO_0[*]}] +set_input_delay -clock [get_clocks QSPI_SCLK] -min 0 [get_ports {QSPI_IO_0[*]}] +set_input_delay -clock [get_clocks QSPI_SCLK] -max 20 [get_ports {QSPI_IO_0[*]}] +set_output_delay -clock [get_clocks QSPI_CLK_o] -min 0 [get_ports {QSPI_IO_0[*]}] +set_output_delay -clock [get_clocks QSPI_CLK_o] -max 20 [get_ports {QSPI_IO_0[*]}] - -create_generated_clock -name ahb_qspi_i/AXI_QSPI_0/inst/ahb_qspi_fpga_wrapper_0/inst/u_top_ahb_qspi/u_ahb_qspi_interface/AHB_QSPI_ENABLE -source [get_pins {ahb_qspi_i/processing_system7_0/inst/PS7_i/FCLKCLK[0]}] -divide_by 1 [get_pins ahb_qspi_i/AXI_QSPI_0/inst/ahb_qspi_fpga_wrapper_0/inst/u_top_ahb_qspi/u_ahb_qspi_interface/AHB_QSPI_ENABLE_reg/Q] -create_generated_clock -name ahb_qspi_i/AXI_QSPI_0/inst/ahb_qspi_fpga_wrapper_0/inst/u_top_ahb_qspi/u_apb_qspi_regs/APB_QSPI_ENABLE -source [get_pins {ahb_qspi_i/processing_system7_0/inst/PS7_i/FCLKCLK[0]}] -divide_by 1 [get_pins {ahb_qspi_i/AXI_QSPI_0/inst/ahb_qspi_fpga_wrapper_0/inst/u_top_ahb_qspi/u_apb_qspi_regs/reg2_reg[8]/Q}] -create_generated_clock -name ahb_qspi_i/AXI_QSPI_0/inst/ahb_qspi_fpga_wrapper_0/inst/u_top_ahb_qspi/u_qspi_controller/QSPI_SCLK_e -source [get_pins {ahb_qspi_i/processing_system7_0/inst/PS7_i/FCLKCLK[0]}] -divide_by 1 [get_pins ahb_qspi_i/AXI_QSPI_0/inst/ahb_qspi_fpga_wrapper_0/inst/u_top_ahb_qspi/u_qspi_controller/QSPI_SCLK_e_reg/Q] -set_clock_groups -logically_exclusive -group [get_clocks -include_generated_clocks ahb_qspi_i/AXI_QSPI_0/inst/ahb_qspi_fpga_wrapper_0/inst/u_top_ahb_qspi/u_apb_qspi_regs/APB_QSPI_ENABLE] -group [get_clocks -include_generated_clocks ahb_qspi_i/AXI_QSPI_0/inst/ahb_qspi_fpga_wrapper_0/inst/u_top_ahb_qspi/u_ahb_qspi_interface/AHB_QSPI_ENABLE] -set_property C_CLK_INPUT_FREQ_HZ 300000000 [get_debug_cores dbg_hub] -set_property C_ENABLE_CLK_DIVIDER false [get_debug_cores dbg_hub] -set_property C_USER_SCAN_CHAIN 1 [get_debug_cores dbg_hub] -connect_debug_port dbg_hub/clk [get_nets clk] diff --git a/logical/qspi_controller/logical/qspi_controller.sv b/logical/qspi_controller/logical/qspi_controller.sv index 73525d1..46cf8c3 100644 --- a/logical/qspi_controller/logical/qspi_controller.sv +++ b/logical/qspi_controller/logical/qspi_controller.sv @@ -212,13 +212,13 @@ always_comb begin next_state = DATA_I; if(QSPI_QIO_MODE==1'b0) begin if((byte_counter[3:0]==QSPI_N_RW_BYTES)) begin - if(data_counter==3'h7) + if(data_counter==3'h6) next_state = IDLE; else next_state = DATA_I; end end else begin - if((byte_counter==QSPI_N_RW_BYTES+1)) begin + if((byte_counter==QSPI_N_RW_BYTES)) begin if(data_counter==3'h0) next_state = IDLE; else @@ -234,7 +234,6 @@ reg QSPI_IO_e_int; always @(negedge QSPI_SCLK_i) begin if(current_state==OP) begin - data_in_reg <= 128'd0; QSPI_IO_e_int <= 1'b1; QSPI_SCLK_e <= 1'b1; if(QSPI_QIO_MODE==1'b1) begin @@ -269,7 +268,7 @@ always @(negedge QSPI_SCLK_i) begin addr_code[23:0] <= {addr_code[22:0], 1'b0}; end end else if(current_state == DUMMY) begin - QSPI_IO_e_int <= 1'b1; + QSPI_IO_e_int <= 1'b0; QSPI_SCLK_e <= 1'b1; end else if(current_state == MODE) begin QSPI_IO_e_int <=1'b1; @@ -286,15 +285,6 @@ always @(negedge QSPI_SCLK_i) begin QSPI_IO_o_reg<=4'hF; QSPI_IO_e_int <= 1'b1; end - if(current_state == DATA_I) begin - if(QSPI_QIO_MODE==1'b1) begin - if(byte_counter!=QSPI_N_RW_BYTES+1) - data_in_reg <= {data_in_reg[123:0], QSPI_IO_i}; - end else begin - if(byte_counter!=QSPI_N_RW_BYTES+1) - data_in_reg <= {data_in_reg[126:0], QSPI_IO_i[1]}; - end - end if(current_state != DATA_O) begin @@ -310,8 +300,10 @@ always @(posedge QSPI_SCLK_i or negedge HRESETn) begin dummy_counter <= 4'h0; addr_counter <= 5'h00; mode_counter <= 1'b1; + data_in_reg <= 128'd0; end else begin if(current_state==OP) begin + data_in_reg <= 128'd0; op_counter<=op_counter+1; end else begin op_counter <= 3'h0; @@ -348,6 +340,17 @@ always @(posedge QSPI_SCLK_i or negedge HRESETn) begin end else begin mode_counter <= 1'b1; end + + if(current_state == DATA_I) begin + if(QSPI_QIO_MODE==1'b1) begin + if(byte_counter!=QSPI_N_RW_BYTES+1) + data_in_reg <= {data_in_reg[123:0], QSPI_IO_i}; + end else begin + if(byte_counter!=QSPI_N_RW_BYTES+1) + data_in_reg <= {data_in_reg[126:0], QSPI_IO_i[1]}; + end + end + end end diff --git a/verif/VIP/qspi_flash.v b/verif/VIP/qspi_flash.v deleted file mode 100644 index e69de29..0000000 diff --git a/verif/cocotb/SST26VF064B.py b/verif/cocotb/SST26VF064B.py new file mode 100644 index 0000000..640492a --- /dev/null +++ b/verif/cocotb/SST26VF064B.py @@ -0,0 +1,238 @@ +import itertools +import logging +import os +from numpy import random +import numpy as np + +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, Timer, ClockCycles +from cocotb.regression import TestFactory + +from cocotbext.ahb import AHBLiteMaster, AHBBus + +ID = 0x4326BF00 + +async def SPI_RESET(dut,tb): + await tb.config_ahb_master.write(0x08, 0x00000066) + await tb.config_ahb_master.write(0x08, 0x00000166) + + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,2) + data = await tb.config_ahb_master.read(0x04,4) + + await tb.config_ahb_master.write(0x08, 0x00000099) + await tb.config_ahb_master.write(0x08, 0x00000199) + + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,2) + data = await tb.config_ahb_master.read(0x04,4) + +async def SPI_READ_JEDIC(dut, tb): + await tb.config_ahb_master.write(0x08, 0x0002009F) + await tb.config_ahb_master.write(0x08, 0x0002039F) + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,10) + data = await tb.config_ahb_master.read(0x04,4) + ID = await tb.config_ahb_master.read(0x10,4) + return int(ID[0]['data'],16) + +async def SET_QPI_MODE(dut,tb): + await tb.config_ahb_master.write(0x08, 0x00000038) + await tb.config_ahb_master.write(0x08, 0x00000138) + + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,2) + data = await tb.config_ahb_master.read(0x04,4) + +async def LEAVE_QPI_MODE(dut, tb): + await tb.config_ahb_master.write(0x08, 0x000000FF) + await tb.config_ahb_master.write(0x08, 0x000001FF) + + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,2) + data = await tb.config_ahb_master.read(0x04,4) + +async def QPI_READ_JEDIC(dut, tb): + await tb.config_ahb_master.write(0x08, 0x000220AF) + await tb.config_ahb_master.write(0x08, 0x000223AF) + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,10) + data = await tb.config_ahb_master.read(0x04,4) + ID = await tb.config_ahb_master.read(0x10,4) + return int(ID[0]['data'],16) + +async def SPI_WRITE_ENABLE(dut, tb): + await tb.config_ahb_master.write(0x08, 0x00000006) + await tb.config_ahb_master.write(0x08, 0x00000106) + + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,2) + data = await tb.config_ahb_master.read(0x04,4) + +async def SPI_WRITE_DISABLE(dut, tb): + await tb.config_ahb_master.write(0x08, 0x00000004) + await tb.config_ahb_master.write(0x08, 0x00000104) + + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,2) + data = await tb.config_ahb_master.read(0x04,4) + +async def SPI_CLR_PROTECTION(dut, tb): + await tb.config_ahb_master.write(0x08, 0x00000098) + await tb.config_ahb_master.write(0x08, 0x00000198) + + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,2) + data = await tb.config_ahb_master.read(0x04,4) + +async def SPI_CHIP_ERASE(dut, tb): + await tb.config_ahb_master.write(0x08, 0x000000C7) + await tb.config_ahb_master.write(0x08, 0x000001C7) + + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,2) + data = await tb.config_ahb_master.read(0x04,4) + +async def SPI_BLOCK_ERASE(dut, tb): + # Write Adress + await tb.config_ahb_master.write(0x0C, 0x000000) + + await tb.config_ahb_master.write(0x08, 0x000008D8) + await tb.config_ahb_master.write(0x08, 0x000009D8) + + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,2) + data = await tb.config_ahb_master.read(0x04,4) + SPI_STAT = await SPI_READ_STAT_REG(dut, tb) + while(SPI_STAT&(1<<24)): + SPI_STAT = await SPI_READ_STAT_REG(dut, tb) + await Timer(time=1, units='ms') + +async def SPI_READ_STAT_REG(dut,tb): + await tb.config_ahb_master.write(0x08, 0x00002005) + await tb.config_ahb_master.write(0x08, 0x00002305) + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,10) + data = await tb.config_ahb_master.read(0x04,4) + data = await tb.config_ahb_master.read(0x10,4) + return (int(data[0]['data'],16)) + +async def QPI_READ_STAT_REG(dut,tb): + await tb.config_ahb_master.write(0x08, 0x00002005) + await tb.config_ahb_master.write(0x08, 0x00002305) + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,10) + data = await tb.config_ahb_master.read(0x04,4) + data = await tb.config_ahb_master.read(0x10,4) + return (int(data[0]['data'],16)) + + +async def SPI_READ_SLOW(dut, tb): + # Write Adress + await tb.config_ahb_master.write(0x0C, 0x000000) + + await tb.config_ahb_master.write(0x08, 0x00001003) + await tb.config_ahb_master.write(0x08, 0x00001303) + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,10) + data = await tb.config_ahb_master.read(0x04,4) + rData = await tb.config_ahb_master.read(0x10,4) + print(rData) + +async def QPI_READ_WORDS(dut,tb, addr =0, n_words=1, cont_read = False): + # Write Adress + await tb.config_ahb_master.write(0x0C, addr) + + if(cont_read==True): + QSPI_CTRL_REG = await tb.config_ahb_master.read(0x00,4) + QSPI_CTRL_REG = int(QSPI_CTRL_REG[0]['data'],16) + QSPI_CTRL_REG = QSPI_CTRL_REG | ((0xA0<<16) + (1<<24)) + await tb.config_ahb_master.write(0x00, QSPI_CTRL_REG) + QSPI_DUMMY_CYCLES = 4 + else: + QSPI_DUMMY_CYCLES = 6 + + + QSPI_CMD = 0x0B + QSPI_READ = 1 + QSPI_WRITE = 0 + QSPI_ADDR_EN = 1 + QSPI_N_RW_BYTES = n_words*4 - 1 + + QSPI_INSTR = QSPI_CMD + QSPI_INSTR += QSPI_READ<<9 + QSPI_INSTR += QSPI_WRITE<<10 + QSPI_INSTR += QSPI_ADDR_EN<<11 + QSPI_INSTR += QSPI_DUMMY_CYCLES<<12 + QSPI_INSTR += QSPI_N_RW_BYTES << 16 + + await tb.config_ahb_master.write(0x08, QSPI_INSTR) + QSPI_INSTR = QSPI_INSTR ^ (1<<8) + await tb.config_ahb_master.write(0x08, QSPI_INSTR) + + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,10) + data = await tb.config_ahb_master.read(0x04,4) + + apb_r_addrs=[0x10, 0x14, 0x18, 0x1C] + rData = [] + for i in range(0,n_words): + rData_temp = await tb.config_ahb_master.read(apb_r_addrs[i],4) + rData.append(int(rData_temp[0]['data'],16)) + return rData + +async def QPI_PAGE_PROGRAM(dut, tb, addr = 0, words=0, n_words = 1): + # Write Adress + await tb.config_ahb_master.write(0x0C, addr) + # Write Data + + apb_addrs = [0x20, 0x24, 0x28, 0x2C] + + for i in range(0,n_words): + await tb.config_ahb_master.write(apb_addrs[i], words[i]) + + QSPI_CMD = 0x02 + QSPI_READ = 0 + QSPI_WRITE = 1 + QSPI_ADDR_EN = 1 + QSPI_DUMMY_CYCLES = 0 + QSPI_N_RW_BYTES = n_words*4 - 1 + + QSPI_INSTR = QSPI_CMD + QSPI_INSTR += QSPI_READ<<9 + QSPI_INSTR += QSPI_WRITE<<10 + QSPI_INSTR += QSPI_ADDR_EN<<11 + QSPI_INSTR += QSPI_DUMMY_CYCLES<<12 + QSPI_INSTR += QSPI_N_RW_BYTES << 16 + + await tb.config_ahb_master.write(0x08, QSPI_INSTR) + QSPI_INSTR = QSPI_INSTR ^ (1<<8) + await tb.config_ahb_master.write(0x08, QSPI_INSTR) + + data = await tb.config_ahb_master.read(0x04,4) + while(int(data[0]['data'],16)&1): + await ClockCycles(dut.HCLK,10) + data = await tb.config_ahb_master.read(0x04,4) + SPI_STAT = await QPI_READ_STAT_REG(dut, tb) + while(SPI_STAT&(1<<24)): + SPI_STAT = await QPI_READ_STAT_REG(dut, tb) + await Timer(time=1, units='us') + + + diff --git a/verif/cocotb/ahb_qspi_tests.py b/verif/cocotb/ahb_qspi_tests.py index 7290cea..df3878e 100644 --- a/verif/cocotb/ahb_qspi_tests.py +++ b/verif/cocotb/ahb_qspi_tests.py @@ -11,6 +11,9 @@ from cocotb.regression import TestFactory from cocotbext.ahb import AHBLiteMaster, AHBBus + +from SST26VF064B import * + FREQ = 240 QSPI_CONFIG_ADDR = 0x0 @@ -42,229 +45,6 @@ async def CACHE_READ(dut,tb): data = await tb.data_ahb_master.read(0x00,4) return int(data[0]['data'],16) -async def SPI_RESET(dut,tb): - await tb.config_ahb_master.write(0x08, 0x00000066) - await tb.config_ahb_master.write(0x08, 0x00000166) - - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,2) - data = await tb.config_ahb_master.read(0x04,4) - - await tb.config_ahb_master.write(0x08, 0x00000099) - await tb.config_ahb_master.write(0x08, 0x00000199) - - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,2) - data = await tb.config_ahb_master.read(0x04,4) - -async def SPI_READ_JEDIC(dut, tb): - await tb.config_ahb_master.write(0x08, 0x0002009F) - await tb.config_ahb_master.write(0x08, 0x0002039F) - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,10) - data = await tb.config_ahb_master.read(0x04,4) - ID = await tb.config_ahb_master.read(0x10,4) - return int(ID[0]['data'],16) - -async def SET_QPI_MODE(dut,tb): - await tb.config_ahb_master.write(0x08, 0x00000038) - await tb.config_ahb_master.write(0x08, 0x00000138) - - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,2) - data = await tb.config_ahb_master.read(0x04,4) - -async def LEAVE_QPI_MODE(dut, tb): - await tb.config_ahb_master.write(0x08, 0x000000FF) - await tb.config_ahb_master.write(0x08, 0x000001FF) - - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,2) - data = await tb.config_ahb_master.read(0x04,4) - -async def QPI_READ_JEDIC(dut, tb): - await tb.config_ahb_master.write(0x08, 0x000220AF) - await tb.config_ahb_master.write(0x08, 0x000223AF) - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,10) - data = await tb.config_ahb_master.read(0x04,4) - ID = await tb.config_ahb_master.read(0x10,4) - return int(ID[0]['data'],16) - -async def SPI_WRITE_ENABLE(dut, tb): - await tb.config_ahb_master.write(0x08, 0x00000006) - await tb.config_ahb_master.write(0x08, 0x00000106) - - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,2) - data = await tb.config_ahb_master.read(0x04,4) - -async def SPI_WRITE_DISABLE(dut, tb): - await tb.config_ahb_master.write(0x08, 0x00000004) - await tb.config_ahb_master.write(0x08, 0x00000104) - - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,2) - data = await tb.config_ahb_master.read(0x04,4) - -async def SPI_CLR_PROTECTION(dut, tb): - await tb.config_ahb_master.write(0x08, 0x00000098) - await tb.config_ahb_master.write(0x08, 0x00000198) - - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,2) - data = await tb.config_ahb_master.read(0x04,4) - -async def SPI_CHIP_ERASE(dut, tb): - await tb.config_ahb_master.write(0x08, 0x000000C7) - await tb.config_ahb_master.write(0x08, 0x000001C7) - - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,2) - data = await tb.config_ahb_master.read(0x04,4) - -async def SPI_BLOCK_ERASE(dut, tb): - # Write Adress - await tb.config_ahb_master.write(0x0C, 0x000000) - - await tb.config_ahb_master.write(0x08, 0x000008D8) - await tb.config_ahb_master.write(0x08, 0x000009D8) - - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,2) - data = await tb.config_ahb_master.read(0x04,4) - SPI_STAT = await SPI_READ_STAT_REG(dut, tb) - while(SPI_STAT&(1<<24)): - SPI_STAT = await SPI_READ_STAT_REG(dut, tb) - await Timer(time=1, units='ms') - -async def SPI_READ_STAT_REG(dut,tb): - await tb.config_ahb_master.write(0x08, 0x00002005) - await tb.config_ahb_master.write(0x08, 0x00002305) - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,10) - data = await tb.config_ahb_master.read(0x04,4) - data = await tb.config_ahb_master.read(0x10,4) - return (int(data[0]['data'],16)) - -async def QPI_READ_STAT_REG(dut,tb): - await tb.config_ahb_master.write(0x08, 0x00002005) - await tb.config_ahb_master.write(0x08, 0x00002305) - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,10) - data = await tb.config_ahb_master.read(0x04,4) - data = await tb.config_ahb_master.read(0x10,4) - return (int(data[0]['data'],16)) - - -async def SPI_READ_SLOW(dut, tb): - # Write Adress - await tb.config_ahb_master.write(0x0C, 0x000000) - - await tb.config_ahb_master.write(0x08, 0x00001003) - await tb.config_ahb_master.write(0x08, 0x00001303) - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,10) - data = await tb.config_ahb_master.read(0x04,4) - rData = await tb.config_ahb_master.read(0x10,4) - print(rData) - -async def QPI_READ_WORDS(dut,tb, addr =0, n_words=1, cont_read = False): - # Write Adress - await tb.config_ahb_master.write(0x0C, addr) - - if(cont_read==True): - QSPI_CTRL_REG = await tb.config_ahb_master.read(0x00,4) - QSPI_CTRL_REG = int(QSPI_CTRL_REG[0]['data'],16) - QSPI_CTRL_REG = QSPI_CTRL_REG | ((0xA0<<16) + (1<<24)) - await tb.config_ahb_master.write(0x00, QSPI_CTRL_REG) - QSPI_DUMMY_CYCLES = 4 - else: - QSPI_DUMMY_CYCLES = 6 - - - QSPI_CMD = 0x0B - QSPI_READ = 1 - QSPI_WRITE = 0 - QSPI_ADDR_EN = 1 - QSPI_N_RW_BYTES = n_words*4 - 1 - - QSPI_INSTR = QSPI_CMD - QSPI_INSTR += QSPI_READ<<9 - QSPI_INSTR += QSPI_WRITE<<10 - QSPI_INSTR += QSPI_ADDR_EN<<11 - QSPI_INSTR += QSPI_DUMMY_CYCLES<<12 - QSPI_INSTR += QSPI_N_RW_BYTES << 16 - - await tb.config_ahb_master.write(0x08, QSPI_INSTR) - QSPI_INSTR = QSPI_INSTR ^ (1<<8) - await tb.config_ahb_master.write(0x08, QSPI_INSTR) - - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,10) - data = await tb.config_ahb_master.read(0x04,4) - - apb_r_addrs=[0x10, 0x14, 0x18, 0x1C] - rData = [] - for i in range(0,n_words): - rData_temp = await tb.config_ahb_master.read(apb_r_addrs[i],4) - rData.append(int(rData_temp[0]['data'],16)) - return rData - -async def QPI_PAGE_PROGRAM(dut, tb, addr = 0, words=0, n_words = 1): - # Write Adress - await tb.config_ahb_master.write(0x0C, addr) - # Write Data - - apb_addrs = [0x20, 0x24, 0x28, 0x2C] - - for i in range(0,n_words): - await tb.config_ahb_master.write(apb_addrs[i], words[i]) - - QSPI_CMD = 0x02 - QSPI_READ = 0 - QSPI_WRITE = 1 - QSPI_ADDR_EN = 1 - QSPI_DUMMY_CYCLES = 0 - QSPI_N_RW_BYTES = n_words*4 - 1 - - QSPI_INSTR = QSPI_CMD - QSPI_INSTR += QSPI_READ<<9 - QSPI_INSTR += QSPI_WRITE<<10 - QSPI_INSTR += QSPI_ADDR_EN<<11 - QSPI_INSTR += QSPI_DUMMY_CYCLES<<12 - QSPI_INSTR += QSPI_N_RW_BYTES << 16 - - await tb.config_ahb_master.write(0x08, QSPI_INSTR) - QSPI_INSTR = QSPI_INSTR ^ (1<<8) - await tb.config_ahb_master.write(0x08, QSPI_INSTR) - - data = await tb.config_ahb_master.read(0x04,4) - while(int(data[0]['data'],16)&1): - await ClockCycles(dut.HCLK,10) - data = await tb.config_ahb_master.read(0x04,4) - SPI_STAT = await QPI_READ_STAT_REG(dut, tb) - while(SPI_STAT&(1<<24)): - SPI_STAT = await QPI_READ_STAT_REG(dut, tb) - await Timer(time=1, units='us') - - - @cocotb.test() async def QSPI_TESTS(dut): @@ -275,9 +55,9 @@ async def QSPI_TESTS(dut): await SPI_RESET(dut, tb) tb.log.info("Reading JEDIC in SPI mode") - ID = 0x4326BF00 + rID = await SPI_READ_JEDIC(dut, tb) - print(rID) + tb.log.info("Read ID: 0x%x",rID) assert rID == ID tb.log.info("Setting QPI mode") @@ -286,7 +66,7 @@ async def QSPI_TESTS(dut): tb.log.info("Reading JEDIC in QPI mode") rID = await QPI_READ_JEDIC(dut, tb) - print(rID) + tb.log.info("Read ID: 0x%x",rID) assert rID == ID tb.log.info("Enable Write") -- GitLab