Loading cocotb/socket_command.py +5 −6 Original line number Diff line number Diff line Loading @@ -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+ Loading Loading @@ -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) cocotb/x393_cocotb_server.py +3 −0 Original line number Diff line number Diff line Loading @@ -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+ Loading cocotb/x393_dut.v +7 −408 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 cocotb/x393interfaces.py +5 −4 Original line number Diff line number Diff line Loading @@ -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 Loading py393/x393_mem.py +1 −14 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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: Loading @@ -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 Loading
cocotb/socket_command.py +5 −6 Original line number Diff line number Diff line Loading @@ -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+ Loading Loading @@ -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)
cocotb/x393_cocotb_server.py +3 −0 Original line number Diff line number Diff line Loading @@ -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+ Loading
cocotb/x393_dut.v +7 −408 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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
cocotb/x393interfaces.py +5 −4 Original line number Diff line number Diff line Loading @@ -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 Loading
py393/x393_mem.py +1 −14 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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: Loading @@ -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