Commit 860b1594 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

minor fixes

parent 05a118d9
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -15,6 +15,11 @@ from __future__ import print_function
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http:#www.gnu.org/licenses/>.
@brief:      Provides sockets-related functionality for both the simulation server
and tghe client. Server is linked to the Cocotb and custom modules and controls
the simulation, server is used to replace memory read/write functionality in the
target system 

@author:     Andrey Filippov
@copyright:  2016 Elphel, Inc.
@license:    GPLv3.0+
@@ -97,19 +102,13 @@ class x393Client():
    def write(self, address, data):
        self.cmd.setWrite([address,data])
        rslt = self.communicate(self.cmd.toJSON())
#        print("write->",rslt)
    def waitIrq(self, irqMask,wait_ns):
        self.cmd.setWait([irqMask,wait_ns])
        rslt = self.communicate(self.cmd.toJSON())
#        print("waitIrq->",rslt)
    def flush(self):
        self.cmd.setFlush()
#        print("flush->",self.communicate(self.cmd.toJSON()))

    def read(self, address):
        self.cmd.setRead(address)
#        print("read->args",self.cmd.getArgs())
        rslt = self.communicate(self.cmd.toJSON())
        #print("read->",rslt)
        return json.loads(rslt)
        
+3 −0
Original line number Diff line number Diff line
@@ -15,6 +15,9 @@ from __future__ import print_function
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http:#www.gnu.org/licenses/>.
@brief:      Simulation server for x393_dut.v top Verilog module.
Listens to the socket connection, accepts incoming commands, applies them
to the simulator and sends back data from the model. 
@author:     Andrey Filippov
@copyright:  2016 Elphel, Inc.
@license:    GPLv3.0+
+7 −408
Original line number Diff line number Diff line
@@ -2,15 +2,15 @@
 * <b>Module:</b> x393_dut
 * @file x393_dut.v
 * @date 2016-06-27  
 * @author eyesis
 * @author Andrey Filippov
 *     
 * @brief Top DUT module for trying cocotb
 * Initially will include other simulation modules, leaving just AXI for communicating
 * with Cocotb
 * @brief Top DUT module for simulating x393 project with Cocotb
 * Includes instances of other Verilog simulation modules and I/O ports
 * for interfacing with Python modules 
 *
 * @copyright Copyright (c) 2016 <set up in Preferences-Verilog/VHDL Editor-Templates> .
 * @copyright Copyright (c) 2016 Elphel, Inc.
 *
 * <b>License </b>
 * <b>License:</b>
 * 
 * x393_dut.v is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
@@ -1712,406 +1712,5 @@ simul_axi_hp_wr #(
assign x393_i.ps7_i.FCLKCLK=        {4{CLK}};
assign x393_i.ps7_i.FCLKRESETN=     {RST,~RST,RST,~RST};
    
//`define SHOW_TMP_TASKS    
   
// Temporary
`ifdef  SHOW_TMP_TASKS
    task   write_contol_register;
        input [29:0] reg_addr;
//        input integer reg_addr;
        input [31:0] data;
        begin
            axi_write_single_w(CONTROL_ADDR+reg_addr, data);
        end
    endtask   

    task   read_contol_register;
        input [29:0] reg_addr;
        begin
            read_and_wait_w(CONTROL_RBACK_ADDR+reg_addr);
        end
    endtask   

    task wait_read_queue_empty;
        begin
        wait (~rvalid && rready && (rid==LAST_ARID)); // nothing left in read queue?   
        SIMUL_AXI_FULL<=1'b0;
        end
    endtask
    task axi_set_rd_lag;
        input [3:0] lag;
        begin
            @(posedge CLK);
            dutm0_xtra_rdlag <= lag;
        end
    endtask

    task axi_set_b_lag;
        input [3:0] lag;
        begin
            @(posedge CLK);
            dutm0_xtra_blag <= lag;
        end
    endtask

    task read_and_wait_w;
    input [29:0] address;
        begin
            read_and_wait ({address,2'b0});
        end
    endtask


    task read_and_wait;
        input      [31:0] address;
        begin
            IRQ_EN = 0;
            wait (CLK);
            while (!MAIN_GO) begin
                wait (!CLK);
                wait (CLK);
            end
            axi_read_addr_inner(
                GLOBAL_READ_ID,    // id
                address & 32'hfffffffc, // addr
                4'h0, // len - single
                1     // burst type - increment
                );
            GLOBAL_READ_ID <= GLOBAL_READ_ID+1;
            wait (!CLK && rvalid && rready);
            wait (CLK);
            registered_rdata <= rdata;
            wait (!CLK); // registered_rdata should be valid on exit
            IRQ_EN = 1;
            if (IRQS) begin
                @(posedge CLK);
                @(negedge CLK);
            end
        end
    endtask
    
    task axi_write_single_w; // address in dwords
        input [29:0] address;
        input [31:0] data;
        begin
`ifdef DEBUG_WR_SINGLE
          $display("axi_write_single_w %h:%h @ %t",address,data,$time);
