Commit bf5ea2bb authored by Andrey Filippov's avatar Andrey Filippov

working to add cocotb simualtion

parent bb9fdc40
// This file may be used to define same pre-processor macros to be included into each parsed file opened in the editor
// `define IVERILOG 1 // if IVERILOG is defined, editor will use simulator's "point of view", if not that of synthesis.
`define COCOTB 1 // if IVERILOG is defined, editor will use simulator's "point of view", if not that of synthesis.
`include "system_defines.vh"
\ No newline at end of file
......@@ -51,4 +51,7 @@ simulation_data/*.jpeg
.project
.pydevproject
#copied from .eclipse_project_setup, can be used to import workin set to limit warnings reported
workingSet.psf
\ No newline at end of file
workingSet.psf
*.fst
cocotb/Makefile
cocotb/sim_build
\ No newline at end of file
FPGA_project_0_SimulationTopFile=x393_testbench03.tf
FPGA_project_1_SimulationTopModule=x393_testbench03
FPGA_project_2_DUTTopFile=cocotb/x393_dut.v
FPGA_project_2_ImplementationTopFile=x393.v
FPGA_project_3_DUTTopModule=x393_dut
FPGA_project_4_part=xc7z030fbg484-1
FPGA_project_5_part=xc7z030fbg484-1
com.elphel.store.context.FPGA_project=FPGA_project_2_ImplementationTopFile<-@\#\#@->FPGA_project_4_part<-@\#\#@->FPGA_project_0_SimulationTopFile<-@\#\#@->FPGA_project_1_SimulationTopModule<-@\#\#@->FPGA_project_5_part<-@\#\#@->
com.elphel.store.context.FPGA_project=FPGA_project_2_ImplementationTopFile<-@\#\#@->FPGA_project_4_part<-@\#\#@->FPGA_project_0_SimulationTopFile<-@\#\#@->FPGA_project_1_SimulationTopModule<-@\#\#@->FPGA_project_5_part<-@\#\#@->FPGA_project_2_DUTTopFile<-@\#\#@->FPGA_project_3_DUTTopModule<-@\#\#@->
eclipse.preferences.version=1
cocotb_107_CocotbDutTopFile=cocotb/x393_dut.v
cocotb_111_CocotbMODULE=x393coco_02<-@\#\#@->
cocotb_112_CocotbTESTCASE=run_test<-@\#\#@->
cocotb_116_GTKWaveSavFile=x393_cocotb_02.sav
cocotb_118_CocotbIncludeDir=${verilog_project_loc}/includes<-@\#\#@->${verilog_project_loc}/ddr3<-@\#\#@->${verilog_project_loc}/x393_sata<-@\#\#@->${verilog_project_loc}/x393_sata/host<-@\#\#@->
cocotb_122_CocotbExtraFiles=glbl.v<-@\#\#@->
com.elphel.store.context.cocotb=cocotb_107_CocotbDutTopFile<-@\#\#@->cocotb_116_GTKWaveSavFile<-@\#\#@->cocotb_118_CocotbIncludeDir<-@\#\#@->cocotb_122_CocotbExtraFiles<-@\#\#@->cocotb_111_CocotbMODULE<-@\#\#@->cocotb_112_CocotbTESTCASE<-@\#\#@->
eclipse.preferences.version=1
......@@ -39,60 +39,65 @@
* with at least one of the Free Software programs.
*/
`timescale 1ns/1ps
`define COCOTB
`include "system_defines.vh"
module x393_dut#(
`include "includes/x393_parameters.vh" // SuppressThisWarning VEditor - not used
`include "includes/x393_simulation_parameters.vh"
)(
// MAXIGP0 AXI interface
output maxigp0aclk,
input maxigp0aresetn,
output dutm0_aclk,
output reset_out,
// axi ps master gp0: read address
input [31:0] maxigp0araddr,
input maxigp0arvalid,
output maxigp0arready,
input [11:0] maxigp0arid,
input [1:0] maxigp0arlock,
input [3:0] maxigp0arcache,
input [2:0] maxigp0arprot,
input [3:0] maxigp0arlen,
input [1:0] maxigp0arsize,
input [1:0] maxigp0arburst,
input [3:0] maxigp0arqos,
input [31:0] dutm0_araddr,
output dutm0_arready,
input dutm0_arvalid, // was dutm0_ar_set_cmd
input [11:0] dutm0_arid,
input [1:0] dutm0_arlock, //SuppressThisWarning VEditor unused
input [3:0] dutm0_arcache, //SuppressThisWarning VEditor unused
input [2:0] dutm0_arprot, //SuppressThisWarning VEditor unused
input [3:0] dutm0_arlen,
input [1:0] dutm0_arsize,
input [1:0] dutm0_arburst,
input [3:0] dutm0_arqos, //SuppressThisWarning VEditor unused
// axi ps master gp0: read data
output [31:0] maxigp0rdata,
output maxigp0rvalid,
input maxigp0rready,
output [11:0] maxigp0rid,
output maxigp0rlast,
output [1:0] maxigp0rresp,
// axi ps master gp0: write address
input [31:0] maxigp0awaddr,
input maxigp0awvalid,
output maxigp0awready,
input [11:0] maxigp0awid,
input [1:0] maxigp0awlock,
input [3:0] maxigp0awcache,
input [2:0] maxigp0awprot,
input [3:0] maxigp0awlen,
input [1:0] maxigp0awsize,
input [1:0] maxigp0awburst,
input [3:0] maxigp0awqos,
output [31:0] dutm0_rdata,
output dutm0_rvalid,
output dutm0_rready, // internally generated as a slow response to dutm0_rvalid. Cn be moved to Python and made input here
output [11:0] dutm0_rid,
output dutm0_rlast,
output [1:0] dutm0_rresp,
// axi ps master gp0: write address
input [31:0] dutm0_awaddr,
input dutm0_awvalid,
output dutm0_awready,
input [11:0] dutm0_awid,
input [1:0] dutm0_awlock, //SuppressThisWarning VEditor unused
input [3:0] dutm0_awcache, //SuppressThisWarning VEditor unused
input [2:0] dutm0_awprot, //SuppressThisWarning VEditor unused
input [3:0] dutm0_awlen,
input [1:0] dutm0_awsize,
input [1:0] dutm0_awburst,
input [3:0] dutm0_awqos, //SuppressThisWarning VEditor unused
// axi ps master gp0: write data
input [31:0] maxigp0wdata,
input maxigp0wvalid,
output maxigp0wready,
input [11:0] maxigp0wid,
input maxigp0wlast,
input [3:0] maxigp0wstrb,
input [31:0] dutm0_wdata,
input dutm0_wvalid,
output dutm0_wready,
input [11:0] dutm0_wid,
input dutm0_wlast,
input [ 3:0] dutm0_wstb,
// axi ps master gp0: write response
output maxigp0bvalid,
input maxigp0bready,
output [11:0] maxigp0bid,
output [1:0] maxigp0bresp,
output dutm0_bvalid,
output dutm0_bready,// internally generated as a slow response to dutm0_bvalid. Cn be moved to Python and made input here
output [11:0] dutm0_bid,
output [1:0] dutm0_bresp,
// SATA and SATA clock I/O
// SATA data interface
input [3:0] dutm0_xtra_rdlag, // ready signal lag in axi read channel (0 - RDY=1, 1..15 - RDY is asserted N cycles after valid)
input [3:0] dutm0_xtra_blag, // ready signal lag in axi arete response channel (0 - RDY=1, 1..15 - RDY is asserted N cycles after valid)
// SATA data interface
input sata_rxn,
input sata_rxp,
output sata_txn,
......@@ -103,6 +108,114 @@ module x393_dut#(
);
// Temporary = to be moved to Python?
// MAXIGP0 AXI interface
wire maxigp0aclk;
wire maxigp0aresetn;
// axi ps master gp0: read address
wire [31:0] maxigp0araddr;
wire maxigp0arvalid;
wire maxigp0arready;
wire [11:0] maxigp0arid;
wire [1:0] maxigp0arlock;
wire [3:0] maxigp0arcache;
wire [2:0] maxigp0arprot;
wire [3:0] maxigp0arlen;
wire [1:0] maxigp0arsize;
wire [1:0] maxigp0arburst;
wire [3:0] maxigp0arqos;
// axi ps master gp0: read data
wire [31:0] maxigp0rdata;
wire maxigp0rvalid;
wire maxigp0rready;
wire [11:0] maxigp0rid;
wire maxigp0rlast;
wire [1:0] maxigp0rresp;
// axi ps master gp0: write address
wire [31:0] maxigp0awaddr;
wire maxigp0awvalid;
wire maxigp0awready;
wire [11:0] maxigp0awid;
wire [1:0] maxigp0awlock;
wire [3:0] maxigp0awcache;
wire [2:0] maxigp0awprot;
wire [3:0] maxigp0awlen;
wire [1:0] maxigp0awsize;
wire [1:0] maxigp0awburst;
wire [3:0] maxigp0awqos;
// axi ps master gp0: write data
wire [31:0] maxigp0wdata;
wire maxigp0wvalid;
wire maxigp0wready;
wire [11:0] maxigp0wid;
wire maxigp0wlast;
wire [3:0] maxigp0wstrb;
// axi ps master gp0: write response
wire maxigp0bvalid;
wire maxigp0bready;
wire [11:0] maxigp0bid;
wire [1:0] maxigp0bresp;
assign dutm0_aclk = maxigp0aclk;
assign dutm0_rdata = maxigp0rdata;
assign dutm0_rid = maxigp0rid;
assign dutm0_rresp = maxigp0rresp;
assign dutm0_bid = maxigp0bid;
assign dutm0_bresp = maxigp0bresp;
assign dutm0_rvalid = maxigp0rvalid;
assign dutm0_bvalid = maxigp0bvalid;
assign dutm0_rready = maxigp0rready; // temporary
assign dutm0_bready = maxigp0bready; // temporary
assign dutm0_rlast= maxigp0rlast;
reg [11:0] LAST_ARID; // last issued ARID
// SuppressWarnings VEditor : assigned in $readmem() system task
wire [SIMUL_AXI_READ_WIDTH-1:0] SIMUL_AXI_ADDR_W;
// SuppressWarnings VEditor
wire SIMUL_AXI_MISMATCH;
// SuppressWarnings VEditor
reg [31:0] SIMUL_AXI_READ;
// SuppressWarnings VEditor
reg [SIMUL_AXI_READ_WIDTH-1:0] SIMUL_AXI_ADDR;
// SuppressWarnings VEditor
reg SIMUL_AXI_FULL; // some data available
// wire SIMUL_AXI_EMPTY= ~rvalid && rready && (rid==LAST_ARID); //S uppressThisWarning VEditor : may be unused, just for simulation // use it to wait for?
// reg [31:0] registered_rdata; // here read data from tasks goes
// SuppressWarnings VEditor
reg WAITING_STATUS; // tasks are waiting for status
// SuppressWarnings VEditor all - these variables are just for viewing, not used anywhere else
reg DEBUG1, DEBUG2, DEBUG3;
reg [11:0] GLOBAL_WRITE_ID=0;
reg [11:0] GLOBAL_READ_ID=0;
// reg [7:0] target_phase=0; // to compare/wait for phase shifter ready
// End of Temporary = to be moved to Python?
// For simulating MAXIGP0
wire [11:0] #(AXI_TASK_HOLD) dutm0_arid_w = dutm0_arid;
wire [31:0] #(AXI_TASK_HOLD) dutm0_araddr_w = dutm0_araddr;
wire [3:0] #(AXI_TASK_HOLD) dutm0_arlen_w = dutm0_arlen;
wire [1:0] #(AXI_TASK_HOLD) dutm0_arsize_w = dutm0_arsize;
wire [1:0] #(AXI_TASK_HOLD) dutm0_arburst_w = dutm0_arburst;
wire [11:0] #(AXI_TASK_HOLD) dutm0_awid_w = dutm0_awid;
wire [31:0] #(AXI_TASK_HOLD) dutm0_awaddr_w = dutm0_awaddr;
wire [3:0] #(AXI_TASK_HOLD) dutm0_awlen_w = dutm0_awlen;
wire [1:0] #(AXI_TASK_HOLD) dutm0_awsize_w = dutm0_awsize;
wire [1:0] #(AXI_TASK_HOLD) dutm0_awburst_w = dutm0_awburst;
wire [11:0] #(AXI_TASK_HOLD) dutm0_wid_w = dutm0_wid;
wire [31:0] #(AXI_TASK_HOLD) dutm0_wdata_w = dutm0_wdata;
wire [ 3:0] #(AXI_TASK_HOLD) dutm0_wstb_w = dutm0_wstb;
wire #(AXI_TASK_HOLD) dutm0_wlast_w = dutm0_wlast;
wire #(AXI_TASK_HOLD) dut_arvalid_w = dutm0_arvalid;
wire #(AXI_TASK_HOLD) dutm0_awvalid_w = dutm0_awvalid; // was dutm0_aw_set_cmd
wire #(AXI_TASK_HOLD) dutm0_wvalid_w = dutm0_wvalid; // was dutm0_wset_cmd
// Connect MAXIGP0 i/o to that of PS7 inside x393_i
assign maxigp0aclk = x393_i.axi_aclk;
assign x393_i.ps7_i.MAXIGP0ARESETN = maxigp0aresetn;
......@@ -160,15 +273,23 @@ module x393_dut#(
`endif // NON_VDT_ENVIROMENT
`else // IVERILOG
// $display("IVERILOG is not defined");
`ifdef CVC
`ifdef COCOTB
`ifdef NON_VDT_ENVIROMENT
parameter fstname = "x393.fst";
`else // NON_VDT_ENVIROMENT
`include "IVERILOG_INCLUDE.v"
`endif // NON_VDT_ENVIROMENT
`else
parameter fstname = "x393.fst";
`endif // CVC
`ifdef CVC
`ifdef NON_VDT_ENVIROMENT
parameter fstname = "x393.fst";
`else // NON_VDT_ENVIROMENT
`include "IVERILOG_INCLUDE.v"
`endif // NON_VDT_ENVIROMENT
`else
parameter fstname = "x393.fst";
`endif // CVC
`endif // COCOTB
`endif // IVERILOG
`define DEBUG_WR_SINGLE 1
`define DEBUG_RD_DATA 1
......@@ -234,6 +355,7 @@ parameter NUM_INTERRUPTS = 9;
// ========================== end of parameters from x353 ===================================
reg [639:0] TEST_TITLE="abcdef"; //SuppressThisWarning VEditor
// Sensor signals - as on sensor pads
wire PX1_MCLK; // input sensor input clock
......@@ -636,7 +758,7 @@ assign #10 gpio_pins[9] = gpio_pins[8];
else if (PS_REG_RD1) PS_RDATA <= PS_REG_DOUT1;
end
reg [639:0] TEST_TITLE; //SuppressThisWarning VEditor May use again later
// reg [639:0] TEST_TITLE="abcdef"; //S uppressThisWarning VEditor May use again later
// Simulation signals
wire CLK;
......@@ -663,13 +785,13 @@ assign #10 gpio_pins[9] = gpio_pins[8];
// Simulation modules interconnection
// integer NUM_WORDS_READ;
// integer NUM_WORDS_EXPECTED;
integer NUM_WORDS_EXPECTED;
// reg [15:0] ENABLED_CHANNELS = 0; // currently enabled memory channels
// reg [31:0] DEBUG_DATA; //S uppressThisWarning VEditor : just for simulation viewing
// integer DEBUG_ADDRESS; //S uppressThisWarning VEditor : just for simulation viewing
assign reset_out = RST || x393_i.arst;
x393 #(
// TODO: Are these parameters needed? They are included in x393 from the save x393_parameters.vh
.MCONTR_WR_MASK (MCONTR_WR_MASK),
......@@ -967,6 +1089,133 @@ assign #10 gpio_pins[9] = gpio_pins[8];
);
// Simulation modules
simul_axi_master_rdaddr #(
.ID_WIDTH (12),
.ADDRESS_WIDTH (32),
.LATENCY (AXI_RDADDR_LATENCY), // minimal delay between inout and output ( 0 -next cycle)
.DEPTH (8), // maximal number of commands in FIFO
.DATA_DELAY (3.5),
.VALID_DELAY (4.0)
) simul_axi_master_rdaddr_i (
.clk (maxigp0aclk),//CLK),// input
.reset (RST), // input
.arid_in (dutm0_arid_w[11:0]), // input[11:0]
.araddr_in (dutm0_araddr_w[31:0]), // input[31:0]
.arlen_in (dutm0_arlen_w[3:0]), // input[3:0]
.arsize_in (dutm0_arsize_w[1:0]), // input[1:0]
.arburst_in (dutm0_arburst_w[1:0]), // input[1:0]
.arcache_in (4'b0), // input[3:0]
.arprot_in (3'b0), // input[2:0]
.arid (maxigp0arid), // output[11:0]
.araddr (maxigp0araddr), // output[31:0]
.arlen (maxigp0arlen), // output[3:0]
.arsize (maxigp0arsize), // output[1:0]
.arburst (maxigp0arburst), // output[1:0]
.arcache (maxigp0arcache), // output[3:0]
.arprot (maxigp0arprot), // output[2:0]
.arvalid (maxigp0arvalid), // output
.arready (maxigp0arready), // input
.set_cmd (dut_arvalid_w), // input // latch all other input data at posedge of clock
.ready (dutm0_arready) // output // command/data FIFO can accept command
);
// Non-implemented signals in simul_axi_master_rdaddr
assign maxigp0aresetn = 'bz;
assign maxigp0arlock = 'bz;
assign maxigp0arqos = 'bz;
simul_axi_master_wraddr #(
.ID_WIDTH (12),
.ADDRESS_WIDTH (32),
.LATENCY (AXI_WRADDR_LATENCY), // minimal delay between inout and output ( 0 - next cycle)
.DEPTH (8), // maximal number of commands in FIFO
.DATA_DELAY (3.5),
.VALID_DELAY (4.0)
) simul_axi_master_wraddr_i (
.clk (maxigp0aclk), // input
.reset (RST), // input
.awid_in (dutm0_awid_w[11:0]), // input[11:0]
.awaddr_in (dutm0_awaddr_w[31:0]), // input[31:0]
.awlen_in (dutm0_awlen_w[3:0]), // input[3:0]
.awsize_in (dutm0_awsize_w[1:0]), // input[1:0]
.awburst_in (dutm0_awburst_w[1:0]), // input[1:0]
.awcache_in (4'b0), // input[3:0]
.awprot_in (3'b0), // input[2:0]
.awid (maxigp0awid), // output[11:0]
.awaddr (maxigp0awaddr), // output[31:0]
.awlen (maxigp0awlen), // output[3:0]
.awsize (maxigp0awsize), // output[1:0]
.awburst (maxigp0awburst), // output[1:0]
.awcache (maxigp0awcache), // output[3:0]
.awprot (maxigp0awprot), // output[2:0]
.awvalid (maxigp0awvalid), // output
.awready (maxigp0awready), // input
.set_cmd (dutm0_awvalid_w), // input // latch all other input data at posedge of clock
.ready (dutm0_awready) // output // command/data FIFO can accept command
);
// Non-implemented signals in simul_axi_master_wraddr
assign maxigp0awlock = 'bz;
assign maxigp0awqos = 'bz;
simul_axi_master_wdata #(
.ID_WIDTH (12),
.DATA_WIDTH (32),
.WSTB_WIDTH (4),
.LATENCY (AXI_WRDATA_LATENCY), // minimal delay between inout and output ( 0 - next cycle)
.DEPTH (8), // maximal number of commands in FIFO
.DATA_DELAY (3.2),
.VALID_DELAY (3.6)
) simul_axi_master_wdata_i (
.clk (maxigp0aclk), // input
.reset (RST), // input
.wid_in (dutm0_wid_w[11:0]), // input[11:0]
.wdata_in (dutm0_wdata_w[31:0]), // input[31:0]
.wstrb_in (dutm0_wstb_w[3:0]), // input[3:0]
.wlast_in (dutm0_wlast_w), // input
.wid (maxigp0wid), // output[11:0]
.wdata (maxigp0wdata), // output[31:0]
.wstrb (maxigp0wstrb), // output[3:0]
.wlast (maxigp0wlast), // output
.wvalid (maxigp0wvalid), // output
.wready (maxigp0wready), // input
.set_cmd (dutm0_wvalid_w), // input // latch all other input data at posedge of clock
.ready (dutm0_wready) // output // command/data FIFO can accept command
);
// These two modules generate ready (from host) as a slow response to valid (from FPGA). This functionality may be moved to Python
// Until then dutm0_rready and dutm0_bready are outputs, not inputs
simul_axi_slow_ready simul_axi_slow_ready_i (
.clk (maxigp0aclk), // input
.reset (RST), // input
.delay (dutm0_xtra_rdlag), // input[3:0]
.valid (maxigp0rvalid), // input
.ready (maxigp0rready) // output
);
simul_axi_slow_ready simul_axi_slow_ready_write_resp_i(
.clk (maxigp0aclk), // input
.reset (RST), // input
.delay (dutm0_xtra_blag), // input[3:0]
.valid (maxigp0bvalid), // input
.ready (maxigp0bready) // output
);
simul_axi_read #(
.ADDRESS_WIDTH (SIMUL_AXI_READ_WIDTH)
) simul_axi_read_i (
.clk (maxigp0aclk), // input
.reset (RST), // input
.last (maxigp0rlast), // input
.data_stb (maxigp0rready & maxigp0rvalid), // input
.raddr (dutm0_araddr_w[SIMUL_AXI_READ_WIDTH+1:2]), // input[9:0]
.rlen (dutm0_arlen_w), // input[3:0]
.rcmd (dut_arvalid_w), // input
.addr_out (SIMUL_AXI_ADDR_W[SIMUL_AXI_READ_WIDTH-1:0]), // output[9:0]
.burst (), // output // burst in progress - just debug
.err_out () // output reg // data last does not match predicted or FIFO over/under run - just debug
);
simul_axi_hp_rd #(
.HP_PORT(0)
......@@ -1461,11 +1710,18 @@ simul_axi_hp_wr #(
// Initilize simulation
`ifndef ROOTPATH
`define ROOTPATH "."
`endif
`define DATAPATH "input_data"
initial begin
$dumpfile(fstname);
// SuppressWarnings VEditor : assigned in $readmem() system task
$dumpvars(0,x393_dut);
$display(`ROOTPATH);
$display({`ROOTPATH,"/",`DATAPATH});
RST_CLEAN = 1;
RST = 1'bx;
#500;
......@@ -1481,8 +1737,413 @@ simul_axi_hp_wr #(
IRQ_FRSEQ_DONE = 0;
IRQ_CMPRS_DONE = 0;
IRQ_SATA_DONE = 0;
#5000;
$finish;
end
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
......
from __future__ import print_function
"""
# Copyright (C) 2016, Elphel.inc.
# Implementation of AXI4-based buses used in Elpphel x393 camera project
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# 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
Uses code from https://github.com/potentialventures/cocotb/blob/master/cocotb/drivers/amba.py
Below are the copyright/license notices of the amba.py
------------------------------------------------------
Copyright (c) 2014 Potential Ventures Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Potential Ventures Ltd,
SolarFlare Communications Inc nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL POTENTIAL VENTURES LTD BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. '''
"""
import cocotb
from cocotb.triggers import Timer, RisingEdge, ReadOnly, Lock
from cocotb.drivers import BusDriver
from cocotb.result import ReturnValue
from cocotb.binary import BinaryValue
import binascii
import array
#channels
AR_CHN="AR"
AW_CHN="AW"
R_CHN="R"
W_CHN="W"
B_CHN="B"
class MAXIGPReadError(Exception):
# print ("MAXIGPReadError")
pass
class MAXIGPMaster(BusDriver):
"""
Implements subset of AXI4 used in x393 project for Xilinx Zynq MAXIGP*
"""
_signals=[ # i/o from the DUT side
# read address channel
"araddr", # input [31:0]
"arready", # output
"arvalid", # input
"arid", # input [11:0]
"arlock", # input [1:0]
"arcache", # input [3:0]
"arprot", # input [2:0]
"arlen", # input [3:0]
"arsize", # input [1:0]
"arburst", # input [1:0],
"arqos", # input [3:0]
# axi ps master gp0: read data
"rdata", # output [31:0]
"rvalid", # output
"rready", # output (normally input, but temporarily in passive ready mode)
"rid", # output [11:0]
"rlast", # output
"rresp", # output [1:0]
# axi ps master gp0: write address
"awaddr", # input [31:0]
"awvalid", # input
"awready", # output
"awid", # input [11:0]
"awlock", # input [1:0]
"awcache", # input [3:0]
"awprot", # input [2:0]
"awlen", # input [3:0]
"awsize", # input [1:0]
"awburst", # input [1:0]
"awqos", # input [3:0]
# axi ps master gp0: write data
"wdata", # input [31:0]
"wvalid", # input
"wready", # output
"wid", # input [11:0]
"wlast", # input
"wstb", # input [3:0]
# axi ps master gp0: write response
"bvalid", # output
"bready", # output (normally input, but temporarily in passive ready mode)
"bid", # output [11:0]
"bresp", # output [1:0]
# x393 specific signals (controls AXI latencies
"xtra_rdlag", #input [3:0]
"xtra_blag" #input [3:0]
]
_channels = [AR_CHN,AW_CHN,R_CHN,W_CHN,B_CHN]
def __init__(self, entity, name, clock, rdlag=None, blag=None):
BusDriver.__init__(self, entity, name, clock)
# set read and write back channels simulation lag between AXI sets valid and host responds with
# ready. If None - drive these signals
self.log.debug ("MAXIGPMaster.__init__(): super done")
if rdlag is None:
self.bus.rready.setimmediatevalue(1)
else:
self.bus.xtra_rdlag.setimmediatevalue(rdlag)
if blag is None:
self.bus.bready.setimmediatevalue(1)
else:
self.bus.xtra_blag.setimmediatevalue(blag)
self.bus.awvalid.setimmediatevalue(0)
self.bus.wvalid.setimmediatevalue(0)
self.bus.arvalid.setimmediatevalue(0)
#just in case - set unimplemented in Zynq
self.bus.arlock.setimmediatevalue(0)
self.bus.arcache.setimmediatevalue(0)
self.bus.arprot.setimmediatevalue(0)
self.bus.arqos.setimmediatevalue(0)
self.bus.awlock.setimmediatevalue(0)
self.bus.awcache.setimmediatevalue(0)
self.bus.awprot.setimmediatevalue(0)
self.bus.awqos.setimmediatevalue(0)
self.busy_channels = {}
self.log.debug ("MAXIGPMaster.__init__(): pre-lcok done")
#Locks on each subchannel
for chn in self._channels:
self.log.debug ("MAXIGPMaster.__init__(): chn = %s"%(chn))
self.busy_channels[chn]=Lock("%s_%s_busy"%(name,chn))
def _float_signals(self,signals):
if not isinstance (signals,(list,tuple)):
signals = (signals,)
for signal in signals:
v = signal.value
v.binstr = "z" * len(signal)
signal <= v
@cocotb.coroutine
def _send_write_address(self, address, delay, id, dlen, dsize, burst):
"""
Send write address with parameters
@param address binary byte address for burst start
@param delay Latency sending address in clock cycles
@param id transaction ID
@param dlen burst length (1..16)
@param dsize - data width - (1 << dsize) bytes (MAXIGP has only 2 bits while AXI specifies 3) 2 means 32 bits
@param burst burst type (0 - fixed, 1 - increment, 2 - wrap, 3 - reserved)
"""
# self.log.debug ("MAXIGPMaster._send_write_address(",address,", ",delay,", ",id,", ",dlen ,", ",dsize, ", ", burst)
yield self.busy_channels[AW_CHN].acquire()
self.log.debug ("MAXIGPMaster._send_write_address(): acquired lock")
for _ in range(delay):
yield RisingEdge(self.clock)
self.log.debug ("MAXIGPMaster._send_write_address(): delay over")
self.bus.awvalid <= 1
self.bus.awid <= id
self.bus.awsize <= dsize
self.bus.awburst <= burst
while dlen > 16:
self.bus.awaddr <= address
address += 16*(1 << dsize)
dlen -= 16
self.bus.awlen <= 15
while True:
yield ReadOnly()
if self.bus.awready.value:
break
yield RisingEdge(self.clock)
yield RisingEdge(self.clock)
self.bus.awaddr <= address
self.bus.awlen <= dlen -1
self.log.debug ("1.MAXIGPMaster._send_write_address(), address=0x%08x, dlen = 0x%x"%(address, dlen))
while True:
yield ReadOnly()
if self.bus.awready.value:
break
yield RisingEdge(self.clock)
yield RisingEdge(self.clock)
self.bus.awvalid <= 0
# FLoat all assigned bus signals but awvalid
self._float_signals((self.bus.awaddr,self.bus.awid, self.bus.awlen, self.bus.awsize,self.bus.awburst))
self.busy_channels[AW_CHN].release()
self.log.debug ("MAXIGPMaster._send_write_address(): released lock %s"%(AW_CHN))
@cocotb.coroutine
def _send_write_data(self, data, wrstb, delay, id, dsize):
"""
Send a data word or a list of data words (supports multi-burst)
@param data a list/tuple of words to send
@param wrstb - write mask list (same size as data)
@param delay latency in clock cycles
@param id transaction ID
@param dsize - data width - (1 << dsize) bytes (MAXIGP has only 2 bits while AXI specifies 3) 2 means 32 bits
"""
# self.log.debug ("MAXIGPMaster._send_write_data(",data,", ",wrstb,", ", delay,", ",id,", ",dsize)
yield self.busy_channels[W_CHN].acquire()
self.log.debug ("MAXIGPMaster._send_write_data(): acquired lock")
for cycle in range(delay):
yield RisingEdge(self.clock)
self.bus.wvalid <= 1
self.bus.wid <= id
for i,val_wstb in enumerate(zip(data,wrstb)):
# self.log.debug ("MAXIGPMaster._send_write_data(), i= ",i,", val_wstb=",val_wstb)
if (i == (len(data) - 1)) or ((i % 16) == 15):
self.bus.wlast <= 1
else:
self.bus.wlast <= 0
self.bus.wdata <= val_wstb[0]
self.bus.wstb <= val_wstb[1]
while True:
yield ReadOnly()
if self.bus.wready.value:
break
yield RisingEdge(self.clock)
yield RisingEdge(self.clock)
self.bus.wvalid <= 0
# FLoat all assigned bus signals but wvalid
self._float_signals((self.bus.wdata,self.bus.wstb,self.bus.wlast))
self.busy_channels[W_CHN].release()
self.log.debug ("MAXIGPMaster._send_write_data(): released lock %s"%(W_CHN))
"""
@cocotb.coroutine
def print_test(self):
print ("test2, clock=",self.clock);
yield Timer(10)
# yield RisingEdge(self.clock)
print ("test2, pass2, clock=",self.clock);
"""
@cocotb.coroutine
def axi_write(self, address, value, byte_enable=None, address_latency=0,
data_latency=0,
id=0, dsize=2, burst=1):
self.log.debug("axi_write")
"""
Write a data burst.
@param address binary byte address for burst start
@param value - a value or a list of values (supports multi-burst, but no interrupts between bursts)
@param byte_enable - byte enable mask. Should be None (all enabled) or have the same number of items as data
@param address_latency latency sending address in clock cycles
@param data_latency latency sending data in clock cycles
@param id transaction ID
@param dsize - data width - (1 << dsize) bytes (MAXIGP has only 2 bits while AXI specifies 3) 2 means 32 bits
@param burst burst type (0 - fixed, 1 - increment, 2 - wrap, 3 - reserved)
"""
# self.log.debug ("1.MAXIGPMaster.write(",address,", ",value, ",", byte_enable,", ",address_latency,",",
# data_latency,", ",id,", ",dsize,", ", burst)
if not isinstance(value, (list,tuple)):
value = (value,)
if not isinstance(byte_enable, (list,tuple)):
if byte_enable is None:
byte_enable = (1 << (1 << dsize)) - 1
byte_enable = [byte_enable]*len(value)
if None in byte_enable:
for i in range(len(byte_enable)):
if byte_enable[i] is None:
byte_enable[i] = (1 << (1 << dsize)) - 1
#assert len(value) == len(byte_enable), ("values and byte enable arrays have different lengths: %d and %d"%
# (len(value),len(byte_enable)))
# self.log.debug ("2.MAXIGPMaster.write(",address,", ",value, ",", byte_enable,", ",address_latency,",",
# data_latency,", ",id,", ",dsize,", ", burst)
c_addr = cocotb.fork(self._send_write_address(address= address,
delay= address_latency,
id = id,
dlen = len(value),
dsize = dsize,
burst = burst))
c_data = cocotb.fork(self._send_write_data(data = value,
wrstb = byte_enable,
delay= data_latency,
id = id,
dsize = dsize))
#(self, data, wrstb, delay, id, dsize)
if c_addr:
self.log.debug ("c_addr.join()")
yield c_addr.join()
if c_data:
self.log.debug ("c_data.join()")
yield c_data.join()
yield RisingEdge(self.clock)
# result = self.bus.bresp.value
# raise ReturnValue(0) #result)
"""
# It will be to slow if to wait for response after each word sent, need to put a separate monitor on B-channel
# Wait for the response
while True:
yield ReadOnly()
if self.bus.BVALID.value and self.bus.BREADY.value:
result = self.bus.BRESP.value
break
yield RisingEdge(self.clock)
yield RisingEdge(self.clock)
if int(result):
raise AXIReadError("Write to address 0x%08x failed with BRESP: %d"
% (address, int(result)))
raise ReturnValue(result)
"""
from __future__ import print_function
"""
# Copyright (C) 2016, Elphel.inc.
# Simulation code for cocotb simulation for x393 project
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# 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
"""
import cocotb
from cocotb.triggers import Timer
from x393buses import MAXIGPMaster
from cocotb.drivers import BitDriver
from cocotb.triggers import Timer, RisingEdge, ReadOnly
from cocotb.result import ReturnValue, TestFailure, TestError, TestSuccess
import logging
class X393_cocotb_02(object):
def __init__(self, dut, debug=True):
self.dut = dut
self.axiwr = MAXIGPMaster(entity=dut, name="dutm0", clock=dut.dutm0_aclk, rdlag=0, blag=0)
# self.clock = dut.dutm0_aclk
level = logging.DEBUG if debug else logging.WARNING
self.axiwr.log.setLevel(level)
def print_test(self):
print ("test");
@cocotb.coroutine
def run_test(dut, data_in=None, config_coroutine=None, idle_inserter=None,
backpressure_inserter=None):
print ("run_test(): starting X393_cocotb_02(dut) init")
tb = X393_cocotb_02(dut)
print ("run_test(): X393_cocotb_02(dut) done")
yield Timer(10000)
# print ("run_test(): First timer wait done")
while dut.reset_out.value.get_binstr() != "1":
# print ("Waiting for reset .., reset_out=",dut.reset_out.value)
yield Timer(10000)
while dut.reset_out.value:
# print ("Waiting for reset ..,reset_out=",dut.reset_out.value)
yield Timer(10000)
# print ("Waiting for reset over...,reset_out=",dut.reset_out.value)
# for i in range (10):
# yield RisingEdge(tb.clock)
# print ("10 clocks later: reset_out=",dut.reset_out.value)
# tb.print_test();
# yield tb.axiwr.print_test();
# yield tb.axiwr.print_test();
# yield tb.axiwr.print_test();
yield tb.axiwr.axi_write(address = 0x1234,
value = [0,1,2,3,4,5,6,7,8],
byte_enable=None,
address_latency=0,
data_latency=0,
id=0,
dsize=2,
burst=1)
dut._log.info("Almost there")
yield Timer(1000)
dut._log.info("Ok!")
# raise TestSuccess("All done for now")
"""
MODULE=test_endian_swapper
class EndianSwapperTB(object):
def convert_string(txt):
number=0
for c in txt:
number = (number << 8) + ord(c)
return number
@cocotb.test()
def hello_test(dut):
yield Timer(100)
for i in range (1000):
if i == 200:
dut.TEST_TITLE=convert_string("passed 200")
elif i == 400:
dut.TEST_TITLE=convert_string("passed 400")
dut.maxigp0arvalid=0
yield Timer(10000)
dut.maxigp0arvalid=1
yield Timer(10000)
"""
\ No newline at end of file
......@@ -145,6 +145,12 @@ assign #tDDO1 HACT= ihact;
assign #tDDO1 VACT= ivact;
assign #tDDO1 VACT1= ivact && !ivact1;
assign DCLK= c;
`ifndef ROOTPATH
`include "IVERILOG_INCLUDE.v"// SuppressThisWarning VEditor - maybe not used
`ifndef ROOTPATH
`define ROOTPATH "."
`endif
`endif
initial begin
//parameter ramp = 1; // 0 - ramp, 1 - random
......@@ -161,13 +167,14 @@ initial begin
$display (" -- t_afterHACT = %d ",t_afterHACT);
$display (" -- t_preHACT = %d ",t_preHACT);
$display (" -- new_bayer = %d ",new_bayer);
// reg [15:0] sensor_data[0:4095]; // up to 64 x 64 pixels
if (SENSOR_IMAGE_TYPE == "NORM") $readmemh("input_data/sensor.dat",sensor_data);
else if (SENSOR_IMAGE_TYPE == "RUN1") $readmemh("input_data/sensor_run1.dat",sensor_data);
if (SENSOR_IMAGE_TYPE == "NORM") $readmemh({`ROOTPATH,"/input_data/sensor.dat"},sensor_data);
else if (SENSOR_IMAGE_TYPE == "RUN1") $readmemh({`ROOTPATH,"/input_data/sensor_run1.dat"},sensor_data);
else begin
$display ("WARNING: Unrecognized sensor image :'%s', using default 'NORM': input_data/sensor.dat",SENSOR_IMAGE_TYPE);
$readmemh("input_data/sensor.dat",sensor_data);
$readmemh({`ROOTPATH,"/input_data/sensor.dat"},sensor_data);
end
c=0;
// {ibpf,ihact,ivact}=0;
......
......@@ -83,12 +83,17 @@
`ifdef IVERILOG
`define SIMULATION
`define OPEN_SOURCE_ONLY
`else
`ifdef CVC
`define SIMULATION
`define OPEN_SOURCE_ONLY
`endif // CVC
`endif // IVERILOG
`endif
`ifdef COCOTB
`define SIMULATION
`define OPEN_SOURCE_ONLY
`endif
`ifdef CVC
`define SIMULATION
`define OPEN_SOURCE_ONLY
`endif // CVC
// will not use simultaneous reset in shift registers, just and input data with ~rst
`define SHREG_SEQUENTIAL_RESET 1
......
......@@ -38,6 +38,7 @@
*/
`timescale 1ns/1ps
//`define IVERILOG // uncomment just to chenck syntax (by the editor) in the corresponding branch
`include "system_defines.vh"
module oserdes_mem #(
parameter MODE_DDR="TRUE"
) (
......
[*]
[*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI
[*] Sun Jun 19 16:45:45 2016
[*] Tue Jun 28 14:16:28 2016
[*]
[dumpfile] "/home/elphel/git/x393/simulation/x393_testbench03-20160618120329839.fst"
[dumpfile_mtime] "Sat Jun 18 18:21:41 2016"
[dumpfile_size] 152787343
[savefile] "/home/elphel/git/x393/x393_testbench04.sav"
[timestart] 0
[size] 1736 841
[pos] 0 0
*-24.755907 54300800 209370000 209396667 209423333 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[dumpfile] "/home/andrey/git/x393/simulation/x393_testbench03-20160627204141983.fst"
[dumpfile_mtime] "Tue Jun 28 03:05:44 2016"
[dumpfile_size] 153062065
[savefile] "/home/andrey/git/x393/x393_testbench04.sav"
[timestart] 26395200
[size] 1736 1145
[pos] 1920 38
*-16.746853 26660000 209370000 209396667 209423333 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] x393_testbench03.
[treeopen] x393_testbench03.read_compressor_frame_irq.
[treeopen] x393_testbench03.read_contol_register_irq.
......@@ -48,26 +48,34 @@
[treeopen] x393_testbench03.x393_i.compressor393_i.genblk3.cmprs_afi0_mux_i.cmprs_afi_mux_status_i.status_generate1_i.genblk2.status_generate_only_i.
[treeopen] x393_testbench03.x393_i.frame_sequencer_block[0].cmd_frame_sequencer_i.
[treeopen] x393_testbench03.x393_i.mcntrl393_i.sens_comp_block[0].
[treeopen] x393_testbench03.x393_i.sensors393_i.
[treeopen] x393_testbench03.x393_i.sensors393_i.sensor_channel_block[0].
[treeopen] x393_testbench03.x393_i.sensors393_i.sensor_channel_block[0].sensor_channel_i.sensor_i2c_io_i.
[treeopen] x393_testbench03.x393_i.sensors393_i.sensor_channel_block[0].sensor_channel_i.sensor_i2c_io_i.sensor_i2c_i.
[treeopen] x393_testbench03.x393_i.sensors393_i.sensor_channel_block[1].
[treeopen] x393_testbench03.x393_i.sensors393_i.sensor_channel_block[1].sensor_channel_i.
[treeopen] x393_testbench03.x393_i.sensors393_i.sensor_channel_block[1].sensor_channel_i.sensor_i2c_io_i.
[treeopen] x393_testbench03.x393_i.sensors393_i.sensor_channel_block[1].sensor_channel_i.sensor_i2c_io_i.sensor_i2c_i.
[treeopen] x393_testbench03.x393_i.sensors393_i.sensor_channel_block[2].
[treeopen] x393_testbench03.x393_i.sensors393_i.sensor_channel_block[2].sensor_channel_i.
[treeopen] x393_testbench03.x393_i.sensors393_i.sensor_channel_block[2].sensor_channel_i.sensor_i2c_io_i.
[treeopen] x393_testbench03.x393_i.sensors393_i.sensor_channel_block[3].
[treeopen] x393_testbench03.x393_i.sensors393_i.sensor_channel_block[3].sensor_channel_i.
[treeopen] x393_testbench03.x393_i.sensors393_i.sensor_channel_block[3].sensor_channel_i.sensor_i2c_io_i.
[sst_width] 395
[signals_width] 334
[sst_expanded] 1
[sst_vpaned_height] 249
[sst_vpaned_height] 356
@820
x393_testbench03.TEST_TITLE[639:0]
@28
x393_testbench03.CLK
x393_testbench03.x393_i.axi_aclk
x393_testbench03.x393_i.ps7_i.MAXIGP0ARESETN
x393_testbench03.x393_i.ps7_i.MAXIGP0ARLOCK[1:0]
@22
x393_testbench03.x393_i.ps7_i.MAXIGP0ARQOS[3:0]
@28
x393_testbench03.AR_SET_CMD
x393_testbench03.AR_READY
@29
x393_testbench03.ARSIZE_IN_r[1:0]
@200
-
@800200
......@@ -84,7 +92,6 @@ x393_testbench03.x393_i.sensors393_i.sensor_channel_block[2].sensor_channel_i.px
@28
x393_testbench03.x393_i.sensors393_i.sensor_channel_block[2].sensor_channel_i.sof
x393_testbench03.x393_i.sensors393_i.sensor_channel_block[2].sensor_channel_i.eof
@29
x393_testbench03.x393_i.sensors393_i.sensor_channel_block[2].sensor_channel_i.hact
@1000200
-chn1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment