Commit ab6fc4dc authored by Andrey Filippov's avatar Andrey Filippov

added support for the variable quality quantization tables

parent 4b80a882
......@@ -62,42 +62,42 @@
<link>
<name>vivado_logs/VivadoBitstream.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoBitstream-20150916155306201.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoBitstream-20150919172017385.log</location>
</link>
<link>
<name>vivado_logs/VivadoOpt.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOpt-20150916155306201.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoOpt-20150919172017385.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPhys-20150916155306201.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPhys-20150919172017385.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPower.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPower-20150916155306201.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPower-20150919172017385.log</location>
</link>
<link>
<name>vivado_logs/VivadoPlace.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoPlace-20150916155306201.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoPlace-20150919172017385.log</location>
</link>
<link>
<name>vivado_logs/VivadoRoute.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoRoute-20150916155306201.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoRoute-20150919172017385.log</location>
</link>
<link>
<name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoSynthesis-20150916153820807.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoSynthesis-20150919164827543.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportImplemented-20150916155306201.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportImplemented-20150919172017385.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
......
......@@ -42,7 +42,10 @@ module compressor393 # (
parameter CMPRS_COLOR_SATURATION= 3,
parameter CMPRS_CORING_MODE= 4,
parameter CMPRS_TABLES= 6, // 6..7
parameter TABLE_QUANTIZATION_INDEX = 0,
parameter TABLE_CORING_INDEX = 1,
parameter TABLE_FOCUS_INDEX = 2,
parameter TABLE_HUFFMAN_INDEX = 3,
parameter FRAME_HEIGHT_BITS= 16, // Maximal frame height
parameter LAST_FRAME_BITS= 16, // number of bits in frame counter (before rolls over)
// Bit-fields in compressor control word
......@@ -323,6 +326,10 @@ module compressor393 # (
.CMPRS_COLOR_SATURATION (CMPRS_COLOR_SATURATION),
.CMPRS_CORING_MODE (CMPRS_CORING_MODE),
.CMPRS_TABLES (CMPRS_TABLES),
.TABLE_QUANTIZATION_INDEX (TABLE_QUANTIZATION_INDEX),
.TABLE_CORING_INDEX (TABLE_CORING_INDEX),
.TABLE_FOCUS_INDEX (TABLE_FOCUS_INDEX),
.TABLE_HUFFMAN_INDEX (TABLE_HUFFMAN_INDEX),
.FRAME_HEIGHT_BITS (FRAME_HEIGHT_BITS),
.LAST_FRAME_BITS (LAST_FRAME_BITS),
.CMPRS_CBIT_RUN (CMPRS_CBIT_RUN),
......
......@@ -52,7 +52,7 @@ module huffman393 (
);
`ifdef INFER_LATCHES
reg [15:0] hcode_latch; // table output huffman code (1..16 bits)
reg [ 3:0] hlen_latch; // table - code length only 4 LSBs are used
reg [ 3:0] hlen_latch; // table - code length only 4 LSBs are used, so 0 means 16
reg [ 7:0] haddr70_latch;
reg haddr8_latch;
reg tables_re_latch;
......
......@@ -35,6 +35,10 @@ module jp_channel#(
parameter CMPRS_COLOR_SATURATION= 3,
parameter CMPRS_CORING_MODE= 4,
parameter CMPRS_TABLES= 6, // 6(data)..7(address)
parameter TABLE_QUANTIZATION_INDEX = 0,
parameter TABLE_CORING_INDEX = 1,
parameter TABLE_FOCUS_INDEX = 2,
parameter TABLE_HUFFMAN_INDEX = 3,
parameter FRAME_HEIGHT_BITS= 16, // Maximal frame height
parameter LAST_FRAME_BITS= 16, // number of bits in frame counter (before rolls over)
......@@ -889,22 +893,26 @@ module jp_channel#(
// wire table_we; // writing to tables (decoded stb from cmd_deser)
wire tser_a_not_d; // address/not data distributed to submodules
wire [ 7:0] tser_d; // byte-wide serialized tables address/data to submodules
wire tser_qe; // write serialized table data to quantizer
wire tser_ce; // write serialized table data to coring
wire tser_fe; // write serialized table data to focusing
wire tser_he; // write serialized table data to Huffman
wire [ 3:0] tser_sel; // vector of individual table selects (decoded from the 8 MSBs of the table address)
wire tser_qe = tser_sel[TABLE_QUANTIZATION_INDEX]; // write serialized table data to quantizer
wire tser_ce = tser_sel[TABLE_CORING_INDEX]; // write serialized table data to coring
wire tser_fe = tser_sel[TABLE_FOCUS_INDEX]; // write serialized table data to focusing
wire tser_he = tser_sel[TABLE_HUFFMAN_INDEX]; // write serialized table data to Huffman
//{tser_he,tser_fe,tser_ce,tser_qe}
// As all commands are 32-bit data, all 4 bytes will be written to a designated table (usually 2 of 16-bit writes)
table_ad_transmit #(
.NUM_CHANNELS(4),
.ADDR_BITS(3)
) table_ad_transmit_i (
.clk (mclk), // input @posedge
.srst (mrst), // @posedge mclk
.a_not_d_in (cmd_a[0]), // input writing table address /not data (a[0] from cmd_deser)
.we (set_tables_w), // input writing to tables (decoded stb from cmd_deser)
.din (cmd_data), // input[31:0] 32-bit data to serialize/write to tables (LSB first) - from cmd_deser
.ser_d (tser_d), // output[7:0] byte-wide serialized tables address/data to submodules
.a_not_d (tser_a_not_d), // output reg address/not data distributed to submodules
.chn_en ({tser_he,tser_fe,tser_ce,tser_qe}) // output[0:0] reg - table 1-hot select outputs
// .chn_en ({tser_he,tser_fe,tser_ce,tser_qe}) // output[0:0] reg - table 1-hot select outputs
.chn_en (tser_sel) // output[0:0] reg - table 1-hot select outputs
);
......@@ -950,7 +958,7 @@ module jp_channel#(
.en (frame_en), // input
.mclk (mclk), // input system clock to write tables
.tser_we (tser_fe), // input - write to a quantization table
.tser_we (tser_fe), // input - write to a focus sharpness table
.tser_a_not_d (tser_a_not_d), // input - address/not data to tables
.tser_d (tser_d), // input[7:0] - byte-wide data to tables
......
parameter FPGA_VERSION = 32'h03930034;
\ No newline at end of file
parameter FPGA_VERSION = 32'h03930035;
\ No newline at end of file
/* This is a generated file with the current DDR3 memory timing parameters */
localparam DLY_LANE0_ODELAY = 80'hd8e8181c1c221c201b20;
localparam DLY_LANE0_IDELAY = 72'h2078807c88797c7884;
localparam DLY_LANE1_ODELAY = 80'hd8e31a181b1a1c1c1c1a;
localparam DLY_LANE1_IDELAY = 72'h247b747b7882787c7c;
localparam DLY_CMDA = 256'hd4d4d4dadcd3dbd0484848484848484848d4d4ccd4d4dcd9ccd8d4d4d3d3dbd0;
localparam DLY_PHASE = 8'h32;
// localparam DFLT_WBUF_DELAY = 4'h8;
/home/andrey/git/x393/includes/x393_cur_params_target_00.vh
\ No newline at end of file
......@@ -545,6 +545,11 @@
parameter CMPRS_COLOR_SATURATION= 3,
parameter CMPRS_CORING_MODE= 4,
parameter CMPRS_TABLES= 6, // 6..7
parameter TABLE_QUANTIZATION_INDEX = 0,
parameter TABLE_CORING_INDEX = 1,
parameter TABLE_FOCUS_INDEX = 2,
parameter TABLE_HUFFMAN_INDEX = 3,
// Bit-fields in compressor control word
parameter CMPRS_CBIT_RUN = 2, // bit # to control compressor run modes
......@@ -725,17 +730,18 @@
parameter CLK_CNTRL = 0,
parameter CLK_STATUS = 1,
`ifdef DEBUG_RING
// These are needed for Python:
//`ifdef DEBUG_RING
// Debug module (read/write serial ring)
parameter DEBUG_ADDR = 'h710, //..'h713
parameter DEBUG_ADDR = 'h710, //..'h713 // SuppressThisWarning VEditor
parameter DEBUG_MASK = 'h7fc,
parameter DEBUG_STATUS_REG_ADDR = 'hfc, // address where status can be read out
parameter DEBUG_READ_REG_ADDR = 'hfd, // read 32-bit received shifted data
parameter DEBUG_SHIFT_DATA = 'h0, // shift i/o data by 32 bits
parameter DEBUG_LOAD = 'h1, // parallel load of the distributed shift registe (both ways)
parameter DEBUG_SET_STATUS = 'h2, // program status (mode 3?)
parameter DEBUG_CMD_LATENCY = 2, // >0 extra registers in the debug_sl (distriburted in parallel)
`endif
parameter DEBUG_STATUS_REG_ADDR = 'hfc, // address where status can be read out // SuppressThisWarning VEditor
parameter DEBUG_READ_REG_ADDR = 'hfd, // read 32-bit received shifted data// SuppressThisWarning VEditor
parameter DEBUG_SHIFT_DATA = 'h0, // shift i/o data by 32 bits// SuppressThisWarning VEditor
parameter DEBUG_LOAD = 'h1, // parallel load of the distributed shift registe (both ways)// SuppressThisWarning VEditor
parameter DEBUG_SET_STATUS = 'h2, // program status (mode 3?)// SuppressThisWarning VEditor
parameter DEBUG_CMD_LATENCY = 2, // >0 extra registers in the debug_sl (distriburted in parallel)// SuppressThisWarning VEditor
//`endif
parameter CLKIN_PERIOD_AXIHP = 20, //ns >1.25, 600<Fvco<1200
parameter DIVCLK_DIVIDE_AXIHP = 1,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -153,12 +153,14 @@ MCNTRL_SCANLINE_MASK__TYPE = str
MCONTR_PHY_0BIT_SDRST_ACT = int
SENSI2C_IBUF_LOW_PWR = str
CLKOUT_DIV_PCLK2X__RAW = str
TILED_EXTRA_PAGES__TYPE = str
CMPRS_JP4__TYPE = str
TABLE_CORING_INDEX = int
DQSTRI_LAST = int
MCNTRL_TEST01_CHN2_STATUS_CNTRL__TYPE = str
STATUS_2LSB_SHFT__TYPE = str
SENS_SS_EN__TYPE = str
MEMBRIDGE_LEN64__TYPE = str
TABLE_QUANTIZATION_INDEX__TYPE = str
LOGGER_CONF_EN__RAW = str
HIST_CONFIRM_WRITE = int
CMPRS_GROUP_ADDR__TYPE = str
......@@ -313,7 +315,7 @@ CMPRS_JP4DIFF = int
RTC_STATUS_REG_ADDR = int
SENS_LENS_BY_MASK__TYPE = str
CMPRS_CBIT_CMODE__RAW = str
CMPRS_JP4__TYPE = str
TILED_EXTRA_PAGES__TYPE = str
AFI_MUX_BUF_LATENCY = int
WINDOW_WIDTH = int
CLK_CNTRL__RAW = str
......@@ -336,6 +338,7 @@ LOGGER_CONF_MSG__RAW = str
MCNTRL_TILED_STATUS_REG_CHN2_ADDR__RAW = str
LAST_FRAME_BITS__RAW = str
SENS_DIVCLK_DIVIDE = int
NEWPAR = int
SENS_LENS_COEFF__RAW = str
CMPRS_CONTROL_REG = int
GPIO_STATUS_REG_ADDR = int
......@@ -455,6 +458,7 @@ MCONTR_ARBIT_ADDR_MASK = int
MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR = int
MCNTRL_SCANLINE_WINDOW_WH = int
WBUF_DLY_WLV__RAW = str
TABLE_HUFFMAN_INDEX = int
MCNTRL_TILED_FRAME_LAST = int
MCNTRL_TEST01_CHN2_MODE__RAW = str
CMPRS_AFIMUX_REG_ADDR0__TYPE = str
......@@ -694,7 +698,7 @@ SENS_CTRL_QUADRANTS_WIDTH = int
STATUS_PSHIFTER_RDY_MASK__RAW = str
TILE_WIDTH__TYPE = str
MCNTRL_TILED_FRAME_LAST__RAW = str
MCONTR_TOP_0BIT_REFRESH_EN__RAW = str
SENSI2C_CMD_RESET__RAW = str
REFRESH_OFFSET = int
MCNTRL_PS_EN_RST = int
MCNTRL_TILED_TILE_WHS = int
......@@ -765,6 +769,7 @@ MULT_SAXI_ADV_WR = int
NUM_CYCLES_10__TYPE = str
MCONTR_LINTILE_EXTRAPG__RAW = str
SENS_LENS_FAT0_IN__RAW = str
NEWPAR__TYPE = str
CMPRS_AFIMUX_STATUS_CNTRL__TYPE = str
LOGGER_CONFIG__RAW = str
LD_DLY_LANE0_ODELAY__RAW = str
......@@ -919,11 +924,12 @@ MCONTR_SENS_STATUS_INC__TYPE = str
CAMSYNC_TRIG_DELAY0__TYPE = str
SENSI2C_STATUS_REG_INC = int
CLKFBOUT_PHASE__TYPE = str
TABLE_QUANTIZATION_INDEX__RAW = str
MCNTRL_TILED_WINDOW_WH = int
CMDFRAMESEQ_MASK = int
CLK_ADDR = int
MCNTRL_TILED_WINDOW_X0Y0__TYPE = str
NUM_XFER_BITS__RAW = str
SENS_CTRL_EXT_CLK__TYPE = str
MCNTRL_TILED_WINDOW_STARTXY__RAW = str
CMPRS_CSAT_CB_BITS__RAW = str
CMPRS_CBIT_RUN__RAW = str
......@@ -943,7 +949,7 @@ CMPRS_FRMT_MBRM1_BITS__TYPE = str
MCNTRL_TILED_TILE_WHS__RAW = str
SENS_REFCLK_FREQUENCY = float
CMD_PAUSE_BITS__TYPE = str
SENS_CTRL_EXT_CLK__TYPE = str
NUM_XFER_BITS__RAW = str
SENS_LENS_BY = int
SENS_LENS_BX = int
NUM_CYCLES_02__TYPE = str
......@@ -968,6 +974,7 @@ CLKFBOUT_MULT_SENSOR = int
CMPRS_AFIMUX_EN = int
COLADDR_NUMBER = int
MCNTRL_TILED_STARTADDR__RAW = str
TABLE_FOCUS_INDEX__TYPE = str
CAMSYNC_DELAY = int
BUF_IPCLK2X_SENS2__TYPE = str
MCNTRL_TEST01_CHN1_MODE__RAW = str
......@@ -1043,6 +1050,7 @@ CMPRS_STATUS_CNTRL__TYPE = str
MCONTR_RD_MASK = int
CMPRS_COLOR_SATURATION = int
NUM_CYCLES_21__RAW = str
NEWPAR__RAW = str
SENSIO_DELAYS__RAW = str
CMDFRAMESEQ_RUN_BIT = int
SENS_SYNC_MINPER = int
......@@ -1295,6 +1303,7 @@ CMPRS_HIFREQ_REG_BASE = int
MCONTR_ARBIT_ADDR = int
MEMBRIDGE_CTRL__RAW = str
CMPRS_CBIT_RUN_RST__RAW = str
TABLE_QUANTIZATION_INDEX = int
NUM_CYCLES_04__TYPE = str
WSEL__RAW = str
CLKOUT_DIV_XCLK__TYPE = str
......@@ -1372,6 +1381,7 @@ IDELAY_VALUE__TYPE = str
CMPRS_CBIT_CMODE_JP4DC__TYPE = str
SENSI2C_CMD_SDA = int
PICKLE__TYPE = str
TABLE_FOCUS_INDEX__RAW = str
SENSOR_MODE_WIDTH__TYPE = str
MCONTR_LINTILE_WRITE__RAW = str
MCNTRL_TILED_CHN2_ADDR__RAW = str
......@@ -1409,6 +1419,7 @@ MCONTR_LINTILE_DIS_NEED = int
MCONTR_CMPRS_STATUS_INC__RAW = str
CMPRS_CBIT_CMODE_JP4DIFFHDR = int
BUF_CLK1X_SYNC = str
TABLE_CORING_INDEX__RAW = str
SENSI2C_CMD_RESET__TYPE = str
CMPRS_CBIT_CMODE_JP4DIFFDIV2__RAW = str
MCONTR_ARBIT_ADDR__TYPE = str
......@@ -1474,6 +1485,7 @@ WBUF_DLY_WLV = int
MCONTR_BUF3_WR_ADDR__RAW = str
MEMBRIDGE_WIDTH64 = int
MCNTRL_TEST01_CHN3_MODE = int
TABLE_HUFFMAN_INDEX__RAW = str
LD_DLY_PHASE__RAW = str
TEST_INITIAL_BURST__RAW = str
CMPRS_CBIT_FRAMES_BITS__TYPE = str
......@@ -1571,6 +1583,7 @@ BUF_CLK1X_PCLK2X = str
MCNTRL_TEST01_CHN4_MODE = int
MCNTRL_PS_STATUS_REG_ADDR__RAW = str
MAX_TILE_WIDTH = int
TABLE_FOCUS_INDEX = int
CMPRS_CBIT_RUN_STANDALONE__RAW = str
CMPRS_CBIT_CMODE_JP4DIFFHDRDIV2 = int
DFLT_DQ_TRI_OFF_PATTERN__RAW = str
......@@ -1779,6 +1792,7 @@ MULT_SAXI_MASK = int
MCNTRL_SCANLINE_WINDOW_STARTXY__TYPE = str
CMDFRAMESEQ_DEPTH__TYPE = str
DLY_LANE0_IDELAY__RAW = str
TABLE_CORING_INDEX__TYPE = str
HISTOGRAM_RADDR1__RAW = str
CLKFBOUT_DIV_REF__TYPE = str
MCONTR_LINTILE_EXTRAPG_BITS__RAW = str
......@@ -1850,7 +1864,7 @@ BUF_CLK1X_AXIHP = str
SENSIO_WIDTH = int
MCONTR_PHY_0BIT_DLY_RST__RAW = str
BUF_CLK1X_PCLK2X__RAW = str
SENSI2C_CMD_RESET__RAW = str
MCONTR_TOP_0BIT_REFRESH_EN__RAW = str
SENSI2C_ADDR_MASK__RAW = str
SENS_HIGH_PERFORMANCE_MODE__TYPE = str
MCONTR_LINTILE_KEEP_OPEN__TYPE = str
......@@ -1976,6 +1990,7 @@ SENS_PCLK_PERIOD__RAW = str
NUM_CYCLES_23__TYPE = str
MCNTRL_TILED_MODE__TYPE = str
MCONTR_TOP_0BIT_MCONTR_EN__RAW = str
TABLE_HUFFMAN_INDEX__TYPE = str
RTC_SET_STATUS__RAW = str
SENS_CTRL_QUADRANTS = int
LD_DLY_PHASE__TYPE = str
......
......@@ -221,7 +221,7 @@ class X393Cmprs(object):
focus_mode = None):
"""
Combine compressor control parameters into a single word. None value preserves old setting for the parameter
@param chn - compressor channel number
@param chn - compressor channel number, "a" or "all" - same for all 4 channels
@param run_mode - 0 - reset, 2 - run single from memory, 3 - run repetitive
@param qbank - quantization table page (0..15)
@param dc_sub - True - subtract DC before running DCT, False - no subtraction, convert as is,
......@@ -243,6 +243,20 @@ class X393Cmprs(object):
@param bayer - Bayer shift (0..3)
@param focus_mode - focus mode - how to combine image with "focus quality" in the result image
"""
try:
if (chn == all) or (chn[0].upper() == "A"): #all is a built-in function
for chn in range(4):
self.compressor_control (chn = chn,
run_mode = run_mode,
qbank = qbank,
dc_sub = dc_sub,
cmode = cmode,
multi_frame = multi_frame,
bayer = bayer,
focus_mode = focus_mode)
return
except:
pass
data = self.func_compressor_control(
run_mode = run_mode,
qbank = qbank,
......
......@@ -161,6 +161,7 @@ class X393Jpeg(object):
x393_axi_tasks=None #x393X393AxiControlStatus
x393_utils=None
x393_cmprs_afi = None
x393_sens_cmprs = None
verbose=1
def __init__(self, debug_mode=1,dry_mode=True, saveFileName=None):
......@@ -171,11 +172,66 @@ class X393Jpeg(object):
self.x393_axi_tasks= x393_axi_control_status.X393AxiControlStatus(debug_mode,dry_mode)
self.x393_cmprs_afi = x393_cmprs_afi.X393CmprsAfi(debug_mode,dry_mode)
self.x393_utils= x393_utils.X393Utils(debug_mode,dry_mode, saveFileName) # should not overwrite save file path
self.x393_sens_cmprs = x393_sens_cmprs.X393SensCmprs(debug_mode,dry_mode, saveFileName)
try:
self.verbose=vrlg.VERBOSE
except:
pass
self.huff_tables=None
def set_qtables(self,
chn,
index = 0, # index of a table pair
y_quality = 80,
c_quality = None,
portrait = False,
verbose = 1
):
"""
Set a pair of quantization tables to FPGA
@param chn - compressor channel number, "a" or "all" - same for all 4 channels
@param y_quality - 1..100 - quantization quality for Y component
@param c_quality - 1..100 - quantization quality for color components (None - use y_quality)
@param portrait - False - use normal order, True - transpose for portrait mode images
@param verbose - verbose level
@return dictionary{"header","fpga"} each with a list of 2 lists of the 64 quantization
table values [[y-table],[c-table]]
'header' points to a pair of tables for the file header, 'fpga' - tables to be
sent to the fpga
"""
try:
if (chn == all) or (chn[0].upper() == "A"): #all is a built-in function
for chn in range(4):
self.set_qtables (chn = chn,
index = index,
y_quality = y_quality,
c_quality = c_quality,
portrait = portrait,
verbose = verbose)
return
except:
pass
quantization_data = self.get_qtables(y_quality = y_quality,
c_quality = c_quality,
portrait = portrait,
verbose = verbose - 1)
quantization_data = quantization_data['fpga'][0] + quantization_data['fpga'][1]
if verbose > 1:
items_per_line = 8
print("quantization_data:")
for i, qd in enumerate(quantization_data):
if (i % items_per_line) == 0:
print("%04x: "%(i), end = "")
print ("%04x"%(qd), end = (", ","\n")[((i+1) % items_per_line) == 0])
self.x393_sens_cmprs.program_quantization (chn = chn,
index = index,
quantization_data = quantization_data,
verbose = verbose)
def get_qtables(self,
y_quality = 80,
c_quality = None,
......@@ -209,7 +265,8 @@ class X393Jpeg(object):
for i,t in enumerate(STD_QUANT_TBLS[t_name]):
d = max(1,min((t * q + 50) // 100, 255))
tbl[ZIG_ZAG[i]] = d
fpga_tbl[i] = min(((0x20000 // d) + 1) >> 1, 0xffff)
# fpga_tbl[i] = min(((0x20000 // d) + 1) >> 1, 0xffff)
fpga_tbl[ZIG_ZAG[i]] = min(((0x20000 // d) + 1) >> 1, 0xffff)
rslt.append(tbl)
fpga.append(fpga_tbl)
if verbose > 0:
......@@ -570,7 +627,6 @@ class X393Jpeg(object):
return {"header":buf,
"quantization":qtables["fpga"],
"huffman": self.huff_tables[FPGA_HUFFMAN_TABLE]}
def jpeg_write(self,
file_path = "/www/pages/img.jpeg",
channel = 0,
......@@ -591,6 +647,21 @@ class X393Jpeg(object):
@param byrshift - Bayer shift
@param verbose - verbose level
"""
try:
if (channel == all) or (channel[0].upper() == "A"): #all is a built-in function
for channel in range(4):
self.jpeg_write (file_path = file_path.replace(".","_%d."%channel),
channel = channel,
y_quality = y_quality, #80,
c_quality = c_quality,
portrait = portrait,
color_mode = color_mode,
byrshift = byrshift,
verbose = verbose)
return
except:
pass
jpeg_data = self.jpegheader_create (
y_quality = y_quality,
c_quality = c_quality,
......@@ -719,20 +790,27 @@ measure_all "*DI"
setup_all_sensors True None 0xf
#reset all compressors
compressor_control 0 0
compressor_control 1 0
compressor_control 2 0
compressor_control 3 0
#compressor_control 0 0
#compressor_control 1 0
#compressor_control 2 0
#compressor_control 3 0
compressor_control all 0
#next line to make compressor aways use the same input video frame buffer (default - 2 ping-pong frame buffers)
#axi_write_single_w 0x6c4 0
#set quadrants
set_sensor_io_ctl 0 None None None None None 0 0x4
set_sensor_io_ctl 1 None None None None None 0 0xe
set_sensor_io_ctl 2 None None None None None 0 0x4
set_sensor_io_ctl 3 None None None None None 0 0xe
# Set Bayer = 3 (probably #1 and #3 need different hact/pxd delays to use the same compressor bayer for all channels)
compressor_control 0 None None None None None 3
compressor_control 1 None None None None None 2
compressor_control 2 None None None None None 3
compressor_control 3 None None None None None 2
#compressor_control 0 None None None None None 3
#compressor_control 1 None None None None None 3
#compressor_control 2 None None None None None 3
#compressor_control 3 None None None None None 3
compressor_control all None None None None None 3
#Gamma 0.57
......@@ -795,16 +873,66 @@ axi_write_single_w 0x6a6 0x079800a3
axi_write_single_w 0x6b6 0x079800a3
#run copmpressors once (#1 - stop gracefully, 0 - reset, 2 - single, 3 - repetitive with sync to sensors)
compressor_control 0 2
compressor_control 1 2
compressor_control 2 2
compressor_control 3 2
#compressor_control 0 2
#compressor_control 1 2
#compressor_control 2 2
#compressor_control 3 2
compressor_control all 2
#jpeg_write "/www/pages/img0.jpeg" 0
#jpeg_write "/www/pages/img1.jpeg" 1
#jpeg_write "/www/pages/img2.jpeg" 2
#jpeg_write "/www/pages/img3.jpeg" 3
jpeg_write "/www/pages/img.jpeg" all
Usage: set_qtables <chn> <index=0> <y_quality=80> <c_quality=None> <portrait=False> <verbose=1>
specify_phys_memory
specify_window
set_qtables all 0 80
compressor_control all 2
jpeg_write "/www/pages/img.jpeg" all 80
-----
setup_membridge_sensor <write_mem=False> <cache_mode=3> <window_width=2592> <window_height=1944> <window_left=0> <window_top=0> <membridge_start=731906048> <membridge_end=768606208> <verbose=1>
setup_membridge_sensor 0 3 2608 1936
setup_membridge_sensor <num_sensor=0> <write_mem=False> <cache_mode=3> <window_width=2592> <window_height=1944> <window_left=0> <window_top=0> <last_buf_frame=1> <membridge_start=731906048> <membridge_end=768606208> <verbose=1>
setup_membridge_sensor 0 0 3 2608 1936
setup_membridge_sensor 1 0 3 2608 1936
# Trying quadrants @param quadrants - 90-degree shifts for data [1:0], hact [3:2] and vact [5:4] (6'h01), None - no change
# set_sensor_io_ctl <num_sensor> <mrst=None> <arst=None> <aro=None> <mmcm_rst=None> <clk_sel=None> <set_delays=False> <quadrants=None>
set_sensor_io_ctl 0 None None None None None 0 1
set_sensor_io_ctl 1 None None None None None 0 1
#make all reddish
write_sensor_i2c 0 1 0 0x90350008
write_sensor_i2c 0 1 0 0x902c0008
write_sensor_i2c 0 1 0 0x902d001f
write_sensor_i2c 1 1 0 0x90350008
write_sensor_i2c 1 1 0 0x902c0008
write_sensor_i2c 1 1 0 0x902d001f
write_sensor_i2c 2 1 0 0x90350008
write_sensor_i2c 2 1 0 0x902c0008
write_sensor_i2c 2 1 0 0x902d001f
jpeg_write "/www/pages/img0.jpeg" 0
jpeg_write "/www/pages/img1.jpeg" 1
jpeg_write "/www/pages/img2.jpeg" 2
jpeg_write "/www/pages/img3.jpeg" 3
write_sensor_i2c 3 1 0 0x90350008
write_sensor_i2c 3 1 0 0x902c0008
write_sensor_i2c 3 1 0 0x902d001f
set_qtables all 0 90
jpeg_write "/www/pages/img.jpeg" all
compressor_control all None 1
compressor_control all None 0
"""
......@@ -618,11 +618,13 @@ class X393SensCmprs(object):
self.program_status_debug (3,0)
if setup_membridge:
self.setup_membridge_sensor(
num_sensor = 0,
write_mem = False,
window_width = window_width,
window_height = window_height,
window_left = window_left,
window_top = window_top,
last_buf_frame = last_buf_frame,
membridge_start = GLBL_MEMBRIDGE_START,
membridge_end = GLBL_MEMBRIDGE_END,
verbose = verbose)
......@@ -809,7 +811,7 @@ class X393SensCmprs(object):
@param seq_number - 6-bit sequence number of the status message to be sent
"""
self.x393_axi_tasks.program_status (vrlg.DEBUG_ADDR ,
self.x393_axi_tasks.program_status (vrlg.DEBUG_ADDR,
vrlg.DEBUG_SET_STATUS,
mode,
seq_num)
......@@ -837,34 +839,57 @@ class X393SensCmprs(object):
def setup_membridge_sensor(self,
num_sensor = 0,
write_mem = False,
cache_mode = 0x3, # 0x13 for debug mode
window_width = 2592,
window_height = 1944,
window_left = 0,
window_top = 0,
last_buf_frame = 1, # - just 2-frame buffer
membridge_start = 0x2ba00000,
membridge_end = 0x2dd00000,
verbose = 1):
"""
Configure membridge to read/write to the sensor 0 area in the video memory
@param num_sensor - sensor port number (0..3)
@param write_mem - Write to video memory (Flase - read from)
@param cache_mode - lower 4 bits, axi cache mode (default 3), bit [4] - debug mode (replace data)
@param window_width - window width in pixels (bytes) (TODO: add 16-bit mode)
@param window_height - window height in lines
@param window_left - window left margin
@param window_top - window top margin
@param last_buf_frame) - 16-bit number of the last frame in a buffer
@param membridge_start system memory low address (bytes) 0x2ba00000,
@param membridge_end system memory buffer length (bytes)= 0x2dd00000,
@param verbose verbose level):
"""
#copied from setup_sensor_channel()
align_to_bursts = 64 # align full width to multiple of align_to_bursts. 64 is the size of memory access
width_in_bursts = window_width >> 4
if (window_width & 0xf):
width_in_bursts += 1
num_burst_in_line = (window_left >> 4) + width_in_bursts
num_pages_in_line = num_burst_in_line // align_to_bursts;
if num_burst_in_line % align_to_bursts:
num_pages_in_line += 1
frame_full_width = num_pages_in_line * align_to_bursts
num8rows= (window_top + window_height) // 8
if (window_top + window_height) % 8:
num8rows += 1
frame_start_address_inc = num8rows * frame_full_width
frame_start_address = (last_buf_frame + 1) * frame_start_address_inc * num_sensor
if verbose >0 :
print ("===================== Setting membridge for sensor 0 =========================")
print ("Write to video buffer = %s"%(("False","True")[write_mem]))
print ("num_sensor = ", num_sensor)
print ("Window width = %d(0x%x)"%(window_width,window_width))
print ("Window height = %d(0x%x)"%(window_height,window_height))
print ("Window left = %d(0x%x)"%(window_left,window_left))
print ("Window top = %d(0x%x)"%(window_top,window_top))
print ("frame_start_address = 0x%x"%(frame_start_address))
print ("frame_start_address_inc = 0x%x"%(frame_start_address_inc))
print ("membridge start = 0x%x"%(membridge_start))
print ("membridge end = 0x%x"%(membridge_end))
print ("membridge size = %d bytes"%(membridge_end - membridge_start))
......@@ -884,7 +909,7 @@ class X393SensCmprs(object):
num8rows= (window_top + window_height) // 8
if (window_top + window_height) % 8:
num8rows += 1
frame_start_addr = 0 # for sensor 0
# frame_start_addr = 0 # for sensor 0
# frame_start_address_inc = num8rows * frame_full_width
# len64 = num_burst_in_line * 2 * window_height
......@@ -901,7 +926,7 @@ class X393SensCmprs(object):
enable = True,
chn_reset = False)
self.x393_axi_tasks.write_control_register(vrlg.MCNTRL_SCANLINE_CHN1_ADDR + vrlg.MCNTRL_SCANLINE_STARTADDR, frame_start_addr) # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_control_register(vrlg.MCNTRL_SCANLINE_CHN1_ADDR + vrlg.MCNTRL_SCANLINE_STARTADDR, frame_start_address) # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_control_register(vrlg.MCNTRL_SCANLINE_CHN1_ADDR + vrlg.MCNTRL_SCANLINE_FRAME_FULL_WIDTH, frame_full_width)
self.x393_axi_tasks.write_control_register(vrlg.MCNTRL_SCANLINE_CHN1_ADDR + vrlg.MCNTRL_SCANLINE_WINDOW_WH, (window_height << 16) | (window_width >> 4)) # WINDOW_WIDTH + (WINDOW_HEIGHT<<16));
self.x393_axi_tasks.write_control_register(vrlg.MCNTRL_SCANLINE_CHN1_ADDR + vrlg.MCNTRL_SCANLINE_WINDOW_X0Y0, (window_top << 16) | (window_left >> 4)) # WINDOW_X0+ (WINDOW_Y0<<16));
......@@ -1149,6 +1174,136 @@ class X393SensCmprs(object):
d = (long_status >> l) & ((1 << p[1]) - 1)
print (("%03x.%02x: %"+str(maximal_name_length)+"s [%2d] = 0x%x (%d)")%(l // 32, l % 32, p[0],p[1],d,d))
l += p[1]
def program_huffman(self,
chn,
index,
huffman_data):
"""
@brief Program data to compressor Huffman table
@param chn - compressor channel (0..3)
@param index offset address by multiple input data sizes
@param huffman_data - list of table 512 items or a file path
with the same data, same as for Verilog $readmemh
"""
if isinstance(huffman_data, (unicode,str)):
with open(huffman_data) as f:
tokens=f.read().split()
huffman_data = []
for w in tokens:
huffman_data.append(int(w,16))
self.program_table(chn = chn,
table_type = "huffman",
index = index,
data = huffman_data)
def program_quantization(self,
chn,
index,
quantization_data,
verbose = 1):
"""
@brief Program data to quantization table ( a pair or four of Y/C 64-element tables)
@param chn - compressor channel (0..3)
@param index offset address by multiple input data sizes
@param quantization_data - list of table 64/128/256 items or a file path (file has 256-entry table)
@param verbose - verbose level
with the same data, same as for Verilog $readmemh
"""
if isinstance(quantization_data, (unicode,str)):
with open(quantization_data) as f:
tokens=f.read().split()
quantization_data = []
for w in tokens:
quantization_data.append(int(w,16))
self.program_table(chn = chn,
table_type = "quantization",
index = index,
data = quantization_data,
verbose = verbose)
def program_coring(self,
chn,
index,
coring_data):
"""
@brief Program data to quantization table ( a pair or four of Y/C 64-element tables)
@param chn - compressor channel (0..3)
@param index offset address by multiple input data sizes
@param coring_data - list of table 64/128/256 items or a file path (file has 256-entry table)
with the same data, same as for Verilog $readmemh
"""
if isinstance(coring_data, (unicode,str)):
with open(coring_data) as f:
tokens=f.read().split()
coring_data = []
for w in tokens:
coring_data.append(int(w,16))
self.program_table(chn = chn,
table_type = "coring",
index = index,
data = coring_data)
def program_focus(self,
chn,
index,
focus_data):
"""
@brief Program data to focus sharpness weight table
@param chn - compressor channel (0..3)
@param index offset address by multiple input data sizes
@param focus_data - list of table 128 items or a file path
with the same data, same as for Verilog $readmemh
"""
if isinstance(focus_data, (unicode,str)):
with open(focus_data) as f:
tokens=f.read().split()
focus_data = []
for w in tokens:
focus_data.append(int(w,16))
self.program_table(chn = chn,
table_type = "focus",
index = index,
data = focus_data)
def program_table(self,
chn,
table_type,
index,
data,
verbose = 0):
"""
@brief Program data to compressor table
@param chn - compressor channel (0..3)
@param table_type : one of "quantization", "coring","focus","huffman"
@param index offset address as index*len(data32) = index*len(data)*merge_num
@param data - list of table items
"""
table_types = [{"name":"quantization", "merge":2, "t_num": vrlg.TABLE_QUANTIZATION_INDEX},
{"name":"coring", "merge":2, "t_num": vrlg.TABLE_CORING_INDEX},
{"name":"focus", "merge":2, "t_num": vrlg.TABLE_FOCUS_INDEX},
{"name":"huffman", "merge":1, "t_num": vrlg.TABLE_HUFFMAN_INDEX}]
for item in table_types:
if (table_type == item['name']):
merge_num = item["merge"];
t_num = item["t_num"];
break;
else:
raise Exception ("Invalid table type :",table_type," table_types=",table_types)
reg_addr = (vrlg.CMPRS_GROUP_ADDR + chn * vrlg.CMPRS_BASE_INC) + vrlg.CMPRS_TABLES # for data, adderss is "reg_addr + 1"
if merge_num == 1:
data32 = data
else:
data32 = []
for i in range(len(data) // merge_num):
d = 0;
for j in range (merge_num):
d |= data[2* i + j] << (j * (32 // merge_num))
data32.append(d)
t_addr = (t_num << 24) + index* len(data32)
self.x393_axi_tasks.write_control_register(reg_addr + 1, t_addr)
for d in data32:
self.x393_axi_tasks.write_control_register(reg_addr, d)
......@@ -654,7 +654,7 @@ class X393Sensor(object):
self.x393_axi_tasks.write_control_register(reg_addr, data18 & ((1 << 18) - 1))
if isinstance(curves_data, unicode):
if isinstance(curves_data, (unicode,str)):
with open(curves_data) as f:
tokens=f.read().split()
curves_data = []
......
......@@ -27,6 +27,7 @@ module table_ad_transmit#(
parameter ADDR_BITS=4
)(
input clk, // posedge mclk
input srst, // reset @posedge clk
input a_not_d_in, // address/not data input (valid @ we)
input we, // write address/data (single cycle) with at least 5 inactive between
input [31:0] din, // 32 bit data to send or 8-bit channel select concatenated with 24-bit byte address (@we)
......@@ -51,16 +52,19 @@ module table_ad_transmit#(
we_r <= we && a_not_d_in;
if ((we && !a_not_d_in) || we_r) any_en <= 1;
if (srst) any_en <= 0;
else if ((we && !a_not_d_in) || we_r) any_en <= 1;
else if (we3) any_en <= 0;
if ((we && !a_not_d_in) || we_r) chn_en <= sel;
if (srst) chn_en <= 0;
else if ((we && !a_not_d_in) || we_r) chn_en <= sel;
else if (we3) chn_en <= 0;
if (we && a_not_d_in) sel_a <= din[24+:ADDR_BITS];
end
dly_16 #(.WIDTH(1)) i_end_burst(.clk(clk),.rst(1'b0), .dly(4'd2), .din(we), .dout(we3)); // dly=2+1=3
// dly_16 #(.WIDTH(1)) i_end_burst(.clk(clk),.rst(1'b0), .dly(4'd2), .din(we), .dout(we3)); // dly=2+1=3
dly_16 #(.WIDTH(1)) i_end_burst(.clk(clk),.rst(1'b0), .dly(4'd3), .din(we), .dout(we3)); // dly=3+1=4
genvar i;
generate
......
......@@ -1699,6 +1699,10 @@ assign axi_grst = axi_rst_pre;
.CMPRS_COLOR_SATURATION (CMPRS_COLOR_SATURATION),
.CMPRS_CORING_MODE (CMPRS_CORING_MODE),
.CMPRS_TABLES (CMPRS_TABLES),
.TABLE_QUANTIZATION_INDEX (TABLE_QUANTIZATION_INDEX),
.TABLE_CORING_INDEX (TABLE_CORING_INDEX),
.TABLE_FOCUS_INDEX (TABLE_FOCUS_INDEX),
.TABLE_HUFFMAN_INDEX (TABLE_HUFFMAN_INDEX),
.FRAME_HEIGHT_BITS (FRAME_HEIGHT_BITS),
.LAST_FRAME_BITS (LAST_FRAME_BITS),
.CMPRS_CBIT_RUN (CMPRS_CBIT_RUN),
......
......@@ -1037,8 +1037,21 @@ assign #10 gpio_pins[9] = gpio_pins[8];
'h100 >> 5); // input [26:0] afi_cmprs3_len; // input [26:0] length; // channel buffer length in 32-byte chunks
camsync_setup (
4'hf ); // sensor_mask); //
/*
TEST_TITLE = "HUFFMAN_LOAD_CHN0";
$display("===================== TEST_%s =========================",TEST_TITLE);
program_huffman (0 );
TEST_TITLE = "QUANTIZATION_LOAD_CHN0";
$display("===================== TEST_%s =========================",TEST_TITLE);
program_quantization (0);
TEST_TITLE = "FOCUS_FILTER_LOAD_CHN0";
$display("===================== TEST_%s =========================",TEST_TITLE);
program_focus_filt (0);
*/
TEST_TITLE = "GAMMA_LOAD";
$display("===================== TEST_%s =========================",TEST_TITLE);
program_curves(
......@@ -1057,11 +1070,12 @@ assign #10 gpio_pins[9] = gpio_pins[8];
$display("===================== TEST_%s =========================",TEST_TITLE);
axi_get_delays;
`endif
/*
compressor_run (0, 2); // run single
compressor_run (1, 2); // run single
compressor_run (2, 2); // run single
compressor_run (3, 2); // run single
*/
TEST_TITLE = "MEMBRIDGE_READ # 1";
$display("===================== TEST_%s =========================",TEST_TITLE);
TEST_TITLE = "MEMBRIDGE READ #1";
......@@ -1101,6 +1115,7 @@ end
initial begin
// #30000;
#200000;
// #250000;
// #60000;
$display("finish testbench 2");
$finish;
......@@ -2328,7 +2343,8 @@ task setup_sensor_channel;
setup_compressor_channel(
num_sensor, // sensor channel number (0..3)
0, // qbank; // [6:3] quantization table page
// 0, // qbank; // [6:3] quantization table page - 100% quality
1, // qbank; // [6:3] quantization table page - 85%? quality
1, // dc_sub; // [8:7] subtract DC
CMPRS_CBIT_CMODE_JPEG18, //input [31:0] cmode; // [13:9] color mode:
// parameter CMPRS_CBIT_CMODE_JPEG18 = 4'h0, // color 4:2:0
......@@ -2370,6 +2386,7 @@ task setup_sensor_channel;
1); // disable "need" (yield to sensor channels)
// compressor_run (num_sensor, 3); // run repetitive mode
compressor_run (num_sensor, 3); // run repetitive mode
TEST_TITLE = "DELAYS_SETUP";
$display("===================== TEST_%s =========================",TEST_TITLE);
......@@ -3272,6 +3289,71 @@ task program_curves;
end
endtask
task program_huffman;
input [1:0] chn;
reg [29:0] reg_addr;
reg [23:0] huff_data[0:511]; // SuppressThisWarning VEditor : assigned in $readmem() system task
integer i;
begin
$readmemh("input_data/huffman.dat",huff_data);
reg_addr = (CMPRS_GROUP_ADDR + chn * CMPRS_BASE_INC) + CMPRS_TABLES; // for data, adderss is "reg_addr + 1"
write_contol_register(reg_addr + 1, (TABLE_HUFFMAN_INDEX << 24) + 0);
for (i=0;i<512;i=i+1) begin
write_contol_register(reg_addr, {8'b0, huff_data[i]});
end
end
endtask
task program_quantization;
input [1:0] chn;
reg [29:0] reg_addr;
reg [15:0] quant_data[0:255]; // Actually 4 pairs of tables, 1 table is just 64 words SuppressThisWarning VEditor : assigned in $readmem() system task
integer i;
begin
$readmemh("input_data/quantization_100.dat",quant_data);
reg_addr = (CMPRS_GROUP_ADDR + chn * CMPRS_BASE_INC) + CMPRS_TABLES; // for data, adderss is "reg_addr + 1"
write_contol_register(reg_addr + 1, (TABLE_QUANTIZATION_INDEX << 24) + 0); // 64*table_number
for (i=0;i<256;i=i+2) begin
write_contol_register(reg_addr, {quant_data[i+1],quant_data[i]});
end
end
endtask
task program_coring;
input [1:0] chn;
reg [29:0] reg_addr;
reg [15:0] coring_data[0:1023]; // SuppressThisWarning VEditor : assigned in $readmem() system task
integer i;
begin
$readmemh("input_data/coring.dat",coring_data);
reg_addr = (CMPRS_GROUP_ADDR + chn * CMPRS_BASE_INC) + CMPRS_TABLES; // for data, adderss is "reg_addr + 1"
write_contol_register(reg_addr + 1, (TABLE_CORING_INDEX << 24) + 0); // start address of coring tables
for (i=0;i<1024;i=i+2) begin
write_contol_register(reg_addr, {coring_data[i+1], coring_data[i]});
end
end
endtask
task program_focus_filt;
input [1:0] chn;
reg [29:0] reg_addr;
reg [15:0] filt_data[0:127]; // SuppressThisWarning VEditor : assigned in $readmem() system task
integer i;
begin
$readmemh("input_data/focus_filt.dat",filt_data);
reg_addr = (CMPRS_GROUP_ADDR + chn * CMPRS_BASE_INC) + CMPRS_TABLES; // for data, adderss is "reg_addr + 1"
write_contol_register(reg_addr + 1, (TABLE_FOCUS_INDEX << 24) + 0); // start address of focus filter tables
for (i=0;i<128;i=i+2) begin
write_contol_register(reg_addr, {filt_data[i+1], filt_data[i]});
end
end
endtask
// x393_sensor.py
task set_sensor_gamma_table_addr;
......
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