Commit 82e11ec7 authored by Andrey Filippov's avatar Andrey Filippov

multiple changes, synchronizing simulation with hardware

parent 7c1a8880
......@@ -2,6 +2,9 @@ unisims
vivado_*
syntax_*
simulation/*
simulation_data/*
www/*
constraints/*
ise_*
attic/*
hardware_tests/*
......@@ -31,3 +34,9 @@ x393_testbench01_debug_membridge.sav
x393_testbench02-0.sav
py393/generated
*.pickle
py393/i2c.py
py393/x393_i2c.py.test
py393/x393_init_usb_hub.py
py393/x393_mcntrl_adjust.py.dbg
x393_testbench03_01.sav
......@@ -62,52 +62,52 @@
<link>
<name>vivado_logs/VivadoBitstream.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoBitstream-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoBitstream-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoOpt.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOpt-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoOpt-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPhys-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPhys-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPower.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPower-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPower-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoPlace.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoPlace-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoPlace-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoRoute.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoRoute-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoRoute-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoSynthesis-20160417173535326.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoSynthesis-20160502180258922.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportImplemented-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportImplemented-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160417173535326.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160502180258922.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimingReportSynthesis-20160417173535326.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimingReportSynthesis-20160502180258922.log</location>
</link>
<link>
<name>vivado_state/x393-opt-phys.dcp</name>
......@@ -127,7 +127,7 @@
<link>
<name>vivado_state/x393-synth.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_state/x393-synth-20160417173535326.dcp</location>
<location>/home/andrey/git/x393/vivado_state/x393-synth-20160502180258922.dcp</location>
</link>
</linkedResources>
</projectDescription>
......@@ -291,6 +291,8 @@ module membridge#(
reg [4:0] rd_id;
reg [4:0] wr_id;
reg read_no_more; // after frame_done - no more requests for new pages to read
assign afi_arid={1'b1,rd_id};
assign afi_awid={1'b1,wr_id};
assign afi_wid= {1'b1,wr_id};
......@@ -324,7 +326,7 @@ module membridge#(
if (hrst) wr_start <= 0;
else wr_start <= rdwr_start[2] && wr_mode;
page_ready_rd <= page_ready && !wr_mode;
// page_ready_rd <= page_ready && !wr_mode && !read_no_more;
if (hrst) rd_id <= 0;
else if (rd_start) rd_id <= rd_id +1;
......@@ -429,7 +431,7 @@ module membridge#(
afi_len <= (|left64[28:4])?4'hf : (left64[3:0]-1);
afi_len_plus1 <= (|left64[28:4]) ? 5'h10 : {1'b0,left64[3:0]};
page_ready_rd <= page_ready && !wr_mode;
page_ready_rd <= page_ready && !wr_mode && !read_no_more;
page_ready_wr <= page_ready && wr_mode;
if (!rw_in_progress) buf_left64 <= len64;
......@@ -450,12 +452,13 @@ module membridge#(
//rdwr_en
reg [7:0] axi_arw_requested; // 64-bit words to be read/written over axi queued to AR/AW channels
reg [7:0] axi_bursts_requested; // number of bursts requested
reg [7:0] wresp_conf; // number of 64-bit words confirmed through axi b channel
wire [7:0] axi_wr_pending; // Number of words qued to AW but not yet confirmed through B-channel;
reg [7:0] wresp_conf; // number of 64-bit words confirmed through axi b channel (wrong confirmed only bursts)!
wire [7:0] axi_wr_pending; // Number of bursts queued to AW but not yet confirmed through B-channel;
reg [7:0] axi_wr_left; // Number of bursts queued through AW but not sent over W;
wire [7:0] axi_rd_pending;
reg [7:0] axi_rd_received;
assign axi_rd_pending= axi_arw_requested - axi_rd_received;
assign axi_rd_pending= axi_arw_requested - axi_rd_received; // WRONG! - use bursts, not words!
// assign axi_wr_pending= axi_arw_requested - wresp_conf;
assign axi_wr_pending= axi_bursts_requested - wresp_conf;
......@@ -520,12 +523,12 @@ module membridge#(
if (hrst) read_page <= 0;
else if (reset_page_rd) read_page <= 0;
else if (next_page_rd_w) read_page <= read_page + 1;
else if (done_page_rd_w) read_page <= read_page + 1;
if (hrst) read_pages_ready <= 0;
else if (!read_busy) read_pages_ready <= 0;
else if ( page_ready_rd && !next_page_rd_w) read_pages_ready <= read_pages_ready +1;
else if (!page_ready_rd && next_page_rd_w) read_pages_ready <= read_pages_ready -1;
else if ( page_ready_rd && !done_page_rd_w) read_pages_ready <= read_pages_ready +1;
else if (!page_ready_rd && done_page_rd_w) read_pages_ready <= read_pages_ready -1;
if (hrst) afi_wd_safe_not_full <= 0;
else afi_wd_safe_not_full <= rdwr_en && (!afi_wcount[7] && !(&afi_wcount[6:3]));
......@@ -544,6 +547,12 @@ module membridge#(
else if (pre_done) done <= 1;
else if (rdwr_start) done <= 0;
if (hrst ) read_no_more <= 0;
else if (!read_busy) read_no_more <= 0;
else if (frame_done) read_no_more <= 1;
end
// handle interaction with the buffer, advance addresses, keep track of partial (last) pages in each line
......@@ -557,17 +566,29 @@ module membridge#(
wire is_last_in_page;
wire next_page_rd_w;
wire next_page_wr_w;
wire done_page_rd_w;
wire safe_some_left_rd_w;
reg left_was_1; // was <=1 (0 does not matter) valid next after buffer address
reg left_many;
// assign next_page_rd_w = read_started && !busy_next_page && is_last_in_page && bufrd_rd[0];
assign next_page_rd_w = read_started && is_last_in_page && bufrd_rd[0];
assign done_page_rd_w = read_started && is_last_in_page && bufrd_rd[0];
assign next_page_rd_w = done_page_rd_w && !read_no_more;
assign is_last_in_line = buf_in_line64 == last_in_line64;
assign is_last_in_page = is_last_in_line || (&buf_in_line64[6:0]);
// assign safe_some_left_rd_w = (axi_wr_left[7:1]!=0) || (axi_wr_left[0] && !bufrd_rd[0]);
assign safe_some_left_rd_w = left_many || (|buf_left64[1:0] && !(|bufrd_rd)); // Fine tune
`ifdef MEMBRIDGE_DEBUG_READ
assign bufrd_rd_w = afi_wd_safe_not_full && (|read_pages_ready[2:1] || (read_pages_ready[0] && !is_last_in_page)) && debug_w_ready;
assign bufrd_rd_w = safe_some_left_rd_w && !read_over && afi_wd_safe_not_full &&
(|read_pages_ready[2:1] || (read_pages_ready[0] && (!is_last_in_page || read_no_more))) && debug_w_ready;
`else
assign bufrd_rd_w = afi_wd_safe_not_full && (|read_pages_ready[2:1] || (read_pages_ready[0] && !is_last_in_page));
// assign bufrd_rd_w = afi_wd_safe_not_full && (|read_pages_ready[2:1] || (read_pages_ready[0] && !is_last_in_page));
assign bufrd_rd_w = safe_some_left_rd_w && !read_over && afi_wd_safe_not_full &&
(|read_pages_ready[2:1] || (read_pages_ready[0] && (!is_last_in_page || read_no_more)));
`endif
//last_in_line64 - last word number in scan line
reg left_was_1; // was <=1 (0 does not matter) valid next after buffer address
reg [3:0] src_wcntr;
// reg [2:0] wlast_in_burst;
reg wlast; // valid 2 after buffer address, same as wvalid
......@@ -581,6 +602,12 @@ module membridge#(
if (!rw_in_progress) left_was_1 <= 0;
else if (buf_rdwr) left_was_1 <= !(|buf_left64[28:1]);
/* if (!rw_in_progress) left_many <= 0;
else if (buf_rdwr) */
left_many <= |buf_left64[28:2];
if (!read_started) src_wcntr <= 0;
else if (bufrd_rd[0]) src_wcntr <= src_wcntr+1;
......@@ -643,6 +670,11 @@ module membridge#(
else if (!write_busy) axi_rd_received <= 0;
else if (bufwr_we[0]) axi_rd_received <= axi_rd_received + 1;
if (hrst) axi_wr_left <= 0;
else if (!read_started) axi_wr_left <= 0;
else if ( advance_rel_addr && !(wlast && afi_wvalid)) axi_wr_left <= axi_wr_left + 1;
else if (!advance_rel_addr && (wlast && afi_wvalid)) axi_wr_left <= axi_wr_left - 1;
if (hrst) afi_rd_safe_not_empty <= 0;
// allow 1 cycle latency, no continuous reads when FIFO is low (like in the very end of the transfer)
......
......@@ -78,7 +78,8 @@ module cmprs_frame_sync#(
output reg force_flush_long, // force flush (abort frame), can be any clock and may last until stuffer_done_mclk
// stuffer will re-clock and extract 0->1 transition
output stuffer_running_mclk,
output reading_frame
output reading_frame,
output frame_started_mclk // use to store frame number
);
/*
Abort frame (force flush) if:
......@@ -87,7 +88,7 @@ module cmprs_frame_sync#(
Abort frame lasts until flush end or timeout expire
*/
// wire vsync_late_mclk; // single mclk cycle, reclocked from vsync_late
wire frame_started_mclk;
// wire frame_started_mclk;
reg bonded_mode;
reg frame_start_dst_r;
reg frames_differ; // src and dest point to different frames (single-frame buffer mode), disregard line_unfinished_*
......
......@@ -33,15 +33,18 @@
*******************************************************************************/
`timescale 1ns/1ps
module cmprs_status(
module cmprs_status #(
parameter NUM_FRAME_BITS = 4
) (
input mrst,
input mclk, // system clock
input eof_written,
input stuffer_running,
input reading_frame,
input [NUM_FRAME_BITS - 1:0] frame_num_compressed,
input set_interrupts,
input [1:0] data_in,
output [4:0] status,
output [NUM_FRAME_BITS+7:0] status,
output irq
);
......@@ -49,9 +52,11 @@ module cmprs_status(
reg flushing_fifo;
reg is_r; // interrupt status (not masked)
reg im_r; // interrupt mask
reg [NUM_FRAME_BITS - 1:0] frame_irq;
assign status = {flushing_fifo,
assign status = {frame_irq,
3'b0,
flushing_fifo,
stuffer_running_r,
reading_frame,
im_r, is_r};
......@@ -65,6 +70,8 @@ module cmprs_status(
else if (eof_written) is_r <= 1;
else if (set_interrupts && (data_in == 1)) is_r <= 0;
if (eof_written) frame_irq <= frame_num_compressed;
stuffer_running_r <= stuffer_running;
if (stuffer_running_r && !stuffer_running) flushing_fifo <= 1;
......
......@@ -127,7 +127,9 @@ module compressor393 # (
parameter CMPRS_AFIMUX_WIDTH = 26, // maximal for status: currently only works with 26)
parameter CMPRS_AFIMUX_CYCBITS = 3,
parameter AFI_MUX_BUF_LATENCY = 4'd2 // buffers read latency from fifo_ren* to fifo_rdata* valid : 2 if no register layers are used
parameter AFI_MUX_BUF_LATENCY = 4'd2, // buffers read latency from fifo_ren* to fifo_rdata* valid : 2 if no register layers are used
parameter NUM_FRAME_BITS = 4 // number of bits use for frame number
`ifdef DEBUG_RING
,parameter DEBUG_CMD_LATENCY = 2
`endif
......@@ -173,6 +175,7 @@ module compressor393 # (
// use as 'eot_real' in 353
output [3:0]suspend, // suspend reading data for this channel - waiting for the source data
output [4*LAST_FRAME_BITS-1:0] frame_number_finished, // frame numbers compressed
// statistics data was not used in late nc353
// input dccout, //enable output of DC and HF components for brightness/color/focus adjustments
......@@ -187,11 +190,12 @@ module compressor393 # (
// Outputs for interrupts generation
output [3:0] eof_written_mclk,
output [3:0] stuffer_done_mclk,
// frame input synchronization
input [3:0] vsync_late, // delayed start of frame, @mclk. In 353 it was 16 lines after VACT active
// source channel should already start, some delay give time for sequencer commands
// that should arrive before it
// Frame numbers to determine number of compressed frame (for interrupts)
input [4 * NUM_FRAME_BITS-1:0] frame_num_compressed,
// AXI_HP inteface (single/dual). afi indices - relative (0,1) may actually be connected to 1,2 (or only to 1)
input hclk,
......@@ -398,7 +402,8 @@ module compressor393 # (
.CMPRS_CSAT_CR_BITS (CMPRS_CSAT_CR_BITS),
.CMPRS_CORING_BITS (CMPRS_CORING_BITS),
.CMPRS_TIMEOUT_BITS (CMPRS_TIMEOUT_BITS),
.CMPRS_TIMEOUT (CMPRS_TIMEOUT)
.CMPRS_TIMEOUT (CMPRS_TIMEOUT),
.NUM_FRAME_BITS (NUM_FRAME_BITS)
`ifdef DEBUG_RING
,.DEBUG_CMD_LATENCY (DEBUG_CMD_LATENCY)
`endif
......@@ -433,7 +438,7 @@ module compressor393 # (
.frame_number_dst (frame_number_dst[LAST_FRAME_BITS * i +: LAST_FRAME_BITS]), // input[15:0]
.frame_done_dst (frame_done_dst[i]), // input
.suspend (suspend[i]), // output
.frame_number_finished (frame_number_finished[LAST_FRAME_BITS * i +: LAST_FRAME_BITS]), // output reg[15:0]
.dccout (1'b0), // input
.hfc_sel (3'b0), // input[2:0]
.statistics_dv (), // output
......@@ -443,6 +448,7 @@ module compressor393 # (
.eof_written_mclk (eof_written_mclk[i]), // output
.stuffer_done_mclk (stuffer_done_mclk[i]), // output
.vsync_late (vsync_late[i]), // input
.frame_num_compressed (frame_num_compressed[i * NUM_FRAME_BITS +: NUM_FRAME_BITS]), // input[3:0]
.hclk (hclk), // input
.fifo_rst (fifo_rst[i]), // input
......
......@@ -111,7 +111,9 @@ module jp_channel#(
parameter CMPRS_CORING_BITS = 3, // number of bits in coring mode
parameter CMPRS_TIMEOUT_BITS= 12,
parameter CMPRS_TIMEOUT= 1000 // mclk cycles
parameter CMPRS_TIMEOUT= 1000, // mclk cycles
parameter NUM_FRAME_BITS = 4 // number of bits use for frame number
`ifdef DEBUG_RING
,parameter DEBUG_CMD_LATENCY = 2 //SuppressThisWarning VEditor - not used
`endif
......@@ -159,6 +161,8 @@ module jp_channel#(
input frame_done_dst, // single-cycle pulse when the full frame (window) was transferred to/from DDR3 memory
// use as 'eot_real' in 353
output suspend, // suspend reading data for this channel - waiting for the source data
output reg [LAST_FRAME_BITS-1:0] frame_number_finished, // valid after stuffer done
// statistics data was not used in late nc353
input dccout, //enable output of DC and HF components for brightness/color/focus adjustments
......@@ -177,6 +181,7 @@ module jp_channel#(
input vsync_late, // delayed start of frame, @mclk. In 353 it was 16 lines after VACT active
// source channel should already start, some delay give time for sequencer commands
// that should arrive before it
input [NUM_FRAME_BITS-1:0] frame_num_compressed,
// Output interface to the AFI mux
input hclk,
......@@ -312,6 +317,17 @@ module jp_channel#(
//TODO: use next signals for status
wire stuffer_running_mclk;
wire reading_frame;
wire frame_started_mclk;// store frame number ? Wrong, frame number should come from the sensor channel
reg stuffer_running_mclk_d;
reg [LAST_FRAME_BITS-1:0] frame_number_started; // valid when stuffer started
// output reg [LAST_FRAME_BITS-1:0] frame_number_finished, // valid after stuffer done
always @ (posedge mclk) begin
stuffer_running_mclk_d <=stuffer_running_mclk;
if ( stuffer_running_mclk && !stuffer_running_mclk_d) frame_number_started <= frame_number_dst;
if (!stuffer_running_mclk && stuffer_running_mclk_d) frame_number_finished <= frame_number_started;
end
`ifdef USE_XCLK2X
wire [15:0] huff_do; // output[15:0] reg
......@@ -581,22 +597,25 @@ module jp_channel#(
.we (cmd_we) // output
);
wire [4:0] status_data;
cmprs_status cmprs_status_i (
wire [11:0] status_data;
cmprs_status #(
.NUM_FRAME_BITS(4)
) cmprs_status_i (
.mrst (mrst), // input
.mclk (mclk), // input
.eof_written (eof_written_mclk), // input
.stuffer_running (stuffer_running_mclk), // input
.reading_frame (reading_frame), // input
.frame_num_compressed (frame_num_compressed), // input[3:0]
.set_interrupts (set_interrupts_w), // input
.data_in (cmd_data[1:0]), // input[1:0]
.status (status_data), // output[2:0]
.status (status_data), // output[9:0]
.irq (irq) // output
);
status_generate #(
.STATUS_REG_ADDR (CMPRS_STATUS_REG_ADDR),
.PAYLOAD_BITS (7),
.PAYLOAD_BITS (14),
.EXTRA_WORDS (1),
.EXTRA_REG_ADDR (CMPRS_HIFREQ_REG_ADDR)
......@@ -779,8 +798,8 @@ module jp_channel#(
.stuffer_running (stuffer_running), // input
.force_flush_long (force_flush_long), // output reg - @ mclk tried to start frame compression before the previous one was finished
.stuffer_running_mclk(stuffer_running_mclk), // output
.reading_frame (reading_frame) // output
.reading_frame (reading_frame), // output
.frame_started_mclk (frame_started_mclk)
);
cmprs_macroblock_buf_iface cmprs_macroblock_buf_iface_i (
......@@ -1239,6 +1258,9 @@ module jp_channel#(
.fifo_count (fifo_count) // output[7:0] - number of 32-byte chunks available in FIFO
);
pulse_cross_clock eof_written_mclk_i (.rst(xrst2xn), .src_clk(~xclk2x), .dst_clk(mclk), .in_pulse(eof_written_xclk2xn), .out_pulse(eof_written_mclk),.busy());
// pulse_cross_clock eof_written_mclk_i (.rst(xrst2xn), .src_clk(~xclk2x), .dst_clk(mclk), .in_pulse(eof_written_xclk2xn), .out_pulse(eof_written_mclk),.busy());
`ifdef DISPLAY_COMPRESSED_DATA
integer dbg_stuffer_word_number;
reg dbg_odd_stuffer_dv;
......
......@@ -32,7 +32,8 @@
* with at least one of the Free Software programs.
*******************************************************************************/
parameter FPGA_VERSION = 32'h03930086; // Adding byte-wide JTAG read to speed-up 10359 load
parameter FPGA_VERSION = 32'h03930087; // Synchronizing i2c sequencer frame number with that of a command sequencer
// parameter FPGA_VERSION = 32'h03930086; // Adding byte-wide JTAG read to speed-up 10359 load
// parameter FPGA_VERSION = 32'h03930085; // Adding software control for i2c pins when sequencer is stopped, timing matched
// parameter FPGA_VERSION = 32'h03930084; // Back to iserdes, inverting xfpgatdo - met
// parameter FPGA_VERSION = 32'h03930083; // Debugging JTAG, using plain IOBUF
......
......@@ -139,6 +139,7 @@ task test_afi_rw; // SuppressThisWarning VEditor - may be unused
input continue; // 0 start from start64, 1 - continue from where it was
input disable_need;
input [4:0] cache_mode; // 'h3 - normal, 'h13 - debug
input rpt;
// -----------------------------------------
......@@ -154,8 +155,8 @@ task test_afi_rw; // SuppressThisWarning VEditor - may be unused
begin
skip_too_late = 1'b0;
disable_need = 1'b0;
repetitive = 1'b1;
single = 1'b0;
repetitive = rpt; //1'b1;
single = !rpt; // 1'b0;
reset_frame = 1'b0;
$display("====== test_afi_rw: write=%d, extra_pages=%d, frame_start= %x, window_full_width=%d, window_width=%d, window_height=%d, window_left=%d, window_top=%d,@%t",
write_ddr3, extra_pages, frame_start_addr, window_full_width, window_width, window_height, window_left, window_top, $time);
......
......@@ -55,15 +55,17 @@
// parameter SENSOR12BITS_NROWA = 1, // number of "blank rows" from last hact to end of vact
// parameter nAV = 24, //240; // clocks from ARO to VACT (actually from en_dclkd)
// parameter SENSOR12BITS_NBPF = 20, //16; // bpf length
parameter SENSOR_IMAGE_TYPE0 = "NORM", // "RUN1",
parameter SENSOR_IMAGE_TYPE0 = "RUN1", //"NORM", // "RUN1",
parameter SENSOR_IMAGE_TYPE1 = "RUN1",
parameter SENSOR_IMAGE_TYPE2 = "NORM", // "RUN1",
parameter SENSOR_IMAGE_TYPE2 = "RUN1", // "NORM", // "RUN1",
parameter SENSOR_IMAGE_TYPE3 = "RUN1",
parameter SIMULATE_CMPRS_CMODE0 = CMPRS_CBIT_CMODE_JPEG18,
parameter SIMULATE_CMPRS_CMODE1 = CMPRS_CBIT_CMODE_JPEG18,
parameter SIMULATE_CMPRS_CMODE2 = CMPRS_CBIT_CMODE_JP4,
parameter SIMULATE_CMPRS_CMODE3 = CMPRS_CBIT_CMODE_JP4,
// parameter SIMULATE_CMPRS_CMODE2 = CMPRS_CBIT_CMODE_JPEG18,
// parameter SIMULATE_CMPRS_CMODE3 = CMPRS_CBIT_CMODE_JPEG18,
// CMPRS_CBIT_CMODE_JPEG18, //input [31:0] cmode; // [13:9] color mode:
// parameter CMPRS_CBIT_CMODE_JPEG18 = 4'h0, // color 4:2:0
// parameter CMPRS_CBIT_CMODE_MONO6 = 4'h1, // mono 4:2:0 (6 blocks)
......
......@@ -311,6 +311,7 @@ module mcntrl393 #(
input [255:0] sens_buf_dout, // (), // output[63:0]
input [3:0] sens_page_written, // single mclk pulse: buffer page (full or partial) is written to the memory buffer
output [3:0] sens_xfer_skipped, // single mclk pulse on each bit indicating one skipped (not written) block.
output reg [3:0] sens_first_wr_in_frame, // single mclk pulse on first write block in each frame
// compressor subsystem interface
// Buffer interfaces, combined for 4 channels
output [3:0] cmprs_xfer_reset_page_rd, // from mcntrl_tiled_rw (
......@@ -319,6 +320,7 @@ module mcntrl393 #(
output [255:0] cmprs_buf_din, // data out
output [3:0] cmprs_page_ready, // single mclk (posedge)
input [3:0] cmprs_next_page, // single mclk (posedge): Done with the page in the buffer, memory controller may read more data
output reg [3:0] cmprs_first_rd_in_frame, // single mclk pulse on first read block in each frame
// master (sensor) with slave (compressor) synchronization I/Os
input [3:0] cmprs_frame_start_dst, // @mclk - trigger receive (tiledc) memory channel (it will take care of single/repetitive
......@@ -734,7 +736,9 @@ module mcntrl393 #(
wire tiled_rw_start_wr16; // start cmd_encod_tiled_32_rw generating command sequence in write mode
wire tiled_rw_start_rd32; // start cmd_encod_tiled_32_rw generating command sequence in read mode
wire tiled_rw_start_wr32; // start cmd_encod_tiled_32_rw generating command sequence in write mode
// for propagating absolute frame number:
reg [3:0] sens_first_wr_pending_r;
reg [3:0] cmprs_first_rd_pending_r;
// Command tree - insert register layer(s) if needed, now just direct assignments
......@@ -756,8 +760,6 @@ module mcntrl393 #(
assign cmd_cmprs_ad= cmd_ad;
assign cmd_cmprs_stb= cmd_stb;
// For now - combinatorial, maybe add registers (modify axibram_read)
assign buf_raddr=axird_raddr;
assign axird_rdata = (select_buf0rd ? buf0_data : 32'b0) |
......@@ -788,6 +790,19 @@ module mcntrl393 #(
assign select_buf4rd_w = ((axird_pre_araddr ^ MCONTR_BUF4_RD_ADDR) & MCONTR_RD_MASK)==0;
assign select_buf4wr_w = ((axiwr_pre_awaddr ^ MCONTR_BUF4_WR_ADDR) & MCONTR_WR_MASK)==0;
always @ (posedge mclk) begin
if (mrst) sens_first_wr_pending_r <= 0;
else sens_first_wr_pending_r <= sens_sof | (sens_first_wr_pending_r & ~sens_start_wr);
//cmprs_first_rd_pending_r
sens_first_wr_in_frame <= sens_first_wr_pending_r & sens_start_wr;
if (mrst) cmprs_first_rd_pending_r <= 0;
else cmprs_first_rd_pending_r <= cmprs_frame_start_dst | (cmprs_first_rd_pending_r & ~cmprs_channel_pgm_en);
cmprs_first_rd_in_frame <= cmprs_first_rd_pending_r & cmprs_channel_pgm_en;
end
always @ (posedge axi_clk) begin
if (mrst) select_cmd0 <= 0;
else if (axiwr_start_burst) select_cmd0 <= select_cmd0_w;
......
......@@ -182,6 +182,7 @@ module mcntrl_linear_rw #(
reg frame_finished_r;
wire last_in_row_w;
wire last_row_w;
wire last_block_w;
reg last_block;
reg [MCNTRL_SCANLINE_PENDING_CNTR_BITS-1:0] pending_xfers; // number of requested,. but not finished block transfers
reg [NUM_RC_BURST_BITS-1:0] row_col_r;
......@@ -340,7 +341,9 @@ module mcntrl_linear_rw #(
// assign pre_want= chn_en && busy_r && !want_r && !xfer_start_r[0] && calc_valid && !last_block && !suspend && !(|frame_start_r);
// accelerating pre_want:
assign pre_want= pre_want_r1 && !want_r && !xfer_start_r[0] && !suspend ;
// assign pre_want= pre_want_r1 && !want_r && !xfer_start_r[0] && !suspend ;
// last_block was too late to inclusde in pre_want_r1, moving it here
assign pre_want= pre_want_r1 && !want_r && !xfer_start_r[0] && !suspend && !last_block;
assign last_in_row_w=(row_left=={{(FRAME_WIDTH_BITS-NUM_XFER_BITS){1'b0}},xfer_num128_r});
assign last_row_w= next_y==window_height;
......@@ -485,8 +488,10 @@ wire start_not_partial= xfer_start_r[0] && !xfer_limited_by_mem_page_r;
// calculate number to read (min of row_left, maximal xfer and what is left in the DDR3 page
always @(posedge mclk) begin
// acceletaring pre_want
pre_want_r1 <= chn_en && !frame_done_r && busy_r && par_mod_r[PAR_MOD_LATENCY-2] && !(|frame_start_r[4:1]) && !last_block;
// pre_want_r1 <= chn_en && !frame_done_r && busy_r && par_mod_r[PAR_MOD_LATENCY-2] && !(|frame_start_r[4:1]) && !last_block;
//last_block is too late for pre_want_r1, moving upsteram
pre_want_r1 <= chn_en && !frame_done_r && busy_r && par_mod_r[PAR_MOD_LATENCY-2] && !(|frame_start_r[4:1]);
if (mrst) par_mod_r<=0;
else if (pgm_param_w ||
xfer_start_r[0] ||
......
......@@ -47,6 +47,7 @@ import time
#import shutil
import socket
import select
import traceback
from import_verilog_parameters import ImportVerilogParameters
#from import_verilog_parameters import VerilogParameters
......@@ -152,6 +153,7 @@ def execTask(commandLine):
sFuncArgs+=' <'+str(a)+'>'
print ("Usage:\n%s %s"%(funcName,sFuncArgs))
print ("exception message:"+str(e))
print (traceback.format_exc())
else:
result = callableTasks[funcName]['func'](callableTasks[funcName]['inst'],*funcArgs)
return result
......@@ -480,7 +482,7 @@ USAGE
print ("args.exception=%d, QUIET=%d"%(args.exceptions,QUIET))
print ("Enter 'R' to toggle show/hide command results, now it is %s"%(("OFF","ON")[showResult]))
print ("Use 'socket_port [PORT]' to (re-)open socket on PORT (0 or no PORT - disable socket)")
# print ("Use 'copy <SRC> <DST> to copy files in file the system")
# print ("Use 'copy <SRC> <DST> to copy files in file the system")
print ("Use 'pydev_predefines' to generate a parameter list to paste to vrlg.py, so Pydev will be happy")
elif lineList[0].upper() == 'R':
if len(lineList)>1:
......
......@@ -106,15 +106,51 @@ class X393CmprsAfi(object):
num_lines_print = 20):
"""
Returns image metadata (start, length,timestamp) or null
@param port_afi - AFI port (0/1), currently only 0
@param port_afi - AFI port (0/1), currently only 0, or file path template for simulated mode
@param channel - AFI input channel (0..3) - with 2 AFIs - 0..1 only
@return - memory segments (1 or two) with image data, timestamp in numeric and string format
"""
if verbose >0:
def read_mem(addr):
if ba_data:
return ba_data[addr + 0] + (ba_data[addr + 1] << 8) + (ba_data[addr + 2] << 16) + (ba_data[addr + 3] << 24)
else:
return self.x393_mem.read_mem(addr)
if isinstance(port_afi, (unicode,str)):
data_file = port_afi%channel # for simulated mode
ba_data=bytearray()
try:
with open(data_file) as f:
for l in f:
line = l.strip()
if line:
dl = []
for item in line.split():
dl.append(int(item,16))
ba_data += bytearray(dl)
if verbose > 0:
print ("Read simulated sensor JPEG data from %s data file"%(data_file))
except:
print("Failed to read data from ", data_file)
return
cirbuf_start = 0
circbuf_len = len(ba_data)
print ("len(ba) = %d"%(len(ba_data)))
if verbose > 1:
for i in range(len(ba_data)):
if not (i%16):
print("\n%04x:"%(i),end="")
print ("%02x "%(ba_data[i]),end="")
else:
ba_data = None
if verbose > 0:
print ("\n------------ channel %d --------------"%(channel))
print ("x393_sens_cmprs.GLBL_WINDOW = ", x393_sens_cmprs.GLBL_WINDOW)
if (self.DRY_MODE):
return None
# if (self.DRY_MODE):
# return None
CCAM_MMAP_META = 12 # extra bytes included at the end of each frame (last aligned to 32 bytes)
CCAM_MMAP_META_LENGTH = 4 # displacement to length frame length data from the end of the 32-byte aligned frame slot
CCAM_MMAP_META_USEC = 8 # // (negative) displacement to USEC data - 20 bits (frame timestamp)
......@@ -122,20 +158,25 @@ class X393CmprsAfi(object):
# offs_len32 = 0x20 - CCAM_MMAP_META_LENGTH # 0x1c #from last image 32-byte chunk to lower of 3-byte image length (MSB == 0xff)
if ba_data:
next_image = len(ba_data)
else:
next_image = self.afi_mux_get_image_pointer(port_afi = port_afi,
channel = channel)
# Bug - got 0x20 more than start of the new image
last_image_chunk = next_image - 0x40
if last_image_chunk < 0:
last_image_chunk += circbuf_len
len32 = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH))
## len32 = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH))
len32 = read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH))
markerFF = len32 >> 24
if (markerFF != 0xff):
print ("Failed to get 0xff marker at offset 0x%08x - length word = 0x%08x, next_image = 0x%08x)"%
(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH) + 3,len32,next_image))
if verbose >0:
for a in range ( next_image - (0x10 * num_lines_print), next_image + (0x10 * num_lines_print), 4):
d = self.x393_mem.read_mem(cirbuf_start + a)
## d = self.x393_mem.read_mem(cirbuf_start + a)
d = read_mem(cirbuf_start + a)
if (a % 16) == 0:
print ("\n%08x: "%(a),end ="" )
print("%02x %02x %02x %02x "%(d & 0xff, (d >> 8) & 0xff, (d >> 16) & 0xff, (d >> 24) & 0xff), end = "")
......@@ -146,7 +187,8 @@ class X393CmprsAfi(object):
last_image_chunk = next_image - 0x40
if last_image_chunk < 0:
last_image_chunk += circbuf_len
len32 = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH))
## len32 = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH))
len32 = read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH))
markerFF = len32 >> 24
if (markerFF != 0xff):
print ("**** Failed to get 0xff marker at CORRECTED offset 0x%08x - length word = 0x%08x, next_image = 0x%08x)"%
......@@ -166,7 +208,8 @@ class X393CmprsAfi(object):
img_start += circbuf_len
if verbose >0:
for a in range ( img_start, img_start + (0x10 * num_lines_print), 4):
d = self.x393_mem.read_mem(cirbuf_start + a)
## d = self.x393_mem.read_mem(cirbuf_start + a)
d = read_mem(cirbuf_start + a)
if (a % 16) == 0:
print ("\n%08x: "%(a),end ="" )
print("%02x %02x %02x %02x "%(d & 0xff, (d >> 8) & 0xff, (d >> 16) & 0xff, (d >> 24) & 0xff), end = "")
......@@ -175,14 +218,17 @@ class X393CmprsAfi(object):
a = a0
if (a < 0):
a -=circbuf_len
d = self.x393_mem.read_mem(cirbuf_start + a)
## d = self.x393_mem.read_mem(cirbuf_start + a)
d = read_mem(cirbuf_start + a)
if (a % 16) == 0:
print ("\n%08x: "%(a),end ="" )
print("%02x %02x %02x %02x "%(d & 0xff, (d >> 8) & 0xff, (d >> 16) & 0xff, (d >> 24) & 0xff), end = "")
print()
sec = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_SEC))
usec = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_USEC))
## sec = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_SEC))
sec = read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_SEC))
## usec = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_USEC))
usec = read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_USEC))
fsec=sec + usec/1000000.0
try:
tstr = time.strftime("%b %d %Y %H:%M:%S", time.gmtime(fsec))
......@@ -196,6 +242,8 @@ class X393CmprsAfi(object):
result = {"timestamp": fsec,
"timestring": tstr,
"segments":segments}
if ba_data:
result["bindata"] = ba_data