/******************************************************************************* * Module: x393_testbench02 * Date:2015-02-06 * Author: Andrey Filippov * Description: testbench for the initial x393.v simulation * * Copyright (c) 2015 Elphel, Inc. * x393_testbench02.v 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. * * x393_testbench02.tf 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 . *******************************************************************************/ `timescale 1ns/1ps `include "system_defines.vh" //`define use200Mhz 1 //`define DEBUG_FIFO 1 `undef WAIT_MRS `define SET_PER_PIN_DELAYS 1 // set individual (including per-DQ pin delays) `define READBACK_DELAYS 1 `define PS_PIO_WAIT_COMPLETE 0 // wait until PS PIO module finished transaction before starting a new one // Disabled already passed test to speedup simulation //`define TEST_WRITE_LEVELLING 1 //`define TEST_READ_PATTERN 1 //`define TEST_WRITE_BLOCK 1 //`define TEST_READ_BLOCK 1 //`define TEST_SCANLINE_WRITE `define TEST_SCANLINE_WRITE_WAIT 1 // wait TEST_SCANLINE_WRITE finished (frame_done) //`define TEST_SCANLINE_READ `define TEST_READ_SHOW 1 //`define TEST_TILED_WRITE 1 `define TEST_TILED_WRITE_WAIT 1 // wait TEST_SCANLINE_WRITE finished (frame_done) //`define TEST_TILED_READ 1 //`define TEST_TILED_WRITE32 1 //`define TEST_TILED_READ32 1 `define TEST_AFI_WRITE 1 `define TEST_AFI_READ 1 module x393_testbench02 #( `include "includes/x393_parameters.vh" // SuppressThisWarning VEditor - not used `include "includes/x393_simulation_parameters.vh" )( ); `ifdef IVERILOG // $display("IVERILOG is defined"); `ifdef NON_VDT_ENVIROMENT parameter lxtname="x393.lxt"; `else `include "IVERILOG_INCLUDE.v" `endif // NON_VDT_ENVIROMENT `else // IVERILOG // $display("IVERILOG is not defined"); `ifdef CVC `ifdef NON_VDT_ENVIROMENT parameter lxtname = "x393.fst"; `else // NON_VDT_ENVIROMENT `include "IVERILOG_INCLUDE.v" `endif // NON_VDT_ENVIROMENT `else parameter lxtname = "x393.lxt"; `endif // CVC `endif // IVERILOG `define DEBUG_WR_SINGLE 1 `define DEBUG_RD_DATA 1 //`include "includes/x393_cur_params_sim.vh" // parameters that may need adjustment, should be before x393_localparams.vh `include "includes/x393_cur_params_target.vh" // SuppressThisWarning VEditor - not used parameters that may need adjustment, should be before x393_localparams.vh `include "includes/x393_localparams.vh" // SuppressThisWarning VEditor - not used // ========================== parameters from x353 =================================== `ifdef SYNC_COMPRESS parameter DEPEND=1'b1; `else parameter DEPEND=1'b0; `endif `ifdef TEST_ABORT `endif parameter SYNC_BIT_LENGTH=8-1; /// 7 pixel clock pulses parameter FPGA_XTRA_CYCLES= 1500; // 1072+; // moved to x393_simulation_parameters.vh // parameter HISTOGRAM_LEFT= 0; //2; // left // parameter HISTOGRAM_TOP = 2; // top // parameter HISTOGRAM_WIDTH= 6; // width // parameter HISTOGRAM_HEIGHT=6; // height parameter CLK0_PER = 6.25; //160MHz parameter CLK1_PER = 10.4; //96MHz parameter CLK3_PER = 83.33; //12MHz parameter CPU_PER=10.4; parameter HBLANK= 12; /// 52; parameter WOI_HEIGHT= 32; parameter BLANK_ROWS_BEFORE= 1; //8; ///2+2 - a little faster than compressor parameter BLANK_ROWS_AFTER= 1; //8; parameter TRIG_LINES= 8; parameter VBLANK= 2; /// 2 lines //SuppressThisWarning Veditor UNUSED parameter CYCLES_PER_PIXEL= 3; /// 2 for JP4, 3 for JPEG `ifdef PF parameter PF_HEIGHT=8; parameter FULL_HEIGHT=WOI_HEIGHT; parameter PF_STRIPES=WOI_HEIGHT/PF_HEIGHT; `else parameter PF_HEIGHT=0; parameter FULL_HEIGHT=WOI_HEIGHT+4; parameter PF_STRIPES=0; `endif parameter VIRTUAL_WIDTH= FULL_WIDTH + HBLANK; parameter VIRTUAL_HEIGHT= FULL_HEIGHT + BLANK_ROWS_BEFORE + BLANK_ROWS_AFTER; //SuppressThisWarning Veditor UNUSED parameter TRIG_INTERFRAME= 100; /// extra 100 clock cycles between frames //SuppressThisWarning Veditor UNUSED /// parameter TRIG_OUT_DATA= 'h80000; // internal cable /// parameter TRIG_EXTERNAL_INPUT= 'h20000; // internal cable, low level on EXT[8] parameter TRIG_DELAY= 200; /// delay in sensor clock cycles parameter FULL_WIDTH= WOI_WIDTH+4; // ========================== end of parameters from x353 =================================== // Sensor signals - as on sensor pads wire PX1_MCLK; // input sensor input clock wire PX1_MRST; // input wire PX1_ARO; // input wire PX1_ARST; // input wire PX1_OFST = 1'b1; // input // I2C address ofset by 2: for simulation 0 - still mode, 1 - video mode. wire [11:0] PX1_D; // output[11:0] wire PX1_DCLK; // output sensor output clock (connect to sensor BPF output ) wire PX1_HACT; // output wire PX1_VACT; // output // Sensor signals - as on FPGA pads wire [ 7:0] sns1_dp; // inout[7:0] {PX_MRST, PXD8, PXD6, PXD4, PXD2, PXD0, PX_HACT, PX_DCLK} wire [ 7:0] sns1_dn; // inout[7:0] {PX_ARST, PXD9, PXD7, PXD5, PXD3, PXD1, PX_VACT, PX_BPF} wire sns1_clkp; // inout CNVCLK/TDO wire sns1_clkn; // inout CNVSYNC/TDI wire sns1_scl; // inout PX_SCL wire sns1_sda; // inout PX_SDA wire sns1_ctl; // inout PX_ARO/TCK wire sns1_pg; // inout SENSPGM //connect sensor to sensor port 1 assign sns1_dp[6:1] = {PX1_D[10], PX1_D[8], PX1_D[6], PX1_D[4], PX1_D[2], PX1_HACT}; assign PX1_MRST = sns1_dp[7]; // from FPGA to sensor assign PX1_MCLK = sns1_dp[0]; // from FPGA to sensor assign sns1_dn[6:0] = {PX1_D[11], PX1_D[9], PX1_D[7], PX1_D[5], PX1_D[3], PX1_VACT, PX1_DCLK}; assign PX1_ARST = sns1_dn[7]; assign sns1_clkn = PX1_D[0]; // inout CNVSYNC/TDI assign sns1_scl = PX1_D[1]; // inout PX_SCL assign PX1_ARO = sns1_ctl; // from FPGA to sensor wire [ 7:0] sns2_dp; // inout[7:0] {PX_MRST, PXD8, PXD6, PXD4, PXD2, PXD0, PX_HACT, PX_DCLK} wire [ 7:0] sns2_dn; // inout[7:0] {PX_ARST, PXD9, PXD7, PXD5, PXD3, PXD1, PX_VACT, PX_BPF} wire sns2_clkp; // inout CNVCLK/TDO wire sns2_clkn; // inout CNVSYNC/TDI wire sns2_scl; // inout PX_SCL wire sns2_sda; // inout PX_SDA wire sns2_ctl; // inout PX_ARO/TCK wire sns2_pg; // inout SENSPGM wire [ 7:0] sns3_dp; // inout[7:0] {PX_MRST, PXD8, PXD6, PXD4, PXD2, PXD0, PX_HACT, PX_DCLK} wire [ 7:0] sns3_dn; // inout[7:0] {PX_ARST, PXD9, PXD7, PXD5, PXD3, PXD1, PX_VACT, PX_BPF} wire sns3_clkp; // inout CNVCLK/TDO wire sns3_clkn; // inout CNVSYNC/TDI wire sns3_scl; // inout PX_SCL wire sns3_sda; // inout PX_SDA wire sns3_ctl; // inout PX_ARO/TCK wire sns3_pg; // inout SENSPGM wire [ 7:0] sns4_dp; // inout[7:0] {PX_MRST, PXD8, PXD6, PXD4, PXD2, PXD0, PX_HACT, PX_DCLK} wire [ 7:0] sns4_dn; // inout[7:0] {PX_ARST, PXD9, PXD7, PXD5, PXD3, PXD1, PX_VACT, PX_BPF} wire sns4_clkp; // inout CNVCLK/TDO wire sns4_clkn; // inout CNVSYNC/TDI wire sns4_scl; // inout PX_SCL wire sns4_sda; // inout PX_SDA wire sns4_ctl; // inout PX_ARO/TCK wire sns4_pg; // inout SENSPGM wire [ 9:0] gpio_pins; // inout[9:0] ([6]-synco0,[7]-syncio0,[8]-synco1,[9]-syncio1) // Connect trigger outs to triggets in (#10 needed for Icarus) assign #10 gpio_pins[7] = gpio_pins[6]; assign #10 gpio_pins[9] = gpio_pins[8]; // DDR3 signals wire SDRST; wire SDCLK; // output wire SDNCLK; // output wire [ADDRESS_NUMBER-1:0] SDA; // output[14:0] wire [ 2:0] SDBA; // output[2:0] wire SDWE; // output wire SDRAS; // output wire SDCAS; // output wire SDCKE; // output wire SDODT; // output wire [15:0] SDD; // inout[15:0] wire SDDML; // inout wire DQSL; // inout wire NDQSL; // inout wire SDDMU; // inout wire DQSU; // inout wire NDQSU; // inout wire DUMMY_TO_KEEP; // output to keep PS7 signals from "optimization" // SuppressThisWarning all - not used wire memclk; wire ffclk0p; // input wire ffclk0n; // input wire ffclk1p; // input wire ffclk1n; // input // axi_hp simulation signals wire HCLK; wire [31:0] afi_sim_rd_address; // output[31:0] wire [ 5:0] afi_sim_rid; // output[5:0] SuppressThisWarning VEditor - not used - just view // reg afi_sim_rd_valid; // input wire afi_sim_rd_valid; // input wire afi_sim_rd_ready; // output // reg [63:0] afi_sim_rd_data; // input[63:0] wire [63:0] afi_sim_rd_data; // input[63:0] wire [ 2:0] afi_sim_rd_cap; // output[2:0] SuppressThisWarning VEditor - not used - just view wire [ 3:0] afi_sim_rd_qos; // output[3:0] SuppressThisWarning VEditor - not used - just view wire [ 1:0] afi_sim_rd_resp; // input[1:0] // reg [ 1:0] afi_sim_rd_resp; // input[1:0] wire [31:0] afi_sim_wr_address; // output[31:0] SuppressThisWarning VEditor - not used - just view wire [ 5:0] afi_sim_wid; // output[5:0] SuppressThisWarning VEditor - not used - just view wire afi_sim_wr_valid; // output wire afi_sim_wr_ready; // input // reg afi_sim_wr_ready; // input wire [63:0] afi_sim_wr_data; // output[63:0] SuppressThisWarning VEditor - not used - just view wire [ 7:0] afi_sim_wr_stb; // output[7:0] SuppressThisWarning VEditor - not used - just view wire [ 3:0] afi_sim_bresp_latency; // input[3:0] // reg [ 3:0] afi_sim_bresp_latency; // input[3:0] wire [ 2:0] afi_sim_wr_cap; // output[2:0] SuppressThisWarning VEditor - not used - just view wire [ 3:0] afi_sim_wr_qos; // output[3:0] SuppressThisWarning VEditor - not used - just view assign HCLK = x393_i.ps7_i.SAXIHP0ACLK; // shortcut name // afi loopback assign #1 afi_sim_rd_data= afi_sim_rd_ready?{2'h0,afi_sim_rd_address[31:3],1'h1, 2'h0,afi_sim_rd_address[31:3],1'h0}:64'bx; assign #1 afi_sim_rd_valid = afi_sim_rd_ready; assign #1 afi_sim_rd_resp = afi_sim_rd_ready?2'b0:2'bx; assign #1 afi_sim_wr_ready = afi_sim_wr_valid; assign #1 afi_sim_bresp_latency=4'h5; // SAXI_GP0 - histograms to system memory wire SAXI_GP0_CLK; wire [31:0] saxi_gp0_sim_wr_address; // output[31:0] SuppressThisWarning VEditor - not used - just view wire [ 5:0] saxi_gp0_sim_wid; // output[5:0] SuppressThisWarning VEditor - not used - just view wire saxi_gp0_sim_wr_valid; // output wire saxi_gp0_sim_wr_ready; // input wire [31:0] saxi_gp0_sim_wr_data; // output[31:0] SuppressThisWarning VEditor - not used - just view wire [ 3:0] saxi_gp0_sim_wr_stb; // output[3:0] SuppressThisWarning VEditor - not used - just view wire [ 1:0] saxi_gp0_sim_wr_size; // output[1:0] SuppressThisWarning VEditor - not used - just view wire [ 3:0] saxi_gp0_sim_bresp_latency; // input[3:0] wire [ 3:0] saxi_gp0_sim_wr_qos; // output[3:0] SuppressThisWarning VEditor - not used - just view assign SAXI_GP0_CLK = x393_i.ps7_i.SAXIGP0ACLK; assign #1 saxi_gp0_sim_wr_ready = saxi_gp0_sim_wr_valid; assign #1 saxi_gp0_sim_bresp_latency=4'h5; // axi_hp register access // PS memory mapped registers to read/write over a separate simulation bus running at HCLK, no waits reg [31:0] PS_REG_ADDR; reg PS_REG_WR; reg PS_REG_RD; reg [31:0] PS_REG_DIN; wire [31:0] PS_REG_DOUT; reg [31:0] PS_RDATA; // SuppressThisWarning VEditor - not used - just view /* reg [31:0] afi_reg_addr; reg afi_reg_wr; reg afi_reg_rd; reg [31:0] afi_reg_din; wire [31:0] afi_reg_dout; reg [31:0] AFI_REG_RD; // SuppressThisWarning VEditor - not used - just view */ initial begin PS_REG_ADDR <= 'bx; PS_REG_WR <= 0; PS_REG_RD <= 0; PS_REG_DIN <= 'bx; PS_RDATA <= 'bx; end always @ (posedge HCLK) if (PS_REG_RD) PS_RDATA <= PS_REG_DOUT; reg [639:0] TEST_TITLE; // Simulation signals reg [11:0] ARID_IN_r; reg [31:0] ARADDR_IN_r; reg [3:0] ARLEN_IN_r; reg [2:0] ARSIZE_IN_r; reg [1:0] ARBURST_IN_r; reg [11:0] AWID_IN_r; reg [31:0] AWADDR_IN_r; reg [3:0] AWLEN_IN_r; reg [2:0] AWSIZE_IN_r; reg [1:0] AWBURST_IN_r; reg [11:0] WID_IN_r; reg [31:0] WDATA_IN_r; reg [ 3:0] WSTRB_IN_r; reg WLAST_IN_r; 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); //SuppressThisWarning 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 wire CLK; reg RST; reg AR_SET_CMD_r; wire AR_READY; reg AW_SET_CMD_r; wire AW_READY; reg W_SET_CMD_r; wire W_READY; wire [11:0] #(AXI_TASK_HOLD) ARID_IN = ARID_IN_r; wire [31:0] #(AXI_TASK_HOLD) ARADDR_IN = ARADDR_IN_r; wire [3:0] #(AXI_TASK_HOLD) ARLEN_IN = ARLEN_IN_r; wire [2:0] #(AXI_TASK_HOLD) ARSIZE_IN = ARSIZE_IN_r; wire [1:0] #(AXI_TASK_HOLD) ARBURST_IN = ARBURST_IN_r; wire [11:0] #(AXI_TASK_HOLD) AWID_IN = AWID_IN_r; wire [31:0] #(AXI_TASK_HOLD) AWADDR_IN = AWADDR_IN_r; wire [3:0] #(AXI_TASK_HOLD) AWLEN_IN = AWLEN_IN_r; wire [2:0] #(AXI_TASK_HOLD) AWSIZE_IN = AWSIZE_IN_r; wire [1:0] #(AXI_TASK_HOLD) AWBURST_IN = AWBURST_IN_r; wire [11:0] #(AXI_TASK_HOLD) WID_IN = WID_IN_r; wire [31:0] #(AXI_TASK_HOLD) WDATA_IN = WDATA_IN_r; wire [ 3:0] #(AXI_TASK_HOLD) WSTRB_IN = WSTRB_IN_r; wire #(AXI_TASK_HOLD) WLAST_IN = WLAST_IN_r; wire #(AXI_TASK_HOLD) AR_SET_CMD = AR_SET_CMD_r; wire #(AXI_TASK_HOLD) AW_SET_CMD = AW_SET_CMD_r; wire #(AXI_TASK_HOLD) W_SET_CMD = W_SET_CMD_r; reg [3:0] RD_LAG; // ready signal lag in axi read channel (0 - RDY=1, 1..15 - RDY is asserted N cycles after valid) reg [3:0] B_LAG; // ready signal lag in axi arete response channel (0 - RDY=1, 1..15 - RDY is asserted N cycles after valid) // Simulation modules interconnection wire [11:0] arid; wire [31:0] araddr; wire [3:0] arlen; wire [2:0] arsize; wire [1:0] arburst; // SuppressWarnings VEditor : assigned in $readmem(14) system task wire [3:0] arcache; // SuppressWarnings VEditor : assigned in $readmem() system task wire [2:0] arprot; wire arvalid; wire arready; wire [11:0] awid; wire [31:0] awaddr; wire [3:0] awlen; wire [2:0] awsize; wire [1:0] awburst; // SuppressWarnings VEditor : assigned in $readmem() system task wire [3:0] awcache; // SuppressWarnings VEditor : assigned in $readmem() system task wire [2:0] awprot; wire awvalid; wire awready; wire [11:0] wid; wire [31:0] wdata; wire [3:0] wstrb; wire wlast; wire wvalid; wire wready; wire [31:0] rdata; // SuppressWarnings VEditor : assigned in $readmem() system task wire [11:0] rid; wire rlast; // SuppressWarnings VEditor : assigned in $readmem() system task wire [1:0] rresp; wire rvalid; wire rready; wire rstb=rvalid && rready; // SuppressWarnings VEditor : assigned in $readmem() system task wire [1:0] bresp; // SuppressWarnings VEditor : assigned in $readmem() system task wire [11:0] bid; wire bvalid; wire bready; integer NUM_WORDS_READ; integer NUM_WORDS_EXPECTED; reg [15:0] ENABLED_CHANNELS = 0; // currently enabled memory channels // integer SCANLINE_CUR_X; // integer SCANLINE_CUR_Y; wire AXI_RD_EMPTY=NUM_WORDS_READ==NUM_WORDS_EXPECTED; //SuppressThisWarning VEditor : may be unused, just for simulation //NUM_XFER_BITS=6 // localparam SCANLINE_PAGES_PER_ROW= (WINDOW_WIDTH>>NUM_XFER_BITS)+((WINDOW_WIDTH[NUM_XFER_BITS-1:0]==0)?0:1); // localparam TILES_PER_ROW= (WINDOW_WIDTH/TILE_WIDTH)+ ((WINDOW_WIDTH % TILE_WIDTH==0)?0:1); // localparam TILE_ROWS_PER_WINDOW= ((WINDOW_HEIGHT-1)/TILE_VSTEP) + 1; // localparam TILE_SIZE= TILE_WIDTH*TILE_HEIGHT; // localparam integer SCANLINE_FULL_XFER= 1<0 - generate HACT from start to specified width setup_sensor_memory ( 0, // input [1:0] num_sensor; FRAME_START_ADDRESS, // input [31:0] frame_sa; // 22-bit frame start address ((3 CA LSBs==0. BA==0) FRAME_START_ADDRESS_INC, // input [31:0] frame_sa_inc; // 22-bit frame start address increment ((3 CA LSBs==0. BA==0) last_buf_frame, // input [31:0] last_frame_num; // 16-bit number of the last frame in a buffer frame_full_width, // input [31:0] frame_full_width; // 13-bit Padded line length (8-row increment), in 8-bursts (16 bytes) window_width, // input [31:0] window_width; // 13 bit - in 8*16=128 bit bursts window_height, // input [31:0] window_height; // 16 bit window_left, // input [31:0] window_left; window_top); // input [31:0] window_top; // Run after histogram channel is set up? set_sensor_mode ( 0, // input [1:0] num_sensor; 4'h1, // input [3:0] hist_en; // [0..3] 1 - enable histogram modules, disable after processing the started frame 4'h1, // input [3:0] hist_nrst; // [4..7] 0 - immediately reset histogram module 1'b1, // input chn_en; // [8] 1 - enable sensor channel (0 - reset) 1'b0); // input bits16; // [9] 0 - 8 bpp mode, 1 - 16 bpp (bypass gamma). Gamma-processed data is still used for histograms // test i2c - manual and sequencer (same data as in 353 test fixture set_sensor_gamma_ctl (// doing last to enable sesnor data when everything else is set up 0, // input [1:0] num_sensor; // sensor channel number (0..3) 2'h3, // input [1:0] bayer; // bayer shift (0..3) 0, // input table_page; // table page (only used if SENS_GAMMA_BUFFER) 1'b1, // input en_input; // enable channel input 1'b1, // input repet_mode; // Normal mode, single trigger - just for debugging 1'b0); // input trig; // pass next frame end endtask task setup_sensor_memory; input [1:0] num_sensor; input [31:0]frame_sa; // 22-bit frame start address ((3 CA LSBs==0. BA==0) input [31:0] frame_sa_inc; // 22-bit frame start address increment ((3 CA LSBs==0. BA==0) input [31:0] last_frame_num; // 16-bit number of the last frame in a buffer input [31:0] frame_full_width; // 13-bit Padded line length (8-row increment), in 8-bursts (16 bytes) input [31:0] window_width; // 13 bit - in 8*16=128 bit bursts input [31:0] window_height; // 16 bit input [31:0] window_left; input [31:0] window_top; /* input [NUM_RC_BURST_BITS-1:0] frame_sa; // 22-bit frame start address ((3 CA LSBs==0. BA==0) input [NUM_RC_BURST_BITS-1:0] frame_sa_inc; // 22-bit frame start address increment ((3 CA LSBs==0. BA==0) input [LAST_FRAME_BITS-1:0] last_frame_num; // 16-bit number of the last frame in a buffer input [FRAME_WIDTH_BITS-1:0] frame_full_width; // 13-bit Padded line length (8-row increment), in 8-bursts (16 bytes) input [FRAME_WIDTH_BITS-1:0] window_width; // 13 bit - in 8*16=128 bit bursts input [FRAME_HEIGHT_BITS-1:0] window_height; // 16 bit input [FRAME_WIDTH_BITS-1:0] window_left; input [FRAME_HEIGHT_BITS-1:0] window_top; */ reg [29:0] base_addr; integer mode; begin base_addr = MCONTR_SENS_BASE + MCONTR_SENS_INC * num_sensor; mode= func_encode_mode_scanline( 1, // repetitive, 0, // single, 0, // reset_frame, 0, // extra_pages, 1, // write_mem, 1, // enable 0); // chn_reset write_contol_register(base_addr + MCNTRL_SCANLINE_STARTADDR, frame_sa); // RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0) write_contol_register(base_addr + MCNTRL_SCANLINE_FRAME_SIZE, frame_sa_inc); write_contol_register(base_addr + MCNTRL_SCANLINE_FRAME_LAST, last_frame_num); write_contol_register(base_addr + MCNTRL_SCANLINE_FRAME_FULL_WIDTH, frame_full_width); write_contol_register(base_addr + MCNTRL_SCANLINE_WINDOW_WH, {window_height[15:0],window_width[15:0]}); //WINDOW_WIDTH + (WINDOW_HEIGHT<<16)); write_contol_register(base_addr + MCNTRL_SCANLINE_WINDOW_X0Y0, {window_top[15:0],window_left[15:0]}); //WINDOW_X0+ (WINDOW_Y0<<16)); write_contol_register(base_addr + MCNTRL_SCANLINE_WINDOW_STARTXY, 32'b0); write_contol_register(base_addr + MCNTRL_SCANLINE_MODE, mode); end endtask task test_i2c_353; begin set_sensor_i2c_command( 2'b0, // input [1:0] num_sensor; 1'b1, // input rst_cmd; // [14] reset all FIFO (takes 16 clock pulses), also - stops i2c until run command 2'b0, // input [SENSI2C_CMD_RUN_PBITS : 0] run_cmd; // [13:12]3 - run i2c, 2 - stop i2c (needed before software i2c), 1,0 - no change to run state 1'b1, // input set_bytes; // [11] if 1, use bytes (below), 0 - nop 2'h3, // input [SENSI2C_CMD_BYTES_PBITS -1 : 0] bytes; // [10:9] set command bytes to send after slave address (0..3) 1'b1, // input set_dly; // [8] if 1, use dly (0 - ignore) 8'h0a, // input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quater i2c cycle (if 0, [3:0] control SCL+SDA) 2'b0, // input [SENSI2C_CMD_SCL_WIDTH -1 : 0] scl_ctl; // [1:0] : 0: NOP, 1: 1'b0->SCL, 2: 1'b1->SCL, 3: 1'bz -> SCL 2'b0); // input [SENSI2C_CMD_SDA_WIDTH -1 : 0] sda_ctl; // [3:2] : 0: NOP, 1: 1'b0->SDA, 2: 1'b1->SDA, 3: 1'bz -> SDA repeat (10) @ (posedge CLK); // wait for initialization to be done TODO: use status set_sensor_i2c_command (0, 0, 3, 0, 0, 0, 0, 0, 0); // run i2c - reset software bits set_sensor_i2c_command (0, 0, 2, 0, 0, 0, 0, 0, 0); // stop i2c, enable software control set_sensor_i2c_command (0, 0, 0, 0, 0, 0, 0, 0, 2); // SDA = 1 set_sensor_i2c_command (0, 0, 0, 0, 0, 0, 0, 0, 1); // SDA = 0 set_sensor_i2c_command (0, 0, 0, 0, 0, 0, 0, 2, 0); // SCL = 1 set_sensor_i2c_command (0, 0, 0, 0, 0, 0, 0, 1, 0); // SCL = 0 set_sensor_i2c_command (0, 0, 0, 0, 0, 0, 0, 0, 2); // SDA = 1 set_sensor_i2c_command (0, 0, 0, 0, 0, 0, 0, 2, 0); // SCL = 1 set_sensor_i2c_command (0, 0, 0, 0, 0, 0, 0, 0, 3); // SDA = 'bz set_sensor_i2c_command (0, 0, 0, 0, 0, 0, 0, 3, 0); // SCL = 'bz set_sensor_i2c_command (0, 0, 3, 0, 0, 0, 0, 0, 0); // run i2c write_sensor_i2c ( 0, // input [1:0] num_sensor; 0, // input rel_addr; // 0 - absolute, 1 - relative 1, // input integer addr; 'h90040793); // input [31:0] data; write_sensor_i2c (0, 0, 1,'h90050a23); write_sensor_i2c (0, 0, 2,'h90080001); write_sensor_i2c (0, 0, 3,'h90090123); write_sensor_i2c (0, 1, 2,'h90091234); write_sensor_i2c (0, 0, 4,'h9004001f); write_sensor_i2c (0, 0, 4,'h9005002f); write_sensor_i2c (0, 1, 3,'h90020013); write_sensor_i2c (0, 1, 3,'h90030017); end endtask task program_status_sensor_i2c; input [1:0] num_sensor; input [1:0] mode; input [5:0] seq_num; begin program_status (SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC + SENSI2C_CTRL_RADDR, SENSI2C_STATUS, mode, seq_num); end endtask task program_status_sensor_io; input [1:0] num_sensor; input [1:0] mode; input [5:0] seq_num; begin program_status (SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC + SENSIO_RADDR, SENSI2C_STATUS, mode, seq_num); end endtask task set_sensor_mode; input [1:0] num_sensor; input [3:0] hist_en; // [0..3] 1 - enable histogram modules, disable after processing the started frame input [3:0] hist_nrst; // [4..7] 0 - immediately reset histogram module input chn_en; // [8] 1 - enable sensor channel (0 - reset) input bits16; // [9] 0 - 8 bpp mode, 1 - 16 bpp (bypass gamma). Gamma-processed data is still used for histograms reg [31:0] tmp; begin tmp= {{(32-SENSOR_MODE_WIDTH){1'b0}},func_sensor_mode(hist_en, hist_nrst, chn_en,bits16)}; write_contol_register( SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC +SENSOR_CTRL_RADDR, tmp); end endtask task set_sensor_i2c_command; input [1:0] num_sensor; input rst_cmd; // [14] reset all FIFO (takes 16 clock pulses), also - stops i2c until run command input [SENSI2C_CMD_RUN_PBITS : 0] run_cmd; // [13:12]3 - run i2c, 2 - stop i2c (needed before software i2c), 1,0 - no change to run state input set_bytes; // [11] if 1, use bytes (below), 0 - nop input [SENSI2C_CMD_BYTES_PBITS -1 : 0] bytes; // [10:9] set command bytes to send after slave address (0..3) input set_dly; // [8] if 1, use dly (0 - ignore) input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quater i2c cycle (if 0, [3:0] control SCL+SDA) input [SENSI2C_CMD_SCL_WIDTH -1 : 0] scl_ctl; // [1:0] : 0: NOP, 1: 1'b0->SCL, 2: 1'b1->SCL, 3: 1'bz -> SCL input [SENSI2C_CMD_SDA_WIDTH -1 : 0] sda_ctl; // [3:2] : 0: NOP, 1: 1'b0->SDA, 2: 1'b1->SDA, 3: 1'bz -> SDA reg [31:0] tmp; begin tmp= {func_sensor_i2c_command(rst_cmd, run_cmd, set_bytes, bytes, set_dly, dly, scl_ctl, sda_ctl)}; write_contol_register( SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC +SENSI2C_CTRL_RADDR, tmp); end endtask task write_sensor_i2c; input [1:0] num_sensor; input rel_addr; // 0 - absolute, 1 - relative input integer addr; input [31:0] data; reg [29:0] reg_addr; begin reg_addr = (SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC) + (rel_addr ? SENSI2C_REL_RADDR : SENSI2C_ABS_RADDR) + (addr & ~SENSI2C_ADDR_MASK); write_contol_register(reg_addr, data); end endtask task set_sensor_io_ctl; input [1:0] num_sensor; input [1:0] mrst; // <2: keep MRST, 2 - MRST low (active), 3 - high (inactive) input [1:0] arst; // <2: keep ARST, 2 - ARST low (active), 3 - high (inactive) input [1:0] aro; // <2: keep ARO, 2 - set ARO (software controlled) low, 3 - set ARO (software controlled) high input [1:0] mmcm_rst; // <2: keep MMCM reset, 2 - MMCM reset off, 3 - MMCM reset on input [1:0] clk_sel; // <2: keep MMCM clock source, 2 - use internal pixel clock, 3 - use pixel clock from the sensor input set_delays; // (self-clearing) load all pre-programmed delays input set_quadrants; // 0 - keep quadrants settings, 1 - update quadrants input [SENS_CTRL_QUADRANTS_WIDTH-1:0] quadrants; // 90-degree shifts for data [1:0], hact [3:2] and vact [5:4] reg [31:0] data; reg [29:0] reg_addr; begin data = func_sensor_io_ctl ( mrst, arst, aro, mmcm_rst, clk_sel, set_delays, set_quadrants, quadrants); reg_addr = (SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC) + SENSIO_RADDR + SENSIO_CTRL; write_contol_register(reg_addr, data); end endtask task set_sensor_io_dly; input [1:0] num_sensor; input [127:0] dly; // {mmsm_phase, bpf, vact, hact, pxd11,...,pxd0] reg [29:0] reg_addr; begin reg_addr = (SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC) + SENSIO_RADDR + SENSIO_DELAYS; write_contol_register(reg_addr + 0, dly[ 31: 0]); // {pxd3, pxd2, pxd1, pxd0} write_contol_register(reg_addr + 1, dly[ 63:32]); // {pxd7, pxd6, pxd5, pxd4} write_contol_register(reg_addr + 2, dly[ 95:64]); // {pxd11, pxd10, pxd9, pxd8} write_contol_register(reg_addr + 3, dly[127:96]); // {mmcm_phase, bpf, vact, hact} set_sensor_io_ctl( num_sensor, 0, // input [1:0] mrst; // <2: keep MRST, 2 - MRST low (active), 3 - high (inactive) 0, // input [1:0] arst; // <2: keep ARST, 2 - ARST low (active), 3 - high (inactive) 0, // input [1:0] aro; // <2: keep ARO, 2 - set ARO (software controlled) low, 3 - set ARO (software controlled) high 0, // input [1:0] mmcm_rst; // <2: keep MMCM reset, 2 - MMCM reset off, 3 - MMCM reset on 0, // input [1:0] clk_sel; // <2: keep MMCM clock source, 2 - use internal pixel clock, 3 - use pixel clock from the sensor 1'b1, //input set_delays; // (self-clearing) load all pre-programmed delays 0, // input set_quadrants; // 0 - keep quadrants settings, 1 - update quadrants 0); // input [SENS_CTRL_QUADRANTS_WIDTH-1:0] quadrants; // 90-degree shifts for data [1:0], hact [3:2] and vact [5:4] end endtask task set_sensor_io_jtag; // SuppressThisWarning VEditor - may be unused input [1:0] num_sensor; input [1:0] pgmen; // <2: keep PGMEN, 2 - PGMEN low (inactive), 3 - high (active) enable JTAG control input [1:0] prog; // <2: keep prog, 2 - prog low (active), 3 - high (inactive) ("program" pin control) input [1:0] tck; // <2: keep TCK, 2 - set TCK low, 3 - set TCK high input [1:0] tms; // <2: keep TMS, 2 - set TMS low, 3 - set TMS high input [1:0] tdi; // <2: keep TDI, 2 - set TDI low, 3 - set TDI high reg [29:0] reg_addr; reg [31:0] data; begin reg_addr = (SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC) + SENSIO_RADDR + SENSIO_JTAG; data = func_sensor_jtag_ctl ( pgmen, // <2: keep PGMEN, 2 - PGMEN low (inactive), 3 - high (active) enable JTAG control prog, // <2: keep prog, 2 - prog low (active), 3 - high (inactive) ("program" pin control) tck, // <2: keep TCK, 2 - set TCK low, 3 - set TCK high tms, // <2: keep TMS, 2 - set TMS low, 3 - set TMS high tdi); // <2: keep TDI, 2 - set TDI low, 3 - set TDI high write_contol_register(reg_addr, data); end endtask task set_sensor_io_width; input [1:0] num_sensor; input [15:0] width; // 0 - use HACT, >0 - generate HACT from start to specified width reg [29:0] reg_addr; begin reg_addr = (SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC) + SENSIO_RADDR + SENSIO_WIDTH; write_contol_register(reg_addr, {16'b0, width}); end endtask task program_curves; input [1:0] num_sensor; input [1:0] sub_channel; reg [9:0] curves_data[0:1027]; // SuppressThisWarning VEditor : assigned in $readmem() system task integer n,i,base,diff,diff1; // reg [10:0] curv_diff; reg [17:0] data18; begin $readmemh("linear1028rgb.dat",curves_data); set_sensor_gamma_table_addr ( num_sensor, sub_channel, 2'b0, //input [1:0] color; 1'b0); //input page; // only used if SENS_GAMMA_BUFFER != 0 for (n=0;n<4;n=n+1) begin for (i=0;i<256;i=i+1) begin base =curves_data[257*n+i]; diff =curves_data[257*n+i+1]-curves_data[257*n+i]; diff1=curves_data[257*n+i+1]-curves_data[257*n+i]+8; // $display ("%x %x %x %x %x %x",n,i,curves_data[257*n+i], base, diff, diff1); #1; if ((diff>63) || (diff < -64)) data18 = {1'b1,diff1[10:4],base[9:0]}; else data18 = {1'b0,diff [ 6:0],base[9:0]}; set_sensor_gamma_table_data ( // need 256 for a single color data num_sensor, data18); // 18-bit table data end end end endtask task set_sensor_gamma_table_addr; input [1:0] num_sensor; input [1:0] sub_channel; input [1:0] color; input page; // only used if SENS_GAMMA_BUFFER != 0 reg [31:0] data; reg [29:0] reg_addr; begin data = 0; data [20] = 1'b1; data [7:0] = 8'b0; data [9:8] = color; if (SENS_GAMMA_BUFFER) data[12:10] = {sub_channel[1:0], page}; else data[11:10] = sub_channel[1:0]; reg_addr = (SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC) + SENS_GAMMA_RADDR + SENS_GAMMA_ADDR_DATA; write_contol_register(reg_addr, data); end endtask task set_sensor_gamma_table_data; // need 256 for a single color data input [1:0] num_sensor; input [17:0] data18; // 18-bit table data reg [29:0] reg_addr; begin reg_addr = (SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC) + SENS_GAMMA_RADDR + SENS_GAMMA_ADDR_DATA; write_contol_register(reg_addr, {14'b0, data18}); end endtask task set_sensor_gamma_heights; input [1:0] num_sensor; input [15:0] height0_m1; // height of the first sub-frame minus 1 input [15:0] height1_m1; // height of the second sub-frame minus 1 input [15:0] height2_m1; // height of the third sub-frame minus 1 (no need for 4-th) reg [29:0] reg_addr; begin reg_addr = (SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC) + SENS_GAMMA_RADDR + SENS_GAMMA_HEIGHT01; write_contol_register(reg_addr, {height1_m1, height0_m1}); reg_addr = (SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC) + SENS_GAMMA_RADDR + SENS_GAMMA_HEIGHT2; write_contol_register(reg_addr, {16'b0, height2_m1}); end endtask task set_sensor_gamma_ctl; input [1:0] num_sensor; // sensor channel number (0..3) input [1:0] bayer; // bayer shift (0..3) input table_page; // table page (only used if SENS_GAMMA_BUFFER) input en_input; // enable channel input input repet_mode; // Normal mode, single trigger - just for debugging input trig; // pass next frame reg [31:0] data; reg [29:0] reg_addr; begin data = func_sensor_gamma_ctl ( bayer, table_page, en_input, repet_mode, trig); reg_addr = (SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC) + SENS_GAMMA_RADDR + SENS_GAMMA_CTRL; write_contol_register(reg_addr, data); end endtask task set_sensor_histogram_window; input [1:0] num_sensor; // sensor channel number (0..3) input [1:0] subchannel; // subchannel number (for multiplexed images) input [15:0] left; input [15:0] top; input [15:0] width_m1; // one less than window width. If 0 - use frame right margin (end of HACT) input [15:0] height_m1; // one less than window height. If 0 - use frame bottom margin (end of VACT) // reg [31:0] data; reg [29:0] reg_addr; begin reg_addr = (SENSOR_GROUP_ADDR + num_sensor * SENSOR_BASE_INC); // + HISTOGRAM_LEFT_TOP; case (subchannel[1:0]) 2'h0: reg_addr = reg_addr + HISTOGRAM_RADDR0; 2'h1: reg_addr = reg_addr + HISTOGRAM_RADDR1; 2'h2: reg_addr = reg_addr + HISTOGRAM_RADDR2; 2'h3: reg_addr = reg_addr + HISTOGRAM_RADDR3; endcase write_contol_register(reg_addr + HISTOGRAM_LEFT_TOP, {top, left}); write_contol_register(reg_addr + HISTOGRAM_WIDTH_HEIGHT, {height_m1, width_m1}); end endtask task set_sensor_histogram_saxi; input en; input nrst; input confirm_write; // wait for the write confirmed befoer swicthing channels input [3:0] cache_mode; // default should be 4'h3 reg [31:0] data; begin data = 0; data [HIST_SAXI_EN] = en; data [HIST_SAXI_NRESET] = nrst; data [HIST_CONFIRM_WRITE] = confirm_write; data [HIST_SAXI_AWCACHE +: 4] = cache_mode; write_contol_register(SENSOR_GROUP_ADDR + HIST_SAXI_MODE_ADDR_REL, data); end endtask task set_sensor_histogram_saxi_addr; input [1:0] num_sensor; // sensor channel number (0..3) input [1:0] subchannel; // subchannel number (for multiplexed images) input [19:0] page; //start address in 4KB pages (1 page - one subchannel histogram) begin write_contol_register(SENSOR_GROUP_ADDR + HIST_SAXI_ADDR_REL + (num_sensor << 2) + subchannel,{12'b0,page}); end endtask function [STATUS_DEPTH-1:0] func_status_addr_sensor_i2c; input [1:0] num_sensor; begin func_status_addr_sensor_i2c = (SENSI2C_STATUS_REG_BASE + num_sensor * SENSI2C_STATUS_REG_INC + SENSI2C_STATUS_REG_REL); end endfunction function [STATUS_DEPTH-1:0] func_status_addr_sensor_io; input [1:0] num_sensor; begin func_status_addr_sensor_io = (SENSI2C_STATUS_REG_BASE + num_sensor * SENSI2C_STATUS_REG_INC + SENSIO_STATUS_REG_REL); end endfunction // RTC tasks task program_status_rtc; // set status mode, and take a time snapshot (wait response and read time) input [1:0] mode; input [5:0] seq_num; begin program_status (RTC_ADDR, RTC_SET_STATUS, mode, seq_num); end endtask task set_rtc; input [31:0] sec; input [19:0] usec; input [15:0] corr; begin write_contol_register(RTC_ADDR + RTC_SET_CORR,{16'b0,corr}); write_contol_register(RTC_ADDR + RTC_SET_USEC,{12'b0,usec}); write_contol_register(RTC_ADDR + RTC_SET_SEC, sec); end endtask function [STATUS_DEPTH-1:0] func_status_addr_rtc_status; begin func_status_addr_rtc_status = RTC_STATUS_REG_ADDR; end endfunction function [STATUS_DEPTH-1:0] func_status_addr_rtc_usec; // sec is in the next address begin func_status_addr_rtc_usec = RTC_SEC_USEC_ADDR; end endfunction // camsync tasks task set_camsync_mode; input [1:0] en_snd; // <2 - NOP, 2 - disable, 3 - enable sending timestamp with sync pulse input [1:0] en_ts_external; // <2 - NOP, 2 - local timestamp in the frame header, 3 - use external timestamp input [1:0] triggered_mode; // <2 - NOP, 2 - async sesnor mode, 3 - triggered sensor mode input [2:0] master_chn; // <4 - NOP, 4..7 - set master channel input [4:0] chn_en; // <16 - NOP, [3:0] - bit mask of enabled sensor channels reg [31:0] data; begin data = 0; data [CAMSYNC_SNDEN_BIT -: 2] = en_snd; data [CAMSYNC_EXTERNAL_BIT -: 2] = en_ts_external; data [CAMSYNC_TRIGGERED_BIT -: 2] = triggered_mode; data [CAMSYNC_MASTER_BIT -: 3] = master_chn; data [CAMSYNC_CHN_EN_BIT -: 5] = chn_en; write_contol_register(CAMSYNC_ADDR + CAMSYNC_MODE, data); end endtask task set_camsync_inout; // set specified input bit, keep other ones input is_out; // 0 - input selection, 1 - output selection input integer bit_number; // 0..9 - bit to use input active_positive; // 0 - active negative pulse, 1 - active positive pulse, reg [31:0] data; begin data = {32'h00055555}; data[2 * bit_number +: 2 ] = {1'b1, active_positive}; if (is_out) write_contol_register(CAMSYNC_ADDR + CAMSYNC_TRIG_DST, data); else write_contol_register(CAMSYNC_ADDR + CAMSYNC_TRIG_SRC, data); end endtask task reset_camsync_inout; // disable all inputs input is_out; // 0 - input selection, 1 - output selection begin if (is_out) write_contol_register(CAMSYNC_ADDR + CAMSYNC_TRIG_DST, 0); else write_contol_register(CAMSYNC_ADDR + CAMSYNC_TRIG_SRC, 0); end endtask task set_camsync_period; input [31:0] period; // 0 - input selection, 1 - output selection begin write_contol_register(CAMSYNC_ADDR + CAMSYNC_TRIG_PERIOD, period); end endtask task set_camsync_delay; input [1:0] sub_chn; input [31:0] dly; // 0 - input selection, 1 - output selection begin write_contol_register(CAMSYNC_ADDR + CAMSYNC_TRIG_DELAY0 + sub_chn, dly); end endtask // command sequencer control // Functions used by sensor-related tasks task ctrl_cmd_frame_sequencer; input [1:0] num_sensor; // sensor channel number input reset; // reset sequencer (also stops) input start; // start sequencer input stop; // stop sequencer reg [31:0] data; reg [29:0] reg_addr; begin reg_addr= CMDFRAMESEQ_ADDR_BASE + num_sensor * CMDFRAMESEQ_ADDR_INC + CMDFRAMESEQ_CTRL; data = 0; data [CMDFRAMESEQ_RST_BIT] = reset; data [CMDFRAMESEQ_RUN_BIT -:2] = {start | stop, start}; write_contol_register(reg_addr, data); end endtask task write_cmd_frame_sequencer; input [1:0] num_sensor; // sensor channel number input relative; // 0 - absolute (address = 0..f), 1 - relative (address= 0..e) input [3:0] frame_addr; // frame address (relative ort absolute) input [AXI_WR_ADDR_BITS-1:0] addr; // command address (register to which command should be applied) input [31:0] data; // command data reg [29:0] reg_addr; begin if (relative && (&frame_addr)) $display("task write_cmd_frame_sequencer(): relative adderss 'hf is invalid, it is reserved for module control"); else begin reg_addr = CMDFRAMESEQ_ADDR_BASE + num_sensor * CMDFRAMESEQ_ADDR_INC + (relative ? CMDFRAMESEQ_REL : CMDFRAMESEQ_ABS) + frame_addr; write_contol_register(reg_addr, {{32-AXI_WR_ADDR_BITS{1'b0}}, addr}); write_contol_register(reg_addr, data); end end endtask function [SENSOR_MODE_WIDTH-1:0] func_sensor_mode; input [3:0] hist_en; // [0..3] 1 - enable histogram modules, disable after processing the started frame input [3:0] hist_nrst; // [4..7] 0 - immediately reset histogram module input chn_en; // [8] 1 - enable sensor channel (0 - reset) input bits16; // [9] 0 - 8 bpp mode, 1 - 16 bpp (bypass gamma). Gamma-processed data is still used for histograms reg [SENSOR_MODE_WIDTH-1:0] tmp; begin tmp = 0; tmp [SENSOR_HIST_EN_BITS +: 4] = hist_en; tmp [SENSOR_HIST_NRST_BITS +: 4] = hist_nrst; tmp [SENSOR_CHN_EN_BIT] = chn_en; tmp [SENSOR_16BIT_BIT] = bits16; func_sensor_mode = tmp; end endfunction function [31 : 0] func_sensor_i2c_command; input rst_cmd; // [14] reset all FIFO (takes 16 clock pulses), also - stops i2c until run command input [SENSI2C_CMD_RUN_PBITS : 0] run_cmd; // [13:12]3 - run i2c, 2 - stop i2c (needed before software i2c), 1,0 - no change to run state input set_bytes; // [11] if 1, use bytes (below), 0 - nop input [SENSI2C_CMD_BYTES_PBITS -1 : 0] bytes; // [10:9] set command bytes to send after slave address (0..3) input set_dly; // [8] if 1, use dly (0 - ignore) input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quater i2c cycle (if 0, [3:0] control SCL+SDA) input [SENSI2C_CMD_SCL_WIDTH -1 : 0] scl_ctl; // [17:16] : 0: NOP, 1: 1'b0->SCL, 2: 1'b1->SCL, 3: 1'bz -> SCL input [SENSI2C_CMD_SDA_WIDTH -1 : 0] sda_ctl; // [19:18] : 0: NOP, 1: 1'b0->SDA, 2: 1'b1->SDA, 3: 1'bz -> SDA reg [31 : 0] tmp; begin tmp = 0; tmp [SENSI2C_CMD_RESET] = rst_cmd; tmp [SENSI2C_CMD_RUN -: SENSI2C_CMD_RUN_PBITS+1] = run_cmd; tmp [SENSI2C_CMD_BYTES] = set_bytes; tmp [SENSI2C_CMD_BYTES -1 -: SENSI2C_CMD_BYTES_PBITS ] = bytes; tmp [SENSI2C_CMD_DLY] = set_dly; tmp [SENSI2C_CMD_DLY -1 -: SENSI2C_CMD_DLY_PBITS ] = dly; tmp [SENSI2C_CMD_SCL +: SENSI2C_CMD_SCL_WIDTH] = scl_ctl; tmp [SENSI2C_CMD_SDA +: SENSI2C_CMD_SDA_WIDTH] = sda_ctl; func_sensor_i2c_command = tmp; end endfunction function [31 : 0] func_sensor_io_ctl; input [1:0] mrst; // <2: keep MRST, 2 - MRST low (active), 3 - high (inactive) input [1:0] arst; // <2: keep ARST, 2 - ARST low (active), 3 - high (inactive) input [1:0] aro; // <2: keep ARO, 2 - set ARO (software controlled) low, 3 - set ARO (software controlled) high input [1:0] mmcm_rst; // <2: keep MMCM reset, 2 - MMCM reset off, 3 - MMCM reset on input [1:0] clk_sel; // <2: keep MMCM clock source, 2 - use internal pixel clock, 3 - use pixel clock from the sensor input set_delays; // (self-clearing) load all pre-programmed delays input set_guadrants; // 0 - keep quadrants settings, 1 - update quadrants input [SENS_CTRL_QUADRANTS_WIDTH-1:0] quadrants; // 90-degree shifts for data [1:0], hact [3:2] and vact [5:4] reg [31 : 0] tmp; begin tmp = 0; tmp [SENS_CTRL_MRST +: 2] = mrst; tmp [SENS_CTRL_ARST +: 2] = arst; tmp [SENS_CTRL_ARO +: 2] = aro; tmp [SENS_CTRL_RST_MMCM +: 2] = mmcm_rst; tmp [SENS_CTRL_EXT_CLK +: 2] = clk_sel; tmp [SENS_CTRL_LD_DLY] = set_delays; tmp [SENS_CTRL_QUADRANTS_EN] = set_guadrants; tmp [SENS_CTRL_EXT_CLK +: SENS_CTRL_QUADRANTS_WIDTH] = quadrants; func_sensor_io_ctl = tmp; end endfunction function [31 : 0] func_sensor_jtag_ctl; input [1:0] pgmen; // <2: keep PGMEN, 2 - PGMEN low (inactive), 3 - high (active) enable JTAG control input [1:0] prog; // <2: keep prog, 2 - prog low (active), 3 - high (inactive) ("program" pin control) input [1:0] tck; // <2: keep TCK, 2 - set TCK low, 3 - set TCK high input [1:0] tms; // <2: keep TMS, 2 - set TMS low, 3 - set TMS high input [1:0] tdi; // <2: keep TDI, 2 - set TDI low, 3 - set TDI high reg [31 : 0] tmp; begin tmp = 0; tmp [SENS_JTAG_TDI +: 2] = pgmen; tmp [SENS_JTAG_TMS +: 2] = prog; tmp [SENS_JTAG_TCK +: 2] = tck; tmp [SENS_JTAG_TMS +: 2] = tms; tmp [SENS_JTAG_TDI +: 2] = tdi; func_sensor_jtag_ctl = tmp; end endfunction function [31 : 0] func_sensor_gamma_ctl; input [1:0] bayer; input table_page; input en_input; input repet_mode; // Normal mode, single trigger - just for debugging TODO: re-assign? input trig; reg [31 : 0] tmp; begin tmp = 0; tmp[SENS_GAMMA_MODE_BAYER +: 2] = bayer; tmp [SENS_GAMMA_MODE_PAGE] = table_page; tmp [SENS_GAMMA_MODE_EN] = en_input; tmp [SENS_GAMMA_MODE_REPET] = repet_mode; tmp [SENS_GAMMA_MODE_TRIG] = trig; func_sensor_gamma_ctl = tmp; end endfunction `include "includes/tasks_tests_memory.vh" // SuppressThisWarning VEditor - may be unused `include "includes/x393_tasks_afi.vh" // SuppressThisWarning VEditor - may be unused `include "includes/x393_tasks_mcntrl_en_dis_priority.vh" `include "includes/x393_tasks_mcntrl_buffers.vh" `include "includes/x393_tasks_pio_sequences.vh" `include "includes/x393_tasks_mcntrl_timing.vh" // SuppressThisWarning VEditor - not used `include "includes/x393_tasks_ps_pio.vh" `include "includes/x393_tasks_status.vh" `include "includes/x393_tasks01.vh" `include "includes/x393_mcontr_encode_cmd.vh" endmodule