`endif                
            axi_write_single ({address,2'b0},data);
        end
    endtask

    task axi_write_single; // address in bytes, not words
        input [31:0] address;
        input [31:0] data;
        begin
          axi_write_addr_data(
                    GLOBAL_WRITE_ID,    // id
//                    address << 2, // addr
                    address & 32'hfffffffc, // addr
                    data,
                    4'h0, // len - single
                    1,    // burst type - increment
                    1'b1, // data_en
                    4'hf, // wstrb
                    1'b1 // last
                );
          GLOBAL_WRITE_ID <= GLOBAL_WRITE_ID+1;
          #0.1; // without this delay axi_write_addr_data() used old value of GLOBAL_WRITE_ID
        end
    endtask
   
    task axi_write_addr_data;
        input [11:0] id;
        input [31:0] addr;
        input [31:0] data;
        input [ 3:0] len;
        input [ 1:0] burst;
        input        data_en; // if 0 - do not send data, only address
        input [ 3:0] wstrb;
        input        last;
        begin
            IRQ_EN = 0;
            wait (CLK);
            while (!MAIN_GO) begin
                wait (!CLK);
                wait (CLK);
            end
            axi_write_addr_data_inner (id, addr, data, len, burst, data_en, wstrb, last);
            IRQ_EN = 1;
            if (IRQS) begin
                @(posedge CLK);
                @(negedge CLK);
            end
        end
    endtask

    task axi_write_data;
        input [11:0] id;
        input [31:0] data;
        input [ 3:0] wstrb;
        input        last;
        begin
            IRQ_EN = 0;
            wait (CLK);
            while (!MAIN_GO) begin
                wait (!CLK);
                wait (CLK);
            end
            axi_write_data_inner (id, data, wstrb, last);
            IRQ_EN = 1;
            if (IRQS) begin
                @(posedge CLK);
                @(negedge CLK);
            end
        end
    endtask

// Tasks called from ISR

    task   read_contol_register_irq;
        input  [29:0] reg_addr;
        output [31:0] rslt;
        begin
            read_and_wait_w_irq(CONTROL_RBACK_ADDR+reg_addr, rslt);
        end
    endtask   

 task read_status_irq;
    input [STATUS_DEPTH-1:0] address;
    output [31:0] rslt;
    begin
        read_and_wait_w_irq(STATUS_ADDR + address , rslt);
    end
 endtask

    task read_and_wait_w_irq;
        input [29:0] address;
        output [31:0] rslt;
        begin
            read_and_wait_irq ({address,2'b0},rslt);
        end
    endtask

    task read_and_wait_irq;
        input      [31:0] address;
        output reg [31:0] rslt;
        begin
            axi_read_addr_irq(
                GLOBAL_READ_ID,    // id
                address & 32'hfffffffc, // addr
                4'h0, // len - single
                1     // burst type - increment
                );
            GLOBAL_READ_ID <= GLOBAL_READ_ID+1;
            wait (!CLK && rvalid && rready);
            wait (CLK);
            rslt <= rdata;
            wait (!CLK); // registered_rdata should be valid on exit
        end
    endtask

    task axi_read_addr_irq; // called ferom the main loop, not from interrupts
        input [11:0] id;
        input [31:0] addr;
        input [ 3:0] len;
        input [ 1:0] burst;
        begin
//            IRQ_EN = 0;
//            wait (CLK);
//            while (!MAIN_GO) begin
//                wait (!CLK);
//                wait (CLK);
//            end
            axi_read_addr_inner (id, addr, len, burst);
//            IRQ_EN = 1;
        end
    endtask

    task   write_contol_register_irq;
        input [29:0] reg_addr;
//        input integer reg_addr;
        input [31:0] data;
        begin
            axi_write_single_w_irq(CONTROL_ADDR+reg_addr, data);
        end
    endtask   

    task axi_write_single_w_irq; // address in dwords
        input [29:0] address;
        input [31:0] data;
        begin
`ifdef DEBUG_WR_SINGLE
          $display("axi_write_single_w %h:%h @ %t",address,data,$time);
