Commit 8df14818 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

more hardware tests

parent 49288bf2
Loading
Loading
Loading
Loading
+18 −18
Original line number Diff line number Diff line
@@ -33,13 +33,13 @@ task wait_status_condition;
    begin
        WAITING_STATUS = 1;
        for (match=0; !match; match = invert_match ^ (((registered_rdata ^ {6'h0,pattern}) & {6'h0,mask})==0)) begin
            read_and_wait_status(status_address);
            read_status(status_address);
            if (wait_seq) begin 
                seq_num = (registered_rdata[STATUS_SEQ_SHFT+:6] ^ 6'h20)&'h30;
                write_contol_register(status_control_address, {24'b0,status_mode,seq_num});
                read_and_wait_status(status_address);
                read_status(status_address);
                while (((registered_rdata[STATUS_SEQ_SHFT+:6] ^ seq_num) & 6'h30)!=0) begin // match just 2 MSBs
                    read_and_wait_status(status_address);
                    read_status(status_address);
                end
            end
        end
@@ -58,7 +58,7 @@ task wait_status_condition_auto; // assumes status is already updating
    begin
        WAITING_STATUS = 1;
        for (match=0; !match; match = invert_match ^ (((registered_rdata ^ {6'h0,pattern}) & {6'h0,mask})==0)) begin
            read_and_wait_status(status_address);
            read_status(status_address);
        end
        WAITING_STATUS = 0;
    end
@@ -68,9 +68,9 @@ endtask
 task wait_phase_shifter_ready;
    begin
        WAITING_STATUS = 1;
        read_and_wait_status(MCONTR_PHY_STATUS_REG_ADDR);
        read_status(MCONTR_PHY_STATUS_REG_ADDR);
        while (((registered_rdata & STATUS_PSHIFTER_RDY_MASK) == 0) || (((registered_rdata ^ {24'h0,target_phase}) & 'hff) != 0)) begin
            read_and_wait_status(MCONTR_PHY_STATUS_REG_ADDR); // exits after negedge CLK
            read_status(MCONTR_PHY_STATUS_REG_ADDR); // exits after negedge CLK
        end
        WAITING_STATUS = 0;
    end
@@ -78,21 +78,21 @@ endtask
 
 task read_all_status;
    begin
        read_and_wait_status (MCONTR_PHY_STATUS_REG_ADDR);
        read_and_wait_status (MCONTR_TOP_STATUS_REG_ADDR);
        read_and_wait_status (MCNTRL_PS_STATUS_REG_ADDR);
        read_and_wait_status (MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR);
        read_and_wait_status (MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR);
        read_and_wait_status (MCNTRL_TILED_STATUS_REG_CHN2_ADDR);
        read_and_wait_status (MCNTRL_TILED_STATUS_REG_CHN4_ADDR);
        read_and_wait_status (MCNTRL_TEST01_STATUS_REG_CHN1_ADDR);
        read_and_wait_status (MCNTRL_TEST01_STATUS_REG_CHN2_ADDR);
        read_and_wait_status (MCNTRL_TEST01_STATUS_REG_CHN3_ADDR);
        read_and_wait_status (MCNTRL_TEST01_STATUS_REG_CHN4_ADDR);
        read_status (MCONTR_PHY_STATUS_REG_ADDR);
        read_status (MCONTR_TOP_STATUS_REG_ADDR);
        read_status (MCNTRL_PS_STATUS_REG_ADDR);
        read_status (MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR);
        read_status (MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR);
        read_status (MCNTRL_TILED_STATUS_REG_CHN2_ADDR);
        read_status (MCNTRL_TILED_STATUS_REG_CHN4_ADDR);
        read_status (MCNTRL_TEST01_STATUS_REG_CHN1_ADDR);
        read_status (MCNTRL_TEST01_STATUS_REG_CHN2_ADDR);
        read_status (MCNTRL_TEST01_STATUS_REG_CHN3_ADDR);
        read_status (MCNTRL_TEST01_STATUS_REG_CHN4_ADDR);
    end
 endtask 
  
 task read_and_wait_status;
 task read_status;
    input [STATUS_DEPTH-1:0] address;
    begin
        read_and_wait_w(STATUS_ADDR + address ); // Will set:       registered_rdata <= rdata;
+6 −0
Original line number Diff line number Diff line
@@ -377,7 +377,13 @@ USAGE
                    print
                    for name,val in sorted(callableTasks.items()):
                        if re.match(helpFilter,name):
                            #enable_memcntrl enable_memcntr .__class__.__name__
                            print('=== %s ==='%name)
                            print('defined in %s.%s, %s: %d)'%(str(callableTasks[name]['inst'].__class__.__module__),
                                                       callableTasks[name]['inst'].__class__.__name__,
                                                       callableTasks[name]['func'].func_code.co_filename,
                                                       callableTasks[name]['func'].func_code.co_firstlineno
                                  ))
                            sFuncArgs=getFuncArgsString(name)
                            docs=callableTasks[name]['docs']
                            if docs:
+6 −2
Original line number Diff line number Diff line
@@ -40,12 +40,16 @@ def hx(obj):
Simulate Verilog concatenation. Input list tuple of items, each being a pair of (value, width)
'''    
def concat(items):
#    print(items)
    val=0
    width=0
    for vw in reversed(items):
        v=vw[0]
        if vw[1]==1:
            v=(0,1)[v] # So True/False will also work, not juet o/1
        if vw[1]==1: # So True/False will also work, not just 0/1
            if v:
                v=1
            else:
                v=0
        val |= (v & ((1 << vw[1])-1))<<width
        width += vw[1]
    return (val,width)
+35 −18
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
#from verilog_utils import hx,concat, bits 
from verilog_utils import hx
        
from time import time
class X393AxiControlStatus(object):
    DRY_MODE= True # True
    DEBUG_MODE=1
@@ -72,13 +72,12 @@ class X393AxiControlStatus(object):
        <data> - 32-bit data to write
        """
        self.x393_mem.axi_write_single_w(self.CONTROL_ADDR+reg_addr, data)
    def read_and_wait_status(self, address):
    def read_status(self, address): # was read_and_wait_status
        """
        Read word from the status register (up to 26 bits payload and 6-bit sequence number)
        <addr> - status register address (currently 0..255)
        """
        return self.x393_mem.axi_read_addr_w(self.STATUS_ADDR + address )
    
    def wait_status_condition(self,
                              status_address,         # input [STATUS_DEPTH-1:0] status_address;
                              status_control_address, # input [29:0] status_control_address;
@@ -86,7 +85,8 @@ class X393AxiControlStatus(object):
                              pattern,                # input [25:0] pattern;        // bits as in read registers
                              mask,                   # input [25:0] mask;           // which bits to compare
                              invert_match,           # input        invert_match;   // 0 - wait until match to pattern (all bits), 1 - wait until no match (any of bits differ)
                              wait_seq):              # input        wait_seq; // Wait for the correct sequence number, False assume correct
                              wait_seq,               # input        wait_seq; // Wait for the correct sequence number, False assume correct
                              timeout=10.0):          # maximal timeout (0 - no timeout)
        """
        Poll specified status register until some condition is matched
        <status_address> -         status register address (currently 0..255)
@@ -100,20 +100,37 @@ class X393AxiControlStatus(object):
        <mask> -                   26-bit mask to enable pattern matching (0-s - ignore)
        <invert_match> -           invert match (wait until matching condition becomes false)
        <wait_seq>-                wait for the correct sequence number, if False - assume always correct
        <timeout>                  maximal time to wait for condition
        Return 1 if success, 0 - if timeout
        """
        match=False
        endTime=None
        if timeout>0:
            endTime=time()+timeout
        while not match:
            data=self.read_and_wait_status(status_address)
            data=self.read_status(status_address)
            if wait_seq:
                seq_num = ((data >> self.STATUS_SEQ_SHFT) ^ 0x20) & 0x30
                data=self.read_and_wait_status(status_address)
                self.write_contol_register(status_control_address, ((status_mode & 3) <<6) | (seq_num & 0x3f))
                data=self.read_status(status_address)
                while (((data >> self.STATUS_SEQ_SHFT) ^ seq_num) & 0x30) !=0:
                    data=self.read_and_wait_status(status_address)
                    data=self.read_status(status_address)
                    if self.DRY_MODE: break
                    if timeout and (time()>endTime):
                        print("TIMEOUT in wait_status_condition(status_address=0x%x,status_control_address=0x%x,pattern=0x%x,mask=0x%x,timeout=%f)"%
                               (status_address,status_control_address,pattern,mask,timeout))
                        print ("last read status data is 0x%x, written seq number is 0x%x"%(data,seq_num))
                        return 0
            match = (((data ^ pattern) & mask & 0x3ffffff)==0)
            if invert_match:
                match = not match
            if self.DRY_MODE: break
            if timeout and (time()>endTime):
                print("TIMEOUT1 in wait_status_condition(status_address=0x%x,status_control_address=0x%x,pattern=0x%x,mask=0x%x,timeout=%f)"%
                    (status_address,status_control_address,pattern,mask,timeout))
                print ("last read status data is 0x%x"%(data))
                return 0
        return 1

    def read_all_status(self):
        """
@@ -123,17 +140,17 @@ class X393AxiControlStatus(object):
#        for name in self.__dict__:
#            print (name+": "+str(name=='MCONTR_PHY_STATUS_REG_ADDR'))
#        print (self.__dict__['MCONTR_PHY_STATUS_REG_ADDR'])
        print ("MCONTR_PHY_STATUS_REG_ADDR:          %s"%(hx(self.read_and_wait_status(self.MCONTR_PHY_STATUS_REG_ADDR))))
        print ("MCONTR_TOP_STATUS_REG_ADDR:          %s"%(hx(self.read_and_wait_status(self.MCONTR_TOP_STATUS_REG_ADDR))))
        print ("MCNTRL_PS_STATUS_REG_ADDR:           %s"%(hx(self.read_and_wait_status(self.MCNTRL_PS_STATUS_REG_ADDR))))
        print ("MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR:%s"%(hx(self.read_and_wait_status(self.MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR))))
        print ("MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR:%s"%(hx(self.read_and_wait_status(self.MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR))))
        print ("MCNTRL_TILED_STATUS_REG_CHN2_ADDR:   %s"%(hx(self.read_and_wait_status(self.MCNTRL_TILED_STATUS_REG_CHN2_ADDR))))
        print ("MCNTRL_TILED_STATUS_REG_CHN4_ADDR:   %s"%(hx(self.read_and_wait_status(self.MCNTRL_TILED_STATUS_REG_CHN4_ADDR))))
        print ("MCNTRL_TEST01_STATUS_REG_CHN1_ADDR:  %s"%(hx(self.read_and_wait_status(self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR))))
        print ("MCNTRL_TEST01_STATUS_REG_CHN2_ADDR:  %s"%(hx(self.read_and_wait_status(self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR))))
        print ("MCNTRL_TEST01_STATUS_REG_CHN3_ADDR:  %s"%(hx(self.read_and_wait_status(self.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR))))
        print ("MCNTRL_TEST01_STATUS_REG_CHN4_ADDR:  %s"%(hx(self.read_and_wait_status(self.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR))))
        print ("MCONTR_PHY_STATUS_REG_ADDR:          %s"%(hx(self.read_status(self.MCONTR_PHY_STATUS_REG_ADDR))))
        print ("MCONTR_TOP_STATUS_REG_ADDR:          %s"%(hx(self.read_status(self.MCONTR_TOP_STATUS_REG_ADDR))))
        print ("MCNTRL_PS_STATUS_REG_ADDR:           %s"%(hx(self.read_status(self.MCNTRL_PS_STATUS_REG_ADDR))))
        print ("MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR:%s"%(hx(self.read_status(self.MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR))))
        print ("MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR:%s"%(hx(self.read_status(self.MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR))))
        print ("MCNTRL_TILED_STATUS_REG_CHN2_ADDR:   %s"%(hx(self.read_status(self.MCNTRL_TILED_STATUS_REG_CHN2_ADDR))))
        print ("MCNTRL_TILED_STATUS_REG_CHN4_ADDR:   %s"%(hx(self.read_status(self.MCNTRL_TILED_STATUS_REG_CHN4_ADDR))))
        print ("MCNTRL_TEST01_STATUS_REG_CHN1_ADDR:  %s"%(hx(self.read_status(self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR))))
        print ("MCNTRL_TEST01_STATUS_REG_CHN2_ADDR:  %s"%(hx(self.read_status(self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR))))
        print ("MCNTRL_TEST01_STATUS_REG_CHN3_ADDR:  %s"%(hx(self.read_status(self.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR))))
        print ("MCNTRL_TEST01_STATUS_REG_CHN4_ADDR:  %s"%(hx(self.read_status(self.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR))))

    def program_status(self,
                       base_addr,   # input [29:0] base_addr;
+65 −9
Original line number Diff line number Diff line
@@ -116,22 +116,31 @@ class X393McntrlTests(object):
                    set_per_pin_delays=0):
        """
        Initial setup of the memory controller, including:
            disable (and reset) memory controller
            enable memory controller
            setup status generation in all modules
            tristate patterns
            DQS/DQM patterns
            all sequences
            channel 0 buffer data
            I/O delays
            clock phase
            status generation
            write buffer latency
        <set_per_pin_delays> - 1 - set individual (per-pin) I/O delays, 0 - use common for the whole class
        Returns 1 if phase was set, 0 if it failed         
        """

#reset memory controller
        self.x393_axi_tasks.enable_memcntrl(0)
#enable memory controller
        self.x393_axi_tasks.enable_memcntrl(1)
#program status for all used modules to refresh at any bit change        
        self.x393_axi_tasks.program_status_all(3, 0)
# set dq /dqs tristate on/off patterns
        self.x393_mcntrl_timing.axi_set_tristate_patterns()
# set patterns for DM (always 0) and DQS - always the same (may try different for write lev.)
        self.x393_mcntrl_timing.axi_set_dqs_dqm_patterns()
# prepare all sequences
        self.set_all_sequences;
        self.set_all_sequences()
# prepare write buffer    
        self.x393_mcntrl_buffers.write_block_buf_chn(0,0,256); # fill block memory (channel, page, number)
# set all delays
@@ -149,11 +158,14 @@ class X393McntrlTests(object):
# set clock phase relative to DDR clk
#        print("Debugging: sleeping for 1 second")
#        sleep(1)
        self.x393_mcntrl_timing.axi_set_phase(self.DLY_PHASE);
#        self.x393_axi_tasks.read_all_status()
        
#program status for all used modules to refresh at any bit change        
        self.x393_axi_tasks.program_status_all(3, 0)
        phaseOK=self.x393_mcntrl_timing.axi_set_phase(self.DLY_PHASE,wait_phase_en=True); # wait for phase set
        if not phaseOK:
            print("Failed to set clock phase")
            return 0
# read and print status (optional)
        self.x393_mcntrl_timing.axi_set_wbuf_delay(self.WBUF_DLY_DFLT)
        self.x393_axi_tasks.read_all_status()
        return 1
        
    def set_all_sequences(self):
        """
@@ -182,6 +194,50 @@ class X393McntrlTests(object):
                                                0x1234, # 15'h1234, # row address
                                                0x100   # 10'h100   # column address
        )
    def init_ddr3(self):
        """
        Enable address/command pins, remove SDRST, enable CKE,
        Setup PS PIO
        Set DDR3 MR0..MR3 registers
        """
        """
// enable output for address/commands to DDR chip    
    enable_cmda(1);
    repeat (16) @(posedge CLK) ;
// remove reset from DDR chip    
    activate_sdrst(0); // was enabled at system reset

    #5000; // actually 500 usec required
    repeat (16) @(posedge CLK) ;
    enable_cke(1);
    repeat (16) @(posedge CLK) ;
    
//    enable_memcntrl(1);                 // enable memory controller
    enable_memcntrl_channels(16'h0003); // only channel 0 and 1 are enabled
    configure_channel_priority(0,0);    // lowest priority channel 0
    configure_channel_priority(1,0);    // lowest priority channel 1
    enable_reset_ps_pio(1,0);           // enable, no reset

// set MR registers in DDR3 memory, run DCI calibration (long)
    wait_ps_pio_ready(DEFAULT_STATUS_MODE, 1); // wait FIFO not half full 
    schedule_ps_pio ( // schedule software-control memory operation (may need to check FIFO status first)
                        INITIALIZE_OFFSET, // input [9:0] seq_addr; // sequence start address
                        0,                 // input [1:0] page;     // buffer page number
                        0,                 // input       urgent;   // high priority request (only for competion with other channels, wiil not pass in this FIFO)
                        0,                // input       chn;      // channel buffer to use: 0 - memory read, 1 - memory write
                        `PS_PIO_WAIT_COMPLETE );//  wait_complete; // Do not request a newe transaction from the scheduler until previous memory transaction is finished
                        
   
`ifdef WAIT_MRS 
    wait_ps_pio_done(DEFAULT_STATUS_MODE, 1);
`else    
    repeat (32) @(posedge CLK) ;  // what delay is needed to be sure? Add to PS_PIO?
//    first refreshes will be fast (accummulated while waiting)
`endif    
    enable_refresh(1);
    axi_set_dqs_odelay('h78); //??? dafaults - wrong?
        
        """
        
    def test_write_levelling(self,
                            wait_complete, # Wait for operation to complete
Loading