`endif                
            axi_write_single_irq ({address,2'b0},data);
        end
    endtask

    task axi_write_single_irq; // address in bytes, not words
        input [31:0] address;
        input [31:0] data;
        begin
          axi_write_addr_data_irq(
                    GLOBAL_WRITE_ID,    // id
                    address & 32'hfffffffc, // addr
                    data,
                    4'h0, // len - single
                    1,    // burst type - increment
                    1'b1, // data_en
                    4'hf, // wstrb
                    1'b1 // last
                );
          GLOBAL_WRITE_ID <= GLOBAL_WRITE_ID+1;
          #0.1; // without this delay axi_write_addr_data() used old value of GLOBAL_WRITE_ID
        end
    endtask

    task axi_write_addr_data_irq;
        input [11:0] id;
        input [31:0] addr;
        input [31:0] data;
        input [ 3:0] len;
        input [ 1:0] burst;
        input        data_en; // if 0 - do not send data, only address
        input [ 3:0] wstrb;
        input        last;
        begin
//            IRQ_EN = 0;
//            wait (CLK);
//            while (!MAIN_GO) begin
//                wait (!CLK);
//                wait (CLK);
//            end
            axi_write_addr_data_inner (id, addr, data, len, burst, data_en, wstrb, last);
//            IRQ_EN = 1;
        end
    endtask


// Tasks common for main ind ISR

    task axi_write_addr_data_inner;
        input [11:0] id;
        input [31:0] addr;
        input [31:0] data;
        input [ 3:0] len;
        input [ 1:0] burst;
        input        data_en; // if 0 - do not send data, only address
        input [ 3:0] wstrb;
        input        last;
        reg          data_sent;
//        wire         data_sent_d;
//        assign #(.1) data_sent_d= data_sent;
        begin
            wait (!CLK && dutm0_awready);
            dutm0_awid    <= id;
            dutm0_awaddr  <= addr;
            dutm0_awlen   <= len;
            dutm0_awsize  <= 2'b10;
            dutm0_awburst <= burst;
            dutm0_awvalid <= 1'b1;
            if (data_en && dutm0_wready) begin
                dutm0_wid <= id;
                dutm0_wdata <= data;
                dutm0_wstb <= wstrb;
                dutm0_wlast <= last;
                dutm0_wvalid <= 1'b1; 
                data_sent <= 1'b1;
            end else begin
                data_sent <= 1'b0;
            end
            DEBUG1 <=1'b1;
            wait (CLK);
            DEBUG1 <=1'b0;
            dutm0_awid    <= 'hz;
            dutm0_awaddr  <= 'hz;
            dutm0_awlen   <= 'hz;
            dutm0_awsize  <= 'hz;
            dutm0_awburst <= 'hz;
            dutm0_awvalid <= 1'b0;
            DEBUG2 <=1'b1;
            if (data_sent) begin
                dutm0_wid    <= 'hz;
                dutm0_wdata  <= 'hz;
                dutm0_wstb  <= 'hz;
                dutm0_wlast  <= 'hz;
                dutm0_wvalid <= 1'b0; 
            end
// Now sent data if it was not sent simultaneously with the address
            if (data_en && !data_sent) begin
                DEBUG3 <=1'b1;
                wait (!CLK && dutm0_wready);
                DEBUG3 <=1'b0;
                dutm0_wid    <= id;
                dutm0_wdata  <= data;
                dutm0_wstb  <= wstrb;
                dutm0_wlast  <= last;
                dutm0_wvalid <= 1'b1; 
                wait (CLK);
                DEBUG3 <=1'bx;
                dutm0_wid    <= 'hz;
                dutm0_wdata  <= 'hz;
                dutm0_wstb  <= 'hz;
                dutm0_wlast  <= 'hz;
                dutm0_wvalid <= 1'b0; 
            end
            DEBUG2 <=1'b0;
            #0.1;
            data_sent <= 1'b0;
            #0.1;
        end
    endtask

    task axi_write_data_inner;
        input [11:0] id;
        input [31:0] data;
        input [ 3:0] wstrb;
        input        last;
        begin
            wait (!CLK && dutm0_wready);
            dutm0_wid    <= id;
            dutm0_wdata  <= data;
            dutm0_wstb  <= wstrb;
            dutm0_wlast  <= last;
            dutm0_wvalid <= 1'b1; 
            wait (CLK);
            dutm0_wid    <= 12'hz;
            dutm0_wdata  <= 'hz;
            dutm0_wstb  <= 4'hz;
            dutm0_wlast  <= 1'bz;
            dutm0_wvalid <= 1'b0;
            #0.1;
        end
    endtask

    task axi_read_addr_inner; // regardless of main loop/interrupts
        input [11:0] id;
        input [31:0] addr;
        input [ 3:0] len;
        input [ 1:0] burst;
        begin
            wait (!CLK && dutm0_arready);
            dutm0_arid    <= id;
            dutm0_araddr  <= addr;
            dutm0_arlen   <= len;
            dutm0_arsize  <= 2'b10;
            dutm0_arburst <= burst;
            dut_arvalid <= 1'b1;
            wait (CLK);
            dutm0_arid    <= 12'hz;
            dutm0_araddr  <= 'hz;
            dutm0_arlen   <= 4'hz;
            dutm0_arsize  <= 2'hz;
            dutm0_arburst <= 2'hz;
            dut_arvalid <= 1'b0;
            LAST_ARID <= id;
            NUM_WORDS_EXPECTED <= NUM_WORDS_EXPECTED+len+1;
        end
    endtask

`endif // SHOW_TMP_TASKS


endmodule
+5 −4
Original line number Diff line number Diff line
@@ -17,10 +17,11 @@ from __future__ import print_function
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http:#www.gnu.org/licenses/>.
@author:     Andrey Filippov
@copyright:  2016 Elphel, Inc.
@license:    GPLv3.0+
@contact:    andrey@elphel.coml
@brief      I/O Interfaces of the x393 project for simulation using cocotb 
@author     Andrey Filippov
@copyright  2016 Elphel, Inc.
@license    GPLv3.0+
@contact    andrey@elphel.coml

Uses code from https://github.com/potentialventures/cocotb/blob/master/cocotb/drivers/amba.py
Below are the copyright/license notices of the amba.py
+1 −14
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ class X393Mem(object):
                try:
                    X393_CLIENT.start()
                except:
                    print ("Failed to communicate to the server. Is it started? Swithching to dry tun mode")
                    print ("Failed to communicate to the server. Is it started? Switching to dry run mode")
                    X393_CLIENT = True
                    
                
@@ -170,7 +170,6 @@ class X393Mem(object):
        @param quiet - reduce output
        """
        if X393_CLIENT is True:
#        if self.DRY_MODE:
            print ("simulated: write_mem(0x%x,0x%x)"%(addr,data))
            return
        elif not X393_CLIENT is None:
@@ -184,23 +183,11 @@ class X393Mem(object):
            page_addr=addr & (~(self.PAGE_SIZE-1))
            page_offs=addr-page_addr
            mm = self.wrap_mm(f, page_addr)
#            if (page_addr>=0x80000000):
#                page_addr-= (1<<32)
#            mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
            packedData=struct.pack(self.ENDIAN+"L",data)
            d=struct.unpack(self.ENDIAN+"L",packedData)[0]
            mm[page_offs:page_offs+4]=packedData
            if quiet <2:
                print ("0x%08x <== 0x%08x (%d)"%(addr,d,d))
        '''    
        if MONITOR_EMIO and VEBOSE:
            gpio0=read_mem (0xe000a068)
            gpio1=read_mem (0xe000a06c)
            print("GPIO: %04x %04x %04x %04x"%(gpio1>>16, gpio1 & 0xffff, gpio0>>16, gpio0 & 0xffff))
            if ((gpio0 & 0xc) != 0xc) or ((gpio0 & 0xff00) != 0):
                print("******** AXI STUCK ************")
                exit (0)
        '''    

    def read_mem (self,addr,quiet=1):
        '''
Loading